larave octane 是什么

octanelaravel 官网提供的第三方包,它能够通过集成 SwooleRoadRunner 这两种高性能的应用服务器来进步应用程序的性能。

RoadRunner 自身是一个用 Go 语言编写的开源 PHP 应用程序服务器。
Swoole 是一个应用 C++ 语言编写的基于异步事件驱动和协程的并行网络通信引擎,为 PHP 提供协程、高性能网络编程反对。

ApacheNginxPHP-FPM 十分类似,HTTP 申请能够发送到 RoadRunnerSwoole 以执行 PHP 代码,而后将响应发送回。 RoadRunnerSwoole 的不同之处在于它能够将 PHP 运行中的应用程序保留在内存中,以便在应用程序启动后取得更快的速度。 对于 Laravel 来说,这是相当有帮忙的。

环境要求

  1. PHP 8.0+
  2. Larave 8.35+
  3. SwooleRoadRunner 必须在 unix 零碎下装置(macOS, linux, window(WSL2)
  4. RoadRunner:请先确保 curlzip sockets 等 php 扩大曾经装置
  5. 本地虚拟机,IP: 192.168.2.11

装置历程

依照 Laravel 的官网文档来装置 SwooleRoadRunner 第三方包是一件十分苦楚的事,因为装置的过程中常常会遇到乌七八糟的问题。为了缩小大家走的弯路,所以我有必要在这里着重强调几个问题。

  1. 肯定要在 unix 零碎下装置,unix 零碎包含 macOS linuxwindows的linux子系统
  2. 为了可能在本地可能拜访虚拟机,请先敞开 linux 防火墙

Step1. 装置 octane

composer require laravel/octane

假如你曾经有了新的 laravel 我的项目。进入我的项目根目录下执行以上命令。

Step2. 配置 nginx 代理

为什么要先配置 nginx 的代理?

官网文档 中说:

The Octane server can be started via the octane:start Artisan command. By default, this command will utilize the server specified by the server configuration option of your application's octane configuration file:

php artisan octane:start

By default, Octane will start the server on port 8000, so you may access your application in a web browser via http://localhost:8000.

意思是执行启动命令后,默认端口 8000,在浏览器中能够通过 http://localhost:8000 拜访。 但我通过 http://192.168.2.11:8000 却拜访不了,晓得这个问题起因的敌人能够留言告知下。

依照官网文档的 nginx 配置

map $http_upgrade $connection_upgrade {    default upgrade;    ''      close;}server {    listen 8009;            # 浏览器端拜访的端口    #listen [::]:80;    server_name 127.0.0.1;    server_tokens off;    root /var/www/html/octane/public;    index index.php;    charset utf-8;    location /index.php {        try_files /not_exists @octane;    }    location / {        try_files $uri $uri/ @octane;    }    location = /favicon.ico { access_log off; log_not_found off; }    location = /robots.txt  { access_log off; log_not_found off; }    access_log /var/log/nginx/octane-access.log main;    error_log  /var/log/nginx/octane-error.log error;    error_page 404 /index.php;    location @octane {        set $suffix "";        if ($uri = /index.php) {            set $suffix ?$query_string;        }        proxy_http_version 1.1;        proxy_set_header Host $http_host;        proxy_set_header Scheme $scheme;        proxy_set_header SERVER_PORT $server_port;        proxy_set_header REMOTE_ADDR $remote_addr;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header Upgrade $http_upgrade;        proxy_set_header Connection $connection_upgrade;        proxy_pass http://127.0.0.1:8010$suffix;            # 代理申请    }}

留神下面配置中正文的中央:

  • listen 8009: 是我将要在浏览器中拜访的端口 http://192.168.2.11:8009
  • http://127.0.0.1:8010: 是 octane 启动时指定的端口

Step3. 应用 Swoole

1. 装置 Swoole 扩大

Octane 是依赖 Swoole 扩大的。php Swoole 扩大的装置大家从网上找些教程装置下就行。

2. 公布 octane 的配置文件

php artisan octane:install

此命令将会在 config 目录下生成 octane.php 的配置文件

3. 开启服务

php artisan octane:start --server=swoole --port=8010

输入:

  INFO  Server running…  Local: http://127.0.0.1:8010   Press Ctrl+C to stop the server

看到这些,阐明 octane 曾经胜利启动了。

4. 浏览器中拜访

因为咱们方才曾经配置了 nginx 代理,只有在浏览器中输出 http://192.168.2.11:8009 并回车。
能够看到命令界面上会呈现 GET 申请。

从上图能够看到,第一次申请用了 85.46ms,而从第二次之后只用了几毫秒,速度上有了极大的晋升。

Step4. ab 压测

上面是虚拟机上的liunx零碎的数据:

  1. 查看内核版本

    [root@localhost ~]# uname -r3.10.0-1160.41.1.el7.x86_64
  2. 查看 CPU

    [root@localhost ~]# grep "model name" /proc/cpuinfo | cut -f2 -d:Intel(R) Core(TM) i5-10500 CPU @ 3.10GHzIntel(R) Core(TM) i5-10500 CPU @ 3.10GHz
  3. 查看 CPU 核数

    [root@localhost ~]# cat /proc/cpuinfo |grep "cores"|uniqcpu cores    : 2
  4. 查看内存

    [root@localhost ~]# grep MemTotal /proc/meminfo | cut -f2 -d:1863020 kB

Swoole 压测

1. 创立 users 表:
CREATE TABLE `users` (  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,  `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,  `role` tinyint(3) unsigned NOT NULL DEFAULT '2' COMMENT '角色:1-管理员,2-会员...',  `created_at` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创立工夫',  `updated_at` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新工夫',  `deleted_at` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '删除工夫',  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='会员表';
2. 批改配置文件
# .envDB_CONNECTION=mysqlDB_HOST=localhostDB_PORT=3306DB_DATABASE=testDB_USERNAME=rootDB_PASSWORD=123456

3. 生成控制器并编写代码

生成控制器

php artisan make:controller UserController

编写代码

namspace App\Http\Controllers;class UserController extends Controller{    public array $store = [];    public function index(Request $request)    {        $nameList = ['james', 'lucy', 'jack', 'jessica', 'lily'];        $name = $nameList[array_rand($nameList)];        if (rand(0, 7) >= 2) {   // 0-1 读 2-7 写            $test = new User();            $test->name = $name;            $test->password = Hash::make(123456);            $test->role = 2;            $test->created_at = time();            $test->updated_at = time();            $test->deleted_at = time();            $test->save();            $data = ['id' => $test->id];        } else {            $data = User::query()->where('name', $name)->first();;        }    }}
4. 增加路由
# web.phpRoute::get('test-mysql', 'UserController@index');
5. 开始压测

压测命令

ab -n 1000 -c 8 http://127.0.0.1:8010/test-mysql
  • -n 1000: 指定测试会话应用的申请数为1000
  • -c 8: 8个并发申请

应用 Octane 压测后果如下:

[root@localhost octane]# ab -n 1000 -c 8 http://127.0.0.1:8010/test-mysqlThis is ApacheBench, Version 2.3 <$Revision: 1430300 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 127.0.0.1 (be patient)Completed 100 requestsCompleted 200 requestsCompleted 300 requestsCompleted 400 requestsCompleted 500 requestsCompleted 600 requestsCompleted 700 requestsCompleted 800 requestsCompleted 900 requestsCompleted 1000 requestsFinished 1000 requestsServer Software:        Server Hostname:        127.0.0.1Server Port:            8010Document Path:          /test-mysqlDocument Length:        0 bytesConcurrency Level:      8Time taken for tests:   22.268 secondsComplete requests:      1000Failed requests:        0Write errors:           0Total transferred:      1048000 bytesHTML transferred:       0 bytesRequests per second:    44.91 [#/sec] (mean)Time per request:       178.141 [ms] (mean)Time per request:       22.268 [ms] (mean, across all concurrent requests)Transfer rate:          45.96 [Kbytes/sec] receivedConnection Times (ms)              min  mean[+/-sd] median   maxConnect:        0    0   0.0      0       1Processing:    14  177  43.8    180     327Waiting:       14  177  43.8    179     327Total:         14  177  43.8    180     327Percentage of the requests served within a certain time (ms)  50%    180  66%    195  75%    207  80%    217  90%    230  95%    241  98%    254  99%    261 100%    327 (longest request)

再看看不必 Octane 时的压测后果

执行一下命令,8008 是我独自配置的端口,不通过 octane

ab -n 1000 -c 8 http://127.0.0.1:8008/test-mysql

后果:

[root@localhost octane]# ab -n 1000 -c 8 http://127.0.0.1:8008/test-mysqlThis is ApacheBench, Version 2.3 <$Revision: 1430300 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 127.0.0.1 (be patient)Completed 100 requestsCompleted 200 requestsCompleted 300 requestsCompleted 400 requestsCompleted 500 requestsCompleted 600 requestsCompleted 700 requestsCompleted 800 requestsCompleted 900 requestsCompleted 1000 requestsFinished 1000 requestsServer Software:        nginx/1.20.1Server Hostname:        127.0.0.1Server Port:            8008Document Path:          /test-mysqlDocument Length:        0 bytesConcurrency Level:      8Time taken for tests:   55.076 secondsComplete requests:      1000Failed requests:        0Write errors:           0Total transferred:      1134000 bytesHTML transferred:       0 bytesRequests per second:    18.16 [#/sec] (mean)Time per request:       440.606 [ms] (mean)Time per request:       55.076 [ms] (mean, across all concurrent requests)Transfer rate:          20.11 [Kbytes/sec] receivedConnection Times (ms)              min  mean[+/-sd] median   maxConnect:        0    0   0.0      0       0Processing:    70  438 193.7    424    1587Waiting:       70  438 193.7    424    1587Total:         70  438 193.7    424    1588Percentage of the requests served within a certain time (ms)  50%    424  66%    511  75%    565  80%    593  90%    652  95%    705  98%    783  99%   1183 100%   1588 (longest request)

依据下面两种后果的比拟能够看出,octane 速度显著晋升了几倍。

Step6. 劣势与劣势

1. 劣势

Octane 之前,咱们始终用 Nginx + PHP-FPM 的组合,它执行的程序是:

  1. 一个申请来到 Nginx
  2. Nginx 将申请委托给 PHP-FPMPHP-FPM 要么产生一个新的 woker,要么应用一个现有的 woker 来解决申请。
  3. PHP-FPM worker 启动 Laravel 应用程序。
  4. Laravel 的利用程序处理申请。
  5. PHP-FPM 将后果返回给 NginxNginx 将输入返回给客户端。

如上所述,每个申请从开始创立过程和到启动 Laravel 应用程序都会产生开销。在第4步中,lavale 框架会加载所有须要的依赖,包含 vendor包, Service Providers, Middlewareroute 等等,随着第三方 service 越来越多,启动速度越来越不受控。

Laravel Octane 则通过启动 Application 一次,常驻内存的形式来减速利用

2. 劣势

  1. 服务容器注入可能绑定不胜利
  2. HTTP Request 注入时申请参数可能会不正确
  3. 可能会呈现内存透露的状况

结语:

Laravel Octane 离新公布只有几个月的工夫,对于很多开发者来说,它并不是必须的,因为许多利用瓶颈都与未优化的数据库查问、迟缓的会话存储或迟缓的内部 API 申请无关。如果要在本人的我的项目中应用 Laravel Octane,就要做好会遇到更多让人头疼的问题的筹备。

下一篇会解说 RoadRunner 的应用。