文档章节

HAProxy高并发问题解决

强子大叔的码田
 强子大叔的码田
发布于 2015/06/24 22:30
字数 1335
阅读 4300
收藏 122

HAProxy现网问题解决

1问题描述

RMI上线后,现网的接口总是报告异常。

 

2问题分析

通过对RMI源码的理解,这个是在RMI客户端那边没有可用的连接时,需要创建一个新的连接,但是连接失败。

 

网络问题一般抓包可以定位,于是通过抓包发现失败的连接有个共同的现象,就是在5秒钟被HAProxy主动关闭,考虑到HAProxy的配置有个connectTimeout参数为5秒,应该是HAProxy连接后端的RMI服务器时失败。

 

通过抓包也验证了这一点,因为在5秒钟内,并没有搜到从HAProxy发起的对后端的SYN报文(除了check导致的握手)

 

于是大胆怀疑问题出在HAProxy这边,否则至少HAProxy应该发起主动连接才对。

此时猜测HAProxy没有拿到可用的服务器。

 

3 HAProxy定位

3.1 connect(...)

刚开始怀疑是HAProxy没有拿到可用的服务器,那么从哪里入手解决问题呢?

考虑到如果HAProxy如果需要对远程服务器建立连接的话,肯定需要调用connect(...)这个C语言的API,所以全文搜索connect(....)

 

在函数

中可以看到调用了connect(...)

 

3.2 tcpv4_connect_server的指定

查看tcpv4_connect_server的调用栈

 

 

上面这个代码是在event_accept函数中,也就是说在session中的client建立时,指定sessionserver端的connect函数,然后后面某个地方触发了tcpv4_connect_server函数。

 

3.3 tcpv4_connect_server的调用

到这里就很清楚了,通过调用connect_server函数,然后根据之前指定的连接函数来触发之,由于我们在3.2中指定了tcpv4_connect_server函数,所以触发它,tcpv4_connect_server函数中又调用了connect函数,所以需要跟踪connect_server函数。

 

3.4 connect_server的调用

查看调用栈,

通过类似的调用机制,尝试定位问题。

更详细的调用栈就不一一列出。

3.4 修改源码添加自定义日志

 

为了定位问题的准确性,修改HAProxy1.4.23】源码,在每一个session创建和后续行为都添加了自己的日志,同时每个日志行都添加了session的唯一ID.

这样就可以跟踪每个会话的具体行为。

 

日志格式如下:

 

3.5 srv_dynamic_maxconn

通过日志,我们发现,其实并不是HAProxy拿不到可用的服务器,而是拿到了之后,通过这个函数动态计算这个服务器当前的动态maxconn.

 跟踪下代码:

 

 

unsigned int srv_dynamic_maxconn(const struct server *s,struct session* session)

{

 

  

unsigned int max;

 

if (s->proxy->beconn >= s->proxy->fullconn)

{

/* no fullconn or proxy is full */

max = s->maxconn;

}

else if (s->minconn == s->maxconn)

{    

    /* static limit */

max = s->maxconn;

}

else 

{

       max = MAX(s->minconn,

       s->proxy->beconn * s->maxconn / s->proxy->fullconn);

 

}

 

if ((s->state & SRV_WARMINGUP) &&

    now.tv_sec < s->last_change + s->slowstart &&

    now.tv_sec >= s->last_change) {

unsigned int ratio;

ratio = 100 * (now.tv_sec - s->last_change) / s->slowstart;

max = MAX(1, max * ratio / 100);

}

return max;

}

于是在此段代码中添加日志,发现在蚂蚁窝环境下,每次此函数都返回1.

于是问题就知道出在什么地方了,这里返回1,导致每次对于某个后端服务器来说,

第一个请求建立连接会被响应,而后续的2,3.。。都被拒绝。

 

再查看日志,完全验证了这一点。

解决方案

既然知道了问题所在,那么怎么解决?

必然是通过此函数的逻辑来解决。

 

查看srv_dynamic_maxconn函数,发现如果在配置中可以有2种方法解决

minconn设置为较大的一个参数

2直接设置为minconnmaxconn一样,彻底去掉最小限制,对于并发量按照maxconn来配置。

 

针对第2种情况,代码中可以看到

也就是如果二者大小一样的话,max就返回s->maxconn。这样也没有问题。

 

HAProxy作者的邮件交流

既然是开源软件,那么就可以直接跟作者交流。

 

下面是跟作者的邮件交流。

5.1 发送邮件描述问题

5.2 对方回复

 

 

 

 

 

5.3 再次发送验证答案

于是发送自己的答案过去,看对方对我们的解决方案的评价,同时不忘热情赞美对方的软件之流行度。

 

 

5.4 对方的最终回应

也就是说,作者认为直接去掉minconn参数更好,于是我们在haproxy.cfg的配置中去掉了这个参数,通过日志打印,minconn的值会等于maxconn参数,也就是走了static limit这个分支。

至此问题得以解决,HAProxy的理解比之前更进一步。

 

后记

碰到问题,迎难而上,尤其是在有源码的情况下,直接debug或者看源码,肯定可以解决问题。一般在linuxc采用gdb,java采用jdb都可逐行跟踪,非常方便准确!

 

开源软件,网上有很多别人踩过的坑,可以尝试搜索是否已经有解决方案。

 

相对于所解决的问题,方法论非常重要,这个也需要经验的积累,比如本文中HAProxy问题的定位其实就在于connect(...) api的入口定位,整理出调用栈,然后添加日志逐步定位问题。

 

 

 

 

 

 

© 著作权归作者所有

强子大叔的码田

强子大叔的码田

粉丝 910
博文 1439
码字总数 1221048
作品 9
南京
架构师
私信 提问
加载中

评论(25)

强子大叔的码田
强子大叔的码田 博主

引用来自“穿林北腿蒋中正”的评论

======接上一条评论=====
So while the parameter names are not perfect, keep in mind that :
- minconn defines the limit when load is low
- maxconn defines the limit when load is high
- fullconn defines what a high load is

In general, I suggest you don't use that, otherwise you'll have in turn
to explain it to your coworkers :-)
嗯,不是bug,然后解决方案我在文中已经给出了,按照我文中的配置也是没问题的:)
穿
穿林北腿蒋中正
======接上一条评论=====
So while the parameter names are not perfect, keep in mind that :
- minconn defines the limit when load is low
- maxconn defines the limit when load is high
- fullconn defines what a high load is

In general, I suggest you don't use that, otherwise you'll have in turn
to explain it to your coworkers :-)
穿
穿林北腿蒋中正
强哥,作者的意思是 minconn要和fullconn一起配置使用,如果对其中动态计算机制机制不清楚的话,建议你去掉minconn。
倒真不是bug,我找到的资料如下,大致意思是haproxy会根据你配置的fullconn来判断backend是否达到了高负载,从而按比例线性的在minconn和maxconn中间浮动。
For such sites, we designed the dynamic connection regulation mechanism,
which involves minconn and fullconn.

minconn is in fact the maxconn to use under low loads. Fullconn defines
at what number of concurrent connections on the whole backend, we should
use the configured maxconn. And the progression between those two numbers
is linear.

So in your example above, under low loads your servers will run with a
100 connections limit (minconn). This limit will linearly increase, to
reach maxconn (1000) when the number of connections on the whole backend
reaches fullconn (10000). Above 10000, it remains at maxconn. That means
that if there are 5000 connections on your backend, your servers will be
running with a limit half-way between minconn and maxconn (550).

So while the parameter names are not perfect, keep in mind that :
- m
强子大叔的码田
强子大叔的码田 博主

引用来自“chuckpu”的评论

3q 对方是中国人吗
显然是外国人啊。 1 HAProxy软件直接在oschina上搜索会出来介绍的啊,法国人写的啊 2 邮件里有对方的邮件地址啊,不是中国的网址啊。。。
chuckpu
chuckpu
3q 对方是中国人吗
强子大叔的码田
强子大叔的码田 博主

引用来自“neo-chen”的评论

楼主钱途无量,我看好你。
承蒙夸奖
强子大叔的码田
强子大叔的码田 博主

引用来自“烟灰o_O”的评论

两个中国人用e文交流?
是啊,两个中国人的汉语不好,后来商量觉得还是用英语沟通比较顺畅,所以就用英语了,嗨。
强子大叔的码田
强子大叔的码田 博主

引用来自“harry_min”的评论

据说haproxy是中国人写的20
你的老板会为你感到自豪的
harry_min
harry_min
据说haproxy是中国人写的20
烟灰o_O
烟灰o_O
两个中国人用e文交流?
高可用高性能负载均衡软件HAproxy详解指南-第一章(简介、安装)

第一章:HAproxy简介及安装配置 对Linux有兴趣的朋友加入QQ群:476794643 在线交流 本文防盗链:http://zhang789.blog.51cto.com 目录 HAproxy简介 为什么要使用HAproxy haproxy 性能特点 负...

好笔记运维
2018/06/26
0
0
Web负载均衡解决方案 - HAproxy

HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点, 这些站点通常又需要会话保持...

匿名
2008/09/20
112.6K
9
HAproxy企业应用,TCP/HTTP动静分离

HAProxy的是一个免费的、开源的的tcp/http反向代理工具、负载均衡器,是一个企业非常快速和可靠的安全的解决方案,提供高可用性、高并发性,负载均衡和代理对TCP和基于HTTP的应用程序。它特别...

xiangyunyan
09/05
19
0
HAproxy企业应用动静分离

HAProxy的是一个免费的、开源的的tcp/http反向代理工具、负载均衡器,是一个企业非常快速和可靠的安全的解决方案,提供高可用性、高并发性,负载均衡和代理对TCP和基于HTTP的应用程序。它特别...

linux-tao
09/05
8
0
HAproxy 1.4.3 发布,Web负载均衡

该版本修正了一个可能因为使用了 Layer7 的哈希算法导致服务器宕机的bug;另外在配置的解析器上也进一步改进,还包括修正了其他一些小问题。建议升级。 HAProxy提供高可用性、负载均衡以及基...

红薯
2010/04/02
437
0

没有更多内容

加载失败,请刷新页面

加载更多

【jQuery基础学习】05 jQuery与Ajax以及序列化

本文转载于:专业的前端网站➭【jQuery基础学习】05 jQuery与Ajax以及序列化 好吧,这章不像上章那么水了,总是炒剩饭也不好。 关于AJAX 所谓Ajax,全名Asynchronous JavaScript and XML。(也...

前端老手
16分钟前
8
0
CVE-2019-14287(Linux sudo 漏洞)分析

作者:lu4nx@知道创宇404积极防御实验室 作者博客:《CVE-2019-14287(Linux sudo 漏洞)分析》 原文链接:https://paper.seebug.org/1057/ 近日 sudo 被爆光一个漏洞,非授权的特权用户可以...

极客君
17分钟前
4
0
关于分布式,你需要知道的真相

目录 一、分布式锁 数据库的唯一索引 Redis 的 SETNX 指令 Redis 的 RedLock 算法 Zookeeper 的有序节点 二、分布式事务 2PC 本地消息表 三、CAP 一致性 可用性 分区容忍性 权衡 四、BASE 基...

李红欧巴
17分钟前
5
0
读书笔记:深入理解ES6 (附录B)

附录B:了解ES7(2016)   ES6经历了4年的发展,之后TC-39决定将发布周期转换为每年一版,以确保新语言特性能够更快地发展。   ES6中添加了三个语法特性,下面一一来讲。 第1节 指数运算...

张森ZS
23分钟前
11
0
计算机公开课推荐 2019.8

欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 面试求职交流群 724187166 ApacheCN 学习资源 编程 哈佛 CS50:计算机科学导论 视频 MIT 6.00.1x:计算机科...

ApacheCN_飞龙
23分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部