# [Apache Dubbo](http://dubbo.apache.org) 高性能分布式RPC框架 👻 [start.dubbo.io](http://start.dubbo.io) > 好的微服务架构师一定是业务架构师,基于业务的建瓴,微服务设计三部曲,遵循自下而上的设计原则,即原子服务、服务组合和业务编排,避免系统之间出现混乱调用。 ### Test - startup zookeeper - mvn clean package - cd whatsmars-dubbo-provider/target - java -jar -Ddubbo.registry.address=zookeeper://127.0.0.1:2181 whatsmars-dubbo-provider.jar - cd whatsmars-dubbo-consumer/target - java -jar -Ddubbo.registry.address=zookeeper://127.0.0.1:2181 whatsmars-dubbo-consumer.jar ### User Guide - https://github.com/javahongxi/dubbo-samples - [Dubbo框架设计](https://github.com/javahongxi/whatsmars/wiki/Dubbo%E6%A1%86%E6%9E%B6%E8%AE%BE%E8%AE%A1) - 配置覆盖策略:java -D > xml > properties,properties适合全局配置。本地调试时,可利用此特性在 IDEA VM options 设置 -Ddubbo.registry.register=false (有id时为-Ddubbo.registry.xx.register=false) - 配置覆盖策略:reference method > service method > reference > service > consumer > provider - 启动时检查:dubbo:reference check="true" Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成 - 集群容错模式:默认 cluster="failover",其他 failfast,failsafe,failback,forking,broadcast - 负载均衡:默认 loadbalance="random",其他 roundrobin,leastactive,consistenthash - 线程模型:默认 + 如果事件处理的逻辑能迅速完成,并且不会发起新的 IO 请求,比如只是在内存中记个标识,则直接在 IO 线程上处理更快,因为减少了线程池调度。 + 但如果事件处理逻辑较慢,或者需要发起新的 IO 请求,比如需要查询数据库,则必须派发到线程池,否则 IO 线程阻塞,将导致不能接收其它请求。 + 如果用 IO 线程处理事件,又在事件处理过程中发起新的 IO 请求,比如在连接事件中发起登录请求,会报“可能引发死锁”异常,但不会真死锁。 + all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。 + message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在 IO 线程上执行。 - 直连提供者: - 只订阅(禁用注册): - 人工管理服务上下线: - 多协议: ```xml ``` - 多注册中心:略 - 服务分组,同一接口不同实现 ```xml ``` - 多版本,类似于服务分组 ```xml ``` - 分组聚合,按组合并返回结果 ```xml ``` - 结果缓存 ```xml ``` - 泛化引用 ```xml ``` ```java GenericService barService = (GenericService) applicationContext.getBean("barService"); Object result = barService.$invoke("sayHello", new String[] { "java.lang.String" }, new Object[] { "World" }); ``` - 回声测试,所有服务自动实现 EchoService 接口,只需将任意服务引用强制转型为 EchoService,即可使用 ```java // 远程服务引用 MemberService memberService = ctx.getBean("memberService"); EchoService echoService = (EchoService) memberService; // 强制转型为EchoService // 回声测试可用性 String status = echoService.$echo("OK"); assert(status.equals("OK")); ``` - 上下文信息
RpcContext 是一个 ThreadLocal 的临时状态记录器,当接收到 RPC 请求,或发起 RPC 请求时, RpcContext 的状态都会变化。比如:A 调 B,B 再调 C,则 B 机器上,在 B 调 C 之前,RpcContext 记录的是 A 调 B 的信息,在 B 调 C 之后,RpcContext 记录的是 B 调 C 的信息。 - 隐式参数 ```java // 隐式传参,后面的远程调用都会隐式将这些参数发送到服务器端,类似cookie,用于框架集成,不建议常规业务使用 RpcContext.getContext().setAttachment("index", "1"); xxxService.xxx(); // 远程调用 ``` - 本地伪装,通常用于降级:
如果服务的消费方经常需要 try-catch 捕获异常,请考虑改为 Mock 实现,并在 Mock 实现中 return null。 如果只是想简单的忽略异常,用mock="return null"即可 - 服务降级,向注册中心写入动态配置覆盖规则: ```java RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181")); // mock=force:return+null mock=fail:return+null registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=fail:return+null")); ``` - 延迟暴露 ```xml ``` - 并发控制,异步调用,本地调用,参数回调,事件通知 ... ### More - [《企业IT架构转型之道:阿里巴巴中台战略思想与架构实战》](https://book.douban.com/subject/27039508/) - [《亿级流量网站架构核心技术》](https://book.douban.com/subject/26999243/) `douban.com` - [《从Paxos到Zookeeper》](https://book.douban.com/subject/26292004/) `douban.com` - [《Netty权威指南》](http://e.jd.com/30186249.html) `e.jd.com`