systemtap查看free_skb的场景

目前的dropwatch仅能查看丢包发生在哪个环节,不能看到丢包的内容,于是七拼八凑,拼了一个脚本,可以看到ip层的信息了,哈哈哈,tcp层的还是要做解析,不过如果不是tcp包的话,还要做一些判断逻辑,所以,先看到ip层信息就可以了。脚本如下:

#! /usr/bin/env stap
%{
#include <linux/version.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <net/ip.h>
#include <linux/skbuff.h>
%}


# Note when we turn the monitor on and off
probe begin { printf("Monitoring for dropped packets\n") }
probe end { printf("Stopping dropped packet monitor\n") }

probe kernel.statement("kfree_skb") {
        iphdr = __get_skb_iphdr($skb)
        family = %{ AF_INET %}
        saddr = format_ipaddr(__ip_skb_saddr(iphdr), %{ AF_INET %})
        daddr = format_ipaddr(__ip_skb_daddr(iphdr), %{ AF_INET %})
        protocol = __ip_skb_proto(iphdr)
  printf("%s->%s\n",saddr,daddr)
}

发现ping包最后都会走到kfree_skb的逻辑去。所以拿kfree_skb衡量丢包不太准确啊

后续:dropwatch跟这个脚本跟踪的都是kfree_skb函数被调用的时机,但是其实这个函数也是正常包被释放的时候会被调用的,所以,这个根本不是衡量丢包的,请注意

发表在 好玩的linux | 留下评论

糟糕网络场景下bbr对带宽影响

最近网络界最火的莫过于google开放出来的bbr算法,未能免俗,跟风测试一把

通过网络上最容易出现的两个场景,丢包跟延迟增大,测试不同场景下bbr跟普通内核的带宽性能对比,安装bbr内核可以参考:https://teddysun.com/489.html,这里不再详述

模拟网络丢包跟延时用如下两条命令:

tc qdisc add dev bond0 root netem loss 1%
tc qdisc add dev bond0 root netem delay 100ms

测试场景是两台万兆服务器,centos7系统,内核版本对比原始默认3.10版本跟4.9bbr版本,带宽单位均为Mbps

测试数据如下:

丢包数据:

丢包率(%) 普通内核 BBR内核
0.01 8470
0.05 5170
0.1 3750
0.2 2300
0.4 1000
1 381 9240
2 91 8920
4 15 7100
8 6 2370
16 251

延迟数据:

延迟(ms) 普通内核 BBR内核
1 8530 5500
10 5000 6440
100 568 612
200 243 109
400 88 27
1000 2 4

 

测试结果可见,bbr对丢包的改善非常显著,丢包在5%内,基本带宽都可以接受,但是默认的算法下,丢包增大,导致的带宽下降非常严重!

关于延迟,两者基本接近,看来跟延迟相关的还是窗口影响占决定因素啊

发表在 未分类 | 留下评论

RTT与tcp窗口对带宽的影响

前几天业务的同学吐槽我们机房到某云厂商的数据库实例传输速度太慢,但是我们机房到这个云厂商的云主机实例传输速度又很快。期间抓包多次,跟正常的包对比,最终发现,这个问题,是RTT跟TCP窗口共同影响决定的,受限与物理环境的约束,我们机房到这个数据库实例的RTT会达到30ms,这意味着在1s内,两边的数据交互只能到33次,如果按照每一个包确认过后才可以发下一个包的方式的话,1s只能发33个包,每个包1500B大小的话,这个带宽只能到50KB/s=400Kbits/s,这个带宽,相信都不能忍吧,咱毕竟不是00年有ADSL就吼开心的时代了。

如果提升这个速度呢?tcp的窗口就需要用到了,窗口的意思就是发送端一次可以发送多个包,但是具体能发送多少呢?这要接受端通知发送端窗口大小来协商,如果窗口等于一个包大小,那么情况就是1s只能发33个包,如果窗口是10000个包大小,那么1s就能发送330000个包,算下,这个带宽已经可以到83Mbits,是不是提升很大呢?

综上所述,高延时的场景下,发送端跟接受端的窗口大小,是对传输速度有致命影响的,在高延时的场景下,如果想获得高的带宽,一定要调整发送端跟接受端的窗口大小,这样才能充分的利用带宽。

如果有想测试高延时的场景的同学,可以用如下的命令设置主机的延时:

tc  qdisc  add  dev  eth0  root  netem  delay  30ms

效果很明显,ping下即可看到效果,测试带宽用iperf就足够了。

 

发表在 好玩的linux | 留下评论

etcd聊天工具

写了个好low的脚本,etcd又被我玩low了,这个脚本是用来做聊天室的,可以设置nickname,依赖etcdctl工具

#!/bin/bash

url="http://127.0.0.1:2379"
room="xxoo"
nickname=$(echo $RANDOM)

while getopts "u:r:n:" arg
do
  case $arg in
    u)
      url="http://$OPTARG:2379"
      ;;
    r)
      room=$OPTARG
      ;;
    n)
      nickname=$OPTARG
      ;;
    ?)
      echo "unkonw argument"
      exit 1
      ;;
  esac
done
export ETCDCTL_PEERS=$url

etcdctl watch talk/$room/room --forever &

while read line
do
  if echo $line |grep -q "^nickname "
  then
    nickname=$(echo $line|awk '{print $2}')
  else
    echo -n "$(tput cuu1)$(tput dl1)"
    etcdctl set talk/$room/room "$nickname: $line" >/dev/null
  fi
done

kill %1

基于watch实现的,可传参数有url,聊天室名字,nickname

服务端客户端均不保留聊天记录,命令行下使用

 

 

发表在 好玩的linux, 药不能停 | 留下评论

while read 循环只一行

惭愧了,之前居然不不知道这个细节,某次在while read接受管道输入,然后循环远程执行ssh命令的时候,只能执行到第一个,但是echo的话是没问题的,查找根源是,重定向的输出是整个循环体,不止是read,也有里面的其他命令,所以,所有会处理标准输入的命令都会被干扰。

形如:

seq 1 5|while read i;
do 
echo $i;
echo hehe;
done

中间有cat的情况:

seq 1 5|while read i;
do 
echo $i;
cat ;
echo hehe;
done

看出问题来了么?

发表在 好玩的linux | 留下评论