仅378条数据居然导致合服失败?!-创新互联

作者:伍旭飞,腾讯云数据库高级工程师,主要负责腾讯云Redis、MongoDB开发。

在官渡等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都做网站、成都网站设计 网站设计制作按需定制开发,公司网站建设,企业网站建设,品牌网站建设,营销型网站建设,成都外贸网站建设,官渡网站建设费用合理。

故事从一个MongoDB数据库连接超时案例说起。该异常导致2次合服失败,前面已在服务器上抓包并dump下来,下方是客户端超时现场截图:

仅378条数据居然导致合服失败?!

从截图不难看出,这是一个Nodejs服务出错信息,推测DBA应该是用的nodejs mongodb来实现连接数据库并进行操作,找到这个driver的官网 https:// -mongodb-native ,clone了一份代码下来。简单看了下,再结合上图,初步分析出错连接是在第38个连接超时的。

1. 分析抓包内容

由于前面已经在出错服务器上抓包了,因此,首先我用wireShark打开从服务器上dump下来的文件,wireShark很智能,能分析多种常用协议,很方便,但是也容易带来误判。比如我们的数据库连接很多地方都被误判为X11协议:

仅378条数据居然导致合服失败?!

一开始很纠结这个错误,其实这当然不是什么x11协议,只是碰巧模式匹配上了,到wireShark设置了下,取消了X11的分析,很容易从端口和连接看出,就是数据库连接。

仔细检查了抓包内容,大致如下:

(1)开始有个连接从数据库拉取了大概3M多的数据。

(2)后面陆续有常规的三次握手连接建立成功,但是都基本没有实质性的数据传输,就走了正常的tcp结束流程了。

(3)从抓包内容来看,服务器不存在未回应客户端syn连接包的情况。

好了,到这里分析的内容,似乎完全解释不了为什么会超时,那么下一步就是和用户沟通,获取更多的信息了。

(4)所有的tcp链接均为客户端发起FIN主动关闭,不存在服务器主动关闭客户端连接的情况。

2. 出错代码

通过沟通,拿到了出错部分工具的代码片段(最开始没有完整的函数,后面才拿到完整函数):

function merge_union_info(dbs) {
    var union_data = [];
    async.each(
        dbs,
        function(path, cb) {
            mongodb.connect(path, (err, db) => {
                if (err) {
                    cb(err);
                    return
                }
                db.collection('union').find().sort({level: -1, exp: -1}).toArray((err1, v) => {
                    if (err1) {
                        db.close();
                        console.log(err1);
                        return
                    }
                    let loop = v.length > 50 ? 50 : v.length;
                    let u_data = [];
                    for (let i = 0; i < loop; i++) {
                        v[i].merge_flag = 1;
                        u_data.push(v[i]);
                    }
                    union_data.push(u_data);
                    db.close();
                    cb();
                });
            })
        },
        function(err) {
            if (err) {
                console.log("[ERROR]merge union-data failed !!!");
                return
            }
            async.waterfall([
                function(cb1) {
                    mongodb.connect(dbs[0], (err1, db) => {
                        if (err1) {
                            cb1(`[ERROR]gen union-data [drop] failed for ${err1}`)
                            return
                        }
                        var col = db.collection('union');
                        db.collection('union').drop((err2, r2) => {
                            db.close();
                            cb1(err2);
                        });
                    }); 
                },
                function(cb1) {
                    async.each(
                        union_data, 
                        function(u_data, cb2) {
                            mongodb.connect(dbs[0], (err1, db) => {
                                if (err1) {
                                    cb2(`[ERROR]gen union-data [insert] failed for ${err1}`)
                                    return
                                }
                                var col = db.collection('union');
                                col.insertMany(u_data, (err2, r2) => {
                                    db.close();
                                    cb2(err2);
                                });
                            }); 
                        },
                        function(errN) {
                            cb1(errN);
                        }
                    );
                },
            ], function(errX, r) {
                if (errX) {
                    console.log("[ERROR]gen union-data failed for ", errX);
                }else {
                    console.log("4 - update union-data ok !!!");
                }
            });
        }
    );
}

文章名称:仅378条数据居然导致合服失败?!-创新互联
路径分享:http://scjbc.cn/article/joshi.html

其他资讯