dubbo 项目环境组网方案

本文介绍了如何通过扩展Dubbo源码实现项目环境与开发环境的高效组网,解决微服务依赖不稳定和联调难题,优先调用本地机器服务,提升开发效率并降低成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

考虑到研发在项目开发中,因微服务化带来的依赖服务不稳定、联调不方便的问题,为减少开发过程中,因环境问题消耗的成本,现基于dubbo的源码的扩展,提供项目环境组网功能。

 

项目组网效果

 

部署说明

项目环境由本地机器启动的应用与开发环境的应用组成。

如上图案例,当前开发的项目涉及变更应用有

  1. 用户A负责的service-A,service-B在本地机器启动
  2. 用户B负责的service-D,在本地机器启动。
  3. 用户B同时在本地启动XXX-web,作为项目环境组网的入口。

调用链路

示例中,APP/H5向后端发起一个请求,调用顺序为

APP/H5 => XXX-web => service-A => service-B => service-C => service-D

  1. 请求到达用户B机器的XXX-web
  2. XXX-web需要请求service-A服务,此服务同时存在用户A机器与开发环境,因为用户机器的的服务优先级高,所以请求到用户A机器service-A.
  3. service-A.需要请求service-B服务,此服务同时存在用户A机器与开发环境,因为用户机器的的服务优先级高,所以请求到用户A机器service-B.
  4. service-B.需要请求service-C服务,此服务同时仅存在开发环境,所以请求到开发环境的service-C
  5. service-C需要请求service-D服务,此服务同时存在用户B机器与开发环境,因为用户机器的的服务优先级高,所以请求到用户B机器service-D.

服务调用过程

服务调用时,可以简单分为两个阶段,

  1. 获取服务提供者列表
  2. 远程调用服务

下面分别分析。

获取服务提供者列表

远程调用服务

获取服务提供者列表时,既能获取到项目环境的服务提供者,也能获取到稳定环境的服务提供者。

远程调用服务时,

  1. 如果服务存在项目环境,则优先调用项目环境的服务,如项目环境服务未找到,则调用稳定环境的服务
  2. 服务请求从项目环境的服务A调到稳定服务B,当服务B需要调用服务的下一个服务C,
    1. 如果服务C在项目环境存在,则调用到项目环境的服务C
    2. 否则,调用到开发环境的服务C

分组特性

消费者的group设置为*时,有以下特点

  • 在查找服务提供者时,只需要匹配服务接口。
  • 在调用服务时,可以匹配所有group不为空的服务提供者。

dubbo分组特性,正好与我们的项目环境组网相同。

在要组网时,所有相关开发约定一个dubbo group(假定为dev1)。需要在本地启动的应用使用"dev1"作为服务group。

< dubbo:reference id="xxxService" check="false" timeout = "60000" version="1.0.0" interface="com.ryze.service.opt.api.service.XXXService" group="*" />

开发环境启动的服务,统一使用group为"*"

< dubbo:reference id="xxxService" check="false" timeout = "60000" version="1.0.0" interface="com. ryze.service.opt.api.service.XXXService" group="*" />

要实前面所述的“XXX-web需要请求service-A服务,此服务同时存在用户A机器与开发环境,因为用户机器的的服务优先级高,所以请求到用户A机器service-A.”。还需要一种机制,在调用服务时,对服务列表进行过滤。

当月group为"*"是,消费调用会进入到“org.apache.dubbo.rpc.cluster.support.MergeableCluster”

 

 

 

而MergeableCluster的doJoin方法返回”org.apache.dubbo.rpc.cluster.support.MergeableClusterInvoker"实例。

MergeableClusterInvoker的doInvoke(Invocation,List<Invoker<T>>,LoadBalance)方法的逻辑是,将集群中的调用结果聚合起来返回结果。

 这个功能有点鸡肋,我们一般用不到。但我们可以利用这里的调用链做我们服务提供者列表过滤功能。因为MergeableCluster方法是代码写死引用MergeableClusterInvoker的。

我们可以复用dubbo spi机制重写“mergeable”指向自定义的ProjectMergeableCluster,在ProjectMergeableCluster中,我们再直接引用片定义的“ProjectMergeableClusterInvoker”

 
package org.apache.dubbo.demo.consumer.comp;

import org.apache.dubbo.rpc.RpcException;

import org.apache.dubbo.rpc.cluster.Directory;

import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;

import org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster;

public class ProjectMergeableCluster extends AbstractCluster {

public static final String NAME = "mergeable";

@Override

public <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {

return new ProjectMergeableClusterInvoker<T>(directory);

}

}
package org.apache.dubbo.demo.consumer.comp;

import org.apache.dubbo.common.constants.CommonConstants;

import org.apache.dubbo.common.utils.CollectionUtils;

import org.apache.dubbo.common.utils.StringUtils;

import org.apache.dubbo.rpc.*;

import org.apache.dubbo.rpc.cluster.Directory;

import org.apache.dubbo.rpc.cluster.LoadBalance;

import org.apache.dubbo.rpc.cluster.support.MergeableClusterInvoker;

import java.util.List;

public class ProjectMergeableClusterInvoker<T> extends MergeableClusterInvoker<T> {

public ProjectMergeableClusterInvoker(Directory directory) {

super(directory);

}

@Override

protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {

List<Invoker<T>> availableInvokers = null;

String projectGroup = RpcContext.getContext().getAttachment("projectGroup");

if(StringUtils.isBlank(projectGroup)){

projectGroup = ProjectEnvUtils.getGroup();

}

if(!StringUtils.isBlank(projectGroup)){

for(Invoker<T> invoker: invokers){

if(projectGroup.equals(invoker.getUrl().getParameter(CommonConstants.GROUP_KEY))){

availableInvokers.add(invoker);

}

}

}

if(CollectionUtils.isEmpty(availableInvokers)){

availableInvokers = invokers;

}

return super.doInvoke(invocation, availableInvokers, loadbalance);

}

}

ProjectMergeableClusterInvoker继承了MergeableClusterInvoker,ProjectMergeableClusterInvoker的doInvoke方法中,先完成服务列表invokers的过滤,然后再调用父类MergeableClusterInvoker的doInvoke。

源码地址:https://gitee.com/raisewang/ryze-commons

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值