× 警告!旧版文档已经暂停维护,请查看新版文档。点击前往新版文档

Http\Server

Http\ServerHttp协议的支持并不完整,建议仅作为应用服务器。并且在前端增加Nginx作为代理

1.7.7版本增加了内置Http服务器的支持,通过几行代码即可写出一个异步非阻塞多进程的Http服务器。

$http = new Swoole\Http\Server("127.0.0.1", 9501);
$http->on('request', function ($request, $response) {
    $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>");
});
$http->start();

通过使用apache bench工具进行压力测试,在Inter Core-I5 4核 + 8G内存的普通PC机器上,Http\Server可以达到近11QPS。远远超过php-fpmGolangNode.js自带Http服务器。性能几乎接近与Nginx的静态文件处理。

ab -c 200 -n 200000 -k http://127.0.0.1:9501/

使用 Http2 协议

  • 使用SSL下的Http2协议必须安装openssl, 且需要高版本openssl必须支持TLS1.2ALPNNPN
  • 编译时需要使用--enable-http2开启
./configure --enable-openssl --enable-http2

设置Http服务器的open_http2_protocoltrue

$serv = new Swoole\Http\Server("127.0.0.1", 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
$serv->set([
    'ssl_cert_file' => $ssl_dir . '/ssl.crt',
    'ssl_key_file' => $ssl_dir . '/ssl.key',
    'open_http2_protocol' => true,
]);

nginx+swoole配置

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 (!-e $request_filename) {
             proxy_pass http://127.0.0.1:9501;
        }
    }
}

通过读取$request->header['x-real-ip']来获取客户端的真实IP


  • 愚安

    测了一下 确实比node的要快好多

  • chris_guojn

    把打印去掉,因为你打印的东西没有报的错

  • 小马哥

    是不是只有用nginx代理 HttpServer服务才可以用呢

  • 键盘侠

    这个nginx的配置有点问题吧,那个location里面的if判断是不是应该不要呢。

  • 木子

    [闭嘴]proxy_pass 是不能放在 if 里面的吧! nginx[5555]: Starting nginx: nginx: [emerg] "proxy_set_header" directive is not allowed here in ...

  • 开飞机的小蜗牛

    到处都看到在宣传 Swoole 性能比其他语言实现(nodejs golang)要高,都是异步,为什么 Swoole 性能就会比其它的高呢,希望有人从代码或者实现上面分析下。

  • Rango-韩天峰

    Swoole的高性能是因为Server逻辑代码全部使用C语言实现,并且使用了全内存缓存和异步IO。Node.js默认是单线程的无法利用全部CPU,Golang的协程调度本身有一定性能消耗。

  • 渡边至秦

    proxy_http_version 1.1;proxy_set_header Connection "keep-alive";放在if语句里面会报错

  • 骑龟上阵

    onRequest 收到一个http请求是不是就会分配一个worker进程处理 ?然后这个worker进程在 response->end 前都一直被占用不能再处理别的请求了?

  • 郝多

    ERROR swPort_onRead_http(:417): recv from connection#17 failed. Error: Software caused connection abort[113] 这是什么鬼?

  • 郝多

    swoole 1.8.5beta,cygwin下 ,http_server 用ab发送10w次ok,但是通过chrome连续刷新几十次后后会导致服务器端不停滚动抛错“ERROR swPort_onRead_http(:417): recv from connection#14 failed. Error: Software caused connection abort[113].”,不中断程序,滚动不停,咋回事?用的官网例子

  • 郝多

    ab -k:keep alive,保持连接相当于长连接进行ab压力测试,,这样得出测试结果没说服力

  • 韦元晓

    的确 -k 参数挺耍流氓的, 实际上的高并发是多用户的高并发,而不是一个连接内多个请求的并发。测试要根据实际情况来进行。

  • 韦元晓

    我认为目前要推广swoole,就要解决广大PHPer的痛点,我认为痛点在于是否可以使用swoole调用目前各种现成的php 服务程序(基于各种框架tp laravel symphony...等),可以不再依赖于Apache/nginx, 而同时又能无缝使用swoole的高效率,异步等特点。

    毕竟,用swoole在web服务之外写一些服务程序,属于锦上添花功能,并非第一痛点。

    也许我孤陋寡闻了。没有完全理解swoole的思想及能力。不知道博主怎么看。

  • 半夏

    说的很有道理,支持一下

  • 宗霖

    我也认为这个是一个比较好的方案。在http的环节,如何无缝的和yii tp laravel 框架结合而不依赖于nginx,实现类似node js 或者golang 及openresty 常作的业务层,是一个比较好的方向。对比了swoole和wokerman,都主要集中在了socket server上。

  • Rango-韩天峰

    压测必须要增加-k参数,不使用-k,那么所有程序很大部分消耗都在处理连接的connect/close上,不同软件的性能差异降低了。增加-k参数排除了connect/close的消耗,剩下就是对比不同软件的处理能力了。

  • 龙飞_无锡

    用nginx+swoole配置的方式跑ab 到nginx,在本机还是产生大量的127.0.0.1:9501 TIME_WAIT 连接,直接ab到127.0.0.1:9501 没有这个问题,ab通过nginx proxy到另外一个nginx也没问题

  • 晕咗

    应该是有人需要这个的(用纯 swoole_http_server 启动web然后转发给php-fpm处理,支持DOCKER): https://github.com/cmptech/cmp_app_server/blob/master/cmp_app_server.php https://github.com/cmptech/cmp_app_server/blob/master/PhpfpmClient.php https://github.com/cmptech/cmp/blob/master/app_root/webroot/cmp_root_controller.php

  • 晕咗

    看我下面的评论。能解决你说的问题。我们自己的项目就在用

  • 鬼眼

    遇到一个比较棘手的问题。我们打算在正式环境里使用swoole的http server。 正常的get post请求swoole可以相应。 但是如果使用 purge 这类非正常http头来请求。swoole不回应,也不断开连接。 这容易被攻击。应该断开链接吧?

  • 马驰

    放在大括号外面来即可

  • keaixiaou

    基于swoole的异步非阻塞框架zapi:欢迎大神们提意见https://github.com/keaixiaou/zapi

  • TT

    go 的gc一直在优化,恐怖现在再来一次对比,swoole比不上咯~

  • Rango-韩天峰

    GC不是性能瓶颈,主要开销在于协程的调度。

  • TT

    协程的调度开销相对于线程和进程已经小很多了吧,当swoole在业务上需要实现高并发的时候底层是通过什么调度呢,例如一个请求给到worker处理的时候,里面涉及到很多io操作,go是通过派生协程实现异步处理,swoole可以通过几个异步函数进行处理,也可以通过add_event_loop进行异步处理,两者的开销,哪个大一点

  • keaixiaou

    请求有post参数,但是request 里没有,什么样的情况下会出现这种情况,nginx版本1.4.4,swoole 1.9.1

  • 郎明

    这个nginx简直就是误导人,文件不存在转到swoole处理什么啊!

  • 小六HI

    gitHub地址已经不存在了,能不能重新分享地址?

  • 奔跑吧!羊驼!

    TP兴许有问题,不过laravel symfony,尤其是symfony,别说无缝了,简直是救星,symfony最大问题在于初始化过程大量的装载和配置解析非常浪费性能,而且每次执行都要重复一次,虽然有缓存,但是毕竟问题还在,这个就完美解决而且平滑过度,主要是现在swoole看到实际商用的项目不多,自己玩玩还好,真正上公司项目就是怕到时候会不会有什么意料之外的问题。

  • oldchiken

    在这里处理php会更快吗????

  • 借口!/ty

    他能应用在生产环境,配合nginx当服务器用吗

  • jianrun

    运行 /Applications/XAMPP/xamppfiles/bin/ab -n 500 -c 5 http://127.0.0.1:8080/ 后 报错 ERROR swReactorKqueue_del(:238): kqueue->del(211, SW_EVENT_WRITE) failed. Error: No such file or directory[2].

    code: //创建服务 $http = new Swoole\Http\Server($config['server']['ip'], $config['server']['port']); $http->set([ 'worker_num' => 100, 'max_request' => 10, // 'daemonize' => true, // 'pid_file' => ROOTPATH . '/server.pid', ]);

    //监听请求 $http->on('request', function ($request, $response) { return; }); 什么业务逻辑都没写就报错,是怎么回事

  • 胜不了的是自己

    使用SwooleHttpServer第一次请求OK,第二次就打不开,并且报下面这个:

    [2017-10-20 09:55:42 #12491.0]  WARNING swConnection_sendfile (ERROR 505): length or offset is invalid.
    [2017-10-20 09:55:42 #12491.0]  WARNING swConnection_sendfile (ERROR 505): length or offset is invalid.
    [2017-10-20 09:55:42 #12491.0]  WARNING swConnection_sendfile (ERROR 505): length or offset is invalid.
    [2017-10-20 09:55:42 #12491.0]  WARNING swConnection_sendfile (ERROR 505): length or offset is invalid.
    [2017-10-20 09:55:42 #12491.0]  WARNING swConnection_sendfile (ERROR 505): length or offset is invalid.
    

    发现的现象: 1. firefox浏览器 勾上 禁用缓存 也没问题。 2. 在每个静态文件后面加一个随机版本号,也没问题。

    这是什么问题呀?怎么处理?总不能真在每个静态文件后面加一个随机版本号吧。

  • cslistener

    Nginx配合Swoole HTTP Server跑服务,我是这样配的: 静态文件(img/css/js等)由Nginx处理,其他请求交给Swoole处理.

    server {
        listen 80;
        server_name test.swoole.com;
    
        root /opt/php/www/test.swoole.com/public_html;
        index index.html index.htm;
    
        location / {
            # 如果$uri对应的文件存在,在Nginx返回文件,否则把请求交给Swoole处理
            try_files $uri @swoole;
        }
    
        location @swoole {
            proxy_pass http://127.0.0.1:8080;
            proxy_http_version 1.1;
            proxy_set_header Connection "keep-alive";
            # Swoole通过$req->header['x-real-ip']拿到该参数
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_set_header Host $host;
        }
    }
    

  • 雪雨丶冰

    swReactorKqueue_del(:238): kqueue->del(47, SW_EVENT_WRITE) failed. Error: No such file or directory[2]. 我是websocket服务都是正常的,但是日志里一直打印这个错误(本地mac环境下的,服务器上并没有)

  • swoole first

    $request get方法没有得到参数

  • shen

    大神们 都有nginx和apache了 为啥还要用swoole_http_server 它的应用场景是啥啊

  • Jack.yin

    @shen 场景就是以swoole的方式,处理http! (:

  • 二狗

    nginx配置一直不成功。我看有的教程下可以通过 域名+端口 的形式,获取php端输出的内容。该怎么配置啊。搞了一天了。

  • 问天涯

    nginx 能转发到 websocket端口吗?

  • 15558133685

    @问天涯 可以

  • 18986008649

    swoole并发超过一定数量就很慢,是什么限制了速度?并发12000,0.5秒,20000要10多秒了 完整问题在这里描述了https://segmentfault.com/q/1010000021276437