Spring Cloud 简单灰度发布
需求
新建三个项目:
demo-server
服务端demo-client
客户端demo-gateway
网关层
现在希望可以根据用户请求调用不同版本的代码,如下所示
gateway -> client(v1版本) -> server(v1版本)
-> client(v2版本) -> server(v2版本)
分析
可知,gateway
项目和client
项目,需要我们根据不同参数来干涉负载分发。Spring Cloud是使用ribbon
作为负载均衡,这里我们引入如下pom依赖:
<dependency>
<groupId>io.jmnarloch</groupId>
<artifactId>ribbon-discovery-filter-spring-cloud-starter</artifactId>
<version>2.1.0</version>
</dependency>
GitHub:https://github.com/jmnarloch/ribbon-discovery-filter-spring-cloud-starter
其原理是通过匹配请求里面的路由参数与Eureka
注册中心上实例配置的metadata
里面的参数值,如果都匹配上了,才选择该实例节点。
实现
gateway项目
在AccessFilter extends ZuulFilter
的run方法中增加如下代码:
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
//灰度示例
RibbonFilterContextHolder.clearCurrentContext();
String version = request.getHeader("dispatch-version");
if (version != null && !"".equals(version)) {
RibbonFilterContextHolder.getCurrentContext().add("dispatch-version", version);
}
注意:gateway
项目记得配置zuul.routes.client-api.sensitiveHeaders=Cookie,Set-Cookie,Authorization
client项目
新增WebMvcConfig
类
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
registry.addInterceptor(new VersionInterceptor());
}
}
新增VersionInterceptor
类
import io.jmnarloch.spring.cloud.ribbon.support.RibbonFilterContextHolder;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class VersionInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
RibbonFilterContextHolder.clearCurrentContext();
String version = request.getHeader("dispatch-version");
if (version != null && !"".equals(version)) {
RibbonFilterContextHolder.getCurrentContext().add("dispatch-version", version);
}
return true;
}
}
在application.yml
里增加:
eureka:
instance:
metadata-map:
dispatch-version: v1
server项目
在application.yml
里增加:
eureka:
instance:
metadata-map:
dispatch-version: v1
验证
- 启动
gateway
,client
,server
项目 - 模拟请求在header里面设置
dispatch-version=v1
,发现访问正常,如果把dispatch-version
改成v
2,发现访问不了 - 这时,修改
client
和server
项目的端口,并且dispatch-version
改成v2
,再启动新实例,这时再模拟请求dispatch-version=v2
,发现访问正常。 - 来回修改
dispatch-version
的值,发现v1
的请求只会访问v1
版本,v2
的请求只会访问v2
版本。至此,灰度发布的demo已验证成功。
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/26/spring-cloud-simple-gray-publish/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论