dubbo扩展解决开发环境共用问题

在开发环境下我们需要解决哪些开发问题呢?
假如你公司有100个服务,并且服务间调用错综复杂可能是A-B-C-D-E,并且公司提供了一套开发环境,在多人开发的情况下,你的请求可能被负载到了别的开发者机器上,又或者你想要你的请求负载回你自己的本机,然后请求出去就消失无踪了。然而你又不能用直连的方式,因为你的服务还有对其它服务有依赖。
需解决如下问题

  • 当你指定负载的时候优先负载至你自己本机
  • 当没有你本机的时候不能负载到别人机器上,必须调用开发环境公共服务。
  • 调用链中间隔性存在负载时,需要优先调用至本机
    例如:A-B-C-D 我在开发A、D服务但是B、C不存在负载,这个时候我需要服务调用到D的时候是负载到我本机。
  • 不影响测试到生产流水线环境。
    根据以上问题做出扩展,需要扩展两个Filter、和一个LoadBalance。

github项目地址
核心代码如下
ConsumerDevFilter.java

package com.dubbo.dev.plugin.filter;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.rpc.*;
import com.dubbo.dev.plugin.loadbalance.CurrRequest;
import com.dubbo.dev.plugin.loadbalance.LbConfig;
import com.dubbo.dev.plugin.loadbalance.LbConst;
import com.dubbo.dev.plugin.loadbalance.ReqMeta;

/**
 * @author 86180
 * @Description:
 * @date 2020/6/210:20
 */
@Activate(group = {Constants.CONSUMER})
public class ConsumerDevFilter implements Filter {
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        ReqMeta meta = CurrRequest.getMeta();
        boolean b = invocation.getAttachments().containsKey(LbConst.DUBBO_LB_HOST);
        if(!b){
            CurrRequest.setAttachment(meta);
        }
        //此filter解决问题:调用链中,间隔性存在负载时,需要优先调用至本机
        Result result = invoker.invoke(invocation);
        return result;
    }
}

ProviderDevFilter.java

package com.dubbo.dev.plugin.filter;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.rpc.*;
import com.dubbo.dev.plugin.loadbalance.CurrRequest;
import com.dubbo.dev.plugin.loadbalance.LbConst;
import com.dubbo.dev.plugin.loadbalance.ReqMeta;

import java.util.Map;

@Activate(group = {Constants.PROVIDER})
public class ProviderDevFilter implements Filter {

    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        ReqMeta reqMeta = new ReqMeta();
        Map<String, String> attachments = invocation.getAttachments();
        String dubboLbHost = attachments.get(LbConst.DUBBO_LB_HOST);
        String dubboLbDefault = attachments.get(LbConst.DUBBO_LB_DEFAULT);
        if (!StringUtils.isBlank(dubboLbHost)) {
            reqMeta.setDubboLbHost(dubboLbHost);
            reqMeta.setDubboLbDefault(dubboLbDefault);
        }
        CurrRequest.setMeta(reqMeta);
        Result result = invoker.invoke(invocation);
        CurrRequest.remove();
        return result;
    }
}

DevLoadBalance.java

package com.dubbo.dev.plugin.loadbalance;

import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance;
import com.alibaba.dubbo.rpc.cluster.loadbalance.RandomLoadBalance;

import java.util.List;

/**
 * @author 86180
 * @Description: 扩展负载
 * @date 2020/6/19:20
 */
public class DevLoadBalance extends AbstractLoadBalance {

    @Override
    protected <T> Invoker<T> doSelect(List<Invoker<T>> list, URL url, Invocation invocation) {
        ReqMeta meta = CurrRequest.getMeta();
        ReqMeta reqMeta = CurrRequest.setAttachment(meta);
        String dubboLbHost = reqMeta.getDubboLbHost();
        String dubboLbDefault = reqMeta.getDubboLbDefault();
        //获取当前配置负载
        if (dubboLbHost != null) {
            for (Invoker<T> invoker : list) {
                if (invoker.getUrl().getHost().matches(dubboLbHost)) {
                    return invoker;
                }
            }
        }
        //获取默认的配置
        String[] split = dubboLbDefault.split(",");
        for (String pattern : split) {
            for (Invoker<T> invoker : list) {
                if (invoker.getUrl().getHost().matches(pattern)) {
                    return invoker;
                }
            }
        }

        return new RandomLoadBalance().select(list, url, invocation);
    }
}

使用此插件就能在开发环境愉快的玩耍了。在也不用担心一个本地请求发出去不知道发到哪里去了,再也不用担心本地请求发出去调用到某人机器上,某人打了个断点拉

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章