专栏首页云计算与大数据工商银行分布式服务 C10K 场景解决方案

工商银行分布式服务 C10K 场景解决方案

作者:颜高飞,微服务领域架构师,主要从事服务发现、高性能网络通信等研发工作,擅长 ZooKeeper、Dubbo、RPC 协议等技术方向。

Dubbo 是一款轻量级的开源 Java 服务框架,是众多企业在建设分布式服务架构时的首选。中国工商银行自 2014 年开始探索分布式架构转型工作,基于开源 Dubbo 自主研发了分布式服务平台。

Dubbo 框架在提供方消费方数量较小的服务规模下,运行稳定、性能良好。随着银行业务线上化、多样化、智能化的需求越来越旺盛,在可预见的未来,会出现一个提供方为数千个、甚至上万个消费方提供服务的场景。

在如此高负载量下,若服务端程序设计不够良好,网络服务在处理数以万计的客户端连接时、可能会出现效率低下甚至完全瘫痪的情况,即为 C10K 问题。那么,基于 Dubbo 的分布式服务平台能否应对复杂的 C10K 场景?为此,我们搭建了大规模连接环境、模拟服务调用进行了一系列探索和验证。

C10K 场景下 Dubbo 服务调用出现大量交易失败

ALIWARE

1

准备环境

使用 Dubbo2.5.9(默认 netty 版本为 3.2.5.Final)版本编写服务提供方和对应的服务消费方。提供方服务方法中无实际业务逻辑、仅 sleep 100ms;消费方侧配置服务超时时间为 5s,每个消费方启动后每分钟调用1次服务。

准备 1 台 8C16G 服务器以容器化方式部署一个服务提供方,准备数百台 8C16G 服务器以容器化方式部署 7000 个服务消费方。

启动 Dubbo 监控中心,以监控服务调用情况。

2

定制验证场景,观察验证结果

操作步骤

观察内容

验证结果

场景 1

先启动服务提供方,后分批启动消费方

调用 1 小时观察交易情况

存在零星交易超时失败。消费方分散在多台服务器上。

场景 2

在服务正常调用一段时间后,重启提供方

观察提供方重启后的表现

在提供方重启后 1-2 分钟内存在大量交易超时失败,后逐渐恢复。消费方分散在多台服务器上。

验证情况不尽如人意。C10K 场景下 Dubbo 服务调用存在超时失败的情况。

如果分布式服务调用耗时长,从服务消费方到服务提供方全链路节点都会长时间占用线程池资源,增加了额外的性能损耗。而当服务调用并发突增时,很容易造成全链路节点堵塞,从而影响其他服务的调用,并进一步造成整个服务集群性能下降甚至整体不可用,导致发生雪崩。服务调用超时问题不可忽视。因此,针对该 C10K 场景下 Dubbo 服务调用超时失败情况我们进行了详细分析。

C10K场景问题分析

ALIWARE

根据服务调用交易链路,我们首先怀疑交易超时是因为提供方或消费方自身进程卡顿或网络存在延迟导致的。

因此,我们在存在交易失败的提供方、消费方服务器上开启进程 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:提供方实际交易前后均耗时长、导致交易超时

细化收集提供方的运行状态及性能指标:

1、在提供方服务器上每隔 3s 收集服务提供方 jstack,观察到 netty worker 线程每 60s 左右频繁处理心跳。

2、同时打印 top -H,观察到占用 CPU 时间片较多的线程排名前 10 中包含 9 个 netty worker 线程。因提供方服务器为 8C,Dubbo 默认 netty worker 线程数为 9 个,即所有 9 个 netty worker 线程均较忙碌。

3、部署服务器系统性能采集工具 nmon,观察到 CPU 每隔 60 秒左右产生毛刺;相同时间网络报文数也有毛刺。

4、部署 ss -ntp 连续打印网络接收队列、发送队列中的数据积压情况。观察到在耗时长的交易时间点附近队列堆积较多。

5、Dubbo 服务框架中提供方和消费方发送心跳报文(报文长度为 17)的周期为 60s,与以上间隔接近。结合网络抓包,耗时长的交易时间点附近心跳包较多。

根据 Dubbo 框架的心跳机制,当消费方数量较大时,提供方发送心跳报文、需应答的消费方心跳报文将会很密集。因此,怀疑是心跳密集导致 netty 线程忙碌,从而影响交易请求的处理,继而导致交易耗时增加。

进一步分析 netty worker 线程的运行机制,记录每个 netty worker 线程在处理连接请求、处理写队列、处理 selectKeys 这三个关键环节的处理耗时。观察到每间隔 60s 左右(与心跳间隔一致)处理读取数据包较多、耗时较大,期间存在交易耗时增加的情况。同一时间观察网络抓包,提供方收到较多的心跳报文。

因此,确认以上怀疑。心跳密集导致 netty worker 线程忙碌,从而导致交易耗时增长。

场景 2:单边连接导致交易超时

1、分析单边连接产生的原因

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、分析单边连接影响范围

单边连接影响范围多为消费方首笔交易,偶发为首笔开始连续失败 2-3 笔。

建立为单边的连接下,交易非必然失败。三次握手全连接队列满后,若半连接队列空闲,提供方创建定时器向消费方重传 syn+ack,重传默认 5 次,重传间隔以倍数增长,1s..2s..4s.. 共 31s。在重传次数内,若全连接队列恢复空闲,消费方应答 ack、连接建立成功。此时交易成功。

在重传次数内,若全连接队列仍然忙碌,新交易到达超时时间后失败。

到达重传次数后,连接被丢弃。此后消费方发送请求,提供方应答 RST。后交易到达超时时间失败。

根据 Dubbo 的服务调用模型,提供方发送RST后,消费方抛出异常 Connection reset by peer,后断开与提供方的连接。而消费方无法收到当前交易的响应报文、导致超时异常。同时,消费方定时器每2s检测与提供方连接,若连接异常,发起重连,连接恢复。此后交易正常。

3

C10K 场景问题分析总结

总结以上造成交易超时的原因有两个:

1、心跳机制导致 netty worker 线程忙碌。在每个心跳任务中,提供方向所有 1 个心跳周期内未收发过报文的消费方发送心跳;消费方向所有 1 个心跳周期内未收发过报文的提供方发送心跳。提供方上所连接的消费方较多,导致心跳报文堆积;同时,处理心跳过程消耗较多 CPU,影响了业务报文的处理时效。

2、全连接队列容量不足。在提供方重启后该队列溢出,导致大量单边连接产生。单边连接下首笔交易大概率超时失败。

4

下一步思考

1、针对以上场景 1:如何能降低单个 netty worker 线程处理心跳的时间,加速 IO 线程的运行效率?初步设想了如下几种方案:

  • 降低单个心跳的处理耗时
  • 增加 netty worker 线程数,降低单个 IO 线程的负载
  • 打散心跳,避免密集处理

2、针对以上场景 2:如何规避首笔大量半连接导致的交易失败?设想了如下方案:

  • 增加 TCP 全连接队列的长度,涉及操作系统、容器、Netty
  • 提高服务端 accept 连接的速度

交易报文处理效率提升

ALIWARE

1

逐层优化

基于以上设想,我们从系统层面、Dubbo 框架层面进行了大量的优化,以提升 C10K 场景下交易处理效率,提升服务调用的性能容量。

优化内容包括以下方面:

具体涉及优化的框架层如下:

经对各优化内容逐项验证,各措施均有不同程度的提升,效果分别如下:

优化内容

优化效果

TCP 全连接队列扩容

提供方重启后交易超时失败现象消除

epoll 模型调整

提供方重启后全连接队列溢出次数明显降低,连接 accept 速度有所提升

心跳绕过序列化

提供方在心跳周期无 CPU 毛刺,CPU 峰值降低 20%消费方与提供方之间平均处理时差由 27ms 降低至 3ms前 99% 的交易耗时从 191ms 下降至 133ms

增加 Iothreads 线程数

将默认的 iothreads 线程数 9 调整为 20 后,消费方与提供方之间平均处理时差由 27ms 降低至 14ms前 99% 的交易耗时从 191ms 下降至 186ms

提供方心跳打散

从提供方网络抓包分析,心跳数据包的毛刺峰值从 1.5万/秒压降至 3000/秒

消费方心跳打散

从提供方网络抓包分析,心跳数据包几乎不再有毛刺峰

2

综合优化验证效果

综合运用以上优化效果最佳。在此 1 个提供方连接 7000 个消费方的验证场景下,重启提供方后、长时间运行无交易超时场景。对比优化前后,提供方 CPU 峰值下降 30%,消费方与提供方之间处理时差控制在 1ms 以内,P99 交易耗时从 191ms 下降至 125ms。在提升交易成功率的同时,有效减少了消费方等待时间、降低了服务运行资源占用、提升了系统稳定性。

3

线上实际运行效果

基于以上验证结果,中国工商银行在分布式服务平台中集成了以上优化内容。截至发文日期,线上已存在应用一个提供方上连接上万个消费方的场景。落地该优化版本后,在提供方版本升级、及长时间运行下均无异常交易超时情况,实际运行效果符合预期。

未来展望

ALIWARE

中国工商银行深度参与 Dubbo 社区建设,在 Dubbo 金融级规模化运用的过程中遇到了诸多技术挑战,为满足金融级高敏交易的苛刻运行要求,开展了大规模自主研发,并通过对 Dubbo 框架的扩展和定制持续提升服务体系的稳定性,以“源于开源、回馈开源”的理念将通用增强能力不断贡献至开源社区。

未来,我们将持续致力于 Dubbo 的金融级规模化应用,协同社区继续提升 Dubbo 的性能容量和高可用水平,加速金融行业数字化创新和转型及基础核心关键的全面自主可控。

逸仙电商Seata企业级落地实践

连续三年入围 Gartner 容器竞争格局,阿里云容器服务新布局首次公开

传统架构 vs 云原生架构,谈谈为什么我们需要云原生架构?

本文分享自微信公众号 - 黑洞日志(heidcloud)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-05-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 关于Nginx的一些你不得不知道的内容(基本介绍),内容比较多建议收藏哦

      因为Nginx在我们项目中的地位是越来越重要了,所以最近话时间整理了下Nginx的内容了,希望对各位小伙伴有帮助哦!

    用户4919348
  • 高性能网络编程(二):上一个10年,著名的C10K并发连接问题1、前言 2、学习交流3、C10K问题系列文章4、C10K问题的提出者5、C10K问题的由来6、技术解读C10K问题7、C10K问题的本质

    对于高性能即时通讯技术(或者说互联网编程)比较关注的开发者,对C10K问题(即单机1万个并发连接问题)应该都有所了解。“C10K”概念最早由Dan Kegel发...

    JackJiang
  • 高并发的那些事

    "高并发"对后台开发同学来说,既熟悉又陌生。熟悉是因为面试和工作经常会提及它。陌生的原由是服务器因高并发导致出现各位问题的情况少之又少。同时,想收获这方面的经验...

    猴哥yuri
  • 分布式场景下的ID生成解决方案

    在服务设计中,经常遇到的一个问题就是如何生成一个全局唯一的ID,例如订单号,流水号等。对于ID的要求主要有以下几点:

    码农架构
  • 腾讯云携手神州信息发布“金融分布式核心”联合方案

    6月24日,基于国内银行对以云为承载的全栈国产化IT系统的需求,腾讯云携手神州信息正式推出了“金融分布式核心”联合解决方案。双方采用开放平台技术-核心平台+云...

    腾讯云数据库 TencentDB
  • BATM面试Java岗:精选200+面试题及答案、6大重点规划和经验总结

    金九银十已经结束了,而每到年后,总会有很多人跳槽。可我发现一个奇怪的现象:那些跳槽的人,总是从一个坑,跳进令一个坑中。毕竟一年过去了,会的还是原来的知识,人的身...

    用户6659115
  • Linux服务端最大并发数是多少?

    思考几分钟,如果你可以有理有据地说出答案,那确实就不用再往下看了,关上手机去陪陪家人是个不错的选择。

    Bug开发工程师
  • Linux服务端最大并发数是多少?

    思考几分钟,如果你可以有理有据地说出答案,那确实就不用再往下看了,关上手机去陪陪家人是个不错的选择。

    用户6543014
  • 首批区块链信息备案中,除了BATJ外,还有哪些值得深挖亮点?

    近日,国家网信办官网发布第一批境内区块链信息服务备案编号。这是2019年2月15日《区块链信息服务管理规定》(以下简称《管理规定》)正式实施以来,国家互联网信息...

    区块链大本营
  • 星环科技陈祖峰:2017年金融行业大数据十大应用的趋势展望

    数据猿导读 过去的2016年可称之为“智能金融”元年。相比过去五年,以云计算、大数据、区块链为首的新兴技术创新全面渗透至金融业的方方面面,用科技手段解决供需矛盾...

    数据猿
  • 金融科技&大数据产品推荐:恒丰银行实时智能决策引擎

    恒丰银行实时智能决策引擎是恒丰银行业务策略管理解决方案的核心产品,该产品让策略业务人员轻松高效地配置出风控、反欺诈、实时营销等场景下实时、准实时的决策模型/规则...

    数据猿
  • 「方案」银行数字化转型难?送你4套解决方案赶紧用起来

    随着大数据时代的到来,金融银行的经营模式正在发生着深刻的变化:由过去单一的存贷汇服务向信息提供者、业务撮合者、财富管理者转变。

    BI最前线
  • 案例| 品钛在美递交上市申请,金融科技to B服务的典型样本

    美国东部时间7月16日,金融科技解决方案提供商品钛(PINTEC)向美国证券交易委员会(SEC)提交了首次公开招股(IPO)申请书,承销商包括高盛、德意志银行与...

    用户1310347
  • 微服务架构的分布式事务解决方案

    分布式事务是一个绕不过去的挑战!微服务架构本质上就是分布式服务化架构,微服务架构的流行,让分布式事务问题日益突出!尤其是在订单业务、资金业务等系统核心业务流程中...

    吴生
  • 微服务架构及分布式事务解决方案

    事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性:

    烂猪皮
  • Java微服务系统分布式事务解决方案

    分布式系统数据的强一致性、弱一致性和最终一致性可以通过Quorum NRW算法分析。

    JavaEdge
  • 微服务架构下分布式事务解决方案

    在微服务架构中,随着服务的逐步拆分,数据库私有已经成为共识,这也导致所面临的分布式事务问题成为微服务落地过程中一个非常难以逾越的障碍,但是目前尚没有一个完整通用...

    java乐园
  • 浙商银行数字化转型实践

    本文围绕浙商银行的转型之路,从反电信欺诈、外汇、区块链等业务场景出发,介绍了 TiDB 在浙商银行的应用情况,最后分享了浙商银行分布式数据中台即新数据中心建设的...

    PingCAP
  • 金融SaaS之市场规模、赛道和竞争要点 | 产业互联网的核心模式(下)

    ? 来源:金融科技微观察  作者:徐磊 ---- 在本文上篇,我们从云服务的交付形态着手,重点讨论了三个问题:XaaS(“X”-as-a-Service)的内...

    腾讯SaaS加速器

扫码关注云+社区

领取腾讯云代金券