作者 | 颜高飞
起源 | 阿里巴巴云原生公众号
Dubbo 是一款轻量级的开源 Java 服务框架,是泛滥企业在建设分布式服务架构时的首选。中国工商银行自 2014 年开始摸索分布式架构转型工作,基于开源 Dubbo 自主研发了分布式服务平台。
Dubbo 框架在提供方生产方数量较小的服务规模下,运行稳固、性能良好。随着银行业务线上化、多样化、智能化的需要越来越旺盛,在可预感的将来,会呈现一个提供方为数千个、甚至上万个生产方提供服务的场景。
在如此高负载量下,若服务端程序设计不够良好,网络服务在解决数以万计的客户端连贯时、可能会呈现效率低下甚至齐全瘫痪的状况,即为 C10K 问题。那么,基于 Dubbo 的分布式服务平台是否应答简单的 C10K 场景?为此,咱们搭建了大规模连贯环境、模仿服务调用进行了一系列摸索和验证。
C10K 场景下 Dubbo 服务调用呈现大量交易失败
1. 筹备环境
应用 Dubbo2.5.9(默认 netty 版本为 3.2.5.Final)版本编写服务提供方和对应的服务生产方。提供方服务办法中无理论业务逻辑、仅 sleep 100ms;生产方侧配置服务超时工夫为 5s,每个生产方启动后每分钟调用 1 次服务。
筹备 1 台 8C16G 服务器以容器化形式部署一个服务提供方,筹备数百台 8C16G 服务器以容器化形式部署 7000 个服务生产方。
启动 Dubbo 监控核心,以监控服务调用状况。
2. 定制验证场景,察看验证后果
验证状况不尽如人意。C10K 场景下 Dubbo 服务调用存在超时失败的状况。
如果分布式服务调用耗时长,从服务生产方到服务提供方全链路节点都会长工夫占用线程池资源,减少了额定的性能损耗。而当服务调用并发突增时,很容易造成全链路节点梗塞,从而影响其余服务的调用,并进一步造成整个服务集群性能降落甚至整体不可用,导致产生雪崩。服务调用超时问题不可漠视。因而,针对该 C10K 场景下 Dubbo 服务调用超时失败状况咱们进行了详细分析。
C10K 场景问题剖析
依据服务调用交易链路,咱们首先狐疑交易超时是因为提供方或生产方本身过程卡顿或网络存在提早导致的。
因而,咱们在存在交易失败的提供方、生产方服务器上开启过程 gc 日志,屡次打印过程 jstack,并在宿主机进行网络抓包。
1. 察看 gc 日志、jstack
提供方、生产方过程 gc 时长、gc 距离、内存应用状况、线程堆栈等无显著异样,临时排除 gc 触发 stop the world 导致超时、或线程设计不当导致阻塞而超时等猜测。
2. 针对两种场景下的失败交易进行察看
针对以上两种场景下的失败交易,别离察看网络抓包,对应有以下两种不同的景象:
针对场景 1:提供方稳固运行过程中交易超时
跟踪网络抓包及提供方、生产方交易日志。生产方发动服务调用申请发动后,在提供方端迅速抓到生产方申请报文,但提供方从收到申请报文到开始解决交易耗时 2s+。
同时,察看交易申请响应的数据流。提供方业务办法处理完毕后到向生产方发送回包之间也耗时 2s+,尔后生产方端迅速收到交易返回报文。但此时交易总耗时已超过 5s、超过服务调用超时工夫,导致抛出超时异样。
由此,判断导致交易超时的起因不在生产方侧,而在提供方侧。
针对场景 2:提供方重启后大量交易超时
服务调用申请发动后,提供方迅速收到生产方的申请报文,但提供方未失常将交易报文递交给应用层,而是回复了 RST 报文,该笔交易超时失败。
察看在提供方重启后 1-2 分钟内呈现大量的 RST 报文。通过部署脚本,在提供方重启后每隔 10ms 打印 established 状态的连接数,发现提供方重启后连接数未能迅速复原到 7000,而是通过 1-2 分钟后连接数才复原至失常数值。而在此过程中,逐台生产方上查问与提供方的连贯状态,均为 established,狐疑提供方存在单边连贯状况。
咱们持续别离剖析这两种异样场景。
场景 1:提供方理论交易前后均耗时长、导致交易超时
细化收集提供方的运行状态及性能指标:
- 在提供方服务器上每隔 3s 收集服务提供方 jstack,察看到 netty worker 线程每 60s 左右频繁解决心跳。
- 同时打印 top -H,察看到占用 CPU 工夫片较多的线程排名前 10 中蕴含 9 个 netty worker 线程。因提供方服务器为 8C,Dubbo 默认 netty worker 线程数为 9 个,即所有 9 个 netty worker 线程均较繁忙。
- 部署服务器零碎性能采集工具 nmon,察看到 CPU 每隔 60 秒左右产生毛刺;雷同工夫网络报文数也有毛刺。
- 部署 ss -ntp 间断打印网络接管队列、发送队列中的数据积压状况。察看到在耗时长的交易工夫点左近队列沉积较多。
- Dubbo 服务框架中提供方和生产方发送心跳报文(报文长度为 17)的周期为 60s,与以上距离靠近。联合网络抓包,耗时长的交易工夫点左近心跳包较多。
依据 Dubbo 框架的心跳机制,当生产方数量较大时,提供方发送心跳报文、需应答的生产方心跳报文将会很密集。因而,狐疑是心跳密集导致 netty 线程繁忙,从而影响交易申请的解决,继而导致交易耗时减少。
进一步剖析 netty worker 线程的运行机制,记录每个 netty worker 线程在解决连贯申请、解决写队列、解决 selectKeys 这三个关键环节的解决耗时。察看到每距离 60s 左右(与心跳距离统一)解决读取数据包较多、耗时较大,期间存在交易耗时减少的状况。同一时间察看网络抓包,提供方收到较多的心跳报文。
因而,确认以上狐疑。心跳密集导致 netty worker 线程繁忙,从而导致交易耗时增长。
场景 2:单边连贯导致交易超时
- 剖析单边连贯产生的起因
TCP 建设连贯三次握手的过程中,若全连贯队列满,将导致单边连贯。
全连贯队列大小由零碎参数 net.core.somaxconn 及 listen(somaxconn,backlog) 的 backlog 取最小值决定。somaxconn 是 Linux 内核的参数,默认值是 128;backlog 在创立 Socket 时设置,Dubbo2.5.9 中默认 backlog 值是 50。因而,生产环境全连贯队列是 50。通过 ss 命令(Socket Statistics)也查得全连贯队列大小为 50。
察看 TCP 连贯队列状况,证实存在全连贯队列溢出的景象。
即:全连贯队列容量有余导致大量单边连贯产生。因在本验证场景下,订阅提供方的生产方数量过多,当提供方重启后,注册核心向生产方推送提供方上线告诉,所有生产方简直同时与提供方重建连贯,导致全连贯队列溢出。
- 剖析单边连贯影响范畴
单边连贯影响范畴多为生产方首笔交易,偶发为首笔开始间断失败 2-3 笔。
建设为单边的连贯下,交易非必然失败。三次握手全连贯队列满后,若半连贯队列闲暇,提供方创立定时器向生产方重传 syn+ack,重传默认 5 次,重传距离以倍数增长,1s..2s..4s.. 共 31s。在重传次数内,若全连贯队列复原闲暇,生产方应答 ack、连贯建设胜利。此时交易胜利。
在重传次数内,若全连贯队列依然繁忙,新交易达到超时工夫后失败。
达到重传次数后,连贯被抛弃。尔后生产方发送申请,提供方应答 RST。后交易达到超时工夫失败。
依据 Dubbo 的服务调用模型,提供方发送 RST 后,生产方抛出异样 Connection reset by peer,后断开与提供方的连贯。而生产方无奈收到以后交易的响应报文、导致超时异样。同时,生产方定时器每 2s 检测与提供方连贯,若连贯异样,发动重连,连贯复原。尔后交易失常。
3. C10K 场景问题剖析总结
总结以上造成交易超时的起因有两个:
- 心跳机制导致 netty worker 线程繁忙。在每个心跳工作中,提供方向所有 1 个心跳周期内未收发过报文的生产方发送心跳;生产方向所有 1 个心跳周期内未收发过报文的提供方发送心跳。提供方上所连贯的生产方较多,导致心跳报文沉积;同时,解决心跳过程耗费较多 CPU,影响了业务报文的解决时效。
- 全连贯队列容量有余。在提供方重启后该队列溢出,导致大量单边连贯产生。单边连贯下首笔交易大概率超时失败。
4. 下一步思考
- 针对以上场景 1:如何能升高单个 netty worker 线程解决心跳的工夫,减速 IO 线程的运行效率?初步构想了如下几种计划:
- 升高单个心跳的解决耗时
- 减少 netty worker 线程数,升高单个 IO 线程的负载
- 打散心跳,防止密集解决
- 针对以上场景 2:如何躲避首笔大量半连贯导致的交易失败?构想了如下计划:
- 减少 TCP 全连贯队列的长度,波及操作系统、容器、Netty
- 进步服务端 accept 连贯的速度
交易报文解决效率晋升
1. 逐层优化
基于以上构想,咱们从零碎层面、Dubbo 框架层面进行了大量的优化,以晋升 C10K 场景下交易解决效率,晋升服务调用的性能容量。
优化内容包含以下方面:
具体波及优化的框架层如下:
经对各优化内容逐项验证,各措施均有不同水平的晋升,成果别离如下:
2. 综合优化验证成果
综合使用以上优化成果最佳。在此 1 个提供方连贯 7000 个生产方的验证场景下,重启提供方后、长时间运行无交易超时场景。比照优化前后,提供方 CPU 峰值降落 30%,生产方与提供方之间解决时差管制在 1ms 以内,P99 交易耗时从 191ms 降落至 125ms。在晋升交易成功率的同时,无效缩小了生产方等待时间、升高了服务运行资源占用、晋升了零碎稳定性。
3. 线上理论运行成果
基于以上验证后果,中国工商银行在分布式服务平台中集成了以上优化内容。截至发文日期,线上已存在利用一个提供方上连贯上万个生产方的场景。落地该优化版本后,在提供方版本升级、及长时间运行下均无异样交易超时状况,理论运行成果合乎预期。
将来瞻望
中国工商银行深度参加 Dubbo 社区建设,在 Dubbo 金融级规模化使用的过程中遇到了诸多技术挑战,为满足金融级高敏交易的刻薄运行要求,发展了大规模自主研发,并通过对 Dubbo 框架的扩大和定制继续晋升服务体系的稳定性,以“源于开源、回馈开源”的理念将通用加强能力一直奉献至开源社区。
将来,咱们将继续致力于 Dubbo 的金融级规模化利用,协同社区持续晋升 Dubbo 的性能容量和高可用程度,减速金融行业数字化翻新和转型及根底外围要害的全面自主可控。
作者简介
颜高飞,微服务畛域架构师,次要从事服务发现、高性能网络通信等研发工作,善于 ZooKeeper、Dubbo、RPC 协定等技术方向。
在 PC 端登录 start.aliyun.com 知口头手实验室,沉迷式体验在线交互教程。