Springboot2.3+Dubbo2.7.3实现灰度跳转
Posted 小泉哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的不同来调用生产服务/灰度服务。
以上是关于Springboot2.3+Dubbo2.7.3实现灰度跳转的主要内容,如果未能解决你的问题,请参考以下文章
springboot2.3.7升级到springboot2.7.2
有几千个 Dubbo 实例的瓜子二手车,为什么要选择2.7.3版本?