Laravel环境下使用wkhtmltopdf批量生成PDF如何不新增硬件提升速度
性能优化方案
你当前的性能瓶颈本质是4核配置下,原有20个进程的超配策略带来了大量上下文切换开销,同时wkhtmltopdf冗余功能、队列与环境的额外消耗吃掉了硬件提升带来的收益,可从以下方向调整:
1. 进程数适配CPU核心数
wkhtmltopdf属于CPU密集型任务,超配过多进程反而会导致调度开销飙升:
- 将supervisord配置的PHP worker数量从20降低到
8~10(CPU密集型任务最优进程数为核心数*2,可根据实际负载微调) - 任务运行时通过
top命令查看总CPU占用,调整worker数直到总CPU长期稳定在380%左右(4核满负载为400%),避免资源浪费
2. wkhtmltopdf 执行参数优化
默认配置下wkhtmltopdf开启了大量非必要功能,调整参数可降低单任务30%以上耗时:
- 不需要JS渲染时直接添加
--disable-javascript参数,需要JS执行时添加--javascript-delay 100将默认等待时间降到最低 - 批量生成场景可关闭冗余功能:添加
--disable-external-links、--disable-internal-links、--disable-smart-shrinking、--no-stop-slow-scripts参数,对质量要求不高时可添加--lowquality参数进一步提升生成速度 - 所有HTML依赖的CSS、字体、图片资源全部本地化存储,优先内联到HTML模板中,避免wkhtmltopdf发起HTTP请求拉取资源产生的等待开销
3. Laravel 任务与队列优化
- 队列驱动从
database切换为redis,避免数据库驱动的任务弹出锁开销,大幅提升队列消费速度 - 任务类中配置
public $tries = 1关闭不必要的任务重试,关闭生成过程中的debug日志,减少磁盘IO开销 - 动态HTML模板提前缓存公共部分,仅替换每个任务的动态变量,减少PHP渲染耗时
- 生成的PDF优先写入本地磁盘,全部处理完成后再异步同步到远端存储,避免网络IO阻塞生成流程
- 可尝试复用wkhtmltopdf常驻实例,避免每个任务都重新启动wkhtmltopdf进程的额外开销
4. Docker 运行环境优化
- 容器启动时添加
--log-driver none参数关闭默认日志收集,避免进程输出写入容器日志的IO开销 - 容器启动时添加
--cpuset-cpus 0-3参数绑定固定CPU核心,减少跨核心调度的上下文切换开销 - 部署环境允许的情况下关闭SELinux、AppArmor安全模块,减少系统调用的校验开销
内容的提问来源于stack exchange,提问作者murume
相关产品推荐
相关产品推荐

