Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1965799
  • 博文数量: 498
  • 博客积分: 2078
  • 博客等级: 大尉
  • 技术积分: 1645
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-18 22:43
个人简介

安大

文章分类

全部博文(498)

文章存档

2017年(1)

2016年(2)

2015年(21)

2014年(90)

2013年(101)

2012年(267)

2011年(16)

分类: LINUX

2013-03-07 13:47:45

欢迎转载,版权所有,转载请保留文档的完整性!
大家对ss或者或者本篇文章有任何见解,欢迎随时沟通

还在用netstat吗?你OUT了


ss是iproute2工具包中的工具。
ss is used to dump socket statistics. It allows showing information similar to netstat.  It can display more TCP and state informations than other tools.
1. 为什么用ss替换netstat?    
这要从netstat的先天缺陷说起,netstat通过遍历proc来获取socket信息,当socket数据上万后,netstat的输出就非常耗时(用过的都知道
)
而与之不同的ss使用netlink与内核tcp_diag模块通信获取socket信息。
2.ss命令输出解释之Recv-Q Send-Q
先来看一下ss的输出:
tingw:~ # ss -at
State       Recv-Q Send-Q                                            Local Address:Port                                                Peer Address:Port   
LISTEN      0      128                                                          :::sunrpc                                                        :::*       
LISTEN      0      128                                                           *:sunrpc                                                         *:*       
LISTEN      0      128                                                          :::http                                                          :::*       
LISTEN      0      128                                                   127.0.0.1:ipp                                                            *:*       
LISTEN      0      128                                                         ::1:ipp                                                           :::*       
LISTEN      0      100                                                         ::1:smtp                                                          :::*       
LISTEN      0      100                                                   127.0.0.1:smtp                                                           *:*       
LISTEN      0      64                                                           :::59642                                                         :::*       
LISTEN      0      128                                                           *:54107                                                          *:*       
LISTEN      0      128                                                          :::xinupageserver                                                       :::*       
LISTEN      0      128                                                           *:xinupageserver                                                        *:*       
LISTEN      0      64                                                            *:50341                                                          *:*       
LISTEN      0      50                                                            *:mysql                                                          *:*       
ESTAB       0      52                                                  192.168.0.1:xinupageserver                                             192.168.0.96:50599  

输出所有的tcp socket信息。
第一列表示tcp socket的状态,第二列和第三列的内容与socket所处的状态有关,查看tcp_diag代码

点击(此处)折叠或打开

  1. static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
  2.                               void *_info)
  3. {
  4.         const struct tcp_sock *tp = tcp_sk(sk);
  5.         struct tcp_info *info = _info;
  6.                                                                                                                     
  7.         if (sk->sk_state == TCP_LISTEN) {
  8.                 r->idiag_rqueue = sk->sk_ack_backlog;
  9.                 r->idiag_wqueue = sk->sk_max_ack_backlog;
  10.         } else {
  11.                 r->idiag_rqueue = tp->rcv_nxt - tp->copied_seq;
  12.                 r->idiag_wqueue = tp->write_seq - tp->snd_una;
  13.         }
  14.         if (info != NULL)
  15.                 tcp_get_info(sk, info);
  16. }

处于LISTEN状态的socket,Recv-Q表示了current listen backlog队列元素数目(等待用户调用accept的完成3次握手的socket),而Send-Q表示了listen socket最大能容纳的backlog。这个数目由listen时指定,且不能大于 /proc/sys/net/ipv4/tcp_max_syn_backlog;对于非LISTEN socket,Recv-Q表示了receive queue中的字节数目(等待接收的下一个tcp段的序号-尚未从内核空间copy到用户空间的段最前面的一个序号);Send-Q表示发送queue中容纳的字节数(已加入发送队列中最后一个序号-输出段中最早一个未确认的序号
3.ss命令输出解释之timer

linux-19:~ # ss -a -t -o -4
State       Recv-Q Send-Q                                            Local Address:Port                                                Peer Address:Port   
LISTEN      0      128                                                           *:sunrpc                                                         *:*       
LISTEN      0      128                                                           *:47093                                                          *:*       
LISTEN      0      3                                                  192.168.86.1:domain                                                         *:*       
LISTEN      0      3                                                  192.168.0.86:domain                                                         *:*       
LISTEN      0      3                                                    10.0.64.19:domain                                                         *:*       
LISTEN      0      3                                                 192.168.100.3:domain                                                         *:*       
LISTEN      0      3                                                172.16.132.189:domain                                                         *:*       
LISTEN      0      3                                                     127.0.0.2:domain                                                         *:*       
LISTEN      0      3                                                     127.0.0.1:domain                                                         *:*       
LISTEN      0      128                                                           *:ssh                                                            *:*       
LISTEN      0      128                                                   127.0.0.1:ipp                                                            *:*       
LISTEN      0      100                                                           *:smtp                                                           *:*       
LISTEN      0      128                                                   127.0.0.1:953                                                            *:*       
LISTEN      0      64                                                            *:33914                                                          *:*       
LISTEN      0      64                                                            *:nfs                                                            *:*       
LISTEN      0      128                                                           *:35659                                                          *:*       
LISTEN      0      128                                                           *:remotefs                                                        *:*       
LISTEN      0      128                                                  10.0.64.19:6380                                                           *:*       
LISTEN      0      128                                                           *:openvms-sysipc                                                        *:*       
ESTAB       0      0                                                172.16.132.189:ssh                                                172.16.132.93:hs-port  timer:(keepalive,65min,0)
ESTAB       0      0                                                    10.0.64.19:35225                                                10.0.64.129:61616   
ESTAB       0      0                                                    10.0.64.19:46617                                                10.0.64.107:61616   
ESTAB       0      0                                                    10.0.64.19:openvms-sysipc                                                10.0.64.2:videotex 
ESTAB       0      0                                                    10.0.64.19:49462                                                10.0.64.107:61616   
ESTAB       0      0                                                172.16.132.189:ssh                                                172.16.132.85:63934    timer:(keepalive,38min,0)
ESTAB       0      0                                                    10.0.64.19:60569                                                10.0.64.107:61616   
ESTAB       0      0                                                    10.0.64.19:52745                                                10.0.64.129:61616   
ESTAB       0      52                                               172.16.132.189:ssh                                                172.16.132.92:50598    timer:(on,476ms,0)
ESTAB       0      0                                                    10.0.64.19:56401                                                10.0.64.107:61616   
ESTAB       0      0                                                    10.0.64.19:54805                                                10.0.64.129:61616   
ESTAB       0      0                                                    10.0.64.19:60772                                                10.0.64.129:61616   
ESTAB       0      0                                                    10.0.64.19:55510                                                10.0.64.129:61616   
ESTAB       0      0                                                    10.0.64.19:45663                                                10.0.64.129:61616   
ESTAB       0      0                                                    10.0.64.19:39262                                                10.0.64.129:61616   
ESTAB       0      0                                                    10.0.64.19:57775                                                10.0.64.129:61616   
ESTAB       0      0                                                    10.0.64.19:52205                                                 10.0.64.18:6379    
ESTAB       0      0                                                    10.0.64.19:remotefs                                               10.0.64.12:sentinel 

这个输出更上次输出相比,多了一个timer输出。这个输出描述的是tcp socket上的定时器,在说明这个之前先了解一下linux对一个tcp socket可能设置的定时器。
tcp socket总共有7个定时器,通过4个timer实现。分别是
通过icsk_retransmit_timer实现的重传定时器、零窗口探测定时器;通过sk_timer实现的连接建立定时器、保活定时器和FIN_WAIT_2定时器;通过icsk_delack_timer实现的延时ack定时器;以及TIME_WAIT定时器。

我们看一下ss的代码

点击(此处)折叠或打开

  1. static const char *tmr_name[] = {
  2.     "off",
  3.     "on",
  4.     "keepalive",
  5.     "timewait",
  6.     "persist",
  7.     "unknown"
  8. };

点击(此处)折叠或打开

  1. if (show_options) {
  2.         if (r->idiag_timer) {
  3.             if (r->idiag_timer > 4)
  4.                 r->idiag_timer = 5;
  5.             printf(" timer:(%s,%s,%d)",
  6.              tmr_name[r->idiag_timer],
  7.              print_ms_timer(r->idiag_expires),
  8.              r->idiag_retrans);
  9.         }
  10.     }
对应的内核代码是

点击(此处)折叠或打开

  1. if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
  2.                 r->idiag_timer = 1;
  3.                 r->idiag_retrans = icsk->icsk_retransmits;
  4.                 r->idiag_expires = EXPIRES_IN_MS(icsk->icsk_timeout);
  5.         } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
  6.                 r->idiag_timer = 4;
  7.                 r->idiag_retrans = icsk->icsk_probes_out;
  8.                 r->idiag_expires = EXPIRES_IN_MS(icsk->icsk_timeout);
  9.         } else if (timer_pending(&sk->sk_timer)) {
  10.                 r->idiag_timer = 2;
  11.                 r->idiag_retrans = icsk->icsk_probes_out;
  12.                 r->idiag_expires = EXPIRES_IN_MS(sk->sk_timer.expires);
  13.         } else {
  14.                 r->idiag_timer = 0;
  15.                 r->idiag_expires = 0;
  16.         }

点击(此处)折叠或打开

  1. static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
  2.                                struct sk_buff *skb, int ext, u32 pid,
  3.                                u32 seq, u16 nlmsg_flags,
  4.                                const struct nlmsghdr *unlh)
  5. {
  6.         long tmo;
  7.         struct inet_diag_msg *r;
  8.         const unsigned char *previous_tail = skb_tail_pointer(skb);
  9.         struct nlmsghdr *nlh = NLMSG_PUT(skb, pid, seq,
  10.                                          unlh->nlmsg_type, sizeof(*r));

  11.         r = NLMSG_DATA(nlh);
  12.         BUG_ON(tw->tw_state != TCP_TIME_WAIT);

  13.         nlh->nlmsg_flags = nlmsg_flags;

  14.         tmo = tw->tw_ttd - jiffies;
  15.         if (tmo < 0)
  16.                 tmo = 0;

  17.         r->idiag_family = tw->tw_family;
  18.         r->idiag_retrans = 0;
  19.         r->id.idiag_if = tw->tw_bound_dev_if;
  20.         r->id.idiag_cookie[0] = (u32)(unsigned long)tw;
  21.         r->id.idiag_cookie[1] = (u32)(((unsigned long)tw >> 31) >> 1);
  22.         r->id.idiag_sport = tw->tw_sport;
  23.         r->id.idiag_dport = tw->tw_dport;
  24.         r->id.idiag_src[0] = tw->tw_rcv_saddr;
  25.         r->id.idiag_dst[0] = tw->tw_daddr;
  26.         r->idiag_state = tw->tw_substate;
  27.         r->idiag_timer = 3;
  28.         r->idiag_expires = DIV_ROUND_UP(tmo * 1000, HZ);
  29.         r->idiag_rqueue = 0;
  30.         r->idiag_wqueue = 0;
  31.         r->idiag_uid = 0;
  32.         r->idiag_inode = 0;
这样timer的输出含义就是(类型,过期时间,重试次数),这里说一下类型的含义:

off: 当前socket没有timer
on: 重传timer
keepalive:连接建立timer or fin_wait_2 timer or 保活timer;具体是那个timer,可以根据连接的状态来确定。
timewait: TIME_WAITtimer
persist:零窗口探测timer 








阅读(1873) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~