Dubbo高级特性

本章主要内容:
• Dubbo高级特性概述;
• Dubbo高级特性原理。

2服务分组和版本
Dubbo中提供的服务分组和版本是强隔离的, 如果服务指定了服务分组和版本, 则消费方调用也必须传递相同的分组名称和版本名称。

<dubbo:service interface="com.alibaba.pay.order.QueryService"
class="com.alibaba.pay.order.StableQueryService" version="1.0.0-stable"/>
<dubbo:service interface="com.alibaba.pay.order.QueryService"
class=Hcom.alibaba.pay.order.PerfomanceQueryService" version=,,2.0.0"/>
<dubbo:reference interface="com.alibaba・pay.order.QueryService"
version="1.0.0-stable,,/>
<dubbo:reference interface="com.alibaba.pay.order.QueryService"
version="2.0.0"/>

3参数回调
Dubbo支持异步参数回调, 当消费方调用服务端方法时, 允许服务端在某个时间点回调回客户端的方法。 在服务端回调到客户端时, 服务端不会重新开启TCP连接, 会复用已经建立的从客户端到服务端的TCP连接。
4隐式参数
Dubbo服务提供者或消费者启动时, 配置元数据会生成URL, 一般是不可变的。 在很多实际的使用场景中, 在服务运行期需要动态改变属性值, 在做动态路由和灰度发布场景中需要这个特性。 Dubbo框架支持消费方在RpcContext#setAttachment方法中设置隐式参数, 在服务端
RpcContext#getAttachment方法中获取隐式传递。
当客户端发起调用前, 设置隐藏参数, 框架会在拦截器中把当前线程隐藏参数传递到Rpclnvocation的attachment中, 服务端在拦截器中提取隐藏参数并设置到当前线程RpcContext中。 隐式传参的详细原理如图9-1所示

5异步调用
在客户端实现异步调用非常简单,在消费接口时配置异步标识, 在调用时从上下文中获取Future对象, 在期望结果返回时再调用阻塞方法Future.get()即可。 

代码清单9・8客户端异步调用
fooService.findFoo(fooId); <— — 触发异步调用
Future<Foo> fooFuture = RpcContext.getContext().getFuture(); <— —
在发起其他RPC调用时, 先获取Future引用, 当结果返回后, 会被通知和设置到此Future
Foo foo = fooFuture.get();
// ...客户端非阻塞处理其他任务
如果foo已返回, 则直接获取返回值, 否则当前线程会被阻塞并等待
代码清单9-9消费方配置异步标识
< !--名略其他消费方配置-->
<dubbo:reference id="fooService" interface="com.alibaba・foo・ FooService"
async="true"/>

站在Dubb。 客户端角度来说, 直接发起RPC调用端属于用户线程。 用户线程①发起任意远程方法调用, 最终会通过I/O线程发送网络报文。 在真实发送报文前会在用户线程中设置当前异步请求Future (③)。 因此在用户线程发起下一个远程方法调用前, 需要先保存异步Future对象(④)o Dubbo框架会把异步请求对象保存在DefaultFuture类中, 当服务端响应或超时时,被挂起的用户线程将被唤醒(⑤)。 用户线程设置异步Future对象的逻辑在
Dubbolnvoker#dolnvoke方法中完成, 感兴趣的读者可以参阅Dubbolnvoker中对应的源码实现。
 

7上下文信息
Dubbo上下文信息的获取和存储同样是基于JDK的ThreadLocal实现的。 上下文中存放的是当前调用过程中所需的环境信息。 RpcContext是一个ThreadLocal的临时状态记录器, 当收到或发送RPC时, 当前线程关联的RpcContext状态都会变化。

代码清单9-11服务端上下文的获取和使用
public class DemoServicelmpl implements DemoService {
public void hello() {
boolean isProviderSide = RpcContext.getContext().isProviderSide();
// 本端是否为提供端, 这里会返回true|
String clientIP = RpcContext.getContext().getRemoteHost(); 

String application = RpcContext.getContext().getUrl().getParameter
("application11);
yyyService.done(); 
boolean isProviderSide = RpcContext.getContext().isProviderSide();
} 此时本端变成消费端, 这里会返回false
}

8 Telnet 操作
目前Dubbo支持通过Telnet登录进行简单的运维, 比如查看特定机器暴露了哪些服务、 显示服务端口连接列表、 跟踪服务调用情况、 调用本地服务和服务健康状况等。
 

10 结果缓存
Dubbo框架提供了对服务调用结果进行缓存的特性, 用于加速热门数据的访问速度, Dubbo提供声明式缓存, 以减少用户加缓存的工作量。 因为每次调用都会使用JSON.toJSONString方法将请求参数转换成字符串, 然后拼装唯一的key,用于缓存唯一键。 如果不能接受缓存造成
的开销, 则谨慎使用这个特性。如果要使用缓存, 则可以在消费方添加如下配置:
<dubbo:reference cache="lru" .../>
LRU缓存策略是框架默认使用的, 因此我们会对它进行简单的说明。 它的原理比较简单, 缓存对应实现类是LRUCacheo缓存实现类LRUCache继承了 JDK的LinkedHashMap类,LinkedHashMap是基于链表的实现, 它提供了钩子方法removeEldestEntry,它的返回值用于判断每次向集合中添加元素时是否应该删除最少访问的元素。 LRUCache重写了这个方法,当缓存值达到1000时, 这个方法会返回true,链表会把头部节点移除。 链表每次添加数据时都会在队列尾部添加, 因此队列头部就是最少访问的数据(LinkedHashMap在更新数据时, 会把更新数据更新到列表尾部) 。
 

备注:文章参考《深入理解Apache Dubbo与实战》,作者:林琳,诣极

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值