ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Linux连接数查看与排查:ss/netstat命令实战指南

Linux连接数查看与排查:ss/netstat命令实战指南 作为一个常年泡在服务器上排查问题的人我见过太多同事在“查连接数”这一步就翻车了。不是说命令不会敲而是经常搞混一件事你到底要查的是哪个“连接数”。有一段时间我们线上Nginx频繁告警有人直接跑了netstat -anp | grep ESTABLISHED | wc -l出来一个四千多的数字当场以为被打流量了结果把状态一拆开发现真正活跃的ESTABLISHED才三百不到剩下的全是TIME_WAIT。那个四千多只是历史短连接留下的“尾巴”根本不影响当前处理能力。Linux查看连接数这个话题看起来就是个命令查询但深入下去其实牵扯到TCP状态机、套接字缓存、内核参数、应用层连接池甚至还有进程文件描述符的数量限制。这篇文章我会把“查看连接数”这件事从头到尾拆开先帮你把概念理清再讲ss、netstat、lsof这类命令怎么组合用然后给出一套从“看到数字”到“定位根因”的排查链路最后补上MySQL、Nginx、Redis、PostgreSQL这些常见业务服务的连接数查看口径。适合刚入门的运维新手也适合那些被线上连接数告警折磨过的老同学。1. 先弄明白连接数这个“数”用好几个口径去看是完全不同的1.1 一个TCP连接的“身份证”四元组要理解连接数首先要理解什么才算“一条连接”。TCP层面的连接是由四元组唯一确定的本地IP 本地端口 远端IP 远端端口。四元组完全一致才算同一条连接任何一个元素不同就是不同连接。举个例子你的服务器是10.0.0.1:80有成千上万个客户端来访问每个客户端的源IP:源端口都不相同那对应的连接就是成千上万条但服务器本地监听端口始终是80所以它们在“本地两端”上看是同一个10.0.0.1:80在“远端两端”上则彼此独立。这个知识点看似基础但很重要。因为后面你会看到运维口中的“连接数”绝大多数时候是指远端维度的连接总和“服务端口连接数”则是在过滤本地端口后统计出来的。如果概念不清后面所有统计命令的过滤条件都会选错。1.2 实际工作里大家口中的“连接数”至少有六种我在实际交流和故障排查中发现大家嘴里的“连接数”至少指向以下几种不同的指标场景或提问实际要关注的指标最推荐的口令“当前服务器有多少TCP连接”所有状态的TCP连接总数ss -tan | wc -l“现在有多少活跃的并发连接”仅ESTABLISHED状态的连接数ss -tan state established | wc -l“某个端口承载了多少连接”过滤本地端口后的连接数ss -tan ( sport :80 )“有没有某个IP在大量连我”按远端IP聚合的连接数ss -tan | awk {print $5} | sort | uniq -c“这个进程开了多少连接”按进程名/PID过滤的连接数ss -tanp | grep 进程名“系统连接表还能扛多少”文件描述符上限、连接跟踪表条目数ulimit -n、cat /proc/sys/fs/file-max如果连要查什么指标都没想清楚就直接敲命令数行数结果大概率是错的。比如“服务很卡连接数是不是爆了”这句话正确的做法是看ESTABLISHED和SYN_RECV这类会占用当前处理资源的连接状态而不是傻乎乎地把TIME_WAIT也加进去算总数。TIME_WAIT多只影响“新建连接时本地端口是否够用”并不代表当前服务正在被多少客户端同时使用。2. 两条主命令的完整拆解netstat 与 ss2.1 netstat老牌命令至今仍在大量旧文档里出现netstat 隶属于 net-tools 工具包在多数Linux发行版里可以用yum install net-tools或apt install net-tools装上。它的核心数据来源是/proc/net/tcp、/proc/net/tcp6、/proc/net/udp这些内核导出的伪文件系统。命令每执行一次就要遍历一次这些文件把文本解析成连接表所以连接数一旦上了几十万netstat的实际开销会非常难看。用的最多的一组参数是netstat -anpt-a显示所有状态的连接包括LISTEN、ESTABLISHED、TIME_WAIT等-n不解析主机名和端口名直接显示数字避免发起DNS反查导致卡住-p显示进程PID和程序名需要root权限才能看到全部进程-t只看TCP连接。输出大概是这样的Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1234/sshd tcp 0 0 10.0.0.1:3306 10.0.0.8:52134 ESTABLISHED 2345/mysqld tcp 0 0 10.0.0.1:3306 10.0.0.9:40000 TIME_WAIT -注意几个容易踩的细节第一netstat输出的TCP状态是大写加下划线的写法比如TIME_WAIT、CLOSE_WAIT、ESTABLISHED第二只有root用户配合-p才能看到其他进程的PID普通用户可能看到-第三LISTEN行的远端地址是0.0.0.0:*意味着还没有具体连接对象。低连接数环境下netstat完全够用但对线上高并发的机器我一般都劝大家少用尤其不要写进定时采集脚本里。一次全量遍历也许没什么如果每秒钟跑一次在高连接数下CPU和磁盘IO都会莫名其妙升高排查半天发现是监控脚本自己的问题那就尴尬了。2.2 ss当前生产环境我更推荐的主查命令ss 是 iproute2 工具包里的命令和ip、bridge等命令同源。它的数据获取方式不是去遍历/proc下的文本文件而是通过 netlink 套接字直接向内核查询socket信息解析开销小、性能高输出格式也更利于脚本处理。我平时最常用的几个组合是ss -tan ss -tanp ss -lnt ss -s-a全部连接-tTCP-n数字显示-p显示进程-l只看LISTEN监听状态-s打印当前协议的汇总统计。ss -tan的输出格式是State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:22 0.0.0.0:* ESTAB 0 0 10.0.0.1:3306 10.0.0.8:52134 users:((mysqld,pid2345,fd21)) TIME-WAIT 0 0 10.0.0.1:3306 10.0.0.9:40000可以看到ss的状态名和netstat是有差异的它是缩写加连字符比如ESTAB、TIME-WAIT、CLOSE-WAIT、SYN-RECV。这个差异平时不注意一旦写成自动化脚本用grep TIME_WAIT去抓ss的输出什么都抓不到。我后来养成了一个习惯所有脚本里先统一命令再统一状态名避免混用。ss 还有一个很实用的特性就是原生支持按状态过滤ss -tan state established ss -tan state time-wait ss -tan state close-wait ss -tan state syn-recv用这种方式统计特定状态的连接数比grep加wc -l干净很多ss -tan state established | wc -l ss -tan state time-wait | wc -l ss -tan state close-wait | wc -l如果还要按端口过滤ss 的过滤表达式也可以组合ss -tan state established ( sport :80 ) ss -tan state time-wait ( dport :3306 )这里括号在shell里是特殊字符所以要用单引号包起来。2.3 两条命令怎么看“总量”ss -s 与 netstat -s很多运维上来直接数行数其实想看的只是一个整体健康度这种场景根本不需要全量数。ss 提供了一个极简的汇总视图ss -s输出类似Total: 587 (kernel 290) TCP: 1560 (estab 1024, closed 120, orphaned 10, synrecv 0, timewait 30/0), ports 0 Transport Total IP IPv6 * 290 - - RAW 0 0 0 UDP 25 20 5 TCP 1560 1240 320 INET 1585 1260 325 FRAG 0 0 0这个输出里最有价值的是estab和timewait这两个数字一眼就能看出活跃连接和TIME_WAIT堆积程度。orphaned表示孤儿连接一般是应用没有及时close同时连接又还没有完全断开的情况数量持续偏高时值得警惕。netstat 的对应命令是netstat -s它输出的是完整协议统计内容很长里面有SYN重传次数、主动连接失败次数、各种重置等。当怀疑网络层有丢包或三次握手机制问题时我会同时结合netstat -s和ss -s来看前者偏协议计数后者偏当前socket快照。3. 连接数统计的四种拆法状态、远端、端口、进程3.1 按状态分布统计先看全貌再下结论连接数异常时我从来不急着看具体某个数字而是先看所有TCP状态的全部分布。只需要一条管道命令ss -tan | awk NR1 {print $1} | sort | uniq -c | sort -rnNR1是为了跳过ss输出的表头行$1是状态列后面sort | uniq -c的作用是分组计数最后sort -rn把数量多的状态排到前面。输出类似1520 ESTAB 210 TIME-WAIT 18 LISTEN 3 CLOSE-WAIT 1 SYN-RECV看到这个全貌后你的判断依据就完全不一样了。ESTAB占绝对大头说明是真实并发在上面跑TIME-WAIT占大头说明是短连接频繁建立和释放但不代表当前压力CLOSE-WAIT有堆积那基本可以认定是应用层没有正确关socketSYN-RECV很多则要怀疑握手队列或者SYN攻击。这里我有一个小建议任何一次连接数排查不管最后定位到什么结论第一步都先跑这个全状态分布。因为后面所有针对性统计都是在确认这个分布里某个数字背后的具体来源。你先看的是“病”再去找“病原体”。3.2 按远端IP统计找出谁在向你“灌”连接当ESTAB或者SYN-RECV的数量异常高时最直接的问题是“这些连接从哪来”。IPv4环境下可以提取Peer Address:Port的IP部分做聚合ss -tan | awk NR1 {print $5} | grep -oE ([0-9]{1,3}\.){3}[0-9]{1,3} | sort | uniq -c | sort -rn | head -n 20$5是Peer列也就是远端地址后面的grep -oE只提取IPv4地址把端口剥掉。这样你就能看见6320 10.0.0.88 830 10.0.0.76 102 192.168.1.12如果你发现自己根本不认识10.0.0.88这个IP或者它不在预期业务网段里这基本就是连接异常的直接来源。有一次我就是靠这条命令发现某个内网业务服务器因为配置错误疯狂用短连接请求另一台机器的接口连接数从几百冲到六千多排查问题的方向立刻就对了。注意如果是IPv6环境上面的grep -oE匹配不到IPv6地址。更通用的做法是把IPv6的方括号和端口处理掉ss -tan | awk NR1 {print $5} | sed s/\[//g; s/\]//g | awk -F: NF2 {ip$2; for(i3;iNF;i) ipip:$i; print ip} NF2 {print $1}不过大多数内网场景还是IPv4为主一条简单命令够用。3.3 按本地端口统计量化服务承载量想确认某个服务进程到底扛了多少连接按本地端口聚合会更直观。提取Local Address:Port里的端口号ss -tan | awk NR1 {print $4} | grep -oE [0-9]$ | sort | uniq -c | sort -rn输出类似8200 80 750 443 120 3306这说明你本机在80端口上有8200条TCP连接443上有750条3306上有120条。想再精细一点只看特定端口的活跃连接ss -tan state established ( sport :80 ) | wc -l ss -tan state syn-recv ( sport :80 ) | wc -l这种过滤在ss里是不需要grep的直接在netlink层做过滤比管道文本过滤更高效尤其连接数很大的机器上性能差距非常明显。3.4 按进程/应用维度统计从系统看业务连接最终归属于某个进程所以从进程维度看往往能直接定位到“哪个应用在制造连接”。ss -tanp会多出Process列内容形如users:((nginx,pid31245,fd8))。想按进程名做统计可以用sed把进程名提取出来ss -tanp | grep ESTAB | sed -n s/.*users:((\([^]*\).*/\1/p | sort | uniq -c | sort -rn输出类似4320 nginx 780 mysqld 192 java如果想知道某个PID下具体连接了哪些地址可以直接ss -tanp | grep pid31245 ss -tanp | grep nginx要补充一个偏门的命令lsof -i :端口它在定位“哪个进程占着某个端口”时非常好用lsof -i :80 lsof -p 31245 | grep -c TCP但lsof在连接数极大时性能很差因为它的实现是遍历进程所有的文件描述符再逐一判定socket。如果你机器上有几万个连接偶发用一次可以别写进高频脚本。4. 连接数异常不等于故障要把状态当线索去排查4.1 TIME_WAIT 堆积短连接太猛端口不够用TIME_WAIT是TCP主动关闭方在连接结束后进入的状态需要等待两个MSLLinux默认约60秒才能彻底消失。设计它的主要目的是防止旧连接的迟到报文进入新连接以及让对端确认收到最后的ACK。这不是故障状态但堆积太多会有副作用。TIME_WAIT大量出现的前提是本机主动发起了大量短连接并主动关闭。比如服务端程序使用短连接去访问MySQL每执行一次就新建一个TCP连接用完后主动断掉那么在60秒内这些断开的连接都会以TIME_WAIT形式存在。如果QPS很高几万个TIME_WAIT一点都不奇怪。TIME_WAIT过多最直观的风险是本地端口耗尽。Linux默认的临时端口范围在net.ipv4.ip_local_port_range里通常是从32768到60999也就是不到3万个可用端口。如果每秒有几千个短连接在建立和释放3万个临时端口会被很快占满后续connect会直接报Cannot assign requested address。我排查TIME_WAIT堆积一般做三件事第一先量化ss -tan state time-wait | wc -l第二按远端IP看谁触发了这些短连接ss -tan state time-wait | awk NR1 {print $5} | grep -oE ([0-9]{1,3}\.){3}[0-9]{1,3} | sort | uniq -c | sort -rn第三决定处理策略。如果确认是业务侧发起连接的一方优先改应用层把短连接改成连接池或长连接复用这才是治本。系统层面的辅助手段是调整tcp_tw_reusesysctl -w net.ipv4.tcp_tw_reuse1 sysctl -w net.ipv4.tcp_timestamps1tcp_tw_reuse必须依赖tcp_timestamps它允许客户端复用处于TIME_WAIT状态的连接作为新连接。但注意它只管“本机作为发起方”的场景如果是服务端被动大量接受连接这个参数帮不上忙。至于老文档里常写的tcp_tw_recycle内核早已把它废弃或标记为高危尤其在NAT环境会引发无法建连的奇葩故障不要再用它了。4.2 CLOSE_WAIT 居高不下应用没关socket典型bug信号CLOSE_WAIT是TCP断开流程里一个很特别的状态。正常四次挥手是这样的主动关闭方发FIN被动关闭方内核回ACK此时被动关闭方的状态变成CLOSE_WAIT表示“对方已经提出关闭等应用程序调用 close() 来完成剩余挥手”。如果应用层一直不调用close这个状态就会一直挂着操作系统又不能自己帮你收尾于是CLOSE_WAIT堆积。换句话说CLOSE_WAIT多几乎和网络无关就是应用层代码不关连接的信号。常见原因有三类开发写了阻塞IO操作线程卡住了压根没走到释放连接的代码使用HTTP客户端、数据库连接池时没有处理好连接回收异常后连接泄漏对端发来了FIN但本进程忙于处理大量请求事件循环调度不过来close迟迟没有执行。排查CLOSE_WAIT先把数量和归属进程查出来ss -tan state close-wait | wc -l ss -tanp | grep CLOSE-WAIT如果数量持续累积再看具体是哪个进程ss -tanp | grep CLOSE-WAIT | sed -n s/.*users:((\([^]*\).*/\1/p | sort | uniq -c | sort -rn定位到进程后基本就是结合业务日志和线程转储找到“谁没有关闭资源”。临时止血可以先重启服务开发同学看到CLOSE_WAIT减少就明白方向了。这个状态别想着靠内核参数解决内核不知道应用什么时候可以把socket彻底关掉只能应用自己close。4.3 SYN_RECV 异常握手队列与并发压测的隐藏问题SYN_RECV表示本端已经收到客户端的SYN并且回了SYNACK但是等待对方的ACK完成三次握手。正常情况下这个状态非常少基本瞬间就转成ESTAB了。如果SYN_RECV数量长期很高意味着大量半连接无法完成握手要从两个方向排查。方向一看看是不是SYN Flood之类的拒绝服务。特征是对端IP非常分散、源端口随机、连注释都没有的握手请求。这时候上面按远端IP聚合的命令会看到很多一次性IP。方向二也可能是正常的业务突发但半连接队列太小导致新到的SYN无法进入队列客户端重试堆积表现为SYN_RECV居高不下。Linux里和半连接队列相关的内核参数主要是sysctl -w net.ipv4.tcp_max_syn_backlog8192 sysctl -w net.core.somaxconn8192同时还要看应用层listen的backlog值。比如Nginx的listen 80 backlog8192;否则内核参数再大应用不接也白搭。查看队列溢出情况我习惯用netstat协议统计netstat -s | grep -i SYNs to LISTEN sockets dropped netstat -s | grep -i times the listen queue of a socket overflowed如果这两个计数在持续上涨就说明确实有握手请求被丢掉需要加大队列或者看看后端处理能力是不是跟不上了。4.4 系统级硬限制file-max、ulimit 与 nf_conntrackTCP连接在系统级至少占用一个文件描述符、一个socket内存对象如果是NAT或负载均衡场景还会占用一个连接跟踪表条目。所以连接数能否增长很多时候根本不是应用的问题而是系统硬限制卡住了。文件描述符层面的上限要分两级看ulimit -n cat /proc/sys/fs/file-maxulimit -n是当前shell/进程能打开的最大文件数/proc/sys/fs/file-max是整个系统能打开的文件总数上限。对于systemd管理的服务比如Nginx、Java服务光改/etc/security/limits.conf是不够的因为systemd会用自己的限制覆盖需要在service单元里加LimitNOFILE100000 LimitNPROC65535这个坑我踩过一次limits.conf改好了ulimit -n显示也变了但重启服务后还是报too many open files最后发现是服务自身的systemd文件里写死了LimitNOFILE。另一个容易被忽略的是连接跟踪表。只要系统加载了nf_conntrack很多环境会作为依赖自动加载所有TCP连接都会被记录这个表满了新连接直接丢包cat /proc/sys/net/netfilter/nf_conntrack_count cat /proc/sys/net/netfilter/nf_conntrack_max如果count接近maxdmesg -T | grep nf_conntrack大概率能看到类似nf_conntrack: table full, dropping packet的日志。调整方式sysctl -w net.netfilter.nf_conntrack_max1048576 sysctl -w net.netfilter.nf_conntrack_buckets262144注意nf_conntrack_buckets通常要在装载模块前或通过/sys/module/nf_conntrack/parameters/hashsize调整有的发行版sysctl直接设置不一定生效。不过这是另一个大话题了这里先提醒大家知道有这层限制存在。5. 常用业务服务的连接数查看口径5.1 MySQLThreads_connected 与 max_connections遇到的MySQL连接问题多半不是靠ss去看的虽然ss也能看但MySQL自己提供了更直接的业务口径。登录MySQL后执行SHOW GLOBAL STATUS LIKE Threads_connected; SHOW GLOBAL STATUS LIKE Threads_running; SHOW VARIABLES LIKE max_connections;Threads_connected是当前所有客户端打开的连接数Threads_running是正在执行语句的线程数比connected更能反映真实压力max_connections是允许的最大连接数。如果Threads_connected经常接近max_connections客户端新建连接就会得到Too many connections错误这时候除了加max_connections更重要的是排查是否有连接泄漏或者连接池配置太小。想看到每个来源的连接情况SHOW PROCESSLIST;这条命令返回所有当前连接及其来源Host和状态能快速看出是不是某个应用服务器把连接数打满了。5.2 NginxActive connections 与 upstream观察Nginx自带的stub_status模块是查看连接数最标准的方式但要先开启。在server配置里加一个locationlocation /nginx_status { stub_status on; allow 127.0.0.1; allow 你的内网网段; deny all; }配置好后访问这个路径会得到Active connections: 291 server accepts handled requests 200026 200026 1050324 Reading: 6 Writing: 179 Waiting: 106Active connections是当前从accept到close的活跃连接数包括Waiting里的空闲keepalive连接accepts是累计接受的客户端连接数handled是累计处理的连接数正常情况下和accepts相等如果差异越来越大大概率是worker进程fd耗尽Reading正在读请求头Writing正在写响应Waiting空闲连接。不配置stub_status的情况下我通常直接ss -tan state established ( sport :80 ) | wc -l ss -tan state close-wait ( sport :80 ) | wc -l这里把80换成443就是HTTPS的连接情况。Nginx作为反向代理时还可以看看它到后端upstream的连接ss -tanp | grep nginx | grep 后端IP如果upstream连接数堆积不是Nginx本身的问题而是后端服务处理不过来的信号需要去查后端的线程池和队列了。5.3 Redis 与 PostgreSQL各自的状态命令Redis查看连接数非常简洁redis-cli info clients输出里的connected_clients是当前客户端连接数maxclients是最大允许连接数。Redis是单线程事件循环模型连接数高本身不是最大瓶颈但如果大量连接同时发请求CPU会先被打满所以看到连接数高时先看一眼info stats里的命令处理量。PostgreSQL那边常用的SQLSELECT count(*) FROM pg_stat_activity; SELECT state, count(*) FROM pg_stat_activity GROUP BY state;pg_stat_activity记录了所有后端进程状态包括idle、active、idle in transaction等。active是真正在执行的查询idle in transaction很危险说明有事务开着没提交会占住连接和锁时间长了会把连接池吃光。这类问题和Linux的CLOSE_WAIT有些类似属于“连接没释放”的另一个形态不过它是数据库连接层的事。6. 实战经验侧记统计连接数的几个习惯与坑6.1 高并发环境下为什么我坚持用 ss 而不是 netstat几年前我接手过一台连接数长期十几万的机器同事的监控脚本用的是netstat每隔5秒统计一次ESTABLISHED。看似没问题但脚本跑起来时机器CPU会莫名出现一个小尖峰。后来我分析发现netstat每次执行要遍历大量/proc/net/tcp和/proc/net/tcp6文件再逐行解析十几万行的解析在cpu调度上并不便宜连续执行时不仅有CPU开销还会因为文本解析逻辑简单而漏掉一些连接状态。换成ss之后cpu开销肉眼可见地降下来了。ss通过netlink直接查询内核socket表数据获取路径短还支持在内核态进行部分过滤。如果你要在生产环境写定时统计脚本我的建议很简单主查命令统一用ss尽量避免netstat。不是netstat不能用而是同样条件下ss性价比高得多。6.2 统计脚本里容易被坑的细节第一是状态名不一致。ss输出TIME-WAIT、CLOSE-WAITnetstat输出TIME_WAIT、CLOSE_WAITss的汇总统计里又叫timewait。如果你在脚本里用grep TIME_WAIT | wc -l去过滤ss的输出结果是0。统一用ss -tan state time-wait | wc -l可以完全绕开这个坑。第二是IPv6问题。上面提到的awk {print $5}然后按:切分IPv6地址会切出很多段。写脚本时要么明确环境是IPv4要么先处理方括号别让统计结果在IPv6机器上产生垃圾数据。第三是快照不能当趋势用。单次的ss -s只是一个时间点的固定值连接数告警需要看持续变化的曲线。我通常会把统计命令输出写入监控系统或者至少用watch -n 1连续观察几秒看趋势而不是孤零零的一个数字。watch -n 1 ss -s watch -n 1 ss -tan state established | wc -l6.3 一次连接数告警到定位根因的完整流程最后分享一个我实际处理过的案例把前面所有步骤串起来。某天下午一台核心接口机报TCP连接数监控阈值触发一开始监控图上显示连接总数从平时的两三千涨到一万二左右。我先在机器上跑了全状态分布ss -tan | awk NR1 {print $1} | sort | uniq -c | sort -rn结果显示6320 TIME-WAIT 3180 ESTAB 210 SYN-RECVTIME-WAIT和SYN-RECV都偏高说明这个机器的主动连接和被动握手都存在异常。因为机器本身是Nginx按理说不应该有这么多的主动连接我判断可能是业务逻辑在往某个后端疯狂发起短连接。接着按远端IP聚合ss -tan | awk NR1 {print $5} | grep -oE ([0-9]{1,3}\.){3}[0-9]{1,3} | sort | uniq -c | sort -rn果然一个内网IP占了六千多条而且都是TIME-WAIT。我又把这个IP过滤出来看状态分布ss -tan state time-wait | grep 10.0.0.88 | head -n 10发现连接的对端端口范围非常集中都在3306附近基本可以确定是这个IP对应的业务服务在通过短连接访问数据库。最后在数据库侧确认确实出现了大量来自该IP的连接释放记录。处理方案分两步短期的调整该业务服务的数据库访问方式把每次请求新建连接改成连接池复用长期的在系统层面开启了tcp_tw_reuse配合timestamps让主动发起方的TIME_WAIT能被复用。执行后连接数在半小时内回落到两千多告警消除。这个案例给我最大的体会是连接数告警只是表象真正的价值在于顺着连接状态分布、远端IP、端口、进程四个维度一层层往下钻。只要路数对大部分连接数异常都能在半小时间内定位到具体来源。现在团队里的新同学问我看连接数用什么命令我都会先反问一句你确定你要查的是哪个数想清楚了再动手。
返回列表