#yyds干货盘点#使用Ribbon完成应用灰度发布

Posted 温哈哈哈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点#使用Ribbon完成应用灰度发布相关的知识,希望对你有一定的参考价值。

使用Ribbon完成应用灰度发布

定义RibbonRequestContext

public class RibbonRequestContext 

    private final Map<String, String> attr = new HashMap<>();

    public String put(String key, String value) 
        return attr.put(key, value);
    

    public String remove(String key) 
        return attr.remove(key);
    

    public String get(String key) 
        return attr.get(key);
    

维护一个map,用于透传解析的请求信息。

RibbonRequestContextHolder:

public class RibbonRequestContextHolder 

    private static ThreadLocal<RibbonRequestContext> holder = new ThreadLocal<RibbonRequestContext>() 
        @Override
        protected RibbonRequestContext initialValue() 
            return new RibbonRequestContext();
        
    ;

    public static RibbonRequestContext getCurrentContext() 
        return holder.get();
    

    public static void setCurrentContext(RibbonRequestContext context) 
        holder.set(context);
    

    public static void clearContext() 
        holder.remove();
    

持有自定义的RibbonRequestContext

然后定义GrayRequestInterceptor

public class GrayInterceptor implements ClientHttpRequestInterceptor 

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
        throws IOException 
        if (request.getHeaders().containsKey("Gray")) 
            String value = request.getHeaders().getFirst("Gray");
            if (value.equals("true")) 
                RibbonRequestContextHolder.getCurrentContext().put("Gray", Boolean.TRUE.toString());
                ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
                attributes.setAttribute("Gray", Boolean.TRUE.toString(), 0);
            
        
        return execution.execute(request, body);
    

GrayRequestInterceptor加入到RestTemplate

        @Bean
    @LoadBalanced
    public RestTemplate restTemplate() 
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getInterceptors().add(new GrayInterceptor());
        return restTemplate;
    

        @Bean
    public IRule myRule() 
        return new GrayRule();
    

自定义IRule:

ublic class GrayRule extends AbstractLoadBalancerRule 

    private Random random = new Random();

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) 

    

    @Override
    public Server choose(Object key) 
        boolean grayInvocation = false;
        try 
            String grayTag = RibbonRequestContextHolder.getCurrentContext().get("Gray");
            if(!StringUtils.isEmpty(grayTag) && grayTag.equals(Boolean.TRUE.toString())) 
                grayInvocation = true;
            

            List<Server> serverList = this.getLoadBalancer().getReachableServers();
            List<Server> grayServerList = new ArrayList<>();
            List<Server> normalServerList = new ArrayList<>();
            for(Server server : serverList) 
                NacosServer nacosServer = (NacosServer) server;
                if(nacosServer.getMetadata().containsKey("gray") && nacosServer.getMetadata().get("gray").equals("true")) 
                    grayServerList.add(server);
                 else 
                    normalServerList.add(server);
                
            

            if(grayInvocation) 
                return grayServerList.get(random.nextInt(grayServerList.size()));
             else 
                return normalServerList.get(random.nextInt(normalServerList.size()));
            
         finally 
            RibbonRequestContextHolder.clearContext();
        
    

服务提供者通过spring.cloud.nacos.discovery.metadata.gray=false 配置项决定元数据内容

最后发起服务调用的时候传递Header中的Gray信息,如果为true,只会路由到灰度实例,否则路由到正常实例。

OpenFeign配置拦截:

public class GrayRequestInterceptor implements RequestInterceptor 
    @Override
    public void apply(RequestTemplate template) 
        if (template.headers().containsKey("Gray")) 
            String value = template.headers().get("Gray").iterator().next();
            if (value.equals("true")) 
                RibbonRequestContextHolder.getCurrentContext().put("Gray", Boolean.TRUE.toString());
            
        
    

以上是关于#yyds干货盘点#使用Ribbon完成应用灰度发布的主要内容,如果未能解决你的问题,请参考以下文章

ELkStack集群核心概念 #yyds干货盘点#

#yyds干货盘点# 常用软件框架,总有一个用的上

Session与Token认证机制 前后端分离下如何登录 #yyds干货盘点#

#yyds干货盘点#YUV采样

SpringCache #yyds干货盘点#

#yyds干货盘点# 基于STM32+ESP8266+华为云IoT设计的健康管理系统并完成应用侧开发