1. 端口基础概念:你每天都在用,但真的懂它吗?
说实话,端口这个概念,很多运维干了两三年还是模模糊糊的。我刚开始接触网络时也觉得——不就是个数字嘛,能通就行。直到有一次线上故障,我排查了半天才发现是端口被占用了……嗯,从那以后我再也不敢小看这个“数字”了。
端口是什么?说白了,它就是计算机和外界通信的“门牌号”。你的服务器只有一个IP地址,但可以同时跑Web服务、数据库、SSH——怎么区分这些流量?靠的就是端口号。
一句话记住:IP地址找到你的机器,端口号找到机器上的具体服务。
1.1 TCP/UDP端口号范围
端口号是一个16位的数字,范围从0到65535。这个范围被分成了三段,每一段的用途都不一样。我习惯用“三扇门”来理解它:
| 分类 | 范围 | 说明 | 我见过的坑 |
|---|---|---|---|
| Well-Known Ports (知名端口) |
0 - 1023 | 系统保留,需要root权限才能绑定 | 我曾经在非root用户下启动Nginx,结果80端口死活起不来 |
| Registered Ports (注册端口) |
1024 - 49151 | 用户进程可用,但部分被IANA分配给特定应用 | 3306、8080这些经常被抢,你想想看 |
| Dynamic / Private Ports (动态/私有端口) |
49152 - 65535 | 临时端口,客户端发起连接时随机分配 | TIME_WAIT状态大多集中在这个范围 |
我的小习惯:生产环境自定义服务端口,我一般选在 10000-20000 之间,避开常见注册端口,也方便iptables批量放行。
1.2 常见服务默认端口
这些端口你得背下来,不是死记硬背,而是遇到问题能条件反射。我列几个最常碰到的:
- HTTP (80) —— Web服务的默认大门。我遇到过最离谱的事:有人把Nginx配成了8080,然后问为什么用户访问不了。
- HTTPS (443) —— 加密的HTTP。现在基本是标配了,连个人博客都上HTTPS了。
- SSH (22) —— 远程管理的命脉。我个人习惯把SSH端口改掉,不是为了防黑客,而是为了减少日志里的扫描噪音。
- MySQL (3306) —— 数据库的默认端口。注意,3306是TCP,但MySQL也支持Socket通信,不走网络端口。
- DNS (53) —— 这个比较特殊,同时用TCP和UDP。UDP用于查询,TCP用于区域传输。
- Redis (6379) —— 缓存数据库。默认无密码,暴露在外网就是找死。
- Elasticsearch (9200/9300) —— 9200是HTTP接口,9300是节点间通信。
⚠️ 避坑指南:我曾经接手过一个项目,开发把MySQL端口改成了3307,但运维脚本里写死了3306。结果每次重启服务都要手动改配置……嗯,从那以后我要求所有服务的端口信息必须写在统一的配置中心里。
1.3 端口状态:LISTEN、ESTABLISHED、TIME_WAIT
你用 netstat -an 或者 ss -an 看端口状态时,会看到一堆状态码。这三个是最常见的,也是排查问题时的关键线索。
| 状态 | 含义 | 排查要点 |
|---|---|---|
| LISTEN | 端口在监听,等待连接 | 服务是否启动?是否绑定了正确的IP? |
| ESTABLISHED | 连接已建立,正在通信 | 连接数是否异常?对端IP是否可信? |
| TIME_WAIT | 连接已关闭,但端口还在等待 | 大量TIME_WAIT会导致端口耗尽 |
LISTEN —— 这是你服务正常运行的标志。如果端口没在LISTEN,服务要么没启动,要么启动失败了。我排查的第一步永远是:ss -tlnp | grep 端口号。
ESTABLISHED —— 表示有客户端正在和你通信。如果ESTABLISHED数量异常高,可能是流量突增,也可能是被攻击了。我记得有一次,某台服务器ESTABLISHED飙到2万多,一查发现是爬虫在疯狂抓数据。
TIME_WAIT —— 这个状态最让人头疼。它是TCP主动关闭连接的一方会进入的状态,持续2MSL(约1-4分钟)。为什么要有这个状态?说白了,就是为了保证最后一个ACK能到达对方。大量TIME_WAIT会导致端口被占用,新连接无法建立。
我的经验:高并发场景下,TIME_WAIT是绕不开的坎。我一般用 net.ipv4.tcp_tw_reuse 和 net.ipv4.tcp_fin_timeout 来优化,但注意——tcp_tw_recycle 在NAT环境下会出大问题,千万别乱开。
1.4 一张图看懂端口知识体系
下面这张图是我自己梳理的端口知识框架,从端口号分类到常见服务,再到状态机,一条线串起来。你把它存下来,以后排查问题时对着看就行。
1.5 实战:快速查看端口状态
光说不练假把式。我平时排查端口问题,最常用的就是下面这几条命令。你直接复制到终端里跑就行:
# 查看所有监听中的TCP端口
ss -tlnp
# 查看指定端口(比如3306)的监听状态
ss -tlnp | grep 3306
# 查看ESTABLISHED连接数
ss -tan | grep ESTAB | wc -l
# 查看TIME_WAIT数量
ss -tan | grep TIME-WAIT | wc -l
# 查看某个端口被哪个进程占用
lsof -i :80
我的建议:别再用 netstat 了,ss 命令更快、更现代。而且 ss 的输出格式更清晰,适合写脚本做监控。