下载php7.3安装包,因为easyswoole安装环境需要大于php7.1,所以我们安装php7.3 php下载地址:
https://www.php.net/downloads.php
安装php7.3
安装依赖包
yum install -y zip unzip autoconf gcc gcc-c++  make zlib zlib-devel pcre pcre-devel  libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers解压
tar -zxvf php-7.3.22.tar.gz
cd php-7.3.22配置
./configure --prefix=/usr/local/php --exec-prefix=/usr/local/php --bindir=/usr/local/php/bin --sbindir=/usr/local/php/sbin --includedir=/usr/local/php/include --libdir=/usr/local/php/lib/php --mandir=/usr/local/php/php/man --with-config-file-path=/usr/local/php/etc --with-openssl --enable-mbstring --enable-fpm编译安装
make && make install复制php.ini
在之前编译的源码包中,找到 php.ini-production,复制到/usr/local/php/etc下,并改名为php.ini
cp php.ini-production /usr/local/php/etc/php.ini将php源码编译目录下的 sapi/fpm/init.d.php-fpm 文件拷贝到系统配置 /etc/init.d 目录下并重命名为 php-fpm
cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
chmod +x /etc/init.d/php-fpm添加 php-fpm 配置文件
将php安装目录下的 /usr/local/php/etc/php-fpm.conf.default 文件拷贝同目录下并重命名为 php-fpm.conf
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf 添加 www.conf 配置文件
将php安装目录下的 /usr/local/php/etc/php-fpm.d/www.conf.default 文件拷贝同目录下并重命名为 www.conf
cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf 添加php安装目录到系统环境变量
创建并打开文件php.sh
vi /etc/profile.d/php.sh 添加内容如下
export PATH=$PATH:/usr/local/php/bin/:/usr/local/php/sbin/ 保存并退出
:wq使用source立即生效刚刚添加的php环境变量
source /etc/profile.d/php.sh启动php-fpm
service php-fpm start设置php开机启动
#修改系统配置目录下的 php-fpm 文件可执行权限 
chmod +x /etc/init.d/php-fpm
#将系统配置目录下的 `php-fpm` 添加到 `系统服务`
chkconfig --add php-fpm
#设置 `php-fpm` `系统服务` 为开机启动
chkconfig php-fpm on查看是否安装成功
#出现版本号则安装成功
php -v首先进入swoole的github下载地址: https://github.com/swoole/swoole-src/releases
如果没有特殊需求,请选择最新版本开始下载(我这里是最新版是v4.4.21):
wget https://github.com/swoole/swoole-src/archive/v4.4.21.tar.gz ## 下载
tar -zvxf v4.4.21.tar.gz  ## 解压到当前目录
cd swoole-src-4.4.21/ ## cd目录
phpize ## 使用phpize创建php编译检测脚本 ./configure
./configure --with-php-config=/usr/local/php/bin/php-config --enable-openssl  ## 创建编译文件,第一个--with,后面是php的安装路径/bin/php-config ,第二个--enable,是开启swoole的ssl功能
sudo make && make install  ## 编译swoole并把编译好的文件移动到php的扩展目录(前面的配置php版本的扩展目录) 需要root权限这个时候已经安装成功,需要进入php.ini,在最后面增加上:
extension=swoole.so成功安装swoole,通过php --ri swoole 查看swoole扩展的信息:
php --ri swoole出现下面的情况则是安装成功
swoole
Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 4.4.21
Built => Oct 13 2020 10:14:03
coroutine => enabled
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 1.0.2k-fips  26 Jan 2017
pcre => enabled
zlib => 1.2.7
mutex_timedlock => enabled
pthread_barrier => enabled
futex => 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安装前请务必确保已经正确安装了 PHP。打开命令行窗口并执行 php -v 查看是否正确输出版本号。打开命令行并依次执行下列命令安装最新版本的 Composer:
php -r "copy(‘https://install.phpcomposer.com/installer‘, ‘composer-setup.php‘);"php composer-setup.php如果出现下面的报错,可以忽略
Downloading...
Composer (version 1.10.13) successfully installed to: /home/down/composer.phar
Use it: php composer.phar
Some settings on your machine may cause stability issues with Composer.
If you encounter issues, try to change the following:
The zlib extension is not loaded, this can slow down Composer a lot.
If possible, install it or recompile php with --with-zlib
The php.ini used by your command-line PHP is: /usr/local/php/etc/php.ini
If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.
执行第三条命令
php -r "unlink(‘composer-setup.php‘);"上述 3 条命令的作用依次是:
下载安装脚本 - composer-setup.php - 到当前目录。
执行安装过程。
删除安装脚本。
全局安装
sudo mv composer.phar /usr/local/bin/composer检查一下是否安装成功
[root@localhost down]# composer 
Do not run Composer as root/super user! See https://getcomposer.org/root for details
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.10.13 2020-09-09 11:46:34
Usage:
  command [options] [arguments]
Options:
  -h, --help                     Display this help message
  -q, --quiet                    Do not output any message
  -V, --version                  Display this application version
      --ansi                     Force ANSI output
      --no-ansi                  Disable ANSI output
  -n, --no-interaction           Do not ask any interactive question
      --profile                  Display timing and memory usage information
      --no-plugins               Whether to disable plugins.
  -d, --working-dir=WORKING-DIR  If specified, use the given directory as working directory.
      --no-cache                 Prevent use of the cache
  -v|vv|vvv, --verbose           Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
提示:不要忘了经常执行 composer selfupdate 以保持 Composer 一直是最新版本哦!
设置阿里镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/composer require easyswoole/easyswoole=3.x如果我们是服务器的root账号会报错,告诉我们不能用root账号来运行composer,所以我们新创建一个账号并给他root的权限:
[root@localhost easyswoole]# composer require easyswoole/easyswoole=3.x
Do not run Composer as root/super user! See https://getcomposer.org/root for details所以我们需要创建一个新的用户账号,并且给它root账号的权限,方便我们以后操作,为了方便我们也给它设置切换账号的时候不用重新输入密码,此处我们添加一个账号swoole,密码也是swoole
useradd swoole
passwd swoole给这个账号设置root权限并且免密码
vi /etc/sudoers添加下面的两行代码
swoole         ALL=(ALL)        ALL
swoole         ALL=(ALL)        NOPASSWD:ALL下面是在文本中内容举例:
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
swoole  ALL=(ALL)       ALL
## Allows members of the ‘sys‘ group to run networking, software,
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS
## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL
## Same thing without a password
# %wheel        ALL=(ALL)       NOPASSWD: ALL
swoole         ALL=(ALL)        NOPASSWD:ALL保存退出
:wq!切换账号
su swoole把我们的项目目录添加权限,以便安装项目,然后进入项目目录,进行安装easyswoole
sudo chmod -R 777 program
cd program安装easyswoole
composer require easyswoole/easyswoole=3.x
php vendor/easyswoole/easyswoole/bin/easyswoole install安装成功
[swoole@localhost easyswoole]$ php vendor/easyswoole/easyswoole/bin/easyswoole install
  ______                          _____                              _
 |  ____|                        / ____|                            | |
 | |__      __ _   ___   _   _  | (___   __      __   ___     ___   | |   ___
 |  __|    / _` | / __| | | | |  \___ \  \ \ /\ / /  / _ \   / _ \  | |  / _  | |____  | (_| | \__ \ | |_| |  ____) |  \ V  V /  | (_) | | (_) | | | |  __/
 |______|  \__,_| |___/  \__, | |_____/    \_/\_/    \___/   \___/  |_|  \___|
                          __/ |
                         |___/
install success,enjoy!  
dont forget run composer dump-autoload  启动框架
php easyswoole start启动成功显示如下
php easyswoole start
  ______                          _____                              _
 |  ____|                        / ____|                            | |
 | |__      __ _   ___   _   _  | (___   __      __   ___     ___   | |   ___
 |  __|    / _` | / __| | | | |  \___ \  \ \ /\ / /  / _ \   / _ \  | |  / _  | |____  | (_| | \__ \ | |_| |  ____) |  \ V  V /  | (_) | | (_) | | | |  __/
 |______|  \__,_| |___/  \__, | |_____/    \_/\_/    \___/   \___/  |_|  \___|
                          __/ |
                         |___/
main server                   SWOOLE_WEB
listen address                0.0.0.0
listen port                   9501
ip@ens33                      192.168.17.147
worker_num                    8
reload_async                  true
max_wait_time                 3
pid_file                      /home/program/easyswoole/Temp/pid.pid
log_file                      /home/program/easyswoole/Log/swoole.log
user                          swoole
daemonize                     false
swoole version                4.4.21
php version                   7.3.22
easy swoole                   3.3.7
develop/produce               develop
temp dir                      /home/program/easyswoole/Temp
log dir                       /home/program/easyswoole/Log此时我们可以访问虚拟机中的项目http://192.168.17.147:9501/,如果打不开,请关闭虚拟机防火墙,很有可能是9501端口没有开启,成功之后,如下图
因为我们的项目在linux虚拟机中运行,所以我们需要在本机上开发代码,实时同步到虚拟机中以便我们的开发,此处我用vscode编辑器来举例怎样同步开发项目
首先我们需要打包虚拟机中下载好的项目
zip -r easyswoole.zip * .[^.]*解压到我们本地项目中,用vscode打开,然后安装插件
1.vscode 安装 sftp插件
在vscode中安装sftp插件扩展
2. 创建sftp配置
使用 ctrl+shift+p 快捷键调出输入框,选择 SFTP:Config 回车
会在 .vscode 目录下创建一个 sftp.json 配置文件,配置如下
{
    "name": "myserver",
    "host": "192.168.2.111",    
    "port": 22,     
    "username": "root", 
    "password": "xxxx", 
    "protocol": "sftp", 
    "passive": false,
    "interactiveAuth": false,
    "remotePath": "/usr/share/nginx/mwServer/web/laravel/",   
    "uploadOnSave": true, 
    "syncMode": "update",
    "ignore": [            
        "**/.vscode/**",
        "**/.git/**",
        "**/.DS_Store"
    ]
}3. 上传本地代码到服务器
使用 ctrl+shift+p 快捷键调出输入框,选择 SFTP:Upload 回车
本地的项目代码就可以上传到服务器了
现在修改本地代码 ctrl+s 保存,即可同步到服务器了EasySwoole服务热重启
由于 swoole 常驻内存的特性,修改文件后需要重启worker进程才能将被修改的文件重新载入内存中,我们可以自定义Process的方式实现文件变动自动进行服务重载
有时间把热启动代码备注一下
热重载进程
新建文件 App/Process/HotReload.php 并添加如下内容,也可以放在其他位置,请对应命名空间
<?php
/**
 * Created by PhpStorm.
 * User: evalor
 * Date: 2018-11-26
 * Time: 23:18
 */
namespace App\Process;
use EasySwoole\Component\Process\AbstractProcess;
use EasySwoole\EasySwoole\ServerManager;
use EasySwoole\Utility\File;
use Swoole\Process;
use Swoole\Table;
use Swoole\Timer;
/**
 * 暴力热重载
 * Class HotReload
 * @package App\Process
 */
class HotReload extends AbstractProcess
{
    /** @var \swoole_table $table */
    protected $table;
    protected $isReady = false;
    protected $monitorDir; // 需要监控的目录
    protected $monitorExt; // 需要监控的后缀
    /**
     * 启动定时器进行循环扫描
     */
    public function run($arg)
    {
        // 此处指定需要监视的目录 建议只监视App目录下的文件变更
        $this->monitorDir = !empty($arg[‘monitorDir‘]) ? $arg[‘monitorDir‘] : EASYSWOOLE_ROOT . ‘/App‘;
        // 指定需要监控的扩展名 不属于指定类型的的文件 无视变更 不重启
        $this->monitorExt = !empty($arg[‘monitorExt‘]) && is_array($arg[‘monitorExt‘]) ? $arg[‘monitorExt‘] : [‘php‘];
        if (extension_loaded(‘inotify‘) && empty($arg[‘disableInotify‘])) {
            // 扩展可用 优先使用扩展进行处理
            $this->registerInotifyEvent();
            echo "server hot reload start : use inotify\n";
        } else {
            // 扩展不可用时 进行暴力扫描
            $this->table = new Table(512);
            $this->table->column(‘mtime‘, Table::TYPE_INT, 4);
            $this->table->create();
            $this->runComparison();
            Timer::tick(1000, function () {
                $this->runComparison();
            });
            echo "server hot reload start : use timer tick comparison\n";
        }
    }
    /**
     * 扫描文件变更
     */
    private function runComparison()
    {
        $startTime = microtime(true);
        $doReload = false;
        $dirIterator = new \RecursiveDirectoryIterator($this->monitorDir);
        $iterator = new \RecursiveIteratorIterator($dirIterator);
        $inodeList = array();
        // 迭代目录全部文件进行检查
        foreach ($iterator as $file) {
            /** @var \SplFileInfo $file */
            $ext = $file->getExtension();
            if (!in_array($ext, $this->monitorExt)) {
                continue; // 只检查指定类型
            } else {
                // 由于修改文件名称 并不需要重新载入 可以基于inode进行监控
                $inode = $file->getInode();
                $mtime = $file->getMTime();
                array_push($inodeList, $inode);
                if (!$this->table->exist($inode)) {
                    // 新建文件或修改文件 变更了inode
                    $this->table->set($inode, [‘mtime‘ => $mtime]);
                    $doReload = true;
                } else {
                    // 修改文件 但未发生inode变更
                    $oldTime = $this->table->get($inode)[‘mtime‘];
                    if ($oldTime != $mtime) {
                        $this->table->set($inode, [‘mtime‘ => $mtime]);
                        $doReload = true;
                    }
                }
            }
        }
        foreach ($this->table as $inode => $value) {
            // 迭代table寻找需要删除的inode
            if (!in_array(intval($inode), $inodeList)) {
                $this->table->del($inode);
                $doReload = true;
            }
        }
        if ($doReload) {
            $count = $this->table->count();
            $time = date(‘Y-m-d H:i:s‘);
            $usage = round(microtime(true) - $startTime, 3);
            if (!$this->isReady == false) {
                // 监测到需要进行热重启
                echo "severReload at {$time} use : {$usage} s total: {$count} files\n";
                ServerManager::getInstance()->getSwooleServer()->reload();
            } else {
                // 首次扫描不需要进行重启操作
                echo "hot reload ready at {$time} use : {$usage} s total: {$count} files\n";
                $this->isReady = true;
            }
        }
    }
    /**
     * 注册Inotify监听事件
     */
    private function registerInotifyEvent()
    {
        // 因为进程独立 且当前是自定义进程 全局变量只有该进程使用
        // 在确定不会造成污染的情况下 也可以合理使用全局变量
        global $lastReloadTime;
        global $inotifyResource;
        $lastReloadTime = 0;
        $files = File::scanDirectory(EASYSWOOLE_ROOT . ‘/App‘);
        $files = array_merge($files[‘files‘], $files[‘dirs‘]);
        $inotifyResource = inotify_init();
        // 为当前所有的目录和文件添加事件监听
        foreach ($files as $item) {
            inotify_add_watch($inotifyResource, $item, IN_CREATE | IN_DELETE | IN_MODIFY);
        }
        // 加入事件循环
        swoole_event_add($inotifyResource, function () {
            global $lastReloadTime;
            global $inotifyResource;
            $events = inotify_read($inotifyResource);
            if ($lastReloadTime < time() && !empty($events)) { // 限制1s内不能进行重复reload
                $lastReloadTime = time();
                ServerManager::getInstance()->getSwooleServer()->reload();
            }
        });
    }
    public function onShutDown()
    {
        // TODO: Implement onShutDown() method.
    }
    public function onReceive(string $str)
    {
        // TODO: Implement onReceive() method.
    }
}
添加好后在全局的 EasySwooleEvent.php 中,注册该自定义进程
use App\Process\HotReload;
public static function mainServerCreate(EventRegister $register)
{
    $swooleServer = ServerManager::getInstance()->getSwooleServer();
    $swooleServer->addProcess((new HotReload(‘HotReload‘, [‘disableInotify‘ => false]))->getProcess());
}
因为虚拟机中inotify无法监听到FTP/SFTP等文件上传的事件,将 disableInotify 设置为 true ,可以关闭inotify方式的热重启,使得虚拟机环境下,强制使用文件循环扫描来触发重载操作,同理 OSX 开发环境下,没有Inotify扩展,将自动使用扫描式重载
原文:https://blog.51cto.com/itafei/2541606