為什么大型互聯(lián)網(wǎng)都需要網(wǎng)關(guān)服務(wù)?-創(chuàng)新互聯(lián)

前言

成都創(chuàng)新互聯(lián)專注于威縣企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,成都做商城網(wǎng)站。威縣網(wǎng)站建設(shè)公司,為威縣等地區(qū)提供建站服務(wù)。全流程按需定制開發(fā),專業(yè)設(shè)計,全程項目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

假設(shè)你正在開發(fā)一個電商網(wǎng)站,那么這里會涉及到很多后端的微服務(wù),比如會員、商品、推薦服務(wù)等等。

為什么大型互聯(lián)網(wǎng)都需要網(wǎng)關(guān)服務(wù)?

那么這里就會遇到一個問題,APP/Browser怎么去訪問這些后端的服務(wù)? 如果業(yè)務(wù)比較簡單的話,可以給每個業(yè)務(wù)都分配一個獨立的域名(https://service.api.company.com),但這種方式會有幾個問題:

  • 每個業(yè)務(wù)都會需要鑒權(quán)、限流、權(quán)限校驗等邏輯,如果每個業(yè)務(wù)都各自為戰(zhàn),自己造輪子實現(xiàn)一遍,會很蛋疼,完全可以抽出來,放到一個統(tǒng)一的地方去做。

  • 如果業(yè)務(wù)量比較簡單的話,這種方式前期不會有什么問題,但隨著業(yè)務(wù)越來越復(fù)雜,比如淘寶、亞馬遜打開一個頁面可能會涉及到數(shù)百個微服務(wù)協(xié)同工作,如果每一個微服務(wù)都分配一個域名的話,一方面客戶端代碼會很難維護,涉及到數(shù)百個域名,另一方面是連接數(shù)的瓶頸,想象一下你打開一個APP,通過抓包發(fā)現(xiàn)涉及到了數(shù)百個遠程調(diào)用,這在移動端下會顯得非常低效。

  • 每上線一個新的服務(wù),都需要運維參與,申請域名、配置Nginx等,當(dāng)上線、下線服務(wù)器時,同樣也需要運維參與,另外采用域名這種方式,對于環(huán)境的隔離也不太友好,調(diào)用者需要自己根據(jù)域名自己進行判斷。

  • 另外還有一個問題,后端每個微服務(wù)可能是由不同語言編寫的、采用了不同的協(xié)議,比如HTTP、Dubbo、GRPC等,但是你不可能要求客戶端去適配這么多種協(xié)議,這是一項非常有挑戰(zhàn)的工作,項目會變的非常復(fù)雜且很難維護。

  • 后期如果需要對微服務(wù)進行重構(gòu)的話,也會變的非常麻煩,需要客戶端配合你一起進行改造,比如商品服務(wù),隨著業(yè)務(wù)變的越來越復(fù)雜,后期需要進行拆分成多個微服務(wù),這個時候?qū)ν馓峁┑姆?wù)也需要拆分成多個,同時需要客戶端配合你進行改造,非常蛋疼。

API Gateway

為什么大型互聯(lián)網(wǎng)都需要網(wǎng)關(guān)服務(wù)?

更好的方式是采用API網(wǎng)關(guān),實現(xiàn)一個API網(wǎng)關(guān)接管所有的入口流量,類似Nginx的作用,將所有用戶的請求轉(zhuǎn)發(fā)給后端的服務(wù)器,但網(wǎng)關(guān)做的不僅僅只是簡單的轉(zhuǎn)發(fā),也會針對流量做一些擴展,比如鑒權(quán)、限流、權(quán)限、熔斷、協(xié)議轉(zhuǎn)換、錯誤碼統(tǒng)一、緩存、日志、監(jiān)控、告警等,這樣將通用的邏輯抽出來,由網(wǎng)關(guān)統(tǒng)一去做,業(yè)務(wù)方也能夠更專注于業(yè)務(wù)邏輯,提升迭代的效率。

通過引入API網(wǎng)關(guān),客戶端只需要與API網(wǎng)關(guān)交互,而不用與各個業(yè)務(wù)方的接口分別通訊,但多引入一個組件就多引入了一個潛在的故障點,因此要實現(xiàn)一個高性能、穩(wěn)定的網(wǎng)關(guān),也會涉及到很多點。

為什么大型互聯(lián)網(wǎng)都需要網(wǎng)關(guān)服務(wù)?

API注冊

業(yè)務(wù)方如何接入網(wǎng)關(guān)?一般來說有幾種方式。

  • 第一種采用插件掃描業(yè)務(wù)方的API,比如Spring MVC的注解,并結(jié)合Swagger的注解,從而實現(xiàn)參數(shù)校驗、文檔&&SDK生成等功能,掃描完成之后,需要上報到網(wǎng)關(guān)的存儲服務(wù)。

  • 手動錄入。比如接口的路徑、請求參數(shù)、響應(yīng)參數(shù)、調(diào)用方式等信息,但這種方式相對來說會麻煩一些,如果參數(shù)過多的話,前期錄入會很費時費力。

為什么大型互聯(lián)網(wǎng)都需要網(wǎng)關(guān)服務(wù)?

  • 配置文件導(dǎo)入。比如通過SwaggerOpenAPI等,比如阿里云的網(wǎng)關(guān):

為什么大型互聯(lián)網(wǎng)都需要網(wǎng)關(guān)服務(wù)?

協(xié)議轉(zhuǎn)換

內(nèi)部的API可能是由很多種不同的協(xié)議實現(xiàn)的,比如HTTP、Dubbo、GRPC等,但對于用戶來說其中很多都不是很友好,或者根本沒法對外暴露,比如Dubbo服務(wù),因此需要在網(wǎng)關(guān)層做一次協(xié)議轉(zhuǎn)換,將用戶的HTTP協(xié)議請求,在網(wǎng)關(guān)層轉(zhuǎn)換成底層對應(yīng)的協(xié)議,比如HTTP -> Dubbo, 但這里需要注意很多問題,比如參數(shù)類型,如果類型搞錯了,導(dǎo)致轉(zhuǎn)換出問題,而日志又不夠詳細的話,問題會很難定位。

服務(wù)發(fā)現(xiàn)

網(wǎng)關(guān)作為流量的入口,負責(zé)請求的轉(zhuǎn)發(fā),但首先需要知道轉(zhuǎn)發(fā)給誰,如何尋址,這里有幾種方式:

  • 寫死在代碼/配置文件里,這種方式雖然比較挫,但也能使用,比如線上仍然使用的是物理機,IP變動不會很頻繁,但擴縮容、包括應(yīng)用上下線都會很麻煩,網(wǎng)關(guān)自身甚至需要實現(xiàn)一套健康監(jiān)測機制。

  • 域名。采用域名也是一種不錯的方案,對于所有的語言都適用,但對于內(nèi)部的服務(wù),走域名會很低效,另外環(huán)境隔離也不太友好,比如預(yù)發(fā)、線上通常是同一個數(shù)據(jù)庫,因此網(wǎng)關(guān)讀取到的可能是同一個域名,這時候預(yù)發(fā)的網(wǎng)關(guān)調(diào)用的就是線上的服務(wù)。

  • 注冊中心。采用注冊中心就不會有上述的這些問題,即使是在容器環(huán)境下,節(jié)點的IP變更比較頻繁,但節(jié)點列表的實時維護會由注冊中心搞定,對網(wǎng)關(guān)是透明的,另外應(yīng)用的正常上下線、包括異常宕機等情況,也會由注冊中心的健康檢查機制檢測到,并實時反饋給網(wǎng)關(guān)。并且采用注冊中心性能也沒有額外的性能損耗,采用域名的方式,額外需要走一次DNS解析、Nginx轉(zhuǎn)發(fā)等,中間多了很多跳,性能會有很大的下降,但采用注冊中心,網(wǎng)關(guān)是和業(yè)務(wù)方直接點對點的通訊,不會有額外的損耗。

服務(wù)調(diào)用

網(wǎng)關(guān)由于對接很多種不同的協(xié)議,因此可能需要實現(xiàn)很多種調(diào)用方式,比如HTTP、Dubbo等,基于性能原因,最好都采用異步的方式,而Http、Dubbo都是支持異步的,比如apache就提供了基于NIO實現(xiàn)的異步HTTP客戶端。

因為網(wǎng)關(guān)會涉及到很多異步調(diào)用,比如攔截器、HTTP客戶端、dubbo、redis等,因此需要考慮下異步調(diào)用的方式,如果基于回調(diào)或者future的話,代碼嵌套會很深,可讀性很差,可以參考zuul和spring cloud gateway的方案,基于響應(yīng)式進行改造。

優(yōu)雅下線

優(yōu)雅下線也是網(wǎng)關(guān)需要關(guān)注的一個問題,網(wǎng)關(guān)底層會涉及到很多種協(xié)議,比如HTTP、Dubbo,而HTTP又可以繼續(xù)細分,比如域名、注冊中心等,有些自身就支持優(yōu)雅下線,比如Nginx自身是支持健康監(jiān)測機制的,如果檢測到某一個節(jié)點已經(jīng)掛掉了,就會把這個節(jié)點摘掉,對于應(yīng)用正常下線,需要結(jié)合發(fā)布系統(tǒng),首先進行邏輯下線,然后對后續(xù)Nginx的健康監(jiān)測請求直接返回失敗(比如直接返回500),然后等待一段時間(根據(jù)Nginx配置決定),然后再將應(yīng)用實際下線掉。另外對于注冊中心的其實也類似,一般注冊中心是只支持手動下線的,可以在邏輯下線階段調(diào)用注冊中心的接口將節(jié)點下線掉,而有些不支持主動下線的,需要結(jié)合緩存的配置,讓應(yīng)用延遲下線。另外對于其他比如Dubbo等原理也是類似。

性能

網(wǎng)關(guān)作為所有流量的入口,性能是重中之重,早期大部分網(wǎng)關(guān)都是基于同步阻塞模型構(gòu)建的,比如Zuul 1.x。但這種同步的模型我們都知道,每個請求/連接都會占用一個線程,而線程在JVM中是一個很重的資源,比如Tomcat默認就是200個線程,如果網(wǎng)關(guān)隔離沒有做好的話,當(dāng)發(fā)生網(wǎng)絡(luò)延遲、FullGC、第三方服務(wù)慢等情況造成上游服務(wù)延遲時,線程池很容易會被打滿,造成新的請求被拒絕,但這個時候其實線程都阻塞在IO上,系統(tǒng)的資源被沒有得到充分的利用。另外一點,容易受網(wǎng)絡(luò)、磁盤IO等延遲影響。需要謹慎設(shè)置超時時間,如果設(shè)置不當(dāng),且服務(wù)隔離做的不是很完善的話,網(wǎng)關(guān)很容易被一個慢接口拖垮。

而異步化的方式則完全不同,通常情況下一個CPU核啟動一個線程即可處理所有的請求、響應(yīng)。一個請求的生命周期不再固定于一個線程,而是會分成不同的階段交由不同的線程池處理,系統(tǒng)的資源能夠得到更充分的利用。而且因為線程不再被某一個連接獨占,一個連接所占用的系統(tǒng)資源也會低得多,只是一個文件描述符加上幾個監(jiān)聽器等,而在阻塞模型中,每條連接都會獨占一個線程,而線程是一個非常重的資源。對于上游服務(wù)的延遲情況,也能夠得到很大的緩解,因為在阻塞模型中,慢請求會獨占一個線程資源,而異步化之后,因為單條連接所占用的資源變的非常低,系統(tǒng)可以同時處理大量的請求。

如果是JVM平臺,Zuul 2、Spring Cloud gateway等都是不錯的異步網(wǎng)關(guān)選型,另外也可以基于Netty、Spring Boot2.x的webflux、vert.x或者servlet3.1的異步支持進行自研。

緩存

對于一些冪等的get請求,可以在網(wǎng)關(guān)層面根據(jù)業(yè)務(wù)方指定的緩存頭做一層緩存,存儲到Redis等二級緩存中,這樣一些重復(fù)的請求,可以在網(wǎng)關(guān)層直接處理,而不用打到業(yè)務(wù)線,降低業(yè)務(wù)方的壓力,另外如果業(yè)務(wù)方節(jié)點掛掉,網(wǎng)關(guān)也能夠返回自身的緩存。

限流

限流對于每個業(yè)務(wù)組件來說,可以說都是一個必須的組件,如果限流做不好的話,當(dāng)請求量突增時,很容易導(dǎo)致業(yè)務(wù)方的服務(wù)掛掉,比如雙11、雙12等大促時,接口的請求量是平時的數(shù)倍,如果沒有評估好容量,又沒有做限流的話,很容易服務(wù)整個不可用,因此需要根據(jù)業(yè)務(wù)方接口的處理能力,做好限流策略,相信大家都見過淘寶、百度搶紅包時的降級頁面。

因此一定要在接入層做好限流策略,對于非核心接口可以直接將降級掉,保障核心服務(wù)的可用性,對于核心接口,需要根據(jù)壓測時得到的接口容量,制定對應(yīng)的限流策略。限流又分為幾種:

  • 單機。單機性能比較高,不涉及遠程調(diào)用,只是本地計數(shù),對接口RT影響最小。但需要考慮下限流數(shù)的設(shè)置,比如是針對單臺網(wǎng)關(guān)、還是整個網(wǎng)關(guān)集群,如果是整個集群的話,需要考慮到網(wǎng)關(guān)縮容、擴容時修改對應(yīng)的限流數(shù)。

  • 分布式。分布式的就需要一個存儲節(jié)點維護當(dāng)前接口的調(diào)用數(shù),比如redis、sentinel等,這種方式由于涉及到遠程調(diào)用,會有些性能損耗,另外也需要考慮到存儲掛掉的問題,比如redis如果掛掉,網(wǎng)關(guān)需要考慮降級方案,是降級到本地限流,還是直接將限流功能本身降級掉。

另外還有不同的策略:簡單計數(shù)、令牌桶等,大部分場景下其實簡單計數(shù)已經(jīng)夠用了,但如果需要支持突發(fā)流量等場景時,可以采用令牌桶等方案。還需要考慮根據(jù)什么限流,比如是IP、接口、用戶維度、還是請求參數(shù)中的某些值,這里可以采用表達式,相對比較靈活。

穩(wěn)定性

穩(wěn)定性是網(wǎng)關(guān)非常重要的一環(huán),監(jiān)控、告警需要做的很完善才可以,比如接口調(diào)用量、響應(yīng)時間、異常、錯誤碼、成功率等相關(guān)的監(jiān)控告警,還有線程池相關(guān)的一些,比如活躍線程數(shù)、隊列積壓等,還有些系統(tǒng)層面的,比如CPU、內(nèi)存、FullGC這些基本的。

網(wǎng)關(guān)是所有服務(wù)的入口,對于網(wǎng)關(guān)的穩(wěn)定性的要求相對于其他服務(wù)會更高,最好能夠一直穩(wěn)定的運行,盡量少重啟,但當(dāng)新增功能、或者加日志排查問題時,不可避免的需要重新發(fā)布,因此可以參考zuul的方式,將所有的核心功能都基于不同的攔截器實現(xiàn),攔截器的代碼采用Groovy編寫,存儲到數(shù)據(jù)庫中,支持動態(tài)加載、編譯、運行,這樣在出了問題的時候能夠第一時間定位并解決,并且如果網(wǎng)關(guān)需要開發(fā)新功能,只需要增加新的攔截器,并動態(tài)添加到網(wǎng)關(guān)即可,不需要重新發(fā)布。

熔斷降級

熔斷機制也是非常重要的一項。若某一個服務(wù)掛掉、接口響應(yīng)嚴重超時等發(fā)生,則可能整個網(wǎng)關(guān)都被一個接口拖垮,因此需要增加熔斷降級,當(dāng)發(fā)生特定異常的時候,對接口降級由網(wǎng)關(guān)直接返回,可以基于Hystrix或者Resilience4j實現(xiàn)。

日志

由于所有的請求都是由網(wǎng)關(guān)處理的,因此日志也需要相對比較完善,比如接口的耗時、請求方式、請求IP、請求參數(shù)、響應(yīng)參數(shù)(注意脫敏)等,另外由于可能涉及到很多微服務(wù),因此需要提供一個統(tǒng)一的traceId方便關(guān)聯(lián)所有的日志,可以將這個traceId置于響應(yīng)頭中,方便排查問題。

隔離

比如線程池、http連接池、redis等應(yīng)用層面的隔離,另外也可以根據(jù)業(yè)務(wù)場景,將核心業(yè)務(wù)部署帶單獨的網(wǎng)關(guān)集群,與其他非核心業(yè)務(wù)隔離開。

網(wǎng)關(guān)管控平臺

這塊也是非常重要的一環(huán),需要考慮好整個流程的用戶體驗,比如接入到網(wǎng)關(guān)的這個流程,能不能盡量簡化、智能,比如如果是dubbo接口,我們可以通過到git倉庫中獲取源碼、解析對應(yīng)的類、方法,從而實現(xiàn)自動填充,盡量幫用戶減少操作;另外接口一般是從測試->預(yù)發(fā)->線上,如果每次都要填寫一遍表單會非常麻煩,我們能不能自動把這個事情做掉,另外如果網(wǎng)關(guān)部署到了多個可用區(qū)、甚至不同的國家,那這個時候,我們還需要接口數(shù)據(jù)同步功能,不然用戶需要到每個后臺都操作一遍,非常麻煩。

這塊個人的建議是直接參考阿里云、aws等提供的網(wǎng)關(guān)服務(wù)即可,功能非常全面。

其他

其他還有些需要考慮到的點,比如接口mock,文檔生成、sdk代碼生成、錯誤碼統(tǒng)一、服務(wù)治理相關(guān)的等,這里就不累述了。

總結(jié)

目前的網(wǎng)關(guān)還是中心化的架構(gòu),所有的請求都需要走一次網(wǎng)關(guān),因此當(dāng)大促或者流量突增時,網(wǎng)關(guān)可能會成為性能的瓶頸,而且當(dāng)網(wǎng)關(guān)接入的大量接口的時候,做好流量評估也不是一項容易的工作,每次大促前都需要跟業(yè)務(wù)方一起針對接口做壓測,評估出大致的容量,并對網(wǎng)關(guān)進行擴容,而且網(wǎng)關(guān)是所有流量的入口,所有的請求都是由網(wǎng)關(guān)處理,要想準確的評估出容量很復(fù)雜??梢詤⒖寄壳氨容^流行的ServiceMesh,采用去中心化的方案,將網(wǎng)關(guān)的邏輯下沉到sidecar中,sidecar和應(yīng)用部署到同一個節(jié)點,并接管應(yīng)用流入、流出的流量,這樣大促時,只需要對相關(guān)的業(yè)務(wù)壓測,并針對性擴容即可,另外升級也會更平滑,中心化的網(wǎng)關(guān),即使灰度發(fā)布,但是理論上所有業(yè)務(wù)方的流量都會流入到新版本的網(wǎng)關(guān),如果出了問題,會影響到所有的業(yè)務(wù),但這種去中心化的方式,可以先針對非核心業(yè)務(wù)升級,觀察一段時間沒問題后,再全量推上線。另外ServiceMesh的方案,對于多語言支持也更友好。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

分享名稱:為什么大型互聯(lián)網(wǎng)都需要網(wǎng)關(guān)服務(wù)?-創(chuàng)新互聯(lián)
鏈接URL:http://muchs.cn/article16/dhiegg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)、商城網(wǎng)站定制開發(fā)、虛擬主機、企業(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)

搜索引擎優(yōu)化