日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

唯品会API网关设计与实践--转

發(fā)布時間:2025/4/5 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 唯品会API网关设计与实践--转 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文地址:https://609518.kuaizhan.com/86/70/p4108366952248f

劉璟宇Leo

  唯品會資深研發(fā)工程師,在大型高性能分布式系統(tǒng)設(shè)計和開發(fā)方面有豐富的經(jīng)驗(yàn)。目前在唯品會平臺與架構(gòu)部負(fù)責(zé)唯品會API網(wǎng)關(guān)和服務(wù)安全方面的設(shè)計、開發(fā)、運(yùn)營工作。

  內(nèi)容解析

  1. 為什么引入網(wǎng)關(guān)

  

  唯品會是一家專門做特賣的網(wǎng)站,唯品會網(wǎng)站是一個巨大型的網(wǎng)站,每張頁面背后,都有多個服務(wù)提供靜態(tài)資源和動態(tài)數(shù)據(jù)。

  這是唯品會網(wǎng)站上一張商品詳情頁面,內(nèi)容是一款女式針織衫。頁面里,除去靜態(tài)頁面、圖片之外,有些動態(tài)內(nèi)容:商品價格、促銷提示語、產(chǎn)品介紹、商品庫存等。每個部分都會從后端的一個或幾個服務(wù)拉取數(shù)據(jù)。

  在唯品會公司內(nèi)部,已經(jīng)采用服務(wù)化的方式把服務(wù)進(jìn)行了拆分,內(nèi)部服務(wù)之間采用基于thrift的二進(jìn)制協(xié)議通訊。這些服務(wù)不能直接對外部提供服務(wù)。

  在引入API網(wǎng)關(guān)前,我們在外部app、瀏覽器和內(nèi)部服務(wù)之間會做一層webapp,起到兩個作用:

  一個是從外部的http協(xié)議,適配到內(nèi)部的二進(jìn)制協(xié)議。

  另一個是對數(shù)據(jù)進(jìn)行聚合。

  另外這些webapp里面還集成了如oauth等的一些公共服務(wù)。

  

  由于唯品會網(wǎng)站的業(yè)務(wù)眾多、業(yè)務(wù)量也非常大,這種webapp的數(shù)量有數(shù)百個,實(shí)例數(shù)量數(shù)千個。

  在數(shù)量達(dá)到這種規(guī)模后,產(chǎn)生了一些問題,我們設(shè)想一個場景,比如某種安全防護(hù)技術(shù)需要升級一下,那么安全開發(fā)組需要先跟業(yè)務(wù)開發(fā)團(tuán)隊(duì)協(xié)商開發(fā)時間,等排期開發(fā),然后需要測試,再排期發(fā)版。這樣幾十個業(yè)務(wù)開發(fā)團(tuán)隊(duì)升級下來,幾個月可能就過去了。

  再設(shè)想一個場景,例如,我可能想app支持一下二進(jìn)制協(xié)議,可以提升數(shù)據(jù)交換效率。

  一般我們做webapp,都是tomcat+springmvc這種結(jié)構(gòu)進(jìn)行開發(fā),支持二進(jìn)制協(xié)議就很困難。

  所以,目前這種webapp的架構(gòu),對于公共服務(wù)集成升級和公共技術(shù)的升級不是很友好。

  

  我們對架構(gòu)進(jìn)行了優(yōu)化,引入了網(wǎng)關(guān)。網(wǎng)關(guān)的主要作用有三個:

  一個是協(xié)議適配

  另一個是公共服務(wù)接入

  最后是公共接入技術(shù)優(yōu)化

  在外網(wǎng)和內(nèi)網(wǎng)中間有了網(wǎng)關(guān),網(wǎng)關(guān)本身和業(yè)務(wù)程序分離,就可以獨(dú)立的對這些技術(shù)進(jìn)行集成和升級。

  

  http://microservices.io/ 總結(jié)的微服務(wù)模式中,網(wǎng)關(guān)已經(jīng)成為服務(wù)化中的一種標(biāo)準(zhǔn)模式。http://microservices.io/patterns/apigateway.html

  

  網(wǎng)關(guān)模式,被一些大型的互聯(lián)網(wǎng)公司采用。國內(nèi)主要有唯品會、百度、阿里、京東、攜程、有贊等,國外主要有Netflix, Amazon, Mashape等。

  2. 選型和設(shè)計

  

  開源網(wǎng)關(guān)按照平臺可以分為基于nginx平臺的網(wǎng)關(guān)和自研網(wǎng)關(guān)

  基于nginx平臺的網(wǎng)關(guān)有:

  KONG

  API Umbrella

  自研的網(wǎng)關(guān)有:

  apigee

  StrongLoop

  Zuul

  Tyk

  按照語言分類,可以見上圖,有基于lua(nginx平臺), nodejs, java, go等語言的網(wǎng)關(guān)。

  

  基于nginx平臺的網(wǎng)關(guān)和自研網(wǎng)關(guān)的優(yōu)勢和劣勢如下:

?

基于nginx

自研

  優(yōu)勢

  1.?nginx有完善的處理http協(xié)議的能力

  2.?全異步高性能基礎(chǔ)處理能力

  3.?http處理過程中多個擴(kuò)展點(diǎn)可進(jìn)行擴(kuò)展

  4.?開箱即用,基于openresty開發(fā)相對簡單

  1.?可以完全掌控對http協(xié)議的處理過程

  2.?可以完全掌控異步化業(yè)務(wù)處理過程

  3.?對內(nèi)部協(xié)議支持可以較好掌控

  4.?和內(nèi)部的配置中心、注冊中心結(jié)合較好

  劣勢

  1.?nginx工作流程復(fù)雜,對大多數(shù)人來說,只能當(dāng)作黑盒子用,出問題難以真正在代碼級理解根本原因,擴(kuò)展核心功能較為困難。

  2.?基于openresty擴(kuò)展,本身有性能開銷,對java、erlang、go的性能優(yōu)勢不明顯

  3.?對內(nèi)部協(xié)議和基礎(chǔ)組件支持不方便

  1.?對http協(xié)議處理有較多的坑需要踩

  2.?需要大量的性能優(yōu)化過程,不像nginx經(jīng)過大量實(shí)踐,本身有較好的性能基礎(chǔ)

  唯品會網(wǎng)關(guān)是基于netty自研的API網(wǎng)關(guān)。

  

  唯品會網(wǎng)關(guān)參考各種開源網(wǎng)關(guān)的實(shí)現(xiàn),和業(yè)內(nèi)各大電商網(wǎng)站的成熟經(jīng)驗(yàn),網(wǎng)關(guān)邏輯上可以分為四層;

  第一層是接入層,負(fù)責(zé)接入技術(shù)的優(yōu)化。

  第二層是業(yè)務(wù)層,負(fù)責(zé)實(shí)現(xiàn)網(wǎng)關(guān)本身的一些業(yè)務(wù)實(shí)現(xiàn)。

  第三層是網(wǎng)關(guān)依賴的基于netty實(shí)現(xiàn)的各種公共組件

  最底層是netty負(fù)責(zé)NIO、內(nèi)存管理、提供各種基礎(chǔ)庫、異步化框架等。

  

  業(yè)務(wù)層前面跟大家分享過,主要包括路由、協(xié)議轉(zhuǎn)換、安全、認(rèn)證驗(yàn)簽、加密解密等,大家一看估計就可以看出,這些業(yè)務(wù)邏輯已經(jīng)劃分的比較獨(dú)立,可以按照模塊進(jìn)行劃分。實(shí)際上我們也是這樣做的。

  業(yè)務(wù)層設(shè)計需要考慮哪些方面呢?

  一方面,是流程的組織。

  另一方面,網(wǎng)關(guān)需要依賴外部服務(wù),需要考慮怎樣異步化的調(diào)用外部服務(wù)。

  最后,網(wǎng)關(guān)需要考慮高可用,高可用在程序設(shè)計方面主要是不停機(jī)發(fā)布。唯品會網(wǎng)關(guān)的所有業(yè)務(wù)配置,都可以通過管理界面動態(tài)管理、動態(tài)下發(fā)、動態(tài)生效,并且支持灰度。

  

  業(yè)務(wù)層實(shí)現(xiàn),最重要的一點(diǎn),是將邏輯和數(shù)據(jù)分離,我們的實(shí)現(xiàn)方式,是業(yè)務(wù)邏輯實(shí)現(xiàn)在模塊里,數(shù)據(jù)通過context傳遞,context通過模塊之間相互調(diào)用時,通過接口傳遞。在異步化調(diào)用其他服務(wù)時,context保存在Channel的AttributeMap里,在異步完成時,回調(diào),取出context。

  有了最基本的模塊設(shè)計,我們再來看唯品網(wǎng)關(guān)怎樣設(shè)計把這些流程串在一起。

  大家看一下上面的圖,在執(zhí)行業(yè)務(wù)邏輯時,有些業(yè)務(wù)邏輯需要串行,比如,路由校驗(yàn)、參數(shù)校驗(yàn)、IP黑白名單、WAF等,由于性能方面考慮,一般情況下,我們會先執(zhí)行黑白名單模塊,因?yàn)檫@塊是cpu消耗最小、能攔掉部分請求的模塊。

  后面再執(zhí)行路由、參數(shù)等的校驗(yàn)。這部分是內(nèi)存運(yùn)算,效率也比較高,也能攔掉一些非法請求,所以先執(zhí)行。

  然后進(jìn)入outh、風(fēng)控、設(shè)備指紋等的外部服務(wù)調(diào)用,這些調(diào)用將會并發(fā)的執(zhí)行。

  執(zhí)行后,將進(jìn)行結(jié)果合并校驗(yàn),如果在認(rèn)證驗(yàn)簽或風(fēng)控等校驗(yàn)未通過的情況下,將會直接返回,如果校驗(yàn)通過,再進(jìn)入后續(xù)的服務(wù)調(diào)用。

  服務(wù)調(diào)用過程,又進(jìn)行了多選一的流程,可能用二進(jìn)制協(xié)議也可能用HTTP協(xié)議等。最終進(jìn)行后處理。

  

  

  大家可能會想,這些模塊看上去可以使用actor模式進(jìn)行封裝,為何沒有使用開源異步框架呢?我們也對開源的異步框架進(jìn)行了詳細(xì)的調(diào)研。在將異步框架結(jié)合進(jìn)網(wǎng)關(guān)時發(fā)現(xiàn)對網(wǎng)關(guān)的性能產(chǎn)生了一些影響。

  目前較為流行的異步框架,主要有akka和quasar fibers。他們的實(shí)現(xiàn)形式不同,但原理基本差不多。

  為什么唯品網(wǎng)關(guān)沒有引入異步框架呢。

  一方面是引入異步框架后,網(wǎng)關(guān)的抖動增加。

  一方面是成熟度問題,quasar fibiers quasar fibers的模式,更加友好一些,可以以接近同步編程的模式實(shí)現(xiàn)異步編程。但最新的release是0.7.6,沒有大規(guī)模的驗(yàn)證過,我們也在實(shí)際使用踩了一些坑,例如,注解的問題、代碼織入沖突問題、長時間運(yùn)行突然響應(yīng)變慢問題,強(qiáng)烈建議大家如果生產(chǎn)使用,需要慎重再慎重。

  我們總結(jié)了一下異步化框架適用于,大量依賴其他服務(wù),經(jīng)常被block的情況。

  網(wǎng)關(guān)的瓶頸在cpu運(yùn)算,因?yàn)橛序?yàn)簽、加解密、協(xié)議轉(zhuǎn)換等cpu密集運(yùn)算,其他的調(diào)用已經(jīng)是全異步的,所以,引入異步框架的收益并不明顯。

  上面分享了業(yè)務(wù)層的設(shè)計,下面分享一下公共組件的設(shè)計。

  網(wǎng)關(guān)不論調(diào)用依賴的服務(wù)還是后端的服務(wù),都會遇到大量并發(fā)調(diào)用的情況。如果對連接不加以復(fù)用和控制,將造成大量的資源消耗和性能問題。因此,唯品網(wǎng)關(guān)自己設(shè)計優(yōu)化了連接池。

  下面就分享一下唯品網(wǎng)關(guān)在連接池方面的設(shè)計。

  

  

  連接復(fù)用主要是指,一個連接可以被多個使用者同時使用,且互相之間不受影響,可以并發(fā)的發(fā)送多個請求,而應(yīng)答是異步的,可復(fù)用的連接一般用于私有協(xié)議的連接,因?yàn)榭蓮?fù)用的連接,請求可以一直發(fā)送,應(yīng)答也不一定是按照請求順序進(jìn)行應(yīng)答,就帶來了一個問題,應(yīng)答怎樣才能和請求對應(yīng)上。私有協(xié)議就比較容易在協(xié)議包內(nèi),增加sequence id,所以能達(dá)到連接復(fù)用的要求。唯品會網(wǎng)關(guān)調(diào)用唯品會內(nèi)部的私有協(xié)議服務(wù)時,就采用的這種連接復(fù)用模式。

  連接復(fù)用還有一種實(shí)現(xiàn)模式,是spymemcache的模式,memcached本身不支持sequenceid,但同一個連接上的操作會保證順序性,所以,spymemcache通過把請求緩存在queue中的形式,順序匹配返回結(jié)果,達(dá)到連接復(fù)用。

  

  獨(dú)占的連接模式,主要是指,一個連接同一時間只能被一個使用者使用,在一個連接上,發(fā)送完一個請求后,必須等待應(yīng)答后,才能發(fā)送第二個請求。一般使用HTTP協(xié)議時,比較多使用這種獨(dú)占的模式。因?yàn)槿绻鸋TTP協(xié)議需要支持連接復(fù)用,需要在HTTP協(xié)議頭上增加sequence id,一般的服務(wù)端都不支持這種擴(kuò)展,所以,我們針對HTTP協(xié)議,使用的是獨(dú)占連接模式。

  

  連接池的異步化,在連接池使用的所有階段都應(yīng)該異步化。我們在設(shè)計網(wǎng)關(guān)的連接池時,考慮了以下幾個方面:

  獲取連接的異步化。從連接池獲取連接,一般情況被認(rèn)為是個沒有block的動作,實(shí)際上分解來看,獲取連接池,可能需要鎖連接池對象所在的隊(duì)列,操作連接池計數(shù)器時,可能會遇到鎖、超時等問題。后面我會跟大家分享我們怎樣去做的優(yōu)化。

  連接使用就是說實(shí)際用連接去調(diào)用其他服務(wù),這塊的異步化,大家基本都會考慮到。

  歸還連接的異步化。歸還連接時,也會操作連接池中的連接隊(duì)列,有時連接已經(jīng)異常還會執(zhí)行關(guān)閉連接等動作,所以也會產(chǎn)生鎖的問題。和獲取連接時類似,我們也把操作封裝為task,交由netty做cpu親緣性路由。

  

  3. 實(shí)踐經(jīng)驗(yàn)

  上面是給大家分享了我們在連接池設(shè)計中的幾個關(guān)鍵點(diǎn),接下來跟大家分享一下我們在實(shí)踐過程中實(shí)際進(jìn)行的優(yōu)化。

  

  jvm啟動后,會在/tmp下建立一個文件,是一個內(nèi)存映射文件,JVM用來導(dǎo)出狀態(tài)數(shù)據(jù)給其它進(jìn)程使用,比如jstat,jconsole等。當(dāng)?shù)竭_(dá)安全點(diǎn)時,JVM會把安全點(diǎn)的相關(guān)信息寫入到這個文件中去。安全點(diǎn)是說,jvm會在這個點(diǎn)上,把所有其他線程都停下來,自己安全的做一些事情,GC是一種安全點(diǎn),還有其他種類的安全點(diǎn)。而gc log和這種監(jiān)控數(shù)據(jù)的寫入,就是在安全點(diǎn)上進(jìn)行寫入。當(dāng)IO頻發(fā)且負(fù)載均重時,可能寫數(shù)據(jù)動作剛好趕上操作系統(tǒng)將磁盤緩存刷到磁盤的過程,此時寫性能數(shù)據(jù)文件的操作就會被block。最終表現(xiàn)為jvm暫停。解決方法,是將這些性能數(shù)據(jù)寫到內(nèi)存文件中,避免和其他操作搶占磁盤io。

  StringBuffer在寫日志等處理字符串拼接的場景下經(jīng)常用到,大多數(shù)情況下,我們會new一個StringBuffer,向里面追加字符串,在高并發(fā)場景,這個過程會產(chǎn)生大量的內(nèi)存重新分配并拷貝內(nèi)容的動作,造成cpu熱點(diǎn)。我們的優(yōu)化方法是,在threadlocal緩存使用過的stringbuffer,在下次使用時,直接復(fù)用。

  我們在初期實(shí)際使用網(wǎng)關(guān)時觀察到,網(wǎng)關(guān)的OLD區(qū)使用會緩慢上升,大概兩天會產(chǎn)生一次FGC,經(jīng)過仔細(xì)的分析,發(fā)現(xiàn),java NIO的server socket類由finalize最后進(jìn)行釋放。而GC過程是第一次GC先將沒有引用的對象放入finalize隊(duì)列,下次GC的時候,調(diào)用finalize,并將對象釋放。而在高并發(fā)的情況下,server socket的finalize并不保證被調(diào)用,所以存活時間可能超過了升級閾值,就會有對象不斷進(jìn)入old區(qū)。

  即使ref queue很快被執(zhí)行,也可能跨兩次ygc,比如創(chuàng)建后接著一次ygc1,然后用完后在下一次ygc2中添加到ref queue,ref queue沒有堆積的情況下,需要在ygc3中釋放這些對象。

  

  由于網(wǎng)關(guān)會并發(fā)接受大量的請求,所以寫日志的量非常大。我們實(shí)際壓測的時候發(fā)現(xiàn),寫日志的IO操作,會周期性的被block,從而產(chǎn)生抖動。經(jīng)過分析發(fā)現(xiàn),被block的時候,操作系統(tǒng)在刷磁盤緩存。linux默認(rèn)是臟數(shù)據(jù)超過10%,或5s刷一次緩存,而這時可能會有大量數(shù)據(jù)在緩存里等待寫入磁盤,操作系統(tǒng)再去刷盤的時候,就會消耗比較多的時間,而這些時間內(nèi),應(yīng)用無法將數(shù)據(jù)寫入磁盤緩存,發(fā)生block。有兩個參數(shù)可以調(diào)整,一個是臟數(shù)據(jù)占比,一個是臟數(shù)據(jù)兩個取較小值生效。我們通過調(diào)小臟數(shù)據(jù)比率,讓刷盤動作在數(shù)據(jù)量較小的時候就開始,減小了毛刺率。

轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/6845178.html

總結(jié)

以上是生活随笔為你收集整理的唯品会API网关设计与实践--转的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。