为什么想到这个呢,算法什么的又不太懂,这是 因为搭建VPN + BBR 与之简直绝配

有的人搭建SSR ,配一个什么锐速,还需要降内核版本, 而且还容易出错,降了之后更加容易出现兼容性问题,所以偶尔看到了google的BBR 拥塞阻塞算法 

算法原理不知道,也不想去深究 。 原理 这篇博客 讲得还是很清楚的 ,可以一探

Google 开源了其 TCP BBR 拥塞控制算法,并提交到了 Linux 内核,从 4.9 开始,Linux 内核已经用上了该算法。根据谷歌的风格,Google 总是先在自家的生产环境上线运用后,才会将代码开源,此次也不例外。
根据大佬的实地测试,在部署了最新版内核并开启了 TCP BBR 的机器上,网速甚至可以提升好几个数量级。

根据某个大佬开发的一键安装的脚本,可以实现最新内核的安装和 TCP BBR 脚本
脚本如下:

谷歌BBR拥塞算法内核更新_谷歌BBR谷歌BBR拥塞算法内核更新_谷歌BBR_02

  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   8 #  9 # URL: https://teddysun.com/489.html 10 # 11  12 red='\033[0;31m' 13 green='\033[0;32m' 14 yellow='\033[0;33m' 15 plain='\033[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  23 if [ -f /etc/redhat-release ]; then 24     release="centos" 25 elif cat /etc/issue | grep -Eqi "debian"; then 26     release="debian" 27 elif cat /etc/issue | grep -Eqi "ubuntu"; then 28     release="ubuntu" 29 elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then 30     release="centos" 31 elif cat /proc/version | grep -Eqi "debian"; then 32     release="debian" 33 elif cat /proc/version | grep -Eqi "ubuntu"; then 34     release="ubuntu" 35 elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then 36     release="centos" 37 else 38     release="" 39 fi 40  41 is_digit(){ 42     local input=${1} 43     if [[ "$input" =~ ^[0-9]+$ ]]; then 44         return 0 45     else 46         return 1 47     fi 48 } 49  50 is_64bit(){ 51     if [ $(getconf WORD_BIT) = '32' ] && [ $(getconf LONG_BIT) = '64' ]; then 52         return 0 53     else 54         return 1 55     fi 56 } 57  58 get_valid_valname(){ 59     local val=${1} 60     local new_val=$(eval echo $val | sed 's/[-.]/_/g') 61     echo ${new_val} 62 } 63  64 get_hint(){ 65     local val=${1} 66     local new_val=$(get_valid_valname $val) 67     eval echo "\$hint_${new_val}" 68 } 69  70 #Display Memu 71 display_menu(){ 72     local soft=${1} 73     local default=${2} 74     eval local arr=(\${${soft}_arr[@]}) 75     local default_prompt 76     if [[ "$default" != "" ]]; then 77         if [[ "$default" == "last" ]]; then 78             default=${#arr[@]} 79         fi 80         default_prompt="(default ${arr[$default-1]})" 81     fi 82     local pick 83     local hint 84     local vname 85     local prompt="which ${soft} you'd select ${default_prompt}: " 86  87     while : 88     do 89         echo -e "\n------------ ${soft} setting ------------\n" 90         for ((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]}" 94             echo -e "${green}${i}${plain}) $hint" 95         done 96         echo 97         read -p "${prompt}" pick 98         if [[ "$pick" == "" && "$default" != "" ]]; then 99             pick=${default}100             break101         fi102 103         if ! is_digit "$pick"; then104             prompt="Input error, please input a number"105             continue106         fi107 108         if [[ "$pick" -lt 1 || "$pick" -gt ${#arr[@]} ]]; then109             prompt="Input error, please input a number between 1 and ${#arr[@]}: "110             continue111         fi112 113         break114     done115 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]}"120     echo -e "\nyour selection: $hint\n"121 }122 123 version_ge(){124     test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"125 }126 127 get_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 1131 132     kernel_arr=()133     for i in ${latest_version[@]}; do134         if version_ge $i 4.14; then135             kernel_arr+=($i);136         fi137     done138 139     display_menu kernel last140 141     if [[ `getconf WORD_BIT` == "32" && `getconf LONG_BIT` == "64" ]]; then142         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"148     else149         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"155     fi156 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 1158 }159 160 get_opsy() {161     [ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return162     [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return163     [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return164 }165 166 opsy=$( get_opsy )167 arch=$( uname -m )168 lbit=$( getconf LONG_BIT )169 kern=$( uname -r )170 171 get_char() {172     SAVEDSTTY=`stty -g`173     stty -echo174     stty cbreak175     dd if=/dev/tty bs=1 count=1 2> /dev/null176     stty -raw177     stty echo178     stty $SAVEDSTTY179 }180 181 getversion() {182     if [[ -s /etc/redhat-release ]]; then183         grep -oE  "[0-9.]+" /etc/redhat-release184     else185         grep -oE  "[0-9.]+" /etc/issue186     fi187 }188 189 centosversion() {190     if [ x"${release}" == x"centos" ]; then191         local code=$1192         local version="$(getversion)"193         local main_ver=${version%%.*}194         if [ "$main_ver" == "$code" ]; then195             return 0196         else197             return 1198         fi199     else200         return 1201     fi202 }203 204 check_bbr_status() {205     local param=$(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}')206     if [[ x"${param}" == x"bbr" ]]; then207         return 0208     else209         return 1210     fi211 }212 213 check_kernel_version() {214     local kernel_version=$(uname -r | cut -d- -f1)215     if version_ge ${kernel_version} 4.9; then216         return 0217     else218         return 1219     fi220 }221 222 install_elrepo() {223 224     if centosversion 5; then225         echo -e "${red}Error:${plain} not supported CentOS 5."226         exit 1227     fi228 229     rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org230 231     if centosversion 6; then232         rpm -Uvh https://www.elrepo.org/elrepo-release-6-9.el6.elrepo.noarch.rpm233     elif centosversion 7; then234         rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm235     fi236 237     if [ ! -f /etc/yum.repos.d/elrepo.repo ]; then238         echo -e "${red}Error:${plain} Install elrepo failed, please check it."239         exit 1240     fi241 }242 243 sysctl_config() {244     sed -i '/net.core.default_qdisc/d' /etc/sysctl.conf245     sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf246     echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf247     echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf248     sysctl -p >/dev/null 2>&1249 }250 251 install_config() {252     if [[ x"${release}" == x"centos" ]]; then253         if centosversion 6; then254             if [ ! -f "/boot/grub/grub.conf" ]; then255                 echo -e "${red}Error:${plain} /boot/grub/grub.conf not found, please check it."256                 exit 1257             fi258             sed -i 's/^default=.*/default=0/g' /boot/grub/grub.conf259         elif centosversion 7; then260             if [ ! -f "/boot/grub2/grub.cfg" ]; then261                 echo -e "${red}Error:${plain} /boot/grub2/grub.cfg not found, please check it."262                 exit 1263             fi264             grub2-set-default 0265         fi266     elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then267         /usr/sbin/update-grub268     fi269 }270 271 reboot_os() {272     echo273     echo -e "${green}Info:${plain} The system needs to reboot."274     read -p "Do you want to restart system? [y/n]" is_reboot275     if [[ ${is_reboot} == "y" || ${is_reboot} == "Y" ]]; then276         reboot277     else278         echo -e "${green}Info:${plain} Reboot has been canceled..."279         exit 0280     fi281 }282 283 install_bbr() {284     check_bbr_status285     if [ $? -eq 0 ]; then286         echo287         echo -e "${green}Info:${plain} TCP BBR has already been installed. nothing to do..."288         exit 0289     fi290     check_kernel_version291     if [ $? -eq 0 ]; then292         echo293         echo -e "${green}Info:${plain} Your kernel version is greater than 4.9, directly setting TCP BBR..."294         sysctl_config295         echo -e "${green}Info:${plain} Setting TCP BBR completed..."296         exit 0297     fi298 299     if [[ x"${release}" == x"centos" ]]; then300         install_elrepo301         [ ! "$(command -v yum-config-manager)" ] && yum install -y yum-utils > /dev/null 2>&1302         [ x"$(yum-config-manager elrepo-kernel | grep -w enabled | awk '{print $3}')" != x"True" ] && yum-config-manager --enable elrepo-kernel > /dev/null 2>&1303         if centosversion 6; then304             if is_64bit; then305                 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/"308             else309                 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/"312             fi313             rpm_kernel_url_2="https://dl.lamp.sh/files/"314             wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_1}${rpm_kernel_name}315             if [ $? -ne 0 ]; then316                 rm -rf ${rpm_kernel_name}317                 wget -c -t3 -T60 -O ${rpm_kernel_name} ${rpm_kernel_url_2}${rpm_kernel_name}318             fi319             wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_1}${rpm_kernel_devel_name}320             if [ $? -ne 0 ]; then321                 rm -rf ${rpm_kernel_devel_name}322                 wget -c -t3 -T60 -O ${rpm_kernel_devel_name} ${rpm_kernel_url_2}${rpm_kernel_devel_name}323             fi324             if [ -f "${rpm_kernel_name}" ]; then325                 rpm -ivh ${rpm_kernel_name}326             else327                 echo -e "${red}Error:${plain} Download ${rpm_kernel_name} failed, please check it."328                 exit 1329             fi330             if [ -f "${rpm_kernel_devel_name}" ]; then331                 rpm -ivh ${rpm_kernel_devel_name}332             else333                 echo -e "${red}Error:${plain} Download ${rpm_kernel_devel_name} failed, please check it."334                 exit 1335             fi336             rm -f ${rpm_kernel_name} ${rpm_kernel_devel_name}337         elif centosversion 7; then338             yum -y install kernel-ml kernel-ml-devel339             if [ $? -ne 0 ]; then340                 echo -e "${red}Error:${plain} Install latest kernel failed, please check it."341                 exit 1342             fi343         fi344     elif [[ x"${release}" == x"debian" || x"${release}" == x"ubuntu" ]]; then345         [[ ! -e "/usr/bin/wget" ]] && apt-get -y update && apt-get -y install wget346         echo -e "${green}Info:${plain} Getting latest kernel version..."347         get_latest_version348         if [ -n ${modules_deb_name} ]; then349             wget -c -t3 -T60 -O ${deb_kernel_modules_name} ${deb_kernel_modules_url}350             if [ $? -ne 0 ]; then351                 echo -e "${red}Error:${plain} Download ${deb_kernel_modules_name} failed, please check it."352                 exit 1353             fi354         fi355         wget -c -t3 -T60 -O ${deb_kernel_name} ${deb_kernel_url}356         if [ $? -ne 0 ]; then357             echo -e "${red}Error:${plain} Download ${deb_kernel_name} failed, please check it."358             exit 1359         fi360         [ -f ${deb_kernel_modules_name} ] && dpkg -i ${deb_kernel_modules_name}361         dpkg -i ${deb_kernel_name}362         rm -f ${deb_kernel_name} ${deb_kernel_modules_name}363     else364         echo -e "${red}Error:${plain} OS is not be supported, please change to CentOS/Debian/Ubuntu and try again."365         exit 1366     fi367 368     install_config369     sysctl_config370     reboot_os371 }372 373 374 clear375 echo "---------- System Information ----------"376 echo " OS      : $opsy"377 echo " Arch    : $arch ($lbit Bit)"378 echo " Kernel  : $kern"379 echo "----------------------------------------"380 echo " Auto install latest kernel for TCP BBR"381 echo382 echo " URL: https://teddysun.com/489.html"383 echo "----------------------------------------"384 echo385 echo "Press any key to start...or Press Ctrl+C to cancel"386 char=`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了

谷歌BBR拥塞算法内核更新_谷歌BBR_03

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 /