SpringCloud灰度发布的设计与实现详解
作者:魔笛Love
这篇文章主要介绍了SpringCloud灰度发布的设计与实现详解,灰度从字面意思理解就是存在于黑与白之间的一个平滑过渡的区域,所以说对于互联网产品来说,上线和未上线就是黑与白之分,而实现未上线功能平稳过渡的一种方式就叫做灰度发布,需要的朋友可以参考下
灰度发布
什么是灰度发布呢?要想了解这个问题就要先明白什么是灰度。
灰度从字面意思理解就是存在于黑与白之间的一个平滑过渡的区域,所以说对于互联网产品来说,上线和未上线就是黑与白之分,而实现未上线功能平稳过渡的一种方式就叫做灰度发布。
在一般情况下,升级服务器端应用,需要将应用源码或程序包上传到服务器,然后停止掉老版本服务,再启动新版本。
但是这种简单的发布方式存在两个问题,一方面,在新版本升级过程中,服务是暂时中断的,另一方面,如果新版本有BUG,升级失败,回滚起来也非常麻烦,容易造成更长时间的服务不可用。
在了解了什么是灰度发布的定义以后,就可以来了解一下灰度发布的具体操作方法了。
可以通过抽取一部分用户,比如说选择自己的测试用户,使这些用户的请求全部访问灰度发布的服务,正式用户请求走正常上线的服务,那么就能够将需要灰度发布的版本也连接到正常上线服务中进行测试,没有问题之后将其设置为正常服务即完成版本的上线测试和发布。
实现设计
实现重点主要在:
- 利用 ThreadLocal+Feign 实现 http head 中实现信息的传递
- 使用Nacos的元数据,定义需要的灰度服务
- 自定义Ribbon的路由规则,根据Nacos的元数据选择服务节点
公共配置
ThreadLocal
public class PassParameters { private static final Logger log = LoggerFactory.getLogger(PassParameters.class); private static final ThreadLocal localParameters = new ThreadLocal(); public static PassParametersModel get(){ PassParametersModel model = (PassParametersModel) localParameters.get(); log.info("ThreadID:{}, threadLocal {}", Thread.currentThread().getId(), model.toString()); return model; } public static void set(PassParametersModel model){ log.info("ThreadID:{}, threadLocal set {}", Thread.currentThread().getId(), model.toString()); localParameters.set(model); } }
携带灰度发布相关数据的类
public class PassParametersModel { private String token; private String grayPublish; }
请求头常量
public class HttpConstants { public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String GRAY_PUBLISH = "Gray-Publish"; public static final String GRAY_PUBLISH_MEAT_KEY = "grayPublish"; }
AOP请求拦截处理
@Aspect @Order(1) @Component public class PermissionsValidationAspect { private final Logger logger = LoggerFactory.getLogger(getClass()); /** * 权限校验以及一些参数的赋值O * @param joinPoint * @return * @throws Throwable */ @Around(value = "需要拦截的方法") public Object check(ProceedingJoinPoint joinPoint) throws Throwable { // 获取一些参数 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String token = request.getHeader(HttpConstants.AUTHORIZATION_HEADER); // FIXME: // token权限校验,不要去查数据库!!!! // 来这里的token肯定都是有用的,因为在网关那里就会进行token有效的校验 // 校验成功之后进行用户身份的赋值,比如uid、username等关键信息 // 本次请求涉及到的灰度发布 // FIXME: 通过用户所属的用户组或其他标识信息,专门指定某些用户是灰度发布测试用户,来设置灰度发布的字段 String grayPublish = request.getHeader(HttpConstants.GRAY_PUBLISH); PassParametersModel model = new PassParametersModel(); model.setToken(token); model.setGrayPublish(grayPublish); PassParameters.set(model); return joinPoint.proceed(); } }
Feign配置
Ribbon请求规则
将会从Nacos中获取元服务器的信息,并根据这个信息选择服务器。
public class GrayPublishInterceptor implements RequestInterceptor { private Logger log = LoggerFactory.getLogger(this.getClass()); @Override public void apply(RequestTemplate requestTemplate) { PassParametersModel model = PassParameters.get(); // token if (StringUtils.isNotEmpty(model.getToken())) { requestTemplate.header(HttpConstants.AUTHORIZATION_HEADER, model.getToken()); } // grayPublish if (StringUtils.isNotEmpty(model.getGrayPublish())) { requestTemplate.header(HttpConstants.GRAY_PUBLISH, model.getGrayPublish()); } // FIXME: 补充其他需要传递的内容 } }
Feign拦截器
将需要传递给下个微服务中的数据进行赋值
public class GrayPublishInterceptor implements RequestInterceptor { private Logger log = LoggerFactory.getLogger(this.getClass()); @Override public void apply(RequestTemplate requestTemplate) { PassParametersModel model = PassParameters.get(); // token if (StringUtils.isNotEmpty(model.getToken())) { requestTemplate.header(HttpConstants.AUTHORIZATION_HEADER, model.getToken()); } // grayPublish if (StringUtils.isNotEmpty(model.getGrayPublish())) { requestTemplate.header(HttpConstants.GRAY_PUBLISH, model.getGrayPublish()); } // FIXME: 补充其他需要传递的内容 } }
配置使用
这里是全局配置使用
@Configuration public class FeignConfig { // 灰度发布Ribbon规则 @Bean public IRule getRule(){ return new GrayPublishRibbonRule(); } // header传递 @Bean public GrayPublishInterceptor getInterceptor(){ return new GrayPublishInterceptor(); } }
Nacos元数据配置
通过在application.yml进行配置
# 服务的元数据 spring: cloud: nacos: discovery: metadata.grayPublish: HAHAHA_TEST
到此这篇关于SpringCloud灰度发布的设计与实现详解的文章就介绍到这了,更多相关SpringCloud灰度发布内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!