Swoole 由來(lái)
從今天開(kāi)始,連續(xù)更新,swoole相關(guān)技術(shù),從入門(mén)安裝到使用,比官方文檔,更好入手。
Swoole 由來(lái)
PHP這個(gè)語(yǔ)言有很大的局限性,甚至可以說(shuō)PHP語(yǔ)言只寫(xiě)做Web程序。網(wǎng)絡(luò)通信框架、異步、多線程,協(xié)程,多進(jìn)程,這些特性正是php所不完善的功能(雖然官方提供很多基礎(chǔ)函數(shù)可以實(shí)現(xiàn)這些功能,PHP語(yǔ)言本身也提供了一些可以實(shí)現(xiàn)進(jìn)行底層操作和網(wǎng)絡(luò)通信的擴(kuò)展,比如sockets、libevent、pcntl之類),普通的phper也不具備這些特性的基礎(chǔ)認(rèn)知,基于此 Swoole 應(yīng)運(yùn)而生。
Swoole是韓天峰在2010年底,因?yàn)楣緲I(yè)務(wù)需要自己實(shí)現(xiàn)一個(gè)Tcp Socket Server 實(shí)現(xiàn)SMTP協(xié)議接收數(shù)據(jù),但是在當(dāng)時(shí)PHP在這個(gè)領(lǐng)域幾乎是一片空白,所以自己學(xué)習(xí),最終完成了需求;隨后便開(kāi)源了此套系統(tǒng),希望能幫助其他PHPer解決在這個(gè)領(lǐng)域的問(wèn)題,讓PHP從單純的Web開(kāi)發(fā)擴(kuò)展到更大的空間。
Swoole這個(gè)名字不是一個(gè)英文單詞,是由作者創(chuàng)造的一個(gè)音近字。最早想到的名字是叫做sword-server,寓意是為廣大PHPer創(chuàng)造一把鋒利的劍,后來(lái)聯(lián)想到google也是憑空創(chuàng)造出來(lái)的,所以我就給它命名為swoole。
swoole 介紹
Swoole是一個(gè)完全使用C語(yǔ)言編寫(xiě)面向生產(chǎn)環(huán)境的 PHP 異步網(wǎng)絡(luò)通信引擎,使 PHP 開(kāi)發(fā)人員可以編寫(xiě)高性能的異步并發(fā) TCP、UDP、Unix Socket、HTTP,WebSocket 服務(wù)。Swoole 可以廣泛應(yīng)用于互聯(lián)網(wǎng)、移動(dòng)通信、企業(yè)軟件、云計(jì)算、網(wǎng)絡(luò)游戲、物聯(lián)網(wǎng)(IOT)、車聯(lián)網(wǎng)、智能家居等領(lǐng)域。使用 PHP + Swoole 作為網(wǎng)絡(luò)通信框架,可以使企業(yè) IT 研發(fā)團(tuán)隊(duì)的效率大大提升,更加專注于開(kāi)發(fā)創(chuàng)新產(chǎn)品。
Swoole特性
PHP的 協(xié)程 高性能網(wǎng)絡(luò)通信引擎,使用C/C++語(yǔ)言編寫(xiě)php擴(kuò)展,提供了多種通信協(xié)議的網(wǎng)絡(luò)服務(wù)器和客戶端模塊。包括:
TCP/UDP/UnixSock 服務(wù)器端
Http/WebSocket/Http2.0 服務(wù)器端
協(xié)程 TCP/UDP/UnixSock
協(xié)程 MySQL
協(xié)程 Redis
協(xié)程 Http/WebSocket
協(xié)程 Http2
AsyncTask
毫秒定時(shí)器
協(xié)程文件讀寫(xiě)
異步 文件讀寫(xiě) 異步mysql redis
Swoole版本
Swoole2.0 支持了類似 Go 語(yǔ)言的協(xié)程 不完美
3 版本協(xié)程 存在兼容問(wèn)題 放棄
Swoole4支持完整的協(xié)程編程模式,可以使用完全同步的代碼實(shí)現(xiàn)異步程序。
PHP代碼無(wú)需額外增加任何關(guān)鍵詞,底層自動(dòng)進(jìn)行協(xié)程調(diào)度,實(shí)現(xiàn)異步IO。
Swoole4協(xié)程僅支持PHP7,無(wú)法在PHP5中使用
異步回調(diào)模塊已過(guò)時(shí),目前僅修復(fù) BUG,不再進(jìn)行維護(hù), 且在4.3版本中移除了異步模塊。請(qǐng)使用 Coroutine 協(xié)程模塊。
僅支持 Linux、FreeBSD、MacOS 三種操作系統(tǒng)
在Windows平臺(tái),可使用CygWin或WSL(Windows Subsystem for Linux)
目前cygwin版本為測(cè)試版本,Windows 下Swoole的功能受限。
swoole案例:https://wiki.swoole.com/wiki/page/p-case.html
workerman swoole區(qū)別
workerman純php swoole C/C++語(yǔ)言編寫(xiě) 作為php的擴(kuò)展
workerman 多進(jìn)程 swoole 協(xié)程 多進(jìn)程 多線程
swoole性能優(yōu)于workerman
workerman win/linux swoole win測(cè)試 線上linux
swoole并沒(méi)有用libevent,所以不需要安裝libevent
swoole并不依賴php的stream/sockets/pcntl/posix/sysvmsg等擴(kuò)展
swoole安裝環(huán)境
centos 7.6
php 7.2 // lnmp 一鍵安裝
swoole 4.4.3
建議使用 Ubuntu14、CentOS7 或更高版本的操作系統(tǒng)
Swoole-1.x需要 PHP-5.3.10 或更高版本
Swoole-4.x需要 PHP-7.0.0 或更高版本
單數(shù)版本為特性新增版本,主要工作是新增功能特性、代碼重構(gòu)、結(jié)構(gòu)調(diào)整??赡軙?huì)帶來(lái)一些BUG
雙數(shù)版本為問(wèn)題修復(fù)版本,主要工作是修復(fù)現(xiàn)有的已知問(wèn)題、提升性能、完善細(xì)節(jié)。穩(wěn)定性更高
swoole安裝方式
第一種
--enable-swoole 編譯 php直接編譯進(jìn)去
第二種
pecl install swoole
第三種
docker 安裝
第四種(推薦)
下載 :http://pecl.php.net/package/swoole
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --enable-openssl --enable-http2 --enable-sockets --enable-mysqlnd
編譯參數(shù) : https://wiki.swoole.com/wiki/page/437.html
make && make install
extension = swoole.so
php -m 或者 phpinfo()
php --ri swoole
Swoole的絕大部分功能只能用于cli命令行環(huán)境,請(qǐng)首先準(zhǔn)備好Linux Shell環(huán)境。
進(jìn)程和線程
進(jìn)程是一個(gè)具有一定獨(dú)立功能的程序在一個(gè)數(shù)據(jù)集上的一次動(dòng)態(tài)執(zhí)行的過(guò)程,是操作系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位,是應(yīng)用程序運(yùn)行的載體。
線程是程序執(zhí)行中一個(gè)單一的順序控制流程,是程序執(zhí)行流的最小單元,是處理器調(diào)度和分派的基本單位。一個(gè)進(jìn)程可以有一個(gè)或多個(gè)線程。
1. 線程是程序執(zhí)行的最小單位,而進(jìn)程是操作系統(tǒng)分配資源的最小單位;
2. 一個(gè)進(jìn)程由一個(gè)或多個(gè)線程組成,線程是一個(gè)進(jìn)程中代碼的不同執(zhí)行路線
3. 進(jìn)程之間相互獨(dú)立,但同一進(jìn)程下的各個(gè)線程之間共享程序的內(nèi)存空間(包括代碼段,數(shù)據(jù)集,堆等)及一些進(jìn)程級(jí)的資源(如打開(kāi)文件和信號(hào)等),某進(jìn)程內(nèi)的線程在其他進(jìn)程不可見(jiàn);
4. 調(diào)度和切換:線程上下文切換比進(jìn)程上下文切換要快得多
5 線程天生的共享內(nèi)存空間,線程間的通信更簡(jiǎn)單,避免了進(jìn)程IPC引入新的復(fù)雜度。
進(jìn)程開(kāi)銷大 線程開(kāi)銷小
php實(shí)現(xiàn)多進(jìn)程
pcntl是php官方的多進(jìn)程擴(kuò)展,只能在linux環(huán)境使用 --enable-pcntl
pcntl_fork — 在當(dāng)前進(jìn)程當(dāng)前位置產(chǎn)生分支(子進(jìn)程)
fork是創(chuàng)建了一個(gè)子進(jìn)程,父進(jìn)程和子進(jìn)程 都從fork的位置開(kāi)始向下繼續(xù)執(zhí)行,不同的是父進(jìn)程執(zhí)行過(guò)程中,得到的fork返回值為子進(jìn)程 號(hào),而子進(jìn)程得到的是0。
$pid = pcntl_fork();
if($pid==0){
echo '我是子進(jìn)程 id:'.getmypid().PHP_EOL;
}else{
echo '我也是子進(jìn)程 '.$pid;
}
進(jìn)程間的通信
在各個(gè)進(jìn)程中,內(nèi)存空間都是不一致的,各個(gè)變量都是在不同的內(nèi)存空間
$str = 'lampol';
$pid = pcntl_fork();
if($pid>0){
$str.='111111';
echo $str.PHP_EOL; //lampol111111
}else{
echo $str; //lampol
}
進(jìn)程間空間獨(dú)立 數(shù)據(jù)不能共享
管道通信
消息隊(duì)列通信
進(jìn)程信號(hào)通信
共享內(nèi)存通信,映射一段能被其他進(jìn)程所訪問(wèn)的內(nèi)存,這段共享內(nèi)存由一個(gè)進(jìn)程創(chuàng)建,但多個(gè)進(jìn)程都可以訪問(wèn)。共享內(nèi)存是最快的 IPC(進(jìn)程間通信) 方式,它是針對(duì)其他進(jìn)程間通信方式運(yùn)行效率低而專門(mén)設(shè)計(jì)的。它往往與其他通信機(jī)制,如信號(hào)量,配合使用,來(lái)實(shí)現(xiàn)進(jìn)程間的同步和通信。
套接字通信
第三方通信,使用文件操作,mysql,redis等方法也可實(shí)現(xiàn)通信
多線程
PHP 默認(rèn)并不支持多線程,要使用多線程需要安裝 pthread 擴(kuò)展,而要安裝 pthread 擴(kuò)展,必須使用 --enable-maintainer-zts 參數(shù)重新編譯 PHP,這個(gè)參數(shù)是指定編譯 PHP 時(shí)使用線程安全方式。
下載pthreads
wget http://pecl.php.net/get/pthreads-3.1.6.tgz
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
extension =pthreads.so
線程安全
多線程是讓程序變得不安分的一個(gè)因素,在使用多線程之前,首先要考慮線程安全問(wèn)題:
線程安全:線程安全是編程中的術(shù)語(yǔ),指某個(gè)函數(shù)、函數(shù)庫(kù)在多線程環(huán)境中被調(diào)用時(shí),能夠正確地處理多個(gè)線程之間的共享變量,使程序功能正確完成。
PHP 實(shí)現(xiàn)的線程安全主要是使用 TSRM 機(jī)制對(duì) 全局變量和靜態(tài)變量進(jìn)行了隔離,將全局變量和靜態(tài)變量 給每個(gè)線程都復(fù)制了一份,各線程使用的都是主線程的一個(gè)備份,從而避免了變量沖突,也就不會(huì)出現(xiàn)線程安全問(wèn)題。
聯(lián)系客服