我们的服务都是部署在K8S集群中,dubbo 提供者默认向注册中心上报的 IP 都是Pod IP,这意味着在 k8s 集群外的网络环境是调用不了 dubbo 服务的,本文总结多个方案。
方案1
每个dubbo服务暴露一个LoadBalancer的IP,固定dubbo访问端口20880,本地使用IP+20880来访问
劣势:每个服务的IP都不一样,本地变更服务端需要变更代码IP,暴露内网LB还多了成本
方案2
在上面的方案下,在deployment里添加 dubbo 提供的DUBBO_IP_TO_REGISTRY和DUBBO_PORT_TO_REGISTRY环境变量,来把对应的LB IP + 20880注册到注册中心里.
优势:本地代码不需要变更了 劣势:每个dubbo服务端都需要添加环境变量,配置繁琐
方案3
dubbo服务暴露一个NodePort的IP,然后每一个服务都配置一个不同的端口,本地使用集群中任意一个Node的 IP + 自定义端口访问
优势:和方案1差不多,少了内网LB的费用, 劣势:继承方案1的劣势;每个服务之间端口不能冲突,当服务多起来之后非常难以管理。
方案4
强大的开源
手撸一个ingress controller来打通dubbo+k8s网络
这里记录下遇到的一个问题:
本地启动此项目:
同时本地起一个dubbo的消费端进行调试:
定义参数类
public class TestRequest implements Serializable {
private Long id;
public TestRequest() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
}
定义接口
public interface TestService {
Response<TestResponse> test(TestRequest var1);
}
定义test类
@Component
@Slf4j
public class Handler {
@DubboReference(check = false, url="dubbo://localhost:20881")
private TestService testService;
public void test() {
TestRequest request = new TestRequest();
request.setId("1");
TestResponse testResponse = invokeAndExtractByCodeAndMsg(testService::test, request, "testService::test", (String)null, (String)null);
System.out.println(testResponse);
}
}
@Activate(group = CONSUMER) public class AddTargetFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
//String remoteApplication = invoker.getUrl().getParameter("remote.application");
String remoteApplication="dubbo-test";
String group = invoker.getUrl().getParameter("group");
String targetApplication = StringUtils.isBlank(remoteApplication) ?
group : remoteApplication;
invocation.setAttachment("target-application", targetApplication);
return invoker.invoke(invocation);
}
发送请求后报错:
server/server.go:53 handle data error:can not find go type name com.cso.addo.dubbo.demo.api.biz.TestRequest in registry
跟踪调用栈
是在反序列化时在找不到com.cso.addo.dubbo.demo.api.biz.TestRequest这个参数类导致,看了默认的反序列化器默认的参数skip就是false,也就是不允许跳过。
我们这边这是为了拿到remote-application这个参数而已。
怎样才能跳过呢?
升级dubbo-go版本后解决
dubbo.apache.org/dubbo-go/v3 v3.0.0-rc4
github.com/apache/dubbo-go-hessian2 v1.9.3
---->
dubbo.apache.org/dubbo-go/v3 v3.0.1
github.com/apache/dubbo-go-hessian2 v1.11.0
原来新版本新加了一个strict参数,默认是false。