dubbo自定义路由规则实际应用

来源:互联网 发布:网络优化工程师考试 编辑:程序博客网 时间:2024/05/16 10:24

最近遇到这么个场景:由于多个业务系统都实现了同一个服务,在调用中通过读取相关配置可以知道此次调用是限制请求到哪几个服务提供者上,而不是所有提供者中任取一个,这个就需要在dubbo上自定义自己的路由规则。


具体做法:实现Router接口,重写route方法,从注册中心所有服务提供者列表中选出符合规范的提供者列表并返回即可。

/** * @author zhuangguoshuai * @description  自定义路由规则,根据配置的limitIp找到对应的providerList * @create 2017-10-19 17:01 **/public class LimitIpRouter implements Router{    private final static Logger logger = LogManager.getLogger(LimitIpRouter.class);    @Override    public List<Provider> route(Invocation invocation, List<Provider> providers) {        providers.stream().forEach(provider -> logger.info("provider:"+provider.toUrl()));        //获取参数中的限制ip列表        String limitIps = getLimitIps(invocation);        return providers.stream().filter(provider -> StringUtils.contains(limitIps, provider.getIp())).collect(Collectors.toList());    }    /**     * 解析worker配置的执行机器限制ips     * @param invocation     * @return     */    private String getLimitIps(Invocation invocation) {        Object[] args = invocation.getArgs();        if(args == null) {            logger.error("LimitIpRouter getLimitIps error, invocation args == null!");            return null;        }        String limitIps = null;        for(Object o : args) {            if(!(o instanceof JobModel)) {                continue;            }            JobModel jm = (JobModel)o;            if(jm == null || StringUtils.isBlank(jm.getLimitIps())) {                logger.error("LimitIpRouter getLimitIps error, limitIps isBlank!");                return null;            }            return jm.getLimitIps();        }        return null;    }}



还有一种取巧的方法,就是在最后确定服务提供者的时候重写软负载均衡规则,在所有服务提供者中选出一个实际调用的提供者。

package com.jd.cron.common.extensions;import com.alibaba.dubbo.common.URL;import com.alibaba.dubbo.common.extension.SPI;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 com.jd.cron.common.dto.JobModel;import org.apache.commons.lang3.StringUtils;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import java.util.List;import java.util.function.Predicate;import java.util.stream.Collectors;/** * @author zhuangguoshuai * @description 自定义复杂均衡策略 * @create 2017-09-07 14:51 **/@SPI(GroupLoadBalance.NAME)public class GroupLoadBalance extends AbstractLoadBalance {    public static final String NAME = "group";    private static final RandomLoadBalance randomLoadBalance = new RandomLoadBalance();    private static Logger logger = LogManager.getLogger(GroupLoadBalance.class);    @Override    protected <T> Invoker<T> doSelect(List<Invoker<T>> list, URL url, Invocation invocation) {        String limitIps = getLimitIps(invocation);        List<Invoker<T>> groupInvokerList = list.stream().filter(new Predicate<Invoker<T>>() {            @Override            public boolean test(Invoker<T> ii) {                return StringUtils.contains(limitIps, ii.getUrl().getHost());            }        }).collect(Collectors.toList());        return randomLoadBalance.select(groupInvokerList, url, invocation);    }    /**     * 解析worker配置的执行机器ip     * @param invocation     * @return     */    private String getLimitIps(Invocation invocation) {        Object[] args = invocation.getArguments();        if(args == null) {            logger.error("GroupLoadBalance doSelect() error, args == null!");            return null;        }        String limitIps = null;        for(Object o : args) {            if(!(o instanceof JobModel)) {                continue;            }            JobModel jm = (JobModel)o;            if(jm == null || StringUtils.isBlank(jm.getLimitIps())) {                logger.error("GroupLoadBalance doSelect() error, limitIps isBlank!");                return null;            }            return jm.getLimitIps();        }        return null;    }}


原创粉丝点击