zoukankan      html  css  js  c++  java
  • Springboot2.3+Dubbo2.7.3实现灰度跳转

    1、jar包依赖

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.0.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
    <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <scope>provided</scope>
            </dependency>
            <!-- Aapche Dubbo相关 start  -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>2.7.3</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>2.13.0</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.apache.zookeeper</groupId>
                        <artifactId>zookeeper</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.11</version>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-log4j12</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- Aapche Dubbo相关 end -->
    </dependencies>  

    2、自定义LoadBalance

    package com.pacmp.config.balance;
    
    
    
    import lombok.extern.slf4j.Slf4j;
    import org.apache.dubbo.common.URL;
    import org.apache.dubbo.rpc.Invocation;
    import org.apache.dubbo.rpc.Invoker;
    import org.apache.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance;
    import org.springframework.stereotype.Component;
    
    import java.util.*;
    import java.util.concurrent.ThreadLocalRandom;
    
    @Slf4j
    @Component
    public class GrayLoadBalance extends AbstractLoadBalance {
    
        public static final String NAME = "gray";
    
        public GrayLoadBalance() {
            log.info("初始化GrayLoadBalance成功!");
        }
    
        @Override
        protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
            List<Invoker<T>> list = new ArrayList<>();
            for (Invoker invoker : invokers) {
                list.add(invoker);
            }
            Map<String, String> map = invocation.getAttachments();
            String ifGary = map.get("ifGary");
            String userId = map.get("userId");
            log.info("userId:"+userId+"=====ifGary:"+ifGary);
            Iterator<Invoker<T>> iterator = list.iterator();
            while (iterator.hasNext()) {
                Invoker<T> invoker = iterator.next();
                String providerStatus = invoker.getUrl().getParameter("status", "prod");
                if (Objects.equals(providerStatus, NAME)) {
                    if ("1".equals(ifGary)) {
                        log.info("userId:"+userId+"=====ifGary:"+ifGary+"=====去灰度服务");
                        return invoker;
                    } else {
                        log.info("userId:"+userId+"=====ifGary:"+ifGary+"=====去正常服务");
                        iterator.remove();
                    }
                }
            }
            return this.randomSelect(list, url, invocation);
        }
    
    
        /**
         * 重写了一遍随机负载策略
         *
         * @param invokers
         * @param url
         * @param invocation
         * @param <T>
         * @return
         */
        private <T> Invoker<T> randomSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
            int length = invokers.size();
            boolean sameWeight = true;
            int[] weights = new int[length];
            int firstWeight = this.getWeight((Invoker) invokers.get(0), invocation);
            weights[0] = firstWeight;
            int totalWeight = firstWeight;
    
            int offset;
            int i;
            for (offset = 1; offset < length; ++offset) {
                i = this.getWeight((Invoker) invokers.get(offset), invocation);
                weights[offset] = i;
                totalWeight += i;
                if (sameWeight && i != firstWeight) {
                    sameWeight = false;
                }
            }
    
            if (totalWeight > 0 && !sameWeight) {
                offset = ThreadLocalRandom.current().nextInt(totalWeight);
    
                for (i = 0; i < length; ++i) {
                    offset -= weights[i];
                    if (offset < 0) {
                        return (Invoker) invokers.get(i);
                    }
                }
            }
            return (Invoker) invokers.get(ThreadLocalRandom.current().nextInt(length));
        }
    }

    3、在resources加配置文件,路径如下图(路径必须一致)

    文件名:org.apache.dubbo.rpc.cluster.LoadBalance

    添加GrayLoadBalance类的路径

    4、application.yml配置

    消费者配置:

    # dubbo
    dubbo:
      application:
        name: dubbo_consumer
      registry:
        address: zookeeper://127.0.0.1:2181
      scan:
        base-packages: com.pacmp.controller
      consumer:
        version: 2.0.0
      provider:
        loadbalance: gray
      protocol:
        port: 10000

    生产者配置:

    loadbalance: gray   表示加载自定义loadbalance:com.pacmp.config.balance.GrayLoadBalance。
    parameters:
          status: gray  表示这个生产者(服务),是否为灰度。如果不是灰度可以不用配置。
    ## Dubbo配置
    dubbo:
      application:
        name: dubbo_provider
      registry:
        address: zookeeper://127.0.0.1:2181
      protocol:
        name: dubbo
        port: -1
      scan:
        base-packages: com.pacmp
      provider:
        loadbalance: gray
        version: 2.0.0
        parameters:
          status: gray

    5、调用示例

    package com.pacmp.controller;
    
    
    import com.pacmp.service.DemoService;
    import lombok.extern.slf4j.Slf4j;
    
    
    import org.apache.dubbo.config.annotation.Reference;
    import org.apache.dubbo.rpc.RpcContext;
    import org.springframework.web.bind.annotation.*;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    import java.util.*;
    
    /**
     * @Author xxx
     * @Date 2020/05/26 9:52
     * @Version 1.0
     * @Description 接入层
     */
    @Slf4j
    @RestController
    @RequestMapping("/api")
    public class ApiController {
    
        @Reference(check = false)
        private DemoService demoService;
    
        @GetMapping("/testUser")
        public String testUser(int userId, String version) {
            //ifGary=1代表灰度用户,0代表普通用户
            int ifGary = 0;
            if(userId<10){
                ifGary = 1;
            }
            RpcContext.getContext().setAttachment("ifGary", String.valueOf(ifGary));
            RpcContext.getContext().setAttachment("userId", String.valueOf(userId));
            return demoService.testUser(userId, version);
        }
    
    }

    6、测试

    启2个生产者服务,1个消费者服务。可根据userId的不同来调用生产服务/灰度服务。

  • 相关阅读:
    getGuid()
    DELPHI7在WIN8和WIN10下安装和运行
    oracle存储过程返回数据集结果
    咏南多层开发框架支持最新的DELPHI 10 SEATTLE
    咏南中间件支持手机客户端
    最精简的IOCP封装
    完成端口iocp——在螺丝壳里做道场
    异步选择模式中使用完成端口做它的消息队列
    阿里百川IMSDK--自定义群聊界面
    Customizing Navigation Bar and Status Bar
  • 原文地址:https://www.cnblogs.com/penghq/p/13093812.html
Copyright © 2011-2022 走看看