自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

歷經(jīng)4年618流量暴擊,京東京麥開放平臺(tái)的高可用架構(gòu)之路

開發(fā) 架構(gòu)
京麥開放平臺(tái)是京東系統(tǒng)與外部系統(tǒng)通訊的重要平臺(tái),技術(shù)架構(gòu)從早期單一 的 Nginx+Tomcat 部署,到現(xiàn)在的單一職責(zé),獨(dú)立部署,去中心化,以及自主研發(fā)了 JSF/HTTP 等多種協(xié)議下的 API 網(wǎng)關(guān)、TCP 消息推送、APNs 推送、降級(jí)、限流等技術(shù)。

 京麥?zhǔn)蔷〇|商家的多端開放式工作平臺(tái),是京東十萬商家唯一的店鋪運(yùn)營(yíng)管理平臺(tái)。

[[217989]]

它為京東商家提供移動(dòng)端和桌面端的操作業(yè)務(wù),京麥本身是一個(gè)開放的端體系架構(gòu),由京東官方和 ISV 為商家提供多樣的應(yīng)用服務(wù)。

京麥開放平臺(tái)是京東系統(tǒng)與外部系統(tǒng)通訊的重要平臺(tái),技術(shù)架構(gòu)從早期單一 的 Nginx+Tomcat 部署,到現(xiàn)在的單一職責(zé),獨(dú)立部署,去中心化,以及自主研發(fā)了 JSF/HTTP 等多種協(xié)議下的 API 網(wǎng)關(guān)、TCP 消息推送、APNs 推送、降級(jí)、限流等技術(shù)。

京麥開放平臺(tái)每天承載海量的 API 調(diào)用、消息推送,經(jīng)歷了 4 年京東 618 的流量洗禮。

本文將為您揭開京麥開放平臺(tái)高性能 API 網(wǎng)關(guān)、高可靠的消息服務(wù)的技術(shù)內(nèi)幕。

高性能 API 網(wǎng)關(guān)

京東內(nèi)部的數(shù)據(jù)分布在各個(gè)獨(dú)立的業(yè)務(wù)系統(tǒng)中,包括訂單中心、商品中心、商家中心等,各個(gè)獨(dú)立系統(tǒng)間通過 JSF(Jingdong Service Framework)進(jìn)行數(shù)據(jù)交換。

而 API 網(wǎng)關(guān)基于 OAuth2 協(xié)議提供,ISV 調(diào)用是通過 HTTP 的 JSON 協(xié)議。

如何將這些內(nèi)部數(shù)據(jù)安全可控地開放給外部 ISV 進(jìn)行服務(wù)調(diào)用,以及如何快速地進(jìn)行 API 接入實(shí)現(xiàn)數(shù)據(jù)報(bào)文轉(zhuǎn)化,在這個(gè)背景下 API 網(wǎng)關(guān)誕生。

API 網(wǎng)關(guān)在架構(gòu)設(shè)計(jì)上采用了多層接口,到達(dá)網(wǎng)關(guān)的請(qǐng)求首先由網(wǎng)關(guān)接入層攔截處理,在接入層進(jìn)行兩個(gè)主要環(huán)節(jié)的處理:

  • 網(wǎng)關(guān)防御校驗(yàn):這里包含降級(jí)和限流,以及多級(jí)緩存等,進(jìn)行數(shù)據(jù)正確性校驗(yàn)。
  • 網(wǎng)關(guān)接入分發(fā):網(wǎng)關(guān)分發(fā)會(huì)根據(jù)網(wǎng)關(guān)注冊(cè)中心的數(shù)據(jù)進(jìn)行協(xié)議解析,之后動(dòng)態(tài)構(gòu)建調(diào)用實(shí)例,完成服務(wù)泛化調(diào)用。

API 網(wǎng)關(guān)是為了滿足 618 高并發(fā)請(qǐng)求下的應(yīng)用場(chǎng)景,網(wǎng)關(guān)在服務(wù)調(diào)度、身份授權(quán)、報(bào)文轉(zhuǎn)換、負(fù)載與緩存、監(jiān)控與日志等關(guān)鍵點(diǎn)上進(jìn)行了針對(duì)性的架構(gòu)優(yōu)化。

API 元數(shù)據(jù)統(tǒng)一配置

API 的調(diào)用依賴對(duì)元數(shù)據(jù)的獲取,比如 API 的字段信息、流控信息、APP 密鑰、IP 白名單等、權(quán)限配置等。

在 618 場(chǎng)景下,元數(shù)據(jù)獲取性能是 API 網(wǎng)關(guān)的關(guān)鍵點(diǎn)?;?DB 元數(shù)據(jù)讀取是不可取的,即使對(duì) DB 做分庫(kù)分表處理也不行,因?yàn)?DB 就不是用來抗量的。

其次,要考慮到元數(shù)據(jù)的更新問題,定時(shí)的輪詢更新會(huì)產(chǎn)生極大延遲性,而且空輪詢也是對(duì)系統(tǒng)資源的極大浪費(fèi),采用 MQ 廣播通知不失為一種解決辦法。

但 MQ 僅僅解決數(shù)據(jù)同步的問題,數(shù)據(jù)緩存在集群里服務(wù)如何保證數(shù)據(jù)一致性和數(shù)據(jù)容災(zāi),又極大的增加了系統(tǒng)復(fù)雜度。

所以綜合考慮服務(wù)器性能和網(wǎng)絡(luò) IO 等因素,在 API 元數(shù)據(jù)讀取采用基于 ZooKeeper 的統(tǒng)一配置。

并自研實(shí)現(xiàn)多級(jí)緩存容災(zāi)架構(gòu)方案,從 ZooKeeper、內(nèi)存和本地文件等進(jìn)行多級(jí)緩存,同時(shí)支持?jǐn)?shù)據(jù)變更時(shí)即時(shí)同步,以及系統(tǒng)宕機(jī)網(wǎng)絡(luò)異常等情況下的數(shù)據(jù)自動(dòng)容災(zāi)等策略。

以讀為例,網(wǎng)關(guān)首先從內(nèi)存中讀取配置,如無數(shù)據(jù),從 ZooKeeper 讀取,讀取后同步到內(nèi)存,并異步保存本次快照。

如果 ZooKeeper 數(shù)據(jù)變更,通過監(jiān)聽 ZooKeeper 的 DataChangeWatcher 變更同步數(shù)據(jù)。如果 ZooKeeper 宕機(jī),重啟服務(wù)器,系統(tǒng)還可以通過本地快照恢復(fù)最近一次的元數(shù)據(jù)配置。

TCP 全雙工的長(zhǎng)鏈接會(huì)話通道

API HTTP 網(wǎng)關(guān)通過接口提供服務(wù)調(diào)用獲取請(qǐng)求數(shù)據(jù)的,而搭建客戶端與服務(wù)平臺(tái)的 TCP 網(wǎng)關(guān)的雙向通道,以保持客戶端與服務(wù)平臺(tái)的會(huì)話狀態(tài),則可以在 HTTP 網(wǎng)關(guān)基礎(chǔ)上提供更多、更靈活的技術(shù)實(shí)現(xiàn)和業(yè)務(wù)實(shí)現(xiàn)。

在業(yè)務(wù)服務(wù)調(diào)用上通過 HTTP 網(wǎng)關(guān),在平臺(tái)服務(wù)調(diào)用上則通過 TCP 網(wǎng)關(guān),實(shí)現(xiàn)平臺(tái)與業(yè)務(wù)解耦,并且平臺(tái)采用 TCP 通道還可以增加對(duì)平臺(tái)的控制力,在此背景下誕生了 TCP 網(wǎng)關(guān)。

TCP 網(wǎng)關(guān)采用長(zhǎng)連接通道,實(shí)現(xiàn)全雙工會(huì)話。TCP 網(wǎng)關(guān)采用 Netty 作為 TCP 容器,在 Channel Pipe 中加載自定義 Channel Handler,構(gòu)建 Container 容器。

并將每個(gè) TCP Connection 封裝到一個(gè) Session 會(huì)話中,保存在 Container 容器中,由 Container 容器構(gòu)建 Session 會(huì)話層提供邏輯層請(qǐng)求調(diào)用。

自研構(gòu)建 Session 會(huì)話層是因?yàn)?HTTP 屬于 OSI 的應(yīng)用層,而 TCP 屬于 OSI 的傳輸層,面向連接的編程極大的增加了程序復(fù)雜度。

所以將 Connection 封裝在每一個(gè) Session 會(huì)話里,再以微服務(wù)的方式提供服務(wù)調(diào)用,極大的精簡(jiǎn)了 TCP 編程。

斷線重連

客戶端與服務(wù)端通過 TCP 長(zhǎng)連接進(jìn)行通信,但在中國(guó)復(fù)雜的網(wǎng)絡(luò)環(huán)境下,移動(dòng)客戶端可能由于網(wǎng)絡(luò)抖動(dòng)、弱網(wǎng)絡(luò)情況下,遭遇非正常網(wǎng)絡(luò)閃斷,如何處理斷開后的斷線重連,保證客戶端與服務(wù)端的通訊穩(wěn)定呢?

客戶端每通過 TCP 與服務(wù)端進(jìn)行一次建連,都會(huì)在服務(wù)容器里創(chuàng)建一個(gè) Session 會(huì)話,該會(huì)話保存 Connection 的句柄,對(duì)應(yīng) Netty 的一個(gè) Channel 通道。

建連成功后,通過定時(shí)的心跳保持 Channel 屬于 Active 活躍。但客戶端進(jìn)入弱網(wǎng)絡(luò)環(huán)境下,客戶端可能已經(jīng)掉線,但并未向服務(wù)端主動(dòng)發(fā)送關(guān)閉 Channel 請(qǐng)求,而服務(wù)端仍認(rèn)為該 Channel 仍存活。

直到在由服務(wù)端的會(huì)話存活檢測(cè)機(jī)制檢測(cè)到 Channel 已經(jīng) InActive,才會(huì)由服務(wù)端銷毀該 Channel。

服務(wù)端的會(huì)話存活檢測(cè)是 5 分鐘一次,所以存在客戶端掉線后,在 5 分鐘內(nèi)又重新建連,而這時(shí)服務(wù)端的建連邏輯,不是重新創(chuàng)建一個(gè) Session,而是去尋找上一次的 Session,并更新標(biāo)識(shí)存活。

具體的實(shí)現(xiàn)是在每次建連的 Channel 里存入 SessionId,當(dāng)網(wǎng)絡(luò)閃斷后,判斷 Channel 是否存在 Session。

之所以實(shí)現(xiàn)是得益于 Netty 的 ChannelHandlerContext,可以存儲(chǔ)一個(gè)自定義屬性到 Channel 的上下文中。

當(dāng)然,TCP 網(wǎng)關(guān)一定是集群,所以,斷線重連也是極有可能請(qǐng)求到不同的服務(wù)器上,而這種情況按照新 Connection 創(chuàng)建的 Session 處理,只有出現(xiàn)重連到同一服務(wù)器時(shí),才需要考慮上述的處理邏輯。

Protobuf 數(shù)據(jù)交換格式

HTTP 網(wǎng)關(guān)基于 JSON 進(jìn)行數(shù)據(jù)傳輸,JSON 是 key-value 的鍵值對(duì)通信協(xié)議,所以生成報(bào)文會(huì)很大,影響傳輸性能。

考慮到報(bào)文傳輸大小,在 TCP 網(wǎng)關(guān)中則通過 Protobuf 定義通信協(xié)議,提升數(shù)據(jù)傳輸效率。

Protobuf 支持 Java、Objective-C 和 C++ 等語言,現(xiàn)支持了京麥平臺(tái) PC 桌面客戶端、移動(dòng) iOS 和 Android 客戶端基于 Protobuf 通過 TCP 與服務(wù)端進(jìn)行通信。

多維度流量控制

由于各個(gè) API 的服務(wù)能力不一致,為了保證各個(gè) API 能夠穩(wěn)定提供服務(wù),不會(huì)被暴漲的請(qǐng)求流量擊垮,那么多維度流量控制是 API 網(wǎng)關(guān)的一個(gè)重要環(huán)節(jié)。

目前 API 網(wǎng)關(guān)是采用令牌桶的方法,實(shí)現(xiàn)方式是 Guava RateLimter,簡(jiǎn)單有效,再結(jié)合統(tǒng)一配置中心,可以動(dòng)態(tài)調(diào)整限流閾值。不用重啟服務(wù)器即可實(shí)現(xiàn)快速限流策略調(diào)整。

在 API 網(wǎng)關(guān)里面還有一個(gè)設(shè)置,就是并發(fā)度,這個(gè)是方法粒度的,對(duì)每一個(gè)調(diào)用接口都有一個(gè)并發(fā)度數(shù)值設(shè)置。

而且是動(dòng)態(tài)設(shè)置,也是通過 ZooKeeper 下發(fā)到每一個(gè)服務(wù)節(jié)點(diǎn)上。并發(fā)度的具體實(shí)現(xiàn)是通過 JDK 的 Semaphore。

高可靠的消息服務(wù)

API 網(wǎng)關(guān)提供 ISV 獲取數(shù)據(jù),但實(shí)時(shí)數(shù)據(jù)的獲取,如果通過輪詢網(wǎng)關(guān),大量空轉(zhuǎn)不僅非常的低效且浪費(fèi)服務(wù)器資源。

基于此,開放平臺(tái)推出了消息推送技術(shù),提供一個(gè)實(shí)時(shí)的、可靠的、異步的雙向數(shù)據(jù)交換通道,提升 API 網(wǎng)關(guān)性能。

AnyCall 和推送系統(tǒng)

AnyCall

負(fù)責(zé)接收各業(yè)務(wù)中心的訂單、商品、商家等消息,進(jìn)行統(tǒng)一的消息過濾、轉(zhuǎn)換、存儲(chǔ),及監(jiān)控和統(tǒng)計(jì)等。

各個(gè)過程中的消息狀態(tài),通過消息采集器存儲(chǔ)到 ElasticSearch 和 HBase 進(jìn)行存儲(chǔ)。

推送系統(tǒng)

基于 Netty 作為網(wǎng)絡(luò)層框架,構(gòu)建海量推送模型,使用靜默長(zhǎng)連接通道,實(shí)現(xiàn)從消息接收、推送、確認(rèn),整個(gè)過程的完全異步化處理。

解耦消息接入層和消息推送層,消息接入層只負(fù)責(zé)Request-Response 和 Notice-Repley。

而消息解析、適配、推送等邏輯處理都全部由消息推送層處理,而消息接入層和消息推送層之間則有消息隊(duì)列異步進(jìn)行通信。

半推半拉還是半推半查?

半推半拉

半推半拉模式中的“推”指的是由服務(wù)器推送 消息通知 到客戶端,“拉”指的是客戶端收到通知后再?gòu)姆?wù)器拉取 消息實(shí)體 到客戶端本地存儲(chǔ)。

其中消息通知發(fā)送的僅是一個(gè)命令關(guān)鍵字,這樣的設(shè)計(jì)是考慮消息推送可能存在丟失,通過拉取的方式,確保即使消息通知未送達(dá),在下次消息通知觸發(fā)下的拉取也能把上一次消息拉取到本地。

采用的半推半拉,每次僅推送通知,推送量小,實(shí)時(shí)性高。

半推半查

后期京麥消息推送模式由“拉”改“查”,“查”指的是消息通知依舊推送,但客戶端收到消息通知后 不再拉取消息實(shí)體,僅更新消息未讀數(shù)和進(jìn)行消息提醒等操作。

而消息內(nèi)容則是由服務(wù)端進(jìn)行云端存儲(chǔ),采用輕客戶端,重服務(wù)端的架構(gòu)方案,只有用戶點(diǎn)擊查詢消息時(shí),才會(huì)按需進(jìn)行數(shù)據(jù)查詢,在客戶端展示,但不存儲(chǔ)。

這種推送模式的改動(dòng)主要考慮了客戶端拉取消息內(nèi)容到本地存儲(chǔ),占用資源,重裝之后客戶端會(huì)丟失消息,以及多端存儲(chǔ)的數(shù)據(jù)存在不一致等問題。

消息云端存儲(chǔ)基于 ElasticSearch 進(jìn)行消息存儲(chǔ),并根據(jù)業(yè)務(wù)類型區(qū)分索引,通過 Routing 優(yōu)化查詢性能,支持多維度進(jìn)行查詢,性能穩(wěn)定。

消息確認(rèn)

評(píng)估消息系統(tǒng)的一個(gè)核心指標(biāo)是消息送達(dá)率。為保證每一條消息準(zhǔn)確送達(dá),為每條消息都會(huì)開啟一個(gè)事務(wù),從推送開始,到確認(rèn)結(jié)束,如果超時(shí)未確認(rèn)就會(huì)重發(fā)這條消息,這就是消息確認(rèn)。

由于互聯(lián)網(wǎng)環(huán)境復(fù)雜,消息超時(shí)時(shí)間不能設(shè)置太短,尤其在移動(dòng)弱網(wǎng)絡(luò)環(huán)境下。在本系統(tǒng)中,超時(shí)設(shè)置為 10 秒。

我們通過實(shí)現(xiàn) Future 自定義 NotifyFuture,為每個(gè)下行通知分配一個(gè) seq,并定義 NotifyFuture 的 timeout。

即每個(gè)下行通知分配一個(gè) seq 存儲(chǔ)緩存中,等待客戶端回應(yīng)這個(gè)應(yīng)答,如果應(yīng)答, 則從緩存移出這個(gè) seq,否則等待超時(shí),自動(dòng)從緩存中被移出。

APNs 消息推送

iOS 在系統(tǒng)層面與蘋果 APNs(Apple Push Notification Service)服務(wù)器建立連接,應(yīng)用通過 Socket 向 APNs Server 推送消息,然后再由 APNs 進(jìn)行推送。

但是基于 Socket 的 APNs 協(xié)議是一種反人類的設(shè)計(jì),在推送消息時(shí)存在很多問題。

鑒于此,對(duì) APNs 推送服務(wù)進(jìn)行重構(gòu),基于 Netty 構(gòu)建了 HTTP2 協(xié)議的推送服務(wù),支持同步和異步的推送方式。

解決 Channel 異常及 InActive 時(shí)重連等問題,保證 HTTP2 推送管道的問題,同時(shí)通過 IdleStateHandler 保持 HTTP2 長(zhǎng)連接的心跳 。

總結(jié)和感悟

***,總結(jié)歷次的大促,京麥開放平臺(tái)在進(jìn)行服務(wù)化架構(gòu)的演進(jìn)過程中,所面臨的技術(shù)難點(diǎn),最重要的還是服務(wù)治理,即調(diào)用關(guān)系的梳理。

因?yàn)槲覀円蛟斓牟皇且粋€(gè)系統(tǒng),也不是一堆系統(tǒng),而是一個(gè)平臺(tái)生態(tài),能夠持續(xù)地提高系統(tǒng)的運(yùn)營(yíng)能力。

這里以“精打細(xì)算,大道至簡(jiǎn)”這句話結(jié)束此次京麥開放平臺(tái)的分享。

[[217991]]

張松然 ,2013 年加入京東,一直從事京東商家京麥開放平臺(tái)的架構(gòu)設(shè)計(jì)和開發(fā)工作,熟悉大規(guī)模分布式系統(tǒng)架構(gòu)。在 Web 開發(fā)、架構(gòu)優(yōu)化上有較豐富的實(shí)戰(zhàn)經(jīng)歷。有多年 NIO 領(lǐng)域的設(shè)計(jì)、開發(fā)經(jīng)驗(yàn),對(duì) HTTP、TCP 長(zhǎng)連接有深入研究與領(lǐng)悟。目前主要致力于多端開放平臺(tái)技術(shù)架構(gòu)的優(yōu)化與實(shí)現(xiàn)。

 

責(zé)任編輯:武曉燕 來源: linkedkeeper
相關(guān)推薦

2018-06-21 09:07:58

京東實(shí)踐京麥平臺(tái)

2017-12-28 09:41:29

微服務(wù)網(wǎng)關(guān)容錯(cuò)

2023-02-27 08:37:52

2019-10-11 10:52:42

Web架構(gòu)MongoDB

2010-10-28 15:37:36

高可用架構(gòu)

2015-05-04 14:17:16

數(shù)據(jù)庫(kù)架構(gòu)高可用

2017-10-23 09:10:52

2011-12-08 16:39:58

京東商城

2022-05-09 11:29:42

架構(gòu)數(shù)據(jù)

2024-03-29 13:25:12

互動(dòng)玩法直播

2020-04-22 14:25:48

云開發(fā)高可用架構(gòu)

2017-10-09 09:12:35

攜程運(yùn)維架構(gòu)

2022-08-07 21:59:57

高可用架構(gòu)

2021-08-20 11:05:14

高并發(fā)架構(gòu)分布式

2022-07-08 14:17:18

Kubernetes集群高可用Linux

2017-11-08 09:32:05

2015-07-17 07:03:09

618應(yīng)戰(zhàn)技術(shù)推動(dòng)業(yè)務(wù)

2018-09-14 17:22:43

大數(shù)據(jù)平臺(tái)京東日志

2018-08-27 10:59:07

京東數(shù)據(jù)庫(kù)智能運(yùn)維

2018-01-10 08:53:23

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)