定制设计Ribbon自定义负载策略实现灰度路由

定制设计这是一个基于实现的微定制设计服务灰度路由,定制设计实现了以下功能:

  • 动态修改ribbon负载策略
  • 定制设计随机权重的灰度路由(流量切分)
  • 指定Header定制设计匹配的灰度路由
  • 指定Cookie匹配的灰度路由
  • 指定请求参数的灰度路、

整体流程如下:

ribbon本质上是一个客户端负载工具,支持多种负载策略,并且支持自定义负载策略,因此我们就可以重写它的负载规则,并在运行时,动态修改规则,从指定位置(Header、Cookie等)获取参数,判断是否需要访问服务,达到灰度路由的目的。

    public static void changeLbRule(String name, IRule rule) {        ZoneAwareLoadBalancer loadBalancer = (ZoneAwareLoadBalancer) clientFactory.getLoadBalancer(name);        rule.setLoadBalancer(loadBalancer);        ((ZoneAwareLoadBalancer) clientFactory.getLoadBalancer(name)).setRule(rule);    }
  • 1
  • 2
  • 3
  • 4
  • 5

通过以上方法即可实时修改Ribbon的负责策略。SpringClientFactory是Ribbon的实例工厂,ribbon的配置、负载规则、实例的创建等都有用到它,我们通过它来获取到指定服务的loadbalabcer,然后再用自定义的负载策略替换原有的。

自定义负载规则如下:

/** * Loadbalancer rule for header */@Slf4jpublic class HeaderMatchRule extends AbstractMatcher {    @Override    public void initWithNiwsConfig(IClientConfig iClientConfig) {    }    @Override    public Server choose(Object key) {        ILoadBalancer lb = getLoadBalancer();        Server server;        if (!this.isMatch()) {            List<Server> notGrayServers = new ArrayList<>(lb.getReachableServers());            notGrayServers.removeAll(GrayRouteHelper.getGrayServer(lb));            server = choose(lb, key, notGrayServers);            log.debug("Not hit gray service, current instance:{}", server);        } else {            server = choose(lb, key, GrayRouteHelper.getGrayServer(lb));            log.debug("Hit gray service,use rule: HeaderMatchRule, current instance:{}", server);        }        return server;    }    @Override    @SuppressWarnings("Duplicates")    public boolean isMatch() {        Map<String, GatewayProperties.GrayRoute> all = GrayRouteHelper.getAll();        GatewayProperties.GrayRoute grayRoute = all.get(getName());        if (grayRoute == null || grayRoute.getServiceInstances().size() == 0) {            return false;        }        RequestContext ctx = RequestContext.getCurrentContext();        HttpServletRequest request = ctx.getRequest();        Enumeration<String> headerNames = request.getHeaderNames();        Map<String, Object> headers = grayRoute.getHeaders();        Set<String> headerSet = headers.keySet();        int count = 0;        while (headerNames.hasMoreElements()) {            String s = headerNames.nextElement();            if (headerSet.contains(s)) {                if (StringUtils.equals(request.getHeader(s), String.valueOf(headers.get(s)))) {                    count++;                }            }        }        return count == headerSet.size();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

以上是一个基于Header匹配的灰度路由负载规则,其中isMatch()用于判断当前路由是否是灰度路由,如果是,则从灰度服务实例里边选择一个实例,否则从非灰度服务实例中选择一个实例。

其中类关系如下:

完整代码:

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发