Webman高并发问卷系统需规避协程状态共享:禁用静态变量存用户数据,改用Context::set;数据库用support\Model确保协程独享连接;限流+submit_token实现幂等;导出走异步队列;插件通过容器隔离实例。

Webman 能撑起高并发问卷系统,但直接照搬传统 MVC 写法会很快卡死——核心问题不在框架本身,而在协程常驻模型下对状态、连接和资源的误用。
协程里别用静态变量存用户数据
问卷提交、选项统计这类操作极易因共享状态出错。比如在 SurveyController 里写 static $cache = [] 缓存题型配置,多个协程同时写入会导致覆盖或丢失。
- 改用
Context::set('survey.user_id', $uid)存当前协程私有数据 - 数据库查询必须走
support\Model基类,它会自动为每个协程分配独立连接实例 - 避免在中间件或监听器中初始化全局单例(如 Redis 客户端),应通过容器绑定+闭包工厂按需获取
高频提交场景必须加限流和幂等校验
问卷提交接口(如 /api/survey/submit)被脚本刷或前端重复点击时,INSERT INTO answers 会瞬间堆积,拖垮整个服务。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 用
RateLimiter中间件限制单 IP 每分钟最多 5 次提交 - 前端提交前生成唯一
submit_token,后端用Redis::setnx()校验并设置 5 分钟过期 - 不要依赖前端禁用按钮——它可被绕过;幂等逻辑必须落在服务端
导出 Excel 别在主线程里干
10 万份答卷导出 PHPSpreadsheet 会吃光内存并阻塞事件循环,所有请求挂起数秒。
- 把导出任务扔进异步队列(
support\Task或第三方如 Redis Queue) - 返回任务 ID,前端轮询
/api/export/status?id=xxx获取进度 - 导出文件生成后存到
public/export/目录,用 Nginx 直接 serve,不经过 PHP
插件化问卷模板要隔离上下文
若支持“自定义题型插件”(如评分矩阵、时间轴排序),每个插件的验证逻辑、渲染模板、统计方法必须完全独立。
- 插件注册时只 bind 接口,如
$container->bind('SurveyTypeInterface', MatrixType::class) - 实际调用用
$container->make(SurveyTypeInterface::class),确保每次 new 出干净实例 - 禁止插件内使用
$_SESSION或global,协程间不共享 - 插件配置热更新需监听
config/reload事件,而非重启进程
真正难的不是功能实现,而是把“每次请求都新建一切”的思维,切换成“进程永生、协程瞬逝”的状态管理——漏掉任意一环,高并发下数据就从错乱走向崩溃。


















