京东商品详情页碎碎念
在之前的兩篇文章《構建需求響應式億級商品詳情頁》和《京東商品詳情頁服務閉環實踐》已經詳細介紹了整個系統的架構設計和實現思路。本篇將介紹下雜七雜八的一些實踐:
- 靜態化
- 突發流量
- 惡意訪問
- 托底數據
- 超時時間/重試
- CDN回源
- 監控和報警
- 日志
?
靜態化
我個人總結為:數據靜態化、頁面片段靜態化、頁面靜態化;數據靜態化即把相關數據聚合為一個大數據,這樣比如獲取數據時只需要一次獲取即可,好處是減少多次獲取帶來的性能開銷;頁面片段靜態化即整個大頁面按照不同的維度進行分拆,生成一些頁面片段,然后通過SSI(服務端包含技術)將多個頁面片段合并輸出,比如商品詳情頁可以分為主框架、面包屑、商家信息、商品介紹、規格參數等頁面片段,可以存儲到磁盤或者分布式文件系統,存儲到磁盤需要注意小文件造成的隨機讀寫變多了和一些文件系統對inode數的限制;而頁面靜態化是把整個大頁面生成靜態頁,缺點是頁面一部分變更需要更新整個頁面;其中數據靜態化最靈活,可以實現數據和模板的分離,模板可以隨意變化,適合經常變更的業務。
?
突發流量
對于突發流量,我這邊系統的一般解決方案:高效緩存、自動降級、減少回源量;高效緩存可以參考《構建需求響應式億級商品詳情頁》和《京東商品詳情頁服務閉環實踐》中的緩存實踐;而自動降級也在這兩篇文章中講到了,不再重復。
?
減少回源量可以通過一致性哈希、非阻塞鎖、304響應來實現;通過一致性哈希可以將相同的請求打到相同的服務器,提升緩存命中率,而輪訓會造成緩存命中率低;非阻塞鎖即比如100個人同時請求一個頁面時,首先讓一個回源到后端系統進行處理,假設超時時間是100ms,如果100ms內返回了內容,則這100個人直接返回這一份內容即可,如果100ms后端系統沒能返回,這100個請求會全部打到后端系統,也就是說如果后端系統響應快則回源量減少,否則回源量不會變少。
?
對于304可以通過兩種機制實現,一種是業務系統提供變更時間,然后去比對是否變更,如果沒有變更則直接返回304,這樣只需要對比變更時間即可;另一個是設置一個容忍時間,比如10s,那么10s內的請求都返回304,不調用業務系統。對于秒殺業務設置10s的容忍時間會減少很多回源量,減少突發流量打掛后端業務系統。
?
惡意訪問
對于惡意方案可以通過:提升緩存命中率,減少回源量、限流、導流到隔離的分組、N頁以后的請求做特殊處理,如降低請求速度。提升緩存命中率或者所有數據都緩存/SSD,這樣只要預估好流量,一般就不怕刷;另外可以減少回源量,比如使用多級緩存、爬蟲做特殊處理等;對于一些請求還是需要做限流,限流可以按照連接數、請求數、流量、用戶進行限流,對于緩存未命中的需要回源查數據庫之類的我們需要限流,而查詢緩存的請求可以根據實際情況進行限流處理;對于一些惡意的請求可能是通過小區寬帶過來的,我們不能完全拒絕掉該IP,可以考慮將這些流量導到隔離的分組,比如進行慢速處理;還有一些列表頁相關的應用,可以考慮對N頁以后的請求做特殊處理,比如慢速處理或者根據實際調用量返回一些過期緩存數據。
?
托底數據
所謂托底數據即假設正常業務處理失敗了,不能返回給用戶一個503錯誤頁,可以進行有損降級處理,比如根據場景返回一些快過期或已過期數據;另外可以進行部分有損服務而不是所有。比如請求一個用戶推薦時,假設用戶推薦沒出來我們可以返回默認的推薦數據或者歷史的推薦數據。還有如CDN緩存的,可以在出問題時返回歷史數據;或者使用html5 localstorage存儲;還可以通過兩個分離的域名,一個失敗后,自動調用另一個拿托底數據。
?
超時時間/重試
對于一個系統來說,超時時間是必須設置的,主要有如TCP連接/讀/寫超時時間、連接池超時時間,還有相關的重試時機/次數;對于一個網絡服務,需要根據實際情況設置TCP連接/讀/寫超時時間,如果不設置很可能會在網絡出問題時服務直接掛斷,比如我們連接Redis都設置在150ms以內;還有如果使用Nginx,還需要考慮Nginx超時時間、upstream超時時間和業務超時時間,假設Nginx超時時間是5s、upstream超時時間是6s,而業務的超時時間是8s,那么假設業務處理了7s,那么upstream超時時間到了需要進行下一個upstream的重試,但是Nginx總的超時時間是5s,所以就無法重試了;連接池也需要設置獲取連接的等待時間,如果不設置會有很多線程一直在等待,之前寫自己實現連接池時,會去發現是否網絡錯誤,如果網絡錯誤就沒必要等待連接了,而立即失敗即可;還需要考慮服務失敗重試時機,比如是立即重試,還是指數式重試;還有重試次數,是一次性重試三次還是指數式等待時間后進行一次次的重試;比如HttpClient(DefaultHttpRequestRetryHandler)默認會立即進行三次重試。?
?
CDN回源
對于CDN減少回源的策略有非阻塞鎖、爬蟲不回源,返回歷史數據、版本化等;對于版本化的意思是對于一些內容可以通過版本化機制設置更長的超時時間,而且固定URL順序,這樣相同的URL請求只要版本不變就會更有效的命中CDN數據;版本可以通過推送機制通知相關系統;比如評價數據的版本化,可以每隔幾分鐘推送變更了版本 的商品更新版本號。
?
監控和報警
對于監控我們一般監控CPU/內存/磁盤、應用實例存活、調用量/響應時間/可用率這些信息,可以根據系統狀況設置一些參數的閥值,比如可用率(系統異常)小于80%則告警,這樣可以及時發現系統問題并解決。
?
日志
對于日志我們一般需要經常收集記錄和查看Nginx日志(訪問日志、錯誤日志)、應用日志(業務日志、異常日志、OOM堆/堆棧日志)、監控日志(調用量、響應時間、可用率)、系統日志。Nginx訪問日志可以記錄IP、UA、Referer等信息以便發現惡意訪問的一些線索,記錄request_time、response_time來發現是否存在一些慢速請求;而Nginx錯誤日志查看是否存在超時或者一些服務出問題了;應用業務日志用來排查業務邏輯是否正確的,而應用異常日志用來發現什么時間、什么位置、哪個類的哪個方法出現了什么問題,以便故障排查,還有如Java應用OOM時的堆/堆棧日志也要存好了;監控日志用來記錄服務的一些吞吐量和性能數據;另外需要經常查看系統日志,如之前遇到過應用大量timeout情況,查看dmsg發現存在nf_conntrack: table full, dropping packet,讓運維把防火墻關掉即可。
?
其他
為了發現是哪臺服務器出現了問題,我們都要在響應響應頭記錄服務器真實IP,這樣出問題后,直接定位到哪臺服務器出問題了;對于多機房業務盡量使用智能DNS,即一個機房的服務盡量調用一個機房的服務,減少跨機房調用;在沒有進行Docker容器化之前,我們還可以減少跨交換機、跨機柜調用;對于整個系統我們無法保證整個系統不出現臟數據,所以需要提供刷臟數據的接口,以便出現問題時進行數據的更新或刪除。
來源:http://jinnianshilongnian.iteye.com/blog/2259546
總結
以上是生活随笔為你收集整理的京东商品详情页碎碎念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 太湖三白(说一说太湖三白的简介)
- 下一篇: 构建亿级前端读服务