首頁  >  文章  >  深入探討「高並發大流量」訪問的解決想法和方案

深入探討「高並發大流量」訪問的解決想法和方案

青灯夜游
青灯夜游轉載
2022-05-11 14:18:184557瀏覽

怎麼解決高並發大流量問題?以下這篇文章就來跟大家分享下高並發大流量web解決思路及方案,希望對大家有幫助!

相關影片課程推薦:《千萬級資料並發解決方案(理論實戰)

分享一些高並發面試題:15個PHP關於高並發的面試題(總結)

高並發web架構相關概念


  • QPS:每秒鐘請求或查詢的數量,在互聯網領域,指每秒對應請求數(http請求)。

  • 峰值每秒的QPS:(總PV數80%)/(6小時秒數20%),80%的訪問量集中在20%的時間

  • 並發連線數:系統同時處理的請求數量

  • ##:單位時間內處理的請求數量(通常由QPS與並發數決定)。

  • 回應時間:從請求發出到收到回應所花費的時間。例如係統處理一個HTTP請求需要100ms,這個100ms就是系統的回應時間。

  • PV:綜合瀏覽量(Page View)即頁面瀏覽量和點擊量,一個訪客在24小時內造訪的頁面數量。

  • UV:獨立訪客(UniQue Visitor),即在一定時間範圍內相同訪客多次造訪網站,只計算為1個獨立訪客。

  • 頻寬:計算頻寬大小關注兩個指標,峰值流量和平均頁面大小。

  • 日網站頻寬=PV/統計時間(一天換算到秒)*平均頁面大小(單位KB)*8。

  • 壓力測試:測試承受的最大並發,測試最大承受的QPS,需要注意的測試並發測試機需要與被測試機器分開,不要對線上伺服器進行並發測試,觀察ab測試的所在機器,以及被測試機器的前端機的CPU,內存,網路等都不超過最高限度的75%。

    • 並發量

    • 回應速度

    • 容錯能力

  • 常用的效能測試工具:ab,wrk,http_load,Web Bench,Siege,Apache JMeter。

高並發大流量web整體解決思路


  • 流量最佳化

  • #web資源防盜鏈防止第三方系統盜用圖片,css,js等佔用伺服器流量和伺服器頻寬

  • #前端最佳化

  • 減少http請求:圖片合併,js合併,css合併壓縮,雖然檔案可能大點但請求會減少

  • 新增非同步請求:透過實際ajax呼叫介面取得資料

  • 啟動瀏覽器的快取和檔案壓縮(也可以啟用nginx的壓縮模組)

    • cdn加速:解決頻寬不夠用的問題,數據快取到cdn的節點,存取的時候選擇就近的節點,減少頻寬加快存取速度

    • 建立獨立的圖片伺服器:圖片是很吃io的,可以將圖片伺服器與web伺服器完全分離開,可以區分其它伺服器單獨搭建圖片伺服器不屬於計算型的配置可以適當的調整,圖片伺服器還可以集群

  • 服務端的最佳化
  • 頁面的靜態化:動態的頁面靜態html,減少伺服器的負載壓力,頁面靜態化穿透,靜態化有有效時間
  • 動態語言並發處理:非同步處理,多線程,佇列的非同步處理
  • #資料庫的最佳化:

  • ##資料庫的快取:memcache ,redis的快取

mysql索引最佳化,mysql分庫分錶,mysql分區操作,mysql主從複製讀寫分離,mysql的負載平衡,mysql的主從熱備

web伺服器的最佳化:

負載平衡:可以使用ningx的反向代理程式使用負載平衡,可以使用網路分層中的第四層lvs實現負載平衡

    web伺服器負載平衡
  • 負債平衡

四層負載平衡:所謂四層負載平衡就是基於IP 連接埠的負載平衡

七層負載平衡:所謂七層的負載平衡就是基於(URL)資訊的負載平衡

#七層負載平衡實作:
  • #基於URL等應用層資訊的負債平衡ningx的proxy是它一個很強大的功能,實現了7層負載平衡,功能強大,性能卓越,運行穩定,配置簡單靈活,能夠自動剔除工作不正常的後端伺服器,上傳檔案可以使用非同步模式上傳,支援多種分配策略,可以分配權重,分配方式靈活。
  • nginx負載平衡策略###################IP Hash(內建)########## #加權輪詢(內建)###
  • fair策略(擴充)

  • 通用hash(擴充)

  • 一致性hash(擴充)

1、IP Hash策略

nginx內建的另一個負載平衡的策略,流程和輪詢很相似,只是其中的演算法和具體的策略有些變化,IP hash演算法是一種變相的輪詢演算法

2、加權輪訓策略

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

3、fair策略

根據後端伺服器的回應時間判斷負載情況,從中選出負載最輕的機器進行分流

通用hash、一致性hash策略,通用hash比較簡單,可以以nginx內建的變數為key進行hash,一致性hash採用了內建的一致性hash環,支援memcache

四層負載平衡實現

透過封包中的目標位址和端口,再加上負載平衡設備設定的伺服器選擇方式,決定最終選擇的內部伺服器

lvs相關術語:

  • DS:director server 目標伺服器,即負載平衡器

  • RS:Real Server 真實伺服器,即後端伺服器

  • VIP:直接面向使用者的IP位址,通常為公網IP位址

  • DIP:Director Server Ip主要用於內部主機通訊的IP位址

  • #RIP:Real Server IP 後端真實伺服器的IP位址

  • CIP:Client IP

lvs負載平衡三種方式:

NAT:修改目標IP位址為後端的RealServer的IP位址

# DR:修改目標mac位址為後端的RealServer的mac位址

TUNNEL:較少使用,常用於異地容災

四、七層負載平衡優缺點

四層比七層可以承載更大的並發量,使用大型站點小

七層可以實現更為複雜的負載平衡控制,例如URL、基於session、動靜分離等

七層能夠佔用大量的CPU時間,承載的並發量

##cdn加速



    #什麼是cdn?
  • 節點:可以理解為真實伺服器的鏡像。

    全名為Content Delivery Network,也就是內容傳遞網路盡可能避開網路上可能影響資料傳輸速度和穩定性的瓶頸和環節,讓內容傳輸的更快、更穩定。
  • 在網路各處放置節點伺服器所構成的現有的互聯網基礎之上的一層智慧虛擬網路。

    cdn系統能夠即時地根據網路流量和各節點的連接,負載狀況以及到用戶的距離和回應時間等綜合資訊將用戶的請求重新導向離用戶最近的服務節點上。
  • cdn的優勢是什麼?
1、本地的cache加速,提高企業網站(尤其含有大量圖片和靜態頁面網站)的存取速度

2、跨運營商的網路加速,確保不同網路的用戶得到良好的存取品質

3、遠端存取用戶根據DNS負載平衡技術智慧自動選擇Cache伺服器

4、自動產生伺服器的遠端Mirror(鏡像)cache伺服器,遠端使用者存取時從cache伺服器上讀取數據,減少遠端存取的頻寬,分擔網路流量,減輕願站點web伺服器負載等功能。

5、廣泛分佈的cdn節點加上節點之間的智慧冗餘機制,可以有效的預防駭客入侵

#cdn的工作原理是什麼?

  • 傳統的存取:使用者在瀏覽器輸入網域名稱發起請求,解析網域名稱取得伺服器ip位址,根據ip位址找到對應的伺服器,伺服器回應並傳回資料。

    使用cdn存取:用戶發起請求,智慧dns的解析(根據ip判斷地理位置,接入網類型,選擇路由最短和負載最輕的伺服器),取得快取伺服器ip,把內容回傳給用戶(如果快取中有),向來源站發起請求,將結果存取給用戶,將結果存入快取伺服器。
  • cdn的適用場景?
  • 網站或應用程式中大量靜態資源的加速分發,例如:css,js,圖片和html############cdn的實作方式? ##################BAT等實作的CDN服務############使用LVS的4層負載平衡####### #####可用nginx,varnish,squid,apache trafficServer做七層負載平衡和cache 使用squid做反向代理或nginx做反向代理###

建立獨立的圖片伺服器


#獨立的必要性?

  • 1、分擔web伺服器的I/O負載,將耗費資源的圖片服務分離出來,提高伺服器的效能和穩定性

  • 2、能夠專門對圖片伺服器進行最佳化,為圖片服務設定針對性的快取方案,減少頻寬成本,提高存取速度

為啥採用獨立的域名?

原因:同一網域下瀏覽器的並發連線數是有限制的,突破瀏覽器連線的限制,由於cookie的原因,對快取不利,大部分web cache都只快取不帶cookie的請求,導致每次的圖片請求都不能夠命中cache

獨立後的問題?

  • 如何進行圖片上傳與圖片同步

  • #NPS分享方式

  • ##利用FTP同步

動態頁面靜態化


#相關概念:什麼是動態語言靜態化,為什麼要靜態化,靜態化的實現方式。


動態語言的並發處理


#什麼是進程

進程(Process)是電腦中的程式關於某資料集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是作業系統結構的基礎

進程是一個「執行中的程式”

進程的狀態的三態模型

多道程式系統中,進程在處理器上交替運行,狀態不斷變化。

  • 執行:當一個行程在處理機上執行時,則稱該行程處於運作狀態。處於此狀態的進程的數目小於等於處理器的數目,對於單處理機系統,處於運作狀態的進程只有一個。在沒有其它進程可以執行時(如所有進程都在阻塞狀態),通常會自動執行系統的空閒進程。

  • 就緒:當一個進程獲得了除處理機以外的一切所有資源,一旦得到處理機即可運行,則稱此進程處於就緒狀態。就緒狀態可以按多個優先權來劃分佇列。例如,當一個行程因時間片用完而進入就緒狀態時,排入低優先權佇列;當行程由I/O作業完成而進入就緒狀態時,排入高優先權佇列。

  • 阻塞:也稱為等待或睡眠狀態,一個行程正在等待某一事件發生(例如請求I/O而等待I/O完成等)而暫時停止執行,這時即使把處理機分配給進程也無法運作,故稱該進程處於阻塞狀態。

什麼是執行緒

#由於使用者的並發請求,為每個請求都建立一個行程顯然是行不通的,從系統資源開銷方面或是回應使用者請求的效率來看。因此操作系統中線程的概念便被引進了。

執行緒有時候被稱為輕量級進程,是程式執行流的最小單元。

執行緒是進程中的一個實體,是被系統獨立調度和分配的基本單位,執行緒自己不擁有系統資源,只擁有一點兒運行中必不可少的資源但它可與同屬一個進程的其它執行緒共享進程所擁有的全部資源。

一個執行緒可以建立和撤銷另一個線程,同一個行程中的多個執行緒之間可以並發執行。

執行緒是程式中一個單一的順序控制流程。進程內一個相對獨立的、可調度的執行單元,是系統獨立調度和分派cpu的基本單位指運作中的程式的調度單位。

執行緒三狀態

  • 就緒狀態:執行緒具備運行的所有條件,邏輯上可以運行,等待處理機。

  • 運作狀態:執行緒佔有處理機正在運作。

  • 阻塞狀態:執行緒在等待一個事件(如某個訊號量),邏輯上無法執行。

什麼是協程

#協程是一種使用者狀態的輕量級線程,協程的調度完全由使用者控制。協程擁有自己的暫存器上下文和堆疊。協稱調度切換時,將暫存器上下文和堆疊保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切的開銷,可以不要加鎖的訪問全域變量,所以上下文的切換非常快。

執行緒和行程的差別?

  • 1、執行緒是進程內的執行單元,進程內至少有一個線程,它們共享進程的位址空間,而進程有自己獨立的位址空間。

  • 2、行程是資源分配和擁有的單位,同一個行程內的執行緒共享行程的資源。

  • 3、執行緒是處理器調度的基本單位,但進程不是

  • 4、二者都可以並發的執行

  • #5、每個獨立的執行緒有一個程式運行的入口,順序執行序列和程式的出口,但是執行緒不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。

執行緒與協程的差別?

  • 1、一個執行緒可以多個協程,一個行程也可以單獨擁有多個協程

  • 2.執行緒進程都是同步機制,而協程則是異步

  • 3、協稱能夠保留上一次呼叫時的狀態,每次過程重入的時,就相當於進入上一次呼叫的狀態

什麼是多進程?

同一個時間裡,同一個電腦系統中如果允許兩個或兩個以上的進程處於運作狀態,這就是多進程多開一個進程,多分配一份資源,進程間通訊不方便

什麼是多執行緒?

執行緒就是把一個行程分成很多片,每一片都可以是獨立的流程,與多行程的差別是只會使用一個行程的資源,執行緒間可以通訊

多個概念之間的差異?

  • 單一行程單執行緒:一個人在一個桌上吃菜

  • 單一行程多執行緒:多個人在一個桌子上吃菜

  • 多行程單執行緒:多個人每個人在自己桌上吃菜

# #同步阻塞模型

多進程:最早的伺服器端程式都是透過多進程,多執行緒來解決並發IO的問題一個請求創建一個進程,然後子進程進入循環同步堵塞地與客戶端連線進行交互,收發處理資料。

步驟

  • 建立一個socket

  • 進入while循環,阻塞在進程accept操作上,等待客戶端連線進入主進程在多進程模型下透過fork建立子進程。

多執行緒模式下可以建立子執行緒

子執行緒/執行緒建立成功後進入while循環,阻塞在recv呼叫上,等待客戶端向伺服器發送數據

收到資料以後伺服器程式進行處理然後使用send向客戶端發送回應

當客戶端連線關閉時,子行程/執行緒退出並銷毀所有資源。主行程/執行緒會回收掉此子程序/執行緒。

這中模型嚴重的依賴進程的數量解決並發問題。

啟動大量的進程會帶來額外的進程調度消耗

異步非阻塞模型

現在各種高並發非同步IO的伺服器程式都是基於epoll實作的

IO複用非同步非阻塞程式使用經典的Reactor模型,Reactor顧名思義就是反應器的意思,它本身不處理任何資料收發。只是可以監視一個socket句柄的事件變化。

Reactor模型:

- add:添加一个socket到reactor
- set:修改socket对应的事件,如可读可写
- del:从reactor中移除
- callback:事件发生后回掉指定的函数

nginx:多執行緒Reactor

swoole:多執行緒Reactor 多進程worker

# php並發程式設計實戰


  • 1.php的swoole擴充、平行、高效能網路通訊引擎,使用純c語言編寫提供了php語言的非同步多線程伺服器,非同步tcp/udp網路客戶端,非同步mysql,異步redis,資料庫連線池,AsyncTask,訊息佇列,毫秒定時器,非同步檔案讀寫,非同步dns查詢。


  • 2.除了非同步IO的支援之外,swoole為php多進程的模式設計了多個並發資料結構和IPC通訊機制,可以大幅簡化多執行緒並發程式設計的工作

  • 3.swoole2.0支援了類似Go語言的協程,可以使用完全同步的程式碼實作非同步程式

  • 4.訊息佇列

  • 5.套用解耦

  • 場景說明:使用者下單後,訂單系統需要通知庫存系統。

  • 假如庫存系統無法訪問,則訂單減庫存將失敗,從而導致訂單失敗

  • ##訂單系統跟庫存系統解耦
  • 引用隊列
  • 用戶下單後,訂單系統完成持久化處理,將訊息寫入訊息佇列,並回傳用戶訂單下單成功
  • 訂閱下單的消息,採用拉/推的方式,獲取下單信息,庫存系統根據下單信息,進行庫存操作
  • #6.流量削峰應用場景:秒殺活動,流量瞬間激增,伺服器壓力大用戶發起請求後,伺服器接收後,先寫入訊息佇列。如果訊息佇列長度超多最大值,則直接報錯或提示使用者 控制請求量,緩解高流量
  • 7.日志处理 应用场景:解决大量日志的传输 日志采集程序将程序写入消息队列,然后通过日志处理程序的订阅消费日志。

  • 8.消息通讯 聊天室

  • 9.常见消息队列产品 kafka,ActiveMQ,ZeroMQ,RabbitMQ,Redis等 php的异步 消息队列

  • 10.接口的并发请求 curl_multi_init

mysql缓存层的优化


1.什么是数据库缓存

mysql等一些常见的关系型数据库的数据都存储在磁盘当中,在高并发场景下,业务应用对mysql产生的增删,改,查的操作造成巨大的I/O开销和查询压力,这无疑对数据库和服务器都是一种巨大的压力,为了解决此类问题,缓存数据的概念应运而生。

  • 极大的解决数据库服务器的压力

  • 提高应用数据的响应速度

常见的缓存形式:内存缓存和文件缓存

2.为什么要使用数据库缓存

  • 缓存数据是为了让客户端很少甚至不访问数据库服务器进行数据的查询,高并发下,能最大程序地降低对数据库服务器的访问压力。

  • 用户请求-》数据查询-》连接数据库服务器并查询数据-》将数据缓存起来(html,内存,json,序列化数据)-》显示给客户端

  • 缓存方式的选择

  • 缓存场景的选择

  • 缓存数据的实时性

  • 缓存数据的稳定性

3.使用mysql查询缓存

  • 启用mysql查询缓存

  • 极大的降低cpu使用率

  • query_cache_type查询缓存类型,有0,1,2三个取值。0则不适用查询缓存。1表示始终使用查询缓存,2表示按需使用查询缓存。

query_cahce_type=1 select SQL_NO_CACHE * from my_table where condition; query_cache_type=2 select SQL_CACHE * from my_table where condition; query_cache_size

默认情况下query_cache_size为0,表示为查询缓存预留的内存为0,则无法使用查询缓存 SET GLOBAL query_cache_size = 134217728; 查询缓存可以看作是SQL文本和查询结果的映射 第二次查询的SQL和第一次查询的SQL完全相同,则会使用缓 SHOW STATUS LIKE ‘Qcache_hits’查看命中次数 表的结构和数据发生改变时,查询缓存中的数据不再有效

情理缓存:

  • FLUSH QUERY CACHE;//清理查询缓存内存碎片

  • RESET QUERY CACHE;//从查询缓存中移出所有查询

  • FLUSH TABLES;//关闭所有打开的表,同时该操作将会清空查询缓存中的内容

4.使用Memcache缓存

对于大型站点,如果没有中间缓存层,当流量打入数据库层时,即便有之前的几层为我们挡住一部分流量,但是在大并发的情况下,还是会有大量请求涌入数据库层,这样对于数据库服务器的压力冲击很大,响应速度也会下降,因此添加中间缓存层很有必要。

memcache是一套分布式的高速缓存系统,由liveJournal的BrandFitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。 memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像,视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存,然后从内存中读取,从而大大提高读取速度。

工作流程:先检查客户端的请求数据是否在memcache中,如有,直接把请求数据返回,不再对数据库进行任何操作;如果请求的数据不在memcache中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到memcached中。

通用缓存机制:用查询的方法名+参数作为查询时的key,value对中的key值

5.使用Redis缓存

与memcache的区别:

  • 性能相差不大

  • redis在2.0版本后增加了自己的VM特性,突破物理内存的限制,memcache可以修改最大可用内存,采用LRU算法

  • redis依赖客户端来实现分布式读写

  • memcache本身没有数据冗余机制

  • redis支持(快照,aof)依赖快照进行持久化aof增强了可靠性的同时,对性能有所影响

  • redis用户数据量较小的高性能操作和运算上

  • memcache用于在动态系统中减少数据库负载,提升性能;适合做缓存提高性能。

  • 可用于存储其他数据:session,session_set_save_handler

mysql資料層的最佳化


  • #資料表資料型別最佳化:int,smallint.,bigint,enum, ip儲存使用int型別ip2long轉換存入

  • 索引不是越多越好,在適當的欄位上建立適當的索引

  • 符合索引的前綴原則

  • like查詢%的問題

  • 全表掃描最佳化

  • or條件索引使用情況

  • 字串類型索引失效的問題

  • 優化查詢資料過程中的資料訪問,使用limit,盡量不要使用*,變得複雜為簡單,切分查詢,分解關聯查詢*

  • #優化特定類型查詢語句,優化count(),優化關聯查詢語句,優化子查詢,優化group by和distinct,優化limit和union

  • 儲存引擎的最佳化:盡量使用innodb

  • 資料庫表結構的最佳化:分區操作(對使用者透明)partion,分庫分錶(水平拆分,垂直拆分做副表)

  • 資料庫伺服器架構的最佳化:主從複製,讀寫分離,雙主熱備,負載平衡(lvs實現負載平衡,MyCat資料庫中間件實現負載平衡)

#
陳述:
本文轉載於:github.io。如有侵權,請聯絡admin@php.cn刪除