dubbo自定义路由设置

本文最后更新于:2022年6月27日 下午

目的

开发人员进行本地开发时,经常会出现接口调到k8s容器内的服务上,我们本地和k8s共用一个nacos服务.

根据调研,打算使用dubbo的自定义路由实现.本地服务调接口时,使用路由过滤掉k8s内部的provider地址,从而实现,本地consumer能够一直本地provider服务.

由于过滤了k8s内部实例的ip,因此需要,将此路由只能在本地生效,在k8s环境内失效,通过spring.profiles实现.

实现自定义路由

继承AbstractRouter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.router.AbstractRouter;

import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Slf4j
public class IpRouter extends AbstractRouter {


public IpRouter(URL url) {
super(url);
}

@Override
public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {

if (!SpringContextUtil.isLocal()) { //仅在本地进行路由
return invokers;
}

log.info(" before route :{},{}", invokers.size(), invokers);
if (invokers.size() <= 1) { //存在少于一个provider时不进行路由,可选
return invokers;
}

//存在多个provider时,过滤掉属于k8s内服务的provider,保留本地服务
Predicate<Invoker<T>> useLocalIP = str -> !str.getUrl().toServiceString().contains("10.0.80.9");
List<Invoker<T>> collect = invokers.stream().filter(useLocalIP).collect(Collectors.toList());

log.info(" after route:{},{}", collect.size(), collect);
return collect;
}
}

实现RouterFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.cluster.Router;
import org.apache.dubbo.rpc.cluster.RouterFactory;

@Activate(group = "consumer")//只在consumer侧激活
public class IpRouterFactory implements RouterFactory {

@Override
public Router getRouter(URL url) {
return new IpRouter(url);
}
}

加载RouterFactory

在resources 目录下创建目录META-INF\dubbo
创建文件:org.apache.dubbo.rpc.cluster.RouterFactory,
值为:ip=com.wtt.demo.app.route.IpRouterFactory

解决只在本地生效

创建SpringContextUtil工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.function.Predicate;

@Slf4j
@Service
public class SpringContextUtil implements ApplicationContextAware {

private static ApplicationContext context = null;


public static String[] getActiveProfileList() {
return context.getEnvironment().getActiveProfiles();
}

public static Boolean isLocal() {
String[] activeProfileList = getActiveProfileList();
Predicate<String> containsLocalProfile = m -> m.contains("local");
return Arrays.stream(activeProfileList).anyMatch(containsLocalProfile);
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}

reference


dubbo自定义路由设置
https://baymax55.github.io/2022/09/13/dubbo/router/dubbo自定义路由设置/
作者
baymax55
发布于
2022年9月13日
许可协议