SpringCloud如何构建本地调试环境

在SpringCloud项目中,当需要调试单个服务时,无需搭建完整环境。可以通过前端设置请求头environment=dev,Nacos注册中心编辑服务元数据,Feign添加请求头拦截器,以及Ribbon扩展实现流量指定到本地服务C。这种方法同样适用于多版本并行测试和灰度发布场景。

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

前言

在Spring Cloud微服务项目中,通常会有多个服务,如果只是修改其中一个服务,该如何本地调试呢,如下图:


在这个项目中,只是修改了服务C,而我现在要在本地调试服务C,需要在本地搭建一套完整的环境吗,答案是不需要,我们只需要修改几个地方,就可以将流量指定到本地的服务C,如下图:


1.前端改造

浏览器中打开F12,在本地存储中添加environment=dev,如下图:

然后前端在发起http请求的时候,读取上面配置,在每个请求中添加请求头environment=dev。至此,前端改造完成。

2.注册中心改造

这里注册中心用的是nacos,在nacos控制台上找到对应的实例,编辑元数据,加上environment=dev,如下图
image.png

3.Feign改造

实际上,前端传递的请求头environment只会通过网关传递到服务A,而服务A到服务B的链路中,Feign默认不会添加environment头,所以我们需要通过RequestInterceptor手动添加请求头,如下:

@Component
public class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getRequest();
            String requestEnvironment = request.getHeader(HEADER_ENVIRONMENT);
            if (StringUtils.isNotBlank(requestEnvironment)) {
                requestTemplate.header(HEADER_ENVIRONMENT, requestEnvironment);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
4.Ribbon改造

Ribbon是微服务架构中的负载均衡组件,它提供了IRule接口作为扩展点,使我们很容易在服务转发中加入自定义逻辑,Nacos框架提供了NacosRule,我们可以作为参考,实现流量的指定,如下

public class NacosExtendRule extends AbstractLoadBalancerRule {
    private static final Logger LOGGER = LoggerFactory.getLogger(NacosExtendRule.class);

    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Autowired
    private NacosServiceManager nacosServiceManager;

    public final static String HEADER_ENVIRONMENT = "environment";

    public NacosExtendRule() {
    }

    public Server choose(Object key) {
        try {
            String requestEnvironment = null;
            try {//尝试获取请求头中的environment
                HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getRequest();
                requestEnvironment = request.getHeader(HEADER_ENVIRONMENT);
            } catch (Exception ex) {
            }
            String environment = requestEnvironment;

            String group = this.nacosDiscoveryProperties.getGroup();
            DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) this.getLoadBalancer();
            String name = loadBalancer.getName();
            NamingService namingService = this.nacosServiceManager.getNamingService(this.nacosDiscoveryProperties.getNacosProperties());
            List<Instance> instances = namingService.selectInstances(name, group, true);

            List<Instance> instancesToChoose = null;
            if (StringUtils.isNotBlank(environment)) { //如果环境配置不为空,先找对应环境的实例列表
                instancesToChoose = instances.stream().filter(x -> Objects.equals(environment, x.getMetadata().get(HEADER_ENVIRONMENT))).collect(Collectors.toList());
            }
            if (CollectionUtils.isEmpty(instancesToChoose)) { //如果实例列表为空,则尝试找环境为空的实例列表
                instancesToChoose = instances.stream().filter(x -> x.getMetadata().get(HEADER_ENVIRONMENT) == null).collect(Collectors.toList());
            }

            if (CollectionUtils.isEmpty(instancesToChoose)) {
                LOGGER.warn("no instance in service {}", name);
                return null;
            }
            Instance instance = ExtendBalancer.getHostByRandomWeight2(instancesToChoose);
            return new NacosServer(instance);
        } catch (Exception var10) {
            LOGGER.warn("NacosRule error", var10);
            return null;
        }
    }

    public void initWithNiwsConfig(IClientConfig iClientConfig) {
    }
}

NacosExtendRule的逻辑主要是获取HttpServletRequest的请求头environment,如果存在则匹配元数据中的environment,匹配不到就寻找元数据为空的注册实例。

扩展

其实不止本地调试场景需要指定流量,还有下面场景:

  • 项目中有多个版本迭代,例如V1.1版本修改AB,V1.2版本修改C,两个版本都需要测试,这个时候就需要配置两个environment。
  • 生产环境中需要灰度上线,这个时候可以根据用户或者其他条件指定部分流量到新上线的服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值