Dubbo 3.0 规模化落地基石 - 社区持续集成机制解析

d223795d4fb40f1dcc5ec6a04ae3999d.gif

01

背景

Aliware

Dubbo 3.0 在阿里巴巴各条业务线包括淘宝、考拉、饿了么、钉钉、达摩院等已全量或开始分批上线,社区企业如小米、工商银行、平安健康等也纷纷引入了 3.0 版本的新特性。支持如此大规模的体量的业务平稳运行,对 Dubbo 3.0 的稳定性有很高的要求,尤其是考虑到社区极高的活跃度,这个挑战就更大了。目前社区有超过 600 位 contributor,近一年以来每天有大约 60 个 commits,陆续支持了 Triple 协议、多实例等功能,这些功能都会涉及到大量的代码变更。每一次提交代码的质量对 Dubbo 3.0 版本的质量、稳定性、可靠性等方面有着至关重要的影响。

02

现状

Aliware

Dubbo 保证提交代码的质量主要体现在以下几个方面:

  • dubbo 代码仓库中的单测

  • dubbo-samples 中的集成测试

  • dubbo-benchmark 中的性能测试

  • code review 机制

其中,dubbo 的单测主要针对 Dubbo 代码单元的独立测试,侧重点在功能、分支覆盖等方面,是最基本的测试。dubbo-samples 主要是对 Dubbo 中常用的功能组合和场景进行测试,同时也会对齐 2.7.x 和 3.0 版本之间的功能。dubbo-benchmark 主要是在每次有重大版本升级变更的时候对性能进行压测。code review 机制是在每一次提交的代码都通过所有的单测和集成测试以后由社区的 contributor 和 committer 对提交的 pr 进行 review,当大家的意见不一致会在社区内进行讨论最终达成一致。

03

问题

Aliware

集成测试和 benchmark 测试都是独立的代码仓库,进过 Dubbo 社区多年的演进,相对来说变更较少已经比较稳定了。code review 机制主要是通过人的主观判断来对代码的质量进行评估,Dubbo 社区一直在不断吸纳更多优秀的 contributor 加入,理论上这方面的质量是在不断提高的。相对而言,dubbo 的单测集中在 100 多个 module 中,是变更最多、最频繁的,也是最容易出问题的地方。

目前 dubbo 的单测存在以下几个问题:

01

耗时长

dubbo 的单测会在 Ubuntu 和 Windows 上分别对 JDK8 和 11 进行测试,其中 Ubuntu 和 Windows 上运行单测的超时时间分别是 40 分钟和 50 分钟,但是我们发现经常会出现超时的情况。

02

多注册中心场景无法覆盖

dubbo 支持多注册中心,但是在单测中很难覆盖到与多注册中心相关的逻辑。dubbo 支持的注册中心包含 zookeeper、nacos、apollo 等,多种不同注册中心的混合场景更加难以覆盖。

04

分析

Aliware

通过对单测运行日志进行抽查和分析我们发现,dubbo 单测的耗时主要集中在与 zookeeper 相关的 module 中。

Testcase

Time elapsed(s)

org.apache.dubbo.rpc.protocol.dubbo.ArgumentCallbackTest

76.013

org.apache.dubbo.config.spring.ConfigTest

61.33

org.apache.dubbo.config.spring.schema.DubboNamespaceHandlerTest

50.437

org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessorTest

44.678

org.apache.dubbo.rpc.cluster.support.AbstractClusterInvokerTest

29.954

org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperClientTest

25.847

org.apache.dubbo.config.spring.beans.factory.annotation.MethodConfigCallbackTest

25.635

org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListenerTest

24.866

org.apache.dubbo.remoting.zookeeper.curator5.Curator5ZookeeperClientTest

19.664

导致这一问题的最主要原因是因为我们在写单测的时候通常会使用 zookeeper 作为注册中心和元数据中心,而在运行单测的过程中要对 zookeeper 进行频繁的 start 和 stop 操作。每一个单测希望彼此之间互不干扰,都采用了独立的 zookeeper 作为注册中心和元数据中心。当将单测并行运行时又会出现 zookeeper 端口冲突的问题。

现在需要解决的问题是:如何处理 dubbo 单测与注册中心和元数据中心的依赖问题。

05

解决方案

Aliware

这个问题看似比较简单,但是在实践过程中却发现比想象的要复杂的多,分别对各种解决方案进行了尝试:

01

TestingServer

TestingServer 是 curator-test 包中提供的专门用来 mock zookeeper 的工具类,目前 dubbo 单测中大量使用了 TestingServer。对与多注册中心的场景是通过同时启动两个 TestingServer 对外暴露不同的端口的方式来实现的。代码如下:

class ZookeeperRegistryCenter extends AbstractRegistryCenter {


    /**
     * Initialize the default registry center.
     */
    public ZookeeperRegistryCenter(int... ports) {
        this.ports = ports;
        this.instanceSpecs = new ArrayList<>(this.ports.length);
        this.zookeeperServers = new ArrayList<>(this.ports.length);
    }


    private static final Logger logger = LoggerFactory.getLogger(ZookeeperRegistryCenter.class);


    /**
     * The type of the registry center.
     */
    private static final String DEFAULT_REGISTRY_CENTER_TYPE = "zookeeper";


    private int[] ports;


    private List<InstanceSpec> instanceSpecs;


    private List<TestingServer> zookeeperServers;


    private AtomicBoolean started = new AtomicBoolean(false);


    /**
     * start zookeeper instances.
     */
    @Override
    public void startup() throws RpcException {
        try {
            if (started.compareAndSet(false, true)) {
                logger.info("The ZookeeperRegistryCenter is starting...");
                for (int port : this.ports) {
                    InstanceSpec instanceSpec = this.createInstanceSpec(port);
                    this.instanceSpecs.add(instanceSpec);
                    this.zookeeperServers.add(new TestingServer(instanceSpec, true));
                }
                logger.info("The ZookeeperRegistryCenter is started successfully");
            }
        } catch (Exception exception) {
            started.set(false);
            throw new RpcException("Failed to initialize ZookeeperRegistryCenter instance", exception);
        }
    }


    /**
     * destroy the zookeeper instances.
     */
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值