SLB 7层负载均衡“HUNG”问题追查
最近接到博客园的反馈,SLB 7层负载均衡的实例会不定期出现流量突跌的情况,突跌持续10s左右;同时,SLB自身监控也观察到了相同的现象;
针对该问题,我们进行了持续追查,最终定位到是nginx配置的原因;在此,分享一下分析排查过程,希望对大家使用nginx有所帮助;
问题描述
- SLB 7层负载均衡(nginx)流量会出现不定期的突跌,每次突跌持续10s左右;同时,每次突跌必然发生在 12点 或者 0点;
- 查看SLB实例流量图,发现 部分实例 在12点 和 0点 流量突增几十倍;
两个时间点吻合,初步推断是突增流量导致nginx异常,从而导致流量下跌;
分析过程
- 观察每台nginx流量,发现当前运行负载比较低,远远小于阈值;CPU/MEM/NET各项指标都不高;
- 通过抓包发现大量的 syn 包被丢弃重传;
从上述现象,怀疑是网络问题,但从协议栈/网卡/交换机多个层面排查,没有发现网络异常;
- 在 Nginx 的机器上 curl 服务的统计接口时也出现了请求被 hang 住的情况;- (突破点)
抓包发现即使是本机发起的请求也会出现 syn 包丢弃重传,从而基本可以确定不是网络的问题,而是我们ngnix有问题。
查看linux协议栈源码,引起 syn 包被丢弃的原因可能有以下两点:
1. Accept backlog
(接收队列)满了
2.
内存分配不出来了
内核代码如下:
inttcp_v4_conn_request(struct
sock
*sk,
struct
sk_buff
*skb)
{
...
if
(sk_acceptq_is_full(sk)
&&
inet_csk_reqsk_queue_young(sk)
>
1)
{
NET_INC_STATS_BH(sock_net(sk),
LINUX_MIB_LISTENOVERFLOWS);
goto
drop;
}
req
=
inet_reqsk_alloc(&tcp_request_sock_ops);
if
(!req)
goto
drop;
...
}
机器内存是够用的,只能是 accept backlog 满掉了,
但是问题在于我们是给每一个 virtual ip 配置一个单独的 server { listen vip; }
的, 怎么会在 backlog 满的时候影响到其他业务的 virtual ip 呢?
我们再回到我们的 Nginx 的配置文件来:
http
{
server
{
listen 1.1.1.1:80
;
location /
{
return
200
"10.232.6.3:80";
}
}
server
{
listen 1.1.1.2:80
;
location /
{
return
200
"10.232.6.3:80";
}
}
server
{
listen 1.1.1.3:80
;
location /
{
return
200
"10.232.6.3:80";
}
}
...
server
{
listen 80
;
location /
{
return
200
"0.0.0.0:80";
}
}
}
深入了解 Nginx 的同学看到这里或许也就了然了。
但是我们拥有非常多的 virtual ip server 在配置文件中,一开始也并没有注意到最后一条 listen 80
的配置(该配置用于 nginx健康检查 和 状态统计)。
原因定位:Nginx 处理 bind listen 的时候会对监听的所有 ip:port
做一次规整合并,也就是由于最后一条 listen 80
导致 Nginx 在 listen 的时候只 bind 了一个 0.0.0.0:80
端口, 之后请求进入 Nginx 的时候会通过 ip 再来查找其对应的 virtual server。这也就导致了我们前面看到的结果,当有瞬时的大流量进来时引起 accept backlog 被占满,从而也影响了其他 virtual ip 的服务。
我们也可以在 Nginx 源码里看到这点:
void
ngx_http_init_connection(ngx_connection_t*c)
{
...
port
=
c->listening->servers;
if
(port->naddrs
>
1)
{
/*
* there are several addresses on this port and one of them
* is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
* is required to determine a server address
*/
if
(ngx_connection_local_sockaddr(c,
NULL,
0)
!=
NGX_OK)
{
ngx_http_close_connection(c);
return;
}
switch
(c->local_sockaddr->sa_family)
{
#if(NGX_HAVE_INET6)
case
AF_INET6:
sin6
=
(struct
sockaddr_in6
*)
c->local_sockaddr;
addr6
=
port->addrs;
/* the last address is "*" */
for
(i
=
0;
i
<
port->naddrs
-
1;
i++)
{
if
(ngx_memcmp(&addr6[i].addr6,
&sin6->sin6_addr,
16)
==
0)
{
break;
}
}
hc->addr_conf
=
&addr6[i].conf;
break;
#endif
default:
/* AF_INET */
sin
=
(struct
sockaddr_in
*)
c->local_sockaddr;
addr
=
port->addrs;
/* the last address is "*" */
for
(i
=
0;
i
<
port->naddrs
-
1;
i++)
{
if
(addr[i].addr
==
sin->sin_addr.s_addr)
{
break;
}
}
hc->addr_conf
=
&addr[i].conf;
break;
}
}
else
{
switch
(c->local_sockaddr->sa_family)
{
#if(NGX_HAVE_INET6)
case
AF_INET6:
addr6
=
port->addrs;
hc->addr_conf
=
&addr6[0].conf;
break;
#endif
default:
/* AF_INET */
addr
=
port->addrs;
hc->addr_conf
=
&addr[0].conf;
break;
}
}
/* the default server configuration for the address:port */
hc->conf_ctx
=
hc->addr_conf->default_server->ctx;
...
}
这里是在建立连接结构体时去查找所属 server,可以清晰的看到针对一个 listening 会有多个 server,也就是说这些 server 公用了一个 listen socket,以及 backlog。
问题解决
原因定位了,解决可以有多种方法;
我们采取的措施是把 listen 80
这条配置加上本地内网IP listen 172.168.1.1:80
,这样Nginx 会对每个 virtual ip 进行一次 bind 和 listen,从而做到了实例间的隔离,各个 virtual ip 之间不会互相影响;
也就不再出现当有一个 virtual ip 瞬时流量过大时导致整个服务看起来像是 hung 住的问题。
SLB 7层负载均衡“HUNG”问题追查的更多相关文章
- Azure上七层负载均衡APP Gateway
Azure的SLB和ILB是最常用的4层负载均衡工具.但有些场景是7层的负载均衡,SLB和ILB就无能为力了. Azure上已经推出了APP Gateway的服务,就是7层负载均衡的负载均衡器. 如上 ...
- 当Kubernets遇上阿里云 -之七层负载均衡(一).
我们知道Kubernetes的service只能实现基于4层的负载均衡,无法提供7层之上的许多特性,诸如基于URL的负载均衡,SSL支持,三方授权等等:Ingress可以实现七层负载均衡的许多功能,唯 ...
- nginx 七层负载均衡
[tcp] nginx 七层负载均衡 nginx负载均衡概述 当我们的Web服务器直接面向用户,往往要承载大量并发请求,单台服务器难以负荷,我使用多台Web服务器组成集群,前端使用Nginx负载均衡, ...
- 13、Nginx七层负载均衡
1.Nginx负载均衡基本概述 1.1为什么需要使用负载均衡 当我们的Web服务器直接面向用户,往往要承载大量并发请求,单台服务器难以负荷,我使用多台WEB服务器组成集群,前端使用Nginx负载均衡, ...
- Linux架构之Nginx 七层负载均衡
第50章 Nginx七层负载均衡 一.Nginx负载均衡基本概述 1)为什么要使用负载均衡 当我们的Web服务器直接面向用户,往往要承载大量并发请求,单台服务器难以负荷.使用多台Web服务器组成集群, ...
- 第十五章 nginx七层负载均衡
一.Nginx负载均衡 1.为什么做负载均衡 当我们的Web服务器直接面向用户,往往要承载大量并发请求,单台服务器难以负荷,我使用多台Web服务器组成集群,前端使用Nginx负载均衡,将请求分散的打到 ...
- 阿里云slb和ucloud负载均衡ulb添加ssl证书将http服务https化的配置详解
阿里云和ucloud服务器配置ssl证书将http服务https化的配置详解 项目背景: 苹果App于2017年1月1日将启用App Transport Security安全功能,即强制App通过HT ...
- Windows Azure支持七层负载均衡--Application Gateway
一直以来Windows Azure的负载均衡(Loadbalancer)功能一直被客户诟病,无法其竞争对手(特别是国内的云厂商)匹敌. Windows Azure的负载均衡器是四层的,前期的版本不支持 ...
- 大型网站系统架构实践(四)http层负载均衡之haproxy实践篇(一)
方案 上篇文章讲到了负载均衡的相关理论知识,这篇文章我打算讲讲实践方法以及实践中遇到的问题 方案:haproxy http层负载均衡 安装一个haproxy服务,两个web服务 haproxy:192 ...
随机推荐
- 08、Spark常用RDD变换
08.Spark常用RDD变换 8.1 概述 Spark RDD内部提供了很多变换操作,可以使用对数据的各种处理.同时,针对KV类型的操作,对应的方法封装在PairRDDFunctions trait ...
- jquery中$.ajax()方法使用详解
1.url 说明:发送请求的地址(默认为当前页面),要求是String类型的参数,比如是.net下,"~wexin(控制器)/getweinxinmenu(动作)", 2.type ...
- WannaCry勒索病毒卷土重来:日本本田工厂被迫关闭
6月22日消息,前阵子WannaCry勒索病毒席卷全球,世界各地网络遭到攻击.日前,偃旗息鼓了一阵的WannaCry勒索病毒又重回人们视线,迫使一家汽车厂在日本关闭. 路透社报道,本田Sayama工厂 ...
- LA 3938 动态最大连续和
题目链接:https://vjudge.net/contest/146667#problem/C 题意:动态的求一个区间的最大连续和. 分析: 看上去可以RMQ去做,但是,当分成两个部分,原来的部分的 ...
- Laravel5 构造器高级查询条件写法
<?php #DB 高级查询 // select * from table where A and B or C $all_data = DB::table("shopnc_goods ...
- 解决调用Office组件的问题
在修改一个之前工作的好好的工具的时候出了如下错误: 无法将类型为“System.__ComObject”的 COM 对象强制转换为接口类型“Microsoft.Office.Interop.Excel ...
- django ORM单表操作
1.ORM介绍 ORM是“对象-关系-映射”的简称 映射关系: mysql---------Python 表名----------类名 字段----------属性 表记录--------实例化对象 ...
- 【杂题总汇】NOIP2013(洛谷P1967) 货车运输
[洛谷P1967] 货车运输 重做NOIP提高组ing... +传送门-洛谷P1967+ ◇ 题目(copy from 洛谷) 题目描述 A国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道 ...
- Shell 入门笔记(一)
Shell简介 在开发过程中Linux系统经常接触和使用的,Shell 是我们用户使用 Linux 的桥梁,是C 语言编写的程序.Shell 是一种命令语言,同时一种程序设计语言.对大多数开发人员来说 ...
- webpack4 单独抽离打包 css 的新实现
webpack4 单独抽离打包 css 的新实现 前言 之前我们使用的打包 css 无非两种方式:① 将 css 代码打包进 入口 js 文件中:② 使用第三方插件(extract-text-webp ...