這篇文章為大家帶來了關於swoole的相關知識,其中包括了fastcgi請求到swoole master進程去分發到子進程,但是不會像php-fpm的子進程使用完後退出等相關問題,希望對大家有幫助。
推薦學習:swoole影片教學
聊天室流程講解
#整個聊天室流程為:
- 使用者http介面登入獲得授權
- 透過授權請求http介面取得好友清單,不同好友的最後一則未讀訊息以及未讀取訊息數(用於首頁顯示)
- 透過授權請求獲得群組列表(群組訊息為了節省儲存空間沒有做已讀未讀)
#- 建立ws連結
- 註冊斷線重連機制,觸發close事件時,重連ws
- 建立ping定時器,每隔30秒進行一次ping
#- 點擊進入某個群組/好友訊息介面時,自動取得最新n條訊息,用戶上拉時繼續取得n條
#行模式運
cgi 協定模式
使用者請求->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就開始wamp,wnmp的開發者來說是最陌生的一種運行模式
該模式不需要藉助其他程式,直接輸入php xx.php 就能執行php程式碼
#命令列模式和常規web模式明顯不一樣的是:
#* 沒有逾時時間
* 預設關閉buffer緩衝
* STDIN和STDOUT標準輸入/輸出/錯誤的使用
#* echo var_dump,phpinfo等輸出直接輸出到控制台
* 可使用的類別/函數不同
* php.ini配置的不同
支援平滑停止/啟動的高階進程管理功能;
可以工作於不同的uid/gid/chroot 環境下,並監聽不同的連接埠和使用不同的php.ini 設定檔(可取代safe_mode 的設定);
stdout 和 stderr 日誌記錄;
在發生意外狀況的時候能夠重新啟動並且快取被破壞的 opcode;
檔案上傳最佳化支援;
"慢日誌" - 記錄腳本(不僅記錄檔名,還記錄PHP backtrace 信息,可以使用ptrace或類似工具讀取和分析遠端進程的運行數據)運行所導致的異常緩慢;
fastcgi_finish_request() - 特殊功能:用於在請求完成和刷新資料後,繼續在背景執行耗時的工作(輸入視訊轉換、統計處理等);
動態/靜態子程序產生;
基本 SAPI 運作狀態資訊(類似Apache的 mod_status);
基於 php.ini 的設定檔。
網路協定依通訊的步驟,層級分割為7個層級,從上往下為:
應用層
表示層#
會話層
傳輸層#
網路層
資料鏈結層
物理層
#ip協定是網際網路的基礎協定,它是目前最受歡迎的一種網路協定
#IP的責任就是將資料從來源傳送到目的地。它不負責保證傳送可靠性,流控制,包順序和其它對於主機到主機協議來說很普通的服務。
#這個協定由主機到主機協定調用,而此協定負責調用本地網路協定將封包傳送以下一個網關或目的主機。例如TCP可以呼叫IP協議,在呼叫時傳送目的位址和來源位址作為參數,IP形成封包並呼叫本地網路(協定)介面傳送封包。
IP實作兩個基本功能:尋址和分段。 IP可以根據資料包包頭中包含的目的位址將資料包傳送到目的位址,在此過程中IP負責選擇傳送的道路,這種選擇道路稱為路由功能。如果有些網路內只能傳送小資料包,IP可以將資料包重新組裝並在標頭域內註明。 IP模組中包含這些基本功能,這些模組存在於網路中的每台主機和網關上,而且這些模組(特別在網關上)有路由選擇和其它服務功能。對IP來說,資料包之間沒有什麼聯繫,對IP不好說什麼連接或邏輯鏈路。
ip位址
###把資料從來源傳送到目的地時,需要有ip位址才能傳輸,現在ip位址分成ipv4和ipv6 兩種位址,現在最常見的就是ipv4位址,例如127.0.0.1(本機位址) 119.75.217.109(百度ip)#####################ip傳輸必須要有明確的ip位址,才能進行資料傳送###### ###
#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連接的另一端。 ### ###
某個應用程式先呼叫close,稱該端執行「主動關閉」(active close)。該端的TCP於是發送一個FIN分節,表示資料發送完畢。
接收到這個FIN的對端執行 「被動關閉」(passive close),這個FIN由TCP確認。
注意:FIN的接收也作為一個檔案結束符號(end-of-file)傳遞給接收端應用程式,放在已排隊等候該應用程式接收的任何其他資料之後,因為,FIN的接收意味著接收端應用程式在相應連線上再無額外資料可接收。
一段時間後,接收到這個檔案結束符號的應用程式將會呼叫close關閉它的套接字。這導致它的TCP也發送一個FIN。
使用php的socket,我們可以直接發送字符串,接收的也是字符串,其他一切都是語言,操作系統所需要做的事,我們只需要處理好字串的完整性,例如我們使用php做tcp服務端
# #過程解析
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
由於php大部分時候都是用於web伺服器,所以php開發者接觸最多的協定也就是基於tcp/ip協定的http協定了
在php初級程式設計師中,其實沒有詳細的了解http協定,但是可以透過瀏覽器的f12->network去查看http協定具體的請求頭,以及服務端發送的回應頭
在沒有WebSocket協定之前,在網頁中,實作一個聊天室只能使用ajax 不斷輪詢,請求伺服器是否有資料產生,而這樣的實作方法會出現一系列的問題:
如果輪詢時間間隔太短,會導致客戶端和服務端在一個時間段內不斷的進行http tcp的握手/揮手動作和http 請求頭,回應頭的傳輸,大量消耗伺服器資源,如果用戶量大的情況,會造成伺服器的繁忙以至於宕機
客戶端每次只能透過發送http 請求獲得伺服器是否有資料回傳,且資料的及時性無法保證
在實作websocket連線過程中,需要透過瀏覽器發出websocket連線請求,然後伺服器發出回應,這個過程通常稱為「握手」 。
在 WebSocket API,瀏覽器和伺服器只需要做一個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。
兩者之間就直接可以資料互相傳送。在此WebSocket 協議中,為我們實現即時服務帶來了兩大好處:
#Header: 互相溝通的Header是很小的-大概只有2 Bytes
Server Push: 伺服器的推送,伺服器不再被動的接收到瀏覽器的請求之後才傳回數據,而是在有新數據時才主動推送給瀏覽器。
#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都屬於傳輸層的協定,都位於ip協定的頂層,他們不同之處有:
udp是無連線協定,不需要進行tcp的握手
udp每次傳送最大長度是65535,而tcp在握手後可以源源不絕的傳送
udp協定使用標頭中的校驗值來確保資料的安全。校驗值首先在資料傳送方透過特殊的演算法計算得出,傳遞到接收方之後,還需要再重新計算。如果某個資料封包在傳輸過程中被第三方竄改或因為線路雜訊等原因損壞,傳送和接收方的校驗計算值將不會相符,由此UDP協定可以偵測是否出錯。這與TCP協定是不同的,後者要求必須具有校驗值。
udp封包沒有可靠保證、順序保證和流量控製欄位等,可靠性較差。但正因為udp協定的控制選項較少,在資料傳輸過程中延遲小、資料傳輸效率高,適合對可靠性要求不高的應用程序,或者可以保障可靠性的應用程序,如DNS、TFTP、SNMP等。
在網路品質令人十分不滿意的環境下,UDP協定封包遺失會比較嚴重。而tcp會進行確認驗證,確保對方接收成功
udp可實現對網關內的所有主機進行廣播
php多重行程
#多行程的概念
由nginx交給php-fpm處理請求,在這個層次,每個請求其實只佔有一個php fast-cgi進程進行處理邏輯,對於運行業務邏輯的這個php進程,其實是單一進程的.
#在傳統web模式下,php一向是單一進程處理業務邏輯,只有在php- cli模式下,用於處理非同步任務,作為網頁伺服器時,才可能用到多進程處理,所以,大部分phper都對php多重進程的概念不熟悉
############進程通訊###############################進程通訊########### ##############管道通訊,分為有名管道,無名管道等,可自行搜尋了解詳細### ###############訊息佇列通訊,使用linux訊息佇列,透過sysvmsg擴充,可查看:### http://www.php20.cn/article/137################進程訊號通訊,可檢視:### http://www.php20.cn/article/134###
共享記憶體通訊,映射一段能被其他行程所存取的內存,這段共享記憶體由一個行程創建,但多個行程都可以存取。
共享記憶體是最快的 IPC 方式,它是針對其他進程間通訊方式運作效率低且專門設計的。
它常與其他通訊機制,如訊號兩,搭配使用,來實現進程間的同步與通訊。
套接字通訊
第三方通訊,使用檔案作業,mysql,redis等方法也可實作通訊
協程
協程不是進程或線程,其執行過程更類似於子例程,或說不帶返回值的函數呼叫。
一個程式可以包含多個協程,可以比較與一個行程包含多個線程,因而下面我們來比較協程和執行緒。
我們知道多個執行緒相對獨立,有自己的上下文,切換受系統控制;而協程也相對獨立,
有自己的上下文,但是其切換由自己控制,由當前協程切換到其他協程由當前協程來控制。
#由於協程就是行程中一串任務程式碼,所以它的全域變數,靜態變數等變數都是共享的,包括了php的全域緩衝區.所以,在開發之中,需要特別注意協程中的全域變量,靜態變數,只要某一個協程內修改了,那將會影響全部的協程,在使用ob緩衝區函數攔截的時候,也得考慮是否會被其他協程的輸出給污染.用協程執行順序中的程式碼2解釋,當task1給$_GET['name']賦值為1時,task2讀取$_GET['name']也會是1,task2將$_GET['name']賦值為2時,task3讀取$_GET['name']也會是2
###在協程中,要特別注意不能共用一個I/O連接,否則會造成數據異常. 用############協程執行順序#############中的程式碼2解釋,當task1,task2函數共用mysql連接,並都進行查詢時,由於協程是交叉運行的,可能會造成task1獲取到task1 task2查詢出來的資料,也可能會遺失部分資料,被task2取得.################# #####由於協程的交叉運行機制,各個協程的I/O連接都必須是獨立的,所以我們需要在每個協程都創建一個連接,但由於mysql,redis的連接數有限,以及連線的開啟關閉需要消耗大量資源,所以我們可以使用連線池方案實現共用連線(只要保證每個連線每次只有一個協程在使用即可)############推薦學習:###swoole教學 ######協程中的I /O連接
以上是詳細整理swoole知識點(總結分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!