精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

靈感乍現!造了個與眾不同的Dubbo注冊中心擴展輪子

開發 前端
隨著這樣的習慣日積月累,低配的Mac上相繼跑了etcd、redis、mysql等等容器,重要的是還打開了N個IDEA窗口。

hello大家好呀,我是小樓。

作為一名基礎組件開發,服務好每一位業務開發同學是我們的義務(KPI)。

客服群里經常有業務開發同學丟來一段代碼、一個報錯,而我們,當然要微笑服務,耐心解答。

有的問題,憑借多年踩坑經驗,一眼就能看出,有的問題,看一眼代碼也能知道原因,但有的問題,還真就光憑看是看不出來的,這時,只能下載代碼,本地跑跑看了。

熟悉我的朋友都知道,我從事dubbo相關開(客)發(服)工作多年,所以我就來講一個dubbo問題排查過程中的有趣的事。

通常遇到看不能解決的問題時,先git拉取代碼,再導入IDEA,找到main方法點擊啟動,一頓操作下來,不出意外,肯定會有點小錯誤,比如這條:

Socket error occurred: localhost/127.0.0.1:2181: Connection refused

看到2181端口就知道這是本地沒有裝zookeeper(下文簡稱zk),問題不大,docker直接拉一個zk鏡像,起個容器就完事。

隨著這樣的習慣日積月累,低配的Mac上相繼跑了etcd、redis、mysql等等容器,重要的是還打開了N個IDEA窗口。

每當啟動一個新的項目時,風扇呼呼地直接將IDEA卡死。

這時,我陷入了思考,能不能少跑點程序?

etcd、redis、mysql暫時搞不定,但dubbo的注冊中心我熟啊!柿子當然要挑軟的捏。

需求梳理

在開干之前,得先梳理一下需求,于是我腦子閃現出無數個在本地測試時遇到的與dubbo注冊中心有關問題的瞬間,但仔細一捋,無外乎兩種:

  • 作為provider:最最最主要的就是不要阻斷應用啟動。
  • 作為consumer:

不要阻斷應用啟動。

可以發現并調用本地的provider。

可以調用遠程的provider。

可以手動指定調用任意provider。

除了這兩個功能上的需求,還得解決我們最初的問題:「不要依賴第三方服務」(如zk)。

調研

由于一開始就想到了利用dubbo注冊中心擴展來實現這個功能,為了不重復造輪子,翻了一下dubbo源碼,看看是否已經有相應的實現:

發現除了dubbo-registry-multicast之外都是依賴了第三方服務,所以這個multicast是啥呢?dubbo官方文檔說的很清楚:

乍一看很符合我們的需求,但仔細一想,還是有幾點不滿足:

  • 不一定能發現遠程的provider,如果大家代碼都是用的zk,而你把代碼拉下來注冊中心改成multicast是沒法發現遠程的服務的;
  • 沒法手動指定調用任意provider。

產品設計

服務發現得有個載體,要么通過第三方組件、要么通過網絡。但我們忽略了,在本地,磁盤也可以作為一個載體。

provider注冊向磁盤文件寫入,consumer訂閱即讀取磁盤文件,當磁盤文件有變更時通知consumer,大概是這么個樣子:

這樣設計有什么好處呢?

  • 不依賴其他服務,只是文件的讀寫,不會阻塞應用啟動。
  • consumer和provider都在本地時,可以像其他注冊中心(如zk、nacos等)一樣工作,對開發者完全透明。
  • 可以手動修改、指定調用任意provider。

唯一的缺點是,無法發現遠程的provider,但我們可以手動指定,也算是沒有大礙。

我們以dubbo 2.7.x版本的接口級服務發現來設計我們的產品,因為這個版本使用的最多。

首先要考慮的是如何去組織服務發現文件,由于是接口級服務發現,我們就按服務名來作為文件名,每個服務一個文件:

其次每個文件的內容怎么組織?最簡單的就是將dubbo注冊的URL直接寫入文件,每行一個URL,就像這樣:

但你可能發現了問題,這dubbo的URL有點長啊~如果讓我手動指定,豈不是很難做到?

這個問題好解決,我們實現一個簡寫版本的URL,比如有一行這樣簡寫,就將它還原為一個可用的URL。

127.0.0.1:20880

代碼實現

在實現之前首先要了解的是dubbo注冊中心擴展是如何編寫的,這塊直接看官方文檔:

https://dubbo.apache.org/zh/docs/v2.7/dev/impls/registry/

雖然我覺得看完了文檔你也不一定能實現一個dubbo注冊中心擴展,但別慌,先往下看,說不定看完了本文你也能自己寫一個。

先看一下代碼結構:

  • 項目命名為:dubbo-registry-mock,和dubbo源碼中的命名風格保持一致。
  • MockRegistry是注冊中心的核心實現。
  • MockRegistryFactory是mock registry的工廠,dubbo會通過這個類來創建MockRegistry。
  • org.apache.dubbo.registry.RegistryFactory這個文件是指定MockRegistryFactory該如何加載,即dubbo的SPI發現文件。

dubbo的注冊中心配置只需要改成:

dubbo.registry.address=mock://127.0.0.1:2181

這里起作用的只有mock,ip、port并不重要,只是占個位置。

當dubbo應用啟動時,讀取到配置的mock,會查找resources/META-INF.dubbo下的org.apache.dubbo.registry.RegistryFactory文件,這里它的內容為:

mock=org.newboo.MockRegistryFactory

于是去new出一個MockRegistryFactory。

注:newboo.org是我曾經注冊的一個域名,用來放博客,不過后來沒有續費,現在我的測試代碼中經常會出現這個包名。

MockRegistryFactory也很簡單,直接new一個MockRegistry:

public class MockRegistryFactory extends AbstractRegistryFactory {

@Override
protected Registry createRegistry(URL url) {
return new MockRegistry(url);
}
}

最后看核心的實現MockRegistry類:

public MockRegistry(URL url) {
super(url);
String basePath = DISCOVERY_DEFAULT_DIR;
if (StringUtils.isNotEmpty(url.getParameter(DISCOVERY_FILE_DIR_KEY))) {
basePath = url.getParameter(DISCOVERY_FILE_DIR_KEY);
}

mockService = new MockService(basePath);

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1, new NamedThreadFactory("file_scan", true));
scheduledExecutorService.scheduleWithFixedDelay(new SubscribeScan(), 1000L, 5000, TimeUnit.MILLISECONDS);
}

這個構造方法,做了3件事情:

  • 獲取basePath,也就是服務發現的文件夾基礎路徑,有個默認值,也可以根據url的參數進行調整,如:
dubbo.registry.address=mock://127.0.0.1:2181?discovery_file=/tmp/mock-registry2
  • new一個MockService,承載了核心的服務發現邏輯,后面再說。
  • 啟動一個定時任務,每隔5秒去掃描一次文件,看文件是否有變化,如果有變化則通知consumer,詳細后面也會說。

MockRegistry繼承自FailbackRegistry,只需要實現它的doRegister、doUnregister、doSubscribe、doUnsubscribe、isAvailable幾個方法即可。

其中isAvailable是判斷注冊中心是否可用,我們直接返回true即可。

doUnsubscribe是取消訂閱,這里也啥都不用干,剩下3個方法我們將邏輯封裝在MockService:

@Override
public void doRegister(URL url) {
try {
mockService.writeUrl(url);
} catch (Throwable e) {
throw new RpcException("Failed to register " + url, e);
}
}

@Override
public void doUnregister(URL url) {
try {
mockService.removeUrl(url);
} catch (Throwable e) {
throw new RpcException("Failed to unregister " + url, e);
}
}

@Override
public void doSubscribe(URL url, NotifyListener listener) {
try {
List<URL> urls = mockService.getUrls(url.getServiceInterface());
listener.notify(urls);
} catch (ServiceNotChangeException ignored) {
} catch (Throwable e) {
throw new RpcException("Failed to subscribe " + url, e);
}
}

writeUrl直接獲取到文件名,往文件中append新的一行URL即可:

public void writeUrl(URL url) throws IOException {
String fileName = pathCenter.getServicePath(url.getServiceInterface());

// 寫入文件
String line = url.toFullString();
FileUtil.appendLine(fileName, line);
}

removeUrl先讀取文件,把要注銷的URL刪除,再把剩余內容覆蓋寫回文件即可:

public void removeUrl(URL url) throws IOException {
String fileName = pathCenter.getServicePath(url.getServiceInterface());
String line = url.toFullString();

List<String> lines = FileUtil.readLines(fileName);
lines = LinesUtil.removeLine(lines, line);

FileUtil.writeLines(fileName, lines);
}

getUrls去掃描文件,如果文件有變更,就把讀取到的最新的URL格式化后返回,之所以要格式化是因為可能會有簡寫的URL(見上文),文件是否有變更直接根據文件的最后更新時間來判斷,精確到毫秒,本地測試也夠用了:

 public List<URL> getUrls(String service) throws Exception {
if (!scan(service)) {
throw new ServiceNotChangeException();
}

String fileName = pathCenter.getServicePath(service);
List<String> lines = FileUtil.readLines(fileName);
List<URL> urls = new ArrayList<>(lines.size());
for (String line : lines) {
if (!LinesUtil.isSkipLine(line)) {
urls.add(format(line));
}
}
return urls;
}

其中scan如果返回false,說明文件沒有變更,直接忽略本次掃描。

最后一個SubscribeScan只需要把已經訂閱的接口拿出來,執行一次doSubscribe即可:

public class SubscribeScan implements Runnable {
@Override
public void run() {
try {
// 已經訂閱的url
Map<URL, Set<NotifyListener>> subscribeds = getSubscribed();
if (subscribeds == null || subscribeds.isEmpty()) {
return;
}

for (Map.Entry<URL, Set<NotifyListener>> entry : subscribeds.entrySet()) {
for (NotifyListener listener : entry.getValue()) {
doSubscribe(entry.getKey(), listener);
}
}
} catch (Throwable t) {
// ignore
}
}
}

看到這里可能有的同學問,為啥要輪詢,不用WatchService監聽文件的變更呢?我寫的時候也查了一下,并且debug了一下,發現WatchService的真實實現是PollingWatchService,而且它也是采用輪詢來實現的,不信可以打開這個類看看。

感覺和自己寫沒啥差別,所以我就自己寫了。

完整代碼已經上傳到了github:https://github.com/lkxiaolou/dubbo-registry-mock。

為了讓這個項目看起來更飽滿一點,還寫了一個README:

最后

如果你耐心看完了本文,且對dubbo有所了解,我相信你已經能自己寫一個dubbo注冊中心擴展。

如果你也經常在本地做測試,也可以用我寫的這個mock registry來試試,當然代碼和想法都有改進的地方,如果你有更好的想法也可以和我交流。

責任編輯:武曉燕 來源: 捉蟲大師
相關推薦

2022-02-10 20:09:24

Dubbo源碼Provider

2022-05-13 09:16:49

Python代碼

2015-08-06 10:14:15

造輪子facebook

2009-12-15 10:03:41

微軟數據中心服務器機柜

2011-09-19 13:57:47

Vista屏保注冊表

2020-09-08 08:45:39

jupyter插件代碼

2010-02-07 14:54:13

Android

2021-05-27 11:10:23

注冊中心業務

2023-02-06 17:27:48

2023-01-30 22:43:39

DubboZooKeeper

2025-06-26 01:25:00

2024-04-10 12:22:19

DubboNacos微服務

2022-09-14 08:22:50

AlloyDB高性能高可用性

2010-01-13 18:39:05

C++安裝

2023-06-25 14:35:27

網絡安全安全漏洞

2022-12-07 10:34:45

AST前端編譯

2021-03-09 16:38:48

加密貨幣比特幣貨幣

2009-12-17 16:53:13

.NET Framew

2022-01-05 11:40:36

Go特性語言

2010-06-17 14:42:31

RS-232C協議
點贊
收藏

51CTO技術棧公眾號

欧美一区二区三区久久精品| 91网在线播放| 午夜久久黄色| 精品国精品国产尤物美女| 成人av在线不卡| 懂色av成人一区二区三区| 93在线视频精品免费观看| 在线播放91灌醉迷j高跟美女 | 精品一区二区三区国产| 国产午夜精品久久久久| 成人3d精品动漫精品一二三| 91精品婷婷国产综合久久竹菊| 青草网在线观看| 欧美扣逼视频| 国产一区二区在线看| 久久久人成影片一区二区三区观看 | 亚洲成人久久影院| 欧美午夜精品理论片a级大开眼界| www.国产毛片| 女生裸体视频一区二区三区| 亚洲成人av片在线观看| 九一精品在线观看| 最新黄网在线观看| 久久久亚洲高清| 国产一区二区丝袜高跟鞋图片| 久久久国产成人| 国产成人影院| 欧美成人精品福利| 尤蜜粉嫩av国产一区二区三区| 182tv在线播放| 国产日韩欧美精品一区| 国产91aaa| 波多野结衣视频在线观看| 午夜性色一区二区三区免费视频| 亚洲国产成人91精品| 国产精品一区二区小说| 9999在线视频| 国产精品视频看| 国产日产精品一区二区三区四区| 久久久国产免费| 亚洲私人影院| 色天天综合狠狠色| 性久久久久久久久久| 视频一区中文字幕精品| 欧美日韩亚洲综合在线 | 国产视频一视频二| 成人ww免费完整版在线观看| 久久久噜噜噜久久中文字幕色伊伊| 成人性生交大片免费看小说| 欧美日韩在线视频播放| 国产精品日本欧美一区二区三区| 美乳少妇欧美精品| 国产人与禽zoz0性伦| 亚洲专区视频| 精品99久久久久久| 色欲无码人妻久久精品| 国外成人福利视频| 欧美在线观看视频一区二区| 逼特逼视频在线| 大桥未久在线视频| 亚洲大尺度视频在线观看| 中文字幕一区二区三区四区五区人| 欧美日本韩国一区二区| 99免费精品视频| 波多野结衣一区二区三区在线观看| 自拍偷拍福利视频| 日韩高清中文字幕一区| 日韩女优在线播放| 无码人妻熟妇av又粗又大| 99精品国产99久久久久久福利| 欧美成人手机在线| 国产一二三四区| 欧美成人嫩草网站| 久久福利视频导航| 国产喷水在线观看| 99成人超碰| 久久精品2019中文字幕| 最新av电影网站| 99精品美女| 欧美成aaa人片在线观看蜜臀| 永久av免费网站| 综合日韩在线| 欧美精品少妇videofree| 无码人妻精品一区二区三区夜夜嗨| 国产精品99久久| 俺去了亚洲欧美日韩| 老湿机69福利| 精品99视频| 2019日本中文字幕| 精品久久久久久久久久久久久久久久久久| 国产农村妇女精品一二区| 青青草国产精品一区二区| 日本视频网站在线观看| 久久成人久久鬼色| 91精品视频网站| 亚洲精品.www| 91免费观看视频| 欧美久久久久久一卡四| 在线观看a视频| 亚洲欧美激情插| 日韩xxxx视频| 手机看片久久| 91精品欧美综合在线观看最新| 国产精品偷伦视频免费观看了| 久久伊人久久| 日韩电影大片中文字幕| 日本人亚洲人jjzzjjz| 欧美一区二区三区久久精品茉莉花| 欧美大学生性色视频| 亚洲午夜18毛片在线看| 蜜桃精品在线观看| 国产精品一区而去| 成人性爱视频在线观看| 亚洲综合免费观看高清在线观看| 女性女同性aⅴ免费观女性恋| 日韩av超清在线观看| 日韩三级电影网址| 国产精品亚洲一区二区无码| 色综合久久中文| 久久中文字幕在线| 人妻丰满熟妇av无码区| 国产一区二三区| 欧美日韩在线一区二区三区| 国产午夜精品久久久久免费视| 五月激情综合网| 欧美一级裸体视频| 国产伦精品一区二区三区在线播放| 国产一区二区免费| 国产午夜小视频| 国产在线精品不卡| 日本一区二区三区免费观看| 好看的中文字幕在线播放| 色综合天天综合网天天看片| 国产在线a视频| 欧美日韩国产在线观看网站| 久久成人精品一区二区三区| 亚洲s码欧洲m码国产av| 日本不卡在线视频| 久久青青草原| 五月花成人网| 欧美区视频在线观看| 国产 中文 字幕 日韩 在线| 激情91久久| 国产精品乱码| av免费在线视| 亚洲高清不卡av| avove在线播放| 国产在线精品国自产拍免费| 一本久道久久综合| 欧美午夜三级| 日韩一二三在线视频播| 中文字幕乱码中文字幕| 国产欧美日韩亚州综合| 99热成人精品热久久66| 另类图片第一页| 欧美激情在线有限公司| 成人av无码一区二区三区| 专区另类欧美日韩| 欧美美女性视频| 天天久久综合| 国产日韩欧美在线看| jizz在线免费观看| 欧美综合天天夜夜久久| 中文字幕第4页| 性一交一乱一区二区洋洋av| 国产一区二区不卡视频在线观看 | 91色乱码一区二区三区| 免费无码毛片一区二三区| 中文字幕一区日韩精品| 欧美日韩aaaa| 蜜臀av中文字幕| 欧美日韩国产综合视频在线观看中文| 欧美性生交xxxxx| 亚洲高清免费| 久久久久久久久久久久久久一区 | 妓院一钑片免看黄大片| 免费欧美视频| 国产精品免费电影| 中文字幕在线视频区| 欧美日韩精品专区| 日韩三级久久久| 国内外成人在线视频| 视色,视色影院,视色影库,视色网| 91成人福利社区| 九九综合九九综合| 高清乱码毛片入口| 一二三区精品视频| 成人h动漫精品一区| 久久久久久夜| 亚洲一区二区高清视频| 国产999精品在线观看| 久久视频在线直播| 亚洲av无码一区二区三区性色 | 欧美黄色片视频| 天天综合天天色| 在线免费亚洲电影| 调教驯服丰满美艳麻麻在线视频| 免费精品视频最新在线| 亚洲国产一二三精品无码| 国产精品调教视频| 国产精品电影网站| 伊人影院在线视频| 日韩精品中文字幕在线| 中文 欧美 日韩| 日韩毛片一二三区| 伊人久久一区二区三区| 日韩成人一区二区三区在线观看| 超碰97免费观看| 外国成人在线视频| 成人免费淫片视频软件| 欧美四级在线| 亚洲摸下面视频| 国产视频一区二区三| 欧美性猛xxx| 黄色录像二级片| 99re66热这里只有精品3直播| 亚洲最大综合网| 亚洲国产高清一区二区三区| 国产综合欧美在线看| 先锋影音网一区二区| 91av视频在线| 成人在线直播| 亚洲一级黄色片| 欧美 日韩 综合| 777欧美精品| 中文字幕一区二区三区手机版 | 亚洲区第一页| 三年中国中文在线观看免费播放| 亚洲精品在线播放| 国产免费成人av| 热三久草你在线| 色综合男人天堂| 欧美日韩国产综合视频| 精品少妇一区二区三区在线视频| 啪啪小视频网站| 欧美日韩国产精品| 国产精品久久久精品四季影院| 久久精品视频免费观看| 成人欧美精品一区二区| 久久99久久99小草精品免视看| 狠狠噜天天噜日日噜| 久久综合国产| 日韩精品久久久毛片一区二区| 高清日韩中文字幕| 99高清视频有精品视频| 婷婷久久免费视频| 国产男女猛烈无遮挡91| 中文字幕乱码在线播放| 96精品视频在线| 91老司机福利在线| 欧美精品激情blacked18| 成人动漫在线播放| 在线观看欧美日韩| 韩国三级av在线免费观看| 欧美精品一区二区三区蜜桃视频 | 亚洲免费福利一区| 国产麻豆日韩| 懂色av一区二区| 国产伦一区二区三区色一情| 超碰成人在线观看| wwwxx欧美| 成人国产网站| 人体精品一二三区| 成人四虎影院| 国产精品专区第二| 国产精品原创视频| 国产精品一区二区久久| 欧美大陆国产| 91欧美视频网站| 欧美成人精品午夜一区二区| 91免费看网站| 先锋影音一区二区| 亚洲xxx大片| 91综合久久爱com| 国内视频一区| 中文字幕av一区二区三区人| 日产国产精品精品a∨| 国产在线日韩精品| 性欧美精品一区二区三区在线播放 | 中文字幕在线免费不卡| 麻豆视频在线免费看| 亚洲精品视频在线观看免费| 午夜少妇久久久久久久久| 一区二区免费看| 成人毛片18女人毛片| 亚洲国产一区二区视频| 美日韩一二三区| 欧美在线观看视频一区二区三区| 在线亚洲欧美日韩| 日韩欧美中文字幕精品| 天堂在线观看免费视频| 亚洲免费成人av电影| 伦理片一区二区三区| 最近2019年好看中文字幕视频| 成人高清免费在线| 久久天堂电影网| 国产三级伦理在线| 国产97在线观看| 9.1麻豆精品| 精品国产乱码久久久久久88av| 欧美猛男同性videos| 成年人黄色在线观看| 激情综合自拍| 簧片在线免费看| 成人黄色在线网站| www深夜成人a√在线| 性感美女极品91精品| 国产精品久久欧美久久一区| 亚洲国产精品福利| 国产盗摄在线观看| 欧美专区在线播放| 国产精品一区二区美女视频免费看| 狠狠色伊人亚洲综合网站色| 日韩欧美一区二区三区免费看| 视频一区二区综合| 激情另类综合| 国产成人强伦免费视频网站| 久久精品夜夜夜夜久久| 久久久无码精品亚洲国产| 欧美三级中文字幕在线观看| 欧美特级特黄aaaaaa在线看| 在线精品国产欧美| 欧美亚洲大片| 国产伦精品一区二区三区免| 亚洲精品国产首次亮相| 国产九九在线观看| www国产精品av| 欧美精品xxxxx| 欧美一区二区三区免费在线看 | 日本网站免费观看| 欧美一级高清大全免费观看| 国产三区四区在线观看| 久久全球大尺度高清视频| jizz久久久久久| 日韩欧美手机在线| 国产欧美一区二区色老头| 怡红院亚洲色图| 国产女同互慰高潮91漫画| 亚洲一区欧美在线| 欧美日韩成人在线一区| 国产人成在线视频| 欧美一区二三区| 亚洲小说图片| 精品国产免费av| www.久久久久久久久| 亚洲一区欧美在线| 亚洲第一黄色网| 变态调教一区二区三区| 国产精品一区二| 亚洲二区精品| 香蕉视频污视频| 精品国产电影一区| 国产视频一区二区三| 久久久91精品| 欧美黄视频在线观看| 这里只有精品66| 韩国成人福利片在线播放| 国产精品视频在| 欧美一区二区私人影院日本| 好吊日视频在线观看| 91亚洲精品久久久| 国内精品久久久久久久影视蜜臀| 伊人成人免费视频| 亚洲专区一二三| 无码精品人妻一区二区| 欧美亚洲激情在线| 国产一区二区三区网| 天天影视综合色| 中文久久乱码一区二区| 91好色先生tv| 欧美成人亚洲成人| www国产精品| 成人一区二区免费视频| 国产欧美一区二区精品性| 夜夜狠狠擅视频| 欧美激情第6页| 自拍欧美一区| 加勒比av中文字幕| 亚洲一区在线视频观看| 视频国产在线观看| 国产精品海角社区在线观看| 91精品国产91久久久久久黑人| 亚洲欧美天堂在线| 亚洲韩国精品一区| 韩国福利在线| 91最新在线免费观看| 你懂的成人av| 久久亚洲AV无码专区成人国产| 欧美日韩亚洲丝袜制服| sm在线播放| 欧美一区二区三区四区在线观看地址 | 日本一道在线观看| 不卡的av网站| 国产美女激情视频| 久久亚洲精品成人| 欧美综合自拍| 亚洲制服在线观看| 动漫精品一区二区| 欧美jizz18hd性欧美| 欧美久久久久久一卡四|