Address already in use 端口地址已在使用中

文章讲述了在开发过程中遇到本地服务每次运行后端口被占用的问题,导致报错Addressalreadyinuse。作者找到了解决方案,即在服务关闭或应用被杀死时,正确终止当前端口的服务,确保下次能重新使用该端口。实现这一目标的方法包括在onDestroy()函数中停止服务并释放端口资源。

在这里插入图片描述

写一个本地服务,每次运行之后,之前的端口号使用不了,报错Address already in use 地址已在使用中,端口号被占用,老烦了,每次都得换一个端口,老不稳定了,这个得想办法解决,经过几天挣扎,找到解决方法了。

问题报错日志:

java.net.BindException: Address already in use
	at sun.nio.ch.Net.bind0(Native Method)
	at sun.nio.ch.Net.bind(Net.java:454)
	at sun.nio.ch.Net.bind(Net.java:446)
	at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
	at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
	at org.java_websocket.server.WebSocketServer.doSetupSelectorAndServerThread(WebSocketServer.java:567)
	at org.java_websocket.server.WebSocketServer.run(WebSocketServer.java:367)
	at java.lang.Thread.run(Thread.java:761)

解决:
其实很简单,就是退出或者应用被杀死时,结束掉当前端口得服务,再次启用时重新启动就好,而我这边得情况是,停止当前端口得服务,下次重新启动服务,这个端口号还能继续使用,其他情况,大家可以通过指令(cmd)杀掉这个端口的服务,具体方法百度一下。
例如:

override fun onDestroy() {
        // 标记服务关闭
        serviceIsLive = false
        // 移除通知
        stopForeground(true)
        super.onDestroy()
        //应用被杀死就停掉所有服务,这个后面需要优化
        stopAndServer()
        SocketServer.webStop()
        Log.e(TAG, "onDestroy")
    }
<think>我们面对的问题是:ZooKeeper启动时报"Address already in use"错误,但通过检查发现端口2181实际上并没有被其他进程占用。这种情况可能由多种原因引起,下面将逐步分析并给出解决方案。 ### 🔍 问题分析 根据引用[1][2][3]提供的信息,结合常见ZooKeeper问题,我们分析可能的原因如下: 1. **系统保留端口**:Windows系统(特别是Win10)中Hyper-V保留端口范围可能导致该问题(引用[3]) 2. **僵尸进程/死锁**:ZooKeeper进程未完全退出,导致端口仍被系统标记为占用 3. **IPv4/IPv6双栈冲突**:服务同时尝试绑定IPv4和IPv6地址时可能产生冲突 4. **防火墙/安全软件干扰**:安全软件可能阻止端口绑定但不显示在端口检测中 5. **配置错误**:`zoo.cfg`中配置了多个端口绑定或错误的绑定地址 ### 🛠 解决方案(针对Linux系统) #### 步骤1:确认端口真实状态 使用更全面的检查命令: ```bash # 检查所有状态(包括TIME_WAIT) sudo netstat -tulnp | grep :2181 # 检查内核端口分配 sudo ss -lntp | grep 2181 ``` 如果显示`TIME_WAIT`状态,可等待1-2分钟或调整内核参数: ```bash # 临时降低TIME_WAIT回收时间 sudo sysctl net.ipv4.tcp_tw_reuse=1 ``` #### 步骤2:检查IPv6绑定冲突 修改`zoo.cfg`明确指定IPv4绑定: ```ini # 强制使用IPv4 clientPortAddress=0.0.0.0 ``` #### 步骤3:检查系统保留端口(Linux版) 查看系统保留端口范围: ```bash cat /proc/sys/net/ipv4/ip_local_port_range # 正常输出应为:32768 60999 ``` 如果2181落在保留范围内,修改配置: ```bash # 临时扩大保留范围 sudo sysctl net.ipv4.ip_local_port_range="10000 65000" ``` #### 步骤4:彻底终止ZooKeeper进程 使用强制清理方式: ```bash # 查找所有Java进程(ZooKeeper通常以Java运行) ps -ef | grep zookeeper # 终止相关进程 sudo kill -9 <PID1> <PID2> ... # 确认进程终止 pgrep -f zookeeper ``` #### 步骤5:清理锁文件(关键步骤) 当进程异常退出时可能遗留锁文件: ```bash # 进入ZooKeeper数据目录 cd /path/to/zookeeper/data # 删除锁文件 rm -f zookeeper_server.pid ``` #### 步骤6:使用调试模式启动 获取详细错误信息: ```bash zkServer.sh start-foreground ``` 重点关注以下日志: - `java.net.BindException`的具体原因 - 是否出现`Cannot assign requested address`等系统级错误 ### ⚠ 针对Windows系统的特殊处理(参考引用[3]) 虽然用户使用Linux,但若在Windows环境遇到此问题: 1. 以管理员身份运行命令提示符 2. 检查Hyper-V保留端口: ```cmd netsh interface ipv4 show excludedportrange protocol=tcp ``` 3. 若2181在保留范围内,解除保留: ```cmd netsh int ipv4 delete excludedportrange protocol=tcp startport=2181 numberofports=1 ``` ### 💡 根本解决方案 | 问题类型 | 永久解决方案 | |---------|------------| | 端口保留 | 修改系统保留端口范围或ZooKeeper端口 | | 进程残留 | 完善服务停止脚本,确保完全退出 | | 双栈冲突 | 在`zoo.cfg`中明确指定`clientPortAddress` | | 权限问题 | 使用非特权端口(>1024)或授权服务用户 | ### 📚 引用说明 [^1]: ZooKeeper报错"Address already in use"的常见原因及解决方案,包括端口占用和系统保留问题。 [^2]: Kafka环境中ZooKeeper启动日志示例,显示成功绑定端口前的完整流程。 [^3]: Windows 10系统因Hyper-V保留端口导致2181端口不可用的特殊情况。 --- ### 🔍 相关问题 1. 如何修改Linux系统临时端口范围以避免服务端口冲突? 2. ZooKeeper集群部署时出现端口绑定失败该如何排查? 3. 为什么`netstat`命令有时无法检测到僵尸进程占用端口? 4. 如何为ZooKeeper配置SSL加密通信?</think>### 解决 ZooKeeper 报 "Address already in use" 但端口未被占用的问题 当 ZooKeeper 启动时报 `Address already in use` 错误,但实际检查发现端口 2181 并未被占用时,通常是由于**系统级端口保留**或**进程死锁**导致的。以下是逐步解决方案: --- ### 🔍 根本原因分析 1. **系统保留端口范围**(尤其 Windows) Hyper-V 等虚拟化技术会保留端口范围,使 2181 端口无法使用(引用[3]) 2. **僵尸进程死锁** ZooKeeper 进程未完全退出,端口仍被内核标记为占用但不可见 3. **IPv4/IPv6 双栈冲突** 服务同时尝试绑定 IPv4 和 IPv6 地址时产生冲突 4. **TIME_WAIT 状态残留** 之前连接处于 `TIME_WAIT` 状态(需等待 60-120 秒释放) --- ### 🛠 解决方案(Linux 环境) #### 步骤 1:验证真实端口状态 ```bash # 检查所有状态(包括TIME_WAIT) sudo netstat -tulnp | grep :2181 # 使用更底层的ss命令 sudo ss -lntp | grep 2181 ``` 若显示 `TIME_WAIT`,等待 2 分钟再试。 #### 步骤 2:彻底终止残留进程 ```bash # 查找所有Java进程(ZooKeeper通常以Java运行) ps -ef | grep -i zookeeper # 强制终止相关进程 sudo kill -9 <PID> # 确认进程终止 pgrep -f zookeeper ``` #### 步骤 3:检查系统保留端口(Linux) ```bash # 查看系统保留端口范围 cat /proc/sys/net/ipv4/ip_local_port_range # 正常输出:32768 60999 (2181不在范围内) # 若2181被保留,临时修改范围 sudo sysctl net.ipv4.ip_local_port_range="10000 65000" ``` #### 步骤 4:修改 ZooKeeper 绑定配置 编辑 `zoo.cfg` 添加: ```ini # 强制使用IPv4 clientPortAddress=0.0.0.0 ``` #### 步骤 5:清理锁文件 ```bash # 进入ZooKeeper数据目录 cd /path/to/zookeeper/data # 删除残留锁文件 rm -f zookeeper_server.pid ``` #### 步骤 6:使用调试模式启动 ```bash zkServer.sh start-foreground ``` 观察日志中是否有: ``` java.net.BindException: Address already in use (Failed to bind to /0.0.0.0:2181) ``` --- ### ⚠️ Windows 系统特殊处理(参考引用[3]) 若在 Windows 遇到此问题: 1. 以管理员身份运行 CMD: ```cmd netsh interface ipv4 show excludedportrange protocol=tcp ``` 2. 若 2181 在保留范围内: ```cmd netsh int ipv4 delete excludedportrange protocol=tcp startport=2181 numberofports=1 ``` --- ### 🔧 预防措施 1. **修改默认端口**(在 `zoo.cfg` 中): ```ini clientPort=21810 # 使用非常用端口 ``` 2. **添加启动等待**(在启动脚本中): ```bash sleep 5 # 等待旧进程完全释放 ``` 3. **使用连接复用**(降低端口冲突概率): ```bash sudo sysctl net.ipv4.tcp_tw_reuse=1 ``` --- ### 💡 技术原理 当出现 "Address already in use" 但端口未被占用时,通常是由于: 1. 内核将端口标记为 `TIME_WAIT` 状态(需等待 2MSL 时间) 2. 套接字处于 `FIN_WAIT2` 状态未完全关闭 3. 系统安全策略禁止绑定特权端口(<1024) > 通过 `ss -aeopn` 命令可查看详细的套接字状态[^1] --- ### 🔍 相关问题 1. 如何永久修改 Linux 系统的临时端口范围? 2. ZooKeeper 集群部署时如何避免端口冲突? 3. Windows 系统如何彻底禁用 Hyper-V 端口保留? 4. 除了 2181 端口,ZooKeeper 还需要哪些端口
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值