`
ahua186186
  • 浏览: 561161 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

dubbo服务治理之路由规则研究

 
阅读更多
1.今天没太多事情,挤出点时间,研究了下dubbo的路由规则实现。

首先,看看dubbo消费端的主要调用流程(这里就不画图了),以后补充:

第一步:创建消费端代理:ReferenceConfig.createProxy,这里没什么特别,典型的C/S调用设计,都是通过JAVA动态代理或是Javassist的代理实现,比如mybatis mapper。


思考:假如我想实现API网关的dubbo协议路由怎么实现呢:毫无疑问必须使用ReferenceConfig的get.set以及init方法,下一篇将展开讨论实现细节..

第二步:直接跳到动态代理代码里的InvokerInvocationHandler:
这里忽略invoker的初始化(基本就是提供者注册+消费端订阅后初始化)

思考:假如让你实现一个RPC的客户端同步和异步调用你会怎么实现呢?

public class InvokerInvocationHandler implements InvocationHandler {
    private final Invoker<?> invoker;

    public InvokerInvocationHandler(Invoker<?> handler) {
        this.invoker = handler;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        Class[] parameterTypes = method.getParameterTypes();
        if (method.getDeclaringClass() == Object.class) {
            return method.invoke(this.invoker, args);
        } else if ("toString".equals(methodName) && parameterTypes.length == 0) {
            return this.invoker.toString();
        } else if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
            return this.invoker.hashCode();
        } else {
            return "equals".equals(methodName) && parameterTypes.length == 1 ? this.invoker.equals(args[0]) : this.invoker.invoke(new RpcInvocation(method, args)).recreate();
        }
    }
}

第三步:AbstractClusterInvoker.invoke;
这里主要是加载一个列表:invoker list

  public Result invoke(Invocation invocation) throws RpcException {
        this.checkWheatherDestoried();
//选择invoker
        List<Invoker<T>> invokers = this.list(invocation);
        LoadBalance loadbalance;
        if (invokers != null && invokers.size() > 0) {
            loadbalance = (LoadBalance)ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(((Invoker)invokers.get(0)).getUrl().getMethodParameter(invocation.getMethodName(), "loadbalance", "random"));
        } else {
            loadbalance = (LoadBalance)ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension("random");
        }

        RpcUtils.attachInvocationIdIfAsync(this.getUrl(), invocation);
        return this.doInvoke(invocation, invokers, loadbalance);
    }

 protected List<Invoker<T>> list(Invocation invocation) throws RpcException {
        List<Invoker<T>> invokers = this.directory.list(invocation);
        return invokers;
    }


第四步:真正加载invoker的实现:AbstractDirectory

注意这里有个路由选择的逻辑,也就是我们今天关注的重点:
router.route:具体的路由实现逻辑:比如ConditionRouter

思考:假如你的程序中需要实现动态的插件式功能,你如何实现呢:基本思路:配置中心配置+ 配置通知更新+插件根据优先级生效。---典型的分布式协调场景,ZK标配

相比静态的插件式功能实现思路:SPI思想,要灵活很多


 public List<Invoker<T>> list(Invocation invocation) throws RpcException {
        if (this.destroyed) {
            throw new RpcException("Directory already destroyed .url: " + this.getUrl());
        } else {
            List<Invoker<T>> invokers = this.doList(invocation);
            List<Router> localRouters = this.routers;
            if (localRouters != null && localRouters.size() > 0) {
                Iterator var5 = localRouters.iterator();

                while(var5.hasNext()) {
                    Router router = (Router)var5.next();

                    try {
                        if (router.getUrl() == null || router.getUrl().getParameter("runtime", true)) {
                            invokers = router.route(invokers, this.getConsumerUrl(), invocation);
                        }
                    } catch (Throwable var7) {
                        logger.error("Failed to execute router: " + this.getUrl() + ", cause: " + var7.getMessage(), var7);
                    }
                }
            }

            return invokers;
        }
    }


第五步:FailoverClusterInvoker.doInvoke:

这里通过负责均衡策略选择一个invoker,然后通过各种过滤器过滤。

最后:通过DubboInvoker发送数据给服务提供端。

了解完调用的主流程,我们基本就梳理清楚路由逻辑的实现在那个环节,以及需要注意设置那些属性,比如runtime.


但是经过我本人测试dubbo的路由功能并不稳定,所有用它做灰度发布不靠谱(但是通过权重设置实现rolling update还是比较靠谱的),不稳定因素有:
1.消费端没有及时订阅新增的服务提供者信息,而我们的需求是需要路由到增的服务提供者,导致ConditionRouter.matchCondition无法匹配成功,然后就不会使用路由规则。
2.路由规则没有及时通知更新到消费端,导致AbstractDirectory.setRouters一直没有添加ConditionRouter。(经过测试这个经常出现,这个问题比较严重,也有可能是我环境的问题)

学习感悟:总的来说通过今天的研究还是学到了一些常用的设计思路,而不仅仅是研究代码和原理。
分享到:
评论

相关推荐

    Apache Dubbo:Dubbo服务治理:服务路由与动态配置

    ### Apache Dubbo:服务治理——服务路由与动态配置 #### 一、服务治理的重要性 在当前流行的微服务架构中,由于各个服务之间存在着频繁而复杂的交互,如何有效地管理和控制这些服务成为了确保整个系统稳定性和可...

    史上最强Dubbo面试26题和答案:核心组件+服务治理+架构设计等

    - **Router**:路由规则,用于控制服务请求的路由。 #### 6. 服务注册与发现流程 - **Provider**启动服务并在注册中心注册服务信息。 - **Consumer**向注册中心订阅所需服务。 - **注册中心**将服务信息推送给...

    dubbo服务限制并发量示例

    通过阅读和分析源码,开发者可以更深入地理解 Dubbo 内部的工作原理,包括并发控制、路由规则和服务降级的实现细节,这对于定制化开发和优化服务性能非常有帮助。 综上所述,理解和掌握这些知识点对于构建健壮、可...

    dubbo 分布式服务框架 开发者学习文档 PDF格式

    同时,Dubbo支持基于规则的服务路由,可以根据不同的条件将请求路由到特定的服务实例,增强了系统的灵活性和可扩展性。 再者,Dubbo内置了软负载均衡策略,如随机、轮询、最少活跃调用数等,这些策略可以在服务消费...

    0816分布式服务治理技术-Dubbo1

    总之,Dubbo是一个强大的服务治理框架,它简化了分布式环境下的服务管理和监控,通过Zookeeper等注册中心实现了服务的自动化发现和注册,提供了丰富的服务治理功能,如权重调整、路由规则、监控等,大大提升了系统的...

    dubbodubbo.zip

    7. **路由(Route)**:路由规则允许根据特定条件动态调整服务调用路径,实现流量控制、灰度发布等高级功能。 二、Dubbo关键特性 1. **远程调用(RPC)**:Dubbo基于Java的反射机制,实现了透明化的远程方法调用,...

    Dubbo服务以及压测脚本开发

    内置了条件、脚本等路由策略,可以根据业务需求动态配置路由规则,实现灰度发布、同机房优先等高级功能。 **6. 可视化的服务治理与运维** Dubbo 提供了丰富的服务治理工具,如服务元数据查询、健康状态检查、调用...

    dubbo-admin-2.5.4.war dubbo的控制台管理工具

    2. **路由规则**:路由规则是Dubbo服务治理中的一个重要环节,它可以根据特定条件对请求进行路由,例如基于IP、服务版本或消费端特征等。`dubbo-admin`提供了直观的界面,允许管理员动态添加、修改和删除路由规则,...

    dubbo源码分析系列

    - 路由规则:解析动态路由、条件路由等高级特性,以及如何根据业务需求定制路由规则。 7. **监控与调优** - 统计与监控:Dubbo内置的监控统计功能,包括服务调用次数、耗时、异常等指标,以及如何集成第三方监控...

    dubbo.io文档

    此外,还会涉及服务治理的高级特性,如动态配置、服务路由规则、集群策略(如广播、集群、代理)和分布式事务解决方案。开发者还可以了解到如何扩展Dubbo,例如自定义Filter、Protocol、Container等,以满足特定业务...

    dubbo-admin管理

    Dubbo-Admin支持多种集群策略,如Failover(失败重试)、Failfast(快速失败)、Failsafe(失败安全)、Failback(失败回调)、Forceloader(强制加载)等,以及灵活的路由规则设置,帮助优化服务间的通信。...

    dubbo-admin.jar

    6. **路由规则**:允许设置服务的路由策略,如按照版本、分组等条件进行路由,实现灰度发布、蓝绿部署等高级功能。 7. **服务版本管理**:便于多版本服务共存,支持平滑升级和回滚。 8. **异常报警**:当服务出现...

    dubbo管控平台2.5.3 dubbo-admin

    4. **路由策略**:允许设置自定义路由规则,如根据服务质量、地域等条件进行智能路由,提高服务的可用性和响应速度。 5. **服务治理**:包括服务的启停、禁用、权重调整等操作,有助于在出现问题时快速响应,降低...

    dubbo 简单测试DEMO

    配置中心可以集中管理服务的元数据,如服务版本、路由规则、权重等。虽然这不是DEMO的必要部分,但了解这一概念有助于理解Dubbo的完整架构。 6. **服务监控(Monitor)** Dubbo提供了内置的服务监控系统,可以...

    Dubbo高级视频教程

    - **服务路由**:基于条件和服务分组的路由规则,实现灵活的服务调度。 - **服务降级与限流**:当服务不可用或响应慢时,采用服务降级策略来保障整体系统的稳定性和可用性;同时实施服务限流措施防止过载。 #### 五...

    dubbo2.8.4后台管理端版本

    5. **集群视图**:可视化展示服务的集群结构,包括路由规则、权重分配等。 6. **日志查看**:提供日志查询功能,便于定位和排查问题。 7. **API文档**:集成API文档,方便开发者了解服务的接口定义和调用方式。 8...

    dubbo-admin-2.6.0-20200414.zip

    5. **路由规则**:设定和查看调用路由策略,如根据权重分配、条件路由等。 6. **集群管理**:管理服务提供者的集群状态,如故障切换、负载均衡等。 7. **异常处理**:记录和追踪服务调用过程中的异常信息,帮助定位...

    dubbo-控制台使用源码

    5. **配置管理**:控制台可以对服务的元数据、参数、路由规则等进行管理,方便服务的动态配置。 6. **opensesame项目**:Opensesame是与Dubbo控制台相关的一个项目,可能是为了简化或者增强Dubbo的监控和管理功能。...

    dubbo registry

    Dubbo是阿里巴巴开源的一款高性能、轻量级的Java服务治理框架,其中Registry(注册中心)是其核心组件之一。在分布式系统中,Registry扮演着服务发现和服务注册的角色,使得服务提供者和服务消费者可以进行有效的...

    dubbo2.5.7 源码包

    根据路由规则选择合适的Invoker。 (4) 负载均衡:`com.alibaba.dubbo.rpc.cluster.loadbalance.LoadBalance`实现负载均衡算法,如Random、RoundRobin等。 (5) 链路建立:`com.alibaba.dubbo.remoting.Transporter`...

Global site tag (gtag.js) - Google Analytics