首页新闻动态正文

根据IP动态路由调用Dubbo服务【黑马java培训】

更新时间:2019年07月26日 10时45分37秒 来源:黑马程序员论坛



一、前言
前面我们探讨了如何获取某一个Dubbo的服务的提供者列表,本节我们探讨如何使用Dubbo的扩展,实现指定IP调用。
二、实现
在Dubbo中集群容错策略Cluster是SPI扩展接口,DUbbo框架提供了丰富的集群容错策略实现,本节我们就基于扩展接口实现指定IP调用功能。
首先我们实现扩展接口Cluster:
[Java] 纯文本查看 复制代码
public class MyCluster implements Cluster{
   @Override
   public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
       return new MyClusterInvoker(directory);
   }
}
然后我们看自己实现的MyClusterInvoker
[Java] 纯文本查看 复制代码
public class MyClusterInvoker<T> extends MyAbstractClusterInvoker<T> {



 public MyClusterInvoker(Directory<T> directory) {

     super(directory);

 }

@Override
 protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)
         throws RpcException {
     //1.查看是否设置了指定ip
     String ip = (String) RpcContext.getContext().get("ip");
     if (StringUtils.isBlank(ip)) {
         throw new RuntimeException("ip is blank ");
     }
     //2.检查是否有可用invoker
     checkInvokers(invokers,invocation);
     //3.根据指定ip获取对应invoker
     Invoker<T> invoked = invokers.stream().filter(invoker -> invoker.getUrl().getHost().equals(ip))
             .findFirst().orElse(null);
     //4.检查是否有可用invoker

     if(null == invoked) {

         throw new RpcException(RpcException.NO_INVOKER_AVAILABLE_AFTER_FILTER,

                 "Failed to invoke the method " + invocation.getMethodName() + " in the service "

                         + getInterface().getName() + ". No provider available for the service "

                         + directory.getUrl().getServiceKey() + " from ip " + ip + " on the consumer "

                         + NetUtils.getLocalHost() + " using the dubbo version " + Version.getVersion()

                         + ". Please check if the providers have been started and registered.");

    }

     //5.发起远程调用,失败则抛出异常

     try {
         return invoked.invoke(invocation);

     } catch (Throwable e) {

         if (e instanceof RpcException && ((RpcException) e).isBiz()) { // biz exception.

             throw (RpcException) e;

         }

         throw new RpcException(e instanceof RpcException ? ((RpcException) e).getCode() : 0,
                 "Fail invoke providers " + (invoked != null?invoked.getUrl():"")+ " " + loadbalance.getClass().getSimpleName()
                         + " select from all providers " + invokers + " for service " + getInterface().getName()
                         + " method " + invocation.getMethodName() + " on consumer " + NetUtils.getLocalHost()
                         + " use dubbo version " + Version.getVersion()
                         + ", but no luck to perform the invocation. Last error is: " + e.getMessage(),
                 e.getCause() != null ? e.getCause() : e);
     }
 }
}
  • 如上代码1,我们从RpcContext.getContext()获取了属性值ip,如果指定了改值说明指定了ip,
  • 代码2则检查是否有可用的服务提供者,如果没有则抛出异常。
  • 代码3变量invokers列表查找指定IP对应的Invoker
  • 代码4 检查是否有对应IP对应的Invoker,没有则抛出异常。
  • 代码5 具体使用选择的invoker发起远程调用。

注意我们还修改了框架的AbstractClusterInvoker为MyAbstractClusterInvoker:

[Java] 纯文本查看 复制代码
public Result invoke(final Invocation invocation) throws RpcException {
  checkWhetherDestroyed();
  // binding attachments into invocation.
  Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
  if (contextAttachments != null && contextAttachments.size() != 0) {
      ((RpcInvocation) invocation).addAttachments(contextAttachments);
  }
  List<Invoker<T>> invokers = list(invocation);
    LoadBalance loadbalance = null;//initLoadBalance(invokers, invocation);
  RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
  return doInvoke(invocation, invokers, loadbalance);
}

这里我们把 LoadBalance loadbalance = initLoadBalance(invokers, invocation);
修改为了 LoadBalance loadbalance = null;因为我们不需要负载均衡了。

然后在消费端调用时候进行下面设置就可以指定ip调用了。


//设置集群容错策略为我们自己的
referenceConfig.setCluster("myCluster");
//指定ip,企图让ip为30.10.67.231的服务提供者来处理服务
RpcContext.getContext().set("ip", "30.10.67.231");

三、总结

Dubbo是一个高度可扩充的框架,基于SPI的扩展接口,我们可以根据需要定制我们自己的实现,本文我们则基于集群容错策略实现了基于ip调用的扩展。





推荐了解热门学科

java培训 Python人工智能 Web前端培训 PHP培训
区块链培训 影视制作培训 C++培训 产品经理培训
UI设计培训 新媒体培训 产品经理培训 Linux运维
大数据培训 智能机器人软件开发




传智播客是一家致力于培养高素质软件开发人才的科技公司“黑马程序员”是传智播客旗下高端IT教育品牌。自“黑马程序员”成立以来,教学研发团队一直致力于打造精品课程资源,不断在产、学、研3个层面创新自己的执教理念与教学方针,并集中“黑马程序员”的优势力量,针对性地出版了计算机系列教材50多册,制作教学视频数+套,发表各类技术文章数百篇。

传智播客从未停止思考

传智播客副总裁毕向东在2019IT培训行业变革大会提到,“传智播客意识到企业的用人需求已经从初级程序员升级到中高级程序员,具备多领域、多行业项目经验的人才成为企业用人的首选。”

中级程序员和初级程序员的差别在哪里?
项目经验。毕向东表示,“中级程序员和初级程序员最大的差别在于中级程序员比初级程序员多了三四年的工作经验,从而多出了更多的项目经验。“为此,传智播客研究院引进曾在知名IT企业如阿里、IBM就职的高级技术专家,集中研发面向中高级程序员的课程,用以满足企业用人需求,尽快补全IT行业所需的人才缺口。

何为中高级程序员课程?

传智播客进行了定义。中高级程序员课程,是在当前主流的初级程序员课程的基础上,增加多领域多行业的含金量项目,从技术的广度和深度上进行拓展“我们希望用5年的时间,打造上百个高含金量的项目,覆盖主流的32个行业。”传智播客课程研发总监于洋表示。




黑马程序员热门视频教程【点击播放】

Python入门教程完整版(懂中文就能学会) 零起点打开Java世界的大门
C++| 匠心之作 从0到1入门学编程 PHP|零基础入门开发者编程核心技术
Web前端入门教程_Web前端html+css+JavaScript 软件测试入门到精通


在线咨询 我要报名
和我们在线交谈!