金丝雀部署在联调和测试阶段的使用

5 篇文章 0 订阅
3 篇文章 0 订阅

痛点

在联调和测试阶段,我们都需要环境,包括前段和后端。如何使用环境?可以使用一个环境,比如dev后者dit。但这样相互影响太严重,我一段代码发布一下,其他人改代码再发布一下,如果修改的有问题可能会影响其他人的联调和测试。
在这里插入图片描述

解决办法

金丝雀部署。有一下四个问题需要解决,一个一个来,慢慢更新

  1. 前端使用nginx
  2. 后端Nacos+FeignClient使用分组实现
  3. 后端网关
  4. 后端mq组件

具体实现

一、前端使用nginx

见:https://blog.csdn.net/o544033135/article/details/128339764
如果想动态,需要使用Kong或者Openrest

二、Nacos+FeignClient

方法一,使用分组实现

服务启动时指定分组,此时,同组的服务才能进行交互。

spring:
  application:
    name: demo
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        group: group001

但是这里有个问题,如果同组没有服务就调用失败了。如果想在同组没有服务的情况下仍然可以发起调用,需要自定义规则。

方法二,自定义路由

使用自定义IRule,修复负载算法,从所有服务端中选择同一个canary环境的服务进行调用,如果没有,则选择稳定环境,代码如下。需要增加这个配置【canary.enable=true】自定义规则才会生效
`package com.org.demo.config;

import com.alibaba.cloud.nacos.ribbon.NacosServerIntrospector;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.stereotype.Component;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.stream.Collectors;

/**

  • 灰度规则

  • @author dzh

  • @date 2023/1/4 8:26
    */
    @Component
    @ConditionalOnProperty(name = “canary.enable”, havingValue = “true”)
    public class CanaryRule implements IRule {
    public static final String CANARY_KEY = “canary”;
    ILoadBalancer loadBalancer;
    LinkedHashSet serverList = new LinkedHashSet<>();
    int index = 0;
    @Value(“${spring.cloud.nacos.discovery.metadata.canary}”)
    String canary;
    ServerIntrospector serverIntrospector = new NacosServerIntrospector();

    @Override
    public Server choose(Object key) {
    filterServer();
    if (serverList.size() == 0) {
    return null;
    }
    return serverList.stream().skip(index++ % serverList.size()).findFirst().orElse(null);
    }

    void filterServer() {

     if (serverList.size() > 1) {
         return;
     }
    
     boolean hasCanary = loadBalancer.getReachableServers().stream()
             .anyMatch(server -> StringUtils.equals(serverIntrospector.getMetadata(server).get(CANARY_KEY), canary));
    
     // 默认获取没有指定虚拟环境的服务
     String[] canaryCompare = new String[]{""};
     if (hasCanary) {
         // 如果有同名指定的虚拟环境,则选择
         canaryCompare[0] = canary;
     }
     List<Server> serverList = loadBalancer.getReachableServers().stream()
             .filter(server -> StringUtils.equals(serverIntrospector.getMetadata(server).get(CANARY_KEY), canaryCompare[0]))
             .collect(Collectors.toList());
    
     // 选择结果为同名灰度环境或者非灰度环境的服务
     this.serverList.addAll(serverList);
    

    }

    @Override
    public void setLoadBalancer(ILoadBalancer lb) {
    loadBalancer = lb;
    }

    @Override
    public ILoadBalancer getLoadBalancer() {
    return loadBalancer;
    }
    }
    `

带来问题

需要更多的资源。因为每个人都需要启动实例。其实可以在本地启动服务节省资源,启动服务也方便。

后端网关

  1. 服务注册。启动Canary环境实例时,需要使用新的应用名称。比如应用叫payment,虚拟环境叫xxo,注册到nacos上的时候,应用会变成payment-xxo,如图
    在这里插入图片描述
    实现逻辑:配置环境变量或者启动参数,在application.yml配置中获取,上代码
spring:
  cloud:
    nacos:
      discovery:
        service: ${spring.application.name}${CANARY:}
        server-addr: server.local.cn:8848
  1. 路由配置
    有了Canary服务以后,网关可以配置对应的路由,让指定的请求分发到制定的Canary环境。代码如下,意思是,如果Cokkie中的Canary的值是xxo的话,将请求发到payment-xxo这台实例。
      routes:
        - id: payment-xxo
          uri: lb://payment-xxo
          predicates:
            - Path=/payment/**
            - Cookie=Canary, xxo

存在问题

  1. 每个虚拟环境都有自己的路由配置,后续可能虚拟环境不用了,这个路由配置就是垃圾数据。我肯可以启动定时任务进行清理,前提是这些配置在数据库中。
  2. 不够智能。我们需要手动配置路由,不方便。可以结合devops,如果有Canary环境实例上线就注册路由。路由一定时间有效,可以进行续期

四、后端mq组件

待更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值