@chendushuai
2019-03-08T11:35:47.000000Z
字数 5604
阅读 603
dubbo java

| 节点 | 角色说明 |
|---|---|
Provider |
暴露服务的服务提供方 |
Consumer |
调用远程服务的服务消费方 |
Registry |
服务注册与发现的注册中心 |
Monitor |
统计服务的调用次数和调用时间的监控中心 |
Container |
服务运行容器 |
Dubbo架构具有以下几个特点,分别是连通性、健壮性、伸缩性,以及向未来架构的升级性。
当服务集群规模进一步扩大,带动T治理结构进一步升级,需要实现动态部署,进行流动计算,现有分布式服务架构不会带来距离。下面是未来可能的一种架构:

| 节点 | 角色说明 |
|---|---|
Deployer |
自动部署服务的本地代理 |
Repository |
仓库用于存储服务应用发布包 |
Scheduler |
调度中心基于访问压力自动增减服务提供者 |
Admin |
统一管理控制台 |
Registry |
服务注册与发现的注册中心 |
Monitor |
统计服务的调用次数和调用时间的监控中心 |

/dubbo/com.foo.BarService/providers目录下写入自己的 URL 地址/dubbo/com.foo.BarService/providers目录下的提供者 URL 地址。并向/dubbo/com.foo.BarService/consumers目录下写入自己的 URL 地址/dubbo/com.foo.BarService目录下的所有提供者和消费者 URL 地址。<dubbo:registry check="false" />时,记录失败注册和订阅请求,后台定时重试<dubbo:registry username="admin" password="1234" />设置 zookeeper 登录信息<dubbo:registry group="dubbo" />设置 zookeeper 的根节点,不设置将使用无根树*号通配符<dubbo:reference group="*" version="*" />,可订阅服务的所有分组和所有版本的提供者阿里内部并没有采用 Zookeeper 做为注册中心,而是使用自己实现的基于数据库的注册中心,即:Zookeeper 注册中心并没有在阿里内部长时间运行的可靠性保障,此 Zookeeper 桥接实现只为开源版本提供,其可靠性依赖于 Zookeeper 本身的可靠性。
因 2.0.8 最初设计的 zookeeper 存储结构不能扩充不同类型的数据,2.0.9 版本做了调整,所以不兼容,需全部改用 2.0.9 版本才行,以后的版本会保持兼容 2.0.9。2.2.0 版本改为基于 zkclient 实现,需增加 zkclient 的依赖包,2.3.0 版本增加了基于 curator 的实现,作为可选实现策略。
建议使用 2.3.3 以上版本的 zookeeper 注册中心客户端

使用 Redis 的 Key/Map 结构存储数据结构:
使用 Redis 的 Publish/Subscribe 事件通知数据变更:
调用过程:
Key:/dubbo/com.foo.BarService/providers下,添加当前提供者的地址Channel:/dubbo/com.foo.BarService/providers发送register事件Channel:/dubbo/com.foo.BarService/providers订阅register和unregister事件Key:/dubbo/com.foo.BarService/consumers下,添加当前消费者的地址register和unregister事件后,从Key:/dubbo/com.foo.BarService/providers下获取提供者地址列表Channel:/dubbo/*订阅register和unregister,以及subscribe和unsubsribe事件register和unregister事件后,从Key:/dubbo/com.foo.BarService/providers下获取提供者地址列表subscribe和unsubsribe事件后,从Key:/dubbo/com.foo.BarService/consumers下获取消费者地址列表Redis 是一个高效的 KV 存储服务器
从 2.1.0 版本开始支持
Redis 过期数据通过心跳的方式检测脏数据,服务器时间必须同步,并且对服务器有一定压力,否则过期检测会不准确
从 2.0.5 版本开始,dubbo 开始支持通过 telnet 命令来进行服务治理。
telnet localhost 20880
或者:
echo status | nc -i 1 localhost 20880
status命令所检查的资源也可以扩展,参见:扩展参考手册。
以下展示了 dubbo 内建的 telnet 命令的说明和用法,此外,telnet 命令还支持用户自行扩展,参见:Telnet 命令扩展。
lsls: 显示服务列表ls -l: 显示服务详细信息列表ls XxxService: 显示服务的方法列表ls -l XxxService: 显示服务的方法详细信息列表psps: 显示服务端口列表ps -l: 显示服务地址列表ps 20880: 显示端口上的连接信息ps -l 20880: 显示端口上的连接详细信息cdcd XxxService: 改变缺省服务,当设置了缺省服务,凡是需要输入服务名作为参数的命令,都可以省略服务参数cd /: 取消缺省服务pwdpwd: 显示当前缺省服务tracetrace XxxService: 跟踪 1 次服务任意方法的调用情况trace XxxService 10: 跟踪 10 次服务任意方法的调用情况trace XxxService xxxMethod: 跟踪 1 次服务方法的调用情况trace XxxService xxxMethod 10: 跟踪 10 次服务方法的调用情况countcount XxxService: 统计 1 次服务任意方法的调用情况count XxxService 10: 统计 10 次服务任意方法的调用情况count XxxService xxxMethod: 统计 1 次服务方法的调用情况count XxxService xxxMethod 10: 统计 10 次服务方法的调用情况invokeinvoke XxxService.xxxMethod({"prop": "value"}): 调用服务的方法invoke xxxMethod({"prop": "value"}): 调用服务的方法(自动查找包含此方法的服务)selectselect 1: 当 invoke 命令匹配到多个方法时使用,根据提示列表选择需要调用的方法statusstatus: 显示汇总状态,该状态将汇总所有资源的状态,当全部 OK 时则显示 OK,只要有一个 ERROR 则显示 ERROR,只要有一个 WARN 则显示 WARNstatus -l: 显示状态列表loglog debug: 修改 dubbo logger 的日志级别log 100: 查看 file logger 的最后 100 字符的日志helphelp: 显示 telnet 命帮助信息help xxx: 显示xxx命令的详细帮助信息clearclear: 清除屏幕上的内容clear 100: 清除屏幕上的指定行数的内容exitshutdownshutdown: 关闭 dubbo 应用shutdown -t 1000: 延迟 1000 毫秒关闭 dubbo 应用建议将服务接口、服务模型、服务异常等均放在 API 包中,因为服务模型和异常也是 API 的一部分,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)。
如果需要,也可以考虑在 API 包中放置一份 Spring 的引用配置,这样使用方只需在 Spring 加载过程中引用此配置即可。配置建议放在模块的包目录下,以免冲突,如:com/alibaba/china/xxx/dubbo-reference.xml。
服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。
服务接口建议以业务场景为单位划分,并对相近业务做抽象,防止接口数量爆炸。
不建议使用过于抽象的通用接口,如:Map query(Map),这样的接口没有明确语义,会给后期维护带来不便。
每个接口都应定义版本号,为后续不兼容升级提供可能,如:<dubbo:service interface="com.xxx.XxxService" version="1.0" />。
建议使用两位版本号,因为第三位版本号通常表示兼容升级,只有不兼容时才需要变更服务版本。
当不兼容时,先升级一半提供者为新版本,再将消费者全部升为新版本,然后将剩下的一半提供者升为新版本。
服务接口增加方法,或服务模型增加字段,可向后兼容,删除方法或删除字段,将不兼容,枚举类型新增字段也不兼容,需通过变更版本号升级。
各协议的兼容性不同,参见:服务协议
如果是完备集,可以用Enum,比如:ENABLE, DISABLE。
如果是业务种类,以后明显会有类型增加,不建议用Enum,可以用String代替。
如果是在返回值中用了Enum,并新增了Enum值,建议先升级服务消费方,这样服务提供方不会返回新值。
如果是在传入参数中用了Enum,并新增了Enum值,建议先升级服务提供方,这样服务消费方不会传入新值。
服务参数及返回值建议使用 POJO 对象,即通过setter, getter方法表示属性的对象。
服务参数及返回值不建议使用接口,因为数据模型抽象的意义不大,并且序列化需要接口实现类的元信息,并不能起到隐藏实现的意图。
服务参数及返回值都必须是传值调用,而不能是传引用调用,消费方和提供方的参数或返回值引用并不是同一个,只是值相同,Dubbo 不支持引用远程对象。
建议使用异常汇报错误,而不是返回错误码,异常信息能携带更多信息,并且语义更友好。
如果担心性能问题,在必要时,可以通过override掉异常类的fillInStackTrace()方法为空方法,使其不拷贝栈信息。
查询方法不建议抛出checked异常,否则调用方在查询时将过多的try...catch,并且不能进行有效处理。
服务提供方不应将 DAO 或 SQL 等异常抛给消费方,应在服务实现中对消费方不关心的异常进行包装,否则可能出现消费方无法反序列化相应异常。
不要只是因为是 Dubbo 调用,而把调用try...catch起来。try...catch应该加上合适的回滚边界上。
Provider 端需要对输入参数进行校验。如有性能上的考虑,服务实现者可以考虑在 API 包上加上服务 Stub 类来完成检验。