Google Cloud CDN

Google 终于推出了自己的 CDN 服务了。去年 12 月份发布了 Alpha 版本,只接受申请试用;而这个月正式升级为 Beta,大伙都可以用了。于是我就又做了一回小白鼠。

之前一直在用 KeyCDN,但是 KeyCDN 的一个弱点是它依然使用 CNAME 来转发流量,而 CNAME 很容易被屏蔽。而 Google 的 CDN 用的是 AnyCast,只需要解析一次 DNS 即可访问,这可比 CNAME 要强壮多了。

除此之外,CDN 的抓取走的是 Google 的内部网络。这个网络有多快呢?据 Google 博客介绍,单机的网速可以达到 10Gb/s 以上。这样的 CDN 性能要远好于任何外部的 CDN。

于是我毫不犹豫地切换了过来。有兴趣的朋友可以对本站测个速。

把 Google Cloud Storage 加载到文件系统

主机移到 Google Cloud 之后,博客的图片都存放于 Google Cloud Storage (GCS) 中。

GCS 是一个独立的储存系统,可以通过 HTTP 访问,用来当作 CDN 使用。但问题是,GCS 无法绑定一个 SSL 的域名,HTTPS 访问成问题,并且经常被墙。于是我采用的方法是定期把 GCS 的文件用 GSUtil 同步到主机上,这个方法很灵活,不必开放整个 GCS 的 Bucket,而且可以限制文件一定要从博客中访问。唯一一点不爽的是,我设置的同步周期是五分钟,也就是在 GCS 上添加一个新文件之后,要等五分钟才可以从博客中看到,有时候等得比较累。而且我也不经常向 GCS 传文件,每五分钟都同步一下,80% 的同步是浪费掉的。

后来我就看到了 GCSFuse 这个工具。

Fuse (Filesystem in Userspace)是 Linux 中的一个概念,它向用户提供了一种虚拟磁盘的访问方式,即把一个不在本地的磁盘,当成本地磁盘一样来访问。这一技术经常被用来映射网络磁盘。

GCSFuse 是 Google Cloud 的一个 Fuse 实现,它可以把 GCS 的 Bucket 映射到本地,然后就可以通过文件系统的方式来访问 GCS 上的文件。

安装 GCSFuse 的方法用下(Ubuntu):

然后就可以通过以下命令行映射一个 Bucket(其中路径和 Bucket 名称按需修改):

GCSFuse 暂时还处于 Beta 状态,没有提供后台运行的方式,如果要在后台运行,还需要依赖 daemon 工具,完整的命令行大概是这个样子的:

这样运行了之后,/path/to/mount/point 就会成为 my-bucket 的映射,可以直接进行文件操作。其中 -o allow_other 表示允许所有用户访问,GCSFuse 默认只允许运行该命令行的用户访问映射的文件(比如 root),要给其它用户开放权限,我发现 -o allow_other 是最简简单的方法,另外你还可以通过 --uid $UID 和 --gid $GID 指定用户,但我尝试了没有成功。

daemon 不会在开机的时候自动运行,如果要在开机的时候就创建映射,需要添加一个 systemd 或者 upstart 的启动项,代码还在调试中,稍后放出。另外 GCSFuse 来提供了一种 mount 的方式加载,但我死活没有成功运行出来,还搞挂了主机,如果你成功了,请知会一声。

恢复 GCE 上无法启动的 Instance

两年前我搞坏过一台 EC2 的机器,而今天一早,我又搞坏了一台 GCE 的机器。这次的起因是 gcsfuse 和 fstab。

先吐槽一下 Ubuntu,在 fstab 加载不成功的时候,居然没有任何恢复的方法,它也不会自己把无法加载的项给禁用了。在 GCE 中,Ubuntu 的表现是无法连上 SSH,没有任何错误信息,连日志文件都看不到。

于是和上次一样,我能做的便是:

  1. 对当前磁盘创建一个 Snapshot;
  2. 创建一台新的临时机器,以 Additional Disk 的方式加载之前创建的 Snapshot;
  3. 修改磁盘上的内容;
  4. 删除临时机器,再创建一台新机器,以 Boot Disk 方式加载修复的磁盘。

GCE 上的 Addition Disk 会出现在 /dev/disk/by-id/ 下,可以使用以下命令查看:

我发现我的磁盘有两个分区,即:

  • /dev/disk/by-id/google-leonax-1
  • /dev/disk/by-id/google-leonax-1-part1

part1 中存放的是主要内容,通过下列命令把它加载出来:

然后在 /leonax-1 中修改相应文件即可。

顺便说一句,GCE 提供了一个 safe_format_and_mount 工具,不知道什么原因,这个工具在这种情况下没有效果,它不认为我的磁盘是一个有效磁盘,拒绝加载。于是我只好用了 Linux 自带的 mount。

在 Google Cloud 架设博客的费用

说说目前博客的费用,给想用 Google Cloud 的同学们一个参考。

Google Cloud 的计费方式和 AWS 有点不太一样,AWS 想要便宜,需要事先买一个套餐,套餐价比常规价格便宜,但必须用上个一年或三年,如果一年内终止使用,套餐的费用是不退的。之前发生过买了三年的套餐,结果 AWS 推出新机型并且降价了,导致老的套餐性能又差又不合算的局面。

而 Google Cloud 则没有这个限制,它只需要你使用一种机型达到一个月,即可以享受优惠价格,比 AWS 要灵活很多。刚搬过来的时候,进行过几次调整,导致没有用满完整的自然月,于是一直没法发这个统计,总算现在有完整一个月的纪录了。

总共使用 45.06 美元,包括三台主机,博客放在亚洲的主机,兼当 DNS 服务器,另外还有两台从属 DNS,分别在欧洲和美国地区。目前这样的配置应该超过90% 的博客了,所以新建博客的费用只会比这个少。

以下是明细,单位为美元,已减掉用满一个月带来的优惠:

  • 博客主机,总计 28.99
    • A(Small / 亚洲):17.29
    • B(Micro / 欧洲):6.11
    • C(Micro / 美国):5.59
  • 流量,总计(58.9 GB) 12.19
    • 中国地区(46 GB):10.63
    • 亚洲其它地区(5.5 GB):0.68
    • 欧洲地区(2.4 GB):0.28
    • 美国地区(5 GB):0.6
  • 硬盘,总计(30 GB)3.85
  • Google Cloud Storage,863 GB * 小时,0.03

需要指出的是,Small 主机的配置是 1.7G 内存,外加我用了 10G 的硬盘,这样的配置比大多数 VPS 是要好的,比如 Linode 和 Digital Ocean 上 2G 内存的 VPS 都要 20 美元一个月。

而这个月 Google Cloud 又进行了一次降价,降完之后应该属于超合算的云主机了。

使用 Google Compute Engine 的一个好处

Compute Engine 出了什么事情,Google 一搜就知道 -_-

今天一早,出门在外的时候,收到监控发来的邮件说博客无法访问了。回到家登到 Cloud Console 上看了一下,没有发现明显的问题,然后重启了机器,于是博客又重新可以访问了。百思不得其解的时候,猜测是 Compute Engine 本身的问题,于是就 Google 了一下,没想到第一条就是 Compute Engine 的事故通报,如下图。

Google Compute Engine Incident #15045

  • 太平洋时间 19 日凌晨 00:30:多个数据中心出现网络问题,目前还在修理过程中。
  • 太平洋时间 19 日凌晨 01:30:故障已修复。

虽然 Compute Engine 出了故障,但 Google 搜索的优势还是非常强大的。

Google Cloud 对国内用户的友好度

由于众所周知的原因,Google 的服务对于国内用户不太友好。,于是很多博主也不太敢把博客放在 Google Cloud 上面。作为喜欢吃螃蟹的博主,我来分享一下 Google Cloud 的友好程度。

本博客放在台湾的数据中心,。以下测试结果来自奇云测。

目标地址 HTTP://leonax.net,总共 79 个监测点,16.5% 的监测点无法访问本站:

  • 电信(42 个监测点):有 4 个监测点(9.5%)无法访问本站,现象都是可以获取 IP,但 HTTP 访问失败。
  • 电信通(4 个监测点):全部通过测试。
  • 教育网(1 个监测点):全部(100%)未通过测试,可以获取 IP,但 HTTP 访问失败。
  • 联通(20 个监测点):有 1 个监测点(5%)无法访问本站,可以获取 IP,但 HTTP 访问失败。
  • 鹏博士(1 个监测点):全部通过测试。
  • 移动(7 个监测点):全部(100%)未通过测试,可以获取 IP,但 HTTP 访问失败。

目标地址 HTTPS://leonax.net总共 79 个监测点,15.2% 的监测点无法访问本站:

  • 电信(42 个监测点):有 8 个监测点(19%)无法访问本站,其中江西省新余市电信把 IP 解析到了 218.87.109.64,其它地区都可以解析到正确的 IP,但 HTTP 访问失败。
  • 电信通(4 个监测点):有 2 个监测点(50%)无法访问本站,可以获取 IP,但 HTTP 访问失败。
  • 教育网(1 个监测点):全部(100%)未通过测试,可以获取 IP,但 HTTP 访问失败。
  • 联通(20 个监测点):有 1 个监测点(5%)无法访问本站,为哈尔滨市联通,把 IP 解析到了 220.181.179.8。
  • 鹏博士(1 个监测点):全部通过测试。
  • 移动(7 个监测点):全部通过测试。

总体而言,不同的地区的网络提供商(ISP)有不同的限制,全国大约有一七分之一的用户无法正常访问本站。如果您发现本站的打开速度有问题,也请留言,并注明您的 ISP。

在 Compute Engine 中创建 Cloud Storage 的镜像

Compute Engine 中的主机访问 Cloud Storage,是一个常见用法。比如我把博客的图片都放在 Cloud Storage 中,然后在博客中直接引用。于是我只能做了一个反向代理,从 //leonax.net/images/ 来访问那些图片。

实践中发现,Apache 的反向代理不太稳定,有时候等了超过一分钟还没有把图片下载完。其实我的那些图片,基本上是不变的,不论下载多少次,都是同样的图。那为何不做了一个本地的镜像呢?调查了一下,做镜像有两种方法:一是通过一个名为 S3FS 的工具。它原本是为 AWS 的 S3 制作的,可以在 EC2 的主机上创建一个磁盘,磁盘的内容即为 S3 中储存的文件。由于 Cloud Storage 提供了仿 S3 的 API,S3FS 也与 Compute Engine 兼容。二是使用 Cloud Storage 的原生 API,它提供了类似 Linux 中的 rsync 功能,可以把 Cloud Storage 的内容同步到本地。

我选了后一种,因为它是原生的,并且我也只需要单向同步。

Cloud Storage 提供了一个工具 gsutil,它有一个指令就是 rsync。使用如下命令可以把容器(bucket)“leonax”同步到本地的 /var/www/images/ 文件夹中。

其中 -m 表示多线程运行,提升效率;-d 表示删除本地多余的文件;-r 表示递归执行,复制全部的子文件夹。如果你想要不间断地同步,可以把上述命令添加到 crontab 中。

如果在同步的过程中需要权限问题,比如“403 Access Denied”,请确保 Cloud Storage 中的帐号设置正确。

首先,在创建 Compute Engine 主机的时候,需要在高级设置(Advanced Options)中开启 Service Account,并允许 Storage 访问,如下图:

然后使用如下命令找到那个 Service Account(形如 xxxxxxx@project.gserviceaccount.com):

最后允许这个 Service Account 访问 Cloud Storage 的现有文件:

以及后续上传的所有文件:

之后要做的事情,就是修改 Apache 的配置,把反向代理改成访问本地的文件即可。