软件架构发展背景
- 单体
- 垂直分层
- 分布式服务
- 流式计算
dubbo出现的基本需求点
- 服务变多带来的服务URL难以配置,F5负载均衡的单点故障
- 服务依赖关系变得复杂,难以描述
- 流量变大的情况下,服务的容量,机器数量等问题难以评估
dubbo架构及其特点
Architecture
- Provider
- Comsumer
- Registry
- Monitor
- Container
Features
主要有以下几大特点:
Connectivity, Robustness, Scalability and Upgradeability.
下面简单分析一下:
Connectivity
- Register只负责注册和查询服务地址,Provider和Consumer直连交互
- Monitor负责统计服务调用的次数以及执行二点时间,数据先放在提供者和消费者的内存里,一段时间统一发送给Monitor
- Provider向Register注册服务,并且把time-consuming的数据汇报给Monitor,不包括网络开销的时间
- Consumer从Registry获取服务提供者的列表,通过LB策略直接访问Provider,然后把time-consuming的数据汇报给Monitor,包括网络开销
- Register, Provider 和 Consumer之间都是长连接,Moniter 是一个异常。
- Register 通过长连接知道Provider 还活着,如果Provider 下线了,Register会将事件推送给Consumer。
- 即使Register和Monitor 都挂掉了,也不会影响正在运行着的Provider 和Consumer ,因为Consumer 那有缓存着吧Providers 列表。
- Register and Monitor都是可选的,Consumer 可以直接和Provider 连接。
Robustness(健壮性)
- Monitor挂了不会影响到程序的运行,仅仅是丢失了一些采样数据
- 在数据库挂掉了的情况下,Register 依然可以通过检查自己缓存的方式来提供服务提供者的地址列表,但是新的Provider 将不能提供任何的服务。
- Register 是对等的集群,一个挂了会自动地原则另外一个。
- 即使所有的Register都挂了,Provider 和 Consumer依然可以通过本地缓存进行通信。
- Provider是无状态的,一个挂掉了不会影响其他的。
- 如果一个服务的所有Provider都挂掉了,Consumer将不能使用该服务,将无限重连等待服务Provider恢复。
Scalability(收缩性)
- Register 是对等集群,所以可以动态的添加实例,所有的客户端都会自动发现这些实例。
- Provider 是无状态的,可以自动的增加部署的实例,Register 也会自动将这些信息推送给Consumer。
Upgradeability(可升级性)
- 当服务集群进一步扩展,IT治理结构进一步升级时,需要进行动态部署,现有的分布式服务架构也是支持的,不会带来阻力。以下是未来可能的架构:
节点角色说明
节点 | 角色说明 |
---|---|
Deployer | 本地代理,可自动服务部署 |
Repository | 仓库,可存储应用程序包 |
Scheduler | 调度器,可根据访问压力自动增加或减少服务Provider |
Admin | 统一的管理控制台 |
Registry | 负责服务发现和配置 |
Monitor | 监控中心,统计服务调用次数和消费时长。 |
用法介绍
Spring configuration of local service
local.xml:
<bean id=“xxxService” class=“com.xxx.XxxServiceImpl” />
<bean id=“xxxAction” class=“com.xxx.XxxAction”>
<property name=“xxxService” ref=“xxxService” />
</bean>
Spring configuration of remote service
只需要对本地服务配置的方式进行少量改变即可
- 将local.xml分成俩部分,把服务定义的部分放到remote-privider.xml(在服务节点)同时把引用部分放到remote-consumer.xml(在消费节点)。
- 在服务提供者的配置中加上dubbo:service,在服务消费者的配置中加上dubbo:reference即可。
remote-provider.xml:
<!-- define remote service bean the same way as local service bean -->
<bean id=“xxxService” class=“com.xxx.XxxServiceImpl” />
<!-- expose the remote service -->
<dubbo:service interface=“com.xxx.XxxService” ref=“xxxService” />
remote-consumer.xml:
<!-- reference the remote service -->
<dubbo:reference id=“xxxService” interface=“com.xxx.XxxService” />
<!-- use remote service the same say as local service -->
<bean id=“xxxAction” class=“com.xxx.XxxAction”>
<property name=“xxxService” ref=“xxxService” />
</bean>