輕量級的內網映射工具,holer服務端采用Java語言實現,服務端界面漂亮簡潔。
我們提供的服務有:成都網站建設、網站制作、微信公眾號開發(fā)、網站優(yōu)化、網站認證、灌陽ssl等。為上千多家企事業(yè)單位解決了網站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的灌陽網站制作公司
Holer客戶端采用了Java語言和GO語言實現了兩種版本,支持幾乎所有的OS平臺。
用到流行的微服務框架springboot和Java網絡框架netty。
配置很簡單,針對所有TCP協(xié)議只需在客戶端設置一個holer access key即可。
采用MySQL數據庫統(tǒng)一管理數據。
go語言應該沒有,java netty這種高性能異步IO模型的框架,建議你還是用java語言開發(fā)吧
netty是一個封裝了nio的java語言實踐的io框架,使編程人員從繁瑣且容器出bug的nio編程中解放出來,更專注于業(yè)務創(chuàng)新能力,而且很多其他的上層框架也會使用netty作為io模塊的實現,例如dubbo,spring-gateway之類.沒事可以去黑馬程序員官網視頻庫看免費視頻。
無論是什么協(xié)議,如果要真正被使用的話,需要將該協(xié)議轉換成為對應的語言才好真正的進行應用,本文將從http2消息的結構出發(fā),探討一下netty對http2消息的封裝,帶大家領略一下真正的框架應該做到什么程度。
http2和http1.1不同的是它使用了新的二進制分幀,通過客戶端和服務器端建立數據流steam來進行客戶端和服務器端之間消息的交互。其中數據流是一個雙向字節(jié)流,用來發(fā)送一條或者多條消息。
消息是客戶端和服務端發(fā)送的一個邏輯上完整的數據。根據數據大小的不同,可以將消息劃分為不同的幀Frame。也就是說message是由不同的frame組成的。
frame就是http2中進行通信的最小單位,根據上一節(jié)的介紹,我們知道frame有這樣幾種:
我們看一下http2中stream和frame的一個大體的結構:
在http2中,一個TCP連接,可以承載多個數據流stream,多個stream中的不同frame可以交錯發(fā)送。
每個frame通過stream id來標記其所屬的stream。
有了上面的http2的基本概念,我們接下來就看下netty對http2的封裝了。
作為一個TCP連接下面的最大的單位stream,netty中提供了接口Http2Stream。注意,Http2Stream是一個接口,它有兩個實現類,分別是DefaultStream和ConnectionStream。
Http2Stream中有兩個非常重要的屬性,分別是id和state。
id前面已經介紹了,是stream的唯一標記。這里要注意由客戶端建立的 Stream ID 必須是奇數,而由服務端建立的 Stream ID 必須是偶數。另外Stream ID 為 0 的流有特殊的作用,它是CONNECTION_STREAM_ID,1 表示HTTP_UPGRADE_STREAM_ID。
state表示stream的狀態(tài),具體而言,stream有下面幾個狀態(tài):
為什么狀態(tài)需要區(qū)分local和remote呢?這是因為stream連接的兩端,所以有兩端的狀態(tài)。
和stream狀態(tài)相對應的就是http2的生命周期了。netty提供了Http2LifecycleManager來表示對http2生命周期的管理:
分別是關閉stream,重置stream,拒絕新建stream:goAway,和處理出錯狀態(tài)這幾種。
stream之后,就是真實承載http2消息的Http2Frame了。在netty中,Http2Frame是一個接口,它有很多具體的實現。
Http2Frame的直接子類包括HTTP2GoAwayFrame、HTTPPingFrame、Http2SettingsFrame和HTTP2SettingsAckFrame。
其中goAway表示不接受新的stream,ping用來進行心跳檢測。SETTINGS用來修改連接或者 Stream 流的配置。
netty中專門有一個Http2Settings類和其對應。
在這個類中定義了一些特別的setting名字:
除了上面講的4個frame之外,其他的frame實現都繼承自Http2StreamFrame,具體而言有PriorityFrame,ResetFrame,HeadersFrame,DataFrame,WindowUpdateFrame,PushPromiseFrame和UnknownFrame。
各個frame分別代表了不同的功能。這里最重要的就是Http2HeadersFrame和Http2DataFrame。
Http2HeadersFrame主要是客戶端發(fā)送給服務器端的http2請求。
具體而言除了標準的http1.1的header之外,http2還支持下面的header:
對于Http2DataFrame來說,他本身是一個ByteBufHolder,用來傳遞具體的數據信息。data frame的Payload直接存儲在ByteBuf中。
以上就是netty對http2消息的封裝了。
本文的例子可以參考: learn-netty4
一、服務注冊中心的由來
假如沒有服務注冊中心,我們會干些什么事情呢?
在傳統(tǒng)行業(yè)的項目架構中以下的方案最為常見了:
這種架構開發(fā)、部署都是最簡單的,一般適用于中小企業(yè)訪問量并不是太多的情況下,各個系統(tǒng)服務一臺機器就搞定了。系統(tǒng)之間的調用也是拿到對方的IP+PORT直接連接。
接下來可能因為應用B開始訪問量大了,單臺機器已經不能滿足我們的需求,于是一些反向代理工具應運而出,其中比較常見的有Apache、Nigix,架構演變?yōu)椋?/p>
相比之前的應用B的單臺機器訪問,這種nginx代理的方式減輕了服務器的壓力,但是可能會出現Nginx掛了,那么整個服務也不可用,于是又來了這么一套架構:
這樣看方案算是完美了吧。然后事情并不是想象的那么一帆風順,這還只是應用A調用一個應用B,如果應用A調用的可能是應用B、C、D、E...,這種完全就不知道他后面到底還想干嘛,這種架構看似可以,但是絕對會累死運維的(nginx的配置將會非常混亂,直接導致運維不干了)。
服務注冊中心干些什么事情呢?
上面提到的那種靠人力(主要是運維干的事情)比較繁瑣,還不好維護,有這么幾點不方便:應用服務的地址變了、雙十一搞活動服務器新增等等。那么我們可以有這么的一種架構:
服務注冊中心主要是維護各個應用服務的ip+port列表,并保持與各應用服務的通訊,在一定時間間隔內進行心跳檢測,如果心跳不能到達則對服務IP列表進行剔除,并同時通知給其它應用服務進行更新。同樣要是有新增的服務進來,應用服務會向注冊中心進行注冊,服務注冊中心將通知給其它應用進行更新。每個應用都有需要調用對應應用服務的地址列表,這樣在進行調用時只要處理客戶負載雜均衡即可。
二、微服務注冊中心
1.Zookeeper
ZooKeeper是一個分布式的,開放源碼的分布式應用程序協(xié)調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個為分布式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分布式同步、組服務等。
上面的話直接摘抄百度百科的內容,國內很多公司做分布式開發(fā)最初的選型大部分都是采用dubbo框架。dubbo框架注冊中心主要使用zookeeper。zookeeper服務端與客戶端的底層通訊為netty。zookeeper采用CAP理論中的CP,一般集群部署最少需要3臺機器。
2.Euraka
先來看一下euraka的架構圖:
Register:服務注冊
當Eureka客戶端向Eureka Server注冊時,它提供自身的元數據,比如IP地址、端口,運行狀況指示符URL,主頁等。
Renew:服務續(xù)約
Eureka客戶會每隔30秒發(fā)送一次心跳來續(xù)約。 通過續(xù)約來告知Eureka Server該Eureka客戶仍然存在,沒有出現問題。 正常情況下,如果Eureka Server在90秒沒有收到Eureka客戶的續(xù)約,它會將實例從其注冊表中刪除。 建議不要更改續(xù)約間隔。
Fetch Registries:獲取注冊列表信息
Eureka客戶端從服務器獲取注冊表信息,并將其緩存在本地。客戶端會使用該信息查找其他服務,從而進行遠程調用。該注冊列表信息定期(每30秒鐘)更新一次。每次返回注冊列表信息可能與Eureka客戶端的緩存信息不同, Eureka客戶端自動處理。如果由于某種原因導致注冊列表信息不能及時匹配,Eureka客戶端則會重新獲取整個注冊表信息。 Eureka服務器緩存注冊列表信息,整個注冊表以及每個應用程序的信息進行了壓縮,壓縮內容和沒有壓縮的內容完全相同。Eureka客戶端和Eureka 服務器可以使用JSON / XML格式進行通訊。在默認的情況下Eureka客戶端使用壓縮JSON格式來獲取注冊列表的信息。
Cancel:服務下線
Eureka客戶端在程序關閉時向Eureka服務器發(fā)送取消請求。 發(fā)送請求后,該客戶端實例信息將從服務器的實例注冊表中刪除。該下線請求不會自動完成,它需要調用以下內容:
DiscoveryManager.getInstance().shutdownComponent();
Eviction 服務剔除
在默認的情況下,當Eureka客戶端連續(xù)90秒沒有向Eureka服務器發(fā)送服務續(xù)約,即心跳,Eureka服務器會將該服務實例從服務注冊列表刪除,即服務剔除。
自我保護機制:
既然Eureka Server會定時剔除超時沒有續(xù)約的服務,那就有可能出現一種場景,網絡一段時間內發(fā)生了 異常,所有的服務都沒能夠進行續(xù)約,Eureka Server就把所有的服務都剔除了,這樣顯然不太合理。所以,就有了 自我保護機制,當短時間內,統(tǒng)計續(xù)約失敗的比例,如果達到一定閾值,則會觸發(fā)自我保護的機制,在該機制下, Eureka Server不會剔除任何的微服務,等到正常后,再退出自我保護機制。自我保護開關(eureka.server.enableself-preservation: false)
3.Consul
consul推薦的架構圖:
Consul不像Euraka的部署那么簡單,他是go語言開發(fā)的,需要運維單獨部署,有提供java的客戶端連接,采用的是CAP的CP。
4.Nacos
Euraka是Spring Cloud Netflix早期版本中推薦使用的,后來euraka1.0版本不再維護,euraka2.0已經閉源,導致很多新項目基于Spring Cloud Netflix 開發(fā)的選型變遷為Consul.
Nacos是阿里開源的服務注冊中心,它可以與spring cloud aliaba集成使用。
Nacos的官方介紹:
Nacos 致力于幫助您發(fā)現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您實現動態(tài)服務發(fā)現、服務配置管理、服務及流量管理。
Nacos 幫助您更敏捷和容易地構建、交付和管理微服務平臺。 Nacos 是構建以“服務”為中心的現代應用架構(例如微服務范式、云原生范式)的服務基礎設施。
Nacos 地圖
Nacos 生態(tài)圖
如 Nacos 全景圖所示,Nacos 無縫支持一些主流的開源生態(tài),例如
Spring Cloud
Apache Dubbo and Dubbo Mesh TODO
Kubernetes and CNCF TODO
三、服務注冊與發(fā)現技術選型
以下是來自網上的一個分享:
除了上述的幾種以外,筆者更推薦使用Nacos作為服務注冊中心。
推薦理由:
Nacos服務注冊表結構Mapnamespace, Mapgroup::serviceName, Service采用多層次Map結構,控制的顆粒度更細,支持金絲雀模式發(fā)布,心跳同步機制也更快速,服務更新更及時。