“微服务高速公鹿” | 微服务高速通信设计

本文深入探讨了华为开源微服务框架ServiceComb在通信处理方面的优化策略,特别是在同步模式下,通过改进单连接和多连接模型,以及优化服务提供者端的线程池管理,实现了高性能和高可靠的微服务通信。

开卷有益,点击蓝字关注哟

2

0

1

8

 企业应用微服务化的思考

近年来越来越多的企业开始实践微服务,而微服务在企业应用落地的过程,面临着微服务开发框架的选型,无论是自研还是选择第三方框架都不得不考虑的问题包括:

微服务框架是否具备高可靠性,任何时间不能中断业务;

微服务框架是否能够实现高速通信性能,保证业务从单体架构向微服务架构切换时,能满足微服务业务的诉求。

本文从服务管理中心、通信处理两个模块来介绍华为开源微服务框架SeviceComb如何帮助企业应用快速具备高性能的通信能力以及高可靠的服务管理能力。

上篇介绍ServiceComb的服务管理中心设计:微服务|打造企业级微服务开发框架(上)

本篇将详细介绍ServiceComb的通信处理。

整体介绍

ServiceComb的底层通信框架依赖Vert.x.vertx标准工作模式为高性能的reactive模式,其工作方式如下图所示:

图1 reactive模式工作方式

业务逻辑直接在eventloop中执行,整个业务流程中没有线程切换,所有的等待逻辑都是异步的,只要有任务,则不会让线程停下来,充分、有效地利用系统资源。

vertx生态中包含了业界常用各种组件的reactive封装,包括jdbc、zookeeper、各种mq等等。但是reactive模式对业务的要求相当高,业务主流程中不允许有任何的阻塞行为。因此,为了简化上层业务逻辑,方便开发人员的使用,在Vertx之上提供同步模式的开发接口还是必不可少的,例如:

  • 各种安全加固的组件,只提供了同步工作模式,比如redis、zookeeper等等

  • 一些存量代码工作于同步模式,需要低成本迁移

  • 开发人员技能不足以控制reactive逻辑

所以ServiceComb底层基于vertx,但在vertx之上进行了进一步封装,同时支持reactive及同步模式。

工作于Reactive模式时,利用Vertx原生的能力,不必做什么额外的优化,仅需要注意不要在业务代码中阻塞整个进程。

而同步模式则会遭遇各种并发性能问题。,本文描述同步模式下的各种问题以及解决方案。

RESTful流程中,连接由vertx管理,当前没有特别的优化,所以本文中,连接都是指highway流程中的tcp连接。

同步模式下的整体线程模型

图2 同步模式下的整体线程模型

  • 一个微服务进程中,为transport创建了一个独立的vertx实例

  • Eventloop是vertx中的网络、任务线程

  • 一个vertx实例默认的Eventloop数为:2 * Runtime.getRuntime().availableProcessors()

服务消费者端

在服务消费者端,主要需要处理的问题是如何更加高效地把请求推送到服务提供者上去,然后拿到服务提供者的返回信息。所以在这一端我们主要关注“如何更高效的发送数据”这个话题。

1

单连接模型最简单的单连接模型

图3 最简单的单连接模型

从模型图中,我们可以看到,所有的consumer线程,如果向同一个目标发送数据,必然产生资源竞争,此时实际的处理如下:

                              

Connection.send内部直接调用Vertx的socket.write(buf),是必然加锁互斥的。

这必然导致大量并发时,大多数consumer线程都无法及时地发送自己的数据。

Socket.write内部会调用netty的channel.write,此时会判断出执行线程不是eventloop线程,所以会创建出一个任务并加入到eventloop任务队列中,如果eventloop线程当前在睡眠态,则立即唤醒eventloop线程,异步执行任务。

这导致频繁的任务下发及线程唤醒,无谓地增加cpu占用,降低性能。

优化的单连接模型

图4 优化的单连接模型

在优化模型中:

  • 每个TcpClientConnection额外配备一个CAS消息队列

  • Connection.send不再直接调用vertx的write方法,而是:

    • 所有消息保存到CAS队列中,减少入队竞争

    • 通过原子变量判定,只有入队前CAS队列为空,才向eventloop下发write任务,唤醒eventloop线程

    • 在eventloop中处理write任务时,将多个请求数据包装为composite buffer,批量发送,减少进入os内核的次数,提高tcp发送效率。

代码参见:

        https://github.com/ServiceComb/ServiceComb-Java-Chassis/blob/master/foundations/foundation-vertx/src/main/java/io/servicecomb/foundation/vertx/client/tcp/TcpClientConnection.java

io.servicecomb.foundation.vertx.client.tcp.TcpClientConnection.packageQueue
io.servicecomb.foundation.vertx.client.tcp.TcpClientConnection.send(AbstractTcpClientPackage,long, TcpResponseCallback)

https://github.com/ServiceComb/ServiceComb-Java-Chassis/blob/master/foundations/foundation-vertx/src/main/java/io/servicecomb/foundation/vertx/tcp/TcpConnection.java

io.servicecomb.foundation.vertx.tcp.TcpConnection.write(ByteBuf)
io.servicecomb.foundation.vertx.tcp.TcpConnection.writeInContext()

进行此项优化后,在同一环境下测试2组数据,可以看到性能有明显提升(不同硬件的测试环境,数据可能差异巨大,不具备比较意义):

表1 单连接模型优化前后性能对比


TPS

Latency

(ms)

CPU

TPS

提升比例

Consumer

Producer

(新-旧)/旧

优化前

81986

1.22

290%

290%

77.31%

优化后

145369

0.688

270%

270%

2

多连接模型

在单连接场景下进行相应的优化后,我们发现其实还有更多的优化空间。因为在大多数场景中,实际机器配置足够高,比如多核、万兆网络连接、网卡支持RSS特性等。此时,需要允许一对consumer与producer之间建立多条连接来充分发挥硬件的性能。

图5 多连接模型

允许配置多个eventloop线程

在microservice.yaml中进行以下配置:

cse:
 highway:
   client:
     thread-count: 线程数
     server:
     thread-count: 线程数

Consumer线程与eventloop线程建立均衡的绑定关系,进一步降低consumer线程的竞争概率。

代码参见:

https://github.com/ServiceComb/ServiceComb-Java-Chassis/blob/master/foundations/foundation-vertx/src/main/java/io/servicecomb/foundation/vertx/client/ClientPoolManager.java

io.servicecomb.foundation.vertx.client.ClientPoolManager.findThreadBindClientPool()

优化后的性能对比:

表2 多连接下线程模型优化前后性能对比


TPS

Latency

(ms)

CPU

TPS

提升比例

Consumer

Producer

(新-旧)/旧

简单单连接*10

543442

0.919

2305%

1766%

72.81%

优化后

939117

0.532

1960%

1758%

每请求大小为1KB,可以看到万兆网的带宽接近吃满了,可以充分利用硬件性能。

(该测试环境,网卡支持RSS特性。)

服务提供者端

不同于服务消费者,服务提供者主要的工作模式就是等待消费者的请求,然后处理后返回应答的信息。所以在这一端,我们更加关注“如何高效的接收和处理数据”这件事情。

同步模式下,业务逻辑和IO逻辑分开,且根据“隔离仓”原则,为了保证整个系统更加稳定和高效地运行,业务逻辑本身也需要在不同隔离的区域内运行。而这些区域,就是线程池。所以构建服务提供者,就需要对线程池进行精细的管理。

下面是针对线程池的各种管理方式。

1

单线程池(ThreadPoolExecutor)

下图为将业务逻辑用单独的线程池实现的方式。在这种方式下,IO仍然采用异步模式,所有接到的请求放入队列中等待处理。在同一个线程池内的线程消费这个队列并进行业务处理。

图6 单线程池实现方式

在这种方式下,有以下瓶颈点:

  • 所有的eventloop向同一个BlockingQueue中提交任务

  • 线程池中所有线程从同一个BlockingQueue中抢任务执行

ServiceComb默认不使用这种线程池。

2

多线程池(ThreadPoolExecutor)

为规避线程池中Queue带来的瓶颈点,我们可以使用一个Executor将多个真正的Executor包起来。

图7 多线程池实现方式

  • Eventloop线程与线程池建立均衡的绑定关系,降低锁冲突概率

  • 相当于将线程分组,不同线程从不同Queue中抢任务,降低冲突概率

ServiceComb默认所有请求使用同一个线程池实例:io.servicecomb.core.executor.FixedThreadExecutor

FixedThreadExecutor内部默认创建2个真正的线程池,每个池中有CPU数目的线程,可以通过配置修改默认值:

servicecomb:
 executor:
   default:
     group: 内部真正线程池的数目
     thread-per-group: 每个线程池中的线程数

代码参见:

https://github.com/ServiceComb/ServiceComb-Java-Chassis/blob/master/core/src/main/java/io/servicecomb/core/executor/FixedThreadExecutor.java

3

隔离仓

业务接口的处理速度有快有慢,如果所有的请求统一在同一个Executor中进行处理,则可能每个线程都在处理慢速请求,导致其他请求在Queue中排队。

此时,可以根据业务特征,事先做好规划,将不同的业务处理按照一定的方式进行分组,每个组用不同的线程池,以达到隔离的目的。

图8 隔离仓

隔离仓的实现依托于ServiceComb灵活的线程池策略,具体在下一节进行描述。

4

灵活的线程池策略

ServiceComb微服务的概念模型如下:

图9 ServiceComb微服务概念模型

可以针对这3个层次进行线程池的配置,operation与线程池之间的对应关系,在启动阶段即完成绑定。

operation与线程池之间的绑定按以下逻辑进行:

  1. 查看配置项cse.executors.Provider.[schemaId].[operationId]是否有值:

    1. 如果有值,则将值作为beanId从spring中获取bean实例,该实例即是一个Executor

    2. 如果没有值,则继续尝试下一步

  2. 使用相同的方式,查看配置项cse.executors.Provider.[schemaId]是否有值

  3. 使用相同的方式,查看配置项cse.executors.default是否有值

  4. 以”cse.executor.groupThreadPool”作为beanId,获取线程池(系统内置的FixedThreadExecutor)

代码参见:

https://github.com/ServiceComb/ServiceComb-Java-Chassis/blob/master/core/src/main/java/io/servicecomb/core/executor/ExecutorManager.java

按以上策略,用户如果需要创建自定义的线程池,需要按以下步骤执行:

  1. 实现java.util.concurrent.Executor接口

  2. 将实现类定义为一个bean

  3. 在microservice.yaml中将线程池与对应的业务进行绑定

5

线程池模型总结

如上一节所述,在默认多线程池的基础上,CSE提供了更为灵活的线程池配置。“隔离仓”模式的核心价值是实现不同业务之间的相互隔离,从而让一个业务的故障不要影响其他业务。这一点在CSE中可以通过对线程池的配置实现。例如,可以为不同的operation配置各自独立的线程池。

另外,灵活性也带来了一定的危险性。要避免将线程池配置为前面提到的“单业务线程池”模式,从而为整个系统引入瓶颈点。

Apache ServiceComb自开源以来,秉持将“复杂扔给自己,将极简留给用户”的原则,诸多技术创新被证明对于微服务化行之有效,并先后获得云计算开源大会《2018 OSCAR 尖峰开源技术奖》和云计算标准和应用大会《中国优秀开源项目一等奖》,这些都离不开社区开源开发者们的共同努力,我们在此也非常欢迎各位感兴趣的读者前往开源社区和我们讨论切磋,甚至加入我们,希望此文可以给正在进行微服务方案实施的读者们一些启发。

往期精彩大放送

Go排坑:http.ServeMux意外重定向的问题分析

三分钟迁移Spring boot工程到Serverless

[良心推荐] 客户管理系统ServiceComb微服务化实战-PartI

【良心推荐】客户管理系统ServiceComb微服务化实战-PartII

【直播精彩回顾+开奖】当Netty大咖遇到ServiceComb首席committer 唇枪舌战为哪般?

长按添加小助手,加入我们


点击左下角“阅读原文”,给SeriveComb加个Star吧

内容概要:本文提出了一种基于非合作博弈理论的居民负荷分层调度模型,并结合双层鲸鱼优化算法(Two-level Whale Optimization Algorithm)进行高效求解,模型与算法均通过Matlab代码实现。研究针对电力系统中居民侧用电负荷的复杂调度问题,引入非合作博弈机制刻画各用户之间的利益竞争关系,实现负荷的分层优化分配;同时设计双层优化架构,上层优化资源配置,下层模拟用户自主决策行为,提升了模型的实用性与合理性。通过智能优化算法求解多层级、非凸非线性的博弈模型,有效提高了调度方案的收敛性与全局寻优能力,适用于现代智能电网中的需求侧管理与能源优化场景。; 适合人群:具备电力系统基础理论知识和Matlab编程能力,从事智能电网、能源优化调度、需求侧管理、博弈论应用等方向的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于居民区电力负荷的分层优化调度系统设计与仿真分析;②为非合作博弈在多主体能源系统建模中的应用提供方法论支持;③利用双层鲸鱼算法解决具有嵌套结构的复杂双层优化问题,提升求解效率与调度方案的可行性。; 阅读建议:建议读者结合提供的Matlab代码深入理解模型构建逻辑与算法实现流程,重点关注博弈模型的效用函数设计、纳什均衡求解思路以及双层优化结构的迭代机制,宜配合实际用电数据开展复现实验以验证模型有效性与鲁棒性。
内容概要:本文围绕基于自适应神经模糊推理系统(ANFIS)智能控制器的可再生能源微电网功率管理系统展开研究,结合Simulink仿真实现,深入探讨了微电网中功率的智能调控与经济机组组合调度问题。通过引入ANFIS控制器,有效应对风能、光伏等可再生能源出力的波动性与不确定性,提升系统运行的稳定性与电能质量。研究内容涵盖微电网多源协调控制策略、功率平衡管理、优化调度模型构建及仿真验证,实现了对分布式电源、储能系统和负荷的协同优化,兼顾经济性与可靠性目标,并通过仿真平台验证了所提方法的有效性与优越性。; 适合人群:具备电力系统、自动化或新能源相关专业背景,熟悉Matlab/Simulink仿真环境,从事微电网能量管理、智能控制、能源优化等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于高比例可再生能源接入场景下的微电网能量管理系统研发与教学实践;②为实现微电网功率稳定控制与经济高效运行提供先进的智能控制解决方案;③支撑高水平学术论文复现、科研课题攻关及实际工程项目的仿真验证与方案优化。; 阅读建议:建议结合提供的Simulink模型与相关代码进行动手实践,重点关注ANFIS控制器的设计流程、规则库构建与参数调优方法,并通过与传统PID或MPC控制策略的对比实验,深入理解其在动态响应与鲁棒性方面的优势。同时可进一步拓展文中提出的优化调度逻辑,应用于多目标、多约束的复杂实际应用场景中。
内容概要:本文档聚焦于“直流电机双闭环控制Matlab仿真”,系统阐述了基于Matlab/Simulink平台实现直流电机双闭环控制系统(主要包括速度环与电流环)的设计与仿真全过程。通过构建直流电机的数学模型,结合PI控制器进行调控,实现对电机转速和电枢电流的高精度动态控制,验证控制策略的稳定性与响应性能。文档详细介绍了仿真模型的搭建流程、关键参数的整定方法、系统动态波形的分析手段以及仿真结果的有效性验证,体现了经典自动控制理论在实际电机系统中的工程应用,是电机控制与电力电子技术相结合的典型研究案例。; 适合人群:具备自动控制原理、电机与拖动基础、电力电子技术和Matlab/Simulink仿真能力的电气工程、自动化、机电一体化等专业的本科生、研究生及从事电机驱动系统研发的工程技术人员。; 使用场景及目标:①作为高校课程设计或实验教学材料,帮助学生深入理解双闭环调速系统的工作机理与工程实现;②服务于科研项目,为新型电机控制算法(如滑模、模糊PID等)的开发与性能对比提供基础仿真验证平台;③作为工业界产品前期设计的仿真工具,用于评估不同控制策略在动态响应、抗干扰能力和稳态精度方面的可行性。; 阅读建议:建议读者在学习过程中紧密结合自动控制理论知识,亲手在Simulink环境中搭建完整的双闭环仿真模型,通过反复调整PI控制器的比例与积分参数,观察并分析转速、电流的阶跃响应曲线,从而深刻理解反馈控制的本质、系统稳定性条件以及参数整定对动态性能的影响,进而掌握电机控制系统的设计精髓。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值