微软云反向解析阿里云实现高可用

背景

我是一个产品经理,自己手里也有几个网站,包括你现在看到无不为,另外还有经方派等。之前因为觉得不重要,就放在了国外的 VPS 上,很长一段时间用的都是 Linode VPS,选择了延迟最小的日本的机房,但依然很慢,最大的问题是线路抖动,经常会打不开网站。后来观察到经方派每天都会有人通过搜索引擎访问,尤其是国内用户占大多数,就想避免再这样频繁宕机,对搜索引擎不友好,用户体验也不好。

把网站搬回国内,面临的第一个问题就是备·鞍,新的政策要求备·鞍负责人和域名注册人信息一致(要求实名认证),这就需要把域名转移回国内,准备接受。但又发现不允许 org、me 的顶级域名备·鞍。这条路就不通了。

购买了阿里云的香港主机,能访问的时候速度很快,但比 Linode VPS 更不稳定,每天都会不定时抽风。

需要解决的问题

问题很简单,就是在不备·鞍的前提下,实现高可用,这里的高可用,指的就是访问稳定、速度快。

整体思路

之前给朋友建得站都部署在了阿里云大陆机房内,监测非常稳定。所以首先确定使用阿里云 ECS 主机。

绕过备·鞍的思路是在微软云(Microsoft Azure)虚拟机上安装 Nginx 进行反向代理。选择了微软云东亚香港区的机房。延迟比较低。

方案

整体思路有了,核心就是从国外把网站迁移到阿里云,再在微软云上配置好 Nginx 反向代理。

阿里云

正好赶上阿里云「开年Hi购季」活动,看到阿里云数据库等产品都在搞活动。既然要放到国内,不妨吃个阿里云小份全家桶:SLB+ECS+RDS+OSS。

ECS 主机花了 ¥1,469.00 (代金券抵扣了 ¥50.00,实际花费 ¥1419.00),时长三年,配置为:1 vCPU、2 GB 内存、1 Mbps 固定宽带。

数据库 RDS,花 ¥10.00 购买了半年,配置为1 vCPU、1 GB 内存、SSD 20G 硬盘,我的网站是基于 WordPress,所以 RDS 的类型是 MySQL 5.7。

为什么要买负载均衡 SLB ?因为阿里云 ECS 选的是 1Mbps 固定宽带,这样下载速度只有 100 Kb/s,非常慢,负载均衡是按流量付费,几乎不限带宽值(实际是5120 Mbps ),而负载均衡和 ECS 之间是内网 VPC 连接,几乎也不限速,这样就突破了 ECS 本身 1 Mbps 固定宽带的限制。而现在网站的流量还比较低,几个网站加起来每小时的负载均衡费用只有2分钱。这里非常巧妙的是用负载均衡突破了宽带限制,而没有使用它原始的作用:主备冗余实现高可用。

因为个人博客上也会有一些图片,也计划接下来多分享一些文章,少不了截图,就干脆把阿里云对象存储 OSS 也用上了。非常便宜,¥9.00买了40G 一年的空间。另外还有一点点后付费几乎忽略不记。

在阿里云上总的花费见下图:

微软云

微软云的虚拟主机还是非常贵的。选择了东亚香港区最低的配置,1 vCPU、0.75 GB 内存、30 GB 硬盘、100 Mbps 固定宽带,预算费用在 US$14.88。但好在微软云有200美金1年的免费体验,1年到头后再另想办法。

这里会有人问:0.75 GB 的内存会不会太小了?答案是不会。因为在微软云上,我们会只用一个 Nginx 做反向代理,不需要太高的内存。

在微软云虚拟机上,我使用了 Ubuntu Server 18.04 LTS 操作系统。之所以选择 Ubuntu,是因为最新的 Ubuntu 系统开启 BBR 网络拥塞控制算法非常容易。开启 BBR 对反向代理速度有多少提升,这一点我并没有做测试。

在微软云上操作的相关命令:

1、升级系统:

sudo -i
apt-get update -y apt-get upgrade -y

2、开启 BBR:

(1)修改系统变量:

echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf

(2)保存生效:

sysctl -p

(3)查看内核是否已开启BBR:

sysctl net.ipv4.tcp_available_congestion_control

显示以下即已开启:

net.ipv4.tcp_available_congestion_control = reno bbr cubic

(4)查看BBR是否启动:

lsmod | grep bbr

显示以下即启动成功:

tcp_bbr 20480 1

3、安装 Nginx :

apt-get install nginx -y

4、配置 Nginx 反向代理:

vi /etc/nginx/conf.d/jingfang.org.conf

配置文件示意:

server
    {
        listen 80;
        #listen [::]:80;
        server_name jingfang.org www.jingfang.org;
        rewrite ^(.*) https://jingfang.org$1 permanent;
    }

server
    {
        listen 443 ssl http2;
        #listen [::]:443 ssl http2;
        server_name jingfang.org ;
        ssl on;
        ssl_certificate /etc/nginx/conf.d/ssl/jingfang.org/fullchain.cer;
        ssl_certificate_key /etc/nginx/conf.d/ssl/jingfang.org/jingfang.org.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        ssl_session_cache builtin:1000 shared:SSL:10m;
        # openssl dhparam -out /usr/local/nginx/conf/ssl/dhparam.pem 2048
        ssl_dhparam /etc/nginx/conf.d/ssl/dhparam.pem;

        #error_page   404   /404.html;

        # Deny access to PHP files in specific directory
        #location ~ /(wp-content|uploads|wp-includes|images)/.*\.php$ { deny all; }

        location / {
            proxy_pass http://xxx.xxx.xxx.xxx:端口号;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_cache_bypass $http_upgrade;
        }
        location ~ /.well-known {
            allow all;
        }

        location ~ /\.
        {
            deny all;
        }

        access_log  /var/log/nginx/jingfang.org.log;
    }

这里关键是proxy\_pass的地址,指向的是阿里云负载均衡 SLB 的 IP 地址和前端端口。

【域名解析】 ——A 记录——> 【微软云虚拟机 IP 】 ——Nginx 反向代理——> 【阿里云 SLB 】——TCP 负载协议——> 【阿里云 ECS 】

下面再返过头来看阿里云相关服务的设置。

虚拟主机 ECS

操作系统同样选择 Ubuntu Server 18.04 LTS。升级系统,开启 BBR。

以前网站的环境都是用军哥的 LNMPA 一键安装脚本搭建。这次在阿里云上选择使用 Docker 技术。

1、安装 Docker 及 Docker-compose 方法:

apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io

安装完成后,查看是否安装成功,如果安装成功,以下命令将输出 Docker 的版本号:

docker --version

继续安装 Docker-compose:

curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

同样查看 Docker-compose 是否安装成功:

docker-compose --version

2、WordPress 的 docker-compose.yml 配置文件:

在网站的目录下,新建 docker-compose.yml 文件,内容如下:

version: '2'
services:
  web:
    image: wordpress:latest
    restart: always
    ports:
      - 9999:80
    environment:
      WORDPRESS_DB_HOST: rds 的内网地址.mysql.rds.aliyuncs.com:3306
      WORDPRESS_DB_USER: rds 新建的用户名
      WORDPRESS_DB_PASSWORD: rds 相关用户的密码
      WORDPRESS_DB_NAME: rds 新建的数据库名
    volumes:
      - ./www/wp-content:/var/www/html/wp-content
      - ./config/php/conf.d/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini

这里因为购买了阿里云 RDS MySQL 5.7,所以就没有用 Docker 实例化 MySQL 容器,而是直接通过内网地址,连接到了阿里云 RDS。

另外映射了数据卷,wp-content 是网站数据集中的目录,包含了上传的文件、插件、主题等,需要持久化在 ECS 中;uploads.ini 是修改了 WordPress 容器中 PHP 的文件上传大小限制(原始仅允许上传为 2 MB)的配置文件,内容如下:

file_uploads = On
upload_max_filesize = 64M
post_max_size = 64M

启动 WordPress Docker 容器:

docker-compose up -d

在 ECS 安全组中配置好 TCP 9999 端口的入站允许安全规则后,在浏览器中打开 http://xxx.xxx.xxx.xxx:9999,应可以看到WordPress 的安装界面,此时只是测试 Docker 容器是否运行正常,不需要继续安装。另外在负载均衡 SLB 配置好后,也不需要在 ECS 安全组中开启 Docker 容器的端口。

负载均衡 SLB

SLB 设置非常简单。

第一步,选择 TCP 协议,输入监听的端口,此处的端口号,即为微软云 Nginx 反向代理proxy\_pass处设置的端口号。

第二步,选默认服务器组,端口号是 Docker-compose 文件里配置的宿主机端口号,如上面的例子配置的是9999。

下一步确认提交即可。

当域名解析到微软云虚拟机 IP 生效后,我们就可以通过域名安装 WordPress 了。

数据库 RDS

阿里云数据库 RDS 的管理界面非常简单,可以很方便地创建数据库、用户,注意要把数据库的权限赋予用户。这里就不详细说了。

对象存储 OSS

分为两步,首先要在 OSS 管理后台中创建 Bucket,其次在 WordPress 中安装 OSS 插件。

1、创建 Bucket

输入 Bucket 名称后即可创建。注意要把读写权限设置为「公共读」。

2、设置 Access Key

为了稍后让插件管理此 Bucket,我们还要设置一个 Access Key。点右侧的 Access Key,在弹出的对话框中选择「子Access Key」。

在新建用户的界面中输入用户名,并选择「编程访问」,即可获得 AccessKeyID 和 AccessKeySecret,稍后在 WordPress 插件中 要填入这两项值。

3、使用 WordPress OSS 插件

我使用的是 aliyun-oss-support下载后通过 WordPress 后台上传安装。此插件的使用说明,请参见作者 Github 说明。

设置如上图,主要是填对 AccessKeyID 和 AccessKeySecret,如果 ECS 和 OSS 在一个区域,可以选中内网。另外就是选中「图片服务」。

至此,微软云香港区反向代理阿里云 SLB+ECS+RDS+OSS 就全部设置完成了,通过近两周的观察,网站的速度很快,稳定性也很好,偶尔会有延迟较高的时候,瓶颈就在于微软云香港机房的线路。但总体上要比原来好很多。