高並發解決方案


一、高並發和大流量解決方案

高並發架構相關概念
  並發:在操作系統中,是指一個時間段中有幾個程序都處於已啟動運行到運行完畢之間,且這幾個程序都是在同一個處理機上運行,但任一個時刻點上只有一個程序在處理機上運行;在互聯網時代,所講的並發,高並發通常是指並發訪問,也就是在某個時間點,有多少個訪問同時到來。通常一個系統的日PV在千萬以上,有可能是一個高並發的系統。有的公司完全不走技術路線,全靠機器堆,這不在討論范圍內。
  QPS:每秒鍾請求或者查詢的數量,在互聯網領域,指每秒響應請求數(指HTTP請求);並發連接數是系統同時處理的請求數量
  吞吐量:單位時間內處理的請求數量(通常由QPS與並發數決定)
  響應時間:從請求發出到收到響應花費的時間。例如系統處理一個HTTP請求需要100ms。
  PV:綜合瀏覽量(page view),即頁面瀏覽量或者點擊量,一個訪客在24小時內訪問的頁面數量;同一個人瀏覽網站同一頁面,只記作一次PV
  UV:獨立訪客(unique visitor),即一定時間范圍內相同訪客多次訪問網站,只計算為一個獨立訪客
  帶寬:計算帶寬大小需關注兩個指標,峰值流量和頁面的平均大小
  日網站帶寬=PV/統計時間(換算到s)*平均頁面大小(單位KB)*8;峰值一般是平均值的倍數,根據實際情況來定
  峰值每秒請求數(QPS)=(總PV數*80%)/(6小時秒數*20%);80%的訪問量集中在20%的時間
  壓力測試:測試能承受的最大並發,測試最大承受的QPS值
  常用性能測試工具:ab,wrk,http_load,web_bench,siege,apache jmeter;ab全稱是apache benchmark,apache官方推出的工具,創建多個並發訪問線程,模擬多個訪問者同時對某一trl地址進行訪問,它的測試目標是基於url的,因此既可以用來測試apache的負載能力,也可以測試nginx,lighthttp,tomcat,IIS等其它web服務器的壓力;ab的使用:模擬並發請求100次,總共請求5000次,ab -c 100 -n 5000 待測試網站;測試機器與被測試機器分開,不要對線上服務做壓力測試,觀察測試工具ab所在機器,以及被測試的前端機的CPU,內存,網絡等都不超過最高限度的75%

高並發解決方案案例  

流量優化:防盜鏈處理
前端優化:減少HTTP請求,合並css或js,添加異步請求,啟用瀏覽器緩存和文件壓縮,CDN加速,建立獨立圖片服務器,
服務端優化:頁面靜態化,並發處理,隊列處理
數據庫優化:數據庫緩存,分庫分表,分區操作,讀寫分離,負載均衡
web服務器優化:負載均衡,nginx反向代理,7,4層LVS軟件

二、web資源防盜鏈

盜鏈在自己的頁面上展示一些並不在自己服務器上的內容,獲得他人服務器上的資源地址,繞過別人的資源展示頁面,直接在自己的頁面上向最終用戶提供此內容,常見的是小站盜用大站的圖片,音樂,視頻,軟件等資源,通過盜鏈的方法可以減輕自己服務器的負擔,因為真實的空間和流量均是來自別人的服務器

防盜鏈:防止別人通過一些技術手段繞過本站的資源展示頁面,盜用本站的資源,讓繞開本站資源展示頁面的資源鏈接失效,可以大大減輕服務器及帶寬的壓力

工作原理:通過請求頭中的referer或者簽名,網站可以檢測目標網頁訪問的來源網頁,如果是資源文件,則可以跟蹤到顯示它的網頁地址,一旦檢測到來源不是本站即進行阻止或者返回制定的頁面,通過計算簽名的方式,判斷請求是否合法,如果合法則顯示,否則返回錯誤信息

實現方法:referer:nginx模塊ngx_http_referer_module用於阻擋來源非法的域名請求,nginx指令valid_referers none | blocked | server_names | string...,none表示referer來源頭部為空的情況,blocked表示referer來源頭部不為空,但是里面的值被代理或者防火牆刪除了,這些值都不以http://或者https://開頭,server_names表示referer來源頭部包含當前的server_names,全局變量$invalid_referer。不能徹底防范,只能提高門檻。也可以針對目錄進行防盜鏈。

傳統防盜鏈遇到的問題:偽造referer:可以使用加密簽名解決

加密簽名:使用第三方模塊HttpAccessKeyModule實現Nginx防盜鏈。accesskey on|off 模塊開關,accesskey_hashmethod md5|sha-1 簽名加密方式,accesskey_arg GET參數名稱,accesskey_signature 加密規則,在nginx的conf中設置

三、減少HTTP請求次數

性能黃金法則:只有10%-20%的最終用戶響應時間花在接收請求的HTML文檔上,剩下的80%-90%時間花在HTML文檔所引用的所有組件(img,script,css,flash等)進行的HTTP請求上。

如何改善:改善響應時間的最簡單途徑就是減少組件的數量,並由此減少HTTP請求的數量

HTTP連接產生的開銷:域名解析--TCP連接--發送請求--等待--下載資源--解析時間

減少HTTP請求的方式:

1、圖片地圖:允許在一個圖片上關聯多個URL,目標URL的選擇取決於用戶單擊了圖片上的哪個位置,以位置信息定位超鏈接,把HTTP請求減少為一個,可以保證設計的完整性和功能的齊全性,使用maparea標簽;

<img usemap="#map" src="/map.gif?t=111">
<map name="map">
    <area shape="rect" coords="0,0,30,30" href=... title="">
    ...       
</map>

2、CSS Sprites:CSS精靈,通過使用合並圖片,通過指定css的background-image和background-position來顯示元素。圖片地圖與css精靈的響應時間基本上相同,但比使用各自獨立圖片的方式要快50%以上。

3、合並腳本和樣式表:使用外部的js和css文件引用的方式,因為這要比直接寫在頁面中性能要更好一點;獨立的一個js比用多個js文件組成的頁面載入要快38%;把多個腳本合並為一個腳本,把多個樣式表合並為一個樣式表

4、圖片使用base64編碼減少頁面請求數:采用base64的編碼方式將圖片直接嵌入到網頁中,而不是從外部載入

四、瀏覽器緩存和數據壓縮優化

HTTP緩存機制:如果請求成功會有三種情況:

1、 200 from cache:直接從本地緩存中獲取相應,最快速,最省流量,因為根本沒有向服務器進行請求;

2、 304 not modified:協商緩存,瀏覽器在本地沒有命中的情況下請求頭中發送一定的校驗數據到服務端,如果服務端數據沒有改變瀏覽器從本地緩存響應,返回304,快速,發送的數據很少,只返回一些基本的響應頭信息,數據量很小,不發送實際響應體;

3、 200 OK:以上兩種緩存全部失敗,服務器返回完整響應,沒有用到緩存,相對最慢。

緩存策略的選擇:

適合緩存的內容:不變的圖像,如logo,圖標等,js,css靜態文件,可下載的內容,媒體文件;

建議使用協商緩存:html文件,經常替換的圖片,經常修改的js,css文件,js和css文件的加載可以加入文件的簽名來拒絕緩存,如a.css?簽名或a.簽名.js;

不建議緩存的內容:用戶隱私等敏感數據,經常改變的api數據接口

nginx配置緩存策略:  

本地緩存配置:add_header指令:添加狀態碼為2xx和3xx的響應頭信息,add_header name value [always];,可以設置Pragma/Expires/Cache-Control,可以繼承;expires指令:通知瀏覽器過期時長,expires time;,為負值時表示Cache-Control: no-cache;,當為正或者0時,就表示Cache-Control: max-age=指定的時間;;當為max時,Cache-Control設置到10年;
協商緩存相關配置:Etag指令:指定簽名;etag on|off;,默認是on

前端代碼和資源的壓縮:

讓資源文件更小,加快文件在網絡中的傳輸,讓網頁更快的展現,降低帶寬和流量開銷;壓縮方式:js,css,圖片,html代碼的壓縮,Gzip壓縮

js代碼壓縮:一般是去掉多余的空格和回車,替換長變量名,簡化一些代碼寫法等,代碼壓縮工具很多UglifyJS(壓縮,語法檢查,美化代碼,代碼縮減,轉化)、YUI Compressor(來自yahoo,只有壓縮功能)、Closure Compiler(來自google,功能和UglifyJS類似,壓縮的方式不一樣),有在線工具tool.css-js.com,應用程序,編輯器插件。

css代碼壓縮:原理和js壓縮原理類似,同樣是去除空白符,注釋並且優化一些css語義規則等,壓縮工具CSS Compressor(可以選擇模式)。

html代碼壓縮:不建議使用代碼壓縮,有時會破壞代碼結構,可以使用Gzip壓縮,當然也可以使用htmlcompressor工具,不過轉換后一定要檢查代碼結構。

img壓縮:一般圖片在web系統的比重都比較大,壓縮工具:tinypng,JpegMini,ImageOptim。

Gzip壓縮:配置nginx服務,gzip on|off,gzip_buffers 32 4K|16 8K #緩沖(在內存中緩存幾塊?每塊多大),gzip_comp_level [1-9] #推薦6 壓縮級別(級別越高,壓的越小,越浪費CPU計算資源),gzip_disable #正則匹配UA 什么樣的uri不進行gzip,gzip_min_length 200 #開始壓縮的最小長度,gzip_http_version 1.0|1.1 #開始壓縮的http協議版本,gzip_proxied #設置請求者代理服務器,該如何緩存內容,gzip_types text/plain applocation/xml #對哪些類型的文件用壓縮,gzip_vary on|off #是否傳輸gzip壓縮標志。其他工具:自動化構建工具Grunt。

五、CDN加速

CDN:Content Delivery Network,內容分發網絡,盡可能避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快更穩定;在網絡各處放置節點服務器所構成的在現有的互聯網基礎之上的一層智能虛擬網絡;CDN系統能夠實時的根據網絡流量和各節點的連接,負載情況以及到用戶的距離和響應時間等綜合信息將用戶的請求重新導向離用戶最近的服務節點上

CDN的工作原理

  • 傳統訪問:用戶在瀏覽器輸入域名發起請求--解析域名獲取服務器IP地址--根據IP地址找到對應的服務器--服務器響應並返回數據;
  • 使用CDN訪問:用戶發起請求--智能DNS的解析(根據IP判斷地理位置,接入網類型,選擇路由最短和負載最輕的服務器)--取得緩存服務器IP--把內容返回給用戶(如果緩存中有)--向源站發起請求--將結果返回給用戶--將結果存入緩存服務器

CDN適用場景:站點或者應用中大量靜態資源的加速分發,如css,js,img和html;大文件下載;直播網站等

CDN的實現:BAT等都有提供CDN服務,可用LVS做4層負載均衡;可用nginx,Varnish,Squid,Apache TrafficServer做7層負載均衡和cache;使用squid反向代理,或者nginx等的反向代理

六、建立獨立的圖片服務器

獨立的必要性:分擔web服務器的I/O負載-將耗費資源的圖片服務分離出來,提高服務器的性能和穩定性;能夠專門的圖片服務器進行優化-為圖片服務設置有針對性的緩存方案,減少帶寬成本,提高訪問速度;提高網站的可擴展性-通過增加圖片服務器,提高圖片吞吐能力

采用獨立域名:原因:同一域名下瀏覽器的並發連接數有限制,突破瀏覽器連接數的限制;由於cookie的原因,對緩存不利,大部分web cache都只緩存不帶cookie的請求,導致每次的圖片請求都不能命中cache

獨立后的問題:如何進行圖片上傳和圖片同步:NFS共享方式;利用FTP同步

七、動態語言靜態化

將現有PHP等動態語言的邏輯代碼生成為靜態HTML文件用戶訪問動態腳本重定向到靜態HTML文件的過程對實時性要求不高的頁面比較適合

原因:動態腳本通常會做邏輯計算和數據查詢,訪問量越大,服務器壓力越大;訪問量大時可能會造成CPU負載過高,數據庫服務器壓力過大;靜態化可以降低邏輯處理壓力,降低數據庫服務器查詢壓力

靜態化的實現方式:

1.使用模板引擎:可以使用smarty的緩存機制生成靜態HTML緩存文件;

2.利用ob系列的函數:ob_start():打開輸出控制緩沖,ob_ge_contents():返回輸出緩沖區內容,ob_clean():清空輸出緩沖區,ob_end_flush():沖刷出(送出)輸出緩沖區內容並關閉緩沖,可以判斷文件的inode修改時間,判斷是否過期使用filectime函數

八、動態語言層的並發處理

進程&線程&協程&多線程等(具體看這里https://www.cnblogs.com/sunny0824/p/13699056.html

九、數據庫緩存層的優化

mysql等一些常見的關系型數據庫的數據都存儲在磁盤當中,在高並發場景下,業務應用對mysql產生的增刪改查的操作造成的巨大的IO開銷和查詢壓力,這無疑對數據庫和服務器都是一種巨大的壓力。

為了解決此類問題,緩存數據的概念應運而生。極大的解決數據庫服務器的壓力,提高應用數據的響應速度。常見的緩存形式:內存緩存文件緩存

緩存數據是為了讓客戶端很少甚至不訪問數據庫服務器進行數據的查詢,高並發下,能最大程度的降低對數據庫服務器的訪問壓力。默認情況下:用戶請求->數據查詢->連接數據庫服務器並查詢數據->將數據緩存起來(html,內存,json,序列化數據)->顯示給客戶端;用戶再次請求或者新用戶訪問->數據查詢->直接從緩存中獲取數據->顯示給客戶端

mysql的查詢緩存:query_cache_type:查詢緩存類型,有0,1,2三個取值,0則不使用查詢緩存,1表示始終使用查詢緩存,2表示按需使用查詢緩存。

方法memcache 與 redis

1. 使用memcache緩存查詢數據

memcache工作原理:是一個高性能的分布式的內存對象緩存系統,通過在內存里維護一個統一的巨大的hash表,能夠用來存儲各種格式的數據,包括圖像,視頻,文件以及數據庫檢索的結果等,簡單的說就是將數據調用到內存,然后從內存中讀取,從而大大提高讀取速度。

memcache工作流程:先檢查客戶端的請求數據是否在memcache中,如有,直接把請求數據返回,不再對數據庫進行任何操作;如果請求的數據不在memcache中,就去查數據庫,把從數據庫中獲取的數據返回給客戶端,同時把數據緩存一份到memcache中。

memcache方法:獲取:get(key) 設置:set(key, val, expire) 刪除:delete(key)

2. 使用redis緩存查詢數據:

與memcache的區別

  • 性能相差不大,redis在2.0版本后增加了自己的VM特性,突破物理內存的限制,memcache可以修改最大可用內存,采用LRU算法;
  • redis依賴客戶端來實現分布式讀寫,memcache本身沒有數據冗余機制;
  • redis支持快照,AOF,依賴快照進行持久化,aof增強了可靠性的同時,對性能有所影響,memcache不支持持久化,通常做緩存,提升性能;
  • memcache在並發場景下,用cas保證一致性,redis事務支持比較弱,只能保證事務中的每個操作連續執行;
  • redis支持多種類的數據類型;redis用於數據量較小的高性能操作和運算上,memcache用於在動態系統中減少數據庫負載,提升性能,適合做緩存,提高性能

十、mysql數據庫層的優化

優化方向:數據表數據類型優化索引優化sql語句優化存儲引擎的優化數據表結構設計的優化數據庫服務器架構的優化

  • 數據表數據類型優化:字段使用什么樣的數據類型更合適,性能更快,tinyint、smallint、bigint,考慮空間和范圍的問題;char、varchar,存儲字符串長度是否固定;enum,特定固定的分類可以使用enum存儲,效率更快;IP地址的存儲,ip2long(),使用整型存儲IP地址
  • 索引的優化:建立合適的索引,索引在什么場景下效率最高,索引的創建原則:不是越多越好,在合適的字段上創建合適的索引,復合索引的前綴原則,like查詢%的問題,全表掃描優化,or條件索引使用情況,字符串類型索引失效的問題
  • sql語句的優化:優化查詢過程中的數據訪問,優化長難句、特定類型的查詢語句。使用limit,返回列不用*,變復雜為簡單,切分查詢,分解關聯查詢,優化count(),優化關聯查詢,優化子查詢,優化group by和distinct,優化limit和union
  • 存儲引擎的優化:盡量使用innoDB存儲引擎
  • 數據表結構設計的優化:分區操作,通過特定的策略對數據表進行物理拆分,對用戶透明,partition by;分庫分表,水平拆分,垂直拆分
  • 數據庫架構的優化:主從復制,讀寫分離,雙主熱備,binlog日志,中繼日志,主從庫binlog的交換,事件傳輸;負載均衡,通過LVS的三種基本模式實現負載均衡,mycat數據庫中間件實現負載均衡

十一、 web服務器的負載均衡

七層負載均衡的實現:

基於URL等應用層信息的負載均衡,nginxproxy是它一個很強大的功能,實現了7層負載均衡,功能強大,性能卓越,運行穩定,配置簡單靈活,能夠自動剔除工作不正常的后端服務器,上傳文件使用異步模式,支持多種分配策略,可以分配權重,分配方式靈活。

nginx負載均衡內置策略IP Hash,加權輪詢擴展策略fair策略,通用hash,一致性hash

加權輪詢:首先將請求都分給高權重的機器,直到該機器的權值降到了比其他機器低,才開始將請求分給下一個高權重的機器,當所有后端機器都down掉時,nginx會立即將所有機器的標志位清成初始狀態,以避免造成所有的機器都處在timeout的狀態;

IP Hash:流程和輪詢很類似,只是其中的算法和具體的策略有些變化,算法是一種變相的輪詢算法;

fair:根據后端服務器的響應時間判斷負載情況,從中選出負載最輕的機器進行分流;

通用hash,一致性hash:通用hash比較簡單,可以以nginx內置的變量為key進行hash,一致性hash采用了nginx內置的一致性hash環,支持memcache

nginx配置:

http {
    upstream cluster{
        #ip_hash;
        server srv1 weight=1;
        server srv2;
        server srv3;
    } 
    server {
        listen 80;
        location / {
            proxy_pass http://cluster;
        }
    }   
}  

四層負載均衡的實現:

通過報文中的目標地址和端口,再加上負載均衡設備設置的服務器選擇方式,決定最終選擇的內部服務器。LVS實現服務器集群負載均衡有三種方式,NAT,DR和TUN。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM