導航:首頁 > 編程語言 > php提高並發

php提高並發

發布時間:2022-12-31 19:34:15

1. php怎麼處理高並發

以下內容轉載自徐漢彬大牛的博客億級Web系統搭建——單機到分布式集群

當一個Web系統從日訪問量10萬逐步增長到1000萬,甚至超過1億的過程中,Web系統承受的壓力會越來越大,在這個過程中,我們會遇到很多的問題。為了解決這些性能壓力帶來問題,我們需要在Web系統架構層面搭建多個層次的緩存機制。在不同的壓力階段,我們會遇到不同的問題,通過搭建不同的服務和架構來解決。

Web負載均衡

Web負載均衡(Load Balancing),簡單地說就是給我們的伺服器集群分配「工作任務」,而採用恰當的分配方式,對於保護處於後端的Web伺服器來說,非常重要。

負載均衡的策略有很多,我們從簡單的講起哈。

1.HTTP重定向

當用戶發來請求的時候,Web伺服器通過修改HTTP響應頭中的Location標記來返回一個新的url,然後瀏覽器再繼續請求這個新url,實際上就是頁面重定向。通過重定向,來達到「負載均衡」的目標。例如,我們在下載PHP源碼包的時候,點擊下載鏈接時,為了解決不同國家和地域下載速度的問題,它會返回一個離我們近的下載地址。重定向的HTTP返回碼是302

這個重定向非常容易實現,並且可以自定義各種策略。但是,它在大規模訪問量下,性能不佳。而且,給用戶的體驗也不好,實際請求發生重定向,增加了網路延時。

2. 反向代理負載均衡

反向代理服務的核心工作主要是轉發HTTP請求,扮演了瀏覽器端和後台Web伺服器中轉的角色。因為它工作在HTTP層(應用層),也就是網路七層結構中的第七層,因此也被稱為「七層負載均衡」。可以做反向代理的軟體很多,比較常見的一種是Nginx。

Nginx是一種非常靈活的反向代理軟體,可以自由定製化轉發策略,分配伺服器流量的權重等。反向代理中,常見的一個問題,就是Web伺服器存儲的session數據,因為一般負載均衡的策略都是隨機分配請求的。同一個登錄用戶的請求,無法保證一定分配到相同的Web機器上,會導致無法找到session的問題。

解決方案主要有兩種:

1.配置反向代理的轉發規則,讓同一個用戶的請求一定落到同一台機器上(通過分析cookie),復雜的轉發規則將會消耗更多的CPU,也增加了代理伺服器的負擔。

2.將session這類的信息,專門用某個獨立服務來存儲,例如redis/memchache,這個方案是比較推薦的。

反向代理服務,也是可以開啟緩存的,如果開啟了,會增加反向代理的負擔,需要謹慎使用。這種負載均衡策略實現和部署非常簡單,而且性能表現也比較好。但是,它有「單點故障」的問題,如果掛了,會帶來很多的麻煩。而且,到了後期Web伺服器繼續增加,它本身可能成為系統的瓶頸。

3. IP負載均衡

IP負載均衡服務是工作在網路層(修改IP)和傳輸層(修改埠,第四層),比起工作在應用層(第七層)性能要高出非常多。原理是,他是對IP層的數據包的IP地址和埠信息進行修改,達到負載均衡的目的。這種方式,也被稱為「四層負載均衡」。常見的負載均衡方式,是LVS(Linux Virtual Server,Linux虛擬服務),通過IPVS(IP Virtual Server,IP虛擬服務)來實現。

在負載均衡伺服器收到客戶端的IP包的時候,會修改IP包的目標IP地址或埠,然後原封不動地投遞到內部網路中,數據包會流入到實際Web伺服器。實際伺服器處理完成後,又會將數據包投遞回給負載均衡伺服器,它再修改目標IP地址為用戶IP地址,最終回到客戶端。

上述的方式叫LVS-NAT,除此之外,還有LVS-RD(直接路由),LVS-TUN(IP隧道),三者之間都屬於LVS的方式,但是有一定的區別,篇幅問題,不贅敘。

IP負載均衡的性能要高出Nginx的反向代理很多,它只處理到傳輸層為止的數據包,並不做進一步的組包,然後直接轉發給實際伺服器。不過,它的配置和搭建比較復雜。

4. DNS負載均衡

DNS(Domain Name System)負責域名解析的服務,域名url實際上是伺服器的別名,實際映射是一個IP地址,解析過程,就是DNS完成域名到IP的映射。而一個域名是可以配置成對應多個IP的。因此,DNS也就可以作為負載均衡服務。

這種負載均衡策略,配置簡單,性能極佳。但是,不能自由定義規則,而且,變更被映射的IP或者機器故障時很麻煩,還存在DNS生效延遲的問題。

5. DNS/GSLB負載均衡

我們常用的CDN(Content Delivery Network,內容分發網路)實現方式,其實就是在同一個域名映射為多IP的基礎上更進一步,通過GSLB(Global Server Load Balance,全局負載均衡)按照指定規則映射域名的IP。一般情況下都是按照地理位置,將離用戶近的IP返回給用戶,減少網路傳輸中的路由節點之間的跳躍消耗。

「向上尋找」,實際過程是LDNS(Local DNS)先向根域名服務(Root Name Server)獲取到頂級根的Name Server(例如.com的),然後得到指定域名的授權DNS,然後再獲得實際伺服器IP。

CDN在Web系統中,一般情況下是用來解決大小較大的靜態資源(html/Js/Css/圖片等)的載入問題,讓這些比較依賴網路下載的內容,盡可能離用戶更近,提升用戶體驗。

例如,我訪問了一張imgcache.gtimg.cn上的圖片(騰訊的自建CDN,不使用qq.com域名的原因是防止http請求的時候,帶上了多餘的cookie信息),我獲得的IP是183.60.217.90。

這種方式,和前面的DNS負載均衡一樣,不僅性能極佳,而且支持配置多種策略。但是,搭建和維護成本非常高。互聯網一線公司,會自建CDN服務,中小型公司一般使用第三方提供的CDN。

Web系統的緩存機制的建立和優化

剛剛我們講完了Web系統的外部網路環境,現在我們開始關注我們Web系統自身的性能問題。我們的Web站點隨著訪問量的上升,會遇到很多的挑戰,解決這些問題不僅僅是擴容機器這么簡單,建立和使用合適的緩存機制才是根本。

最開始,我們的Web系統架構可能是這樣的,每個環節,都可能只有1台機器。

我們從最根本的數據存儲開始看哈。

一、 MySQL資料庫內部緩存使用

MySQL的緩存機制,就從先從MySQL內部開始,下面的內容將以最常見的InnoDB存儲引擎為主。

1. 建立恰當的索引

最簡單的是建立索引,索引在表數據比較大的時候,起到快速檢索數據的作用,但是成本也是有的。首先,佔用了一定的磁碟空間,其中組合索引最突出,使用需要謹慎,它產生的索引甚至會比源數據更大。其次,建立索引之後的數據insert/update/delete等操作,因為需要更新原來的索引,耗時會增加。當然,實際上我們的系統從總體來說,是以select查詢操作居多,因此,索引的使用仍然對系統性能有大幅提升的作用。

2. 資料庫連接線程池緩存

如果,每一個資料庫操作請求都需要創建和銷毀連接的話,對資料庫來說,無疑也是一種巨大的開銷。為了減少這類型的開銷,可以在MySQL中配置thread_cache_size來表示保留多少線程用於復用。線程不夠的時候,再創建,空閑過多的時候,則銷毀。

其實,還有更為激進一點的做法,使用pconnect(資料庫長連接),線程一旦創建在很長時間內都保持著。但是,在訪問量比較大,機器比較多的情況下,這種用法很可能會導致「資料庫連接數耗盡」,因為建立連接並不回收,最終達到資料庫的max_connections(最大連接數)。因此,長連接的用法通常需要在CGI和MySQL之間實現一個「連接池」服務,控制CGI機器「盲目」創建連接數。

建立資料庫連接池服務,有很多實現的方式,PHP的話,我推薦使用swoole(PHP的一個網路通訊拓展)來實現。

3. Innodb緩存設置(innodb_buffer_pool_size)

innodb_buffer_pool_size這是個用來保存索引和數據的內存緩存區,如果機器是MySQL獨占的機器,一般推薦為機器物理內存的80%。在取表數據的場景中,它可以減少磁碟IO。一般來說,這個值設置越大,cache命中率會越高。

4. 分庫/分表/分區。

MySQL資料庫表一般承受數據量在百萬級別,再往上增長,各項性能將會出現大幅度下降,因此,當我們預見數據量會超過這個量級的時候,建議進行分庫/分表/分區等操作。最好的做法,是服務在搭建之初就設計為分庫分表的存儲模式,從根本上杜絕中後期的風險。不過,會犧牲一些便利性,例如列表式的查詢,同時,也增加了維護的復雜度。不過,到了數據量千萬級別或者以上的時候,我們會發現,它們都是值得的。

二、 MySQL資料庫多台服務搭建

1台MySQL機器,實際上是高風險的單點,因為如果它掛了,我們Web服務就不可用了。而且,隨著Web系統訪問量繼續增加,終於有一天,我們發現1台MySQL伺服器無法支撐下去,我們開始需要使用更多的MySQL機器。當引入多台MySQL機器的時候,很多新的問題又將產生。

1. 建立MySQL主從,從庫作為備份

這種做法純粹為了解決「單點故障」的問題,在主庫出故障的時候,切換到從庫。不過,這種做法實際上有點浪費資源,因為從庫實際上被閑著了。

2. MySQL讀寫分離,主庫寫,從庫讀。

兩台資料庫做讀寫分離,主庫負責寫入類的操作,從庫負責讀的操作。並且,如果主庫發生故障,仍然不影響讀的操作,同時也可以將全部讀寫都臨時切換到從庫中(需要注意流量,可能會因為流量過大,把從庫也拖垮)。

3. 主主互備。

兩台MySQL之間互為彼此的從庫,同時又是主庫。這種方案,既做到了訪問量的壓力分流,同時也解決了「單點故障」問題。任何一台故障,都還有另外一套可供使用的服務。

不過,這種方案,只能用在兩台機器的場景。如果業務拓展還是很快的話,可以選擇將業務分離,建立多個主主互備。

三、 MySQL資料庫機器之間的數據同步

每當我們解決一個問題,新的問題必然誕生在舊的解決方案上。當我們有多台MySQL,在業務高峰期,很可能出現兩個庫之間的數據有延遲的場景。並且,網路和機器負載等,也會影響數據同步的延遲。我們曾經遇到過,在日訪問量接近1億的特殊場景下,出現,從庫數據需要很多天才能同步追上主庫的數據。這種場景下,從庫基本失去效用了。

於是,解決同步問題,就是我們下一步需要關注的點。

1. MySQL自帶多線程同步

MySQL5.6開始支持主庫和從庫數據同步,走多線程。但是,限制也是比較明顯的,只能以庫為單位。MySQL數據同步是通過binlog日誌,主庫寫入到binlog日誌的操作,是具有順序的,尤其當SQL操作中含有對於表結構的修改等操作,對於後續的SQL語句操作是有影響的。因此,從庫同步數據,必須走單進程。

2. 自己實現解析binlog,多線程寫入。

以資料庫的表為單位,解析binlog多張表同時做數據同步。這樣做的話,的確能夠加快數據同步的效率,但是,如果表和表之間存在結構關系或者數據依賴的話,則同樣存在寫入順序的問題。這種方式,可用於一些比較穩定並且相對獨立的數據表。

國內一線互聯網公司,大部分都是通過這種方式,來加快數據同步效率。還有更為激進的做法,是直接解析binlog,忽略以表為單位,直接寫入。但是這種做法,實現復雜,使用范圍就更受到限制,只能用於一些場景特殊的資料庫中(沒有表結構變更,表和表之間沒有數據依賴等特殊表)。

四、 在Web伺服器和資料庫之間建立緩存

實際上,解決大訪問量的問題,不能僅僅著眼於資料庫層面。根據「二八定律」,80%的請求只關注在20%的熱點數據上。因此,我們應該建立Web伺服器和資料庫之間的緩存機制。這種機制,可以用磁碟作為緩存,也可以用內存緩存的方式。通過它們,將大部分的熱點數據查詢,阻擋在資料庫之前。

1. 頁面靜態化

用戶訪問網站的某個頁面,頁面上的大部分內容在很長一段時間內,可能都是沒有變化的。例如一篇新聞報道,一旦發布幾乎是不會修改內容的。這樣的話,通過CGI生成的靜態html頁面緩存到Web伺服器的磁碟本地。除了第一次,是通過動態CGI查詢資料庫獲取之外,之後都直接將本地磁碟文件返回給用戶。

在Web系統規模比較小的時候,這種做法看似完美。但是,一旦Web系統規模變大,例如當我有100台的Web伺服器的時候。那樣這些磁碟文件,將會有100份,這個是資源浪費,也不好維護。這個時候有人會想,可以集中一台伺服器存起來,呵呵,不如看看下面一種緩存方式吧,它就是這樣做的。

2. 單台內存緩存

通過頁面靜態化的例子中,我們可以知道將「緩存」搭建在Web機器本機是不好維護的,會帶來更多問題(實際上,通過PHP的apc拓展,可通過Key/value操作Web伺服器的本機內存)。因此,我們選擇搭建的內存緩存服務,也必須是一個獨立的服務。

內存緩存的選擇,主要有redis/memcache。從性能上說,兩者差別不大,從功能豐富程度上說,Redis更勝一籌。

3. 內存緩存集群

當我們搭建單台內存緩存完畢,我們又會面臨單點故障的問題,因此,我們必須將它變成一個集群。簡單的做法,是給他增加一個slave作為備份機器。但是,如果請求量真的很多,我們發現cache命中率不高,需要更多的機器內存呢?因此,我們更建議將它配置成一個集群。例如,類似redis cluster。

Redis cluster集群內的Redis互為多組主從,同時每個節點都可以接受請求,在拓展集群的時候比較方便。客戶端可以向任意一個節點發送請求,如果是它的「負責」的內容,則直接返回內容。否則,查找實際負責Redis節點,然後將地址告知客戶端,客戶端重新請求。

對於使用緩存服務的客戶端來說,這一切是透明的。

內存緩存服務在切換的時候,是有一定風險的。從A集群切換到B集群的過程中,必須保證B集群提前做好「預熱」(B集群的內存中的熱點數據,應該盡量與A集群相同,否則,切換的一瞬間大量請求內容,在B集群的內存緩存中查找不到,流量直接沖擊後端的資料庫服務,很可能導致資料庫宕機)。

4. 減少資料庫「寫」

上面的機制,都實現減少資料庫的「讀」的操作,但是,寫的操作也是一個大的壓力。寫的操作,雖然無法減少,但是可以通過合並請求,來起到減輕壓力的效果。這個時候,我們就需要在內存緩存集群和資料庫集群之間,建立一個修改同步機制。

先將修改請求生效在cache中,讓外界查詢顯示正常,然後將這些sql修改放入到一個隊列中存儲起來,隊列滿或者每隔一段時間,合並為一個請求到資料庫中更新資料庫。

除了上述通過改變系統架構的方式提升寫的性能外,MySQL本身也可以通過配置參數innodb_flush_log_at_trx_commit來調整寫入磁碟的策略。如果機器成本允許,從硬體層面解決問題,可以選擇老一點的RAID(Rendant Arrays of independent Disks,磁碟列陣)或者比較新的SSD(Solid State Drives,固態硬碟)。

5. NoSQL存儲

不管資料庫的讀還是寫,當流量再進一步上漲,終會達到「人力有窮時」的場景。繼續加機器的成本比較高,並且不一定可以真正解決問題的時候。這個時候,部分核心數據,就可以考慮使用NoSQL的資料庫。NoSQL存儲,大部分都是採用key-value的方式,這里比較推薦使用上面介紹過Redis,Redis本身是一個內存cache,同時也可以當做一個存儲來使用,讓它直接將數據落地到磁碟。

這樣的話,我們就將資料庫中某些被頻繁讀寫的數據,分離出來,放在我們新搭建的Redis存儲集群中,又進一步減輕原來MySQL資料庫的壓力,同時因為Redis本身是個內存級別的Cache,讀寫的性能都會大幅度提升。

國內一線互聯網公司,架構上採用的解決方案很多是類似於上述方案,不過,使用的cache服務卻不一定是Redis,他們會有更豐富的其他選擇,甚至根據自身業務特點開發出自己的NoSQL服務。

6. 空節點查詢問題

當我們搭建完前面所說的全部服務,認為Web系統已經很強的時候。我們還是那句話,新的問題還是會來的。空節點查詢,是指那些資料庫中根本不存在的數據請求。例如,我請求查詢一個不存在人員信息,系統會從各級緩存逐級查找,最後查到到資料庫本身,然後才得出查找不到的結論,返回給前端。因為各級cache對它無效,這個請求是非常消耗系統資源的,而如果大量的空節點查詢,是可以沖擊到系統服務的。

在我曾經的工作經歷中,曾深受其害。因此,為了維護Web系統的穩定性,設計適當的空節點過濾機制,非常有必要。

我們當時採用的方式,就是設計一張簡單的記錄映射表。將存在的記錄存儲起來,放入到一台內存cache中,這樣的話,如果還有空節點查詢,則在緩存這一層就被阻擋了。

異地部署(地理分布式)

完成了上述架構建設之後,我們的系統是否就已經足夠強大了呢?答案當然是否定的哈,優化是無極限的。Web系統雖然表面上看,似乎比較強大了,但是給予用戶的體驗卻不一定是最好的。因為東北的同學,訪問深圳的一個網站服務,他還是會感到一些網路距離上的慢。這個時候,我們就需要做異地部署,讓Web系統離用戶更近。

一、 核心集中與節點分散

有玩過大型網游的同學都會知道,網游是有很多個區的,一般都是按照地域來分,例如廣東專區,北京專區。如果一個在廣東的玩家,去北京專區玩,那麼他會感覺明顯比在廣東專區卡。實際上,這些大區的名稱就已經說明了,它的伺服器所在地,所以,廣東的玩家去連接地處北京的伺服器,網路當然會比較慢。

當一個系統和服務足夠大的時候,就必須開始考慮異地部署的問題了。讓你的服務,盡可能離用戶更近。我們前面已經提到了Web的靜態資源,可以存放在CDN上,然後通過DNS/GSLB的方式,讓靜態資源的分散「全國各地」。但是,CDN只解決的靜態資源的問題,沒有解決後端龐大的系統服務還只集中在某個固定城市的問題。

這個時候,異地部署就開始了。異地部署一般遵循:核心集中,節點分散。

·核心集中:實際部署過程中,總有一部分的數據和服務存在不可部署多套,或者部署多套成本巨大。而對於這些服務和數據,就仍然維持一套,而部署地點選擇一個地域比較中心的地方,通過網路內部專線來和各個節點通訊。

·節點分散:將一些服務部署為多套,分布在各個城市節點,讓用戶請求盡可能選擇近的節點訪問服務。

例如,我們選擇在上海部署為核心節點,北京,深圳,武漢,上海為分散節點(上海自己本身也是一個分散節點)。我們的服務架構如圖:

需要補充一下的是,上圖中上海節點和核心節點是同處於一個機房的,其他分散節點各自獨立機房。
國內有很多大型網游,都是大致遵循上述架構。它們會把數據量不大的用戶核心賬號等放在核心節點,而大部分的網游數據,例如裝備、任務等數據和服務放在地區節點里。當然,核心節點和地域節點之間,也有緩存機制。

二、 節點容災和過載保護

節點容災是指,某個節點如果發生故障時,我們需要建立一個機制去保證服務仍然可用。毫無疑問,這里比較常見的容災方式,是切換到附近城市節點。假如系統的天津節點發生故障,那麼我們就將網路流量切換到附近的北京節點上。考慮到負載均衡,可能需要同時將流量切換到附近的幾個地域節點。另一方面,核心節點自身也是需要自己做好容災和備份的,核心節點一旦故障,就會影響全國服務。

過載保護,指的是一個節點已經達到最大容量,無法繼續接接受更多請求了,系統必須有一個保護的機制。一個服務已經滿負載,還繼續接受新的請求,結果很可能就是宕機,影響整個節點的服務,為了至少保障大部分用戶的正常使用,過載保護是必要的。

解決過載保護,一般2個方向:

·拒絕服務,檢測到滿負載之後,就不再接受新的連接請求。例如網游登入中的排隊。

·分流到其他節點。這種的話,系統實現更為復雜,又涉及到負載均衡的問題。

小結

Web系統會隨著訪問規模的增長,漸漸地從1台伺服器可以滿足需求,一直成長為「龐然大物」的大集群。而這個Web系統變大的過程,實際上就是我們解決問題的過程。在不同的階段,解決不同的問題,而新的問題又誕生在舊的解決方案之上。

系統的優化是沒有極限的,軟體和系統架構也一直在快速發展,新的方案解決了老的問題,同時也帶來新的挑戰。

2. php解決高並發

<?php

2 //優化方案1:將庫存欄位number欄位設為unsigned,當庫存為0時,因為欄位不能為負數,將會返回false

3 include('./mysql.php');

4 $username = 'wang'.rand(0,1000);

5 //生成唯一訂單

6 function build_order_no(){

7  return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);

8 }

9 //記錄日誌

10 function insertLog($event,$type=0,$username){

11    global $conn;

12    $sql="insert into ih_log(event,type,usernma)

13    values('$event','$type','$username')";

14    return mysqli_query($conn,$sql);

15 }

16 function insertOrder($order_sn,$user_id,$goods_id,$sku_id,$price,$username,$number)

17 {

18      global $conn;

19      $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price,username,number)

20      values('$order_sn','$user_id','$goods_id','$sku_id','$price','$username','$number')";

21      return  mysqli_query($conn,$sql);

22 }

23 //模擬下單操作

24 //庫存是否大於0

25 $sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id' ";

26 $rs=mysqli_query($conn,$sql);

27 $row = $rs->fetch_assoc();

28  if($row['number']>0){//高並發下會導致超賣

29      if($row['number']<$number){

30        return insertLog('庫存不夠',3,$username);

31      }

32      $order_sn=build_order_no();

33      //庫存減少

34      $sql="update ih_store set number=number-{$number} where sku_id='$sku_id' and number>0";

35      $store_rs=mysqli_query($conn,$sql);

36      if($store_rs){

37          //生成訂單

38          insertOrder($order_sn,$user_id,$goods_id,$sku_id,$price,$username,$number);

39          insertLog('庫存減少成功',1,$username);

40      }else{

41          insertLog('庫存減少失敗',2,$username);

42      }

43  }else{

44      insertLog('庫存不夠',3,$username);

45  }

46 ?>

3. php處理高並發能力強嗎

強。PHP可以解決高並發,也不能說適合,只是相對其他語言弱一些,Java和Go,不過PHP7出來以後PHP性能得到了很大的提升,性能與其它的語言之間的差距不是很大了,甚至比有的語言更快。

4. PHP做游戲服務端可以達到多少並發

PHP做游戲服務端可以達到並發十萬。

包括使用緩存加速工具,經過優化後web性能有明顯的提高。這是我用壓力測試工具測試的並發數量。

自己下載個軟體來做下壓力測試才能得出較准確的數據,使用nginx更多是用來支持動態頁面,而且還可以做代理和一些限制設置,但論功能而言比apache更廣, apache 更擅長於對靜態頁面的解釋,穩定且比nginx配置更為簡單。

2012年數據:

2012上半年,中國游戲市場(包括PC網路游戲市場、移動網路游戲市場、PC單機游戲市場等)實際銷售收入248.4億元人民幣,比2011上半年增長了18.5%。

2012上半年,中國PC網路游戲市場實際銷售收入(包括了客戶端網游、網頁游戲、社交遊戲及游戲平台的市場銷售額)為235.5億元人民幣,比2011上半年增長了16.9%。

2012上半年,中國自主研發的PC網路游戲市場實際銷售收入為168.6億元人民幣,占網路游戲市場實際銷售收入的71.6%,較2011年同期的63%左右有明顯提升。

5. PHP如何使用文件鎖解決高並發問題

<?php
//連接資料庫
$con=mysqli_connect("192.168.2.186","root","root","test");
//查詢商品數量是否大於0,大於0才能下單,並減少庫存
$fp = fopen("lock.txt", "r");
//加鎖
if(flock($fp,LOCK_EX))
{
$res=mysqli_fetch_assoc(mysqli_query($con,'SELECT total FROM shop WHERE id=1 LIMIT 1'));
if($res['total']>0){mysqli_query($con,'UPDATE shop SET total=total-1 WHERE id=1');}
//執行完成解鎖
flock($fp,LOCK_UN);
}
//關閉文件
fclose($fp);
unset($res);
mysqli_close($con);
?>

6. 為什麼這么多人覺得運行PHP的並發可以上1000

關鍵還在於nginx+php+fastcgi搭建完或搭建過程中的一些優化。

7. 用PHP 編寫支持高並發的網站,需要做什麼處理

PHP支持高並發很多時候不是光靠PHP的。具體根據你的業務邏輯,下面列一些例子:

  1. 資料庫層面,表結構必須合理,盡量避免聯表查詢,能夠縮短處理時間

  2. 配置額外圖片伺服器或使用cdn,降低伺服器壓力

  3. 使用緩存處理類似搶購、投票等高並發請求,如redis。

  4. 消息隊列處理耗時較久的請求,如發郵件等

  5. 必要時使用多台伺服器,後台使用一台,前台可將高並發的業務與其他分開,避免因其中一個業務導致全部崩潰

8. php 高並發解決思路解決方案

php 高並發解決思路解決方案,如何應對網站大流量高並發情況。本文為大家總結了常用的處理方式,但不是細節,後續一系列細節教程給出。希望大家喜歡。

一 高並發的概念

在互聯網時代,並發,高並發通常是指並發訪問。也就是在某個時間點,有多少個訪問同時到來。

二 高並發架構相關概念

1、QPS (每秒查詢率) : 每秒鍾請求或者查詢的數量,在互聯網領域,指每秒響應請求數(指 HTTP 請求)

2、PV(Page View):綜合瀏覽量,即頁面瀏覽量或者點擊量,一個訪客在 24 小時內訪問的頁面數量

--註:同一個人瀏覽你的網站的同一頁面,只記做一次 pv

3、吞吐量(fetches/sec) :單位時間內處理的請求數量 (通常由 QPS 和並發數決定)

4、響應時間:從請求發出到收到響應花費的時間

5、獨立訪客(UV):一定時間范圍內,相同訪客多次訪問網站,只計算為 1 個獨立訪客

6、帶寬:計算帶寬需關注兩個指標,峰值流量和頁面的平均大小

7、日網站帶寬: PV/統計時間(換算到秒) * 平均頁面大小(kb)* 8

三 需要注意點:

1、QPS 不等於並發連接數(QPS 是每秒 HTTP 請求數量,並發連接數是系統同時處理的請求數量)

2、峰值每秒請求數(QPS)= (總 PV 數*80%)/ (六小時秒數*20%)【代表 80%的訪問量都集中在 20%的時間內】

3、壓力測試: 測試能承受的最大並發數 以及測試最大承受的 QPS 值

4、常用的性能測試工具【ab,wrk,httpload,Web Bench,Siege,Apache JMeter】

四 優化

1、當 QPS 小於 50 時

優化方案:為一般小型網站,不用考慮優化

2、當 QPS 達到 100 時,遇到數據查詢瓶頸

優化方案: 資料庫緩存層,資料庫的負載均衡

3、當 QPS 達到 800 時, 遇到帶寬瓶頸

優化方案:CDN 加速,負載均衡

4、當 QPS 達到 1000 時

優化方案: 做 html 靜態緩存

5、當 QPS 達到 2000 時

優化方案: 做業務分離,分布式存儲

五、高並發解決方案案例:

1、流量優化

防盜鏈處理(去除惡意請求)

2、前端優化

(1) 減少 HTTP 請求[將 css,js 等合並]

(2) 添加非同步請求(先不將所有數據都展示給用戶,用戶觸發某個事件,才會非同步請求數據)

(3) 啟用瀏覽器緩存和文件壓縮

(4) CDN 加速

(5) 建立獨立的圖片伺服器(減少 I/O)

3、服務端優化

(1) 頁面靜態化

(2) 並發處理

(3) 隊列處理

4、資料庫優化

(1) 資料庫緩存

(2) 分庫分表,分區

(3) 讀寫分離

(4) 負載均衡

5、web 伺服器優化

(1) nginx 反向代理實現負載均衡

(2) lvs 實現負載均衡

9. php如何處理高並發

並發讀方面,多用內存緩存。減少資料庫查詢次數。多加幾台資料庫從伺服器。
並發寫方面,數據先走內存隊列

閱讀全文

與php提高並發相關的資料

熱點內容
dvd光碟存儲漢子演算法 瀏覽:757
蘋果郵件無法連接伺服器地址 瀏覽:962
phpffmpeg轉碼 瀏覽:671
長沙好玩的解壓項目 瀏覽:142
專屬學情分析報告是什麼app 瀏覽:564
php工程部署 瀏覽:833
android全屏透明 瀏覽:736
阿里雲伺服器已開通怎麼辦 瀏覽:803
光遇為什麼登錄時伺服器已滿 瀏覽:302
PDF分析 瀏覽:484
h3c光纖全工半全工設置命令 瀏覽:143
公司法pdf下載 瀏覽:381
linuxmarkdown 瀏覽:350
華為手機怎麼多選文件夾 瀏覽:683
如何取消命令方塊指令 瀏覽:349
風翼app為什麼進不去了 瀏覽:778
im4java壓縮圖片 瀏覽:362
數據查詢網站源碼 瀏覽:150
伊克塞爾文檔怎麼進行加密 瀏覽:892
app轉賬是什麼 瀏覽:163