谷歌BBR拥塞算法内核更新
为什么想到这个呢,算法什么的又不太懂,这是 因为搭建VPN + BBR 与之简直绝配
有的人搭建SSR ,配一个什么锐速,还需要降内核版本, 而且还容易出错,降了之后更加容易出现兼容性问题,所以偶尔看到了google的BBR 拥塞阻塞算法
算法原理不知道,也不想去深究 。 原理 这篇博客 讲得还是很清楚的 ,可以一探
Google 开源了其 TCP BBR 拥塞控制算法,并提交到了 Linux 内核,从 4.9 开始,Linux 内核已经用上了该算法。根据谷歌的风格,Google 总是先在自家的生产环境上线运用后,才会将代码开源,此次也不例外。
根据大佬的实地测试,在部署了最新版内核并开启了 TCP BBR 的机器上,网速甚至可以提升好几个数量级。
根据某个大佬开发的一键安装的脚本,可以实现最新内核的安装和 TCP BBR 脚本
脚本如下:
1 #!/usr/bin/env bash 2# 3 # Auto install latest kernel for TCP BBR 4# 5 # System Required: CentOS 6+, Debian7+, Ubuntu12+6#
7 # Copyright (C) 2016-2018 Teddysun <i@teddysun.com>
8#
9 # URL: https://teddysun.com/489.html
10#
11
12 red="33[0;31m"
13 green="33[0;32m"
14 yellow="33[0;33m"
15 plain="33[0m"
16
17 cur_dir=$(pwd)
18
19 [[ $EUID -ne 0 ]] && echo -e "${red}Error:${plain} This script must be run as root!" && exit 1
20
21 [[ -d "/proc/vz" ]] && echo -e "${red}Error:${plain} Your VPS is based on OpenVZ, which is not supported." && exit 1
22
23if [ -f /etc/redhat-release ]; then
24 release="centos"
25elifcat /etc/issue | grep -Eqi "debian"; then
26 release="debian"
27elifcat /etc/issue | grep -Eqi "ubuntu"; then
28 release="ubuntu"
29elifcat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
30 release="centos"
31elifcat /proc/version | grep -Eqi "debian"; then
32 release="debian"
33elifcat /proc/version | grep -Eqi "ubuntu"; then
34 release="ubuntu"
35elifcat /proc/version | grep -Eqi "centos|red hat|redhat"; then
36 release="centos"
37else
38 release=""
39fi
40
41is_digit(){
42 local input=${1}
43if [[ "$input" =~ ^[0-9]+$ ]]; then
44 return 0
45else
46 return 1
47fi
48}
49
50is_64bit(){
51if [ $(getconf WORD_BIT) = "32" ] && [ $(getconf LONG_BIT) = "64" ]; then
52 return 0
53else
54 return 1
55fi
56}
57
58get_valid_valname(){
59 local val=${1}
60 local new_val=$(eval echo $val | sed"s/[-.]/_/g")
61echo ${new_val}
62}
63
64get_hint(){
65 local val=${1}
66 local new_val=$(get_valid_valname $val)
67 eval echo"$hint_${new_val}"
68}
69
70#Display Memu
71display_menu(){
72 local soft=${1}
73 local default=${2}
74 eval local arr=(${${soft}_arr[@]})
75 local default_prompt
76if [[ "$default" != "" ]]; then
77if [[ "$default" == "last" ]]; then
78 default=${#arr[@]}
79fi
80 default_prompt="(default ${arr[$default-1]})"
81fi
82 local pick
83 local hint
84 local vname
85 local prompt="which ${soft} you"d select ${default_prompt}: "
86
87while :
88do
89echo -e "
------------ ${soft} setting ------------
"
90for ((i=1;i<=${#arr[@]};i++ )); do
91 vname="$(get_valid_valname ${arr[$i-1]})"
92 hint="$(get_hint $vname)"
93 [[ "$hint" == "" ]] && hint="${arr[$i-1]}"
94echo -e "${green}${i}${plain}) $hint"
95done
96echo
97 read -p "${prompt}" pick
98if [[ "$pick" == "" && "$default" != "" ]]; then
99 pick=${default}
100 break
101fi
102
103if ! is_digit "$pick"; then
104 prompt="Input error, please input a number"
105 continue
106fi
107
108if [[ "$pick" -lt 1 || "$pick" -gt ${#arr[@]} ]]; then
109 prompt="Input error, please input a number between 1 and ${#arr[@]}: "
110 continue
111fi
112
113 break
114done
115
116 eval ${soft}=${arr[$pick-1]}
117 vname="$(get_valid_valname ${arr[$pick-1]})"
118 hint="$(get_hint $vname)"
119 [[ "$hint" == "" ]] && hint="${arr[$pick-1]}"
120echo -e "
your selection: $hint
"
121}
122
123version_ge(){
124 test "$(echo "$@" | tr """
" | sort -rV | head -n 1)" == "$1"
125}
126
127get_latest_version() {
128 latest_version=($(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/ | awk -F""v" "/v[4-9]./{print $2}" | cut -d/ -f1 | grep -v - | sort -V))
129
130 [ ${#latest_version[@]} -eq 0 ] && echo -e "${red}Error:${plain} Get latest kernel version failed." && exit 1
131
132 kernel_arr=()
133for i in ${latest_version[@]}; do
134if version_ge $i 4.14; then
135 kernel_arr+=($i);
136fi
137done
138
139 display_menu kernel last
140
141if [[ `getconf WORD_BIT` == "32" && `getconf LONG_BIT` == "64" ]]; then
142 deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-image" | grep "generic" | awk -F"">" "/amd64.deb/{print $2}" | cut -d"<" -f1 | head -1)
143 deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"
144 deb_kernel_name="linux-image-${kernel}-amd64.deb"
145 modules_deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-modules" | grep "generic" | awk -F"">" "/amd64.deb/{print $2}" | cut -d"<" -f1 | head -1)
146 deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"
147 deb_kernel_modules_name="linux-modules-${kernel}-amd64.deb"
148else
149 deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-image" | grep "generic" | awk -F"">" "/i386.deb/{print $2}" | cut -d"<" -f1 | head -1)
150 deb_kernel_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${deb_name}"
151 deb_kernel_name="linux-image-${kernel}-i386.deb"
152 modules_deb_name=$(wget -qO- https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/ | grep "linux-modules" | grep "generic" | awk -F"">" "/i386.deb/{print $2}" | cut -d"<" -f1 | head -1)
153 deb_kernel_modules_url="https://kernel.ubuntu.com/~kernel-ppa/mainline/v${kernel}/${modules_deb_name}"
154 deb_kernel_modules_name="linux-modules-${kernel}-i386.deb"
155fi
156
157 [ -z ${deb_name} ] && echo -e "${red}Error:${plain} Getting Linux kernel binary package name failed, maybe kernel build failed. Please choose other one and try again." && exit 1
158}
159
160get_opsy() {
161 [ -f /etc/redhat-release ] && awk"{print ($1,$3~/^[0-9]/?$3:$4)}" /etc/redhat-release && return
162 [ -f /etc/os-release ] && awk -F"[= "]""/PRETTY_NAME/{print $3,$4,$5}" /etc/os-release && return
163 [ -f /etc/lsb-release ] && awk -F"[="]+""/DESCRIPTION/{print $2}" /etc/lsb-release && return
164}
165
166 opsy=$( get_opsy )
167 arch=$( uname -m )
168 lbit=$( getconf LONG_BIT )
169 kern=$( uname -r )
170
171get_char() {
172 SAVEDSTTY=`stty -g`
173 stty -echo
174 stty cbreak
175ddif=/dev/tty bs=1 count=12> /dev/null
176 stty -raw
177 stty echo
178 stty $SAVEDSTTY
179}
180
181getversion() {
182if [[ -s /etc/redhat-release ]]; then
183grep -oE "[0-9.]+" /etc/redhat-release
184else
185grep -oE "[0-9.]+" /etc/issue
186fi
187}
188
189centosversion() {
190if [ x"${release}" == x"centos" ]; then
191 local code=$1
192 local version="$(getversion)"
193 local main_ver=${version%%.*}
194if [ "$main_ver" == "$code" ]; then
195 return 0
196else
197 return 1
198fi
199else
200 return 1
201fi
202}
203
204check_bbr_status() {
205 local param=$(sysctl net.ipv4.tcp_congestion_control | awk"{print $3}")
206if [[ x"${param}" == x"bbr" ]]; then
207 return 0
208else
209 return 1
210fi
211}
212
213check_kernel_version() {
214 local kernel_version=$(uname -r | cut -d- -f1)
215if version_ge ${kernel_version} 4.9; then
216 return 0
217else
218 return 1
219fi
220}
221
222install_elrepo() {
223
224if centosversion 5; then
225echo -e "${red}Error:${plain} not supported CentOS 5."
226 exit 1
227fi
228
229 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
230
231if centosversion 6; then
232 rpm -Uvh https://www.elrepo.org/elrepo-release-6-9.el6.elrepo.noarch.rpm
233elif centosversion 7; then
234 rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
235fi
236
237if [ ! -f /etc/yum.repos.d/elrepo.repo ]; then
238echo -e "${red}Error:${plain} Install elrepo failed, please check it."
239 exit 1
240fi
241}
242
243sysctl_config() {
244sed -i "/net.core.default_qdisc/d" /etc/sysctl.conf
245sed -i "/net.ipv4.tcp_congestion_control/d" /etc/sysctl.conf
246echo"net.core.default_qdisc = fq" >> /etc/sysctl.conf
247echo"net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf
248 sysctl -p >/dev/null2>&1
249}
250
251install_config() {
252if [[ x"${release}" == x"centos" ]]; then
253if centosversion 6; then
254if [ ! -f "/boot/grub/grub.conf" ]; then
255echo -e "${red}Error:${plain} /boot/grub/grub.conf not found, please check it."
256 exit 1
257fi
258sed -i "s/^default=.*/default=0/g" /boot/grub/grub.conf
259elif centosversion 7; then
260if [ ! -f "/boot/grub2/grub.cfg" ]; then
261echo -e "${red}Error:${plain} /boot/grub2/grub.cfg not found, please check it."
262 exit 1
263fi
264 grub2-set-default 0
265fi
266elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then
267 /usr/sbin/update-grub
268fi
269}
270
271reboot_os() {
272echo
273echo -e "${green}Info:${plain} The system needs to reboot."
274 read -p "Do you want to restart system? [y/n]" is_reboot
275if [[ ${is_reboot} == "y" || ${is_reboot} == "Y" ]]; then
276 reboot
277else
278echo -e "${green}Info:${plain} Reboot has been canceled..."
279 exit 0
280fi
281}
282
283install_bbr() {
284 check_bbr_status
285if [ $? -eq 0 ]; then
286echo
287echo -e "${green}Info:${plain} TCP BBR has already been installed. nothing to do..."
288 exit 0
289fi
290 check_kernel_version
291if [ $? -eq 0 ]; then
292echo
293echo -e "${green}Info:${plain} Your kernel version is greater than 4.9, directly setting TCP BBR..."
294 sysctl_config
295echo -e "${green}Info:${plain} Setting TCP BBR completed..."
296 exit 0
297fi
298
299if [[ x"${release}" == x"centos" ]]; then
300 install_elrepo
301 [ ! "$(command -v yum-config-manager)" ] && yuminstall -y yum-utils > /dev/null2>&1
302 [ x"$(yum-config-manager elrepo-kernel | grep -w enabled | awk "{print $3}")" != x"True" ] && yum-config-manager --enable elrepo-kernel > /dev/null2>&1
303if centosversion 6; then
304if is_64bit; then
305 rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.x86_64.rpm"
306 rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.x86_64.rpm"
307 rpm_kernel_url_1="http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/x86_64/RPMS/"
308else
309 rpm_kernel_name="kernel-ml-4.18.20-1.el6.elrepo.i686.rpm"
310 rpm_kernel_devel_name="kernel-ml-devel-4.18.20-1.el6.elrepo.i686.rpm"
311 rpm_kernel_url_1="http://repos.lax.quadranet.com/elrepo/archive/kernel/el6/i386/RPMS/"
312fi
313 rpm_kernel_url_2="https://dl.lamp.sh/files/"
314wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_1}${rpm_kernel_name}
315if [ $? -ne 0 ]; then
316rm -rf ${rpm_kernel_name}
317wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_2}${rpm_kernel_name}
318fi
319wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_1}${rpm_kernel_devel_name}
320if [ $? -ne 0 ]; then
321rm -rf ${rpm_kernel_devel_name}
322wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_2}${rpm_kernel_devel_name}
323fi
324if [ -f "${rpm_kernel_name}" ]; then
325 rpm -ivh ${rpm_kernel_name}
326else
327echo -e "${red}Error:${plain} Download ${rpm_kernel_name} failed, please check it."
328 exit 1
329fi
330if [ -f "${rpm_kernel_devel_name}" ]; then
331 rpm -ivh ${rpm_kernel_devel_name}
332else
333echo -e "${red}Error:${plain} Download ${rpm_kernel_devel_name} failed, please check it."
334 exit 1
335fi
336rm -f ${rpm_kernel_name} ${rpm_kernel_devel_name}
337elif centosversion 7; then
338yum -y install kernel-ml kernel-ml-devel
339if [ $? -ne 0 ]; then
340echo -e "${red}Error:${plain} Install latest kernel failed, please check it."
341 exit 1
342fi
343fi
344elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then
345 [[ ! -e "/usr/bin/wget" ]] && apt-get -y update && apt-get -y installwget
346echo -e "${green}Info:${plain} Getting latest kernel version..."
347 get_latest_version
348if [ -n ${modules_deb_name} ]; then
349wget -c -t3 -T60 -O ${deb_kernel_modules_name} ${deb_kernel_modules_url}
350if [ $? -ne 0 ]; then
351echo -e "${red}Error:${plain} Download ${deb_kernel_modules_name} failed, please check it."
352 exit 1
353fi
354fi
355wget -c -t3 -T60 -O ${deb_kernel_name} ${deb_kernel_url}
356if [ $? -ne 0 ]; then
357echo -e "${red}Error:${plain} Download ${deb_kernel_name} failed, please check it."
358 exit 1
359fi
360 [ -f ${deb_kernel_modules_name} ] && dpkg -i ${deb_kernel_modules_name}
361 dpkg -i ${deb_kernel_name}
362rm -f ${deb_kernel_name} ${deb_kernel_modules_name}
363else
364echo -e "${red}Error:${plain} OS is not be supported, please change to CentOS/Debian/Ubuntu and try again."
365 exit 1
366fi
367
368 install_config
369 sysctl_config
370 reboot_os
371}
372
373
374clear
375echo"---------- System Information ----------"
376echo" OS : $opsy"
377echo" Arch : $arch ($lbit Bit)"
378echo" Kernel : $kern"
379echo"----------------------------------------"
380echo" Auto install latest kernel for TCP BBR"
381echo
382echo" URL: https://teddysun.com/489.html"
383echo"----------------------------------------"
384echo
385echo"Press any key to start...or Press Ctrl+C to cancel"
386char=`get_char`
387
388 install_bbr 2>&1 | tee ${cur_dir}/install_bbr.log
View Code
也可以采用在线安装的方式:
wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh && chmod +x bbr.sh && ./bbr.sh
安装完成后,脚本会提示需要重启 VPS,输入 y 并回车后重启。
重启完成后,进入 VPS,验证一下是否成功安装最新内核并开启 TCP BBR,输入命令:
uname -r
查看内核版本,显示为最新版就表示 OK了
sysctl net.ipv4.tcp_available_congestion_control返回值一般为:
net.ipv4.tcp_available_congestion_control
= bbr cubic reno或者为:
net.ipv4.tcp_available_congestion_control
= reno cubic bbr=================================================================================
sysctl net.ipv4.tcp_congestion_control
返回值一般为:
net.ipv4.tcp_congestion_control
= bbr=================================================================================
sysctl net.core.default_qdisc
返回值一般为:
net.core.default_qdisc
= fq==================================================================================
lsmod | grep bbr返回值有 tcp_bbr 模块即说明 bbr 已启动。注意:并不是所有的 VPS 都会有此返回值,若没有也属正常。
另外:
附上大佬的CentOS 下最新版内核 headers 安装方法
本来打算在脚本里直接安装 kernel-ml-headers,但会出现和原版内核 headers 冲突的问题。因此在这里添加一个脚本执行完后,手动安装最新版内核 headers 之教程。执行以下命令
yum --enablerepo=elrepo-kernel -y install kernel-ml-headers
根据 CentOS 版本的不同,此时一般会出现类似于以下的错误提示:
Error: kernel-ml-headers conflicts with kernel-headers-2.6.32-696.20.1.el6.x86_64
Error: kernel-ml-headers conflicts with kernel-headers-3.10.0-693.17.1.el7.x86_64
因此需要先卸载原版内核 headers ,然后再安装最新版内核 headers。执行命令:
yum remove kernel-headers
确认无误后,输入 y,回车开始卸载。注意,有时候这么操作还会卸载一些对内核 headers 依赖的安装包,比如 gcc、gcc-c++ 之类的。不过不要紧,我们可以在安装完最新版内核 headers 后再重新安装回来即可。
卸载完成后,再次执行上面给出的安装命令。
yum --enablerepo=elrepo-kernel -y install kernel-ml-headers
成功安装后,再把那些之前对内核 headers 依赖的安装包,比如 gcc、gcc-c++ 之类的再安装一次即可。
为什么要安装最新版内核 headers 呢?
这是因为 ss-libev 版有个 tcp fast open 功能,如果不安装的话,这个功能是无法开启的。
内核升级方法
如果是 CentOS 系统,执行如下命令即可升级内核:
yum -y install kernel-ml kernel-ml-devel
如果你还手动安装了新版内核 headers ,那么还需要以下命令来升级 headers :
yum -y install kernel-ml-headers
CentOS 6 的话,执行命令:
sed -i "s/^default=.*/default=0/g" /boot/grub/grub.conf
CentOS 7 的话,执行命令:
grub2-set-default 0
如果是 Debian/Ubuntu 系统,则需要手动下载最新版内核来安装升级。
去这里下载最新版的内核 deb 安装包。
如果系统是 64 位,则下载 amd64 的 linux-image 中含有 generic 这个 deb 包;
如果系统是 32 位,则下载 i386 的 linux-image 中含有 generic 这个 deb 包;
安装的命令如下(以最新版的 64 位 4.12.4 举例而已,请替换为下载好的 deb 包):
dpkg -i linux-image-4.12.4-041204-generic_4.12.4-041204.201707271932_amd64.deb
安装完成后,再执行命令:
/usr/sbin/update-grub
最后,重启 VPS 即可。
特别说明
如果你使用的是 Google Cloud Platform (GCP)更换内核,有时会遇到重启后,整个磁盘变为只读的情况。只需执行以下命令即可恢复:
mount -o remount rw /
参考链接:
https://github.com/google/bbr/blob/master/Documentation/bbr-quick-start.md
http://elrepo.org/tiki/tiki-index.php
http://kernel.ubuntu.com/~kernel-ppa/mainline/
https://teddysun.com/489.html
以上是 谷歌BBR拥塞算法内核更新 的全部内容, 来源链接: utcz.com/z/512755.html