億級流量網(wǎng)站架構(gòu)核心技術(shù)【筆記】(一)

一、交易型系統(tǒng)設計的一些原則

1.在設計系統(tǒng)時,應該多思考墨菲定律:

* 任何事情都沒有表面看起來那么簡單

* 所有的事都會比你預計的時間長

* 可能出錯的事總會出錯

* 如果你擔心某種情況發(fā)生,那么它就更有可能發(fā)生

2.系統(tǒng)劃分時,要思考康威定律:

* 系統(tǒng)架構(gòu)是公司組織架構(gòu)的反映

* 應該按照業(yè)務閉環(huán)進行系統(tǒng)拆分/組織架構(gòu)劃分,實現(xiàn)閉環(huán)/高內(nèi)聚/低耦合,減少溝通成本

* 如果溝通出現(xiàn)問題,那么就應該考慮進行系統(tǒng)和組織架構(gòu)的調(diào)整

* 在合適時機進行系統(tǒng)拆分,不要一開始就把系統(tǒng)/服務拆得非常細,雖然閉環(huán),但是每個人維護的系統(tǒng)多,維護成本高

3.在有限資源的情況下,一定是先解決當下最核心的問題,預測并發(fā)現(xiàn)未來可能出現(xiàn)的問題,一步步解決最痛點的問題,即滿足需求的系統(tǒng)是不斷迭代優(yōu)化出來的

A.高并發(fā)原則

1.無狀態(tài):比較容易進行水平擴展,應用無狀態(tài),配置文件有狀態(tài)

2.拆分:在系統(tǒng)設計初期,是做一個大而全的系統(tǒng)還是按功能模塊拆分系統(tǒng),這個需要根據(jù)環(huán)境進行權(quán)衡

* 系統(tǒng)維度:按照系統(tǒng)功能/業(yè)務拆分

* 功能維度:對一個系統(tǒng)進行功能再拆分

* 讀寫維度:根據(jù)讀寫比例特征進行拆分

* AOP維度:根據(jù)訪問特征,按照AOP進行拆分

* 模塊維度:按照基礎(chǔ)或者代碼維護特征進行拆分

3.服務化

* 判斷是不是只需要簡單的單點遠程服務調(diào)用,單機不行集群是不是就可以解決?在客戶端注冊多臺機器并使用Nginx進行負載均衡是不是就可以解決?隨著調(diào)用方越來越多,應該考慮使用服務自動注冊和發(fā)現(xiàn)(Dubbo使用ZooKeeper)

* 考慮服務的分組/隔離

* 后期隨著調(diào)用量的增加還要考慮服務的限流、黑白名單等

* 進程內(nèi)服務->單機遠程服務->集群手動注冊服務->自動注冊和發(fā)現(xiàn)服務->服務的分組/隔離/路由->服務治理如限流/黑白名單

4.消息隊列

* 用來解耦一些不需要同步調(diào)用的服務或者訂閱一些自己系統(tǒng)關(guān)心的變化

* 可以實現(xiàn)服務解耦(一對多消費)、異步處理、流量削峰/緩沖等

* 要注意處理生產(chǎn)消息失敗,以及消息重復接收時的場景

* 大流量緩沖(電商大促等),犧牲強一致性,而保證最終一致性,需要考慮并發(fā)處理和重復處理的問題

* 在使用了消息異步機制的場景下,可能存在消息的丟失,需要考慮進行數(shù)據(jù)校對和修正來保證數(shù)據(jù)的一致性和完整性

5.數(shù)據(jù)異構(gòu)

* 對訂單表進行異構(gòu),異構(gòu)一套用戶訂單表,按照用戶ID進行分庫分表,還需要考慮對歷史訂單數(shù)據(jù)進行歸檔處理

* 數(shù)據(jù)閉環(huán)如商品詳情頁,通過如MQ機制接收數(shù)據(jù)變更,然后原子化存儲到合適的存儲引擎,如Redis或持久化KV存儲;使用數(shù)據(jù)聚合,前端就可以一個調(diào)用拿到所有數(shù)據(jù),一般存儲在KV存儲中;前端通過一次或少量幾次調(diào)用拿到所需要的數(shù)據(jù);

* 如果一次需要多個數(shù)據(jù),可以考慮使用Hash Tag機制將相關(guān)的數(shù)據(jù)聚合到一個實例

6.緩存銀彈

* 瀏覽器緩存:設置請求過期時間,如對響應頭Expires、Cache-control進行控制,適用于對實時性不太敏感的數(shù)據(jù)

* APP客戶端緩存:一般會在大促之前把APP需要訪問的一些素材提前下發(fā)到客戶端進行緩存

* CDN緩存:將頁面、活動頁、圖片推送到離用戶最近的CDN節(jié)點,要考慮URL的設計

* 接入層緩存:考慮使用如Nginx搭建一層接入層,URL重寫、一致性哈希、proxy_cache、proxy_cache_lock、shared_dict

* 應用層緩存:Redis等

* 分布式緩存:Redis集群

7.并發(fā)化

B.高可用原則

1.降級

* 開關(guān)集中化管理:通過推送機制把開關(guān)推送到各個應用

* 可降級的多級讀服務:比如服務調(diào)用降級為只讀本地緩存、只讀分布式緩存、只讀默認降級數(shù)據(jù)

* 開關(guān)前置化:如架構(gòu)是Nginx->Tomcat,可以將開關(guān)前置到Nginx接入層

* 業(yè)務降級:把一些同步調(diào)用改成異步調(diào)用,優(yōu)先處理高優(yōu)先級數(shù)據(jù)或特殊特征的數(shù)據(jù)

2.限流

* 惡意請求流量只訪問到cache

* 對于穿透到后端應用的流量可以考慮使用Nginx的limit模塊處理

* 對于惡意IP可以使用nginx deny進行屏蔽

3.切流量

* DNS:切換機房入口

* HttpDNS:主要APP場景下,在客戶端分配好流量入口,繞過運營商LocalDNS并實現(xiàn)更精準流量調(diào)度

* LVS/HaProxy:切換故障的Nginx接入層

4.可回滾:版本化

C.業(yè)務設計原則

1.防重設計:考慮防重key、防重表

2.冪等設計:在重復消息消費時進行冪等處理

3.流程可定義

4.狀態(tài)與狀態(tài)機:正向狀態(tài)(付款、發(fā)貨)和逆向狀態(tài)(取消、退款)應該根據(jù)系統(tǒng)和特征來決定要不要分離存儲,狀態(tài)設計時應有狀態(tài)軌跡,方便跟蹤當前訂單的軌跡并記錄相關(guān)日志,還有訂單狀態(tài)的變遷以及并發(fā)狀態(tài)修改問題

5.后臺系統(tǒng)操作可反饋:需要考慮效果的可預覽,可反饋

6.后臺系統(tǒng)審批化:對于有些重要的后臺功能需要設計審批流,并記錄日志,從而保證操作可追溯、可審計

7.文檔和注釋:在一個系統(tǒng)發(fā)展的一開始就應該有文檔庫(設計架構(gòu)、設計思想、數(shù)據(jù)字典/業(yè)務流程、現(xiàn)有問題),業(yè)務代碼和特殊需求都要有注釋

8.備份:代碼備份和人員備份

二、負載均衡與反向代理

1.外網(wǎng)DNS應該用來實現(xiàn)用GSLB(全局負載均衡)進行流量調(diào)度,如將用戶分配到離他最近的服務器上以提升體驗

2.對于內(nèi)網(wǎng)DNS,可以實現(xiàn)簡單的輪詢負載均衡,但會有一定的緩存時間并且沒有失敗重試機制,我們可以考慮選擇如HaProxy和Nginx

3.Nginx一用于七層負載,其吞吐量是有一定限制的,為了提升整體吞吐,會在DNS和Nginx之間引入接入層,如使用LVS、F5可以做四層負載均衡,即首先DNS解析到LVS/F5、然后LVS/F5轉(zhuǎn)發(fā)給Nginx,再由Nginx轉(zhuǎn)發(fā)給后端RealServer

4.Nginx目前提供了HTTP(ngx_http_upstreamm_module)七層負載均衡,1.9.0版本支持TCP(ngx_stream_upstream_module)四層負載均衡

5.二層負載均衡是通過改寫報文的目標MAC地址為上游服務器MAC地址,源IP地址和目標IP地址是沒有變的,負載均衡服務器和真實服務器共享同一個VIP,如LVS DR工作模式

6.四層負載均衡是根據(jù)端口將報文轉(zhuǎn)發(fā)到上游服務器(不同的IP地址+端口),如LVS NAT模式、HaProxy

7.七層負載均衡是根據(jù)端口號和應用層協(xié)議如HTTP協(xié)議的主機名、URL,轉(zhuǎn)發(fā)報文到上游服務器(不同的IP地址+端口),如HaProxy、Nginx

A.upstream配置

1.在http指令下配置upstream即可

2.主要配置:

* IP地址和端口

* 權(quán)重:默認是1,越高分配給這臺服務器的請求就越多

B.負載均衡算法

1.用來解決用戶請求到來時如何選擇upstream server進行處理,默認采用的是round-robin(輪詢),同時支持ip_hash

2.hash key [consistent],對某個key進行哈?;蛘呤褂靡恢滦怨K惴ㄟM行負載均衡,建議考慮使用一致性哈希算法

3.least_conn,將請求均衡到最少活躍連接的上游服務器

C.失敗重試

1.主要兩部分配置:

* upstream server:server xxxx:80 max_fails=2 ?fail_timeout=10s weight=1;...

* proxy_pass:配置proxy_next_upstream相關(guān)配置,proxy_next_upstream、proxy_next_upstream_timeout、proxy_next_upstream_tries

D.健康檢查

1.nginx對上游服務器的健康檢查默認采用的是惰性策略

2.TCP心跳檢查:check interval=3000 rise=1 fall=3 timeout=2000 type=tcp;

3.HTTP心跳檢查:

* check_http_send "HEAD /status HTTP/1.0\r\n\r\n";

* check_http_expect_alive http_2xx http_3xx;

3.使用的是opensresty模塊,安裝nginx之前需要先打nginx_upstream_check_module補丁

E.其他配置

1.備份上游服務器,backup

2.不可用上游服務器,down

F.長連接

1.可以通過keepalive指令配置長連接數(shù)量

G.HTTP反向代理

1.反向代理除了實現(xiàn)負載均衡之外,還提供如緩存來減少上游服務器的壓力

2.還可以開啟gzip壓縮,減少網(wǎng)絡傳輸?shù)臄?shù)據(jù)包大小

H.HTTP動態(tài)負載均衡

1.Consul是一款開源的分布式服務注冊與發(fā)瑞系統(tǒng),通過HTTP API可以使得服務注冊、發(fā)現(xiàn)實現(xiàn)起來非常簡單

2.Consul+Consul-template

2.Consul+OpenResty

I.Nginx四層負載均衡

1.靜態(tài)負載均衡

* 啟用ngx_stream_core_module,安裝Nginx時,添加--with-stream

* 配置在stream指令下

* 可配置數(shù)據(jù)庫連接

2.動態(tài)負載均衡

* nginx-upsync-module,提升了HTTP七層動態(tài)負載均衡,動態(tài)更新上游服務器不需要reload nginx

三、隔離術(shù)

1.隔離是指將系統(tǒng)或資源分割開,系統(tǒng)隔離是為了在系統(tǒng)發(fā)生故障時,能限定傳播范圍和影響范圍,即發(fā)生故障后不會出現(xiàn)滾雪球效應,從而保證只有出問題的服務不可用,其他服務還是可用的

2.資源隔離通過隔離來減少資源競爭,保障服務間的相互不影響和可用性

A.線程隔離

1.主要是指線程池隔離,在實際使用時,我們會把請求分類,然后交給不同的線程池處理

B.進程隔離

1.在公司發(fā)展初期,一般是先從零到一,不會一上來就進行系統(tǒng)拆分,這樣就會開發(fā)出一些大而全的系統(tǒng),系統(tǒng)中的一個模塊/功能出現(xiàn)問題,整個系統(tǒng)就不可用了

2.通過將系統(tǒng)拆分為多個子系統(tǒng)來實現(xiàn)物理隔離,通過進程隔離使得某一個子系統(tǒng)出現(xiàn)問題時不會影響到其他子系統(tǒng)

C.集群隔離

1.隨著系統(tǒng)的發(fā)展,單實例服務無法滿足需求,此時需要服務化技術(shù),通過部署多個服務形成服務集群,來提升系統(tǒng)容量

D.機房隔離

1.隨著對系統(tǒng)可用性的要求,會進行多機房部署,每個機房的服務都有自己的服務分組,本機房的服務應該只調(diào)用本機房服務,不進行跨機房調(diào)用

2.當一個機房服務發(fā)生問題時,可以通過DNS/負載均衡將請求全部切到另一個機房,或者考慮服務能自動重試其他機房的服務

3.一種辦法是根據(jù)IP(不同機房IP段不一樣)自動分組,還有一種較靈活的辦是通過在分組名中加上機房名

E.讀寫隔離

1.通過主從模式將讀和寫集群分離

F.動靜隔離

1.將動態(tài)內(nèi)容和靜態(tài)資源分離,將靜態(tài)資源放在CDN上

G.爬蟲隔離

1.爬蟲和正常流量的比例能達到5:1,甚至更高,一種解決辦法是通過限流解決,另一種解決辦法是在負載均衡層面將爬蟲路由到單獨集群,Nginx即可配置

2.使用OpenResty,不僅對爬蟲user-agent過濾,還會過濾一些惡意IP ,可以考慮IP+Cookie的方式

H.資源隔離

1.最常見的資源,如磁盤、CPU、網(wǎng)絡,這些寶貴的資源,都會存在競爭問題

I.使用Hystrix實現(xiàn)隔離

1.Hystrix是Netflix開源的一款針對分布式系統(tǒng)的延遲和容錯庫,目的是用來隔離分布式服務故障

2.提供線程和信號量隔離,以減少不同服務之間資源競爭帶來的相互影響:提供優(yōu)雅降級機制;提供熔斷機制使得服務可以快速失敗,而不是一直阻塞等待服務響應,并能從中快速恢復

3.解決的問題:

* 限制調(diào)用分布式服務的資源使用,某一個調(diào)用的服務出現(xiàn)問題不會影響其他服務調(diào)用,通過線程池隔離和信號量隔離實現(xiàn)

* 提供了優(yōu)雅降級機制:超時降級、資源不足時(線程或信號量)降級,降級后可以配合降級接口返回拖底數(shù)據(jù)

* 提供了熔斷器實現(xiàn),當失敗率達到閾值自動觸發(fā)降級(如因網(wǎng)絡故障/超時造成的失敗率高),熔斷器觸發(fā)的快速失敗會進行快速恢復

* 提供了請求緩存、請求合并實現(xiàn)

J.基于Servlet3實現(xiàn)請求隔離

四、限流詳解

1.限流的目的是通過對并發(fā)訪問/請求進行限速或者一個時間窗口內(nèi)的請求進行限速來保護系統(tǒng),一旦達到限制速率則可以拒絕服務(定向到錯誤頁或告知資源沒有了)、排隊或等待(比如秒殺、評論、下單)、降級(返回兜底數(shù)據(jù)或默認數(shù)據(jù))

2.在壓測時我們能找出每個系統(tǒng)的處理峰值,然后通過設定峰值閾值,來防止系統(tǒng)過載時,通過拒絕處理過載的請求來保障系統(tǒng)可用,另外,也應根據(jù)系統(tǒng)的吞吐量、響應時間、可用率來動態(tài)調(diào)整限流閾值

3.常見的限流有

限制總并發(fā)數(shù)(比如數(shù)據(jù)庫連接池、線程池)

限制瞬時并發(fā)數(shù)(如Nginx的limit_conn模塊)

限制時間窗口內(nèi)的平均速率(如Guava的RateLimiter、Nginx的limit_req模塊,用來限制每秒的平均速率)

限制遠程接口調(diào)用速率

限制MQ的消費速率

還可以根據(jù)網(wǎng)絡連接數(shù)、網(wǎng)絡流量、CPU或內(nèi)存負載來限流

4.緩存目的是提升系統(tǒng)訪問速度和增大系統(tǒng)處理能力,可謂是抗高并發(fā)的銀彈。降級是當服務出問題或者影響到核心流程的性能,需要暫時屏蔽掉,待高峰過去或者問題解決后再打開的場景

A.限流算法

1.令牌桶算法:是一個存放固定容量令牌的桶,按照固定速率往桶里添加令牌

2.漏桶算法:漏桶作為計量工具(The Leaky Bucket Algorithm as a Meter)時,可以用于流量整形(Traffic Shaping)和流量控制(Traffic Policing)

B.應用級限流

1.限流總資源數(shù):可以使用池化技術(shù),如連接池、線程池

2.限流總并發(fā)/連接/請求數(shù):Tomcat配置、MySQL(max_connections)、Redis(tcp-backlog)

3.限流某個接口的總并發(fā)/請求數(shù):Java的AtomicLong或Semaphore

C.分布式限流

1.Redis+Lua

2.Nginx+Lua

D.接入層限流

1.接入層通常指請求流量的入口,該層的主要目的有:負載均衡、非法請求過濾、請求聚合、緩存、降級、限流、A/B測試、服務質(zhì)量監(jiān)控等

2.ngx_http_limit_conn_module,limit_conn是對某個key對應的總的網(wǎng)絡連接數(shù)進行限流,可以按照IP來限制IP維度的總連接數(shù),或者按照服務域名來限制某個域名的總連接數(shù),只有被Nginx處理的且已經(jīng)讀取了整個請求頭的請求連接才會被計數(shù)器統(tǒng)計

3.ngx_http_limit_req_module,limit_req是漏桶算法實現(xiàn),用于對指定key對應的請求進行限流,比如按照IP維度限制請求速率

4.lua-resty-limit-traffic,OpenResty了Lua限流模塊,可以按照更復雜的業(yè)務邏輯進行動態(tài)限流處理,提供了limit.conn和limit.req實現(xiàn)

E.節(jié)流

1.我們想在特定埋單窗口內(nèi)對重復的相同事件最多只處理一次,或者想限制多個連續(xù)相同事件最小執(zhí)行時間間隔,可使用節(jié)流(Throttle)實現(xiàn),其防止多個相同事件連續(xù)重復執(zhí)行,主要有:throttleFirst、throttleLast、throttleWithTimeout

2.throttleFirst/throttleLast

* 是指在一個時間窗口內(nèi),如果有重復的多個相同事件要處理,則只處理第一個或最后一個,其相當于一個事件頻率控制器,把一段時間內(nèi)重復的多個相同事件變?yōu)橐粋€,減少事件處理頻頻率,從而減少無用處理

* 前端開發(fā)可以使用jquery-throttle-debounce-plugin實現(xiàn)

* Android開發(fā)可以使用RxAndroid實現(xiàn)

3.throttleWithTimeout

* 也叫作debounce(去抖),限制兩個連續(xù)事件的先后執(zhí)行時間不得小于某個時間窗口

* 當兩個連續(xù)事件的時間間隔小于最小間隔時間窗口,就會丟棄上一個事件,而如果最后一個事件等待了最小間隔時間窗口后還沒有新的事件到來,那么會處理最后一個事件

* 可用于搜索關(guān)鍵詞自動補全等功能

五、降級特技

1.當訪問量劇增、服務出現(xiàn)問題(如響應時間長或不響應)或非核心服務影響到核心流程的性能時,仍然需要保證服務還是可用的,即使是有損服務。系統(tǒng)可以根據(jù)一些關(guān)鍵數(shù)據(jù)進行自動降級,也可以配置開關(guān)實現(xiàn)人工降級

2.降級的最終目的是保證核心服務可用,即使是有損的。而且有些服務是無法降級的(如購物車、結(jié)算)。降級也需要根據(jù)系統(tǒng)的吞吐量、響應時間、可用率等條件進行手工降級或自動降級

A.降級預案

1.參考日志級別設置預案

* 一般:有些服務偶爾因為網(wǎng)絡抖動或者服務正在上線而超時,可以自動降級

* 警告:有些服務在一段時間內(nèi)成功率有波動,可以自動降級或人工降級并發(fā)送警告

* 錯誤:可用率低于90%,或數(shù)據(jù)庫連接池用完了,或訪問量突然猛增到系統(tǒng)能承受的最大閾值

* 嚴重錯誤:因為特殊原因數(shù)據(jù)出現(xiàn)錯誤,需要緊急人工降級

2.降級按照是否自動化可分為:自動開關(guān)降級和人工開關(guān)降級

3.降級按照功能可分為:讀服務降級和寫服務降級

4.降級按照處于系統(tǒng)層次可分為:多級降級

5.降級的功能點主要從服務器端鏈路考慮,即根據(jù)用戶訪問的服務調(diào)用鏈路來梳理哪里需要降級

* 頁面降級

* 頁面片段降級

* 頁面異步請求降級

* 服務功能降級

* 讀降級:如多級緩存模式,如果后端服務有問題,則可以降級為只讀緩存,適用于對讀一致性要求不高的場景

* 寫降級:秒殺搶購,可以只進行Cache的更新,然后異步扣減庫存到DB,保證最終一致性即可,此時可以將DB降級為Cache

* 爬蟲降級:大促活動時,可以將爬蟲流量導向靜態(tài)頁或者返回空數(shù)據(jù),從而保護后端稀缺資源

* 風控降級:搶購/秒殺等業(yè)務,完全可以識別機器人、用戶畫像或者根據(jù)用戶風控級別進行降級處理,直接拒絕高風險用戶

B.自動開關(guān)降級

1.超時降級

* 當訪問的數(shù)據(jù)庫/HTTP服務/遠程調(diào)用響應慢或者長時間響應慢,且該服務不是核心服務的話,可以在超時后自動降級

* 如果是調(diào)用別人的遠程服務,則可以和對方定義一個服務響應最大時間,如果超時了,則自動降級

* 在實際場景中一定要配置好超時時間和超時重試次數(shù)及機制

2.統(tǒng)計失敗次數(shù)降級:當失敗調(diào)用次數(shù)達到一定閾值自動降級(熔斷器),然后通過異步線程去探測服務是否恢復了

3.故障降級:要調(diào)用的遠程服務掛掉了,則可以直接降級,降級后的處理方案:默認值(比如庫存掛了返回默認) 、兜底數(shù)據(jù)(比如廣告掛了返回提前準備好的靜態(tài)頁面)、緩存

4.限流降級:當達到限流閾值時,后續(xù)請求會被降級,降級后的處理方案:排隊頁面、無貨、錯誤頁

C.人工開關(guān)降級

1.開關(guān)可以存放到配置文件、數(shù)據(jù)庫、Redis/ZooKeeper,可以定期同步開關(guān)數(shù)據(jù),然后通過判斷某個KEY的值來決定是否降級

2.對于新開發(fā)的服務進行灰度測試,就需要設置開關(guān),還有多機房服務,也可以通過開關(guān)完成

3.還有一引起是因為功能問題需要暫時屏蔽掉某些功能

D.讀服務降級

1.一般采取的策略有:暫時切換讀(降級到讀緩存、降級走靜態(tài)化)、暫時屏蔽讀(屏蔽讀入口、屏蔽某個讀服務)

2.我們會在接入層、應用層設置開關(guān),當分布式緩存、RPC服務/DB有問題時自動降級為不調(diào)用,適用于讀一致性要求不高的場景

3.頁面降級、頁面片段降級、頁面異步請求降級都是讀服務降級,目的是丟卒保帥

4.動態(tài)化降級為靜態(tài)化

5.靜態(tài)化降級為動態(tài)化

E.寫服務降級

1.大多數(shù)場景下是不可降級的,不過可以:將同步操作轉(zhuǎn)換為異步操作、限制寫的量/比例(如評論開關(guān)量大時不可見)

F.多級降級

1.降級是離用戶走越近越對系統(tǒng)保護得好,因為業(yè)務的復雜性導致越到后端QPS/TPS越低

* 頁面JS降級開關(guān):控制頁面功能降級

* 接入層降級開關(guān):控制請求入口的降級

* 應用層降級開關(guān):控制業(yè)務的降級

G.配置中心

1.應用層API封裝

2.使用配置文件實現(xiàn)開關(guān)配置

3.使用配置中心實現(xiàn)開關(guān)配置:ZooKeeper、Diamond、Disconf、Etcd 3、Consul

H.使用Hystrix實現(xiàn)降級

I.使用Hystrix實現(xiàn)熔斷

六、超時與重試機制

A.簡介

1.如果應用不設置超時,則可能會導致請求響應慢,慢請求累積導致連鎖反應,甚至造成應用雪崩

2.讀服務天然適合重試,而寫服務大多不能重試(如果寫服務是冪等的,則重試是允許的),重試次數(shù)太多會導致多倍請求流量

3.在進行代碼Review時,一定記得Review超時與重試機制

4.超時與重試機制:

* 代理層超時與重試

* Web容器超時

* 中間件客戶端超時與重試

* 數(shù)據(jù)庫客戶端超時

* NoSQL客戶端超時

* 業(yè)務超時

* 前端Ajax超時

B.代理層超時與重試

1.Nginx

* client_header_timeout time:設置讀取客戶端請求頭超時時間,默認為60s,響應408,如果在些超時時間內(nèi)客戶端沒有發(fā)送完請求頭

* client_body_timeout time:設置讀取客戶端內(nèi)容體超時時間,默認為60s,響應408,兩次成功讀操作間隔時間,而不是發(fā)送整個請求體超時時間

* send_timeout_time:設置發(fā)送響應到客戶端的超時時間,默認60s,兩次成功寫操作間隔時間,而不是發(fā)送整個響應的超時時間

* keepalive_timeout timeout [header_timeout]:設置HTTP長連接超時時間,要配合keepalive_disable和keepalive_requests一起使用

2.DNS解析超時設置

* resolver_timeout 30s:設置DNS解析超時時間,默認30s,配合resolver address ... [valid=time]進行DNS域名解析

3.代理超時設置

* proxy_connect_timeout time:與后端/上游服務器建立連接的超時時間

* proxy_read_timeout time:設置從后端/上游服務器讀取響應的超時時間

* proxy_send_timeout time:設置往后端/上游服務器發(fā)送請求的超時時間

* proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | non_idempotent | off ...:配置什么情況下需要請求下一臺上游服務器進行重試ZXCV

* proxy_next_upstream_tries number:設置重試次數(shù),指所有請求次數(shù),默認0表示不限制

* proxy_next_upstream_timeout time:設置重試最大超時時間,默認0表示不限制

* upstream存活超時,max_fails和fail_timeout:配置什么時候Nginx將上游服務器認定為不可用/不存活

4.Twemproxy:Twitter開源的Redis和Memcache代理中間件,減少與后端緩存服務器的連接數(shù)

C.Web容器超時

D.中間件客戶端超時與重試

1.JSF是京東自研的SOA框架,主要有三個組件:注冊中心、服務提供端、服務消費端

2.JMQ是京東消息中間件,主要有四個組件:注冊中心、Broker(JMQ的服務器端實例,生產(chǎn)和消費消息都跟它交互)、生產(chǎn)者、消費者

E.數(shù)據(jù)庫客戶端超時

F.NoSQL客戶端超時

G.業(yè)務超時

1.任務型:可以通過Worker定期掃描數(shù)據(jù)庫修改狀態(tài),有時需要遠程服務超時了,可以考慮使用隊列或者暫時記錄到本地稍后重試

2.服務調(diào)用型:可以簡單地使用Futrue來解決問題(Java)

H.前端Ajax超時

1.可以在請求時帶上timeout參數(shù)

2.使用setTimeout進行超時重試

七、回滾機制

A.事務回滾

1.對于單庫事務回滾直接使用相關(guān)SQL即可

2.分布式事務常見的如兩階段提交、三階段提交協(xié)議,可以考慮事務表、消息隊列、補償機制(執(zhí)行/回滾)、TCC模式(預占/確認/取消)、Sagas模式(拆分事務+補償機制)等實現(xiàn)最終一致性

B.代碼庫回滾

1.SVN、Git等

C.部署版本回滾

1.部署版本化:發(fā)布時采用全量發(fā)布,避免增量發(fā)布

2.小版本增量發(fā)布:先發(fā)布1臺驗證,沒問題發(fā)布10臺,最后全部發(fā)布

3.大版本灰度發(fā)布:兩個版本并行跑一段時間

4.架構(gòu)升級并發(fā)發(fā)布:通過A/B方式慢慢地將流量引入到新版本集群,如果新版本出現(xiàn)大面積故障,降級回老版本

D.數(shù)據(jù)版本回滾

1.兩種思路:全量和增量

* 全量版本化是指即使只變更了其中一個字段也將整體記錄進行歷史版本化

* 增量版本化是只保存變化的字段

八、壓測與預案

A.系統(tǒng)壓測

1.壓測一般指性能壓力測試,用來評估系統(tǒng)的穩(wěn)定性和性能,從而決定是否需要擴容或縮容

2.壓測之前要有壓測方案【如壓測接口、并發(fā)量、壓測策略(突發(fā)、逐步加壓、并發(fā)量)、壓測指標(機器)】,之后要產(chǎn)出壓測報告【壓測方案、機器負載、QPS/TPS、響應時間(平均、最小、最大)、成功率、相關(guān)參數(shù)(JVM參數(shù)、壓縮參數(shù))】,最后根據(jù)壓測報告分析的結(jié)果進行系統(tǒng)優(yōu)化和容災

3.線下壓測:通過如JMeter、Apache ab壓測系統(tǒng)的某個接口或者某個組件

4.線上壓測:按讀寫分為讀壓測、寫壓測和混合壓測,按數(shù)據(jù)仿真度分為仿真壓測和引流壓測,按是否給用戶提供服務分為隔離集群壓測和線上集群壓測

5.讀壓測是壓測系統(tǒng)的讀流量,寫壓測是辱沒系統(tǒng)的寫流量,讀和寫是會相互影響 的,因此,這種情況下要進行混合壓測

6.仿真壓測是通過模擬請求進行系統(tǒng)壓測,數(shù)據(jù)可以是使用程序構(gòu)造、人工構(gòu)造,或者使用Nginx訪問日志

7.隔離集群壓測是指將對外提供服務的部分服務器從線上集群摘除,然后將線上流量引流到該集群進行壓測,這種方式很安全

8.單機壓測是指對集群中的一臺機器進行壓測,從而評估出單機極限處理能力,發(fā)現(xiàn)單機的瓶頸點,這樣可以把單機性能優(yōu)化到極致

9.離散壓測,即選擇的數(shù)據(jù)應該是分散的或者長尾的

10.全鏈路壓測

B.系統(tǒng)優(yōu)化和容災

1.拿到壓測報告 后,接下來會分析報告,然后進行一些有針對性的優(yōu)化,如硬件升級、系統(tǒng)擴容、參數(shù)調(diào)優(yōu)、代碼優(yōu)化、架構(gòu)優(yōu)化

2.在進行系統(tǒng)優(yōu)化時,要進行代碼走查,發(fā)現(xiàn)不合理的參數(shù)配置,如超時時間、降級策略、緩存時間等,在系統(tǒng)壓測中進行慢查詢排查,包括Redis、MySQL等,通過優(yōu)化查詢解決慢查詢問題

3.在應用系統(tǒng)擴容方面,可以根據(jù)去年流量、與運營業(yè)務方溝通促銷力度、最近一段時間的流量來評估出是否需要進行擴容,需要擴容多少倍

4.在擴容時要考慮系統(tǒng)容災,比如分組部署、跨機房部署,容災是通過部署多組(單機房/多機房)相同應用系統(tǒng),當其中一組出現(xiàn)問題時,可以切換到另一個分組

C.應急預案

1.系統(tǒng)分級:可以按照交易核心系統(tǒng)和交易支撐系統(tǒng)進行劃分

2.針對核心系統(tǒng)進行全鏈路分析,從用戶入口到后端存儲,梳理出各個關(guān)鍵路徑,對相關(guān)路徑進行評估并制定預案

* 網(wǎng)絡接入層:由系統(tǒng)工程師負責,關(guān)注機房不可用、DNS故障、VIP故障等預案處理

* 應用接入層:由開發(fā)工程師負責,關(guān)注上游應用路由切換、限流、降級、隔離等預案處理

* Web應用層和服務層:由開發(fā)工程師負責,關(guān)注依賴服務的路由切換、連接池(數(shù)據(jù)庫、線程池等)異常、限流、超時降級、服務異常降級、應用負載異常、數(shù)據(jù)庫故障切換、緩存故障切換等

* 數(shù)據(jù)層:由開發(fā)工程師或系統(tǒng)工程師負責,關(guān)注數(shù)據(jù)庫/緩存負載高、數(shù)據(jù)庫/緩存故障等

3.制定好預案后,應對預案進行演習,來驗證預案的正確性,在制定預案時也要設定故障的恢復時間

4.要對關(guān)聯(lián)路徑實施監(jiān)控報警,包括服務器監(jiān)控(CPU使用率、磁盤使用每戶、網(wǎng)絡帶寬等)、系統(tǒng)監(jiān)控(系統(tǒng)存活、URL狀態(tài)/內(nèi)容監(jiān)控、端口存活等)、JVM監(jiān)控(堆內(nèi)存、GC次數(shù)、線程數(shù)等)、接口監(jiān)控【接口調(diào)用量(每秒/每分鐘)、接口性能(TOP50/TOP99/TOP999)、接口可用率等】,然后配置報警策略如監(jiān)控時間段、報警閾值、通知方式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容