go語言應(yīng)該沒有,java netty這種高性能異步IO模型的框架,建議你還是用java語言開發(fā)吧
創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比上街網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式上街網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋上街地區(qū)。費用合理售后完善,十多年實體公司更值得信賴。
一、服務(wù)注冊中心的由來
假如沒有服務(wù)注冊中心,我們會干些什么事情呢?
在傳統(tǒng)行業(yè)的項目架構(gòu)中以下的方案最為常見了:
這種架構(gòu)開發(fā)、部署都是最簡單的,一般適用于中小企業(yè)訪問量并不是太多的情況下,各個系統(tǒng)服務(wù)一臺機器就搞定了。系統(tǒng)之間的調(diào)用也是拿到對方的IP+PORT直接連接。
接下來可能因為應(yīng)用B開始訪問量大了,單臺機器已經(jīng)不能滿足我們的需求,于是一些反向代理工具應(yīng)運而出,其中比較常見的有Apache、Nigix,架構(gòu)演變?yōu)椋?/p>
相比之前的應(yīng)用B的單臺機器訪問,這種nginx代理的方式減輕了服務(wù)器的壓力,但是可能會出現(xiàn)Nginx掛了,那么整個服務(wù)也不可用,于是又來了這么一套架構(gòu):
這樣看方案算是完美了吧。然后事情并不是想象的那么一帆風(fēng)順,這還只是應(yīng)用A調(diào)用一個應(yīng)用B,如果應(yīng)用A調(diào)用的可能是應(yīng)用B、C、D、E...,這種完全就不知道他后面到底還想干嘛,這種架構(gòu)看似可以,但是絕對會累死運維的(nginx的配置將會非?;靵y,直接導(dǎo)致運維不干了)。
服務(wù)注冊中心干些什么事情呢?
上面提到的那種靠人力(主要是運維干的事情)比較繁瑣,還不好維護,有這么幾點不方便:應(yīng)用服務(wù)的地址變了、雙十一搞活動服務(wù)器新增等等。那么我們可以有這么的一種架構(gòu):
服務(wù)注冊中心主要是維護各個應(yīng)用服務(wù)的ip+port列表,并保持與各應(yīng)用服務(wù)的通訊,在一定時間間隔內(nèi)進行心跳檢測,如果心跳不能到達則對服務(wù)IP列表進行剔除,并同時通知給其它應(yīng)用服務(wù)進行更新。同樣要是有新增的服務(wù)進來,應(yīng)用服務(wù)會向注冊中心進行注冊,服務(wù)注冊中心將通知給其它應(yīng)用進行更新。每個應(yīng)用都有需要調(diào)用對應(yīng)應(yīng)用服務(wù)的地址列表,這樣在進行調(diào)用時只要處理客戶負載雜均衡即可。
二、微服務(wù)注冊中心
1.Zookeeper
ZooKeeper是一個分布式的,開放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù),是Google的Chubby一個開源的實現(xiàn),是Hadoop和Hbase的重要組件。它是一個為分布式應(yīng)用提供一致性服務(wù)的軟件,提供的功能包括:配置維護、域名服務(wù)、分布式同步、組服務(wù)等。
上面的話直接摘抄百度百科的內(nèi)容,國內(nèi)很多公司做分布式開發(fā)最初的選型大部分都是采用dubbo框架。dubbo框架注冊中心主要使用zookeeper。zookeeper服務(wù)端與客戶端的底層通訊為netty。zookeeper采用CAP理論中的CP,一般集群部署最少需要3臺機器。
2.Euraka
先來看一下euraka的架構(gòu)圖:
Register:服務(wù)注冊
當(dāng)Eureka客戶端向Eureka Server注冊時,它提供自身的元數(shù)據(jù),比如IP地址、端口,運行狀況指示符URL,主頁等。
Renew:服務(wù)續(xù)約
Eureka客戶會每隔30秒發(fā)送一次心跳來續(xù)約。 通過續(xù)約來告知Eureka Server該Eureka客戶仍然存在,沒有出現(xiàn)問題。 正常情況下,如果Eureka Server在90秒沒有收到Eureka客戶的續(xù)約,它會將實例從其注冊表中刪除。 建議不要更改續(xù)約間隔。
Fetch Registries:獲取注冊列表信息
Eureka客戶端從服務(wù)器獲取注冊表信息,并將其緩存在本地。客戶端會使用該信息查找其他服務(wù),從而進行遠程調(diào)用。該注冊列表信息定期(每30秒鐘)更新一次。每次返回注冊列表信息可能與Eureka客戶端的緩存信息不同, Eureka客戶端自動處理。如果由于某種原因?qū)е伦粤斜硇畔⒉荒芗皶r匹配,Eureka客戶端則會重新獲取整個注冊表信息。 Eureka服務(wù)器緩存注冊列表信息,整個注冊表以及每個應(yīng)用程序的信息進行了壓縮,壓縮內(nèi)容和沒有壓縮的內(nèi)容完全相同。Eureka客戶端和Eureka 服務(wù)器可以使用JSON / XML格式進行通訊。在默認的情況下Eureka客戶端使用壓縮JSON格式來獲取注冊列表的信息。
Cancel:服務(wù)下線
Eureka客戶端在程序關(guān)閉時向Eureka服務(wù)器發(fā)送取消請求。 發(fā)送請求后,該客戶端實例信息將從服務(wù)器的實例注冊表中刪除。該下線請求不會自動完成,它需要調(diào)用以下內(nèi)容:
DiscoveryManager.getInstance().shutdownComponent();
Eviction 服務(wù)剔除
在默認的情況下,當(dāng)Eureka客戶端連續(xù)90秒沒有向Eureka服務(wù)器發(fā)送服務(wù)續(xù)約,即心跳,Eureka服務(wù)器會將該服務(wù)實例從服務(wù)注冊列表刪除,即服務(wù)剔除。
自我保護機制:
既然Eureka Server會定時剔除超時沒有續(xù)約的服務(wù),那就有可能出現(xiàn)一種場景,網(wǎng)絡(luò)一段時間內(nèi)發(fā)生了 異常,所有的服務(wù)都沒能夠進行續(xù)約,Eureka Server就把所有的服務(wù)都剔除了,這樣顯然不太合理。所以,就有了 自我保護機制,當(dāng)短時間內(nèi),統(tǒng)計續(xù)約失敗的比例,如果達到一定閾值,則會觸發(fā)自我保護的機制,在該機制下, Eureka Server不會剔除任何的微服務(wù),等到正常后,再退出自我保護機制。自我保護開關(guān)(eureka.server.enableself-preservation: false)
3.Consul
consul推薦的架構(gòu)圖:
Consul不像Euraka的部署那么簡單,他是go語言開發(fā)的,需要運維單獨部署,有提供java的客戶端連接,采用的是CAP的CP。
4.Nacos
Euraka是Spring Cloud Netflix早期版本中推薦使用的,后來euraka1.0版本不再維護,euraka2.0已經(jīng)閉源,導(dǎo)致很多新項目基于Spring Cloud Netflix 開發(fā)的選型變遷為Consul.
Nacos是阿里開源的服務(wù)注冊中心,它可以與spring cloud aliaba集成使用。
Nacos的官方介紹:
Nacos 致力于幫助您發(fā)現(xiàn)、配置和管理微服務(wù)。Nacos 提供了一組簡單易用的特性集,幫助您實現(xiàn)動態(tài)服務(wù)發(fā)現(xiàn)、服務(wù)配置管理、服務(wù)及流量管理。
Nacos 幫助您更敏捷和容易地構(gòu)建、交付和管理微服務(wù)平臺。 Nacos 是構(gòu)建以“服務(wù)”為中心的現(xiàn)代應(yīng)用架構(gòu)(例如微服務(wù)范式、云原生范式)的服務(wù)基礎(chǔ)設(shè)施。
Nacos 地圖
Nacos 生態(tài)圖
如 Nacos 全景圖所示,Nacos 無縫支持一些主流的開源生態(tài),例如
Spring Cloud
Apache Dubbo and Dubbo Mesh TODO
Kubernetes and CNCF TODO
三、服務(wù)注冊與發(fā)現(xiàn)技術(shù)選型
以下是來自網(wǎng)上的一個分享:
除了上述的幾種以外,筆者更推薦使用Nacos作為服務(wù)注冊中心。
推薦理由:
Nacos服務(wù)注冊表結(jié)構(gòu)Mapnamespace, Mapgroup::serviceName, Service采用多層次Map結(jié)構(gòu),控制的顆粒度更細,支持金絲雀模式發(fā)布,心跳同步機制也更快速,服務(wù)更新更及時。
netty是一個封裝了nio的java語言實踐的io框架,使編程人員從繁瑣且容器出bug的nio編程中解放出來,更專注于業(yè)務(wù)創(chuàng)新能力,而且很多其他的上層框架也會使用netty作為io模塊的實現(xiàn),例如dubbo,spring-gateway之類.沒事可以去黑馬程序員官網(wǎng)視頻庫看免費視頻。
Netty是Java語言中一個高性能的網(wǎng)絡(luò)通信框架,零拷貝又是這個框架的特色之一,它是如何實現(xiàn)的呢?
在計算機中完成一次數(shù)據(jù)傳輸,一般需要經(jīng)過兩個階段。第一步,操作系統(tǒng)把數(shù)據(jù)從本地硬盤或網(wǎng)卡拷貝到內(nèi)核空間的內(nèi)存;第二步,應(yīng)用程序再把數(shù)據(jù)從系統(tǒng)內(nèi)核空間的內(nèi)存拷貝到用戶空間的內(nèi)存;接下來才是應(yīng)用程序中的數(shù)據(jù)處理工作。
先來看幾個名詞。
DMA(Direct Memory Access)直接存儲器訪問,將數(shù)據(jù)從一個地址空間復(fù)制到另一個地址空間。當(dāng)CPU初始化這個傳輸動作后,傳輸動作本身是由DMA控制器(DMAC)來完成的。也就是說在數(shù)據(jù)傳輸期間,系統(tǒng)可以并行執(zhí)行其他任務(wù)。CPU拷貝,是由CPU直接處理的數(shù)據(jù)的傳送,數(shù)據(jù)拷貝時一直占用CPU資源。
從上圖中可以看出,傳統(tǒng)的IO讀寫流程,包括4次用戶態(tài)和內(nèi)核態(tài)的切換,4次上下文切換,4次的數(shù)據(jù)拷貝,2次CPU拷貝,2次DMA拷貝。
一、什么是零拷貝?
拷貝,是指數(shù)據(jù)從一個存儲區(qū)域復(fù)制到另一個存儲區(qū)域。 零,表示次數(shù)為0,復(fù)制的次數(shù)為0,也就是數(shù)據(jù)不需要從一個存儲區(qū)域復(fù)制到另一個存儲區(qū)域。
二、為什么需要零拷貝?
零拷貝,就是指從系統(tǒng)內(nèi)核空間的內(nèi)存到用戶空間的內(nèi)存,不需要采用傳統(tǒng)方式的數(shù)據(jù)復(fù)制。而是將系統(tǒng)內(nèi)核空間的內(nèi)存和用戶空間的內(nèi)存實現(xiàn)關(guān)聯(lián)映射(mmap內(nèi)存映射機制),從而省去了數(shù)據(jù)傳輸過程中的復(fù)制。
mmap(memory map)內(nèi)存映射機制,簡單來說就是將文件/設(shè)備映射到內(nèi)存中,進程可以通過讀寫內(nèi)存的方式,實現(xiàn)對mmap文件的操作。零拷貝并不是完全沒有拷貝,而是減少了數(shù)據(jù)拷貝的次數(shù)。
三、零拷貝在Netty中的三種實現(xiàn)。
1.使用堆外內(nèi)存,也叫直接內(nèi)存(Direct Memory)。netty的接收和發(fā)生都是使用Direct buffer,對應(yīng)系統(tǒng)底層的mmap機制,直接使用堆外內(nèi)存進行Socket讀寫,不需要進行字節(jié)緩沖區(qū)的二次拷貝。
2.提供了組合buffer對象 (CompositeByteBuf),可以聚合多個ByteBuffer對象,用戶只需要像操作一個ByteBuffer一樣操作組合ByteBuffer,避免了傳統(tǒng)通過內(nèi)存拷貝的方式將幾個buffer合并成一個大buffer,不需要內(nèi)存拷貝。
3.文件傳輸采用TransferTo方法,它可以直接將文件緩沖區(qū)的數(shù)據(jù)發(fā)送到目標channel,避免了傳統(tǒng)通過循環(huán)write方式導(dǎo)致的內(nèi)存拷貝問題。
最后總結(jié)
通過整理可以發(fā)現(xiàn),netty的零拷貝并不是完全不拷貝,而是減少了CPU拷貝,也就是數(shù)據(jù)從系統(tǒng)內(nèi)核空間的內(nèi)存到用戶空間內(nèi)存的拷貝。DMA拷貝還是存在的,畢竟它是操作系統(tǒng)所做的事情,不屬于應(yīng)用程序的操作范圍。在netty中,目前有三種方式實現(xiàn)的零拷貝。第一種使用堆外內(nèi)存。第二種,CompositeByteBuf組合buffer對象。第三種,文件傳輸采用TransferTo方法。
參考文檔:
holer 輕量級的內(nèi)網(wǎng)穿透工具,holer服務(wù)端采用Java語言實現(xiàn),服務(wù)端界面漂亮簡潔。
Holer客戶端采用了Java語言和GO語言實現(xiàn)了兩種版本,支持幾乎所有的OS平臺。
用到流行的微服務(wù)框架springboot和Java網(wǎng)絡(luò)框架netty。
配置很簡單,針對所有TCP協(xié)議只需在客戶端設(shè)置一個holer access key即可。
采用MySQL數(shù)據(jù)庫統(tǒng)一管理數(shù)據(jù)。