/** * 灰度发布的规则 */
public class GrayRule extends ZoneAvoidanceRule {
@Override
public void initWithNiwsConfig(IClientConfig clientConfig){}
@Override
public Server choose(Object key){
try {//从ThreadLocal中获取灰度标记
boolean grayTag = GrayRequestContextHolder.getGrayTag().get();//获取所有可用服务
List<Server> serverList = this.getLoadBalancer().getReachableServers();//灰度发布的服务
List<Server> grayServerList = new ArrayList<>();//正常的服务
List<Server> normalServerList = new ArrayList<>();
for(Server server : serverList){
NacosServer nacosServer =(NacosServer) server;//从nacos中获取元素剧进行匹配
if(nacosServer.getMetadata().containsKey(GrayConstant.GRAY_HEADER)&& nacosServer.getMetadata().get(GrayConstant.GRAY_HEADER).equals(GrayConstant.GRAY_VALUE)){
grayServerList.add(server);} else {
normalServerList.add(server);}}//如果被标记为灰度发布,则调用灰度发布的服务
if(grayTag){
return originChoose(grayServerList,key);} else {
return originChoose(normalServerList,key);}} finally {//清除灰度标记
GrayRequestContextHolder.remove();}}
private Server originChoose(List<Server> noMetaServerList, Object key){
Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(noMetaServerList, key);
if (server.isPresent()){
return server.get();} else {
return null;}}}
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.
逻辑很简单,如下:
获取灰度标记
从Nacos注册中心获取灰度服务和正常服务
根据灰度标记去判断,如果灰度发布则选择特定的灰度服务进行转发
定义一个配置类,注入改造的灰度策略GrayRule,如下:
/** * 灰度部署的负载规则配置类 * 注意:这个类一定不要被Spring Boot 扫描进入IOC容器中,一旦扫描进入则对全部的服务都将生效 */
public class GrayRuleConfig {
@Bean
public GrayRule grayRule(){
return new GrayRule();}}
@RibbonClients(value ={//指定对comments这个服务开启灰度部署
@RibbonClient(value ="comments",configuration = GrayRuleConfig.class)})
public class ArticleApplication {}