安装目录


在linux上安装php7.3


下载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扩展


首先进入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

安装composer


安装前请务必确保已经正确安装了 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/

安装easyswoole框架

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端口没有开启,成功之后,如下图
从0开始搭建开发easyswoole_linux


用window系统电脑开发easyswoole


因为我们的项目在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扩展,将自动使用扫描式重载


需要帮助/做项目/交朋友可加微信:a2106593278