Composer install不会死锁,所谓“卡住”99%是依赖求解、网络fallback或缓存污染导致的假死;Resolving dependencies阶段实为SAT求解器暴力回溯版本冲突,非网络问题,且无超时机制,可能耗尽内存。

Composer install 不会死锁——它根本没有文件锁或并发竞争逻辑,所谓“卡住”99% 是依赖求解、网络 fallback 或缓存污染导致的假死。
为什么 composer install 会卡在 Resolving dependencies
这是最常被误判为“死锁”的场景。实际上 composer install 本身不解析依赖,只按 composer.lock 还原;但如果你删了 lock 文件又没手动补上,它会悄悄退化成 composer update 行为,触发 SAT 求解器暴力回溯。
- 现象:CPU 拉满、终端无输出、
composer.lock长时间未更新 - 确认方式:立刻中断,运行
composer install --dry-run -v,看末尾是否反复出现同一路径(如vendor/a → vendor/b → vendor/a) - 根本原因:
composer.json中存在隐式循环依赖(比如require-dev里某个测试工具 autoloads 了你的 src/,而你的代码又用了它的类) - 别等它自己退出——SAT 求解器没有超时机制,可能跑满内存才崩
换中文镜像后命令行无响应怎么办
这不是镜像“卡死”,是 Composer 在 fallback 到 packagist.org 后因 DNS/TLS 超时挂起,本质是配置静默失效。
- 必须三步清障:
composer clear-cache→ 删除vendor/和composer.lock→ 再跑composer install --no-cache - 别保留旧
composer.lock:它记录的是原始源的包哈希,和镜像返回的元数据不兼容,必报hash does not match - 验证镜像生效:
composer config -g repo.packagist输出 URL 必须带结尾/,否则拼接路径出错导致 404
高并发下载卡在 Downloading 阶段
不是网络慢,是镜像 QPS 限流触发了请求排队——默认并发数 5~10,在 CI 环境下极易被打满。
- 必须同时做三件事:配置至少 3 个国内镜像(每个带
"canonical": false)、全局设concurrent-downloads为 2、执行composer clear-cache - 错误信号:
curl: (28) Operation timed out或日志里反复重试同一包 - 注意:
http-max-concurrent-downloads是旧配置项,新版用repos.packagist.org.concurrent-downloads - 多镜像不是负载均衡,而是顺序 fallback——第一个响应快的才被采用,后面全跳过
Windows 下 Permission denied 或文件占用失败
不是文件锁争用,是进程或 IDE 正在占用 vendor/ 下的文件,尤其常见于 Swoole、Xdebug、PhpStorm 索引服务。
- 先关掉所有 PHP 进程(
php -S、Laravel Sail、Valet)、禁用 Xdebug、退出 PhpStorm - 用 PowerShell 执行
Remove-Item -Recurse -Force vendor\some-package,避开全局删除失败 - 仍不行?重启终端(CMD/PowerShell),或临时加
--prefer-dist减少对符号链接的依赖(Windows 默认禁用 symlinks) -
composer install --force-reinstall可强制覆盖重装,但前提是composer.lock已是最新的——否则版本错乱
真正麻烦的从来不是“卡住”本身,而是你不知道它卡在哪一层:是依赖图闭环、镜像 fallback、QPS 限流,还是 Windows 文件句柄没释放。每种现象对应完全不同的排查路径,混用方案只会让问题更模糊。











