日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

easyswoole学习笔记

發(fā)布時(shí)間:2023/12/29 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 easyswoole学习笔记 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

1,常規(guī)安裝,根據(jù)文檔檢查環(huán)境要求

  • 保證?PHP?版本大于等于?7.1

  • 保證?Swoole?拓展版本大于等于?4.3.0

  • 需要?pcntl?拓展的任意版本

  • 使用?Linux?/?FreeBSD?/?MacOS?這三類操作系統(tǒng)

  • 使用?Composer?作為依賴管理工具

2,采用composer安裝

切換阿里云鏡像

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

composer安裝

composer require easyswoole/easyswoole=3.x php vendor/bin/easyswoole install

如果其中報(bào)錯(cuò),不能用管理員安裝,切換為普通用戶安裝完成,并且暫時(shí)修改目錄權(quán)限為可寫(xiě)就好

chmod 755 ./composer.json chmod 755 ./composer.lock

啟動(dòng)框架代碼

php easyswoole start

composer 安裝報(bào)錯(cuò)?

Failed to decode response: zlib_decode(): data error

? ?網(wǎng)上查? 運(yùn)用這個(gè)命令 composer diagnose,再次安裝依然報(bào)錯(cuò)

??composer self-update 還是不行??

??

? ?執(zhí)行命令? composer dump-autoload

? 執(zhí)行命令? ?composer update命令更新依賴? 執(zhí)行成功

3,本地環(huán)境無(wú)法訪問(wèn)9501端口 ,明顯swoole已經(jīng)在服務(wù)器啟動(dòng)

開(kāi)始以為是防火墻的問(wèn)題,于是想現(xiàn)在打開(kāi)防火墻端口號(hào)看看,結(jié)果還是不行

iptables -A INPUT -ptcp --dport 端口號(hào)-j ACCEPT? ?service iptables save

看了官方文檔介紹:

我以為訪問(wèn)的是 localhost:9501 ,結(jié)果是要以虛擬機(jī)的地址來(lái)訪問(wèn)

192.168.xx.xx:9501來(lái)進(jìn)行訪問(wèn)

linux渣渣,命途多舛............

?

4,啟動(dòng)停止

php easyswoole

守護(hù)模式

php easyswoole start d php easyswoole reload 只重啟task進(jìn)程 php easyswoole reload all 重啟task + worker進(jìn)程

5,反向代理模式

由于 Swoole Server 對(duì) HTTP 協(xié)議的支持并不完整,建議僅將 EasySwoole 作為后端服務(wù),并且在前端增加 NGINX 或 APACHE 作為代理,參照下面的例子添加轉(zhuǎn)發(fā)規(guī)則

ngiinx

server {root /data/wwwroot/;server_name local.swoole.com;location / {proxy_http_version 1.1;proxy_set_header Connection "keep-alive";proxy_set_header X-Real-IP $remote_addr;if (!-f $request_filename) {proxy_pass http://127.0.0.1:9501;}} }

代理之后,可通過(guò)$request->getHeader('x-real-ip')[0]獲取客戶端真實(shí)ip

apache

<IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f #RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] fcgi下無(wú)效 RewriteRule ^(.*)$ http://127.0.0.1:9501/$1 [QSA,P,L] #請(qǐng)開(kāi)啟 proxy_mod proxy_http_mod request_mod </IfModule>

?

6,開(kāi)發(fā)者必讀??看完了官方文檔,就抄寫(xiě)了一堆文檔注意事項(xiàng)在這

注意事項(xiàng)

  • 不要在代碼中執(zhí)行sleep以及其他睡眠函數(shù),這樣會(huì)導(dǎo)致整個(gè)進(jìn)程阻塞 exit/die是危險(xiǎn)的,會(huì)導(dǎo)致worker進(jìn)程退出
  • 可通過(guò)register_shutdown_function來(lái)捕獲致命錯(cuò)誤,在進(jìn)程異常退出時(shí)做一些請(qǐng)求工作。
  • PHP代碼中如果有異常拋出,必須在回調(diào)函數(shù)中進(jìn)行try/catch捕獲異常,否則會(huì)導(dǎo)致工作進(jìn)程退出
  • swoole不支持set_exception_handler,必須使用try/catch方式處理異常
  • Worker進(jìn)程不得共用同一個(gè)Redis或MySQL等網(wǎng)絡(luò)服務(wù)客戶端,Redis/MySQL創(chuàng)建連接的相關(guān)代碼可以放到onWorkerStart回調(diào)函數(shù)中。

類/函數(shù)重復(fù)定義

  • 新手非常容易犯這個(gè)錯(cuò)誤,由于easySwoole是常駐內(nèi)存的,所以加載類/函數(shù)定義的文件后不會(huì)釋放。因此引入類/函數(shù)的php文件時(shí)必須要使用include_once或require_once,否會(huì)發(fā)生cannot redeclare function/class 的致命錯(cuò)誤。

進(jìn)程隔離與內(nèi)存管理

  • 進(jìn)程隔離也是很多新手經(jīng)常遇到的問(wèn)題。修改了全局變量的值,為什么不生效,原因就是全局變量在不同的進(jìn)程,內(nèi)存空間是隔離的,所以無(wú)效。 所以使用easySwoole開(kāi)發(fā)Server程序需要了解進(jìn)程隔離問(wèn)題。不同的進(jìn)程中PHP變量不是共享,即使是全局變量,在A進(jìn)程內(nèi)修改了它的值,在B進(jìn)程內(nèi)是無(wú)效的,如果需要在不同的Worker進(jìn)程內(nèi)共享數(shù)據(jù),可以用Redis、MySQL、文件、Swoole\Table、APCu、shmget等工具實(shí)現(xiàn) 還有,不同進(jìn)程的文件句柄是隔離的,所以在A進(jìn)程創(chuàng)建的Socket連接或打開(kāi)的文件,在B進(jìn)程內(nèi)是無(wú)效,即使是將它的fd發(fā)送到B進(jìn)程也是不可用的。

  • 進(jìn)程克隆。在Server啟動(dòng)時(shí),主進(jìn)程會(huì)克隆當(dāng)前進(jìn)程狀態(tài),此后開(kāi)始進(jìn)程內(nèi)數(shù)據(jù)相互獨(dú)立,互不影響。有疑問(wèn)的新手可以先弄懂php的pcntl

swoole_server中對(duì)象的4層生命周期

開(kāi)發(fā)swoole程序與普通LAMP下編程有本質(zhì)區(qū)別。在傳統(tǒng)的Web編程中,PHP程序員只需要關(guān)注request到達(dá),request結(jié)束即可。而在swoole程序中程序員可以操控更大范圍,變量/對(duì)象可以有四種生存周期。

變量、對(duì)象、資源、require/include的文件等下面統(tǒng)稱為對(duì)象

程序全局期

在swoole_server->start之前就創(chuàng)建好的對(duì)象,我們稱之為程序全局生命周期。這些變量在程序啟動(dòng)后就會(huì)一直存在,直到整個(gè)程序結(jié)束運(yùn)行才會(huì)銷毀。

有一些服務(wù)器程序可能會(huì)連續(xù)運(yùn)行數(shù)月甚至數(shù)年才會(huì)關(guān)閉/重啟,那么程序全局期的對(duì)象在這段時(shí)間持續(xù)駐留在內(nèi)存中的。程序全局對(duì)象所占用的內(nèi)存是Worker進(jìn)程間共享的,不會(huì)額外占用內(nèi)存。

這部分內(nèi)存會(huì)在寫(xiě)時(shí)分離(COW),在Worker進(jìn)程內(nèi)對(duì)這些對(duì)象進(jìn)行寫(xiě)操作時(shí),會(huì)自動(dòng)從共享內(nèi)存中分離,變?yōu)檫M(jìn)程全局對(duì)象。

程序全局期include/require的代碼,必須在整個(gè)程序shutdown時(shí)才會(huì)釋放,reload無(wú)效

進(jìn)程全局期

swoole擁有進(jìn)程生命周期控制的機(jī)制,一個(gè)Worker子進(jìn)程處理的請(qǐng)求數(shù)超過(guò)max_request配置后,就會(huì)自動(dòng)銷毀。Worker進(jìn)程啟動(dòng)后創(chuàng)建的對(duì)象(onWorkerStart中創(chuàng)建的對(duì)象),在這個(gè)子進(jìn)程存活周期之內(nèi),是常駐內(nèi)存的。onConnect/onReceive/onClose 中都可以去訪問(wèn)它。

進(jìn)程全局對(duì)象所占用的內(nèi)存是在當(dāng)前子進(jìn)程內(nèi)存堆的,并非共享內(nèi)存。對(duì)此對(duì)象的修改僅在當(dāng)前Worker進(jìn)程中有效 進(jìn)程期include/require的文件,在reload后就會(huì)重新加載

會(huì)話期

會(huì)話期是在onConnect后創(chuàng)建,或者在第一次onReceive時(shí)創(chuàng)建,onClose時(shí)銷毀。一個(gè)客戶端連接進(jìn)入后,創(chuàng)建的對(duì)象會(huì)常駐內(nèi)存,直到此客戶端離開(kāi)才會(huì)銷毀。

在LAMP中,一個(gè)客戶端瀏覽器訪問(wèn)多次網(wǎng)站,就可以理解為會(huì)話期。但傳統(tǒng)PHP程序,并不能感知到。只有單次訪問(wèn)時(shí)使用session_start,訪問(wèn)$_SESSION全局變量才能得到會(huì)話期的一些信息。

swoole中會(huì)話期的對(duì)象直接是常駐內(nèi)存,不需要session_start之類操作。可以直接訪問(wèn)對(duì)象,并執(zhí)行對(duì)象的方法。

?

請(qǐng)求期

請(qǐng)求期就是指一個(gè)完整的請(qǐng)求發(fā)來(lái),也就是onReceive收到請(qǐng)求開(kāi)始處理,直到返回結(jié)果發(fā)送response。這個(gè)周期所創(chuàng)建的對(duì)象,會(huì)在請(qǐng)求完成后銷毀。

swoole中請(qǐng)求期對(duì)象與普通PHP程序中的對(duì)象就是一樣的。請(qǐng)求到來(lái)時(shí)創(chuàng)建,請(qǐng)求結(jié)束后銷毀。

?

swoole_server中內(nèi)存管理機(jī)制

swoole_server啟動(dòng)后內(nèi)存管理的底層原理與普通php-cli程序一致。具體請(qǐng)參考Zend VM內(nèi)存管理方面的文章。

?

局部變量

在事件回調(diào)函數(shù)返回后,所有局部對(duì)象和變量會(huì)全部回收,不需要unset。如果變量是一個(gè)資源類型,那么對(duì)應(yīng)的資源也會(huì)被PHP底層釋放。

function test() {$a = new Object;$b = fopen('/data/t.log', 'r+');$c = new swoole_client(SWOOLE_SYNC);$d = new swoole_client(SWOOLE_SYNC);global $e;$e['client'] = $d; }

$a, $b, $c 都是局部變量,當(dāng)此函數(shù)return時(shí),這3個(gè)變量會(huì)立即釋放,對(duì)應(yīng)的內(nèi)存會(huì)立即釋放,打開(kāi)的IO資源文件句柄會(huì)立即關(guān)閉。 $d 也是局部變量,但是return前將它保存到了全局變量$e,所以不會(huì)釋放。當(dāng)執(zhí)行unset($e['client'])時(shí),并且沒(méi)有任何其他PHP變量仍然在引用$d變量,那么$d 就會(huì)被釋放。

?

全局變量

在PHP中,有3類全局變量。

  • 使用global關(guān)鍵詞聲明的變量
  • 使用static關(guān)鍵詞聲明的類靜態(tài)變量、函數(shù)靜態(tài)變量
  • PHP的超全局變量,包括$_GET、$_POST、$GLOBALS等

全局變量和對(duì)象,類靜態(tài)變量,保存在swoole_server對(duì)象上的變量不會(huì)被釋放。需要程序員自行處理這些變量和對(duì)象的銷毀工作。

class Test {static $array = array();static $string = ''; }function onReceive($serv, $fd, $reactorId, $data) {Test::$array[] = $fd;Test::$string .= $data; }
  • 在事件回調(diào)函數(shù)中需要特別注意非局部變量的array類型值,某些操作如 TestClass::$array[] = "string" 可能會(huì)造成內(nèi)存泄漏,嚴(yán)重時(shí)可能發(fā)生爆內(nèi)存,必要時(shí)應(yīng)當(dāng)注意清理大數(shù)組。
  • 在事件回調(diào)函數(shù)中,非局部變量的字符串進(jìn)行拼接操作是必須小心內(nèi)存泄漏,如 TestClass::$string .= $data,可能會(huì)有內(nèi)存泄漏,嚴(yán)重時(shí)可能發(fā)生爆內(nèi)存。

解決方法

  • 同步阻塞并且請(qǐng)求響應(yīng)式無(wú)狀態(tài)的Server程序可以設(shè)置max_request,當(dāng)Worker進(jìn)程/Task進(jìn)程結(jié)束運(yùn)行時(shí)或達(dá)到任務(wù)上限后進(jìn)程自動(dòng)退出。該進(jìn)程的所有變量/對(duì)象/資源均會(huì)被釋放回收。
  • 程序內(nèi)在onClose或設(shè)置定時(shí)器及時(shí)使用unset清理變量,回收資源

?

?

?

總結(jié)

以上是生活随笔為你收集整理的easyswoole学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。