Swoft与Swoole有什么关系呢?
Swoole是一个异步引擎,核心是为PHP提供异步IO执行的能力,同时提供一套异步编程可能会用到的工具及。Swoole HTTP Server是Swoole中的一个组件,是Swoole Server中的一种服务器,提供了一个适合在Swoole上直接运行HTTP Server的环境。Swoft作为现代的Web框架和Swoole亲和性很高,同时也是Swoole HTTP Server模型的一个实践。
Swoole HTTP Server
Swoole-HTTP-ServerSwoole HTTP Server中充当WebServer角色的构件不仅仅有Nginx,应用本身也包含一个内建的WebServer,不过由于Swoole HTTP Server不是专业的HTTP Server,对HTTP的处理不完善,因此仍需要使用Nginx作为静态资源服务器以及反向代理,而Swoole HTTP Server仅处理PHP相关的HTTP流程。
由于Swoole已经包含了WebServer,不再需要实现CGI或FastCGI的通用协议去和WebServer通信。另外,Swoole有自己的进程管理,因此PHP-FPM也可以直接被去除。因此,对于PHP资源而言,Swoole HTTP Server的地位相当于传统模型中的Nginx和PHP-FPM。
Swoole HTTP Server的优势在于一次加载常驻内存,不同的请求之间基本上复用了onRequest
以外的所有流程,使得每个请求的开销大大降低。异步IO的特性使得这种模型吞吐量远远高于传统的LNMP模型。另外,相对于独立的Swoole服务,内嵌在Web系统中的Swoole使用起来更加直接方便,支持更好。
Swoft
Swoole生命周期 onWorkStart在Swoft服务启动阶段,重点关注OnWorkerStart
事件,此事件会在Worker
启动的时候触发,这个过程也是Swoft众多机制实现的关键,此时Swoft会执行:扫描目录、读取配置文件、收集注解信息、收集事件监听器...,然后根据扫描到的注解信息执行对应的功能逻辑,并存储在与注解对应的Collector
容器内,包括但不限于注册路由信息、注册事件监听器、注册中间件、注册过滤器...
Swoft的生命周期是什么样的呢?
每个请求从开始到结束,都是由Swoole本身的onRequest()
或onResponse()
事件监听并委托给Dispatcher
来处理并响应的,而Dispatcher
得主要职责是负责调度请求声明周期内的各个参与者(组件)。
在HTTP服务器中将由ServerDispatcher
负责调度,参与者主要包括RequestContext
、ExceptionHandler
、RequestHandler
。
-
RequestContext
请求上下文:作为当前的请求信息的容器将贯穿整个请求生命周期,负责信息的存储和传递。 -
ExceptionHandler
异常处理器:在遇到异常的情况时出来收拾场面,确保在各种异常情况下依旧能给客户端返回一个预期内的结果。 -
RequestHandler
请求处理器:是整个请求生命周期的核心组件,也就是中间件Middleware
,该组件实现了PSR-15
协议。- 负责将
Request
->Router
->Controller
->Action
->Render
->Response
整个请求流程贯穿起来,也就是从Request
到Response
的过程。 - 只要在任意一个环节返回一个有效的
Response
对象便能对该请求做出响应并返回
- 负责将
应用结构
一个完整的Swoft应用可以包含
- HTTP服务
- WebSocket服务
- RPC服务
Swoft的目录结构
ls -ali
total 273
13153 drwxrwxrwx 1 1000 staff 4096 Apr 24 09:34 .
1309178 drwxr-xr-x 1 root root 4096 Jan 21 14:46 ..
26529 -rwxrwxrwx 1 1000 staff 316 Jan 21 14:38 .editorconfig
26525 -rwxrwxrwx 1 1000 staff 2471 Apr 23 20:35 .env
26530 -rwxrwxrwx 1 1000 staff 328 Jan 21 14:38 .env.docker-compose
26531 -rwxrwxrwx 1 1000 staff 2471 Jan 21 14:38 .env.example
26532 drwxrwxrwx 1 1000 staff 4096 Apr 24 09:35 .git
26520 drwxrwxrwx 1 1000 staff 0 Apr 23 19:24 .github
26521 -rwxrwxrwx 1 1000 staff 123 Jan 21 14:38 .gitignore
27458 drwxrwxrwx 1 1000 staff 4096 Apr 24 09:35 .idea
26523 -rwxrwxrwx 1 1000 staff 978 Jan 21 14:38 .php_cs
26522 -rwxrwxrwx 1 1000 staff 557 Jan 21 14:38 .phpstorm.meta.php
26524 -rwxrwxrwx 1 1000 staff 469 Jan 21 14:38 .travis.yml
13365 -rwxrwxrwx 1 1000 staff 2782 Jan 21 14:38 CONTRIBUTING.md
13368 -rwxrwxrwx 1 1000 staff 2068 Jan 21 14:38 Dockerfile
13369 -rwxrwxrwx 1 1000 staff 11357 Jan 21 14:38 LICENSE
13373 -rwxrwxrwx 1 1000 staff 5992 Jan 21 14:38 README.md
13374 -rwxrwxrwx 1 1000 staff 5653 Jan 21 14:38 README_CN.md
13359 drwxrwxrwx 1 1000 staff 4096 Apr 23 19:24 app
13360 drwxrwxrwx 1 1000 staff 0 Apr 23 19:24 bin
13361 -rwxrwxrwx 1 1000 staff 1520 Jan 21 14:38 changelog.md
13362 -rwxrwxrwx 1 1000 staff 1882 Jan 21 14:38 composer.json
13363 -rwxrwxrwx 1 1000 staff 181853 Apr 23 20:02 composer.lock
13364 drwxrwxrwx 1 1000 staff 0 Apr 23 19:24 config
13366 -rwxrwxrwx 1 1000 staff 1999 Jan 21 14:38
13367 -rwxrwxrwx 1 1000 staff 335 Apr 23 19:35 docker-compose.yml
13370 -rwxrwxrwx 1 1000 staff 853 Jan 21 14:38 phar.build.inc
13371 -rwxrwxrwx 1 1000 staff 695 Jan 21 14:38 phpunit.xml
13372 drwxrwxrwx 1 1000 staff 0 Apr 23 19:24 public
13375 drwxrwxrwx 1 1000 staff 0 Apr 23 19:24 resources
13376 drwxrwxrwx 1 1000 staff 0 Apr 23 19:24 runtime
13377 drwxrwxrwx 1 1000 staff 0 Apr 23 19:31 swoft
13378 drwxrwxrwx 1 1000 staff 0 Apr 23 19:24 test
13379 drwxrwxrwx 1 1000 staff 4096 Apr 23 20:02 vendor
服务管理 bin/swoft
php bin/swoft -h
____ __ _
/ ___|_ _____ / _| |_
\___ \ \ /\ / / _ \| |_| __|
___) \ V V / (_) | _| |_
|____/ \_/\_/ \___/|_| \__|
Usage:
php bin/swoft -h {command} [arguments] [options]
Commands:
app There are some help command for application[built-in]
dev Some commands for application dev[built-in]
entity The group command list of database entity
gen Generate some common application template classes[built-in]
rpc The group command list of rpc server
server The group command list of HTTP-Server
test Test command
ws There are some commands for manage the webSocket server
Options:
-h, --help Display help information
-v, --version Display version information
- HTTP服务器
# 启动HTTP服务,根据.env环境配置决定是否设置为后台守护进程。
$ php bin/swoft start
# 启动HTTP服务,-d表示以后台守护进程(daemonize)方式运行,会覆盖.env环境配置中的项目。
$ php bin/swoft start -d
# 重启HTTP服务
$ php bin/swoft restart
# 重新加载
$ php bin/swoft reload
# 关闭服务
$ php bin/swoft stop
- WebSocket服务器
$ php bin/swoft ws:start
$ php bin/swoft ws:start -d
$ php bin/swoft ws:restart
$ php bin/swoft ws:stop
$ php bin/swoft ws:reload
- RPC服务器
$ php bin/swoft rpc:start
$ php bin/swoft rpc:start -d
$ php bin/swoft rpc:restart
$ php bin/swoft rpc:stop
$ php bin/swoft rpc:reload
启动流程
启动流程- 基础
bootstrap
行为:如必要的常量define
、composer
加载器引入、配置读取... - 需要生成被所有
worker/task
进程共享的程序全局期的对象 - 启动时所有进程中只能执行一次的操作:如前置Process的启动...
-
Bean
容器基本初始化以及项目启动流程需要的coreBean
的加载
环境配置.env
# 应用程序
# 设置时区
TIME_ZONE=Asia/Shanghai
# 是否开启日志
LOG_ENABLE=false
# 是否开启应用程序调试模式
APP_DEBUG=false
# 服务器配置
# 进程编号文件,当在一台机器上同时运行多个服务器时需更改pid文件。
PFILE=@runtime/swoft.pid
# 项目名称,当在一台机器上同时运行多个服务器时需配置,以方便区分服务器。
PNAME=php-swoft
# 是否启动RPC远程过程调用
TCPABLE=true
# 是否启动定时任务
CRONABLE=false
# 是否启用热重载,推荐开发环境启用。
AUTO_RELOAD=true
AUTO_REGISTER=false
# HTTP服务器设置
HTTP_HOST=0.0.0.0
HTTP_PORT=80
HTTP_MODE=SWOOLE_PROCESS
HTTP_TYPE=SWOOLE_SOCK_TCP
# WebSocket服务器设置,WebSocket服务器继承自HTTP服务器。
WS_ENABLE_HTTP=true
# TCP服务器配置
TCP_HOST=0.0.0.0
TCP_PORT=8099
TCP_MODE=SWOOLE_PROCESS
TCP_TYPE=SWOOLE_SOCK_TCP
TCP_PACKAGE_MAX_LENGTH=2048
TCP_OPEN_EOF_CHECK=false
# Crontab定时任务配置
CRONTAB_TASK_COUNT=1024
CRONTAB_TASK_QUEUE=2048
# Swoole配置
WORKER_NUM=1
MAX_REQUEST=100000
DAEMONIZE=0
DISPATCH_MODE=2
TASK_IPC_MODE=1
MESSAGE_QUEUE_KEY=1879052289
TASK_TMPDIR=/tmp/
LOG_FILE=@runtime/logs/swoole.log
TASK_WORKER_NUM=1
PACKAGE_MAX_LENGTH=2048
OPEN_HTTP2_PROTOCOL=false
SSL_CERT_FILE=/path/to/ssl_cert_file
SSL_KEY_FILE=/path/to/ssl_key_file
# 数据库主节点配置
DB_NAME=dbMaster
DB_URI=127.0.0.1:3306/test?user=root&password=123456&charset=utf8,127.0.0.1:3306/test?user=root&password=123456&charset=utf8
DB_MIN_ACTIVE=5
DB_MAX_ACTIVE=10
DB_MAX_WAIT=20
DB_MAX_WAIT_TIME=3
DB_MAX_IDLE_TIME=60
DB_TIMEOUT=2
# 数据库从节点
DB_SLAVE_NAME=dbSlave
DB_SLAVE_URI=127.0.0.1:3306/test?user=root&password=123456&charset=utf8,127.0.0.1:3306/test?user=root&password=123456&charset=utf8
DB_SLAVE_MIN_ACTIVE=5
DB_SLAVE_MAX_ACTIVE=10
DB_SLAVE_MAX_WAIT=20
DB_SLAVE_MAX_WAIT_TIME=3
DB_SLAVE_MAX_IDLE_TIME=60
DB_SLAVE_TIMEOUT=3
# Redis配置
REDIS_NAME=redis
REDIS_DB=2
REDIS_URI=127.0.0.1:6379,127.0.0.1:6379
REDIS_MIN_ACTIVE=5
REDIS_MAX_ACTIVE=10
REDIS_MAX_WAIT=20
REDIS_MAX_WAIT_TIME=3
REDIS_MAX_IDLE_TIME=60
REDIS_TIMEOUT=3
REDIS_SERIALIZE=1
# other redis node
REDIS_DEMO_REDIS_DB=6
REDIS_DEMO_REDIS_PREFIX=demo_redis_
# User service (demo service)
USER_POOL_NAME=user
USER_POOL_URI=127.0.0.1:8099,127.0.0.1:8099
USER_POOL_MIN_ACTIVE=5
USER_POOL_MAX_ACTIVE=10
USER_POOL_MAX_WAIT=20
USER_POOL_TIMEOUT=200
USER_POOL_MAX_WAIT_TIME=3
USER_POOL_MAX_IDLE_TIME=60
USER_POOL_USE_PROVIDER=false
USER_POOL_BALANCER=random
USER_POOL_PROVIDER=consul
# User service breaker (demo service)
USER_BREAKER_FAIL_COUNT = 3
USER_BREAKER_SUCCESS_COUNT = 6
USER_BREAKER_DELAY_TIME = 5000
# Consul
CONSUL_ADDRESS=http://127.0.0.1
CONSUL_PORT=8500
CONSUL_REGISTER_NAME=user
CONSUL_REGISTER_ETO=false
CONSUL_REGISTER_SERVICE_ADDRESS=127.0.0.1
CONSUL_REGISTER_SERVICE_PORT=8099
CONSUL_REGISTER_CHECK_NAME=user
CONSUL_REGISTER_CHECK_TCP=127.0.0.1:8099
CONSUL_REGISTER_CHECK_INTERVAL=10
CONSUL_REGISTER_CHECK_TIMEOUT=1