成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring Cloud Gateway + Nacos 實現服務上下線無縫切換

開發(fā) 前端
這里通過去監(jiān)聽 Nacos 實例刷新事件,一旦出現實例發(fā)生變化馬上刪除緩存。在刪除負載均衡緩存后,Spring Cloud Gateway 在處理請求時發(fā)現沒有緩存會重新拉取一遍服務列表,這樣之后都是用的是最新的服務列表了,也就達到了我們動態(tài)感知上下線的目的。

?大家好,我是不才陳某~

最近知識星球的球友在學習星球中的《精盡Spring Cloud Alibaba》專欄提到一個問題,相信也有很多人在線上環(huán)境遇到過,或許也因此被批過:一個集群中有某個服務突然下線,但是網關還是會去請求這個實例,所以線上就報錯了,報錯信息如下圖:

圖片

究其原因到底為何呢?有沒有一種靠譜的解決方案呢?別著急,往下看

產生原因

Gateway中有個緩存 CachingRouteLocator ,而網關服務使用的是lb模式,服務在上線或者下線之后,未能及時刷新這個緩存,相應的源碼如下:

public class CachingRouteLocator implements Ordered, RouteLocator,
ApplicationListener<RefreshRoutesEvent>, ApplicationEventPublisherAware {

private static final Log log = LogFactory.getLog(CachingRouteLocator.class);

private static final String CACHE_KEY = "routes";

private final RouteLocator delegate;

private final Flux<Route> routes;

private final Map<String, List> cache = new ConcurrentHashMap<>();

private ApplicationEventPublisher applicationEventPublisher;

public CachingRouteLocator(RouteLocator delegate) {
this.delegate = delegate;
routes = CacheFlux.lookup(cache, CACHE_KEY, Route.class)
.onCacheMissResume(this::fetch);
}

private Flux<Route> fetch() {
return this.delegate.getRoutes().sort(AnnotationAwareOrderComparator.INSTANCE);
}

@Override
public Flux<Route> getRoutes() {
return this.routes;
}

/**
* Clears the routes cache.
* @return routes flux
*/
public Flux<Route> refresh() {
this.cache.clear();
return this.routes;
}

@Override
public void onApplicationEvent(RefreshRoutesEvent event) {
try {
fetch().collect(Collectors.toList()).subscribe(list -> Flux.fromIterable(list)
.materialize().collect(Collectors.toList()).subscribe(signals -> {
applicationEventPublisher
.publishEvent(new RefreshRoutesResultEvent(this));
cache.put(CACHE_KEY, signals);
}, throwable -> handleRefreshError(throwable)));
}
catch (Throwable e) {
handleRefreshError(e);
}
}

private void handleRefreshError(Throwable throwable) {
if (log.isErrorEnabled()) {
log.error("Refresh routes error !!!", throwable);
}
applicationEventPublisher
.publishEvent(new RefreshRoutesResultEvent(this, throwable));
}

@Deprecated
/* for testing */ void handleRefresh() {
refresh();
}

@Override
public int getOrder() {
return 0;
}

@Override
public void setApplicationEventPublisher(
ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
}

那么解決方案就自然能夠想出來,只需要在服務下線時能夠去實時的刷新這個緩存自然就解決了

解決方案

這里通過去監(jiān)聽 Nacos 實例刷新事件,一旦出現實例發(fā)生變化馬上刪除緩存。在刪除負載均衡緩存后,Spring Cloud Gateway 在處理請求時發(fā)現沒有緩存會重新拉取一遍服務列表,這樣之后都是用的是最新的服務列表了,也就達到了我們動態(tài)感知上下線的目的。

代碼如下:

@Component
@Slf4j
public class NacosInstancesChangeEventListener extends Subscriber<InstancesChangeEvent> {
@Resource
private CacheManager defaultLoadBalancerCacheManager;

@Override
public void onEvent(InstancesChangeEvent event) {
log.info("Spring Gateway 接收實例刷新事件:{}, 開始刷新緩存", JacksonUtils.toJson(event));
Cache cache = defaultLoadBalancerCacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME);
if (cache != null) {
cache.evict(event.getServiceName());
}
log.info("Spring Gateway 實例刷新完成");
}

@Override
public Class<? extends com.alibaba.nacos.common.notify.Event> subscribeType() {
return InstancesChangeEvent.class;
}
}

這里通過繼承的方式監(jiān)聽 Nacos 的 InstancesChangeEvent?,在 onEvent 接收到實例刷新的信息后直接刪除對應服務的負載均衡緩存,緩存的名字是定義在 Spring Gateway 的相關代碼中的,直接引入即可,Cache 則是繼承自 Spring Cache 接口,負載均衡緩存也繼承了 Cache 接口,有了 Cache 接口就可以直接使用其接口定義的 evict 方法即可,而緩存的 key 名就則就是服務名,在 InstancesChangeEvent 中,通過 getServiceName 就可以得到服務名。

這里就不演示了,有興趣的小伙伴可以測試一下

責任編輯:武曉燕 來源: 碼猿技術專欄
相關推薦

2025-05-27 02:55:00

Spring微服務

2023-02-20 10:13:00

灰度發(fā)布實現

2022-02-07 07:10:32

服務注冊功能

2024-05-13 18:35:06

負載均衡主機端口

2019-08-22 09:55:17

RedisAPI數據

2024-01-29 08:00:00

架構微服務開發(fā)

2023-03-08 09:03:55

2024-07-29 08:24:43

2022-08-15 09:22:12

JWT認證系統(tǒng)

2021-07-07 07:44:20

微服務Nacos緩存

2023-02-04 18:19:39

2023-11-09 08:31:56

Spring微服務網關

2021-01-14 07:54:19

Spring Clou應用路由

2023-01-26 01:41:27

核心全局過濾器

2022-01-07 07:29:08

Rbac權限模型

2023-07-24 08:00:56

客戶端訪問指定

2023-09-12 13:12:23

服務器系統(tǒng)

2023-02-13 08:10:40

Gateway網關Spring

2023-09-15 08:18:49

cookie網關代理

2021-11-04 10:11:02

Sentinel網關限流
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩三级在线观看 | 一区二区在线 | 爱操影视 | 免费国产网站 | 国产99久久精品一区二区永久免费 | 久久久91精品国产一区二区精品 | 涩在线 | 国产精品国产a级 | 在线视频 欧美日韩 | 亚洲精品免费视频 | 日韩一区二区三区在线播放 | 国产乱码精品一区二区三区忘忧草 | 日韩在线国产 | 欧美日韩不卡 | 色久电影| 91人人视频在线观看 | 国内精品一区二区 | 亚洲综合精品 | 成人亚洲性情网站www在线观看 | 色婷婷久久久亚洲一区二区三区 | 日韩视频在线一区二区 | 久久精品国产99国产 | 91视频一区二区 | 亚洲欧美一区二区三区国产精品 | 成人三级在线播放 | 日韩中文一区 | 正在播放国产精品 | 国产乱码精品一区二区三区av | 一呦二呦三呦国产精品 | 午夜影晥| 欧美一区二区三区 | 午夜成人免费电影 | 亚洲一区二区三区免费在线 | 日本午夜精品一区二区三区 | 国产一二三区免费视频 | 日韩一区二区三区在线 | 99综合| 久久久久久久一区 | 成人av高清在线观看 | 亚洲一区二区三区在线免费观看 | 最新国产精品 |