在测试Adhesive的时候发现一个Mongodb官方驱动1.1.0.4184比较严重的BUG

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 在测试Adhesive的时候发现,使用过一段时间后台之后,就会不能连接到数据库,查看日志发现报的错误大致是 connection refused because too many open connections: 819 通过mongostat查看连接数的确很夸张有近819个连接,尝试在启动的...

测试Adhesive的时候发现,使用过一段时间后台之后,就会不能连接到数据库,查看日志发现报的错误大致是

connection refused because too many open connections: 819

通过mongostat查看连接数的确很夸张有近819个连接,尝试在启动的时候指定最大连接数到10000,重新启动Mongodb这个问题似乎解决了

但是在刷新几下页面之后连接数串到了4000,以前在使用的过程中即使在线上非常大的压力情况下连接数也在50之内,几千的连接数还是第一次见到

首先想是不是程序问题引起的,因为在程序中我们的折线图一次需要进行100次左右的Count操作来得到每一个点的总数:

image

虽然在程序中使用了并行库但是在只有一条折线的情况下是单线程的,因此排除并行库问题

而且发现每一次刷页面连接数都会大幅上涨,根本没有回落的时候

这想到了是连接没有释放,经过查看官方文档知道并不需要在每次调用之后显式释放连接

写了一个最简单的程序来测试:

      static MongoServer server = MongoDB.Driver.MongoServer.Create("mongodb://192.168.129.172:20000/?slaveok=true");
        static void Main(string[] args)
        {
            while (true)
            {
                Console.ReadLine();
                var db = server.GetDatabase("qqtest");
                var col = db.GetCollection("test");
                try
                {
                    Console.WriteLine(col.Count());
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }

很明显,按一次回车,连接数涨1!但是奇怪的是,写入数据的Master却不会有这个问题,于是把连接字符串修改为Master的地址

mongodb://192.168.129.142:20000/

居然正常了,不管怎么按回车,或是循环几百次连接始终只增加了一个,说明连接复用了

至此,肯定是连接Slave的时候才会有这个问题,这问题也算是隐蔽。

当时的这个版本是直接从NuGet引用的,没有源代码,于是下载到1.1.0.4184的源代码调试

在调试后发现MongoServer.cs其中有一个方法:

 private void InstanceStateChanged(
            object sender,
            object args
        ) {
            lock (instances) {
                if (instances.Any(i => i.State == MongoServerState.Connected && i.IsPrimary)) {
                    // Console.WriteLine("Server state: Connected");
                    state = MongoServerState.Connected;
                    return;
                }

                if (settings.SlaveOk) {
                  if (instances.Any(i => i.State == MongoServerState.Connected && (i.IsSecondary || i.IsPassive))) {
                        // Console.WriteLine("Server state: Connected");
                        state = MongoServerState.Connected;
                        return;
                    }
                }

                if (instances.Any(i => i.State == MongoServerState.Connecting)) {
                    // Console.WriteLine("Server state: Connecting");
                    state = MongoServerState.Connecting;
                    return;
                }

                // Console.WriteLine("Server state: Disconnected");
                state = MongoServerState.Disconnected;
            }
        }

把注释语句去掉,看看运行的情况:

image

这个方法中会根据连接状态改变来改变服务器的状态,在连接上数据库之后,由于SlaveOk进入了黑体的语句,instances其中已经有一个状态是Connected的项了,但是由于i又不是IsSecondary也不是IsPassive,因此不能满足条件,直接变为了state = MongoServerState.Disconnected。也就是对于SlaveOk每次都是不能认为数据库已连接,每次都是重新连接!从图中可以看到,每次最后都转到了state = MongoServerState.Disconnected,其实应该是运行state = MongoServerState.Connected。我想这里作者的意思大概是为了增加一个SlaveOk的判断吧,而对于Slave的情况,IsSecondary和IsPassive都为false的,那么我把黑体代码改为如下:

 if (instances.Any(i => i.State == MongoServerState.Connected && (!i.IsPrimary))) {

再运行程序,发现这个问题解决了。。。再来看看运行情况:

image

这次就对了,在进行一次连接之后,后面的请求都没有再初始化一个连接

 

想到是否可以更新下客户端看看最新的客户端版本是否解决了这个问题,去官网下载了最新的1.3版本,发现没有了这个问题。那么我想看看作者是怎么修改的,查看这个文件的历史,在某一个历史中看到了这段代码的改动记录:

image

image

可以看到原先的这段判断被删除了,这下思路清晰很多了!直接进行对应状态的设置,SlaveOk的判断和状态的设置不在有关系。

分享此次排查问题的过程,抛砖引玉,提醒下大家在使用开源组件的时候需要小心测试。

作者: lovecindywang
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
11天前
|
数据采集 人工智能 自然语言处理
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
Midscene.js 是一款基于 AI 技术的 UI 自动化测试框架,通过自然语言交互简化测试流程,支持动作执行、数据查询和页面断言,提供可视化报告,适用于多种应用场景。
113 1
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
智能化软件测试:AI驱动的自动化测试策略与实践####
本文深入探讨了人工智能(AI)在软件测试领域的创新应用,通过分析AI技术如何优化测试流程、提升测试效率及质量,阐述了智能化软件测试的核心价值。文章首先概述了传统软件测试面临的挑战,随后详细介绍了AI驱动的自动化测试工具与框架,包括自然语言处理(NLP)、机器学习(ML)算法在缺陷预测、测试用例生成及自动化回归测试中的应用实例。最后,文章展望了智能化软件测试的未来发展趋势,强调了持续学习与适应能力对于保持测试策略有效性的重要性。 ####
|
2月前
|
机器学习/深度学习 数据采集 人工智能
探索AI驱动的自动化测试新纪元###
本文旨在探讨人工智能如何革新软件测试领域,通过AI技术提升测试效率、精准度和覆盖范围。在智能算法的支持下,自动化测试不再局限于简单的脚本回放,而是能够模拟复杂场景、预测潜在缺陷,并实现自我学习与优化。我们正步入一个测试更加主动、灵活且高效的新时代,本文将深入剖析这一变革的核心驱动力及其对未来软件开发的影响。 ###
|
3月前
|
存储 测试技术 数据库
数据驱动测试和关键词驱动测试的区别
数据驱动测试 数据驱动测试或 DDT 也被称为参数化测试。
43 1
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
探索软件测试的未来:AI 驱动的自动化测试方法
【5月更文挑战第29天】随着人工智能(AI)技术的不断发展和成熟,其在软件测试领域的应用也日益广泛。本文旨在探讨 AI 如何改变软件测试的面貌,特别是自动化测试方法。我们将分析当前自动化测试的挑战,并介绍 AI 如何提供解决方案,包括智能化测试用例生成、测试执行优化、以及结果分析等。通过实际案例研究,我们还将讨论 AI 在提高测试效率、减少错误和提升软件质量保障中的作用。最后,文章将预测 AI 在自动化测试领域的未来趋势,并提出对测试工程师的建议。
|
4月前
|
SQL 安全 测试技术
『软件测试6』bug一两是小事,但安全漏洞是大事!
该文章强调了在软件测试中识别与处理安全漏洞的重要性,并详细介绍了常见的安全测试类型、测试流程及使用的主要工具,帮助测试人员有效地检测和防止安全问题。
『软件测试6』bug一两是小事,但安全漏洞是大事!
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
AI驱动的自动化测试:提升软件质量的未来之路
【9月更文挑战第3天】AI驱动的自动化测试是提升软件质量的未来之路。它借助AI技术的力量,实现了测试用例的智能生成、测试策略的优化、故障预测与定位等功能的自动化和智能化。随着技术的不断进步和应用场景的不断拓展,AI驱动的自动化测试将在未来发挥更加重要的作用,为软件开发和运维提供更加高效、准确和可靠的解决方案。
|
6月前
|
Java 开发者 运维
开发与运维测试问题之OpenJDK官方还未正式发布Compact Object Headers如何解决
开发与运维测试问题之OpenJDK官方还未正式发布Compact Object Headers如何解决
45 1
|
5月前
|
机器学习/深度学习 人工智能 自然语言处理
探索软件自动化测试的未来:AI驱动的测试策略
【7月更文挑战第47天】 随着人工智能(AI)技术不断进步,其在软件测试领域的应用也日益广泛。本文将探讨如何整合AI技术与现有的自动化测试流程,提出一个面向未来的测试策略。文章重点分析了AI在测试用例生成、执行、结果分析和持续集成中的作用,同时预测了这种技术融合对测试工程师角色的影响,以及它如何提高软件测试的效率和准确性。