前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Dubbo to Istio / Dubbo Mesh 极简改造指南

Dubbo to Istio / Dubbo Mesh 极简改造指南

原创
作者头像
谢正伟
修改2020-06-13 13:37:31
1K0
修改2020-06-13 13:37:31
举报
文章被收录于专栏:云原生研究云原生研究

无需改造 dubbo sdk,无需更换 dubbo 协议,直接使用 istio 治理 dubbo 流量。这是史上最简单的改造方法。

step 1. 改造 provider

去掉 registry 配置,让 provider 变成一个纯纯的 dubbo 应用。

修改配置,三个false,address 随便写一个字符串(因为他不能为空):

代码语言:txt
复制
<beans>
    <dubbo:application name="hello-dubbo-provider"/>
    <dubbo:protocol name="dubbo" port="20880" />
    <dubbo:registry register="false" subscribe="false" check="false" address="none" />
    <!--<dubbo:registry address="zookeeper://zk.dubbo:2181" client="curator" />-->
    <bean id="demoService" class="tencent.demo.provider.DemoServiceImpl"/>
    <dubbo:service interface="tencent.demo.DemoService" ref="demoService" />
</beans>

先在本地启动它。

step 2. 改造 consumer

去掉 registry 配置,让 consumer 变成一个傻傻的 dubbo 应用。

手工指定 service 的服务地址,当然了,要把他变成你部署在 istio 中的服务名 url="dubbo://hello-dubbo-provider:20880"

代码语言:txt
复制
<beans>
    <dubbo:application name="demo-consumer"/>
    <dubbo:registry address="none" register="false" subscribe="false" check="false" />
    <!--<dubbo:registry address="zookeeper://zk.dubbo:2181" client="curator" />-->
    <dubbo:reference id="demoService" check="false" interface="tencent.demo.DemoService" url="dubbo://hello-dubbo-provider:20880" />
</beans>

在 hosts 中映射一下。 

代码语言:txt
复制
127.0.0.1 hello-dubbo-provider

启动 consumer,不出意外,完美运行。

上面的对 dubbo 的改造其实是在使用 dubbo 的调试功能,但他恰恰是 istio 需要的效果。

step 3. 部署到 istio 中

在低版本的 istio 中,控制面无法解析。需要配置 EnvoyFilter。 但配了半天,完全不通 。干脆装个 1.6 玩玩。

经过实验,在 istio 1.6.1 中,基于 tcp 服务治理的 dubbo mesh 直接启动成功。

以下是实验过程:示例中的镜像地址目前是公开可测的。

1 创建 ns

代码语言:txt
复制
apiVersion: v1
kind: Namespace
metadata:
  name: dubbo
  labels:
    istio-injection: enabled
spec:
  finalizers:
    - kubernetes

2 创建 provider 的部署集

代码语言:txt
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-dubbo-provider
  namespace: dubbo
  labels:
    app: hello-dubbo-provider
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-dubbo-provider
      version: v1
  template:
    metadata:
      labels:
        app: hello-dubbo-provider
        version: v1
    spec:
      containers:
        - name: hello-dubbo-provider
          image: tencent-cloud-one-docker.pkg.coding.net/xyz-demo/images/hello-dubbo-provider:1.0.4
          command: ["java","-jar","hello-dubbo-provider-fat.jar"]
          ports:
            - containerPort: 20880
              protocol: TCP
---
# 部署 hello-dubbo-provider v2
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-dubbo-provider-v2
  namespace: dubbo
  labels:
    app: hello-dubbo-provider
    version: v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-dubbo-provider
      version: v2
  template:
    metadata:
      labels:
        app: hello-dubbo-provider
        version: v2
    spec:
      containers:
        - name: hello-dubbo-provider
          image: tencent-cloud-one-docker.pkg.coding.net/xyz-demo/images/hello-dubbo-provider:2.0.0
          command: ["java","-jar","hello-dubbo-provider-fat.jar"]
          ports:
            - containerPort: 20880
              protocol: TCP

3 创建 service

代码语言:txt
复制
apiVersion: v1
kind: Service
metadata:
  name: hello-dubbo-provider
  namespace: dubbo
  labels:
    name: hello-dubbo-provider
spec:
  ports:
  - name: dubbo-rpc
    protocol: TCP
    port: 20880
    targetPort: 20880
  selector:
    app: hello-dubbo-provider

4 创建 consumer 部署

代码语言:txt
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-dubbo-consumer
  namespace: dubbo
  labels:
    app: hello-dubbo-consumer
    version: v1
spec:
  replicas: 10
  selector:
    matchLabels:
      app: hello-dubbo-consumer
      version: v1
  template:
    metadata:
      labels:
        app: hello-dubbo-consumer
        version: v1
    spec:
      containers:
        - name: hello-dubbo-consumer
          image: tencent-cloud-one-docker.pkg.coding.net/xyz-demo/images/hello-dubbo-consumer:1.0.3
          command: ["java","-jar","hello-dubbo-consumer-fat.jar"]

5 流量/灰度控制

代码语言:txt
复制
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: hello-vs
  namespace: dubbo
spec:
  hosts:
    - hello-dubbo-provider
  tcp:
    - route:
        - destination:
            host: hello-dubbo-provider
            port:
              number: 20880
            subset: v1
          weight: 20
        - destination:
            host: hello-dubbo-provider
            port:
              number: 20880
            subset: v2
          weight: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: hello-subset
  namespace: dubbo
spec:
  host: hello-dubbo-provider
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2

测试结果

部署完成,查看 consumer 的各个 pod 的 log。会发现,少量 consumer 打印了 hello-dubbo-provider:v1 的结果。

代码语言:txt
复制
2020-06-10T10:58:22.870417943Z Hello 哈哈, V1 @ 2020-06-10 10:58:22 @ 172.24.0.136
2020-06-10T10:58:27.872374594Z Hello 哈哈, V1 @ 2020-06-10 10:58:27 @ 172.24.0.136
2020-06-10T10:58:32.874072253Z Hello 哈哈, V1 @ 2020-06-10 10:58:32 @ 172.24.0.136

v2 的结果的比较多:

代码语言:txt
复制
2020-06-10T11:00:32.625814149Z 你好世界, 版本 2 升级了这个提示 哈哈, V2 @ 2020-06-10 11:00:32 @ 172.24.0.7
2020-06-10T11:00:37.638914148Z 你好世界, 版本 2 升级了这个提示 哈哈, V2 @ 2020-06-10 11:00:37 @ 172.24.0.7
2020-06-10T11:00:42.635862572Z 你好世界, 版本 2 升级了这个提示 哈哈, V2 @ 2020-06-10 11:00:42 @ 172.24.0.7

调整 vs 的百分比,重启 pod(因为长连接,所以重启),看看他是不是按照指挥来调度。

另外可以使用如下的命令多次执行 consumer 进行验证:

代码语言:txt
复制
kubectl exec -n dubbo hello-dubbo-consumer-855fcb7878-5qcb4 -- java -jar hello-dubbo-consumer-fat.jar

在 kiali 中,也能看到流量的监控图表。

more: 改造成 http 协议

dubbo 可以通过简单的注册文件的修改,就可以完成通信协议的改变。

依赖包大概需要增加:

代码语言:txt
复制
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>9.0.36</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>9.4.29.v20200521</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>9.4.29.v20200521</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.github.briandilley.jsonrpc4j</groupId>
            <artifactId>jsonrpc4j</artifactId>
            <version>1.2.0</version>
        </dependency>

provider 的配置修改

代码语言:txt
复制
<dubbo:protocol name="http" id="http" port="20880" server="jetty"/>

consumer 的配置修改

代码语言:txt
复制
 <dubbo:reference id="demoService" check="false" interface="tencent.demo.DemoService" url="http://hello-dubbo-provider:20880" />

修改通信协议之后,程序的行为基本不变,只是每次访问改成了 http,会每次重新连接。

而对于 istio,现在可以通过 接口名称 来进行流量治理了。因为,他的服务的接口名现在放在 url 中了。

下面就是一个访问的示例:

代码语言:txt
复制
http://hello-dubbo-provider:20880/tencent.demo.DemoService?application=demo-consumer&check=false&init=false&interface=tencent.demo.DemoService&pid=74873&register.ip=192.168.1.15&remote.application=&side=consumer&sticky=false

在 VirtualService 中,即可 通过 uri 匹配 "tencent.demo.DemoService" 来进行服务治理了。

附:dubbo 的 java 代码

Provider。版本 1 和 2 分别打印了不同的内容。

代码语言:txt
复制
    public String sayHello(String name) {
        String myHost = "";
        try {
            InetAddress inetAddress = InetAddress.getLocalHost();
            myHost = inetAddress.getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        Date date = new Date();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String str = format.format(date);
        return "你好世界, 版本 2 升级了这个提示 " + name + ", V2 @ " + str + " @ " + myHost ;
    }

consumer 每 5 秒调用一次:

代码语言:txt
复制
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"META-INF/spring/consumer.xml"});
        context.start();
        DemoService demoService = (DemoService)context.getBean("demoService");
        while(true) {
            String hello = demoService.sayHello("哈哈");
            System.out.println(hello);
            Thread.sleep(5 * 1000);
        }
    }

总结

使用了最简单的方法,将 dubbo 的服务发现和治理功能去掉,保留了他的 rpc 功能,并通过与 istio 一致的部署方法进行服务部署和 TCP 流量操控。

但现在基于 istio 本身的调用链还没有看到,基于内容的流量操控还待继续探索。


参考:

dubbo:registry

dubbo:reference

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • step 1. 改造 provider
  • step 2. 改造 consumer
  • step 3. 部署到 istio 中
    • 1 创建 ns
      • 2 创建 provider 的部署集
        • 3 创建 service
          • 4 创建 consumer 部署
            • 5 流量/灰度控制
              • 测试结果
              • more: 改造成 http 协议
              • 附:dubbo 的 java 代码
              • 总结
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档