谷歌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

回到顶部