Webman是基于PHP+Swoole的高性能异步Web框架,非Python框架;需用composer create-project初始化,依赖Swoole扩展,运行命令为php start.php start,不依赖Apache/Nginx托管。

Webman 不是 Python 框架,也不是纯前端工具——它是基于 PHP + Swoole 的高性能异步 Web 框架,和 Laravel、ThinkPHP 定位不同,但性能更接近 Workerman。直接拿它当“调查问卷 CMS”用会踩坑,必须按它的运行模型来设计。
Webman 是什么?先别装 pip 或 npm
看到“pip install webman”就停手。Webman 是 PHP 生态项目,不是 Python 包。所有混淆都源于早期中文资料误传(比如把 Workerman/Webman 名字写混、把 Python 投票脚本套上 Webman 标签)。真实 Webman 项目由 composer create-project workerman/webman 初始化,依赖 swoole 扩展,运行靠 php start.php start,不是 Apache/Nginx 直接托管。
- 如果你的服务器没装 PHP 8.1+ 和
swoole,webman命令根本不存在 - 所谓“Webman 2.2.0 强化 TCP/UDP 支持”,指的就是 Swoole 底层能力,不是框架自己写的网络层
- 数据库操作默认用
think-swoole或illuminate/database,不是 Django ORM 那套
投票功能的核心:状态一致性不能靠 session_file
Webman 默认不启用传统 PHP session(因为多进程下文件锁会拖垮并发),用户登录态、投票记录、防刷标记必须走外部存储。否则高并发时出现“同一人投两次”或“计票漏加”是必然的。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 用 Redis 存
vote:token:{user_id}标记已投,过期时间设为投票截止后 5 分钟 - 计票更新必须用 Lua 脚本或
INCR原子操作,避免SELECT + UPDATE导致竞态 - 不要在
$_SESSION里存选项 ID 列表——Webman 的session组件默认关闭,开了也建议配 Redis 驱动
路由与中间件怎么配才不丢请求
Webman 的路由是注册制,不是文件扫描制。写错路径前缀或 HTTP 方法,请求直接 404,连日志都不打——尤其注意 POST /api/vote 和 GET /api/result 必须显式声明,不能靠控制器命名自动映射。
- 在
config/route.php里用Route::post('/api/vote', [VoteController::class, 'store']),别写成Route::any() - 防刷中间件必须放在全局中间件数组最前,否则
$request->get('ip')可能被后续中间件覆盖 -
$request->post('option_id')返回 null 时,不是参数没传,而是 Content-Type 不是application/x-www-form-urlencoded或multipart/form-data—— 前端发 JSON 就得用$request->post()+ 手动json_decode($request->rawBody(), true)
部署后为什么 ab 测试压不出 28 万并发
单机 28 万并发是特定场景下的极限值(静态响应 + 内存充足 + 网络直连 + 关闭日志),真实投票系统带数据库写入、Redis 查询、JSON 编码,QPS 通常卡在 3000–8000。盲目追求数字反而掩盖瓶颈。
- 测试前关掉
config/log.php中的file日志驱动,改用null或syslog - MySQL 连接池必须启用,否则每个请求新建连接,100 并发就耗尽 max_connections
- 前端 Nginx 如果开了 gzip,会吃掉大量 CPU,压测时建议关掉,用
ab -H "Accept-Encoding: identity"
真正要盯的是 Redis 连接数、MySQL 的 Threads_running、Swoole 的 worker_num 是否匹配 CPU 核心数——这些比“框架多快”影响更大。


















