easyswoole用ioc重写系统日志类

easyswoole 3.3.7

定义自己的日志类

<?php

namespace App\Ioc;

use EasySwoole\Log\LoggerInterface;
use EasySwoole\Log\Logger;

class Log implements LoggerInterface
{

    private $logger;

    function __construct()
    {
        $this->logger = new Logger(EASYSWOOLE_LOG_DIR);
    }

    function log(?string $msg,int $logLevel = self::LOG_LEVEL_INFO,string $category = 'debug')
    {
        return $this->logger->log($msg, $logLevel, $category);
    }

    function console(?string $msg,int $logLevel = self::LOG_LEVEL_INFO,string $category = 'debug')
    {
        var_dump($msg);
        $this->logger->console($msg, $logLevel, $category);
    }
}

IOC覆盖系统日志类

项目根目录创建文件 bootstrap.php

<?php

use App\Ioc\Log;
use EasySwoole\Component\Di;
use EasySwoole\EasySwoole\SysConst;

Di::getInstance()->set(SysConst::LOGGER_HANDLER, Log::class);

分析

EasySwoole\EasySwoole\Core.php

查看源码中的registerErrorHandler方法

....
        //初始化配置Logger
        $logger = Di::getInstance()->get(SysConst::LOGGER_HANDLER);
        if(!$logger instanceof LoggerInterface){
            $logger = new DefaultLogger(EASYSWOOLE_LOG_DIR);
        }
        Logger::getInstance($logger);

        //初始化追追踪器
        $trigger = Di::getInstance()->get(SysConst::TRIGGER_HANDLER);
        if(!$trigger instanceof TriggerInterface){
            $trigger = new DefaultTrigger(Logger::getInstance());
        }
        Trigger::getInstance($trigger);

        //在没有配置自定义错误处理器的情况下,转化为trigger处理
        $errorHandler = Di::getInstance()->get(SysConst::ERROR_HANDLER);
        if(!is_callable($errorHandler)){
            $errorHandler = function($errorCode, $description, $file = null, $line = null){
                $l = new Location();
                $l->setFile($file);
                $l->setLine($line);
                Trigger::getInstance()->error($description,$errorCode,$l);
            };
        }
        set_error_handler($errorHandler);
....

查看 easyswoole-事件文档

查看 easyswoole-生命周期

easyswoole之消息队列nqs

easyswoole版本: 3.3.7

文档提供有安装和docker-compose示例代码,启动的时候会报告错误(如果你不调试可能也看不到错误).

错误1: TOPIC_NOT_FOUND 你需要先创建一个topic 登录到nqs中创建

错误2: UPSTREAM_ERROR: Failed to query any nsqlookupd 这个时候应该是没有数据需要执行命令 curl -d 'hello world 2' 'http://127.0.0.1:4151/pub?topic=test'

错误3: [2020-06-24 09:28:50][debug][warning]:[Swoole\Client::recv(): recv() failed. Error: Resource temporarily unavailable [11] at file:/var/www/eseckill/vendor/easyswoole/nsq/src/Connection/AbstractMonitor.php line:52 作者回应是断线问题, 需要自己处理断线重连.

相关资料

官方文档
github-nqs

easyswoole自义命令加载自定义配置文件

需求: 目前框架默认只会加载两个配置文件 dev.php 和 produce.php 只有本地开发和线上生产两个环境, 但是现在需要一个线上测试环境的配置.

版本: easyswoole-3.3.7

loadEnv 加载配置文件的方法

启动命令

启动命令会执行loadEnv方法, 我们自己复制Command/DefaultCommand/Start.php 文件加载自己的配置文件覆盖之前的配置

在自己的项目中 App/Command/test.php 增加一个文件 如何自定义命令点我

<?php
/**
 * Created by PhpStorm.
 * User: yf
 * Date: 2019-01-24
 * Time: 23:44
 */

namespace EasySwoole\EasySwoole\Command\DefaultCommand;

use EasySwoole\EasySwoole\Command\CommandInterface;
use EasySwoole\EasySwoole\Command\Utility;
use EasySwoole\EasySwoole\Config;
use EasySwoole\EasySwoole\Core;
use EasySwoole\EasySwoole\ServerManager;
use EasySwoole\EasySwoole\SysConst;

class Start implements CommandInterface
{

    public function commandName(): string
    {
        // TODO: Implement commandName() method.
        return 'start';
    }

    public function exec(array $args): ?string
    {
        // TODO: Implement exec() method.
        Utility::opCacheClear();
        $response = Utility::easySwooleLog();
        $mode = 'develop';
        if (!Core::getInstance()->isDev()) {
            $mode = 'produce';
        }
        $conf = Config::getInstance();
        if (in_array("d", $args) || in_array("daemonize", $args)) {
            $conf->setConf("MAIN_SERVER.SETTING.daemonize", true);
        }
        //create main Server
        Core::getInstance()->globalInitialize()->createServer();
        //重点这一行
        Config::getInstance()->loadEnv( EASYSWOOLE_ROOT.'/test.php');
        $serverType = $conf->getConf('MAIN_SERVER.SERVER_TYPE');
        switch ($serverType) {
            case EASYSWOOLE_SERVER:
                {
                    $serverType = 'SWOOLE_SERVER';
                    break;
                }
            case EASYSWOOLE_WEB_SERVER:
                {
                    $serverType = 'SWOOLE_WEB';
                    break;
                }
            case EASYSWOOLE_WEB_SOCKET_SERVER:
                {
                    $serverType = 'SWOOLE_WEB_SOCKET';
                    break;
                }
            case EASYSWOOLE_REDIS_SERVER:
                {
                    $serverType = 'SWOOLE_REDIS';
                    break;
                }
            default:
                {
                    $serverType = 'UNKNOWN';
                }
        }
        $response = $response . Utility::displayItem('main server', $serverType) . "\n";
        $response = $response . Utility::displayItem('listen address', $conf->getConf('MAIN_SERVER.LISTEN_ADDRESS')) . "\n";
        $response = $response . Utility::displayItem('listen port', $conf->getConf('MAIN_SERVER.PORT')) . "\n";
        $list = ServerManager::getInstance()->getSubServerRegister();
        $index = 1;
        foreach ($list as $serverName => $item) {
            if (empty($item['setting'])) {
                $type = $serverType;
            } else {
                $type = $item['type'] % 2 > 0 ? 'SWOOLE_TCP' : 'SWOOLE_UDP';
            }
            $response = $response . Utility::displayItem("sub server:{$serverName}", "{$type}@{$item['listenAddress']}:{$item['port']}") . "\n";
            $index++;
        }
        $ips = swoole_get_local_ip();
        foreach ($ips as $eth => $val) {
            $response = $response . Utility::displayItem('ip@' . $eth, $val) . "\n";
        }

        $data = $conf->getConf('MAIN_SERVER.SETTING');
        if(empty($data['user'])){
            $data['user'] = get_current_user();
        }

        if(!isset($data['daemonize'])){
            $data['daemonize'] = false;
        }

        foreach ($data as $key => $datum){
            $response = $response . Utility::displayItem($key,$datum) . "\n";
        }

        $response = $response . Utility::displayItem('swoole version', phpversion('swoole')) . "\n";
        $response = $response . Utility::displayItem('php version', phpversion()) . "\n";
        $response = $response . Utility::displayItem('easy swoole', SysConst::EASYSWOOLE_VERSION) . "\n";
        $response = $response . Utility::displayItem('develop/produce', $mode) . "\n";
        $response = $response . Utility::displayItem('temp dir', EASYSWOOLE_TEMP_DIR) . "\n";
        $response = $response . Utility::displayItem('log dir', EASYSWOOLE_LOG_DIR) . "\n";
        echo $response;
        Core::getInstance()->start();
        return null;
    }

    public function help(array $args): ?string
    {
        // TODO: Implement help() method.
        $logo = Utility::easySwooleLog();
        return $logo . <<<HELP_START
\e[33mOperation:\e[0m
\e[31m  php easyswoole start [arg1] [arg2]\e[0m
\e[33mIntro:\e[0m
\e[36m  to start current easyswoole server \e[0m
\e[33mArg:\e[0m
\e[32m  daemonize \e[0m                   run in daemonize
\e[32m  produce \e[0m                     load produce.php
HELP_START;
    }
}

linux参数调优之swoole

连接数优化、系统内核调优

ulimit -n 文件最大打开数 单个进程能支持最大的 fd 取决于 ulimit -n 的值 参考资料

net.ipv4.tcp_mem  =   379008       505344  758016 
net.ipv4.tcp_wmem = 4096        16384   4194304
net.ipv4.tcp_rmem = 4096          87380   4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216

sysctl -a 查看全部参数
sysctl -N [参数] 参数是否存在
sysctl -n [参数] 查看参数的值
sysctl -w arg=value # -w arg=value arg表示内核参数,value表示设置值。给内核参数临时设置一个值

net.ipv4.tcp_mem

#确定 TCP 栈应该如何反映内存使用;每个值的单位都是内存页(通常是 4KB)
#第一个值是内存使用的下限
#第二个值是内存压力模式开始对缓冲区使用应用压力的上限
#第三个值是内存上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的 BDP 可以增大这些值(但是要记住,其单位是内存页,而不是字节)

net.ipv4.tcp_rmem

#与 tcp_wmem 类似,不过它表示的是为自动调优所使用的接收缓冲区的值

net.ipv4.tcp_wmem = 30000000 30000000 30000000

#为自动调优定义每个 socket 使用的内存。
#第一个值是为 socket 的发送缓冲区分配的最少字节数
#第二个值是默认值(该值会被 wmem_default 覆盖),缓冲区在系统负载不重的情况下可以增长到这个值
#第三个值是发送缓冲区空间的最大字节数(该值会被 wmem_max 覆盖)

net.core.wmem_default = 11059200

#定义默认的发送窗口大小;对于更大的 BDP 来说,这个大小也应该更大

net.core.rmem_default = 10000000

#指定了接收套接字缓冲区大小的缺省值(以字节为单位)

net.core.rmem_max = 10000000

#指定了接收套接字缓冲区大小的最大值(以字节为单位)

net.core.wmem_max = 11059200

#定义发送窗口的最大大小;对于更大的 BDP 来说,这个大小也应该更大

net.ipv4.tcp_tw_reuse 在Ubuntu中这个参数值是0(r73)

是否socket reuse,此函数的作用是Server重启时可以快速重新使用监听的端口。如果没有设置此参数,会导致server重启时发生端口未及时释放而启动失败
表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭

net.ipv4.tcp_tw_recycle 在Ubuntu中没有发现这个参数(r73)

使用socket快速回收,短连接Server需要开启此参数。此参数表示开启TCP连接中TIME-WAIT sockets的快速回收,Linux系统中默认为0,表示关闭。打开此参数可能会造成NAT用户连接不稳定,请谨慎测试后再开启。
表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭

相关资料

内核参数调整之swoole
内核参数调整之easy-swoole
TCP/IP及内核参数优化调优
linux系统怎么查看及设置内核参数

tcp_tw_reuse、tcp_tw_recycle 使用场景及注意事项

es-docker

FROM php:7.2

# Version
ENV PHPREDIS_VERSION 4.0.1
ENV SWOOLE_VERSION 4.4.4
ENV EASYSWOOLE_VERSION 3.x-dev

# Timezone
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo 'Asia/Shanghai' > /etc/timezone

# Libs
RUN apt-get update \
    && apt-get install -y \
    curl \
    wget \
    git \
    zip \
    libz-dev \
    libssl-dev \
    libnghttp2-dev \
    libpcre3-dev \
    && apt-get clean \
    && apt-get autoremove -y

# Composer
RUN curl -sS https://getcomposer.org/installer | php \
    && mv composer.phar /usr/local/bin/composer \
    && composer self-update --clean-backups

# PDO extension
RUN docker-php-ext-install pdo_mysql

# Bcmath extension
RUN docker-php-ext-install bcmath

# Redis extension
RUN wget http://pecl.php.net/get/redis-${PHPREDIS_VERSION}.tgz -O /tmp/redis.tar.tgz \
    && pecl install /tmp/redis.tar.tgz \
    && rm -rf /tmp/redis.tar.tgz \
    && docker-php-ext-enable redis

# Swoole extension
RUN wget https://github.com/swoole/swoole-src/archive/v${SWOOLE_VERSION}.tar.gz -O swoole.tar.gz \
    && mkdir -p swoole \
    && tar -xf swoole.tar.gz -C swoole --strip-components=1 \
    && rm swoole.tar.gz \
    && ( \
    cd swoole \
    && phpize \
    && ./configure --enable-async-redis --enable-mysqlnd --enable-openssl --enable-http2 \
    && make -j$(nproc) \
    && make install \
    ) \
    && rm -r swoole \
    && docker-php-ext-enable swoole


# 部署node-agent
ADD swoole-tracker-vx.y.z.tar.gz /tmp/
RUN cp /tmp/86d89a960330704760/swoole_tracker72.so /usr/local/lib/php/extensions/no-debug-non-zts-20170718/ && \
    cd /tmp/86d89a960330704760 && \
    ./deploy_env.sh 192.168.56.102 && \
    rm -rf /tmp/86d89a960330704760

# 添加entrypoint脚本
RUN printf '#!/bin/sh\n/opt/swoole/script/php/swoole_php /opt/swoole/node-agent/src/node.php &\nphp $@' > /opt/swoole/entrypoint.sh && \
    chmod 755 /opt/swoole/entrypoint.sh

# 启用entrypoint脚本(-x方便调试, 可以去掉)
# ENTRYPOINT [ "sh", "-x", "/opt/swoole/entrypoint.sh" ]

RUN printf 'extension=/usr/local/lib/php/extensions/no-debug-non-zts-20170718/swoole_tracker72.so\n' > /usr/local/etc/php/conf.d/swoole-tracker.ini


WORKDIR /var/www/code



# Install easyswoole
RUN cd /var/www/code \
    && composer require easyswoole/easyswoole=${EASYSWOOLE_VERSION} \
    && php vendor/bin/easyswoole install

EXPOSE 9501

ENTRYPOINT ["php", "/var/www/code/easyswoole", "start"]
FROM centos:centos7

#version defined
ENV SWOOLE_VERSION 4.4.4
ENV EASYSWOOLE_VERSION 3.x-dev

#update core
RUN yum update -y

#install libs
RUN yum install -y curl zip unzip  wget openssl-devel gcc-c++ make autoconf

#install php
RUN yum install -y epel-release
RUN rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
RUN yum clean all
RUN yum update -y
RUN yum install -y php71w-devel php71w-openssl php71w-gd php71w-mbstring php71w-mysqli

# composer
RUN curl -sS https://getcomposer.org/installer | php \
    && mv composer.phar /usr/bin/composer \
    && composer self-update --clean-backups

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

# swoole ext
RUN wget https://github.com/swoole/swoole-src/archive/v${SWOOLE_VERSION}.tar.gz -O swoole.tar.gz \
    && mkdir -p swoole \
    && tar -xf swoole.tar.gz -C swoole --strip-components=1 \
    && rm swoole.tar.gz \
    && ( \
    cd swoole \
    && phpize \
    && ./configure --enable-openssl \
    && make \
    && make install \
    ) \
    && sed -i "2i extension=swoole.so" /etc/php.ini \
    && rm -r swoole

# Dir
WORKDIR /easyswoole

# install easyswoole

RUN cd /easyswoole \
    && composer require easyswoole/easyswoole=${EASYSWOOLE_VERSION} \
    && php vendor/bin/easyswoole install


# 部署node-agent
ADD swoole-tracker-vx.y.z.tar.gz /tmp/
RUN cp /tmp/86d89a960330704760/swoole_tracker71.so /usr/lib64/php/modules/ && \
    cd /tmp/86d89a960330704760 && \
    ./deploy_env.sh 192.168.56.102 && \
    rm -rf /tmp/86d89a960330704760

# 添加entrypoint脚本
RUN printf '#!/bin/sh\n/opt/swoole/script/php/swoole_php /opt/swoole/node-agent/src/node.php &\nphp-fpm $@' > /opt/swoole/entrypoint.sh && \
    chmod 755 /opt/swoole/entrypoint.sh

# 启用entrypoint脚本(-x方便调试, 可以去掉)
ENTRYPOINT [ "sh", "-x", "/opt/swoole/entrypoint.sh" ]

RUN printf 'extension=/usr/lib64/php/modules/swoole_tracker71.so\n' > /etc/php.d/swoole-tracker.ini


EXPOSE 9501

easyswoole中的mysqli带条件返回数据及总条数

easyswoole mysqli 分页

正确用法

<?php
$table_name = 'xsk_test';
$page=3;
$page_size=20;
$db->where('status', 1);
$db->withTotalCount();
$data = $db->get($table_name,[($page-1)*$page_size,$page_size],'*');
$count = $db->getTotalCount();

错误用法

<?php
$table_name = 'xsk_test';
$page=3;
$page_size=20;
$db->where('status', 1);
$data = $db->get($table_name,[($page-1)*$page_size,$page_size],'*');
$count = $db->count();// 这儿的count的where条件会消失

mysqli的源码

count是再次调用了get的方法 源码位置

    /**
     * 聚合-计算总数
     * @param string $tableName 表名称
     * @param string|null $filedName 字段名称
     * @return mixed
     * @throws ConnectFail
     * @throws PrepareQueryFail
     */
    public function count($tableName, $filedName = null)
    {
        if (is_null($filedName)) {
            $filedName = '*';
        }
        $isFetch = $this->isFetchSql;
        $retval = $this->get($tableName, null, "COUNT({$filedName}) as retval");
        if ($isFetch || $retval instanceof Mysqli) {
            return $retval;
        }
        return $retval ? $retval[0]['retval'] : false;
    }

相关资料

官方文档

php-单元测试

easyswoole 单元测试 php单元测试

安装

composer require easyswoole/phpunit Tip: 自3.2.5版本的Easyswoole起,已经默认集成了 easyswoole/phpunit 组件

目录结构

|--App
|--|--|
.....
|--Tests
|--|--Api
|--|--|--IndexTests.php
|--|--Models
|--|--|--UserTests.php

IndexTests.php API接口测试

<?php


namespace Tests\Api;
use PHPUnit\Framework\TestCase;
use App\HttpController\Index;
use EasySwoole\HttpClient\HttpClient;

class IndexTests extends TestCase
{
    protected $baseUrl = 'http://ip地址:9501';

    public function testIndex()
    {
        $url = $this->baseUrl . '/user/login'; 
        $client = new HttpClient($url);


        $username = 'zhangshan';
        $password = 'qwe12345';
        $deviceId = 1;

        $client->setQuery(['username' => $username, 'password' => $password, 'device_type' => $deviceId]);

        $response = $client->get();

        $body = $this->parsingJson($response->getBody());

        if ($response->getBody()) {
            var_dump($body);
        } else {
            echo 'Error: ' . $response->getErrCode() . ': ' . $response->getErrMsg() . "\n";
        }

        $this->assertTrue(true);//断言结果是否为true,如果不为true则报错
        $this->assertEquals('hello world', $response->response);//断言结果是否等于hello world,如果不等于则报错
    }
    /**
     * 解析json数据
     *
     * @param string $jsonStr
     * @return object
     */
    protected function parsingJson($jsonStr)
    {
        // $body = json_decode($jsonStr);
        return json_decode($jsonStr);
    }
}

UserTests.php 数据模型测试

<?php
namespace Tests\Models;
use PHPUnit\Framework\TestCase;
use App\Models\AccountModel;

class UserTests extends TestCase
{
    public function testInfo()
    {
        $uid = 13;
        $accountModel = new AccountModel();
        $data=  $accountModel->info($uid);
        // var_dump($data); 8
        $this->assertEquals(8, $data['robot_id']);//断言返回的id为1
    }
}

相关资料

phpunit-单元测试神器
Easyswoole/Phpunit

APP支付SDK-支付宝-PHP

调试支付宝一直出现-ALIN10146-系统繁忙

出现的问题: ALIN10146-系统繁忙

  • 错误1: 由于在创建应用的使用选择了[公钥证书]加签方式、(PHP不要选择这一项、这个一旦确定就不可以修改了、只能重新创建提交审核)
  • 错误2: 参数加的位置错误
// 使用easyswoole集成的composer包-错误使用方式
        $aliConfig = new \EasySwoole\Pay\AliPay\Config();
        $aliConfig->setGateWay(\EasySwoole\Pay\AliPay\GateWay::NORMAL);
        $aliConfig->setAppId('2019091167181387');
        $aliConfig->setPublicKey('xxxxxx');
        $aliConfig->setPrivateKey('xxxxxxxx');
        $pay = new \EasySwoole\Pay\Pay();
        $order = new \EasySwoole\Pay\AliPay\RequestBean\App();
        $order->setSubject($orderDesc);
        $order->setOutTradeNo($orderSn);
        $order->setTotalAmount($money);
        $aliPay = $pay->aliPay($aliConfig);
        $result = $aliPay->app($order)->toArray();
        $result ['notify_url'] = 'http://261843m3y6.wicp.vip:52034/ali/pay_notify'; # 这个回调通知地址不可以加到这儿、可有可无
        foreach ($result as &$value) {
            $value = $this->characet($value, $result['charset']);
        }
        $body ['body'] = http_build_query($result);
        return $body;
// 使用easyswoole集成的composer包-正确使用方式
        $aliConfig = new \EasySwoole\Pay\AliPay\Config();
        $aliConfig->setGateWay(\EasySwoole\Pay\AliPay\GateWay::NORMAL);
        $aliConfig->setAppId('2019091167181387');
        $aliConfig->setPublicKey('xxxxxx');
        $aliConfig->setPrivateKey('xxxxxxxx');
        $aliConfig->setNotifyUrl('http://261843m3y6.wicp.vip:52034/ali/pay_notify'); # 需要的话通过这个方法添加
        $pay = new \EasySwoole\Pay\Pay();
        $order = new \EasySwoole\Pay\AliPay\RequestBean\App();
        $order->setSubject($orderDesc);
        $order->setOutTradeNo($orderSn);
        $order->setTotalAmount($money);
        $aliPay = $pay->aliPay($aliConfig);
        $result = $aliPay->app($order)->toArray();
        foreach ($result as &$value) {
            $value = $this->characet($value, $result['charset']);
        }
        $body ['body'] = http_build_query($result);
        return $body;

支付结果验签

// 使用easyswoole集成的composer包
        $param = $this->request()->getRequestParam();
        unset($param['sign_type']);
        $aliConfig = $this->aliPayConfig();
        $aliConfig->setPublicKey('支付宝公钥(当你生成公钥填入到支付宝开发平台、平台会生成一个公钥-共两个公钥)'); # 支付的时候用自己的公钥、验签用支付宝公钥
        $order = new \EasySwoole\Pay\AliPay\RequestBean\NotifyRequest($param,true);
        $pay = new \EasySwoole\Pay\Pay();
        $aliPay = $pay->aliPay($aliConfig);
        if($aliPay->verify($order)) {

沙箱配置

RSA(SHA1)密钥 和 RSA2(SHA256)密钥(推荐) 两个只要填写一个即可, RSA指得是工具中的1024, RSA2指得是工具生成的2048

应用网关: 指得是支付宝服务推送消息接收地址(我们自己服务器中的地址外网可访问的)

授权回调地址: 用于需要用户授权的处理的回调地址

阿里开发平台-APP应用添加

注意: 加签管理中-选择公钥(不要选择公钥证书-官方SDK没有提供PHP对证书的加签方式 需要自己实现-JAVA的官方SDK提供了)

秘钥生成工具

注意: 要选择PKCS1(非JAVA使用)

相关资料

调用接口-时序图 下拉到: 第四步:调用接口
请求参数
PHP服务端 SDK 生成 APP支付订单信息示例

生成 RSA 密钥
联调日志排查
沙箱调试 需要登录后-开发中心-开发服务-研发服务

ALIN10146-系统繁忙

支付宝接口错误代码 invalid-signature 错误原因: 验签出错
支付宝报错:系统繁忙,请稍后再试

遇到调试不同可以点击、有技术点我、图标然后输入"人工客服"

swoole开启openssl

安装swoole扩展两种方式1. pecl 2. 编译安装

环境说明

  • 宿机win10
  • 操作主机vbox-ubuntu
  • 安装主机docker [letsdockerize/laradock-php-fpm:2.4-7.2]

pecl方式安装

pecl install swoole-4.4.4

执行上面命令后待定一段时间后、会出现下面询问对话输入[y]就是开启, 但是在dockerfile中无法自动为其输入[y]. 方法未找到. dockerfile可以使用编译方式安装.

...
381 source files, building
running: phpize
Configuring for:
PHP Api Version:         20170718
Zend Module Api No:      20170718
Zend Extension Api No:   320170718
enable sockets supports? [no] : 
enable openssl support? [no] : 
enable http2 support? [no] : 
enable mysqlnd support? [no] : 
building in /tmp/pear/temp/pear-build-defaultusernDqLij/swoole-4.4.1
....

编译安装

    curl -o /tmp/swoole.tar.gz https://github.com/swoole/swoole-src/archive/v4.4.1.tar.gz -L && \
    tar zxvf /tmp/swoole.tar.gz && cd swoole-src* && \
    phpize && \
    ./configure \
    --enable-openssl  \
    --enable-http2  \
    --enable-async-redis \
    --enable-mysqlnd && \
    make && make install && \
    docker-php-ext-enable swoole

查看swoole扩展信息

php --ri swoole

出现openssl字符说明已启用openssl

root@4c5bf38c1a5d:/var/www/html# php --ri swoole

swoole

Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 4.4.1
Built => Sep  6 2019 05:54:34
coroutine => enabled
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 1.1.0j  20 Nov 2018
http2 => enabled
zlib => enabled
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
mysqlnd => enabled
async_redis => enabled

Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608

pecl install 参数选择 pecl help install

Options:
  -f, --force
        will overwrite newer installed packages
  -l, --loose
        do not check for recommended dependency version
  -n, --nodeps
        ignore dependencies, install anyway
  -r, --register-only
        do not install files, only register the package as installed
  -s, --soft
        soft install, fail silently, or upgrade if already installed
  -B, --nobuild
        don't build C extensions
  -Z, --nocompress
        request uncompressed files when downloading
  -R DIR, --installroot=DIR
        root directory used when installing files (ala PHP's INSTALL_ROOT), use packagingroot for RPM
  -P DIR, --packagingroot=DIR
        root directory used when packaging files, like RPM packaging
  --ignore-errors
        force install even if there were errors
  -a, --alldeps
        install all required and optional dependencies
  -o, --onlyreqdeps
        install all required dependencies
  -O, --offline
        do not attempt to download any urls or contact channels
  -p, --pretend
        Only list the packages that would be downloaded

相关资料

pecl-swoole
github-swoole-tag
pecl 安装swoole怎么开启openssl | 如果是 Nginx 代理到 Swoole,那么 Swoole 不需要配置 SSL 编译Swoole时指定--enable-openssl或--with-openssl-dir可以开启SSL

expect - 自动交互脚本 待研究

websocket-nginx反向代理

nginx反向代理easyswoole的http和websocket

server {
    root /var/www/es;
    server_name esapi.test;
    # 代理http
    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://192.168.3.67:9501;
        }
        # 代理websocket就靠下面两行
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection upgrade;
    }
}

相关资料

官方文档参考