资讯首页 新闻资讯 云计算测评 云服务商动态 技术频道
上云无忧 > 云计算资讯  > 技术频道 > Octavia API 接口慢问题排查引发的思考

Octavia API 接口慢问题排查引发的思考

发布时间: 2020-07-10 09:09:42|浏览量:311| 评论: 0

文本梳理了Octavia API接口访问慢问题的排查过程和解决方案,并对排查过程中涉及到的相关知识点进行了梳理,希望日后遇到类似的问题可以有所借鉴和参考。

Octavia API接口慢问题排查引发的思考

1、问题背景

Octavia是为openstack集群提供高可用的负载均衡解决方案,它对外提供REST API来创建业务访问的VIP,后端采用Haproxy+LVS来提供负载均衡服务,将业务请求自动分发给真实服务器。

在我们实际的使用中,Octavia对外提供的REST API接口的访问响应时间存在0.2s-50s之间的较大波动,造成VIP可能无法正常创建和查询。



Octavia服务架构



上图是我们Octavia服务使用的部署模式,通过keepalived vrrp实现高可用,haproxy后端挂载多个Octavia API服务节点。

2、问题排查过程

抓包

API接口访问慢,首先需要知道请求的时间具体消耗在哪个步骤。对接口的访问请求进行抓包,并观察请求过程中数据包的传输情况。由于接口请求较多,通过添加自定义头部信息对请求进行区分,并使用http header过滤抓包结果。发现时间消耗较长的请求,存在数据包重传现象。



分析

1)时间消耗

从抓包情况来看,client访问haproxy很快得到响应,时间消耗都在haproxy与octavia-api之间的交互,排除haproxy问题。

2)物理硬件/机器负载/网络抖动

查看服务器网卡不存在丢包和错包;haproxy与octavia-api都属于同一网段,也不存在网络抖动导致丢包;查看三台octavia-api机器负载不高,连接数等没有异常。

3)应用程序层面

从抓包现象上看,octavia-api没有响应syn或ack,查看9876端口连接情况。

netstat -s |grep -i listen  #发现两个数值都在增长

1173805 times the listen queue of a socket overflowed
1175909 SYNs to LISTEN sockets dropped
增长的两个数值涉及到server端在连接建立过程中的两个队列:

半连接队列(syn queue):用来保存处于SYN_SENT和SYN_RECV状态的请求。

队列大小:max_qlen = 2^max_qlen_log(linux-3.10.0)

全连接队列(accept queue):用来保存处于established状态,但是应用层没有调用accept取走的请求。

队列大小:min(backlog, net.core.somaxconn)

当server端在建立连接过程中,收到client发出的syn或者ack包时,都要对accept队列是否溢出进行判断,溢出则会引起以上两个数值的增长。

部署环境接口压力并不大,为何会引起accept队列溢出呢?通过ss命令来查看当前server端对应accept队列的大小。

ss -ntlp|grep 9876

LISTEN     6     5     10.145.69.9:9876                     *:*                   users:(("octavia-api",pid=10209,fd=4))


6和5分别表示Recv-Q和Send-Q,Recv-Q表示accept队列等待用户调用accept的完成3次握手的socket,Send-Q表示accept队列实际的大小。从数值看出,server端的accept队列确实存在溢出情况。

队列溢出后,server端如何处理此时收到的syn或者ack呢?由以下内核参数来决定:

/proc/sys/net/ipv4/tcp_abort_on_overflow


0表示直接丢弃ack,client会进行重传,重传次数根据内核参数tcp_synack_retries决定;1则直接发送rst将连接断开。

在测试环境将该值改为1后,请求被立即断开,证明重传server端队列溢出有关。

3、解决方案

确定是server端连接队列溢出导致重传后,需要修改accept队列的大小来解决。

第2部分中我们看到accept队列长度等于5,somaxconn默认为128,这说明octavia-api 服务端listen创建时传入的backlog值为5。该值过小,导致accept队列很容易就会溢出。

那么Octavia的backlog值来源于哪里呢?我们需要查看它代码的具体实现来找到答案。

octavia-api的启动逻辑中调用了wsgiref库中的simple_server.py中的make_server方法来创建这个WSGI server。具体逻辑如下:

simple_server.make_server(host, port, app) -> WSGIServer() -> server_bind -> BaseHTTPServer.HTTPServer.server_bind -> SocketServer.TCPServer.server_bind



图里看到SocketServer.TCPServer类中的server_activate方法listen函数传入的self.request_queue_size为固定值5,这就是octavia-api backlog值的来源。因此要改动该值,需要修改request_queue_size值的大小。

4、问题后续

经过一番排查确认并修改request_queue_size值大小后,查看octavia-api的backlog值已经为128。访问octavia-api发现数据包已无重传现象,accept队列无溢出,但访问速度仍然没有明显提升。

再次抓包发现连接正常,但octavia-api回包较慢,应该是应用层请求处理不过来导致。octavia-api只有单进程在处理请求,无法响应较多的接口调用。

结合openstack其他项目的处理方式,修改octavia-api WSGI server的创建方式。不再使用wsgiref库,改用openstack的oslo_service库来创建WSGI server,增加设置进程数的参数来设置octavia-api的进程个数(默认与cpu process个数相同),且oslo_service的WSGI server默认backlog值为128。经过此次修改后,接口响应速度提升至1s内。

另外,也可以使用httpd的mod_wsgi与Octavia配合部署提升其处理能力,毕竟wsgiref是官方给出的一个实现了WSGI标准用于演示用的简单Python内置库,并不建议在线上部署使用。

相关文章
https://www.cnblogs.com/Alexkk/p/12101950.html
http://jm.taobao.org/2017/05/25/525-1/
linux-3.10.0-957.27.2.el7内核源码

更多【技术频道】相关文章

有话要说

全部评论

暂无评论
官方微信
联系客服
400-826-7010
7x24小时客服热线
分享
  • QQ好友
  • QQ空间
  • 微信
  • 微博
返回顶部