分布式服务框架之服务化最佳实践分布式服务框架之服务化最佳实践
编者按:InfoQ开设栏目“品味书香”,精选技术书籍的精彩章节,以及分享看完书留下的思考和收获,欢迎大家关注。本文节
选自李林锋著《分布式服务框架原理与实践》中的章节“服务化最佳实践”,对服务化之后面临的挑战进行分析,并给出解决方
案和业务最佳实践。
在服务化之前,业务通常都是本地API调用,本地方法调用性能损耗较小。服务化之后,服务提供者和消费者之间采用远程网
络通信,增加了额外的性能损耗,业务调用的时延将增大,同时由于网络闪断等原因,分布式调用失败的风险也增大。如果服
务框架没有足够的容错能力,业务失败率将会大幅提升。
除了性能、可靠性等问题,跨节点的事务一致性问题、分布式调用带来的故障定界困难、海量微服务运维成本增加等也是分布
式服务框架必须要解决的难题。本章节我们将对服务化之后面临的挑战进行分析,并给出解决方案和业务最佳实践。
1. 性能和时延问题
在服务化之前,业务通常都是本地API调用,本地方法调用性能损耗较小。服务化之后,服务提供者和消费者之间采用远程网
络通信,增加了额外的性能损耗:
1) 客户端需要对消息进行序列化,主要占用CPU计算资源。
2) 序列化时需要创建二进制数组,耗费JVM堆内存或者堆外内存。
3) 客户端需要将序列化之后的二进制数组发送给服务端,占用网络带宽资源。
4) 服务端读取到码流之后,需要将请求数据报反序列化成请求对象,占用CPU计算资源。
5) 服务端通过反射的方式调用服务提供者实现类,反射本身对性能影响就比较大。
6) 服务端将响应结果序列化,占用CPU计算资源。
7) 服务端将应答码流发送给客户端,占用网络带宽资源。
8) 客户端读取应答码流,反序列化成响应消息,占用CPU资源。
通过分析我们发现,一个简单的本地方法调用,切换成远程服务调用之后,额外增加了很多处理流程,不仅占用大量的系统资
源,同时增加了时延。一些复杂的应用会拆分成多个服务,形成服务调用链,如果服务化框架的性能比较差、服务调用时延也
比较大,业务服务化之后的性能和时延将无法满足业务的性能需求
1.1 RPC框架高性能设计
影响RPC框架性能的主要因素有三个。
1) I/O调度模型:同步阻塞I/O(BIO)还是非阻塞I/O(NIO)。
2) 序列化框架的选择:文本协议、二进制协议或压缩二进制协议。
3) 线程调度模型:串行调度还是并行调度,锁竞争还是无锁化算法。
1. I/O调度模型
在I/O编程过程中,当需要同时处理多个客户端接入请求时,可以利用多线程或者I/O多路复用技术进行处理。I/O多路复用技术
通过把多个I/O的阻塞复用到同一个select的阻塞上,从而使得系统在单线程的情况下可以同时处理多个客户端请求。与传统的
多线程/多进程模型比,I/O多路复用的最大优势是系统开销小,系统不需要创建新的额外进程或者线程,也不需要维护这些进
程和线程的运行,降低了系统的维护工作量,节省了系统资源。
JDK1.5_update10版本使用epoll替代了传统的select/poll,极大地提升了NIO通信的性能,它的工作原理如图1-1所示。
图1-1 非阻塞I/O工作原理