记录一次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 ...
随机推荐
- php常用函数归纳
php常用函数归纳: /** * 截取指定长度的字符 * @param type $string 内容 * @param type $start 开始 * @param type $length 长度 ...
- ACM进阶之路
第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码, 因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打 出来. 3.大数(高精度)加减乘除 ...
- JavaScript 实现单例模式的两种方式
单例模式: 要求一个类只有一个实例化对象存在 这个实例化对象必须提供一个全局对外访问方式 这个实例化对象应当是私有的,不能被外界直接访问或者更改 方式1 get实现 唯一实例化:判断这个对象是否存在, ...
- Go之Cookie和Session
文章引用自 Cookie和Session Cookie和Session是Web开发绕不开的一个环节,本文介绍了Cookie和Session的原理及在Go语言中如何操作Cookie. Cookie Co ...
- Follow somebody
networkersdiary A personnel blog with Network Engineering articles https://networkersdiary.com/cisco ...
- IEEE 802.11r-2008
IEEE 802.11r-2008 or fast BSS transition (FT), also called fast roaming, is an amendment to the IEEE ...
- ANSYS热分析简介1
目录 1. ANSYS热分析简介 1.1 传导 1.2 热载荷分类 1.2.1 载荷施加 1.3 热分析分类 1.3.1 稳态热分析 1.3.2 瞬态热分析 1.3.3 非线性分析综述 2. 热分析单 ...
- Java中获取MongoDB连接的方法
首先是所需jar包,Maven中的配置如下: <dependency> <groupId>org.mongodb</groupId> <artifactId& ...
- 刚下载好的 vscode 不能运行,一片黑 以及终端不能输入 解决办法
1.鼠标右键vscode快捷方式点击属性,选择兼容性,勾选以兼容模式运行,下拉列表调整为windows vista (service pack 1)即可解决. 2.如果打开终端不能输入命令,首先点击属 ...
- vue.js ②
1.Vue实例的生命周期钩子 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等.同时在这个过程中也会运行 ...