zhamao-robot / zhamao-framework

协程、高性能、灵活的聊天机器人 & Web 开发框架(炸毛框架)
https://framework.zhamao.xin
Apache License 2.0
158 stars 26 forks source link

如何在主进程中进行全局唯一 单例注册? #207

Closed YiwanGi closed 1 year ago

YiwanGi commented 1 year ago

描述

rt

例子

No response

crazywhalecc commented 1 year ago

首先,全局唯一的单例注册可能在多进程的模型下没有什么意义,因为每个 Worker 进程会复制主进程的进程空间,复制后父子进程和各个 Worker 之间的静态变量、单例,都是仅限于对应进程的,fork 后不同进程内操作都是分道扬镳的。在 Worker 重启后,新的 Worker 又会以 Master 进程(主进程,以下同理)内的进程空间为基础进行复制。

如果你想使用全局唯一的单例类,可以采用以下方法:

  1. 将 Worker 数调整为 1,即只 fork 一个 Worker 进程,所有操作均只在这一个 Worker 内进行。好处是既可以方便使用单例,也可以让 reload 等热重载不受影响。(reload 会重置 Worker 进程的内存空间)
  2. 将运行模式完全设置为单进程模式运行,单进程即从始至终都只会有一个 PHP 进程,无法使用 reload 热重载功能。但 2.x 和 3.x 框架设置的方式不太一样,下面会列举方法。

2.x 设置单进程启动

config/global.php 中的 swoole 内的 worker_num 删除,将 runtime 内的 swoole_server_mode 改为 SWOOLE_BASE

3.x 设置单进程启动

  1. 3.x 在 Windows 环境下默认以单进程模式启动。
  2. 在 Linux/macOS 环境下使用 Workerman 驱动无法设置为单进程模式。
  3. 使用 Swoole 驱动设置方式和 2.x 同理,但配置项变成了 swoole_options 内的 swoole_server_modeswoole_set 下的 worker_num
  4. 未来支持自编写的 Choir 驱动,可以直接使用单进程模式启动,目前还在跟进中。

但如果你还是想在多进程的情况下在主进程创建注册一个单例类,有以下的方法:

  1. 2.x 版本,可以使用 @OnSetup 注解,这个注解绑定的方法会在框架所有初始化操作之前执行,同时也必定是在 Master 进程内。
  2. 3.x 版本,可以使用 @Setup 注解,同理。