静态化配置
不妨回想一下,在Dubbo等微服务框架出现之前,一个模块调用另外一个模块通常的做法是使用一个配置文件,将服务提供的列表配置配置在配置文件中,客户端从按照配置文件中的列表进行沦陷。
其弊端也非常明显:如果需要调用的服务众多,配置文件会变得臃肿,对扩容缩容的管理、机器宕机等变更不友好,管理非常困难。
动态发现
通常基于注册中心实现服务的注册与动态发现,由于上文已详细介绍,在这里就不累述。
2.2 负载均衡客户端通过服务发现机制,能动态发现当前存活的服务提供者列表,接下来要考虑的是如果从服务提供者列表中选择一个服务提供者发起调用,这就是所谓的负载均衡,即 LoadBalance。
在Dubbo中默认提供了随机、加权随机、最少活跃连接、一致性Hash等负载均衡算法。
2.3 路由机制其实Dubbo中不仅提供了负载均衡机制,还提供了智能路由机制,这是实现Dubbo灰度发布的理论基础。
所谓的路由机制,是在服务提供者列表中,再设置一定的规则,进行过滤选择,负载均衡时只从路由过滤规则筛选出来的服务提供者列表中选择,为了更加形象的阐述路由机制的工作原理,给出如下示意图:
上述设置了一条路由规则,即查询机构ID为102的查询用户请求信息,请发送到新版本,即192168.3.102上,那主要在进行负载均衡之前先执行路由规则,从原始的服务提供者列表者按照路由规则进行过滤,从中挑选出符合要求的提供者列表,然后再进行负载均衡。
路由机制的核心理念:在进行负载均衡之前先对服务提供者列表运用路由规则,得出一个参与负载均衡的提供者列表。
2.4 故障转移远程服务调用通常涉及到网络等因素,客户端向服务提供者发起RPC请求调用时并不一定100%成功,当调用失败后该采用何种策略呢?
Dubbo提供了如下策略:
failover
失败后选择另外一台服务提供者进行重试,重试次数可配置,通常适合实现幂等服务的场景。
failfast
快速失败,失败后立即返回错误。
failsafe
调用失败后打印错误日志,返回成功,通常用于记录审计日志等场景。
failback
调用失败后,返回成功,但会在后台定时无限次重试,重启后不再重试。
forking
并发调用,收到第一个响应结果后返回给客户端。通常适合实时性要求比较高的场景,但浪费服务器资源,通常可以通过forks参数设置并发调用度。
Dubbo的通信线程模型入下图所示:
网络传输通常需要自定义通信协议,通常采用 Header + Body 的协议设计理念,并且 Header 长度固定,并且包含一个长度字段,用于记录整个协议包的大小。
网络传输为了提高传输效率,可以采取对传输数据进行压缩,通常是对 body 进行序列化与压缩。
Dubbo支持目前支持 java、compactedjava、nativejava、fastjson、fst、hessian2、kryo等序列化协议。
3.2 线程派发机制在Dubbo中默认会创建200个线程用于处理业务方法,所谓的线程派发机制就是IO线程如何决定何种请求转发到哪类线程中执行。
目前Dubbo中所有的心跳包、网络读写在IO线程中执行,无法通过配置进行修改。
Dubbo提供了如下几种线程派发机制(Dispatcher):
all
所有的请求转发到业务线程池中执行(除IO读写、心跳包)
message
只有请求事件在线程池中执行,其他在IO线程上执行。
connection
请求事件在线程池中执行,连接、断开连接事件排队执行(含一个线程的线程池)。
direct
所有请求直接在IO线程中执行。
温馨提示:有关线程模型,网络通信模式,可以参考笔者如下这篇文章。
线程派发机制之所有会有多种策略,主要是考虑线程切换带来的开销是否能容忍,即线程切换带来的开销小于多线程处理带来的提升。