從0開始搭建開發easyswoole

須要幫助/作項目/交朋友可加微信:a2106593278

在linux上安裝php7.3

下載php7.3安裝包,由於easyswoole安裝環境須要大於php7.1,因此咱們安裝php7.3 php下載地址:
https://www.php.net/downloads.php
安裝php7.3php

安裝依賴包node

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

解壓linux

tar -zxvf php-7.3.22.tar.gz
cd php-7.3.22

配置nginx

./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

編譯安裝laravel

make && make install

複製php.inic++

在以前編譯的源碼包中,找到 php.ini-production,複製到/usr/local/php/etc下,並更名爲php.inigit

cp php.ini-production /usr/local/php/etc/php.ini

將php源碼編譯目錄下的 sapi/fpm/init.d.php-fpm 文件拷貝到系統配置 /etc/init.d 目錄下並重命名爲 php-fpmgithub

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 web

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 redis

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端口沒有開啓,成功以後,以下圖
easyswoole安裝成功

用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擴展,將自動使用掃描式重載

相關文章
相關標籤/搜索