一次应用访问数据库 IP 配成外网 IP 引发的血案
2017-11-04 20:18
721 查看
我们生产的渠道对接系统出现大量推送运营商信息失败的现象。问题最终定位到 mongo 身上:
.00:03:05.425 [http-nio-9100-exec-53] ERROR c.d.r.s.i.CarrierOpRepServiceImpl -
存储运营商数据失败,Timeout waiting for a pooled item after 120000 MILLISECONDS;
nested exception is com.mongodb.MongoTimeoutException:
Timeout waiting for a pooled item after 120000 MILLISECONDS
org.apache.catalina.valves.ErrorReportValveinvoke(ErrorReportValve.java:79)
冰冻三尺非一日之寒,其实 mongo 的问题早已暴露出来:基本信息的推送经常出现超时,前边也已定位到 mongo 操作比较慢这里,推送的成败完全看 mongo 的心情。耽搁于其他事情一时没抽出时间来慎重处理,如今运营商信息推送大量失败忽然爆发,mongo 的问题不得不提前排上处理日程。
首先想到的当然是 mongo 的慢查询,但查看 mongo 日志,很少有超过 150 ms 的 sql 语句。
其次想到的是系统资源吃紧,比如 CPU、内存利用率过高,因为我们的那台机器上同时部署有 nginx、mongo、mysql、java 等。但这个只能说是硬件限制,换句话说,完全可以靠垂直扩展硬件来提升你的系统性能——只要你有足够的钱。但最大限度的利用硬件资源是每个系统设计师应尽的职责所在。
根据笔者的经验,任何恶劣的生产问题,始终会有一个始作俑者的点(问题的制造者),然后各种问题(如内存、CPU、I/O 以及其他,问题的受害者)集中爆发出来,然后系统运维人员被卷入其中而被各种乱象所惑而无从下手——笔者之前就碰到过一位资深 IT 处理这种问题的时候找不到要领所在,而去统计、处理各种问题受害者,完全南辕北辙了。生产事故发生时,作为处理人员应该保持头脑的冷静,综合分析找到问题的制造者,一击制敌。
再次,查看问题爆发时的 mongo 连接数,已上升至 100 多个,再往后受限于整个系统的内存情况无法再升,造成上述 Timeout waiting for a pooled item 等待问题。
最后,查看整个 mongo 库数据大小、出问题的 mongo 的那张表及索引空间大小,库大小 20 G,单表几百兆,索引不到表数据空间的一半。这种级别的数据量莫说 mongo,就是 mysql 也不会有任何问题。
综上总结信息:mongo 没有慢查询,大量连接将 mongo 连接数占满而迟迟不释放,大量操作在等待连接池以致超时造成无法存储的生产故障。
问题到了这里,大家应该能够分析的出问题出在 mongo 结果集传输上了——大量的大的对象的传输受限于带宽限制长久占据着 mongo 连接——该应用里的 mongo 存储的是一些大的基本信息、运营商报文,笔者在系统空闲时用 MongoChef (配外网 ip 访问)根据 id 查询一条基本信息就耗用了近半分钟,事实上该条 sql 的执行只是几个毫秒级别的。
去查看该应用的 spring data mongodb 连接池配置,果然配的是外网。修改为内网 IP 访问,问题应用而解,这才是峰值到来时 mongo 应有的表现:
.00:03:05.425 [http-nio-9100-exec-53] ERROR c.d.r.s.i.CarrierOpRepServiceImpl -
存储运营商数据失败,Timeout waiting for a pooled item after 120000 MILLISECONDS;
nested exception is com.mongodb.MongoTimeoutException:
Timeout waiting for a pooled item after 120000 MILLISECONDS
org.apache.catalina.valves.ErrorReportValveinvoke(ErrorReportValve.java:79)
冰冻三尺非一日之寒,其实 mongo 的问题早已暴露出来:基本信息的推送经常出现超时,前边也已定位到 mongo 操作比较慢这里,推送的成败完全看 mongo 的心情。耽搁于其他事情一时没抽出时间来慎重处理,如今运营商信息推送大量失败忽然爆发,mongo 的问题不得不提前排上处理日程。
首先想到的当然是 mongo 的慢查询,但查看 mongo 日志,很少有超过 150 ms 的 sql 语句。
其次想到的是系统资源吃紧,比如 CPU、内存利用率过高,因为我们的那台机器上同时部署有 nginx、mongo、mysql、java 等。但这个只能说是硬件限制,换句话说,完全可以靠垂直扩展硬件来提升你的系统性能——只要你有足够的钱。但最大限度的利用硬件资源是每个系统设计师应尽的职责所在。
根据笔者的经验,任何恶劣的生产问题,始终会有一个始作俑者的点(问题的制造者),然后各种问题(如内存、CPU、I/O 以及其他,问题的受害者)集中爆发出来,然后系统运维人员被卷入其中而被各种乱象所惑而无从下手——笔者之前就碰到过一位资深 IT 处理这种问题的时候找不到要领所在,而去统计、处理各种问题受害者,完全南辕北辙了。生产事故发生时,作为处理人员应该保持头脑的冷静,综合分析找到问题的制造者,一击制敌。
再次,查看问题爆发时的 mongo 连接数,已上升至 100 多个,再往后受限于整个系统的内存情况无法再升,造成上述 Timeout waiting for a pooled item 等待问题。
最后,查看整个 mongo 库数据大小、出问题的 mongo 的那张表及索引空间大小,库大小 20 G,单表几百兆,索引不到表数据空间的一半。这种级别的数据量莫说 mongo,就是 mysql 也不会有任何问题。
综上总结信息:mongo 没有慢查询,大量连接将 mongo 连接数占满而迟迟不释放,大量操作在等待连接池以致超时造成无法存储的生产故障。
问题到了这里,大家应该能够分析的出问题出在 mongo 结果集传输上了——大量的大的对象的传输受限于带宽限制长久占据着 mongo 连接——该应用里的 mongo 存储的是一些大的基本信息、运营商报文,笔者在系统空闲时用 MongoChef (配外网 ip 访问)根据 id 查询一条基本信息就耗用了近半分钟,事实上该条 sql 的执行只是几个毫秒级别的。
去查看该应用的 spring data mongodb 连接池配置,果然配的是外网。修改为内网 IP 访问,问题应用而解,这才是峰值到来时 mongo 应有的表现:
相关文章推荐
- 外网访问PG数据库,如何赋予IP访问权限
- NAT 通过NAT应用从外网 访问 内网数据库主机(端口映射)
- 内网ip映射到外网,利用80端口映射发布网站,利用全端口映射外网访问内网应用
- mysql数据迁移后,打开网站提示500----一次由ip addr引发的血案
- [IP端口映射]利用ip端口映射进行外网访问内网数据库
- 动态IP或无公网IP时外网访问内网固定端口管家婆等应用
- Mysql 开放特定外网IP远程访问数据库
- 记一次 k8s 集群单点故障引发的血案
- 限制特定IP访问数据库
- 一次数据库分表分库的真实场景应用
- 阿里云数据库开通内网连接后,外网访问连接内网数据库的实现
- SOAP在远程数据库访问中的应用
- 数据库应用-半结构化数据访问-2
- 新花生壳应用教程:外网访问内网ERP系统
- Tomcat服务器输入IP代替localhost外网不能访问的解决办法
- 从零开始部署Node.js服务至阿里云ECS服务器并实现外网IP访问
- 一次活动引发的血案
- linux 下允许外部ip访问你到mysql 数据库
- 服务器上发布的网站应用80端口时内网可以访问,外网不能访问
- sqlsever2005限指定IP访问数据库--登录触发器实现