[Java微服務組件]注冊中心P3-Nacos中的設計模式1-觀察者模式

在P1-簡單注冊中心實現和P2-Nacos解析中,我們分別實現了簡單的注冊中心并總結了Nacos的一些設計。
本篇繼續看Nacos源碼,了解一下Nacos中的設計模式。

目錄

  • Nacos 觀察者模式 Observer Pattern
  • 觀察者模式總結

Nacos 觀察者模式 Observer Pattern

模式定義:觀察者模式是一種行為型模式,定義對象間一對多依賴,確保當一個對象變化時,其依賴對象也會被通知并自動更新。

在配置管理中,客戶端 (ConfigService) 注冊監聽器 (Listener) 來監聽特定 dataId 和 group 的配置變更。當 Nacos Server 上的配置發生變化時,會通知所有監聽該配置的客戶端。
在服務發現中,客戶端 (NamingService) 訂閱 (subscribe) 特定服務名。當該服務的實例列表(上線、下線、狀態變更)發生變化時,Nacos Server 會將最新的服務實例列表推送給所有訂閱的客戶端。
這種推送機制和探測機制不一樣,是不區分服務實例是持久化(persistent)還是臨時(ephemeral)實例的,都會觸發通知。

下面是簡單的模擬:

// 觀察者接口 (Nacos 客戶端 Listener)
public interface ConfigObserver {void onConfigChange(String dataId, String group, String newContent);
}
// 被觀察者 (Nacos 配置中心)
public class ConfigSubject {private Map<String, List<ConfigObserver>> observers = new HashMap<>();private Map<String, String> configStore = new HashMap<>(); // 模擬配置存儲private String getConfigKey(String dataId, String group) {return dataId + "@" + group;}// 注冊觀察者 (客戶端添加 Listener)public void addObserver(String dataId, String group, ConfigObserver observer) {String key = getConfigKey(dataId, group);observers.computeIfAbsent(key, k -> new ArrayList<>()).add(observer);System.out.println("Observer added for: " + key);// 首次添加時,可以考慮推送當前配置String currentContent = configStore.getOrDefault(key, null);if (currentContent != null) {observer.onConfigChange(dataId, group, currentContent);}}// 移除觀察者public void removeObserver(String dataId, String group, ConfigObserver observer) {String key = getConfigKey(dataId, group);List<ConfigObserver> observerList = observers.get(key);if (observerList != null) {observerList.remove(observer);System.out.println("Observer removed for: " + key);}}// 發布配置 (模擬配置變更)public void publishConfig(String dataId, String group, String content) {String key = getConfigKey(dataId, group);System.out.println("Publishing config for " + key + ": " + content);configStore.put(key, content);notifyObservers(dataId, group, content);}// 通知觀察者private void notifyObservers(String dataId, String group, String newContent) {String key = getConfigKey(dataId, group);List<ConfigObserver> observerList = observers.get(key);if (observerList != null && !observerList.isEmpty()) {System.out.println("Notifying " + observerList.size() + " observers for " + key);// 創建副本以防并發修改List<ConfigObserver> observersToNotify = new ArrayList<>(observerList);for (ConfigObserver observer : observersToNotify) {try {observer.onConfigChange(dataId, group, newContent);} catch (Exception e) {System.err.println("Error notifying observer: " + e.getMessage());}}}}
}
// 具體觀察者實現 (客戶端應用中的監聽器)
public class MyConfigListener implements ConfigObserver {private String listenerName;public MyConfigListener(String name) {this.listenerName = name;}@Overridepublic void onConfigChange(String dataId, String group, String newContent) {System.out.println("[" + listenerName + "] Received config change: DataId=" + dataId + ", Group=" + group + ", Content=" + newContent);// 在這里處理配置變更邏輯,例如更新應用內部狀態}
}
// --- Demo Main ---
public class ObserverDemo {public static void main(String[] args) {ConfigSubject configCenter = new ConfigSubject();MyConfigListener listener1 = new MyConfigListener("App1-Listener");MyConfigListener listener2 = new MyConfigListener("App2-Listener");// App1 和 App2 都監聽同一個配置configCenter.addObserver("app.properties", "DEFAULT_GROUP", listener1);configCenter.addObserver("app.properties", "DEFAULT_GROUP", listener2);System.out.println("\n--- Publishing first config ---");configCenter.publishConfig("app.properties", "DEFAULT_GROUP", "database.url=jdbc:mysql://localhost:3306/mydb");System.out.println("\n--- Publishing updated config ---");configCenter.publishConfig("app.properties", "DEFAULT_GROUP", "database.url=jdbc:mysql://remote:3306/prod_db");System.out.println("\n--- App1 stops listening ---");configCenter.removeObserver("app.properties", "DEFAULT_GROUP", listener1);System.out.println("\n--- Publishing final config ---");configCenter.publishConfig("app.properties", "DEFAULT_GROUP", "database.url=jdbc:mysql://new_remote:3306/final_db");}
}

Nacos源碼(用的是nacos2.1.1版本源碼,可以在release中下載)位置如下:

  • 配置監聽
    客戶端接口: com.alibaba.nacos.api.config.ConfigService#addListener
    客戶端監聽器接口: com.alibaba.nacos.api.config.listener.Listener
    客戶端內部實現: com.alibaba.nacos.client.config.NacosConfigService, com.alibaba.nacos.client.config.impl.ClientWorker (處理長輪詢和回調)
    服務端通知邏輯: com.alibaba.nacos.config.server.service.LongPollingService, com.alibaba.nacos.config.server.utils.ConfigExecutor (處理配置變更事件和推送)

  • 服務訂閱
    客戶端接口: com.alibaba.nacos.api.naming.NamingService#subscribe
    客戶端監聽器接口: com.alibaba.nacos.api.naming.listener.EventListener
    客戶端內部實現: com.alibaba.nacos.client.naming.NacosNamingService, com.alibaba.nacos.client.naming.core.ServiceInfoUpdater
    服務端推送邏輯: com.alibaba.nacos.naming.push.PushService, com.alibaba.nacos.naming.core.Service (管理服務實例變更并觸發推送)

觀察者模式總結

通過Nacos的案例,我們可以簡單總結出觀察者模式的特點,如下圖:
![[Pasted image 20250419152551.png]]

其中,被觀察的通知動作可以是異步業可以是同步,觀察者收到通知后,可以決定是否告知已接收還是或是不告知。
上面的類圖只是用于簡單理解。出于單一職責原則與低耦合、可擴展設計等考慮,觀察者模式可以做出如下抽象:
被觀察者(主題 Subject)、觀察者(Observer)

![[Pasted image 20250419153013.png]]

將觀察者被和被觀察主要功能抽象成接口。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/77549.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/77549.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/77549.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

電腦 訪問 github提示 找不到網頁,處理方案

1、找到 本機的 host文件 例如 windows 的 一般在 C:\Windows\System32\drivers\etc\hosts 用管理員身份打開 hosts 文件 如果文件中沒有 github的配置&#xff0c;需要自己手動添加上去&#xff1b; 如果有&#xff0c;則需要 檢查 github.com 與 github.global.ssl.fastly.…

Linux系統中的網絡管理

1.RHEL9版本中&#xff0c;使用nm進行網絡配置&#xff0c;ifcfg不再是網絡配置文件的主存儲&#xff0c;樣式仍然可用&#xff0c;但它不再是NetworkManger存儲新網絡配置文件的默認位置&#xff0c;RHEL以key-file格式在etc/NetworkManger/system-connections/中存儲新的網絡…

AI技術深度解析:從移動芯片到AIoT的全面突破

作為全球無線通信技術和半導體解決方案的重要參與者,高通始終將技術創新作為核心驅動力,在移動通信、物聯網(IoT)、汽車電子、AI計算等領域占據關鍵地位。本文將從其核心產品線、技術突破、應用場景及未來布局四個維度,客觀解析高通的技術積累與行業角色。 一、核心產品線…

使用CS Roofline Toolkit測量帶寬

使用CS Roofline Toolkit測量帶寬 工程下載&#xff1a;使用CS Roofline Toolkit測量帶寬-案例工程文件&#xff0c;也可以按照下面的說明使用git clone下載 目錄 使用CS Roofline Toolkit測量帶寬0、Roofline模型理解1、CS Roofline Toolkit下載1.1、設置代理1.2、git clone下…

EAGLE代碼研讀+模型復現

要對代碼下手了&#xff0c;加油(? ?_?)? 作者在他們自己的設備上展現了推理的評估結果&#xff0c;受第三方評估認證&#xff0c;EAGLE為目前最快的投機方法&#xff08;雖然加速度是評估投機解碼方法的主要指標&#xff0c;但其他點也值得關注。比如PLD和Lookahead無需額…

基于SFC的windows修復程序,修復絕大部分系統損壞

效果:可以自動修復大部分由系統文件損壞而導致的錯誤 例如:系統應用無法打開 系統窗口(例如開始菜單)無法使用 電腦藍屏或者卡死.....文章 01技術背景 Windows自帶了一個SFC命令行應用程序,可以檢查大部分的系統文件錯誤,以及復這些文件 其中自動檢查所有系統文件&#x…

liunx日志問題

一、日志定向 Linux 系統的日志配置文件&#xff08;如/etc/syslog.conf或/etc/rsyslog.conf &#xff09;中&#xff0c;用于定義系統日志的記錄規則&#xff0c;決定哪些類型的日志消息會被記錄到特定的日志文件中。 *.info;mail.none;authpriv.none;cron.none /va…

2.凸包優化求解

1.減而治之(Decrease and Conquer) 插入排序 典型的減而治之算法就是插入排序方法 插入排序法: 在未排序中選擇一個元素&#xff0c;插入到已經排序號的序列中 將凸包也采用減而治之的方法 2.In-Convex-Polygon Test 怎么判斷引入的極點存在于多邊形里面還是外面&#xff1…

系統思考:危機中的轉型機遇

“危機不僅是挑戰&#xff0c;更是轉型的機會” 每當大事發生&#xff0c;很多企業老板常常被眼前的困境壓得喘不過氣&#xff0c;焦慮與壓力讓人難以思考長遠。特別是在危機面前&#xff0c;大家忙于應對眼前的風險&#xff0c;卻忽略了背后隱藏的機遇。而危機&#xff0c;恰…

大模型Rag - 如何評估Rag

一.RAG流程與評估標準補充 RAG&#xff08;Retrieval-Augmented Generation&#xff09;是一種結合檢索與生成的問答架構。為了確保系統效果&#xff0c;需要從以下三個角度對其評估&#xff1a; 回顧RAG流程 用戶提出問題 → 系統檢索相關上下文 → 基于上下文由大語言模型…

Linux RT RT RT

RT的最終目的是盡可能多的讓原來系統不可搶占的部分變成可搶占&#xff0c;讓高優先級的程序先跑。這里的rt引入了一個deadline的說法&#xff0c;此時的實時性是保證在最大一個時間間隔內&#xff0c;程序被執行。比如每100ms算法做一次決策。 所以此時面臨著幾座大山…

演員柳琦正式加入創星演員出道計劃,開創演藝事業新天地

4月18日&#xff0c;演員柳琦正式加入“創星演員出道計劃”&#xff0c;不僅得到參演都市愛情喜劇《和我結婚吧》角色的機會&#xff0c;還獲得文旅精品網劇《醉夢靈州》的出演機會&#xff0c;自此開啟全新影視之路。對表演藝術極具天賦的柳琦&#xff0c;相信未來可以憑借自身…

16.Chromium指紋瀏覽器開發教程之WebGPU指紋定制

WebGPU指紋概述 WebGPU是下一代的Web圖形和計算API&#xff0c;旨在提供高性能的圖形渲染和計算能力。它是WebGL的后繼者&#xff0c;旨在利用現代GPU的強大功能&#xff0c;使得Web應用能夠實現接近原生應用的圖形和計算性能。而且它是一個低級別的API&#xff0c;可以直接與…

HTTP:九.WEB機器人

概念 Web機器人是能夠在無需人類干預的情況下自動進行一系列Web事務處理的軟件程序。人們根據這些機器人探查web站點的方式,形象的給它們取了一個飽含特色的名字,比如“爬蟲”、“蜘蛛”、“蠕蟲”以及“機器人”等!爬蟲概述 網絡爬蟲(英語:web crawler),也叫網絡蜘蛛(…

Vue3+TS中svg圖標的使用

安裝依賴 pnpm i vite-plugin-svg-icons -D配置引入 vite.config.ts ... import { createSvgIconsPlugin } from vite-plugin-svg-icons import path from node:pathconst svgIconsPlugin createSvgIconsPlugin({iconDirs: [path.resolve(process.cwd(), src/assets/icons)]…

【java實現+4種變體完整例子】排序算法中【堆排序】的詳細解析,包含基礎實現、常見變體的完整代碼示例,以及各變體的對比表格

以下是堆排序的詳細解析&#xff0c;包含基礎實現、常見變體的完整代碼示例&#xff0c;以及各變體的對比表格&#xff1a; 一、堆排序基礎實現 原理 基于二叉堆結構&#xff08;最大堆&#xff09;&#xff0c;通過以下步驟實現排序&#xff1a; 構建最大堆&#xff1a;將…

論文閱讀筆記:Generative Modeling by Estimating Gradients of the Data Distribution

1、參考來源 論文《Generative Modeling by Estimating Gradients of the Data Distribution》 來源&#xff1a;NeurIPS 2019 論文鏈接&#xff1a;https://arxiv.org/abs/1907.05600 參考鏈接&#xff1a; 【AI知識分享】真正搞懂擴散模型Score Matching一定要理解的三大核心…

Kubernetes相關的名詞解釋CNI插件(1)

&#xff08;一&#xff09;什么是CNI插件&#xff1f; 在 Kubernetes 中&#xff0c;CNI 插件&#xff08;Container Network Interface Plugin&#xff09; 是一種用于配置容器網絡接口的標準工具&#xff0c;負責為 Pod 分配網絡資源&#xff08;如 IP 地址&#xff09;并建…

2021-11-10 C++蝸牛爬井進3退1求天數

緣由C大一編程題目。-編程語言-CSDN問答 int n 0, t 0;cin >> n;while ((n - 3)>0)n, t;cout << t << endl;

分享一個DeepSeek+自建知識庫實現人工智能,智能回答高級用法。

這個是我自己搞的DeepSeek大模型自建知識庫相結合到一起實現了更強大的回答問題能力還有智能資源推薦等功能。如果感興趣的小伙伴可以聯系進行聊聊&#xff0c;這個成品已經有了實現了&#xff0c;所以可以融入到你的項目&#xff0c;或者畢設什么的還可以去參加比賽等等。 1.項…