首頁  >  文章  >  php框架  >  詳細整理swoole知識點(總結分享)

詳細整理swoole知識點(總結分享)

WBOY
WBOY轉載
2022-02-28 18:13:523414瀏覽

這篇文章為大家帶來了關於swoole的相關知識,其中包括了fastcgi請求到swoole master進程去分發到子進程,但是不會像php-fpm的子進程使用完後退出等相關問題,希望對大家有幫助。

詳細整理swoole知識點(總結分享)

推薦學習:swoole影片教學

#swoole##swoole

聊天室流程講解

#整個聊天室流程為:

- 使用者http介面登入獲得授權

- 透過授權請求http介面取得好友清單,不同好友的最後一則未讀訊息以及未讀取訊息數(用於首頁顯示)

- 透過授權請求獲得群組列表(群組訊息為了節省儲存空間沒有做已讀未讀)

#- 建立ws連結

- 註冊斷線重連機制,觸發close事件時,重連ws

- 建立ping定時器,每隔30秒進行一次ping

- 透過ws介面,取得所有未讀訊息,客戶端進行處理,推送到通知列等

#-接收新訊息推播,並顯示到訊息清單

#- 點擊進入某個群組/好友訊息介面時,自動取得最新n條訊息,用戶上拉時繼續取得n條

#行模式運

cgi 協定模式

cgi模式通用網關介面(Common Gateway Interface),它允許web伺服器通過特定的協議與應用程式通訊, 呼叫原理大概為:

#  

使用者請求->Web伺服器接收請求->fork子程序 #  

呼叫程式/執行程式->程式回傳內容/程式呼叫結束->網頁伺服器接收內容->傳回給使用者   

由於每次使用者要求,都得fork建立進程呼叫一次程式,然後銷毀進程,所以效能較低###### ############fast-cgi 協定模式######################fast-cgi是cgi模式的升級版,它像是一個常駐型的cgi,只要開啟後,就可一直處理請求,不再需要結束進程, 呼叫原理大概為:#########  ###############web伺服器fast-cgi進程管理器初始化->預先fork n個進程########  ###

用戶請求->web伺服器接收請求->交給fast-cgi進程管理器->fast-cgi進程管理區接收,給其中一個空閒fast-cgi進程處理->處理完成,fast-cgi進程變為空閒狀態,等待下次請求->web伺服器接收內容->返回給用戶模組模式   

#模組模式

#apache php運行時,預設使用的是模組模式,它把php當作apache的模組隨apache啟動而啟動,接收到用戶請求時則直接透過呼叫mod_php模組進行處理,詳細內容可自行百度

##php- cli模式

php-cli模式屬於命令列模式,對於許多剛開始學php就開始wamp,wnmp的開發者來說是最陌生的一種運行模式

該模式不需要藉助其他程式,直接輸入php xx.php 就能執行php程式碼

#命令列模式和常規web模式明顯不一樣的是:

  • #* 沒有逾時時間

  • * 預設關閉buffer緩衝

  • * STDIN和STDOUT標準輸入/輸出/錯誤的使用

  • #* echo var_dump,phpinfo等輸出直接輸出到控制台

  • * 可使用的類別/函數不同

  • * php.ini配置的不同

php-fpm

PHP-FPM(FastCGI 進程管理器)用於取代PHP FastCGI 的大部分附加功能,對於高負載網站是非常有用的。

它的功能包括:

  • 支援平滑停止/啟動的高階進程管理功能;

  • 可以工作於不同的uid/gid/chroot 環境下,並監聽不同的連接埠和使用不同的php.ini 設定檔(可取代safe_mode 的設定);  

  • stdout 和 stderr 日誌記錄;  

  • 在發生意外狀況的時候能夠重新啟動並且快取被破壞的 opcode;  

  • 檔案上傳最佳化支援;

  • "慢日誌" - 記錄腳本(不僅記錄檔名,還記錄PHP backtrace 信息,可以使用ptrace或類似工具讀取和分析遠端進程的運行數據)運行所導致的異常緩慢;

  • fastcgi_finish_request() - 特殊功能:用於在請求完成和刷新資料後,繼續在背景執行耗時的工作(輸入視訊轉換、統計處理等);  

  • 動態/靜態子程序產生;  

  • 基本 SAPI 運作狀態資訊(類似Apache的 mod_status);  

  • 基於 php.ini 的設定檔。

工作原理:

它的工作原理大概為:

php-fpm啟動->產生n個fast-cgi協定處理進程->監聽一個連接埠等待任務

使用者請求->web伺服器接收請求->請求轉發給php-fpm->php-fpm交給一個空閒進程處理

->進程處理完成->php-fpm回傳給web伺服器->web伺服器接收資料->傳回給使用者

網路協定

#網路協定為電腦網路中進行資料交換而建立的規則,標準或約定的集合,所有的電腦/手機等網路設備通訊都得遵循網路協定.

網路協定依通訊的步驟,層級分割為7個層級,從上往下為:

  • 應用層  

  • 表示層#  

  • 會話層  

  • 傳輸層#  

  • 網路層  

  • 資料鏈結層  

  • 物理層

ip協定(網路層)

#ip協定是網際網路的基礎協定,它是目前最受歡迎的一種網路協定

#範圍

#IP的責任就是將資料從來源傳送到目的地。它不負責保證傳送可靠性,流控制,包順序和其它對於主機到主機協議來說很普通的服務。

介面

#這個協定由主機到主機協定調用,而此協定負責調用本地網路協定將封包傳送以下一個網關或目的主機。例如TCP可以呼叫IP協議,在呼叫時傳送目的位址和來源位址作為參數,IP形成封包並呼叫本地網路(協定)介面傳送封包。

操作

IP實作兩個基本功能:尋址和分段。 IP可以根據資料包包頭中包含的目的位址將資料包傳送到目的位址,在此過程中IP負責選擇傳送的道路,這種選擇道路稱為路由功能。如果有些網路內只能傳送小資料包,IP可以將資料包重新組裝並在標頭域內註明。 IP模組中包含這些基本功能,這些模組存在於網路中的每台主機和網關上,而且這些模組(特別在網關上)有路由選擇和其它服務功能。對IP來說,資料包之間沒有什麼聯繫,對IP不好說什麼連接或邏輯鏈路。

IP使用四個關鍵技術提供服務:服務類型,生存時間,選項和標頭校驗碼。服務類型指希望得到的服務品質。服務類型是一個參數集,這些參數是Internet能夠提供服務的代表。這種服務類型由網關使用,用於在特定的網絡,或用於下一個要經過的網絡,或是下一個要對這個資料包進行路由的網關上選擇實際的傳送參數。生存時間是資料包可以生存的時間上限。它由發送者設置,由經過路由的地方處理。如果未到達時生存時間為零,請拋棄此資料包。對於控制函數來說選項是重要的,但對於通常的通訊來說它沒有存在的必要。選項包括時間戳,安全和特殊路由。報頭校驗碼保證資料的正確傳輸。如果校驗出錯,拋棄整個資料包。

ip位址

###把資料從來源傳送到目的地時,需要有ip位址才能傳輸,現在ip位址分成ipv4和ipv6 兩種位址,現在最常見的就是ipv4位址,例如127.0.0.1(本機位址) 119.75.217.109(百度ip)#####################ip傳輸必須要有明確的ip位址,才能進行資料傳送###### ###

tcp(傳輸層)

#TCP(Transmission Control Protocol 傳輸控制協定)是一種面向連接的、可靠的、基於位元組流的傳輸層通訊協議,由IETF的RFC 793定義。在簡化的電腦網路OSI模型中,它完成第四層傳輸層所指定的功能,用戶資料封包協定(UDP)是同一層內 另一個重要的傳輸協定。在因特網協定族(Internet protocol suite)中,TCP層是位於IP層之上,並應用層之下的中間層。不同主機的應用層之間經常需要可靠的、像管道一樣的連接,但是IP層不提供這樣的流機制,而是提供不可靠的包交換。

應用層向TCP層發送用於網間傳輸的、用8位元組表示的資料流,然後TCP把資料流分區成適當長度的封包段(通常受該電腦連接的網路的資料鏈結層的最大傳輸單元( MTU)的限制)。之後TCP把結果包傳給IP層,由它來透過網路將包傳送給接收端實體 的TCP層。 TCP為了確保不發生丟包,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的依序接收。然後接收端實體對已成功收到的包發回一個相應的確認(ACK);如果發送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的資料包就被假設為已丟失將會被進行重傳。 TCP用一個校驗和函數來檢驗資料是否有錯誤;在傳送和接收時都要計算校驗和。

三次握手

TCP是因特網中的傳輸層協議,使用三次握手協議建立連接。當主動方發出SYN連線要求後,等待對方回答SYN ACK ,並最終對對方的 SYN 執行 ACK 確認。這種建立連接的方法可以防止產生錯誤的連接,TCP使用的流量控制協定是可變大小的滑動視窗協定。 TCP三次握手的流程如下:

  • 客戶端傳送SYN(SEQ=x)封包給伺服器端,進入SYN_SEND狀態。  

  • 伺服器端收到SYN封包,回應一個SYN (SEQ=y)ACK(ACK=x 1)封包,進入SYN_RECV狀態。  

  • 客戶端收到伺服器端的SYN封包,回應一個ACK(ACK=y 1)封包,進入Established狀態。

連線成功

  • ##連線成功之後雙方即可互相傳輸位元組流,並隨時可關閉連線,傳輸的資料有以下特性
  • #傳輸的資料被tcp分割成了最適合發送的資料塊傳遞給ip協定,這個發送資料稱為封包段或段

  • tcp作為可靠性連接,每次發送資料段,會啟動一個定時器,每次接收資料段,會發送一次確認,如果定時器沒有及時收到確認,則會重發資料  

    #########TCP將維持它首部和資料的檢驗和。這是一個端到端的檢驗和,目的是檢測資料在傳輸過程中的任何變化。如果收到段的檢驗和有錯誤,TCP將丟棄這個報文段和不確認收到此報文段(希望發端逾時並重發)。 ###  ###############兩個應用程式透過TCP連線交換8bit位元組構成的位元組流。 TCP不在位元組流中插入記錄標識符。我們將此稱為位元組流服務(bytestreamservice)。如果一方的應用程式先發10字節,又傳20字節,再傳50字節,連接的另一方將無法了解發方每次發送了多少字節。只要自己的接收快取沒有塞滿,TCP 接收方將有多少就收多少。一端將位元組流放到TCP連線上,同樣的位元組流將出現在TCP連接的另一端。 ###  ###

四揮手

  • 建立一個連接需要三次握手,而終止一個連接要經過四次揮手,這是由TCP的半關閉(half-close)造成的。具體過程如下圖所示。

  • 某個應用程式先呼叫close,稱該端執行「主動關閉」(active close)。該端的TCP於是發送一個FIN分節,表示資料發送完畢。  

  • 接收到這個FIN的對端執行 「被動關閉」(passive close),這個FIN由TCP確認。

  • 注意:FIN的接收也作為一個檔案結束符號(end-of-file)傳遞給接收端應用程式,放在已排隊等候該應用程式接收的任何其他資料之後,因為,FIN的接收意味著接收端應用程式在相應連線上再無額外資料可接收。  

一段時間後,接收到這個檔案結束符號的應用程式將會呼叫close關閉它的套接字。這導致它的TCP也發送一個FIN。  

接收這個最終FIN的原始發送端TCP(也就是執行主動關閉的那一端)確認這個FIN。既然每個方向都需要一個FIN和一個ACK,因此通常需要4個分節。 「通常」是指,在某些情況下,步驟1的FIN會隨資料一起傳送,另外,步驟2和步驟3發送的分節都出自執行被動關閉那一端,有可能被合併成一個分節。在步驟2與步驟3之間,從執行被動關閉一端到執行主動關閉一端流動資料是可能的,這稱為「半關閉」(half-close)。當一個Unix進程無論自願地(調用exit或從main函數返回)還是非自願地(收到一個終止本進程的信號)終止時,所有打開的描述符都被關閉,這也導致仍然打開的任何TCP連接上也發出一個FIN。無論是客戶還是伺服器,任何一端都可以執行主動關閉。通常情況是,客戶執行主動關閉,但是某些協議,例如,HTTP/1.0卻由伺服器執行主動關閉。

    php中的tcp
  • php可透過socket函數,swoole擴展,stream流函數進行創建tcp協議的socket,綁定網卡端口,進行tcp服務端/客戶端操作在php中,我們並不需要了解tcp的握手/揮手,我們只需要知道ip:port能連接/創建一個tcp服務端/客戶端就行了
  • 使用php的socket,我們可以直接發送字符串,接收的也是字符串,其他一切都是語言,操作系統所需要做的事,我們只需要處理好字串的完整性,例如我們使用php做tcp服務端

#客戶端連線成功後,發送了一個"easyswoole是一個非常好的swoole框架"的字串

而服務端每次只接收9個位元組,那第一次取得只會接收到"easyswool"的殘缺字串,需要繼續取得資料

   http協定

  • # #過程解析

  • http一次請求的過程大概如下:
  • 使用者在瀏覽器中輸入

      www.easyswoole.com

    ######dns伺服器解析/或本機hosts,路由器hosts比較 取得ip###  ###############瀏覽器存取預設連接埠80,則存取的tcp位址為 ip:80####  ###############tcp協定3次握手,建立連線###  ###############發送一個http request請求標頭### ###############伺服器取得http request請求頭,表示該次存取為http存取,解析http請求頭,取得請求類型,請求格式,以及請求資料(cookie,get, post資料)###  ###############伺服器傳送response回應資料,主動斷開####  ###
  • 瀏覽器接收response回應資料,解析回應文字類型,解析資料,斷開連線  

    https協定中,在請求以及回應時多了一層tls,ssl加密解密協定,預設埠從80變成443

phper中的http

由於php大部分時候都是用於web伺服器,所以php開發者接觸最多的協定也就是基於tcp/ip協定的http協定了

在php初級程式設計師中,其實沒有詳細的了解http協定,但是可以透過瀏覽器的f12->network去查看http協定具體的請求頭,以及服務端發送的回應頭

WebSocket協定

產生背景

在沒有WebSocket協定之前,在網頁中,實作一個聊天室只能使用ajax 不斷輪詢,請求伺服器是否有資料產生,而這樣的實作方法會出現一系列的問題:

  • 如果輪詢時間間隔太短,會導致客戶端和服務端在一個時間段內不斷的進行http tcp的握手/揮手動作和http 請求頭,回應頭的傳輸,大量消耗伺服器資源,如果用戶量大的情況,會造成伺服器的繁忙以至於宕機  

  • 客戶端每次只能透過發送http 請求獲得伺服器是否有資料回傳,且資料的及時性無法保證

正因為在這種情況下,所以WebSocket出現了,它只需要一次http握手,就可以保持一個長連接,使得伺服器可以主動發送訊息給客戶端,大大減少了輪詢機制的消耗

實作原理

在實作websocket連線過程中,需要透過瀏覽器發出websocket連線請求,然後伺服器發出回應,這個過程通常稱為「握手」 

在 WebSocket API,瀏覽器和伺服器只需要做一個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。

兩者之間就直接可以資料互相傳送。在此WebSocket 協議中,為我們實現即時服務帶來了兩大好處:

  • #Header: 互相溝通的Header是很小的-大概只有2 Bytes

  • Server Push: 伺服器的推送,伺服器不再被動的接收到瀏覽器的請求之後才傳回數據,而是在有新數據時才主動推送給瀏覽器。    

udp(傳輸層)

#UDP 是User Datagram Protocol的簡稱, 中文名是用戶資料報協議,是OSI(Open System Interconnection,開放式系統互聯) 參考模型中一種無連接的傳輸層協議,提供面向事務的簡單不可靠訊息傳送服務,IETF RFC 768是UDP的正式規範。 UDP在IP封包的協定號碼是17。

UDP協定全名為使用者資料報協議,在網路中它與TCP協定一樣用於處理資料包,是一種無連線的協定。在OSI模型中,在第四層-傳輸層,處於IP協定的上一層。 UDP有不提供資料包分組、組裝和無法對資料包進行排序的缺點,也就是說,當封包發送之後,是無法得知其是否安全完整到達的。 UDP用來支援那些需要在電腦之間傳輸資料的網路應用。包括網路視訊會議系統在內的眾多的客戶/伺服器模式的網路應用都需要使用UDP協定。 UDP協定從問世至今已經被使用了很多年,雖然其最初的光彩已經被一些類似協定所掩蓋,但是即使是在今天UDP仍然不失為一項非常實用和可行的網路傳輸層協定。

與所熟知的TCP(傳輸控制協定)協定一樣,UDP協定直接位於IP(網路協定)協定的頂層。根據OSI(開放系統互連)參考模型,UDP和TCP都屬於傳輸層協定。 UDP協定的主要作用是將網路資料流量壓縮成資料包的形式。一個典型的資料包就是一個二進位資料的傳輸單位。每一個資料包的前8個位元組用來包含報頭訊息,剩餘位元組則用來包含具體的傳輸資料。

udp與tcp

udp和tcp都屬於傳輸層的協定,都位於ip協定的頂層,他們不同之處有:

  • udp是無連線協定,不需要進行tcp的握手  

  • udp每次傳送最大長度是65535,而tcp在握手後可以源源不絕的傳送  

  • udp協定使用標頭中的校驗值來確保資料的安全。校驗值首先在資料傳送方透過特殊的演算法計算得出,傳遞到接收方之後,還需要再重新計算。如果某個資料封包在傳輸過程中被第三方竄改或因為線路雜訊等原因損壞,傳送和接收方的校驗計算值將不會相符,由此UDP協定可以偵測是否出錯。這與TCP協定是不同的,後者要求必須具有校驗值。  

  • udp封包沒有可靠保證、順序保證和流量控製欄位等,可靠性較差。但正因為udp協定的控制選項較少,在資料傳輸過程中延遲小、資料傳輸效率高,適合對可靠性要求不高的應用程序,或者可以保障可靠性的應用程序,如DNS、TFTP、SNMP等。  

  • 在網路品質令人十分不滿意的環境下,UDP協定封包遺失會比較嚴重。而tcp會進行確認驗證,確保對方接收成功

  • udp可實現對網關內的所有主機進行廣播   

php多重行程

#多行程的概念

前面有講到,多進程主要是在開發業務邏輯層面,並行處理多個任務的開發方式,什麼叫做開發業務邏輯層面呢?在上面我們有講到,php-fpm是fast-cgi的進程管理器,啟動之後會啟動多個fast-cgi進程,等待任務處理

在php-fpm軟體層面,fast-cgi的多個進程就屬於多重處理處理,但是,當使用者發起請求,

由nginx交給php-fpm處理請求,在這個層次,每個請求其實只佔有一個php fast-cgi進程進行處理邏輯,對於運行業務邏輯的這個php進程,其實是單一進程的.

##同理,當我們直接執行一個php檔,預設是只開啟了一個php行程進行運行php的程式碼

多進程的開發場景

  • #在傳統web模式下,php一向是單一進程處理業務邏輯,只有在php- cli模式下,用於處理非同步任務,作為網頁伺服器時,才可能用到多進程處理,所以,大部分phper都對php多重進程的概念不熟悉
  • 使用pcntl擴充

    ############進程通訊###############################進程通訊########### ##############管道通訊,分為有名管道,無名管道等,可自行搜尋了解詳細###  ###############訊息佇列通訊,使用linux訊息佇列,透過sysvmsg擴充,可查看:###   http://www.php20.cn/article/137################進程訊號通訊,可檢視:###   http://www.php20.cn/article/134###
  • 共享記憶體通訊,映射一段能被其他行程所存取的內存,這段共享記憶體由一個行程創建,但多個行程都可以存取。  

  • 共享記憶體是最快的 IPC 方式,它是針對其他進程間通訊方式運作效率低且專門設計的。  

  • 它常與其他通訊機制,如訊號兩,搭配使用,來實現進程間的同步與通訊。  

  • 套接字通訊

  • 第三方通訊,使用檔案作業,mysql,redis等方法也可實作通訊   

協程

協程不是進程或線程,其執行過程更類似於子例程,或說不帶返回值的函數呼叫。

一個程式可以包含多個協程,可以比較與一個行程包含多個線程,因而下面我們來比較協程和執行緒。

我們知道多個執行緒相對獨立,有自己的上下文,切換受系統控制;而協程也相對獨立,

有自己的上下文,但是其切換由自己控制,由當前協程切換到其他協程由當前協程來控制。

##由上面的

協程執行順序

中的程式碼2,我們很容易發現,協程其實只是運行在一個行程中的函數,只是這個函數會被切換到下一個執行,可以這麼說:

##協程只是一串運行在進程中的任務代碼,只是這些任務代碼可以交叉運行注意,協程並不是多任務並行,屬於多任務串行,每個進程在一個時間只執行了一個任務

協程的作用域

#由於協程就是行程中一串任務程式碼,所以它的全域變數,靜態變數等變數都是共享的,包括了php的全域緩衝區.所以,在開發之中,需要特別注意協程中的全域變量,靜態變數,只要某一個協程內修改了,那將會影響全部的協程,在使用ob緩衝區函數攔截的時候,也得考慮是否會被其他協程的輸出給污染.協程執行順序中的程式碼2解釋,當task1給$_GET['name']賦值為1時,task2讀取$_GET['name']也會是1,task2將$_GET['name']賦值為2時,task3讀取$_GET['name']也會是2

協程中的I /O連接

###在協程中,要特別注意不能共用一個I/O連接,否則會造成數據異常. 用############協程執行順序#############中的程式碼2解釋,當task1,task2函數共用mysql連接,並都進行查詢時,由於協程是交叉運行的,可能會造成task1獲取到task1 task2查詢出來的資料,也可能會遺失部分資料,被task2取得.################# #####由於協程的交叉運行機制,各個協程的I/O連接都必須是獨立的,所以我們需要在每個協程都創建一個連接,但由於mysql,redis的連接數有限,以及連線的開啟關閉需要消耗大量資源,所以我們可以使用連線池方案實現共用連線(只要保證每個連線每次只有一個協程在使用即可)############推薦學習:###swoole教學 ######

以上是詳細整理swoole知識點(總結分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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