开发者必读
文件路径不要依赖当前工作目录
本地前台启动时,相对路径可能碰巧从项目根目录解析;使用 php easyswoole.php server start -d 后,Swoole 守护进程的当前工作目录可能变化,代码中的 ./Config、Temp/cache.json 就可能指向错误位置。这是工作目录变化,不是 -d 自动启用了 chroot。
在控制器、事件或任务中,用框架常量构造绝对路径:
$projectFile = EASYSWOOLE_ROOT . '/Config/business.php';
$temporaryFile = EASYSWOOLE_TEMP_DIR . '/business-cache.json';
EASYSWOOLE_ROOT 是项目根目录;EASYSWOOLE_TEMP_DIR 是已初始化的临时目录,默认对应项目下的 Temp,也可能由 TEMP_DIR 配置改到其他绝对路径。框架定义的是 EASYSWOOLE_TEMP_DIR,不是 EASYSWOOLE_TMP_DIR。配置文件加载发生在临时目录初始化之前,因此在 dev.php、produce.php 中设置目录时使用 EASYSWOOLE_ROOT,不要提前使用 EASYSWOOLE_TEMP_DIR。详情见基础管理命令与配置文件。
如果另外显式配置了 Swoole 的 chroot,那是真正的文件系统根目录隔离;还需确认这些绝对路径在隔离后的进程中可见,不能只靠改用常量解决。
常驻内存不是 PHP-FPM
Worker 启动后,已加载的类、静态属性、单例和全局变量会持续存在。不要假设一次请求结束后所有状态都会自动清空。
// 错误示例:不同请求会共享并累加
private static array $currentUser = [];
请求级数据应放在局部变量、请求对象或协程上下文中,并在生命周期结束时释放。
多进程之间不共享普通内存
每个 Worker 都有自己的 PHP 内存空间。修改某个 Worker 的数组、单例或配置,不会自动传播到其他 Worker。跨进程共享应使用数据库、Redis、Swoole Table、消息队列或明确的 IPC 机制。
注意协程安全
同一 Worker 可以交错执行多个协程。以下对象不应被并发请求随意复用:
- 保存“当前用户”等请求状态的单例。
- 没有连接池保护的数据库连接。
- 可变的全局 Request/Response 引用。
- 非协程安全的第三方客户端。
框架默认模板调用:
Coroutine::set(['hook_flags' => SWOOLE_HOOK_TCP]);
Hook 能力取决于 Swoole 版本和编译选项。启用 Hook 不代表任意扩展或 SDK 都自动变得协程安全。
阻塞操作
Worker 中执行长时间 CPU 计算或未被 Hook 的阻塞 I/O 会影响同一 Worker 处理其他请求。CPU 密集任务应考虑 Task Worker、独立进程或外部队列。
代码更新
PHP 文件修改后,已运行 Worker 不会像 PHP-FPM 一样在下一请求自动重新加载。开发或发布时执行:
php easyswoole.php server reload
主服务监听配置等启动期变更需要完整重启。
异常与日志
不要在生产接口中直接输出完整堆栈。控制器可以覆盖 onException(),将详细信息写入日志,对客户端返回稳定错误结构。