当前位置:首页 > PHP > 正文内容

php端口复用,php socket端口复用

高老师6年前 (2019-11-04)PHP15535

第一次听说端口复用是在mixphp最新版本中发现的,mixphp启动监听9501端口,现在作者说可以多开几个进程来执行mixphp,我心里想了下再启动不是会端口冲突嘛,但是却没有问题,于是下载mixphp的源码解读,原来是启动http服务器使用new Co\Http\Server('0.0.0.0', 80, false, true); swoole这个http构造方法第4个参数是是否开启端口复用,这样就能多个进程来监听相同端口。底层负载调度由linux自动处理。切记需要linux3.10以上内核才支持。我们来做个试验。

【一】.基于swoole的端口复用

(1).创建t1.php:监听80端口

go(function () {
    $server = new Co\Http\Server('0.0.0.0', 80, false, true);
    $server->handle('/', function ($request, $response) {
        $response->end("<h1>T1 is work!</h1>");
        echo 'replay from T1' . PHP_EOL;
    });
    $server->start();
});

(2).创建t2.php:监听80端口

go(function () {
    $server = new Co\Http\Server('0.0.0.0', 80, false, true);
    $server->handle('/', function ($request, $response) {
        $response->end("<h1>T2 is work!</h1>");
        echo 'replay from T2' . PHP_EOL;
    });
    $server->start();
});

(3).通过ab.exe并发请求:

./ab.exe -n 1000 -c 1000 http://127.0.0.1/

(4).查看服务器php脚本输出:

replay from T2
replay from T1
replay from T2
replay from T1
replay from T1
replay from T2
replay from T1
replay from T2
replay from T1

(5).关闭t1脚本继续访问80端口:

replay from T2
replay from T2
replay from T2

通过上面的验证我们可以知道端口复用能够提高多核利用率,提高socket的处理能力,同时也实现了高可用,一个进程意外退出,其他继续工作,不需要重新建立socket句柄。另外端口重用解决了端口占用不能及时释放的问题,不释放我们可以直接重用。

【二】.基于原生socket的端口复用

(1).创建w1.php:监听8484端口

// 设置IP
$host = '0.0.0.0';

// 设置端口
$port = 8484;

// 创建socket
$listen_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// 设置端口复用
socket_set_option($listen_socket, SOL_SOCKET, SO_REUSEPORT, 1);

// 绑定端口
socket_bind($listen_socket, $host, $port);

// 监听socket
socket_listen($listen_socket);

// 事件轮询
while (true)
{
    // 客户端
    $client = socket_accept($listen_socket);

    // 向客户端发送消息
    $msg = "This is w1\r\n";

    // 记录响应来自哪个进程
    echo 'replay from W1' . PHP_EOL;

    //发送消息
    socket_write($client, $msg, strlen($msg));

    //关闭客户端
    socket_close($client);
}
socket_close($listen_socket);

(2).创建w2.php:监听8484端口

// 设置IP
$host = '0.0.0.0';

// 设置端口
$port = 8484;

// 创建socket
$listen_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// 设置端口复用
socket_set_option($listen_socket, SOL_SOCKET, SO_REUSEPORT, 1);

// 绑定端口
socket_bind($listen_socket, $host, $port);

// 监听socket
socket_listen($listen_socket);

// 事件轮询
while (true)
{
    // 客户端
    $client = socket_accept($listen_socket);

    // 向客户端发送消息
    $msg = "This is w2\r\n";

    // 记录响应来自哪个进程
    echo 'replay from W2' . PHP_EOL;

    //发送消息
    socket_write($client, $msg, strlen($msg));

    //关闭客户端
    socket_close($client);
}
socket_close($listen_socket);

(3).并发后两个脚本的输出:

replay from W1
replay from W1
replay from W1
replay from W1
replay from W1
replay from W1
replay from W1
replay from W1
replay from W1
replay from W2
replay from W2
replay from W2
replay from W2
replay from W2
replay from W2
replay from W2
replay from W2
replay from W2
replay from W2
replay from W2

Linux底层会自动负载均衡。

注意事项:

linux内核必须大于等于3.10以上

windows下的php原生socket不支持端口复用。

windows下的linux子系统wsl1暂时对内核实现不完整,测试不出负载调度效果。

扫描二维码推送至手机访问。

版权声明:本文由高久峰个人博客发布,如需转载请注明出处。

本文链接:https://blog.20230611.cn/post/111.html

分享给朋友:

“php端口复用,php socket端口复用” 的相关文章

PHP跨域问题最佳解决方案

PHP跨域问题最佳解决方案

1、允许单个域名访问指定某域名(http://client.runoob.com)跨域访问,则只需在http://server.runoob.com/server.php文件头部添加如下代码:header('Access-Control-Allow-Origin:http://client....

 php抽象类和接口作用

php抽象类和接口作用

【一】.抽象类假设如下场景:团队准备开发某网站,表建好了,页面设计好了.A组负责开发底层数据库操作类(DB),B组负责调用DB类.但是此时A组发生了争执,MySQL? Oracle? DB2? sqlite?到底使用什么数据库?B组.... 进入漫长的等待.解决方法:A组和B组 先定1个数据库类的模...

php创建webservice,php搭建webservice,php编写webservice

php创建webservice,php搭建webservice,php编写webservice

第一步:服务端文件<?php $wsdlfile='webservice.wsdl'; ini_set('soap.wsdl_cache_enabled','0');    //关闭WSDL缓存 //001...

php arrayaccess的应用场景:配置管理器

php arrayaccess的应用场景:配置管理器

上篇文章已经讲解arrayacces的原理,现在来讲解下arrayaccess的实际应用。一个大型的互联网项目中必然会存在各种配置信息,例如多种数据库信息:mysql,tidb,mongodb,redis,某个业务模块单独的配置信息如比例,额度等等,那么该如何治理配置信息?PHP项目中大部分的框架都...

PHP Startup: Unable to load dynamic library 'C:\php\ext\php_curl.dll找不到指定的模块

PHP Startup: Unable to load dynamic library 'C:\php\ext\php_curl.dll找不到指定的模块

最近在编写windows php多线程的东西,从官网下载了PHP的线程安全版,尝试开启curl扩展extension=php_curl.dllphp -m 却提示 PHP Startup: Unable to load dynamic library 'C:\php\ext\php_curl...

PHP最快方式模拟curl,PHP最快爬虫模拟方法

PHP最快方式模拟curl,PHP最快爬虫模拟方法

有时候我们需要爬一个接口,但是这个接口需要很多参数,包括header和cookie要去编写,使用php curl模拟实在太慢。我们可以通过浏览器的network来复制请求为curl命令。例如我需要模拟请求接口地址:https://www.xkmz.cc/Ajax/Debug/delly,我们只需要在...