---
## Continuous Updates
- *Please `Watch` this repository to get the latest updates.*
Table of Contents
=================
* [Features](#features)
* [Benchmark](#benchmark)
* [Requirements](#requirements)
* [Install](#install)
* [Run](#run)
* [Deploy](#deploy)
* [Cooperate with Nginx (Recommended)](#cooperate-with-nginx-recommended)
* [Cooperate with Apache](#cooperate-with-apache)
* [Enable WebSocket server](#enable-websocket-server)
* [Listen events](#listen-events)
* [System events](#system-events)
* [Customized asynchronous events](#customized-asynchronous-events)
* [Asynchronous task queue](#asynchronous-task-queue)
* [Millisecond cron job](#millisecond-cron-job)
* [Automatically reload after modifying code](#automatically-reload-after-modifying-code)
* [Get the instance of SwooleServer in your project](#get-the-instance-of-swooleserver-in-your-project)
* [Use SwooleTable](#use-swooletable)
* [Multi-port mixed protocol](#multi-port-mixed-protocol)
* [Coroutine](#coroutine)
* [Custom process](#custom-process)
* [Common components](#common-components)
* [Apollo](#apollo)
* [Prometheus](#prometheus)
* [Other features](#other-features)
* [Configure Swoole events](#configure-swoole-events)
* [Serverless](#serverless)
* [Important notices](#important-notices)
* [Users and cases](https://github.com/hhxsv5/laravel-s/blob/master/README-CN.md#%E7%94%A8%E6%88%B7%E4%B8%8E%E6%A1%88%E4%BE%8B)
* [Alternatives](#alternatives)
* [Sponsor](#sponsor)
* [License](#license)
## Features
- Built-in Http/[WebSocket](https://github.com/hhxsv5/laravel-s/blob/master/README.md#enable-websocket-server) server
- [Multi-port mixed protocol](https://github.com/hhxsv5/laravel-s/blob/master/README.md#multi-port-mixed-protocol)
- [Custom process](https://github.com/hhxsv5/laravel-s/blob/master/README.md#custom-process)
- Memory resident
- [Asynchronous event listening](https://github.com/hhxsv5/laravel-s/blob/master/README.md#customized-asynchronous-events)
- [Asynchronous task queue](https://github.com/hhxsv5/laravel-s/blob/master/README.md#asynchronous-task-queue)
- [Millisecond cron job](https://github.com/hhxsv5/laravel-s/blob/master/README.md#millisecond-cron-job)
- [Common Components](https://github.com/hhxsv5/laravel-s/blob/master/README.md#common-components)
- Gracefully reload
- [Automatically reload after modifying code](https://github.com/hhxsv5/laravel-s/blob/master/README.md#automatically-reload-after-modifying-code)
- Support Laravel/Lumen both, good compatibility
- Simple & Out of the box
## Benchmark
- [Which is the fastest web framework?](https://github.com/the-benchmarker/web-frameworks)
- [TechEmpower Framework Benchmarks](https://www.techempower.com/benchmarks/)
## Requirements
| Dependency | Requirement |
| -------- | -------- |
| [PHP](https://secure.php.net/) | `>= 5.5.9` `Recommend PHP7+` |
| [Swoole](https://www.swoole.co.uk/) | `>= 1.7.19` `No longer support PHP5 since 2.0.12` `Recommend 4.5.0+` |
| [Laravel](https://laravel.com/)/[Lumen](https://lumen.laravel.com/) | `>= 5.1` `Recommend 8.0+` |
## Install
1.Require package via [Composer](https://getcomposer.org/)([packagist](https://packagist.org/packages/hhxsv5/laravel-s)).
```bash
composer require "hhxsv5/laravel-s:~3.7.0" -vvv
# Make sure that your composer.lock file is under the VCS
```
2.Register service provider(pick one of two).
- `Laravel`: in `config/app.php` file, `Laravel 5.5+ supports package discovery automatically, you should skip this step`
```php
'providers' => [
//...
Hhxsv5\LaravelS\Illuminate\LaravelSServiceProvider::class,
],
```
- `Lumen`: in `bootstrap/app.php` file
```php
$app->register(Hhxsv5\LaravelS\Illuminate\LaravelSServiceProvider::class);
```
3.Publish configuration and binaries.
> *After upgrading LaravelS, you need to republish; click [here](https://github.com/hhxsv5/laravel-s/releases) to see the change notes of each version.*
```bash
php artisan laravels publish
# Configuration: config/laravels.php
# Binary: bin/laravels bin/fswatch bin/inotify
```
4.Change `config/laravels.php`: listen_ip, listen_port, refer [Settings](https://github.com/hhxsv5/laravel-s/blob/master/Settings.md).
5.Performance tuning
- [Adjust kernel parameters](https://wiki.swoole.com/#/other/sysctl?id=%e5%86%85%e6%a0%b8%e5%8f%82%e6%95%b0%e8%b0%83%e6%95%b4)
- [Number of Workers](https://www.swoole.co.uk/docs/modules/swoole-server/configuration#worker_num): LaravelS uses Swoole's `Synchronous IO` mode, the larger the `worker_num` setting, the better the concurrency performance, but it will cause more memory usage and process switching overhead. If one request takes 100ms, in order to provide 1000QPS concurrency, at least 100 Worker processes need to be configured. The calculation method is: worker_num = 1000QPS/(1s/1ms) = 100, so incremental pressure testing is needed to calculate the best` worker_num`.
- [Number of Task Workers](https://www.swoole.co.uk/docs/modules/swoole-server/configuration#task_worker_num)
## Run
> `Please read the notices carefully before running`, [Important notices](https://github.com/hhxsv5/laravel-s#important-notices)(IMPORTANT).
- Commands: `php bin/laravels {start|stop|restart|reload|info|help}`.
| Command | Description |
| --------- | --------- |
| start | Start LaravelS, list the processes by "*ps -ef|grep laravels*" |
| stop | Stop LaravelS, and trigger the method `onStop` of Custom process |
| restart | Restart LaravelS: Stop gracefully before starting; The service is `unavailable` until startup is complete |
| reload | Reload all Task/Worker/Timer processes which contain your business codes, and trigger the method `onReload` of Custom process, CANNOT reload Master/Manger processes. After modifying `config/laravels.php`, you `only` have to call `restart` to restart |
| info | Display component version information |
| help | Display help information |
- Boot options for the commands `start` and `restart`.
| Option | Description |
| --------- | --------- |
| -d|--daemonize | Run as a daemon, this option will override the `swoole.daemonize` setting in `laravels.php` |
| -e|--env | The environment the command should run under, such as `--env=testing` will use the configuration file `.env.testing` firstly, this feature requires Laravel 5.2+ |
| -i|--ignore | Ignore checking PID file of Master process |
| -x|--x-version | The version(branch) of the current project, stored in $_ENV/$_SERVER, access via `$_ENV['X_VERSION']` `$_SERVER['X_VERSION']` `$request->server->get('X_VERSION')` |
- `Runtime` files: `start` will automatically execute `php artisan laravels config` and generate these files, developers generally don't need to pay attention to them, it's recommended to add them to `.gitignore`.
| File | Description |
| --------- | --------- |
| storage/laravels.conf | LaravelS's `runtime` configuration file |
| storage/laravels.pid | PID file of Master process |
| storage/laravels-timer-process.pid | PID file of the Timer process |
| storage/laravels-custom-processes.pid | PID file of all custom processes |
## Deploy
> It is recommended to supervise the main process through [Supervisord](http://supervisord.org/), the premise is without option `-d` and to set `swoole.daemonize` to `false`.
```
[program:laravel-s-test]
directory=/var/www/laravel-s-test
command=/usr/local/bin/php bin/laravels start -i
numprocs=1
autostart=true
autorestart=true
startretries=3
user=www-data
redirect_stderr=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
```
## Cooperate with Nginx (Recommended)
> [Demo](https://github.com/hhxsv5/docker/blob/master/nginx/conf.d/laravels.conf).
```nginx
gzip on;
gzip_min_length 1024;
gzip_comp_level 2;
gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml application/x-httpd-php image/jpeg image/gif image/png font/ttf font/otf image/svg+xml;
gzip_vary on;
gzip_disable "msie6";
upstream swoole {
# Connect IP:Port
server 127.0.0.1:5200 weight=5 max_fails=3 fail_timeout=30s;
# Connect UnixSocket Stream file, tips: put the socket file in the /dev/shm directory to get better performance
#server unix:/yourpath/laravel-s-test/storage/laravels.sock weight=5 max_fails=3 fail_timeout=30s;
#server 192.168.1.1:5200 weight=3 max_fails=3 fail_timeout=30s;
#server 192.168.1.2:5200 backup;
keepalive 16;
}
server {
listen 80;
# Don't forget to bind the host
server_name laravels.com;
root /yourpath/laravel-s-test/public;
access_log /yourpath/log/nginx/$server_name.access.log main;
autoindex off;
index index.html index.htm;
# Nginx handles the static resources(recommend enabling gzip), LaravelS handles the dynamic resource.
location / {
try_files $uri @laravels;
}
# Response 404 directly when request the PHP file, to avoid exposing public/*.php
#location ~* \.php$ {
# return 404;
#}
location @laravels {
# proxy_connect_timeout 60s;
# proxy_send_timeout 60s;
# proxy_read_timeout 120s;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header Server-Protocol $server_protocol;
proxy_set_header Server-Name $server_name;
proxy_set_header Server-Addr $server_addr;
proxy_set_header Server-Port $server_port;
# "swoole" is the upstream
proxy_pass http://swoole;
}
}
```
## Cooperate with Apache
```apache
LoadModule proxy_module /yourpath/modules/mod_proxy.so
LoadModule proxy_balancer_module /yourpath/modules/mod_proxy_balancer.so
LoadModule lbmethod_byrequests_module /yourpath/modules/mod_lbmethod_byrequests.so
LoadModule proxy_http_module /yourpath/modules/mod_proxy_http.so
LoadModule slotmem_shm_module /yourpath/modules/mod_slotmem_shm.so
LoadModule rewrite_module /yourpath/modules/mod_rewrite.so
LoadModule remoteip_module /yourpath/modules/mod_remoteip.so
LoadModule deflate_module /yourpath/modules/mod_deflate.so