记录一次Nginx使用第三方模块fair导致的线上故障排错
一、问题
今天发现有一台服务器的内存飙升,然后有预警,立即排查,发现该服务内存使用达到了 2G ,询问开发,当天是否有活动,被告知没有,登陆 Pinpoint 发现该服务是有两台机器,并且所有的访问都是到那台内存飙升的机器上面。这就很清楚了,是所有请求到一台服务器,导致的,我们查看那台没有收到任何请求的服务器上,发现服务是启动了,端口也在监听的。
启动日志:
2019-11-05 16:07:09.024 [main] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.061 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.062 [main] INFO o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2019-11-05 16:07:09.122 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 18096 (http)
二、故障排查
2.1 第一次排查(服务没有正常启动)
启动日志里面也没有任何异常的报错。我就以为服务是已经 启动了,可能是 Nginx 的问题,登陆到 Nginx 服务器进行查看 ,是配置了 fair 插件的,想着是不是 fair 判断 那台服务器内存不够就不把请求转发过去了,我们就把 fair 这个插件去除了。然后 Nginx reload 了一下(16.26这个时间)。不到 一分钟,我 Pinpoint 发现 有访问到这个服务器上了,心想难道真的是这个问题导致的,不可能啊,然后我回到我 控制台(幸好我有个 tail -f ),然后发现下面的,日志。 到底是 fair 导致的还是 启动没有成功导致的。后面查阅昨天发版日志,发现昨天发版后,下面后面那三行日志就一直没打印,也就是一直没启动成功,但是正常的服务的那个服务器是有后面三行日志的。
当时启动打印的
2019-11-05 16:07:09.024 [main] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.061 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.062 [main] INFO o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2019-11-05 16:07:09.122 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 18096 (http)
后面打印的
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
2019-11-05 16:26:53.473 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms
第一次排查结论
基于上面的情况,我们认为问题就是服务没有初始化成功,应该是由于服务器内存不足导致的。也可能是和 Tomcat 启动慢的原因是一致的。
2.2 第二次排查
再次排障后发现这个问题取决于 Nginx 与应用 两者。
场景
我们有另一个服务也部署在两个服务器上,一个服务器上启动后正常提供服务,另外一台服务一直没有接收到请求,也没有处理任何东西,日志如下:
当我们启动 spring boot 框架的服务后。日志出现了
2019-11-05 16:07:09.024 [main] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.061 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.062 [main] INFO o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2019-11-05 16:07:09.122 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 18096 (http)
一直停留在这个界面。
然后我们通过 模拟请求,也就是在服务器上通过 curl ip+port, 立马就打印出来日志。
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
2019-11-05 16:26:53.473 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms
第二次排查结论
第一就是出现在 Nginx 上,我们 Nginx 上使用了 fair 模块(github链接)。 fair 模块采用的不是负载均衡默认的轮询的均衡算法,而是可以根据页面大小、加载时间长短智能的进行负载均衡。
推测是fair 将其中一台服务器直接屏蔽掉了(也就是我们没有收到请求的机器),然后就把所有的请求发送到另外一台机器了。
怪异之处
屏蔽掉的服务器内存和CPU 都是正常状态(内存还有剩余),为什么会屏蔽掉它,fair模块算法是有什么问题?
-- 去监控下请求返回的时常,对比下另外一台。(对比后无异常,返回都在 1s 内)
- 为什么启动后接受了请求才会打印类似初始化的日志。
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
2019-11-05 16:26:53.473 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms
询问开发后: 得到答复:
2019-11-05 16:07:09.024 [main] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.061 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.062 [main] INFO o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2019-11-05 16:07:09.122 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 18096 (http)
上面的日志,就是表明已经启动了,web 容器 Tomcat 已经 ok了。可以正常提供服务。
那么下面那个日志是怎么回事?
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
2019-11-05 16:26:53.473 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms
原因是(开发告知): 这个是DispatcherServlet初始化,当第一个请求过来后,它才初始化。
三、总结
上述的故障最后的问题定位于 : Nginx 的 fair插件导致的问题,与服务本身没有任何关系,但是 fair插件的具体的问题没有去细究。
记录一次Nginx使用第三方模块fair导致的线上故障排错的更多相关文章
- nginx增加第三方模块
增加第三方模块 ============================================================ 一.概述nginx文件非常小但是性能非常的高效,这方面完胜ap ...
- nginx 的第三方模块ngx_http_accesskey_module 来实现下载文件的防盗链步骤(linux系统下)
nginx 的第三方模块ngx_http_accesskey_module 来实现下载文件的防盗链步骤(linux系统下),安装Nginx和HttpAccessKeyModule模块(参考LNMP环境 ...
- Debian 为nginx增加第三方模块
为nginx增加第三方模块需要重新编译nginx的,但是debian在安装nginx的时候做了很多事情,比如systemd,/etc/nginx/里的各种文件,所以我们最好在debian源代码包的基础 ...
- nginx 安装第三方 模块
查看nginx在安装时开启了哪些模块 如果你nginx是rpm包安装的,直接用如下命令nginx -V 如果你是源码包编译安装,假如你的安装路径是/usr/local/nginx,那么你可以使用: / ...
- nginx安装第三方模块的方法
nginx第三方模块安装方法: ./configure --prefix=/你的安装目录 --add-module=/第三方模块目录 以安装fair模块实例 下载fair安装包并解压 1.在未安装ng ...
- nginx安装第三方模块echo
要使用第三方模块ngx_echo的功能,请重新配置添加到nginx插件中 ##下载第三方模块 wget https://github.com/openresty/echo-nginx-module/a ...
- yum安装的Nginx添加第三方模块支持tcp
需求:生产有个接口是通过socket通信.nginx1.9开始支持tcp层的转发,通过stream实现的,而socket也是基于tcp通信. 实现方法:Centos7.2下yum直接安装的nginx, ...
- nginx 安装第三方模块(lua)并热升级
需求: nginx上将特定请求拒绝,并返回特定值. 解决办法: 使用lua脚本,实现效果. 操作步骤: 安装Luajit环境 重新编译nginx(目标机器上nginx -V 配置一致,并新增两个模块n ...
- nginx安装第三方模块
原已经安装好的nginx,现在需要添加一个未被编译安装的模块 举例说明:安装第三方的ngx_cache_purge模块(用于清除指定URL的缓存) nginx的模块是需要重新编译nginx,而不是像a ...
随机推荐
- 删除设备和驱动器中的PPS、百度云、360云盘图标
1.win+R,regedit打开注册表 2.找到 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MyCom ...
- acwing练习
220. 最大公约数 给定整数N,求1<=x,y<=N且GCD(x,y)为素数的数对(x,y)有多少对. GCD(x,y)即求x,y的最大公约数. 输入格式 输入一个整数N 输出格式 输出 ...
- Bug搬运工-CSCvi02106 :Cisco 2800, 3800, 1560 APs: when connected to a Cisco Switch CDP-4-DUPLEX_MISMATCH log is seen
Cisco 2800, 3800, 1560 APs: when connected to a Cisco Switch CDP-4-DUPLEX_MISMATCH log is seen CSCvi ...
- 日期相关类data,simpledataformat类
(1) (2)
- JSON parse error: default constructor not found. class java.time.YearMonth; nested exception is com.alibaba.fastjson.JSONException: default constructor not found. class java.time.YearMonth
java8新出的YearMonth可以方便的用来表示某个月.我的项目中使用springmvc来接收YearMonth类型的数据时发现 x-www-from-urlencoded 格式的数据可以使用&q ...
- yii2.0 验证码
首先我们在控制器里创建一个actions方法,用于使用yii\captcha\CaptchaAction <?php namespace app\controllers; use YII; us ...
- SpringCloud项目实战
在工作业余时间,自学了SpringCloud的基本组件:Eureka.Ribbo.Feign.Zuul.Config.Bus,是时候操练一下自己所学的这些知识了,记录一下自己的学习过程. 一.目录结构 ...
- SpringCloud全家桶学习之一阶段总结(一)
一.概述 前几篇小博客记录了我学习SpringCloud组件的过程,并与工作中所用的Dubbo框架做了一点比较,基本组件:Eureka.Ribbon.Hystrix.Feign.Zuul.Config ...
- 使用URLConnection获取页面返回的xml数据
public static void main(String[] args) throws Exception { String path="http://flash.weather.com ...
- oracle用户密码忘记怎么修改
安装完数据库很久不用常常会忘记其密码,碰到这种情况不要动不动就重装数据库,按其下方法修改即可. 一:忘记sys,system用户的密码 1,在开始菜单点击‘运行’,输入‘cmd’,打开命令提示窗口,输 ...