dubbo本地调试方法实践(解决多人多版本并行开发调试问题)

2021-06-28  本文已影响0人  星城天空

背景

我们有个业务的项目,已做了微服务拆分,使用dubbo的rpc框架。有多位开发同事一起参与开发,但可能每个同事在同一时刻负责的版本不一样,例如有2位同事负责开发版本1,有另外2位同事负责开发版本2。某一天,一位同学向我吐槽,在本地开发调试过,自己开发的版本1的web经常调用到另外一为同事开发版本2的app,不能得到自己想要的结果。又不想逐个修改dubbo的@reference注解中url参数或者在jvm参数中增加类似-Dcom.test.testService=dubbo://localhost:20880等配置。

方案

1.实现自定义cluster,查询本地ip和注册zk的dubbo接口配置
2.若配置中存在与本地ip相同,则选取ip为本地ip的Invoker发起远程调用
3.若不存在,则交付默认cluster执行
4.配合apollo配置中心,本地开发环境开启自定义cluster,生产环境默认不开启

具体实现

1.新建DevCluster类继承Cluster

2.在resource文件夹下新建META-INF/dubbo/org.apache.dubbo.rpc.cluster.Cluster文件,文件内容:
dev=com.test.common.dubbo.DevCluster

3.开发环境,apollo开启配置:dubbo.consumer.cluster = dev(生产环境不增加此配置,使用默认的)

@Slf4j
public class DevCluster implements Cluster {

    public final static String NAME = "dev";

    @Override
    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
            return new AbstractClusterInvoker<T>(directory) {
                public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
                    // 1.检查是否有可用invoker
                    checkInvokers(invokers, invocation);

                    // 2.查询本地IP和注册zk的Dubbo使用IP
                    String ip = NetUtils.getLocalHost();
                    List<String> registerHosts = invokers.stream().map(i->i.getUrl().getHost()).collect(Collectors.toList());

                    // 3.注册IP为空,或者本地IP不在zk测试IP,则交由原cluster处理
                    if (CollectionUtils.isEmpty(registerHosts) || !registerHosts.contains(ip)){
                        FailoverClusterInvoker failoverClusterInvoker = new FailoverClusterInvoker(directory);
                        return failoverClusterInvoker.doInvoke(invocation,invokers,loadbalance);
                    }
                    Invoker<T> invoked = invokers.stream().filter(invoker -> invoker.getUrl().getHost().equals(ip)).findFirst()
                            .orElseThrow(() -> new RpcException("Failed to invoke the method "));

                    // 4.使用选取的Invoker发起远程调用,失败则抛出异常
                    try {
                        return invoked.invoke(invocation);
                    } catch (Throwable e) {
                        log.error("");
                        throw (RpcException) e;
                    }
                }
            };
    }
}
上一篇 下一篇

猜你喜欢

热点阅读