36

『互联网架构』软件架构-Dubbo调用模块(46)

 4 years ago
source link: https://idig8.com/2019/05/01/hulianwangjiagouruanjianjiagou-dubbodiaoyongmokuai46/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

之前说了RPC协议,RPC传输,终于到调用这块了,一步步走过来看的头都炸了,太艰辛了,上次主要说的就是线程之间的协作,业务线程池,IO线程池,重连线程池,心跳发送的线程池,调用重试的线程池。每个连接都有2个守护线程(心跳连接,重连接检测)。线程之前的协作:(客户端:调度线程,IO线程,结果Exchange线程)(服务端:IO线程,业务线程)

RzAnuaF.png!web

(一)Dubbo调用模块概述

dubbo调用模块核心功能是发起一个远程方法的调用并顺利拿到返回结果,其体系组成如下:

  1. 透明代理:通过动态代理技术,屏蔽远程调用细节以提高编程友好性。
  2. 负载均衡:当有多个提供者是,如何选择哪个进行调用的负载算法。
  3. 容错机制:当服务调用失败时采取的策略。
  4. 调用方式:支持同步调用、异步调用。
  5. 结果获取:指同步等待结果返回,还是异步通过回调通知获取结果。

YJfEjyj.png!web

  • 负载均衡

    >Dubbo 目前官方支持以下负载均衡策略

1.随机(random):按权重设置随机概率。此为默认算法。

2.轮循 (roundrobin):按公约后的权重设置轮循比率。

3.最少活跃调用数(leastactive):相同活跃数的随机,活跃数指调用前后计数差。

4.一致性Hash(consistenthash ):相同的参数总是发到同一台机器。

设置方式支持如下四种方式设置,优先级由低至高

<!-- 服务端级别-->
<dubbo:service interface="..." loadbalance="roundrobin" />
<!-- 客户端级别-->
<dubbo:reference interface="..." loadbalance="roundrobin" />
<!-- 服务端方法级别-->
<dubbo:service interface="...">
<dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:service>
<!-- 客户端方法级别-->
<dubbo:reference interface="...">
<dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:reference>
  • 容错

    >Dubbo 官方目前支持以下容错策略:

  1. 失败自动切换:调用失败后基于retries=“2” 属性重试其它服务器
  2. 快速失败:快速失败,只发起一次调用,失败立即报错。
  3. 勿略失败:失败后勿略,不抛出异常给客户端。
  4. 失败重试:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
  5. 并行调用: 只要一个成功即返回,并行调用指定数量机器,可通过 forks=”2″ 来设置最大并行数。
  6. 广播调用:广播调用所有提供者,逐个调用,任意一台报错则报错。

设置方式支持如下两种方式设置,优先级由低至高

<!-- 
failover 失败自动切换 retries="1" 切换次数
failfast 快速失败
failsafe 勿略失败
failback 失败重试,5秒后仅重试一次
forking 并行调用 forks="2" 最大并行数
broadcast 广播调用
-->
<dubbo:service interface="..." cluster="broadcast" />
<dubbo:reference interface="..." cluster="broadcast"/ >
  • 异步调用

    >异步调用是指发起远程调用之后获取结果的方式

  1. 同步等待结果返回
  2. 异步等待结果返回
  3. 不需要返回结果

FRrMb26.png!web

Dubbo 中关于异步等待结果返回的实现流程

zieaquU.png!web

异步调用配置

<dubbo:reference id="asyncDemoService"
interface="com.idig8.service.async.AsyncDemoService">
<!-- 异步调async:true 异步调用 false 同步调用-->
<dubbo:method name="sayHello1" async="true"/>
<dubbo:method name="sayHello2" async="false"/>
<!-- return="false" 不需要返回结果,直接返回-->
<dubbo:method name="notReturn" return="false"/>
</dubbo:reference>

异步调用结果获取

demoService.sayHello1("han");
Future<Object> future1 = RpcContext.getContext().getFuture();
demoService.sayHello2("han2");
Future<Object> future2 = RpcContext.getContext().getFuture();
Object r1 = null, r2 = null;
// wait 直到拿到结果 获超时
r1 = future1.get();
// wait 直到拿到结果 获超时
r2 = future2.get();
  • 过滤器

    >类似于 WEB 中的Filter ,Dubbo本身提供了Filter 功能用于拦截远程方法的调用。其支持自定义过滤器与官方的过滤器,以上配置 就是 为 服务提供者 添加 日志记录过滤器, 所有访问日志将会集中打印至 accesslog 当中

<dubbo:provider filter="accesslog" accesslog="E:\logs\dubbo.log"/>
````


* 泛化提供
>是指不通过接口的方式直接将服务暴露出去。通常用于Mock框架或服务降级框架实现。

``` java
public static void doExportGenericService() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("demo-provider");
// 注册中心
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("zookeeper");
registryConfig.setAddress("192.168.0.147:2181");
ProtocolConfig protocol=new ProtocolConfig();
protocol.setPort(-1);
protocol.setName("dubbo");
GenericService demoService = new MyGenericService();
ServiceConfig<GenericService> service = new ServiceConfig<GenericService>();
// 弱类型接口名
service.setInterface("com.tuling.teach.service.DemoService");
// 指向一个通用服务实现
service.setRef(demoService);
service.setApplication(applicationConfig);
service.setRegistry(registryConfig);
service.setProtocol(protocol);
// 暴露及注册服务
service.export();
}
  • 泛化引用

    >不通过常规接口的方式去引用服务,通常用于测试框架。

ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("demo-provider");
// 注册中心
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("zookeeper");
registryConfig.setAddress("192.168.0.147:2181");
// 引用远程服务
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
// 弱类型接口名
reference.setInterface("com.tuling.teach.service.DemoService");
// 声明为泛化接口
reference.setGeneric(true);
reference.setApplication(applicationConfig);
reference.setRegistry(registryConfig);
// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
GenericService genericService = reference.get();
Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"});
  • 隐示传参

    >是指通过非常方法参数传递参数,类似于http 调用当中添加cookie值。通常用于分布式追踪框架的实现。

//客户端隐示设置值
RpcContext.getContext().setAttachment("index", "1"); // 隐式传参,后面的远程调用都会隐
//服务端隐示获取值
String index = RpcContext.getContext().getAttachment("index");
  • 令牌验证

    >通过令牌验证在注册中心控制权限,以决定要不要下发令牌给消费者,可以防止消费者绕过注册中心访问提供者,另外通过注册中心可灵活改变授权方式,而不需修改或升级提供者

<!--随机token令牌,使用UUID生成--><dubbo:provider interface="com.idig8.BarService" token="true" />

qQbERnN.png!web

PS:dubbo毕竟是国人写的,很符合国人的口味,虽然dubbo有年头了,但是始终没有996icu的star多,这是为什么呢?实践的人少了,吹牛的人多啊。dubbo里面的一些细节感谢【国美】哥的爱心解答。另外感谢dubbo.io api的详细。

yaqI3iF.png!web

百度未收录

>>原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢!

>>原文链接地址:上一篇:

已是最新文章


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK