Clash 端口被占用怎么办:7890 冲突定位与修改监听端口全流程
启动提示 address already in use 时,先别急着重装或者换客户端。用 ss、lsof、netstat 找出占用 7890 端口的具体进程,判断是该结束这个进程还是改用别的端口,再按流程修改 mixed-port 并同步更新系统代理设置,整个过程几分钟就能走完。
端口冲突是怎么发生的
Clash 内核(无论是原版 Clash 还是 Mihomo)启动时会绑定一个本地端口用来接收代理流量,常见默认值是 7890。这个端口在配置文件里对应 mixed-port 字段(早期版本分成 port 和 socks-port 两个字段,现在多数客户端已经统一为 mixed-port,同时支持 HTTP 和 SOCKS5 协议)。当系统里已经有另一个进程占用了这个端口,内核绑定监听端口时就会失败,日志里通常会出现类似下面的信息:
ERRO[0000] Start HTTP server error: listen tcp 127.0.0.1:7890: bind: address already in use
这种报错的本质很简单:同一个端口在同一时刻只能被一个进程独占监听。造成冲突的原因常见有三类。第一类是重复启动,比如上一次 Clash 进程没有正常退出就直接又开了一个新实例,旧进程还占着端口。第二类是端口被其他软件抢先占用,常见的有其他代理工具(如 v2ray、trojan、其他 Clash 分支客户端)、开发环境里的本地服务、甚至某些容器映射出来的端口。第三类是同一台机器上跑了两套 Clash 相关服务,比如系统级的 clash 服务和用户手动跑的一个测试实例同时存在。
无论原因是哪一种,处理思路都是一样的:先定位到底是谁占用了端口,再决定结束它还是让 Clash 换个端口。
用 ss / lsof / netstat 定位占用进程
Linux 下有三个常用工具可以查看端口占用情况,任选一个即可,建议优先用 ss,它是目前主流发行版自带且性能最好的方式。
方法一:ss 命令
sudo ss -tulnp | grep 7890
输出里能看到本地地址、端口以及占用该端口的进程名和 PID,类似:
tcp LISTEN 0 4096 127.0.0.1:7890 0.0.0.0:* users:(("mihomo",pid=8123,fd=12))
括号里的 pid=8123 就是占用端口的进程 ID,"mihomo" 是进程名。如果这里显示的正是 Clash 自己的内核进程(mihomo 或 clash),说明是上一次实例没退干净,直接结束旧进程再重启客户端即可。
方法二:lsof 命令
如果系统没装 ss 或者习惯用 lsof,可以这样查:
sudo lsof -i :7890
输出会列出 COMMAND、PID、USER 等字段,同样能拿到占用进程的名称和 PID。lsof 在部分极简发行版上需要单独安装,Ubuntu/Debian 系可用 sudo apt install lsof,Fedora 系用 sudo dnf install lsof。
方法三:netstat 命令
netstat 在新版发行版里逐渐被 ss 取代,但很多脚本和老教程仍在用,查法如下:
sudo netstat -tulnp | grep 7890
三种命令拿到的信息本质一致,选一个能在自己系统上跑起来的即可,不需要都装。
提示
如果 grep 没有任何输出,说明当前 7890 端口实际上没有被占用,报错可能是配置文件里其他地方写错了地址(比如 bind-address 配置不当),或者是权限问题导致绑定失败,而不是单纯的端口冲突,这时应该去看完整的启动日志而不是继续纠结端口。
判断该结束进程还是改端口
定位到占用者之后,处理方式取决于这个进程是什么。
- 是 Clash/Mihomo 自己的残留进程:说明上一次没有正常退出,直接结束这个 PID,再重新启动客户端即可,不用改任何配置。
sudo kill 8123 # 若普通终止无效再用 sudo kill -9 8123 - 是其他代理工具或长期运行的服务:这类进程通常有明确用途,不建议随意结束,更稳妥的做法是让 Clash 换一个不冲突的端口。
- 是不认识、无法判断用途的进程:先用
ps -p PID -o comm=,args=查看完整启动命令,确认是不是系统关键服务(比如某些容器网络组件、数据库客户端代理),不确定就优先选择改端口而不是结束进程,避免影响其他正在使用的服务。
一般经验是:如果冲突方是 Clash 自己的旧进程,结束它是最干净的方案;如果冲突方是无关的第三方服务,改端口比结束进程更安全,尤其是在服务器或者多人共用的机器上,随意杀掉不熟悉的进程风险更高。
修改 mixed-port 并重启内核
确定要改端口后,找到 Clash 的配置文件(GUI 客户端一般在设置里能看到配置文件路径,命令行部署常见路径类似 ~/.config/clash/config.yaml 或 /etc/clash/config.yaml),把 mixed-port 改成一个未被占用的端口,比如 7891:
mixed-port: 7891
allow-lan: false
bind-address: "*"
mode: rule
log-level: info
如果你的配置文件里还保留着老式的 port 和 socks-port 分离写法,同样要一起改掉,并确认没有其他地方还写着旧端口号:
port: 7891
socks-port: 7892
改完端口之后,新的端口号本身也要先确认没有被占用,可以重复上一步的 ss -tulnp | grep 端口号 检查一遍,避免改了半天还是撞上另一个冲突。确认无误后,重启 Clash 服务或客户端使配置生效:
# systemd 管理的场景
sudo systemctl restart clash
# 手动运行内核的场景,先结束旧进程再重新启动
sudo pkill mihomo
mihomo -d /etc/clash
重启后再查看一次启动日志,确认没有再出现 bind: address already in use 的报错,同时确认监听端口已经切换成功:
sudo ss -tulnp | grep mihomo
同步更新系统代理设置
改完 mixed-port 只是让内核换了个地方监听,如果操作系统或浏览器的代理设置里还写着旧端口号,流量依然打不通,这一步经常被漏掉,导致排查者以为改端口没生效。
GNOME 桌面环境
gsettings set org.gnome.system.proxy mode 'manual'
gsettings set org.gnome.system.proxy.http host '127.0.0.1'
gsettings set org.gnome.system.proxy.http port 7891
gsettings set org.gnome.system.proxy.https host '127.0.0.1'
gsettings set org.gnome.system.proxy.https port 7891
也可以在「设置 → 网络 → 网络代理」的图形界面里直接把端口号改成新值。
命令行环境变量
如果习惯用环境变量方式走代理,同样要把端口改掉,建议写进 ~/.bashrc 或 ~/.zshrc 里长期生效:
export http_proxy="http://127.0.0.1:7891"
export https_proxy="http://127.0.0.1:7891"
export all_proxy="socks5://127.0.0.1:7891"
改完记得 source ~/.bashrc 让当前终端立即生效,否则已经打开的终端窗口仍会用旧端口。
浏览器插件
如果通过浏览器扩展(如 SwitchyOmega 一类的代理切换插件)配置代理规则,同样要进插件设置里把端口号从 7890 改成新端口,插件端口和系统端口是两套独立配置,互不联动。
注意
如果开启了 TUN 模式接管全局流量,TUN 模式本身不走 mixed-port 这个 HTTP/SOCKS 端口,理论上不受这次端口冲突影响;但如果同时还保留着系统代理或浏览器插件指向旧端口,退出 TUN 模式后这些设置就会失效,记得一并检查。
其他容易被忽略的细节
- 开机自启脚本里的旧端口号:如果用 systemd 或其他方式配置了开机自启,脚本或环境变量文件里可能单独硬编码了端口号,只改配置文件里的
mixed-port是不够的,启动脚本要同步检查。 - 外部控制面板端口:配置里的
external-controller(通常是 9090)是 Clash 的 API 管理端口,和代理端口mixed-port是两个独立的字段,如果 9090 也被占用会导致面板打不开,处理方式类似,单独排查即可。 - 多用户共用一台机器:如果同一台服务器有多个用户各自跑了一份 Clash 配置,建议每个用户使用不同的端口区间,避免频繁冲突,比如约定 7890~7899 给用户 A,7900~7909 给用户 B。
- Docker 容器场景:如果 Clash 跑在容器里,端口冲突还可能发生在宿主机的端口映射层,这时要查的是宿主机上
docker ps里的端口映射配置,而不是容器内部的mixed-port。
常见问题
改了端口后浏览器还是连不上代理? 大概率是系统代理设置或浏览器插件里的端口号没有同步改,回到上面「同步更新系统代理设置」章节逐项核对。
为什么每次重启电脑都会遇到一次端口冲突? 检查是否配置了开机自启的 Clash 服务,同时手动又习惯性双击图标启动一次客户端,导致两个实例先后抢占同一端口,只保留一种启动方式即可解决。
结束占用进程后还是无法启动? 用 ss -tulnp | grep 端口号 再确认一次端口是否真的已经释放,有些进程结束后端口会短暂处于 TIME_WAIT 状态,等几秒或换一个端口测试即可排除疑虑。
获取 Clash 客户端
下载页提供 Linux、Windows、macOS 等平台的客户端与内核选择,遇到配置问题也可以先查阅使用文档。