0%

源码对比

左侧为原BBR   右侧为魔改BBR  (能看懂的可以瞅瞅)

源码地址: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/plain/net/ipv4/tcp_bbr.c https://gist.github.com/anonymous/ba338038e799eafbba173215153a7f3a/raw/55ff1e45c97b46f12261e07ca07633a9922ad55d/tcp_tsunami.c

大佬特别提醒:编译时系统必须安装4.10以上版本的kernel及对应的linux-header,gcc版本应在4.9以上

鉴于之前的那篇文章内核是 4.9的,所以再水一篇文章吧!!

特别提醒:OpenVZ虚拟不能直接升级。升级内核可能会造成服务器无法启动。请酌情使用。

 

CentOS 6 X64

CentOS系统本文演示使用 4.11.8 内核。如果下面代码中的内核地址失效,请自行搜索最新的内核地址即可。

内核地址:http://elrepo.org/linux/kernel

升级系统内核

1)依次执行以下代码。

1
2
3
4
5
rpm —import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
yum install –y http://elrepo.org/linux/kernel/el6/x86_64/RPMS/kernel-ml-4.11.8-1.el6.elrepo.x86_64.rpm
yum remove –y kernel–headers
yum install –y http://elrepo.org/linux/kernel/el6/x86_64/RPMS/kernel-ml-headers-4.11.8-1.el6.elrepo.x86_64.rpm
yum install –y http://elrepo.org/linux/kernel/el6/x86_64/RPMS/kernel-ml-devel-4.11.8-1.el6.elrepo.x86_64.rpm

设置启动引导

2)修改启动引导,修改配置文件即可。

执行命令:

1
vi /etc/grub.conf

红框可看见我们新安装的内核。修改 default=0  即可。然后保存。重启服务器。

编译安装

依次执行以下脚本

1
2
3
4
5
6
7
8
9
10
yum install –y make gcc
wget –O ./tcp_tsunami.chttps://gist.github.com/anonymous/ba338038e799eafbba173215153a7f3a/raw/55ff1e45c97b46f12261e07ca07633a9922ad55d/tcp_tsunami.c
echo “obj-m:=tcp_tsunami.o” > Makefile
make –C /lib/modules/$(uname –r)/build M=`pwd` modules CC=/usr/bin/gcc
chmod +x ./tcp_tsunami.ko
cp –rf ./tcp_tsunami.ko /lib/modules/$(uname –r)/kernel/net/ipv4
insmod tcp_tsunami.ko
depmod –a
echo “net.core.default_qdisc=fq” >> /etc/sysctl.conf
echo “net.ipv4.tcp_congestion_control=tsunami” >> /etc/sysctl.conf

执行完之后 重启一下服务器。

1
reboot

重启成功后,执行以下命令。如果有显示内容说明启动成功。

1
lsmod  grep tsunami

>> tcp_tsunami 6053 5

CentOS 7 X64

由于手头暂时没有CentOS7 系统的服务器。以下代码并没有测试。

升级系统内核,请执行以下代码。其他的请参考 CentOS 6 X64!!

1
2
3
4
5
rpm —import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
yum install –y http://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-ml-4.11.8-1.el7.elrepo.x86_64.rpm
yum remove –y kernel–headers
yum install –y http://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-ml-headers-4.11.8-1.el7.elrepo.x86_64.rpm
yum install –y http://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-ml-devel-4.11.8-1.el7.elrepo.x86_64.rpm

Debian 8/Ubuntu 14

升级系统内核

 

分别安装 headers   和 images 即可。

内核地址:http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.10.9/

你可以选择更高版本的内核试一试,注意自己替换命令中的 v4.10.9

1
2
3
wget http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.10.9/linux-headers-4.10.9-041009_4.10.9-041009.201704080516_all.deb
dpkg –i linux–headers–4.10.9*.deb

设置启动引导

1)查看系统内核列表,执行以下命令

1
dpkg –lgrep linux–image

执行命令后,可见多个内核如下:

1
2
3
ii linux–image–3.16.0–4–amd64 3.16.7–ckt9–3~deb8u1 amd64 Linux 3.16 for 64–bit PCs
ii linux–image–4.10.9–041009–generic 4.10.9–041009.201704080516 amd64 Linux kernel image forversion 4.10.9 on 64 bit x86 SMP
ii linux–image–amd64 3.16+63 amd64 Linux for 64–bit PCs (meta–package)

上面显示的我们需要将 linux-image-3.16.0  这个删除掉。

PS : 如果你显示的是其他的内核版本,那么就删掉它。只保留 4.10.9。

2)删除内核。

1
apt–get remove linux–image–3.16.0–4–amd64

注意:Debian8 系统会弹出一个提示,直接【Tab】选择 【NO】然后回车。

3)重新生成启动引导。

1
update–grub

4)重启系统。

1
reboot

安装gcc

根据大佬的要求 gcc版本必须 >= 4.9 ,否则无法编译。

我在 Ubuntu 14上安装gcc的时候竟然是 4.8版本,可能是由于 Ubuntu 14版本的问题。

1)查看 gcc 版本 。如果 版本 >= 4.9 可跳过这个步骤了。

1
gcc –v

2) 执行以下命令来安装 gcc-4.9

1
2
3
4
apt–get install build–essential
add–apt–repository ppa:ubuntu–toolchain–r/test
apt–get update
apt–get install gcc–4.9

编译安装

1)请依次执行以下脚本。执行完重启服务器。

1
2
3
4
5
6
7
8
9
apt–get install make gcc–4.9
wget –O ./tcp_tsunami.chttps://gist.github.com/anonymous/ba338038e799eafbba173215153a7f3a/raw/55ff1e45c97b46f12261e07ca07633a9922ad55d/tcp_tsunami.c
echo “obj-m:=tcp_tsunami.o” > Makefile
make –C /lib/modules/$(uname –r)/build M=`pwd` modules CC=/usr/bin/gcc–4.9
install tcp_tsunami.ko /lib/modules/$(uname –r)/kernel
cp –rf ./tcp_tsunami.ko /lib/modules/$(uname –r)/kernel/net/ipv4
depmod –a
echo “net.core.default_qdisc=fq” >> /etc/sysctl.conf
echo “net.ipv4.tcp_congestion_control=tsunami” >> /etc/sysctl.conf

2)重启成功后,执行以下命令。如果有显示内容 说明启动成功。

1
lsmod  grep tsunami

>> tcp_tsunami 6053 5

一键安装脚本

对于小白用户,以上手动安装可能有点复杂。那么就推荐你使用大佬的一键脚本吧。

提醒一下几位大佬的一键暂不支持 CentOS系统。大佬们的一键脚本可能在 Ubuntu14 下执行可能出问题。

如果一键出错,那么只能上面的内容手动安装了。

谢谢@Leonn 的博客 收集以下内容。

落雨无声版本

原文地址:https://ylws.me/tech/68.html

注意只支持 Debian8 / Ubuntu16 +

1
wget –N —no–check–certificate https://raw.githubusercontent.com/FunctionClub/YankeeBBR/master/bbr.sh && bash bbr.sh install

Vicer版本

原文地址:https://moeclub.org/2017/06/24/278/

注意只支持 Debian8 / Ubuntu16 +

1
wget —no–check–certificate –qO ‘BBR_POWERED.sh’‘https://moeclub.org/attachment/LinuxShell/BBR_POWERED.sh’ && chmod a+x BBR_POWERED.sh &&bash BBR_POWERED.sh

91Yun版本

原文地址:https://www.91yun.org/archives/16781

注意只支持 Debian8 / Ubuntu16 +

1
2
3
wget https://raw.githubusercontent.com/singhigh/502newbbr/master/502newbbr.sh
chmod +x 502newbbr.sh
./502newbbr.sh

Crontab是一个Unix/Linux系统下的常用的定时执行工具,可以在无需人工干预的情况下运行指定作业。很多时候我们都要用到Crontab命令,例如在Let’s Encrypt Wildcard 免费泛域名SSL证书中提到了acme.sh 脚本就是利用了Crontab定时任务的形式来更新SSL证书。

通过crontab命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script脚本,在Linux VPS挂载Google Drive和Dropbox中就可以用Crontab命令实现定时同步备份,用Crontab实现每天定时重启VPS、服务器或者是Nginx、PHP、MysqL服务等。

总之,掌握基本的Crontab命令语法对于我们管理自己的VPS主机是非常有必要的,本篇文章通过实例来讲解如何使用Linux Crontab命令,不作深入的探究,主要是方便日后的快速查询与参考。

Linux Crontab命令定时任务基本语法与操作教程-VPS/服务器自动化操作

更多的关于VPS主机有关的命令使用方法与应用,可以看看:

  1. Linux系统监控命令整理汇总-掌握CPU,内存,磁盘IO等找出性能瓶颈
  2. 三个命令工具Rsync,SCP,Tar-快速解决VPS远程网站搬家与数据同步
  3. Linux共享文件夹目录三种方法-NFS远程挂载,GlusterFS共享存储和samba共享目录

一、Crontab查看编辑重启

1、查看crontab定时执行任务列表

1
crontab -l

2、编辑crontab定时执行任务

1
crontab -e

3、删除crontab定时任务

crontab -r

4、相关命令:

1
2
3
4
5
sudo service crond start     #启动服务
sudo service crond stop #关闭服务
sudo service crond restart #重启服务
sudo service crond reload #重新载入配置
sudo service crond status #查看服务状态

二、Crontab基本格式语法

crontab 的时间表达式:

1
2
3
基本格式 :
*  *  *  *  *  command
分 时 日 月 周 命令

先来看一个例子。每天凌晨1:00执行备份程序:0 1 * * * /root/wzfou.com/backup.sh 。其中/root/wzfou.com/backup.sh 这是脚本路径,要使用绝对路径,前面的日期格式请直接看下图就知道了。

Linux Crontab命令日期格式

crontab还有操作符,用来实现一些复杂的时间设定需要。操作符有:

1、* 取值范围内的所有数字 ,代表所有。

2、/ 每过多少个数字 ,代表每隔n长时间。

3、- 从X到Z ,代表一段时间范围。

4、,散列数字,代表分割开多个值。

PS:2018年4月15日更新,感谢好友云落提醒,如果还有搞不懂代码公式的,可以使用这个在线Cron表达式生成器:http://cron.qqe2.com/

三、20个经典Crontab应用实例

以脚本/root/wzfou.com/backup.sh 为演示,大家在使用时记得替换为自己的脚本路径。感谢bukai.men提醒,请在相应的脚本第一行加上#!/bin/bash,否则脚本在定时任务中无法执行。

Linux Crontab命令应用实例

实例1:每1分钟执行一次

* * * * * /root/wzfou.com/backup.sh

实例2:每小时的第3和第15分钟执行一次

3,15 * * * * /root/wzfou.com/backup.sh

实例3:每天的8点到11点的第3和第15分钟执行一次

3,15 8-11 * * * /root/wzfou.com/backup.sh

实例4:每隔两天的上午8点到11点的第3和第15分钟执行一次

3,15 8-11 */2 * * /root/wzfou.com/backup.sh

实例5:每周一上午8点到11点的第3和第15分钟执行一次

3,15 8-11 * * 1 /root/wzfou.com/backup.sh

实例6:每晚的21:30执行一次

30 21 * * * /root/wzfou.com/backup.sh

实例7:每月1、10、22日的4 : 45执行一次

45 4 1,10,22 * * /root/wzfou.com/backup.sh

实例8:每周六、周日的1 : 10执行一次

10 1 * * 6,0 /root/wzfou.com/backup.sh

实例9:每天18 : 00至23 : 00之间每隔30分钟执行一次

0,30 18-23 * * * /root/wzfou.com/backup.sh

实例10:每星期六的晚上23: 00 pm执行一次

0 23 * * 6 /root/wzfou.com/backup.sh

实例11:每一小时执行一次

* */1 * * * /root/wzfou.com/backup.sh

实例12:每天晚上23点到第二天7点之间,每隔一小时执行一次

* 23-7/1 * * * /root/wzfou.com/backup.sh

实例13: 每个星期的第一天执行一次(即每个星期天晚上24:00开始执行).

@weekly /root/wzfou.com/backup.sh

实例14:每个月的15日执行一次.

0 11 15 * * /root/wzfou.com/backup.sh

实例15:每个月的第一天执行一次(即每个月的1日凌晨0点开始执行).

@monthly /root/wzfou.com/backup.sh

实例16: 在指定的月份执行一次(在1月,4月和 6月每天晚上0点执行一次).

0 0 * jan,apr,jun * /root/wzfou.com/backup.sh

实例17: 重启后执行一次.

@reboot /root/wzfou.com/backup.sh

实例18:定时任务执行后发一封邮件通知.

MAILTO=”raj”
1 1 * * * /root/wzfou.com/backup.sh

实例19:指定shell (默认的是/bin/bash)

SHELL=/bin/sh
1 1 * * * /root/wzfou.com/backup.sh

实例20:指定环境变量.

PATH=/sbin:/bin:/usr/sbin:/usr/bin
1 1 * * * /root/wzfou.com/backup.sh

四、Crontab可能存在的问题

4.1  Crontab不立即生效

大家新建的Crontab定时任务保存后需要等待2分钟后才会执行,当然如果想要立即执行可以重启Crontab。当crontab失效时,可以尝试/etc/init.d/crond restart解决问题,或者查看日志看某个任务有没有执行/报错tail -f /var/log/cron。

4.2  Crontab不执行

脚本中涉及文件路径时写全局路径,更新系统时间时区后需要重启cron。当手动执行脚本OK,但是crontab死活不执行时很有可能是环境变量,可尝试在crontab中直接引入环境变量解决问题,例如:

0 * * * * . /etc/profile;/bin/sh /root/wzfou.com/backup.sh

4.3  Crontab无权限执行

要注意系统级任务调度与用户级任务调度。只有 root 用户和 crontab 文件的所有者可以在 -e 、-l-r 和 -v标志后面使用 UserName 以编辑、列出、除去或验证指定用户的 crontab 文件。

root用户的任务调度操作可以通过”crontab –uroot –e”来设置,也可以将调度任务直接写入/etc/crontab文件。

想编辑别的用户的 crontab, 使用root运行下面的命令,同一个格式 (追加 “-u _username_” 到命令后) 也可以用来列出或删除 crontabs。

crontab -u username -e

4.4  Crontab执行后通知

Crontab定时任务在你所指定的时间执行后,系统会寄一封信给你,显示该程序执行的内容,可以在日志中**/var/log/cron**看到。若是你不希望收到这样的通知,请在每一行空一格之后加上 > /dev/null 2>&1 即可。

    • 背景:

原版的BBR对于我们来说,速度不太稳定. 通过修改BBR源码,调整参数,使其更强劲.


  • 更新:

  • [2017.07.25]

  • 修复一个由检测gcc版本引起的不可预料的错误.

  • [2017.07.15]

  • 自动检测gcc版本,如果gcc版本大于4.9的将不会再安装gcc.

  • [2017.07.12]

  • 支持用户自行指定内核版本(需要与 -f 命令同时使用).


    • 准备:

使用前,请确认能够开启BBR. 可参考: Debian/Ubuntu 开启 TCP BBR 拥塞算法 或者直接执行此命令进行开启.

1
wget --no-check-certificate -qO 'BBR.sh' 'https://moeclub.org/attachment/LinuxShell/BBR.sh' && chmod a+x BBR.sh && bash BBR.sh -f

注意:执行此命令会自动重启.


    • 一键地址:
1
wget --no-check-certificate -qO 'BBR_POWERED.sh' 'https://moeclub.org/attachment/LinuxShell/BBR_POWERED.sh' && chmod a+x BBR_POWERED.sh && bash BBR_POWERED.sh
    • 指定内核版本(以v4.11.9内核版本为例):
1
wget --no-check-certificate -qO 'BBR_POWERED.sh' 'https://moeclub.org/attachment/LinuxShell/BBR_POWERED.sh' && chmod a+x BBR_POWERED.sh && bash BBR_POWERED.sh -f v4.11.9

    • 说明:
      • 执行过程中会重新编译模块.
      • 模块默认为开机自动加载.
      • 模块名称:tcp_bbr_powered
      • 可用 modprobe tcp_bbr_powered 命令进行加载模块.
      • 可执行 lsmod grep 'bbr_powered' 结果不为空,则加载模块成功
      • 可执行 sysctl -w net.ipv4.tcp_congestion_control=bbr_powered 使用此模块.

以上只是说明,直接使用一键脚本即可.


    • 完整代码:
1
2
#!/bin/bash


    • 注意事项:

如遇报错:Error! Header not be matched by Linux Kernel. 请用使用本博客提供的脚本重新开启BBR,或使用-f参数.可参考本篇中的准备步骤. 如遇报错:Error! Install makeError! Install gcc. 首先尝试apt-get update,再次执行此脚本. 如果未解决想办法自行安装gcc(>=4.9),或切换系统后再试. 本脚本在Debian8,Debian9,Ubuntu16.04上通过测试.


    • 引用评论中提供的在Ubuntu安装gcc-4.9的方法:
1
2
3
4
sudo apt-get install -y software-properties-common
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get -y install g++-4.9

按:前些天本站分享了 BBR2 ,但是因为这玩意发包太猛,那怎么样调 BBR 的参数呢?之前  @EvanVane 大佬给我分享过一篇文章,本人实践中也很受用。如果你有一定的技术底气可以看看这篇文章,小白可以略过。另外也请不要伸手党,比如针对 C3 优化的 BBR 对 QN 就不一定适用(网络状况不同),今天调的参数下个月就不一定有用(因为其他人也会调,人家抢带宽后,我怎么样抢更多的带宽?那需要重新调参数。) 这个技术目前看来也不可能出一键包,要是想享受,还是好好自学下网络基础吧。

原题: 深夜聊聊 Bufferbloat 以及 TCP BBR  原作者: Bomb250

这篇文章的写作动机来源于知乎上的一个问题,有人问既然 Bufferbloat 是个问题,为什么路由器的缓存还要设计那么大。起初,我也是觉得缓存越大越好,这个就像人们拼命比拼谁的电脑内存大一样,因为在一般人眼里,内存越大就越快!然而对于网络而言,恰好相反,内存越大,越让人不想归家。 酒店舒适,但只是路过,没人会把家装修成酒店的样子,家才是越大越好。 路由器设计成携带大缓存的设备,这是一个错误!路由器不该有那么大的缓存,然而 TCP 大牛当年的一个“ AIMD 错误决定”让路由器的缓存越来越大,最终引发了 Bufferbloat !事情还要从安迪 – 比尔定律说起。

网络上的“安迪 – 比尔定律”

先解释一下安迪 – 比尔定律,即“比尔 . 盖茨拿走了安迪 . 格鲁夫所给的”。狭义的讲就是无论 Intel 的芯片快到多么牛逼的地步,微软的下一个 Windows 版本总是能把芯片的性能榨干,然而广义的讲,安迪 – 比尔定律连同摩尔定律一起事实上构成了信息产业的一台泵,典型的一个正反馈系统,这是决定互联网产业大爆发的本质原因,这个系统如下: 摩尔定律 -> 硬件性能提升 -> 软件填补硬件提升的空间

我们可以理解为,摩尔定律和安迪 – 比尔定律驱动了信息革命的车轮不断滚动从而碾压一切!

可以把路由器的越来越大的 Buffer 以及 TCP 贪婪地占据这些路由器 Buffer 两者看作是另一个“安迪 – 比尔定律”。因为 BBR 之前的 TCP 拥塞算法都是盲目且贪婪的,路由器加大的 Buffer 总是能被 TCP 的 AI( 加性增窗 ) 过程快速榨干,反过来大缓存延迟了 TCP 的丢包,同时增加了丢包的成本,这要求路由器提供更多的缓存。 具体来讲就是,如果路由器 Buffer 过小,基于丢包的拥塞算法固有的全局同步现象将会使得带宽的利用率极低,所以必须增加 Buffer 来弥补。这就是一个正反馈循环,肇事者可以说是基于丢包的 TCP 算法,它驱动了路由器 Buffer 越来越大,当 Buffer 越来越大, TCP 又会瞬间用完,永远喂不饱,直到永远。 好在有摩尔定律和 TCP 的 MD( 乘性减窗 ) 过程二者从中协调,如果同时失去了二者, TCP 早晚会全局崩溃! 我们假设硬件已经逼近了热密度的极限,摩尔定律失效了,此时不会再增加 Buffer 的大小了,会发生什么呢? 只要有 TCP 的 MD 过程在,互联网就不会崩溃,所以说, TCP 的 AI 过程保障了其效率,而 MD 过程则保证了收敛。 Google 的新拥塞控制框架来了以后, MD 过程便不被保证了,任何人都可以写一个永不降窗的算法,如果把主动的 MD 过程看作道德的话,那么路由器的 AQM 就是法律了。这就是 TCP/IP 的几乎全部内容了,我们可以看到,它极其复杂。 值得注意的是, TCP/IP 的安迪 – 比尔定律展现的这种复杂性,其促进因素不是摩尔定律,而是“人们对带宽的高利用率的追求”,因此便有了以下的关系: 提高带宽利用率 -> 路由器加大 Buffer->TCP 的 AIMD 填补加大的 Buffer 其实,这完全是错觉, TCP/IP 的框架不该这么复杂的。或许, AIMD 根本就不需要,事实上,是路由器不断加大的 Buffer 和 AIMD 一起纵容了坏事的频繁发生。这一点正如人们不断买新电脑,不断买新手机,然而过不了多久,你依然会发现不管再新的机器都卡的要死一样的道理,只不过,人们买的电脑也好,手机也好,它们的更新换代是摩尔定律驱动的,机器完全是个人所有的,你随时可以跟着摩尔定律的节奏更新换代,然而对于网络设备却不是这样。 网络设备,比如路由器,交换机之类,它们只是整个 TCP/IP 系统的一个环节而已,机房里面的设备是不可能频繁更新换代的,摩尔定律几乎被它们所无视。虽然摩尔定律依旧影响着设备的实际制造和升级,但由于这种周期相对较长,也就是可以忽略的了。但这里面有一个不变的定论,那就是 TCP 几乎全部都是以 AIMD 原则来运作的, UDP 则是无限贪婪的。 TCP 的 AI 会造成主动丢包,这也是基于丢包的拥塞控制算法的核心,而 MD 会造成全局同步,这两点无疑造成了带宽利用率的低下,这是 TCP 的硬伤,不得不靠不断加大的路由器 Buffer 来弥补,至少是延迟了悲剧的发生,在延迟悲剧的这段时间内,路由器当然希望端系统可以意识到事情正在悄悄起变化并采取一些措施。 …… AIMD ,正如以太网的 CSMA/CD 一样,并不完美,但是可用。现在的人们在千兆以太网出现之前,曾经推导出一个结论,那就是依靠 CSMA/CD 是不可能达到千兆 bps 的,然而如今已经是万兆甚至 4 万兆了 … 如果说以太网的载波监听,冲突检测是不必要且可被替换的,那么 TCP 的 AIMD 也是不必要且可被替换的,二者简直太像了!

Bufferbloat 问题

我不想说 TCP 的 AI/MD( 加性增和乘性减 ) 是错误的,我也不敢给出如此决绝的否定,然而,至少我想表达的是,在“安迪 – 比尔定律”的作用下, AI/MD 是有问题的!什么问题呢? Bufferbloat 问题! 再次重申,路由器携带很大的 Buffer ,是错误的!路由器 Buffer 在够用前提下越小越好,没有 Buffer ,自然就不会 bloat ,本来无一物,何处惹尘埃?!但是不能没有 Buffer…Buffer 到底是用来干什么的?到底多少合适? Buffer 其实就比较类似我们吃的食物,曾经,在物资贫乏的年代,大家都在追求要多吃,现在营养过剩了,则反过来了,要少吃,实际上,人体根本不需要太多的食物,够用即可,人体大部分的精力要用来做更有意义的事情。同样基于存储 / 转发 TCP/IP 网络上的路由器其根本任务不是做存储,而是做转发,存储只是在理论上不得已的一个手段。我来解释下是为什么。 路由器的入口和出口分别接收到达的数据包和转发数据包,一台路由器上往往有多个接口同时全双工地进行接收 / 转发,数据包的到达频率是统计意义上的,符合泊松分布,然而数据包的发送则是固有的接口速率,这是分组交换网的核心根基!路由器扮演什么角色?它是一个典型的多服务台排队系统!所以路由器必须携带一个 Buffer 用来平滑泊松分布的包到达和固定速率的包发送之间的关系。 那么,设计多大的 Buffer 合适呢?按照排队理论的现成公式计算,够用即可! 我们考虑极端一点的情况,如果我们把存储队列的 Buffer 设计成无穷大,从而转发延迟也将是无穷大 ( 因为排队延迟会趋向无穷大 ) ,会发生什么?无疑,这台路由器将会变成一个超级存储器,它将会拥有全世界所有的信息! 爆炸!转发设备变成了存储设备!这就是 Bufferbloat 。注意, Bufferbloat 的恶劣影响并不是会造成丢包,而是会无端增加无辜连接的延迟。这里有个认识上的误区,这种认识在中国人的思维中特别明显。很多人会觉得 Bufferbloat 会造成“丢包反馈延迟增加”,其实丢不丢包是你自己的事,如果你通过 RTT 梯度检测到了 Bufferbloat ,你依旧继续猛发,结果被 AQM 给丢了,那完全是你自己全责,事实上,这个时候大家都应该全局 MD 才对。

真正的危害在于,由于 Bufferbloat 造成了整个大 Buffer 被填充,所有的数据包都将等待一个固有的排队延迟,这会严重影响任意经过的实时类应用!千万别扯什么 QoS ,区分服务,综合服务,流量工程什么的,这些要真有用, 120 救护车就不会被堵在路上了,请注意,事在人为,事在人不为。

我最喜欢的其实不是 TCP/IP 网络什么的,而是城市规划,道路规划以及机械设计 (2002 年我的专业就是机械工程 ) ,我只是在 2004 年的时候初识了路由器,交换机之类的东西,发现自己竟然可以不用挖地铲土浇筑建桥就可以完成一条自己想象中的道路,并且还有那么多的现实场景,这不禁可以让人随时进入禅境 … 实际上,关于城市规划,道路规划以及机械设计也有很多电脑上的模拟器,但问题是它们毕竟只是模拟,是不真实的,而路由器,交换机是真实的,它们就摆在那,登录设备打开 Monitor ,我看到的是真实的东西,这与模拟器有大不同。

在后来的学习中,我发现路由器交换机之上有个 TCP/IP ,折腾起来一点也不比挖地铲土浇筑建桥来的轻松,但至少除了搬机器,上架,插线之外,没有什么体力活了,也还好。

路由器 Buffer 是什么?以高架路为例,它相当于上匝道前面的位置:

图中的汇入区就相当于路由器的 Buffer ,可以看出,如果汇入区过大的话,单位时间内就会有更多的车辆汇入主线,当这个量超过主线流量的时候,就会造成汇入区拥堵,同时大大降低主线的通行能力。这意味着,很多无辜的车辆被堵在了汇入区,主线上的车辆也会由于汇入去有大量车辆汇入而显示拥堵迹象,我给出给具体的例子吧,那就是上海南北高架广中路由南向北上匝道,那个汇入区太长了,足足 200 米 + ,结果造成那个位置几乎持续拥堵,不光广中路上匝道新上南北高架的车辆走不动,就连主路上的车辆也被拥堵,这是什么造成的?这是错觉造成的!广中路上匝道下面准备上高架的司机一看匝道是空的,唰唰全上去了,结果堵在汇入区了 … 如果广中路上匝道的汇入区修的短一些,那么拥堵只会体现在上匝道或者广中路路口,这种拥堵反馈到准备上高架的司机那里,结果就是,要么等,要么绕,至少会阻止他们上主线汇入区去添堵,伤害无辜的流量。 好了,该回到 TCP 了。路由器 Buffer 减小有什么好处呢?好处在于,即使有连接拼命去 AI 添堵,那么丢包会很快到来,并且很快反馈给发送方,于是发送方会执行 MD 以表示忏悔,整个过程中,实时流量不会受到丝毫影响。

劣币驱良币

BBR 是什么我就不解释了,我写了很多文章。这些文章中没有提到的是, BBR 属于那种即便上匝道汇入区修的再长也不上去添堵的德国好司机。那么结果是什么?你以为这种行为会感动全中国吗? 错了,这正是中国人所期许的,你谦让,我就流氓。你不去堵,我去堵。结果就是, BBR 即便不去主动添堵,也会被其它人堵在路上, BBR 只能说,这拥堵不是自己造成的,仅此而已。吃亏做好事又不被认可反被讹,这是我们这里常有的事, BBR 到了中国应该入乡随俗,你堵,我也堵!

BBR 开始为网络添堵

永远不要欺负老实人, BBR 开始做损人不利己的事了。在中国,所有的 TCP 拥塞控制算法都无法被公正评估,请注意,这个修改的意义在于, BBR 对于自身的性能没有任何提升,只是为了损人而已。我跑得慢,我踹你一脚把你整瘸了,你会更慢,这样我就第一了,竞速,竞速而已! 那么,这件坏事如何来做呢? 我的第一个版本不公开,事实证明它更有效,起码上了我的版本,别的就没的跑了,但问题是上两个我的版本,他俩双胞胎也会打架打得头破血流 … 本着和谐共存的原则,我从不教人学坏,所以我会删除并忘掉代码,再不提起。我这里给出稍微温和点的版本,兄弟俩打架的情况依然存在,但不严重,问题是,如何区别对方是否是自家人 … 难! BBR 计算总的最大发送量的时候,不是按照 max-Bandwidth 和 min-RTT 的乘积计算的吗?我这里维护了一个最小 RTT 窗口内的 max-RTT ,只要在一个最小 RTT 窗口内的实际 RTT 不大于上一次的 max-RTT ,我就让 BBR 使用这个实际的 RTT 而不是什么最小的 RTT 。这里的原则在于, BBR 会尝试在排队不丢包的情况下也去主动排队,入乡随俗。 代码非常简单,先为 BBR 增加一个字段,即 max_rtt_us ,与 min_rtt_us 相对,然后修改 update RTT 和 calc CWND 的逻辑:

1. 修改 bbr_update_min_rtt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* Track min RTT seen in the min_rtt_win_sec filter window: */  
filter_expired = after(tcp_time_stamp,  
                            bbr->min_rtt_stamp + bbr_min_rtt_win_sec * HZ);  
if (rs->rtt_us >= 0 &&  
    (rs->rtt_us <= bbr->min_rtt_us filter_expired)) {  
        bbr->min_rtt_us = rs->rtt_us;  
        bbr->min_rtt_stamp = tcp_time_stamp;  
        bbr->rtt_us = rs->rtt_us;  
        if (filter_expired)  
            bbr->max_rtt_us = rs->rtt_us;  
}  
bbr->rtt_us = bbr->min_rtt_us;  
  
if (!filter_expired && rs->rtt_us >= 0 && rs->rtt_us < bbr->max_rtt_us) {  
    bbr->rtt_us = rs->rtt_us;  
}

2. 修改 bbr_target_cwnd

1
2
3
4
if (inet_csk(sk)->icsk_ca_state != TCP_CA_Open)  
    w = (u64)bw * bbr->min_rtt_us;  
else  
    w = (u64)bw * bbr->rtt_us;

最大 RTT 和最小 RTT 之差就是排队延迟,充分利用这个排队延迟去添堵是一件简单的好事,但是如何去对抗 AQM 则是一件非常复杂的事,因为你并不知道 AQM 的行为。以上的讨论均建立在尾部丢包的基础之上,然而现实情况则要面临复杂的 AQM ,在文章《 Linux Kernel 4.9 中 TCP BBR 算法的科普解释 》的“君莫舞,君不见玉环飞燕皆尘土”以及“ BBR 的优势之 – 与 AQM 的关系”两节中,我有阐述 BBR 如何乐观地等待 CUBIC 之流被惩罚以及如何愉快地上位,然而在“广中路上匝道”情形中, CUBIC 并不会被惩罚, BBR 自然也就不会上位,那怎么办,只能添堵,至于 AQM 怎么处理,一视同仁吧。换句话说, BBR 在 CUBIC 以及任意所谓“ TCP 加速者”面前,不必客气,他们抽烟,你就放火。

快递或者网络可靠吗

现在人们没了互联网就不能生活,这也是一种错觉。 其实互联网本身就是一种错觉,它是一种不得已而为之的错觉! 去年 1 月我去深圳万象城 ( 之所以说万象城而不是人人乐,我是想说我买的东西有多么高大上,以至于我多么迫不及待地想拥有 ) 买东西,无货,咋办?店主说次日可取,他们从广州拿货。现在问题来了,去一趟广州难吗?为什么我自己不直接去广州买,还要深圳万象城去广州拿货后再卖给我?因为我没时间!如果我有大把的时间又那么喜欢那件物品,我肯定自己去广州了,顺带旅游,然而我缺的正是时间。 快递业务填补了人们的时间间隙。但是快递业务真的可靠吗? 如果我自己去广州拿货,假设高铁不脱轨,汽车不翻车,自己不被人捅的情况下,一路上我愉快地去,拿到货后愉快地归来,一路上我亲自护送货品,我放心,我踏实。如果交由快递,我不知道快递车会不会翻车,会不会被人抢,里面会不会是假货 … 一切我都不确定,在送到我手里前,我只能祷告 ~ !但好处在于,这段送货的时间,在我信任快递公司的前提下,我可以做别的工作,如果我不信任快递公司,我只能心急如焚。好在,现在的快递公司,特别是顺丰还算靠谱,你不需要心急如焚。

但是网络,其可靠性完全是另一回事,幸亏人们用了 TCP ,不然就别玩了。字节的复制往往比丝帛的织造更加廉价,所以 TCP 有一个存储重发的机制,发送信息前先存储信息,一段时间没有收到回应,就重发被存储的信息,收到回应则将信息删除,如果发了一批丝绸到远方,一段时间没有反馈,然后再去织一批新的,那代价可就大了去了 …

我不亲自去广州而去委托快递公司,正是因为我没有时间,那么如果快递公司的快递过程“弥补”了我本应该节省的时间 ( 比如快递员懒惰 ) ,我还不如自己去拿货呢。 网络也一样,如果网络的延迟太高,那还不如用 U 盘拷贝信息,用汽车运输 U 盘,然后交付呢 … 网络和快递一样,就是图快,用专业的运输代替你自己的自取。然而,如果网络中有 Bufferbloat ,那么还不如去自取,甚至去用 U 盘拷贝。 Bufferbloat 让网络丧失了快速传输通道的名声。

新的 Bloat 版本的 BBR 算法

周日早晨,我登录到了温州老板提供的位于国外的 VPS 机器上,演绎了一个新版的 BBR 。也是添堵版的,在我的 WIFI 环境下碾压了标准的 BBR ,这就好像魔人布欧的分身一样,一个是好人的时候,另一个必须是恶棍。 非常简单:

1. 为 bbr 增加一个 minmax 类型的 max_rtt 字段

2. 修改 bbr_update_min_rtt 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
filter_expired = after(tcp_time_stamp,  
                            bbr->min_rtt_stamp + bbr_min_rtt_win_sec * HZ);  
if (rs->rtt_us >= 0 &&  
        (rs->rtt_us <= bbr->min_rtt_us filter_expired)) {  
    bbr->min_rtt_us = rs->rtt_us;  
    bbr->min_rtt_stamp = tcp_time_stamp;  
    bbr->rtt_us = rs->rtt_us;  
}  
bbr->rtt_us = rs->rtt_us;  
rtt_prior = minmax_get(&bbr->max_rtt);  
// 迄今为止最大的RTT与当前RTT取其小!是不是拿最大RTT和最小RTT求个"平均"什么的更合理呢?  
// 反正我是占点Buffer空间  
bbr->rtt_us = min(bbr->rtt_us, rtt_prior);  
  
minmax_running_max(&bbr->max_rtt, bbr_bw_rtts, bbr->rtt_cnt, rs->rtt_us);

我祝愿所有的 TCP 连接早日崩溃,我祝愿互联网越来越拥堵,最终不可用。

为什么 BBR 是合理的

AIMD 是基于丢包的拥塞控制算法的根基,这必然会 Buffer bloat ,解决之道就是不采用基于丢包的算法,而采用基于时延的算法,但是 …. 但是只要有一个基于丢包的算法还跑在互联网上,那么所有基于时延的算法都会集体退让 … 这是基于时延算法弊端,既然它基于时延而不是丢包,那么它就是注定要吃亏的。正确的做法是什么? BBR 无视丢包 ( 也并非绝对, BBR 在处理非 Open 状态时还是有措施的 ) ,无视时延 ( 也非绝对, BBR 只是无视了 RTT 的瞬时变化值 ) ,采用了实时采集并保留时间窗口的策略,这初看起来是吃亏的算法,与基于时延的算法无异,但是 BBR 拥有 Probe More 和 Drain Less 过程,这非常合理。

合理的并不意味着是可用的。我依然祝愿所有的 TCP 连接早日崩溃,我祝愿互联网越来越拥堵,最终变得不可用。我有一个梦想,每个人抡起铁锤去炼钢,少说多做,最好不说。

亲测,在安装锐速后,再进行一次 tcp 优化,还能增加下载效果。

增加 tcp 连接数量

编辑 limits.conf

1
vi /etc/security/limits.conf

增加以下两行

1
2
* soft nofile 51200
* hard nofile 51200

开启酸酸乳 服务之前,先设置一下 ulimit

1
ulimit -n 51200

调整内核参数

首先科普下 TCP 拥塞控制算法: 中美之间的线路质量不是很好, rtt 较长且时常丢包。 TCP 的设计目的是解决不可靠线路上可靠传输的问题,即为了解决丢包,但丢包却使 TCP 传输速度大幅下降。 HTTP 协议在传输层使用的是 TCP 协议,所以网页下载的速度就取决于 TCP 单线程下载的速度(因为网页就是单线程下载的)。丢包使得 TCP 传输速度大幅下降的主要原因是丢包重传机制,控制这一机制的就是 TCP 拥塞控制算法。

Linux 内核中提供了若干套 TCP 拥塞控制算法,这些算法各自适用于不同的环境。 1 ) reno 是最基本的拥塞控制算法,也是 TCP 协议的实验原型。 2 ) bic 适用于 rtt 较高但丢包极为罕见的情况,比如北美和欧洲之间的线路,这是 2.6.8 到 2.6.18 之间的 Linux 内核的默认算法。 3 ) cubic 是修改版的 bic ,适用环境比 bic 广泛一点,它是 2.6.19 之后的 linux 内核的默认算法。 4 ) hybla 适用于高延时、高丢包率的网络,比如卫星链路——同样适用于中美之间的链路。

我们需要做的工作就是将 TCP 拥塞控制算法改为 hybla 算法,并且优化 TCP 参数。

1 、查看可用的算法。 主要看内核是否支持 hybla ,如果没有,只能用 cubic 了。

1
sysctl net.ipv4.tcp_available_congestion_control

2 、如果没有该算法,则加载 hybla 算法(不支持 OpenVZ )

1
/sbin/modprobe tcp_hybla

3 、首先做好备份工作,把 sysctl.conf 备份到 root 目录

1
cp /etc/sysctl.conf /root/

4 、修改 sysctl.conf 配置文件,优化 TCP 参数

1
vi /etc/sysctl.conf

添加以下代码

1
2
3
4
5
6
7
fs.file-max = 51200
#提高整个系统的文件限制
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.netdev_max_backlog = 250000
net.core.somaxconn = 3240000

5 、保存生效

1
sysctl -p

小结

经测试, digitalocean,ramnode 的 KVM 等内核支持 hybla 算法。但是 linode 的内核目前不支持

需要注意的是每次重启需要重新加载 hybla 算法模块,可以写入 rc.local 自动启动。

来自Hostloc的一位坛友做的一个脚本,方便测试回程Ping值。目前支持众多区域和各大运营商。

脚本

1
2
wget https://raw.githubusercontent.com/helloxz/mping/master/mping.sh
bash mping.sh

截图

如果希望增加更多测试节点,直接编辑源码,修改修改即可。(节点来自各地运营商DNS)

Speedometer

这是我首推的一个工具,原因是有彩色的图表,简单直观。

安装使用

1
2
3
4
# Debian / Ubuntu
apt-get update
apt-get install speedometer -y

Bmon

如果说上面的那款工具过于花哨,功能性不强的话,可以试试看这款 Bmon,感觉就是增强版的 nload。

安装使用

1
2
3
4
5
6
7
8
# Debian / Ubuntu
apt-get update
apt-get install bmon -y

# CentOS / RHEL
yum install epel-release -y
yum install bmon -y

本文以Ubuntu 12.04 LTS Desktop (x64)默认配置为例(机器的内存为4GB),推荐先阅读**《TCP连接的状态与关闭方式,及其对Server与Client的影响》《Windows系统下的TCP参数优化》**,以了解TCP优化的相关知识。


/proc/sys/net目录

所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失),例如下面这些重要的参数:

参数(路径**+**文件)

描述

默认值

优化值

/proc/sys/net/core/rmem_default

默认的TCP数据接收窗口大小(字节)。

229376

256960

/proc/sys/net/core/rmem_max

最大的TCP数据接收窗口(字节)。

131071

513920

/proc/sys/net/core/wmem_default

默认的TCP数据发送窗口大小(字节)。

229376

256960

/proc/sys/net/core/wmem_max

最大的TCP数据发送窗口(字节)。

131071

513920

/proc/sys/net/core/netdev_max_backlog

在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。

1000

2000

/proc/sys/net/core/somaxconn

定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数。

128

2048

/proc/sys/net/core/optmem_max

表示每个套接字所允许的最大缓冲区的大小。

20480

81920

/proc/sys/net/ipv4/tcp_mem

确定TCP栈应该如何反映内存使用,每个值的单位都是内存页(通常是4KB)。第一个值是内存使用的下限;第二个值是内存压力模式开始对缓冲区使用应用压力的上限;第三个值是内存使用的上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的BDP可以增大这些值(注意,其单位是内存页而不是字节)。

94011  125351  188022

131072  262144  524288

/proc/sys/net/ipv4/tcp_rmem

为自动调优定义socket使用的内存。第一个值是为socket接收缓冲区分配的最少字节数;第二个值是默认值(该值会被rmem_default覆盖),缓冲区在系统负载不重的情况下可以增长到这个值;第三个值是接收缓冲区空间的最大字节数(该值会被rmem_max覆盖)。

4096  87380  4011232

8760  256960  4088000

/proc/sys/net/ipv4/tcp_wmem

为自动调优定义socket使用的内存。第一个值是为socket发送缓冲区分配的最少字节数;第二个值是默认值(该值会被wmem_default覆盖),缓冲区在系统负载不重的情况下可以增长到这个值;第三个值是发送缓冲区空间的最大字节数(该值会被wmem_max覆盖)。

4096  16384  4011232

8760  256960  4088000

/proc/sys/net/ipv4/tcp_keepalive_time

TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效。

7200

1800

/proc/sys/net/ipv4/tcp_keepalive_intvl

探测消息未获得响应时,重发该消息的间隔时间(秒)。

75

30

/proc/sys/net/ipv4/tcp_keepalive_probes

在认定TCP连接失效之前,最多发送多少个keepalive探测消息。

9

3

/proc/sys/net/ipv4/tcp_sack

启用有选择的应答(1表示启用),通过有选择地应答乱序接收到的报文来提高性能,让发送者只发送丢失的报文段,(对于广域网通信来说)这个选项应该启用,但是会增加对CPU的占用。

1

1

/proc/sys/net/ipv4/tcp_fack

启用转发应答,可以进行有选择应答(SACK)从而减少拥塞情况的发生,这个选项也应该启用。

1

1

/proc/sys/net/ipv4/tcp_timestamps

TCP时间戳(会在TCP包头增加12个字节),以一种比重发超时更精确的方法(参考RFC 1323)来启用对RTT 的计算,为实现更好的性能应该启用这个选项。

1

1

/proc/sys/net/ipv4/tcp_window_scaling

启用RFC 1323定义的window scaling,要支持超过64KB的TCP窗口,必须启用该值(1表示启用),TCP窗口最大至1GB,TCP连接双方都启用时才生效。

1

1

/proc/sys/net/ipv4/tcp_syncookies

表示是否打开TCP同步标签(syncookie),内核必须打开了CONFIG_SYN_COOKIES项进行编译,同步标签可以防止一个套接字在有过多试图连接到达时引起过载。

1

1

/proc/sys/net/ipv4/tcp_tw_reuse

表示是否允许将处于TIME-WAIT状态的socket(TIME-WAIT的端口)用于新的TCP连接 。

0

1

/proc/sys/net/ipv4/tcp_tw_recycle

能够更快地回收TIME-WAIT套接字。

0

1

/proc/sys/net/ipv4/tcp_fin_timeout

对于本端断开的socket连接,TCP保持在FIN-WAIT-2状态的时间(秒)。对方可能会断开连接或一直不结束连接或不可预料的进程死亡。

60

30

/proc/sys/net/ipv4/ip_local_port_range

表示TCP/UDP协议允许使用的本地端口号

32768  61000

1024  65000

/proc/sys/net/ipv4/tcp_max_syn_backlog

对于还未获得对方确认的连接请求,可保存在队列中的最大数目。如果服务器经常出现过载,可以尝试增加这个数字。

2048

2048

/proc/sys/net/ipv4/tcp_low_latency

允许TCP/IP栈适应在高吞吐量情况下低延时的情况,这个选项应该禁用。

0

/proc/sys/net/ipv4/tcp_westwood

启用发送者端的拥塞控制算法,它可以维护对吞吐量的评估,并试图对带宽的整体利用情况进行优化,对于WAN 通信来说应该启用这个选项。

0

/proc/sys/net/ipv4/tcp_bic

为快速长距离网络启用Binary Increase Congestion,这样可以更好地利用以GB速度进行操作的链接,对于WAN通信应该启用这个选项。

1

 


/etc/sysctl.conf文件

/etc/sysctl.conf是一个允许你改变正在运行中的Linux系统的接口。它包含一些TCP/IP堆栈和虚拟内存系统的高级选项,可用来控制Linux网络配置,由于/proc/sys/net目录内容的临时性,建议把TCPIP参数的修改添加到/etc/sysctl.conf文件, 然后保存文件,使用命令“/sbin/sysctl –p”使之立即生效。具体修改方案参照上文:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
net.core.rmem_default = 256960

net.core.rmem_max = 513920

net.core.wmem_default = 256960

net.core.wmem_max = 513920

net.core.netdev_max_backlog = 2000

net.core.somaxconn = 2048

net.core.optmem_max = 81920

net.ipv4.tcp_mem = 131072  262144  524288

net.ipv4.tcp_rmem = 8760  256960  4088000

net.ipv4.tcp_wmem = 8760  256960  4088000

net.ipv4.tcp_keepalive_time = 1800

net.ipv4.tcp_keepalive_intvl = 30

net.ipv4.tcp_keepalive_probes = 3

net.ipv4.tcp_sack = 1

net.ipv4.tcp_fack = 1

net.ipv4.tcp_timestamps = 1

net.ipv4.tcp_window_scaling = 1

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_fin_timeout = 30

net.ipv4.ip_local_port_range = 1024  65000

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
这儿所列参数是老男孩老师生产中常用的参数:
net.ipv4.tcp_syn_retries = 1

net.ipv4.tcp_synack_retries = 1

net.ipv4.tcp_keepalive_time = 600

net.ipv4.tcp_keepalive_probes = 3

net.ipv4.tcp_keepalive_intvl =15

net.ipv4.tcp_retries2 = 5

net.ipv4.tcp_fin_timeout = 2

net.ipv4.tcp_max_tw_buckets = 36000

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_max_orphans = 32768

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_max_syn_backlog = 16384

net.ipv4.tcp_wmem = 8192 131072 16777216

net.ipv4.tcp_rmem = 32768 131072 16777216

net.ipv4.tcp_mem = 786432 1048576 1572864

net.ipv4.ip_local_port_range = 1024 65000

net.ipv4.ip_conntrack_max = 65536

net.ipv4.netfilter.ip_conntrack_max=65536

net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=180

net.core.somaxconn = 16384

net.core.netdev_max_backlog = 16384

有的时候 , 你需要临时下载个文件 , 但安装 nginx 又显得过于劳师动众 , 那么用 python 架设个简易的 http 服务器就很方便啦 .

1
python -m SimpleHTTPServer 80

这个命令会把你运行命令的 当前目录 作为 http 服务的根目录 . 所以选好目录再运行哦 .

运行后 , 你就可以在浏览器通过服务器 ip 进行访问了

如果你不想用 80 端口 , 可以把这个 80 改成其他端口 .

如果你想在后台长时间运行这个程序那么可以使用 nohup 命令

1
nohup python -m SimpleHTTPServer 80 &

是不是很方便呢 .

之前我们介绍过一行代码架设个 HTTP 服务器 < 教程 : 一行代码架设个简易 http 服务 >

相比与 http,ftp 对于大文件的传输更加保险 , 而且还能使用各种软件进行挂载 .

今天介绍的 FTP 命令也是用 python 来实现 .

安装环境

因为这个组件 python 默认没有 , 所以要先安装下

1
pip install pyftpdlib

使用

最简单的

. 请放到你要 ftp 的目录 , 它会把该目录变成根目录 . 并且匿名访问 : 默认端口是 2121

1
python -m pyftpdlib

你就可以在浏览器里面通过 : ftp:// 服务器 ip:2121 来访问你的 ftp 服务器了

如果需要使用用户名和密码

1
python -m pyftpdlib -u jarods -P www.jarods.org

-u 是指定用户名  -P 是指定密码 ( 这个 P 是大写 ). 这个语句的含义就是 : 用户名是 jarods, 密码是 www.jarods.org

后台运行

1
nohup python -m pyftpdlib -u jarods -P www.jarods.org &

后台运行后 , 如果要删除进程关闭 ftp 的话可以执行命令 :

1
ps auxgrep pyftpdlibawk '{print $2}'xargs kill -9

开机启动

把后台运行的那个代码写入 /etc/rc.local

1
echo "nohup python -m pyftpdlib -u jarods-p www.jarods.org &" >> /etc/rc.local

 

其他一些参数

除上之外,还有一些可选参数:

  • p 指定端口(默认为 2121 )
  • w 写权限(默认为只读)
  • d 指定目录 (默认为当前目录)