自定义Ribbon的IRule实现服务之间的灰度发布

概述

为实现服务和服务之间调用能通过版本号来控制服务调用规则,避免开发人员需要启动所有的服务才能进行业务测试

实现loadbalancer提供的ZoneAvoidanceRule类

public class VersionHandler extends ZoneAvoidanceRule {
    private static final Logger log = LoggerFactory.getLogger(VersionHandler.class);
    @Autowired
    private DiscoveryClient discoveryClient;
    @Value("${eureka.instance.metadata-map.version:#{null}}")
    public String version;
    public VersionHandler() {
    }

    public Server choose(Object key) {
        
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest httpServletRequest = ((ServletRequestAttributes) requestAttributes).getRequest();
String version =httpServletRequest.getHeader("version");
return getServerByVersion(version,key);
    }

    /**
     * 通过版本号获取服务
     * @param version
     * @param key
     * @return
     */
    private  Server getServerByVersion(String version,Object key){
        if(StringUtils.isEmpty(version)){
            version = version;
        }
        ILoadBalancer lb = this.getLoadBalancer();
        List<Server> upList = lb.getReachableServers();
        Server server1 = this.getServerByVersion(version, upList);
        if (null != server1) {
            log.info("通过版本号version==[{}],获取服务ip==[{}],端口号port==[{}]",version,server1.getHost(),server1.getPort());
            return server1;
        } else {
            log.info("版本号version==[{}]未获取到对应服务,走轮循",version);
            Optional<Server> server_opt = this.getPredicate().chooseRoundRobinAfterFiltering(lb.getAllServers(), key);
            return server_opt.isPresent() ? (Server)server_opt.get() : null;
        }
    }


    /**
     * 过滤服务
     * @param version
     * @param upList
     * @return
     */
    private Server getServerByVersion(String version, List<Server> upList){
        Server server =null;
        //判断版本号是否配置多个
        if (!StringUtils.isEmpty(version) && version.contains(",")){
            String[] versions = version.split(",");
            for (String ver : versions) {
                server = this.getServer(ver, upList);
                if (server != null){
                    break;
                }
            }
        }else {
            server = this.getServer(version, upList);
        }
        return  server;
    }


    /**
     * 过滤服务
     * @param version
     * @param upList
     * @return
     */
    private Server getServer(String version, List<Server> upList) {
        if (!StringUtils.isEmpty(version) && !CollectionUtils.isEmpty(upList) && upList.size() >= 1) {
            String[] split = ((Server)upList.get(0)).getMetaInfo().getAppName().split("@");
            String appName = split[split.length - 1];
            List<ServiceInstance> sis = this.discoveryClient.getInstances(appName);
            Iterator var6 = upList.iterator();

            while(var6.hasNext()) {
                Server server = (Server)var6.next();
                Iterator var8 = sis.iterator();

                while(var8.hasNext()) {
                    ServiceInstance si = (ServiceInstance)var8.next();
                    if (server.getHost().equals(si.getHost()) && server.getPort() == si.getPort() && version.equals(si.getMetadata().get("version"))) {
                        return server;
                    }
                }
            }
        }

        return null;
    }
}

将自定义的规则注入到spring容器内

 

@Configuration
public class SelfRuleConfig {

    @Bean
    public AbstractLoadBalancerRule metadataAwareRule() {
        return new VersionHandler();
    }

}

 RibbonClient客户端全局设置成自定义的规则

@Configuration
@RibbonClients(defaultConfiguration = SelfRuleConfig.class)
public class RuleConfig {

}

在配置类上配置eureka对应的版本号

eureka.instance.metadata-map.version=system-1

前端请求头version值为system-1既可以找到对应服务

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值