本篇文章給大家分享的是有關(guān)Soul高可用網(wǎng)關(guān)中配置緩存三大同步策略是什么,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
成都創(chuàng)新互聯(lián)公司專注于企業(yè)營銷型網(wǎng)站建設(shè)、網(wǎng)站重做改版、禹城網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5場景定制、商城網(wǎng)站開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為禹城等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
網(wǎng)關(guān)是流量請求的入口,在微服務(wù)架構(gòu)中承擔(dān)了非常重要的角色,網(wǎng)關(guān)高可用的重要性不言而喻。在使用網(wǎng)關(guān)的過程中,為了滿足業(yè)務(wù)訴求,經(jīng)常需要變更配置,比如流控規(guī)則、路由規(guī)則等等。因此,網(wǎng)關(guān)動態(tài)配置是保障網(wǎng)關(guān)高可用的重要因素。那么,Soul
網(wǎng)關(guān)又是如何支持動態(tài)配置的呢?
使用過 Soul
的同學(xué)都知道,Soul
的插件全都是熱插拔的,并且所有插件的選擇器、規(guī)則都是動態(tài)配置,立即生效,不需要重啟服務(wù)。但是我們在使用 Soul
網(wǎng)關(guān)過程中,用戶也反饋了不少問題
依賴 zookeeper
,這讓使用 etcd
、consul
、nacos
注冊中心的用戶很是困擾
依賴 redis
、influxdb
,我還沒有使用限流插件、監(jiān)控插件,為什么需要這些
因此,我們對 Soul
進(jìn)行了局部重構(gòu),歷時兩個月的版本迭代,我們發(fā)布了 2.0
版本
數(shù)據(jù)同步方式移除了對 zookeeper
的強(qiáng)依賴,新增 http 長輪詢
以及 websocket
限流插件與監(jiān)控插件實現(xiàn)真正的動態(tài)配置,由之前的 yml
配置,改為 admin
后臺用戶動態(tài)配置
答:首先,引入配置中心,會增加很多額外的成本,不管是運維,而且會讓 Soul
變得很重;另外,使用配置中心,數(shù)據(jù)格式不可控,不便于 soul-admin
進(jìn)行配置管理。
答:soul作為網(wǎng)關(guān),為了提供更高的響應(yīng)速度,所有的配置都緩存在JVM的Hashmap中,每次請求都走的本地緩存,速度非???。所以本文也可以理解為分布式環(huán)境中,內(nèi)存同步的三種方式。
先來張高清無碼圖,下圖展示了 Soul
數(shù)據(jù)同步的流程,Soul
網(wǎng)關(guān)在啟動時,會從從配置服務(wù)同步配置數(shù)據(jù),并且支持推拉模式獲取配置變更信息,并且更新本地緩存。而管理員在管理后臺,變更用戶、規(guī)則、插件、流量配置,通過推拉模式將變更信息同步給 Soul
網(wǎng)關(guān),具體是 push
模式,還是 pull
模式取決于配置。關(guān)于配置同步模塊,其實是一個簡版的配置中心。
在 1.x
版本中,配置服務(wù)依賴 zookeeper
實現(xiàn),管理后臺將變更信息 push
給網(wǎng)關(guān)。而 2.x
版本支持 webosocket
、http
、zookeeper
,通過 soul.sync.strategy
指定對應(yīng)的同步策略,默認(rèn)使用 http
長輪詢同步策略,可以做到秒級數(shù)據(jù)同步。但是,有一點需要注意的是,soul-web
和 soul-admin
必須使用相同的同步機(jī)制。
如下圖所示,soul-admin
在用戶發(fā)生配置變更之后,會通過 EventPublisher
發(fā)出配置變更通知,由 EventDispatcher
處理該變更通知,然后根據(jù)配置的同步策略(http、weboscket、zookeeper),將配置發(fā)送給對應(yīng)的事件處理器
如果是 websocket
同步策略,則將變更后的數(shù)據(jù)主動推送給 soul-web
,并且在網(wǎng)關(guān)層,會有對應(yīng)的 WebsocketCacheHandler
處理器處理來處 admin
的數(shù)據(jù)推送
如果是 zookeeper
同步策略,將變更數(shù)據(jù)更新到 zookeeper
,而 ZookeeperSyncCache
會監(jiān)聽到 zookeeper
的數(shù)據(jù)變更,并予以處理
如果是 http
同步策略,soul-web
主動發(fā)起長輪詢請求,默認(rèn)有 90s 超時時間,如果 soul-admin
沒有數(shù)據(jù)變更,則會阻塞 http 請求,如果有數(shù)據(jù)發(fā)生變更則響應(yīng)變更的數(shù)據(jù)信息,如果超過 60s 仍然沒有數(shù)據(jù)變更則響應(yīng)空數(shù)據(jù),網(wǎng)關(guān)層接到響應(yīng)后,繼續(xù)發(fā)起 http 請求,反復(fù)同樣的請求
基于 zookeeper 的同步原理很簡單,主要是依賴 zookeeper
的 watch 機(jī)制,soul-web
會監(jiān)聽配置的節(jié)點,soul-admin
在啟動的時候,會將數(shù)據(jù)全量寫入 zookeeper
,后續(xù)數(shù)據(jù)發(fā)生變更時,會增量更新 zookeeper
的節(jié)點,與此同時,soul-web
會監(jiān)聽配置信息的節(jié)點,一旦有信息變更時,會更新本地緩存。
soul
將配置信息寫到zookeeper節(jié)點,是通過精細(xì)設(shè)計的。
websocket
和 zookeeper
機(jī)制有點類似,將網(wǎng)關(guān)與 admin
建立好 websocket
連接時,admin
會推送一次全量數(shù)據(jù),后續(xù)如果配置數(shù)據(jù)發(fā)生變更,則將增量數(shù)據(jù)通過 websocket
主動推送給 soul-web
使用websocket同步的時候,特別要注意斷線重連,也叫保持心跳。soul
使用java-websocket
這個第三方庫來進(jìn)行websocket
連接。
public class WebsocketSyncCache extends WebsocketCacheHandler { /** * The Client. */ private WebSocketClient client; public WebsocketSyncCache(final SoulConfig.WebsocketConfig websocketConfig) { ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, SoulThreadFactory.create("websocket-connect", true)); client = new WebSocketClient(new URI(websocketConfig.getUrl())) { @Override public void onOpen(final ServerHandshake serverHandshake) { //.... } @Override public void onMessage(final String result) { //.... } }; //進(jìn)行連接 client.connectBlocking(); //使用調(diào)度線程池進(jìn)行斷線重連,30秒進(jìn)行一次 executor.scheduleAtFixedRate(() -> { if (client != null && client.isClosed()) { client.reconnectBlocking(); } }, 10, 30, TimeUnit.SECONDS); }
zookeeper、websocket 數(shù)據(jù)同步的機(jī)制比較簡單,而 http 同步會相對復(fù)雜一些。Soul 借鑒了 Apollo
、Nacos
的設(shè)計思想,取決精華,自己實現(xiàn)了 http
長輪詢數(shù)據(jù)同步功能。注意,這里并非傳統(tǒng)的 ajax 長輪詢!
http 長輪詢機(jī)制如上所示,soul-web 網(wǎng)關(guān)請求 admin 的配置服務(wù),讀取超時時間為 90s,意味著網(wǎng)關(guān)層請求配置服務(wù)最多會等待 90s,這樣便于 admin 配置服務(wù)及時響應(yīng)變更數(shù)據(jù),從而實現(xiàn)準(zhǔn)實時推送。
http 請求到達(dá) sou-admin 之后,并非立馬響應(yīng)數(shù)據(jù),而是利用 Servlet3.0 的異步機(jī)制,異步響應(yīng)數(shù)據(jù)。首先,將長輪詢請求任務(wù) LongPollingClient
扔到 BlocingQueue
中,并且開啟調(diào)度任務(wù),60s 后執(zhí)行,這樣做的目的是 60s 后將該長輪詢請求移除隊列,即便是這段時間內(nèi)沒有發(fā)生配置數(shù)據(jù)變更。因為即便是沒有配置變更,也得讓網(wǎng)關(guān)知道,總不能讓其干等吧,而且網(wǎng)關(guān)請求配置服務(wù)時,也有 90s 的超時時間。
public void doLongPolling(final HttpServletRequest request, final HttpServletResponse response) { // 因為soul-web可能未收到某個配置變更的通知,因此MD5值可能不一致,則立即響應(yīng) List<ConfigGroupEnum> changedGroup = compareMD5(request); String clientIp = getRemoteIp(request); if (CollectionUtils.isNotEmpty(changedGroup)) { this.generateResponse(response, changedGroup); return; } // Servlet3.0異步響應(yīng)http請求 final AsyncContext asyncContext = request.startAsync(); asyncContext.setTimeout(0L); scheduler.execute(new LongPollingClient(asyncContext, clientIp, 60)); } class LongPollingClient implements Runnable { LongPollingClient(final AsyncContext ac, final String ip, final long timeoutTime) { // 省略...... } @Override public void run() { // 加入定時任務(wù),如果60s之內(nèi)沒有配置變更,則60s后執(zhí)行,響應(yīng)http請求 this.asyncTimeoutFuture = scheduler.schedule(() -> { // clients是阻塞隊列,保存了來處soul-web的請求信息 clients.remove(LongPollingClient.this); List<ConfigGroupEnum> changedGroups = HttpLongPollingDataChangedListener.compareMD5((HttpServletRequest) asyncContext.getRequest()); sendResponse(changedGroups); }, timeoutTime, TimeUnit.MILLISECONDS); // clients.add(this); } }
如果這段時間內(nèi),管理員變更了配置數(shù)據(jù),此時,會挨個移除隊列中的長輪詢請求,并響應(yīng)數(shù)據(jù),告知是哪個 Group 的數(shù)據(jù)發(fā)生了變更(我們將插件、規(guī)則、流量配置、用戶配置數(shù)據(jù)分成不同的組)。網(wǎng)關(guān)收到響應(yīng)信息之后,只知道是哪個 Group 發(fā)生了配置變更,還需要再次請求該 Group 的配置數(shù)據(jù)。有人會問,為什么不是直接將變更的數(shù)據(jù)寫出?我們在開發(fā)的時候,也深入討論過該問題,因為 http 長輪詢機(jī)制只能保證準(zhǔn)實時,如果在網(wǎng)關(guān)層處理不及時,或者管理員頻繁更新配置,很有可能便錯過了某個配置變更的推送,安全起見,我們只告知某個 Group 信息發(fā)生了變更。
// soul-admin發(fā)生了配置變更,挨個將隊列中的請求移除,并予以響應(yīng) class DataChangeTask implements Runnable { DataChangeTask(final ConfigGroupEnum groupKey) { this.groupKey = groupKey; } @Override public void run() { try { for (Iterator<LongPollingClient> iter = clients.iterator(); iter.hasNext(); ) { LongPollingClient client = iter.next(); iter.remove(); client.sendResponse(Collections.singletonList(groupKey)); } } catch (Throwable e) { LOGGER.error("data change error.", e); } } }
當(dāng) soul-web
網(wǎng)關(guān)層接收到 http 響應(yīng)信息之后,拉取變更信息(如果有變更的話),然后再次請求 soul-admin
的配置服務(wù),如此反復(fù)循環(huán)。
get soul-admin.jar
> wget https://yu199195.github.io/jar/soul-admin.jar
start soul-admin.jar
java -jar soul-admin.jar -Dspring.datasource.url="your MySQL url" -Dspring.datasource.username='you username' -Dspring.datasource.password='you password'
visit : http://localhost:8887/index.html username:admin password :123456
get soul-bootstrap.jar
> wget https://yu199195.github.io/jar/soul-bootstrap.jar
start soul-bootstrap.jar
java -jar soul-bootstrap.jar
此文介紹了soul
作為一個高可用的微服務(wù)網(wǎng)關(guān),為了優(yōu)化響應(yīng)速度,在對配置規(guī)則選擇器器數(shù)據(jù)進(jìn)行本地緩存的三種方式,學(xué)了此文,我相信你對現(xiàn)在比較流行的配置中心有了一定的了解,看他們的代碼也許會變得容易,我相信你也可以自己寫一個分布式配置中心出來。3.0版本已經(jīng)在規(guī)劃中,肯定會給大家?guī)眢@喜。
以上就是Soul高可用網(wǎng)關(guān)中配置緩存三大同步策略是什么,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)站題目:Soul高可用網(wǎng)關(guān)中配置緩存三大同步策略是什么
轉(zhuǎn)載來源:http://www.rwnh.cn/article30/jcjjpo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計公司、營銷型網(wǎng)站建設(shè)、、企業(yè)網(wǎng)站制作、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)