
目标
swoole与现有框架结合
推荐(免费):swoole
风格
环境
HTTP Server
# 查看SWOOLE版本 $ php -r 'echo SWOOLE_VERSION;' 4.3.1
基础概念
HTTP报文
关于HTTP请求报文的组成结构

HTTP请求报文结构
POST /search HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, application/x-shockwave-flash, */* Referer: http://www.google.cn/ Accept-Language: zh-cn Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld) Host: www.google.cn Connection: Keep-Alive Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g; NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y- FxlRugatx63JLv7CWMD6UB_O_r hl=zh-CN&source=hp&q=domety
关于HTTP响应报文的组成结构

HTTP响应报文结构
HTTP/1.1 200 OK Date: Mon, 23 May 2005 22:38:34 GMT Content-Type: text/html; charset=UTF-8 Content-Encoding: UTF-8 Content-Length: 138 Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux) ETag: "3f80f-1b6-3e1cb03b" Accept-Ranges: bytes Connection: close
创建HTTP服务器
Swoole在1.7.7版本后内置HTTP服务器,可创建一个异步非阻塞多进程的HTTP服务器。Swoole的HTTP服务器对HTTP协议支持的并不完整,建议仅作为应用服务器,并在前端增加Nginx作为代理。
因为Swoole是在CLI命令行中执行的,在传统的NGINX+FastCGI模式下很多root的shell是无法执行的,而使用Swoole服务器就能很好的控制rsync、git、svn等。
使用Swoole的API,构建HTTP服务器需要4个步骤
# 创建应用 $ mkdir test && cd test # 创建并编辑服务器文件 $ vim server.php
<?php
//创建HTTP服务器对象
$host = &amp;amp;quot;0.0.0.0&amp;amp;quot;;
$port = 9501;
$server = new swoole_http_server($host, $port);
var_dump($server);
//设置服务器运行参数
$configs = [];
$configs[&amp;amp;quot;worker_num&amp;amp;quot;] = 2;//设置Worker工作进程数量
$configs[&amp;amp;quot;daemonize&amp;amp;quot;] = 0;//设置是否已后台守护进程运行
$server->set($configs);
//注册监听客户端HTTP请求回调事件
$server->on(&amp;amp;quot;request&amp;amp;quot;, function(swoole_http_request $request, swoole_http_response $response) use($server){
var_dump($request);
var_dump($response);
//获取客户端文件描述符
$fd = $request->fd;
if(!empty($fd)){
//获取连接信息
$clientinfo = $server->getClientInfo($fd);
var_dump($clientinfo);
//获取收包时间
var_dump($clientinfo[&amp;amp;quot;last_time&amp;amp;quot;]);
}
//响应客户端HTTP请求
$response->write(&amp;amp;quot;success&amp;amp;quot;);//向客户端写入响应数据
$response->end();//浏览器中输出结果
});
//启动服务器
$server->start();# 使用PHP-CLI运行服务器脚本 $ php server.php # 使用CURL向HTTP服务器发送请求测试 $ curl 127.0.0.1:9501
使用注意
echo、var_dump、print_r的内容是在服务器中输出的$rp->end(string $contents),end()方法只能调用一次。$rp->write(string $content)方法swoole_http_request对象中swoole_http_response对象进行封装并发送HTTP服务器的本质
由于swoole_http_server是基于swoole_server的,所以swoole_server下的方法在swoole_http_server中都可以使用,只是swoole_http_server只能被客户端唤起。简单来说,swoole_http_server是基于swoole_server加上HTTP协议,再加上request和response类库去实现请求数据和获取数据。与PHP-FPM不同的是,Web服务器收到请求后会传递给Swoole的HTTP服务器,直接返回请求。

swoole_http_server
Swoole\HTTP\Server继承自Server,是一个HTTP服务器实现,支持同步与有异步两种模式。无论是同步模式还是异步模式,HTTP服务器都可以维持大量的TCP客户端连接,同步与异步仅仅提现在对请求的处理方式。
同步模式等同于Nginx+PHP-FPM/Apache,需要设置大量Worker工作进程来完成并发请求处理,Worker工作进程可以使用同步阻塞IO,编程方式与普通的PHP的Web程序完全一致。与PHP-FPM/Apache不同的是,客户端连接并不会独占进程,服务器依然可以应对大量并发连接。
异步模式下整个HTTP服务器是异步非阻塞的,服务器可以应答大规模的并发连接和并发请求,编程方式需要完全使用异步API,如MySQL、Redis、HTTP客户端、file_get_contents、sleep等阻塞IO操作必须切换为异步方式,如异步Client、Event、Timer等API。
查看HTTP服务器实例对象
var_dump($server);
object(Swoole\Connection\Iterator)#2 (0) {
[&amp;amp;quot;host&amp;amp;quot;]=>string(7) &amp;amp;quot;0.0.0.0&amp;amp;quot;
[&amp;amp;quot;port&amp;amp;quot;]=>int(9501)
[&amp;amp;quot;type&amp;amp;quot;]=>int(1)
[&amp;amp;quot;mode&amp;amp;quot;]=>int(2)
[&amp;amp;quot;ports&amp;amp;quot;]=>
array(1) {
[0]=>
object(Swoole\Server\Port)#3 (16) {
[&amp;amp;quot;onConnect&amp;amp;quot;:&amp;amp;quot;Swoole\Server\Port&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;onReceive&amp;amp;quot;:&amp;amp;quot;Swoole\Server\Port&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;onClose&amp;amp;quot;:&amp;amp;quot;Swoole\Server\Port&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;onPacket&amp;amp;quot;:&amp;amp;quot;Swoole\Server\Port&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;onBufferFull&amp;amp;quot;:&amp;amp;quot;Swoole\Server\Port&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;onBufferEmpty&amp;amp;quot;:&amp;amp;quot;Swoole\Server\Port&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;onRequest&amp;amp;quot;:&amp;amp;quot;Swoole\Server\Port&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;onHandShake&amp;amp;quot;:&amp;amp;quot;Swoole\Server\Port&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;onOpen&amp;amp;quot;:&amp;amp;quot;Swoole\Server\Port&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;onMessage&amp;amp;quot;:&amp;amp;quot;Swoole\Server\Port&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;host&amp;amp;quot;]=>string(7) &amp;amp;quot;0.0.0.0&amp;amp;quot;
[&amp;amp;quot;port&amp;amp;quot;]=>int(9501)
[&amp;amp;quot;type&amp;amp;quot;]=>int(1)
[&amp;amp;quot;sock&amp;amp;quot;]=>int(4)
[&amp;amp;quot;setting&amp;amp;quot;]=>NULL
[&amp;amp;quot;connections&amp;amp;quot;]=>object(Swoole\Connection\Iterator)#4 (0) {
}
}
}
[&amp;amp;quot;master_pid&amp;amp;quot;]=>int(0)
[&amp;amp;quot;manager_pid&amp;amp;quot;]=>int(0)
[&amp;amp;quot;worker_id&amp;amp;quot;]=>int(-1)
[&amp;amp;quot;taskworker&amp;amp;quot;]=>bool(false)
[&amp;amp;quot;worker_pid&amp;amp;quot;]=>int(0)
[&amp;amp;quot;onRequest&amp;amp;quot;:&amp;amp;quot;Swoole\Http\Server&amp;amp;quot;:private]=>NULL
[&amp;amp;quot;onHandshake&amp;amp;quot;:&amp;amp;quot;Swoole\Http\Server&amp;amp;quot;:private]=>NULL
}配置选项
upload_tmp_dir HTTP服务器支持大文件上传,但由于Swoole底层的限制,文件内容是存放在内存中的,因此如果并发上传大量文件可能会导致内存占用量过大的问题。
可以修改upload_tmp_dir选项用于配置上传文件的临时目录,需要注意是目录文件夹的名称最大长度不得超过220个字节。
$configs = []; $configs[&amp;amp;quot;upload_tmp_dir&amp;amp;quot;] = &amp;amp;quot;/data/uploads/&amp;amp;quot;; $server->set($configs);
POST解析http_parse_post
可通过修改http_parse_post配置项用来设置表单POST提交后是否解析,若设置为true则表示会自动将Content-Type内容类型为x-www-urlencode的请求包体解析到 POST 数组,若设置为false则表示将会关闭 POST解析。
$configs = []; $configs[&amp;amp;quot;http_parse_post&amp;amp;quot;] = true; $server->set($configs);
POST尺寸 package_max_length
默认情况下,表单上传或POST提交2MB的数据的限制,可通过修改package_max_length选项调整POST尺寸大小。
$configs = []; $configs[&amp;amp;quot;package_max_length&amp;amp;quot;] = 2*1024; $server->set($configs);
解析Cookiehttp_parse_cookie
通过修改http_parse_cookie配置项可以开启或关闭Cookie解析,关闭后将会在Header头信息学中保留未经处理的原始Cookies信息。
$configs = []; $configs[&amp;amp;quot;http_parse_cookie&amp;amp;quot;] = true; $server->set($configs);
http_compression http_compression适用于Swoole4.1.0+版本,用于启用或关闭对HTTP信息的压缩,默认为开启状态。
由于http-chunk不支持分段独立压缩,因此默认已强制关闭了压缩功能。
$configs = []; $configs[&amp;amp;quot;http_compression&amp;amp;quot;] = false; $server->set($configs);
目前HTTP支持gzip、br(需google brotli库支持)、deflate三种压缩格式,Swoole底层会根据客户端浏览器传入的Accept-Encoding头信息自动选择压缩方式。
http_compression_level http_compression_level选项用于配置压缩的级别,压缩级别越高压缩后体积越小,同时也会越占用CPU。
$configs = []; $configs[&amp;amp;quot;http_compression_level&amp;amp;quot;] = 1; $server->set($configs);
document_root document_root选项适用于Swoole1.9.17+版本,用于配置静态文件的根目录,该功能由于较为简易不推荐在公网环境下直接使用,常于enable_static_handler选项配合使用。
如果设置document_root和enable_static_handler = true后,Swoole底层收到HTTP请求时会先判断document_root的路径下是否存在某静态文件,如果存在会直接发送内容给客户端,并不再调用onRequest函数。
这里需要注意的时,在使用静态文件处理特性时,应当将动态PHP代码于静态文件进行隔离,静态文件应存放到特定的目录下。
$configs = []; $configs[&amp;amp;quot;document_root&amp;amp;quot;] = &amp;amp;quot;/app&amp;amp;quot;; $server->set($configs);
enable_static_handler enable_static_handler选项用于开启或关闭静态文件请求处理功能,常配合document_root选项使用。
$configs = []; $configs[&amp;amp;quot;enable_static_handler&amp;amp;quot;] = true; $server->set($configs);
static_handler_locations static_handler_location选项适用于Swoole4.4.0+版本,用于设置静态处理器的路径,类型为数组,默认不启用。
静态处理器类似于Nginx的location指令,可以指定一个或多个路径为静态路径。只有URL在指定路径下才会启用静态问而建处理器,否则会视为动态请求。location选项必须以/开头并支持多级路径,如/app/images。
当启用static_handler_locations选项后,如果请求对应的文件不存在,将直接会返回404错误。
$configs = []; $configs[&amp;amp;quot;static_handler_locations&amp;amp;quot;] = [&amp;amp;quot;/static&amp;amp;quot;, &amp;amp;quot;/public/assets&amp;amp;quot;]; $server->set($configs);
由于swoole_http_server对HTTP协议支持的并不完整,建议仅仅作为应用服务器,并在前端增加Nginx作为反向代理。
操作前需要修改服务器的运行参数,设置enable_static_handle为true后,底层收到HTTP请求会像判断document_root路径下是否存在目标文件,若存在则会直接发送文件给客户端,不再触发onRequest回调。
$ vim server.php
$configs = []; $configs[&amp;amp;quot;enable_static_handler&amp;amp;quot;] = true; $configs[&amp;amp;quot;document_root&amp;amp;quot;] = &amp;amp;quot;/test&amp;amp;quot;; $server->set($configs);
例如:设置Nginx反向代理127.0.0.1:9501
$ vim /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] &amp;amp;quot;$request&amp;amp;quot; '
# '$status $body_bytes_sent &amp;amp;quot;$http_referer&amp;amp;quot; '
# '&amp;amp;quot;$http_user_agent&amp;amp;quot; &amp;amp;quot;$http_x_forwarded_for&amp;amp;quot;';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream swoole{
server 127.0.0.1:9501;
keepalive 4;
}
server {
listen 80;
server_name www.swoole.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://swoole;
proxy_set_header Connection &amp;amp;quot;&amp;amp;quot;;
proxy_http_version 1.1;
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}Nginx+Swoole的组合中Nginx反向代理的配置
server {
root /data/wwwroot/;
server_name local.swoole.com;
location / {
proxy_http_version 1.1;
proxy_set_header Connection &amp;amp;quot;keep-alive&amp;amp;quot;;
proxy_set_header X-Real-IP $remote_addr;
if (!-e $request_filename) {
proxy_pass http://127.0.0.1:9501;
}
}
}请求对象
swoole_http_request请求对象保存了HTTP客户端请求的相关信息,包括GET、POST、COOKIE、Header等,请求对象$request销毁时会自动删除上传的临时文件,不要使用&amp;amp;符号引用$request请求对象。
var_dump($request);
object(Swoole\Http\Request)#6 (10) {
[&amp;amp;quot;fd&amp;amp;quot;]=>int(1)
[&amp;amp;quot;streamId&amp;amp;quot;]=>int(0)
[&amp;amp;quot;header&amp;amp;quot;]=>array(3) {
[&amp;amp;quot;host&amp;amp;quot;]=>string(14) &amp;amp;quot;127.0.0.1:9501&amp;amp;quot;
[&amp;amp;quot;user-agent&amp;amp;quot;]=>string(11) &amp;amp;quot;curl/7.52.1&amp;amp;quot;
[&amp;amp;quot;accept&amp;amp;quot;]=>string(3) &amp;amp;quot;*/*&amp;amp;quot;
}
[&amp;amp;quot;server&amp;amp;quot;]=>array(10) {
[&amp;amp;quot;request_method&amp;amp;quot;]=>string(3) &amp;amp;quot;GET&amp;amp;quot;
[&amp;amp;quot;request_uri&amp;amp;quot;]=>string(1) &amp;amp;quot;/&amp;amp;quot;
[&amp;amp;quot;path_info&amp;amp;quot;]=>string(1) &amp;amp;quot;/&amp;amp;quot;
[&amp;amp;quot;request_time&amp;amp;quot;]=>int(1561689532)
[&amp;amp;quot;request_time_float&amp;amp;quot;]=>float(1561689533.0563)
[&amp;amp;quot;server_port&amp;amp;quot;]=>int(9501)
[&amp;amp;quot;remote_port&amp;amp;quot;]=>int(51188)
[&amp;amp;quot;remote_addr&amp;amp;quot;]=>string(9) &amp;amp;quot;127.0.0.1&amp;amp;quot;
[&amp;amp;quot;master_time&amp;amp;quot;]=>int(1561689532)
[&amp;amp;quot;server_protocol&amp;amp;quot;]=>string(8) &amp;amp;quot;HTTP/1.1&amp;amp;quot;
}
[&amp;amp;quot;request&amp;amp;quot;]=>NULL
[&amp;amp;quot;cookie&amp;amp;quot;]=>NULL
[&amp;amp;quot;get&amp;amp;quot;]=>NULL
[&amp;amp;quot;files&amp;amp;quot;]=>NULL
[&amp;amp;quot;post&amp;amp;quot;]=>NULL
[&amp;amp;quot;tmpfiles&amp;amp;quot;]=>NULL
}HTTP请求的头部信息,类型为数组,所有的键名均为小写。
$host = $request->header[&amp;amp;quot;host&amp;amp;quot;]; $accept = $request->header[&amp;amp;quot;accept&amp;amp;quot;];
Http\Request->$server
HTTP请求相关的服务器信息,相当于PHP的$_SERVER全局数组,包含了HTTP请求的方法、URL路径、客户端IP等信息。服务器信息为关联数组,数组中的键名全部小写,并且与PHP的$_SERVER数组保持一致。
$request_method = $request->server[&amp;amp;quot;request_method&amp;amp;quot;]; $request_time = $request->server[&amp;amp;quot;request_time&amp;amp;quot;]; $request_uri = $request->server[&amp;amp;quot;request_uri&amp;amp;quot;];
请求路径
当Google的Chrome浏览器访问服务器是会产生两次请求,这是因为Chrome会自动请求一次favicon.ico文件,所以服务器会收到两个HTTP请求,通过打印$request->server[&amp;quot;request_uri&amp;quot;]可以查看到请求URL路径。如果需要屏蔽掉对favicon.ico的请求,可采用以下方式。
$uri = $request->server[&amp;amp;quot;request_uri&amp;amp;quot;];
if($uri == &amp;amp;quot;/favicon.icon&amp;amp;quot;)
{
$respoonse->status(404);
$response->end();
}收包时间
request_time请求时间是在Worker工作进程中设置的,在SWOOLE_PROCESS多进程模式下存在dispatch分发的过程,因此可能会与实际收包时间存在偏差,尤其当请求量超过服务器处理能力时,有可能滞后于实际收包时间。
可通过Server->getClientInfo()方法获取last_time以获取 准确的收包时间。
//获取客户端文件描述符
$fd = $request->fd;
if(!empty($fd)){
//获取连接信息
$clientinfo = $server->getClientInfo($fd);
var_dump($clientinfo);
//获取收包时间
var_dump($clientinfo[&amp;amp;quot;last_time&amp;amp;quot;]);
}客户端信息
Server->getClientInfo()用于获取连接的客户端信息
bool|array Server->getClientInfo(int $fd, int $extraData, bool $ignoreError = false)
int $fd 表示客户端连接文件描述符int $extraData 表示扩展信息是保留参数目前无任何效果bool $ignoreError 表示是否忽略错误,若设置为true表示即使连接关闭也会返回连接信息。如果传入的$fd客户端连接文件描述符存在则返回一个数组,若不存在或已关闭则返回false。
array(10) {
[&amp;amp;quot;server_port&amp;amp;quot;]=>int(9501)
[&amp;amp;quot;server_fd&amp;amp;quot;]=>int(4)
[&amp;amp;quot;socket_fd&amp;amp;quot;]=>int(12)
[&amp;amp;quot;socket_type&amp;amp;quot;]=>int(1)
[&amp;amp;quot;remote_port&amp;amp;quot;]=>int(51194)
[&amp;amp;quot;remote_ip&amp;amp;quot;]=>string(9) &amp;amp;quot;127.0.0.1&amp;amp;quot;
[&amp;amp;quot;reactor_id&amp;amp;quot;]=>int(0)
[&amp;amp;quot;connect_time&amp;amp;quot;]=>int(1561690606)
[&amp;amp;quot;last_time&amp;amp;quot;]=>int(1561690606)
[&amp;amp;quot;close_errno&amp;amp;quot;]=>int(0)
}Http\Request->$get
HTTP请求的GET参数,相当于PHP中的$_GET,格式为键值对的关联数组。为防止HASH攻击,GET参数最大不允许超过128个。
$get = $request->get;//获取HTTP请求的所有GET参数
HTTP的GET请求只有一个HTTP Header头,Swowole底层使用固定大小的内存缓冲区为8K,而且不可修改。如果请求不是正确的HTTP请求,将会出现错误,底层会抛出错误。
WARN swReactorThead_onReceive_http_request: http header is too long.
Http\Request->$post
HTTP请求携带POST参数,格式为键值对的关联数组,POST与Header加起来的尺寸不得超过package_max_length的设置,否则会认为是恶意请求,另外POST参数的个数不得超过128个。
$post = $request->post;
由于POST文件上传时最大尺寸收到package_max_length配置项目的限制,默认为2MB,可以调用swoole_server->set传入新值修改尺寸。
由于Swoole底层是全内存的,因此如果设置过大可能会导致大量并发请求,将服务器资源耗尽。
设置计算方法:最大内存占用 = 最大并发请求数量 * package_max_length
当使用CURL发送POST请求时服务器端会超时
CURL在发送较大的POST请求时会首先发送一个100-continue的请求,当收到服务器的回应才会发送实际的POST数据。然后swoole_http_server并不支持100-continue,因此会导致CURL请求超时。解决的办法时关闭CURL的100-continue。
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1);//设置为POST方式 curl_setopt($ch, CURLOPT_HTTPHEADER, [&amp;amp;quot;Exception:&amp;amp;quot;]); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
Http\Request->$cookie
HTTP请求携带的COOKIE信息,格式为键值对的关联数组。
Http\Request->$files
HTTP请求携带的文件上传信息,类型为以form表单名称为key键名的二维数组,与PHP原生的$_FILES相同,最大文件尺寸不得超过package_max_length中设置的值,不要使用Swoole\Http\Server处理大文件上传。
$files = $request->files; var_dump($files);
array(5) {
[name] => facepalm.jpg
[type] => image/jpeg
[tmp_name] => /tmp/swoole.upfile.n3FmFr
[error] => 0
[size] => 15476
}name表示浏览器上传时传入的文件名称type表示浏览器上传时的MIME类型tmp_name 表示浏览器上传的临时文件,文件名默认以/tmp/swoole.upfile开头。size表示上传文件的尺寸Swoole1.9.10+版本支持is_uploaded_file和move_uploaded_file函数。当HTTP请求对象$request对象销毁时,会自动删除上传的临时文件。
Http\Request->rawContent()
rawContent表示获取原始的POST包体,用于非application/x-www-form-urlencode格式的HTTP的POST请求。等同于原生PHP的fopen(&amp;quot;php://input&amp;quot;),有时服务器不需要解析HTTP的POST请求参数。
Swoole1.7.18+版本增加了http_parse_post配置用于关闭或开启POST数据解析。
string HTTP\Request->rawContent();
Http\Request->getData()
getData()方法用于获取完整的HTTP请求报文,包括 Http Header和`HTTP Body消息体。
function swoole_http_request_getData() : string
getData需要Swoole1.10.3或Swoole2.1.2或更高的版本。
响应对象
swoole_http_response响应对象是进程隔离的,不能跨越进程或对象。如果是当前进程中,想使用fd文件描述符保存response响应对象、存储上下文,可使用PHP全局数组变量来保存。
swoole_http_response响应对象,通过调用此对象的方法实现HTTP响应的发送,当响应对象销毁时,如果没有调用end发送HTTP响应,底层会自动执行end方法。不要使用&amp;amp;符号引用$response对象。
object(Swoole\Http\Response)#7 (4) {
[&amp;amp;quot;fd&amp;amp;quot;]=>int(1)
[&amp;amp;quot;header&amp;amp;quot;]=>NULL
[&amp;amp;quot;cookie&amp;amp;quot;]=>NULL
[&amp;amp;quot;trailer&amp;amp;quot;]=>NULL
}HTTP服务器Response响应对象,通过调过此对象的方法,实现HTTP响应发送。当Response对象销毁时,如果未调用则直接调用end方法,不要使用&amp;amp;符号引用$response对象。
Http\Response->header
function Http\Response->header( string $key, string $value, bool $ucworods = true )
header方法用于设置HTTP响应的Header头信息,如果设置失败返回false,设置成功则无返回值。
string $key 表示HTTP头的Keystring $value 表示HTTP头的Valuebool $ucwords 表示是否需要对Key进行HTTP约定格式化,默认true会自动格式化。$response->header(&amp;amp;quot;Content-Type&amp;amp;quot;, &amp;amp;quot;image/jpeg&amp;amp;quot;, true);
跨域处理
$origin = $request->header['origin'];
// Access-Control-Allow-Origin 不能使用 *,这样修改是不支持php版本低于7.0的。
// $response->header('Access-Control-Allow-Origin', '*');
$response->header('Access-Control-Allow-Origin', $origin);
$response->header('Access-Control-Allow-Methods', 'OPTIONS');
$response->header('Access-Control-Allow-Headers', 'x-requested-with,session_id,Content-Type,token,Origin');
$response->header('Access-Control-Max-Age', '86400');
$response->header('Access-Control-Allow-Credentials', 'true');
if ($request->server['request_method'] == 'OPTIONS') {
$response->status(200);
$response->end();
return;
};Http\Response->cookie
cookie方法用来设置HTTP响应的Cookie信息,方法参数与原生PHP的setcookie函数完全一致。
function Http\Response->cookie( string $key, string $value = &amp;amp;quot;&amp;amp;quot;, int $expire = 0, string $path = &amp;amp;quot;/&amp;amp;quot;, string $domain = &amp;amp;quot;&amp;amp;quot;, bool $secure = false, bool $httponly = false )
Cookie设置必须在end方法之前方才生效,Swoole底层自动会对$value进行urlencode编码处理,同时允许设置多个相同的$key的Cookie。
Http\Response->status
swoole_http_response->status( int $http_status_code )
status方法用于发送HTTP状态码,$http_status_code必须是合法的HTTP状态码,如2xx、3xx、4xx、5xx等,若不是在会报错,另外status方法也必须在$response->end()之前执行方才生效。
string $url表示跳转的新地址会作为HTTP Header头中的Location选项进行发送int $http_code 表示状态码,默认为302临时跳转,传入301表示永久跳转。Http\Response->redirect
redirect方法适用于Swoole2.2.0+版本,用于发送HTTP跳转,调用后会自动执行end方法并发送结束响应。
function Http\Response->redirect( string $url, int $http_code = 302 )
例如
$server = new swoole_http_server(&amp;amp;quot;0.0.0.0&amp;amp;quot;, 9501, SWOOLE_BASE);
$server->on(&amp;amp;quot;request&amp;amp;quot;, function(swoole_http_request $request, swoole_http_response $response){
$url = &amp;amp;quot;http://www.baidu.com&amp;amp;quot;;
$response->redirect($url, 301);
});
$server->start();Http\Response->write
write方法用于启用HTTP的chunk分段以向浏览器发送相应的内容,使用write分段发送数据后end方法将不再接收任何参数,调用end方法后会发送一个长度为0的分段chunk表示数据传输完毕。
bool Http\Response->write(string $data)
参数$data表示要发送的数据内容,最大长度不得超过2MB,受buffer_output_size配置项控制。
Http\Response->sendfile
sendfile用于发送文件到浏览器
function Http\Response->sendfile( string $filename, int $offset = 0, int $length = 0 )
string $filename 表示要发送的文件名称,文件不存在或没有访问权限则会发送失败。int $offset 表示上传文件的偏移量,可以指定从文件在中间部分开始传输数据,用于断点续传,适用于Swoole1.9.11+。int $length 表示发送数据的尺寸,默认为整个文件的尺寸,适用于Swoole1.9.11+。$response->header(&amp;amp;quot;Content-Type&amp;amp;quot;, &amp;amp;quot;image/jpeg&amp;amp;quot;); $filepath = $request->server[&amp;amp;quot;request_uri&amp;amp;quot;]; $filename = __DIR__.$filepath; $response->sendfile($filename);
由于Swoole底层无法推断要发送文件的媒体类型MIME格式,因此需要应用程序指定Content-Type。调用sendfile前不得使用write方法发送HTTP数据段Chunk,调用sendfile后Swoole底层会自动执行end方法,另外sendfile不支持gzip压缩。
Http\Response->end
end方法用于发送HTTP响应体,并结束请求处理。
function Http\Response->end(string $html);
end方法只能调用一次,如果需要分多次向客户端发送数据下需使用write方法,send操作后将会向客户端浏览器发送HTML内容。如果客户端开启了KeepAlive连接会保持,服务器会等待下一次请求。如果没有开启KeepAlive服务器将会切断连接。
Http\Response->detach
detach表示分离响应对应,调用后$response对象销毁时将不会自动执行end方法,一般detach会与Http\Response::create以及Server::send配合使用,适用于Swoole2.2.0+版本。
function Http\Response->detach():bool
detach方法操作后,若客户端已经完成响应则会返回true,否则返回false。
detach应用于跨进程响应
在某些情况下需要在Task任务进程中对客户端发出响应,此时可以利用detach方法使$response对象独立,如此一来在Task任务进程中就可以重新构建$response对象以发起HTTP请求响应。
<?php
//创建HTTP服务器对象
$host = &amp;amp;quot;0.0.0.0&amp;amp;quot;;
$port = 9501;
$server = new swoole_http_server($host, $port);
//设置服务器运行参数
$configs = [];
$configs[&amp;amp;quot;worker_num&amp;amp;quot;] = 1;//设置Worker工作进程数量
$configs[&amp;amp;quot;task_worker_num&amp;amp;quot;] = 1;//设置Task任务进程数量
$configs[&amp;amp;quot;daemonize&amp;amp;quot;] = 0;//设置是否已后台守护进程运行
$server->set($configs);
//注册客户端请求处理回调函数
$server->on(&amp;amp;quot;request&amp;amp;quot;, function(swoole_http_request $request, swoole_http_response $response) use($server){
//分离响应对象
$response->detach();
//在Task任务进程中对客户端发出响应
$fd = strval($response->fd);
$server->task($fd);
});
//注册异步任务处理回调函数
$server->on(&amp;amp;quot;task&amp;amp;quot;, function(swoole_http_server $server, $worker_id, $data){
//创建响应对象
$response = swoole_http_response::create($data);
//向客户端发送响应
$html = &amp;amp;quot;in task&amp;amp;quot;;
$response->end($html);
});
//注册Task异步任务执行完毕回调函数
$server->on(&amp;amp;quot;finish&amp;amp;quot;, function(){
echo &amp;amp;quot;[finish] task&amp;amp;quot;.PHP_EOL;
});
//启动服务器
$server->start();detach方法应用于发送任意内容
在某些特殊场景下,需要对客户端发送特殊的响应内容,Http\Response对象自带的end方法无法满足需求,可以使用detach方法分离响应对象,然后自行组包并使用Server::send方法发送数据。
<?php
//创建HTTP服务器对象
$host = &amp;amp;quot;0.0.0.0&amp;amp;quot;;
$port = 9501;
$server = new swoole_http_server($host, $port);
//设置服务器运行参数
$configs = [];
$configs[&amp;amp;quot;worker_num&amp;amp;quot;] = 2;//设置Worker工作进程数量
$configs[&amp;amp;quot;daemonize&amp;amp;quot;] = 0;//设置是否已后台守护进程运行
$server->set($configs);
//注册监听客户端HTTP请求回调事件
$server->on(&amp;amp;quot;request&amp;amp;quot;, function(swoole_http_request $request, swoole_http_response $response) use($server){
//分离响应对象
$response->detach();
//自行组包并使用Server::send方法发送数据
$fd = $response->fd;
$message = &amp;amp;quot;HTTP/1.1 200 OK\r\n&amp;amp;quot;;
$message .= &amp;amp;quot;Server: server\r\n&amp;amp;quot;;
$message .= &amp;amp;quot;\r\n&amp;amp;quot;;
$message .= &amp;amp;quot;Hello World\n&amp;amp;quot;;
$server->send($fd, $message);
});
//启动服务器
$server->start();Http\Response::create
create静态方法用于构造新的Http\Response响应对象,使用前必须调用detach方法将旧有$response对象分离,否则 可能会造成同一个请求发送两次响应内容。
function Http\Response::createE(int $fd) : Http\Response
create静态方法的参数$fd表示需要绑定连接的文件描述符,调用Http\Response对象的end方法和write方法时会向此连接发送数据。如果调用成功则返回一个新的Http\Response对象,否则失败返回false,适用于Swoole2.2.0+版本。
注册事件回调函数
Http\Server注册事件回调函数于Http\Server->on相同,不同之处在于HTTP\Server->on不接受onConnect和onReceive回调设置,Http\Server->on会额外接受一种新的事务类型onRequest。
onRequest 事件
onRequest事件适用于Swoole1.7.7+版本,当服务器收到一个完整的HTTP请求后会调用onRequest函数。
$server->on(&amp;amp;quot;request&amp;amp;quot;, function(swoole_http_request $request, swoole_http_response $response) use($server){
$html = &amp;amp;quot;success&amp;amp;quot;;
$response->end($html);
});onRequest回调函数共有两个参数
swoole_http_requst $request HTTP请求信息对象,包含了Header/GET/POST/Cookie等信息。swoole_http_response $response HTTP响应信息对象,支持Cookie/Header/Status等HTTP操作。在onRequest回调函数返回时会销毁$request和$response对象,如果未执行$response->end()操作,Swoole底层会自动执行一次$response->end("")。
$request和$response对象在传递给其它函数时,是不需要添加&amp;amp;取地址的引用符号的,传递后引用计数会增加,当onRequest退出时并不会被销毁。
案例
$ vim http_server.php
<?php
$addr = &amp;amp;quot;0.0.0.0&amp;amp;quot;;
$port = 9501;
$svr = new swoole_http_server($addr, $port);
$svr->on(&amp;amp;quot;request&amp;amp;quot;, function(swoole_http_request $rq, swoole_http_response $rp){
//处理动态请求
$path_info = $rq->server[&amp;amp;quot;path_info&amp;amp;quot;];
$file = __DIR__.$path_info;
echo &amp;amp;quot;\nfile:{$file}&amp;amp;quot;;
if(is_file($file) &amp;amp;amp;&amp;amp;amp; file_exists($file)){
$ext = pathinfo($path_info, PATHINFO_EXTENSION);
echo &amp;amp;quot;\next:{$ext}&amp;amp;quot;;
if($ext == &amp;amp;quot;php&amp;amp;quot;){
ob_start();
include($file);
$contents = ob_get_contents();
ob_end_clean();
}else{
$contents = file_get_contents($file);
}
echo &amp;amp;quot;\ncontents:{$contents}&amp;amp;quot;;
$rp->end($contents);
}else{
$rp->status(404);
$rp->end(&amp;amp;quot;404 not found&amp;amp;quot;);
}
});
$svr->start();# 创建静态文件 $ vim index.html index.html # 测试静态文件 $ curl 127.0.0.1:9501/index.html # 观察http_server输出 file:/home/jc/projects/swoole/chat/index.html ext:html contents:index.html # 测试动态文件 $ vim index.php <?php echo &amp;amp;quot;index.php&amp;amp;quot;; #观察http_server日志输出 file:/home/jc/projects/swoole/chat/index.php ext:php contents:index.php
获取动态请求的参数
$ vim http_server.php
<?php
$addr = &amp;amp;quot;0.0.0.0&amp;amp;quot;;
$port = 9501;
$svr = new swoole_http_server($addr, $port);
$svr->on(&amp;amp;quot;request&amp;amp;quot;, function(swoole_http_request $rq, swoole_http_response $rp){
//获取请求参数
$params = $rq->get;
echo &amp;amp;quot;\nparams:&amp;amp;quot;.json_encode($params);
//处理动态请求
$path_info = $rq->server[&amp;amp;quot;path_info&amp;amp;quot;];
$file = __DIR__.$path_info;
echo &amp;amp;quot;\nfile:{$file}&amp;amp;quot;;
if(is_file($file) &amp;amp;amp;&amp;amp;amp; file_exists($file)){
$ext = pathinfo($path_info, PATHINFO_EXTENSION);
echo &amp;amp;quot;\next:{$ext}&amp;amp;quot;;
if($ext == &amp;amp;quot;php&amp;amp;quot;){
ob_start();
include($file);
$contents = ob_get_contents();
ob_end_clean();
}else{
$contents = file_get_contents($file);
}
echo &amp;amp;quot;\ncontents:{$contents}&amp;amp;quot;;
$rp->end($contents);
}else{
$rp->status(404);
$rp->end(&amp;amp;quot;404 not found&amp;amp;quot;);
}
});
$svr->start();测试带参数的请求
$ curl 127.0.0.1:9501?k=v
观察请求参数的输出
params:{&amp;amp;quot;k&amp;amp;quot;:&amp;amp;quot;v&amp;amp;quot;}
file:/home/jc/projects/swoole/chat/index.html
ext:html
contents:index.html静态文件处理
$ vim mimes.php
<?php
return [
&amp;amp;quot;jpg&amp;amp;quot;=>&amp;amp;quot;image/jpeg&amp;amp;quot;,
&amp;amp;quot;jpeg&amp;amp;quot;=>&amp;amp;quot;image/jpeg&amp;amp;quot;,
&amp;amp;quot;bmp&amp;amp;quot;=>&amp;amp;quot;image/bmp&amp;amp;quot;,
&amp;amp;quot;ico&amp;amp;quot;=>&amp;amp;quot;image/x-icon&amp;amp;quot;,
&amp;amp;quot;gif&amp;amp;quot;=>&amp;amp;quot;image/gif&amp;amp;quot;,
&amp;amp;quot;png&amp;amp;quot;=>&amp;amp;quot;image/png&amp;amp;quot;,
&amp;amp;quot;css&amp;amp;quot;=>&amp;amp;quot;text/css&amp;amp;quot;,
&amp;amp;quot;html&amp;amp;quot;=>&amp;amp;quot;text/html&amp;amp;quot;,
&amp;amp;quot;xml&amp;amp;quot;=>&amp;amp;quot;text/xml&amp;amp;quot;,
&amp;amp;quot;bin&amp;amp;quot;=>&amp;amp;quot;application/octet-stream&amp;amp;quot;,
&amp;amp;quot;js&amp;amp;quot;=>&amp;amp;quot;application/javascript&amp;amp;quot;,
&amp;amp;quot;tar&amp;amp;quot;=>&amp;amp;quot;application/x-tar&amp;amp;quot;,
&amp;amp;quot;ppt&amp;amp;quot;=>&amp;amp;quot;application/vnd.ms-powerpoint&amp;amp;quot;,
&amp;amp;quot;pdf&amp;amp;quot;=>&amp;amp;quot;application/pdf&amp;amp;quot;,
&amp;amp;quot;swf&amp;amp;quot;=>&amp;amp;quot;application/x-shockwave-flash&amp;amp;quot;,
&amp;amp;quot;zip&amp;amp;quot;=>&amp;amp;quot;application/x-zip-compressed&amp;amp;quot;
];$ vim http_server.php
<?php
//创建HTTP服务器
$addr = &amp;amp;quot;0.0.0.0&amp;amp;quot;;
$port = 9501;
$srv = new swoole_http_server($addr, $port);
//设置HTTP服务器参数
$cfg = [];
$cfg[&amp;amp;quot;worker_num&amp;amp;quot;] = 4;//设置工作进程数量
$cfg[&amp;amp;quot;daemonize&amp;amp;quot;] = 0;//守护进程化,程序转入后台。
$srv->set($cfg);
//处理请求
$srv->on(&amp;amp;quot;request&amp;amp;quot;, function(swoole_http_request $rq, swoole_http_response $rp) use($srv){
//获取请求文件信息与文件后缀
$path_info = $rq->server[&amp;amp;quot;path_info&amp;amp;quot;];
$ext = pathinfo($path_info, PATHINFO_EXTENSION);
//文件是否存在
$file = __DIR__.$path_info;
if(!is_file($file) || !file_exists($file)){
$rp->status(404);
$rp->end(&amp;amp;quot;404 NOT FOUND&amp;amp;quot;);
}
//处理静态请求
if($ext != &amp;amp;quot;php&amp;amp;quot;){
//设置响应头信息的内容内容
$mimes = include(&amp;amp;quot;mimes.php&amp;amp;quot;);
$rp->header(&amp;amp;quot;Content-Type&amp;amp;quot;, $mimes[$ext]);
//获取静态文件内容
$contents = file_get_contents($file);
//返回内容
$rp->end($contents);
}
});
//启动服务
$srv->start();发送请求,浏览器访问127.0.0.1:9501/test.jpeg,查看图片。
面向对象
$ vim http_server.php
<?php
class HttpServer
{
public static function run($host, $port, $options=[])
{
$srv = new swoole_http_server($host, $port);
if(!empty($options)){
$srv->set($options);
}
$srv->on(&amp;amp;quot;request&amp;amp;quot;, function(swoole_http_request $rq, swoole_http_response $rp) use($srv){
$rp->end(&amp;amp;quot;test&amp;amp;quot;);
$srv->close($rq->fd);
});
$srv->start();
}
}
HttpServer::run(&amp;amp;quot;127.0.0.1&amp;amp;quot;, 9501, [&amp;amp;quot;worker_num&amp;amp;quot;=>2, &amp;amp;quot;daemonize&amp;amp;quot;=>0]);压力测试
使用Apache Bench工具进行压力测试可以发现,swoole_http_server远超过PHP-FPM、Golang自带的HTTP服务器、Node.js自带的HTTP服务器,性能接近Nginx的静态文件处理。
Swoole的http server与PHP-FPM的性能对比
安装Apache的压测工作ab
$ sudo apt install apache2-util
使用100个客户端跑1000次,平均每个客户端10个请求。
$ ab -c 100 -n 1000 127.0.0.1:9501/index.php
Concurrency Level: 100
Time taken for tests: 0.480 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 156000 bytes
HTML transferred: 9000 bytes
Requests per second: 2084.98 [#/sec] (mean)
Time per request: 47.962 [ms] (mean)
Time per request: 0.480 [ms] (mean, across all concurrent requests)
Transfer rate: 317.63 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 3.0 0 12
Processing: 4 44 10.0 45 57
Waiting: 4 44 10.1 45 57
Total: 16 45 7.8 45 57
Percentage of the requests served within a certain time (ms)
50% 45
66% 49
75% 51
80% 52
90% 54
95% 55
98% 55
99% 56
100% 57 (longest request)观察可以发现QPS可以达到 Requests per second: 2084.98 [#/sec] (mean)。
HTTP SERVER 配置选项
swoole_server::set()用于设置swoole_server运行时的各项参数化。
$cfg = []; // 处理请求的进程数量 $cfg[&amp;amp;quot;worker_num&amp;amp;quot;] = 4; // 守护进程化 $cfg[&amp;amp;quot;daemonize&amp;amp;quot;] = 1; // 设置工作进程的最大任务数量 $cfg[&amp;amp;quot;max_request&amp;amp;quot;] = 0; $cfg[&amp;amp;quot;backlog&amp;amp;quot;] = 128; $cfg[&amp;amp;quot;max_request&amp;amp;quot;] = 50; $cfg[&amp;amp;quot;dispatch_mode&amp;amp;quot;] = 1; $srv->set($cfg);
配置HTTP SERVER参数后测试并发
$ vim http_server.php
<?php
//创建HTTP服务器
$addr = &amp;amp;quot;0.0.0.0&amp;amp;quot;;
$port = 9501;
$srv = new swoole_http_server($addr, $port);
//设置HTTP服务器参数
$cfg = [];
$cfg[&amp;amp;quot;worker_num&amp;amp;quot;] = 4;//设置工作进程数量
$cfg[&amp;amp;quot;daemonize&amp;amp;quot;] = 1;//守护进程化,程序转入后台。
$srv->set($cfg);
$srv->on(&amp;amp;quot;request&amp;amp;quot;, function(swoole_http_request $rq, swoole_http_response $rp){
//获取请求参数
$params = $rq->get;
echo &amp;amp;quot;\nparams:&amp;amp;quot;.json_encode($params);
//处理动态请求
$path_info = $rq->server[&amp;amp;quot;path_info&amp;amp;quot;];
$file = __DIR__.$path_info;
echo &amp;amp;quot;\nfile:{$file}&amp;amp;quot;;
if(is_file($file) &amp;amp;amp;&amp;amp;amp; file_exists($file)){
$ext = pathinfo($path_info, PATHINFO_EXTENSION);
echo &amp;amp;quot;\next:{$ext}&amp;amp;quot;;
if($ext == &amp;amp;quot;php&amp;amp;quot;){
ob_start();
include($file);
$contents = ob_get_contents();
ob_end_clean();
}else{
$contents = file_get_contents($file);
}
echo &amp;amp;quot;\ncontents:{$contents}&amp;amp;quot;;
$rp->end($contents);
}else{
$rp->status(404);
$rp->end(&amp;amp;quot;404 not found&amp;amp;quot;);
}
});
//启动服务
$srv->start();查看进程
$ ps -ef|grep http_server.php root 16224 1207 0 22:41 ? 00:00:00 php http_server.php root 16225 16224 0 22:41 ? 00:00:00 php http_server.php root 16227 16225 0 22:41 ? 00:00:00 php http_server.php root 16228 16225 0 22:41 ? 00:00:00 php http_server.php root 16229 16225 0 22:41 ? 00:00:00 php http_server.php root 16230 16225 0 22:41 ? 00:00:00 php http_server.php root 16233 2456 0 22:42 pts/0 00:00:00 grep --color=auto http_server.php
查看后台守护进程
$ ps axuf|grep http_server.php root 16622 0.0 0.0 21536 1044 pts/0 S+ 22:46 0:00 | | \_ grep --color=auto http_server.php root 16224 0.0 0.3 269036 8104 ? Ssl 22:41 0:00 \_ php http_server.php root 16225 0.0 0.3 196756 8440 ? S 22:41 0:00 \_ php http_server.php root 16227 0.0 0.6 195212 14524 ? S 22:41 0:00 \_ php http_server.php root 16228 0.0 0.6 195212 14524 ? S 22:41 0:00 \_ php http_server.php root 16229 0.0 0.6 195212 14524 ? S 22:41 0:00 \_ php http_server.php root 16230 0.0 0.6 195212 14524 ? S 22:41 0:00 \_ php http_server.php $ ps auxf|grep http_server.php|wc -l 7
杀死后台进程
# 强杀后台进程
$ kill -9 $(ps aux|grep swoole|grep -v grep|awk '{print $2}')
$ kill -9 16224
$ kill -9 16225
$ kill -9 16227
$ kill -9 16228
$ kill -9 16229
$ kill -9 16230
# 重启后台进程
$ kill -10 $(ps aux|grep http_server|grep -v grep|awk '{print $2}')压测
$ ab -c 100 -n 1000 127.0.0.1:9501/index.php
Server Software: swoole-http-server
Server Hostname: 127.0.0.1
Server Port: 9501
Document Path: /index.php
Document Length: 9 bytes
Concurrency Level: 100
Time taken for tests: 0.226 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 156000 bytes
HTML transferred: 9000 bytes
Requests per second: 4417.72 [#/sec] (mean)
Time per request: 22.636 [ms] (mean)
Time per request: 0.226 [ms] (mean, across all concurrent requests)
Transfer rate: 673.01 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 2.8 0 11
Processing: 4 21 7.2 20 49
Waiting: 1 21 7.2 20 49
Total: 5 22 7.6 20 56
Percentage of the requests served within a certain time (ms)
50% 20
66% 23
75% 25
80% 26
90% 30
95% 38
98% 45
99% 53
100% 56 (longest request)观察可以发现QPC为Requests per second: 4417.72 [#/sec] (mean)。
性能优化
使用swoole_http_server服务后,若发现服务的请求耗时监控毛刺十分严重,接口耗时波动较大的情况,可以观察下服务的响应包response的大小,若响应包超过1~2M甚至更大,则可判断是由于包太多而且很大导致服务响应波动较大。
为什么响应包惠导致相应的时间波动呢?主要有两个方面的影响,第一是响应包太大导致Swoole之间进程通信更加耗时并占用更多资源。第二是响应包太大导致Swoole的Reactor线程发包更加耗时。
以上就是Swoole与HTTP的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号