薅羊毛党的胜利——合理利用腾讯云搭建服务

TL;DR

腾讯云因为低廉的价格和稳定的服务,以及各种优惠政策,一直被戏称为良心云。对于一些用户量不大、对保密性要求不是特别高的服务,如果充分利用腾讯云的各种优惠,几乎可以零成本搭建。要知道在内网搭建一个服务现在非常多复杂(申请资源、审批权限等等),而且还面临各种限制,运维方面费时费力,所以把服务搬到云上不失为一个好的解决方案。

腾讯云常用免费套餐

  1. 对象存储服务 —— 高可用、可靠、可扩展的对象存储。免费额度:每月50GB存储空间,免费流量共20G及读写请求数量共110万次
  2. 内容分发网络CDN —— 将源站内容分发至最接近用户的节点,有效降低访问时延。免费额度:每月10G免费流量,新用户更有连续6个月50GB免费流量
  3. SSL证书 —— 腾讯云 SSL证书(SSL Certificates)提供了安全套接层(SSL)证书的一站式服务,包括证书申请、管理及部署功能,与顶级的数字证书授权(CA)机构和代理商合作,为您的网站、移动应用提供 HTTPS 解决方案。免费额度:同一主域最多只能申请20张亚洲诚信品牌免费型DV版SSL证书
  4. 无服务器云函数 —— 自动、弹性、无需服务器管理的代码运行环境。免费额度:每月100万次调用,40万GBs 资源使用
  5. 网站安全基础防护 —— 抵御2G DDos攻击的免费服务,实时检测,业界领先!免费使用
  6. 云解析 —— 安全、稳定、快速的免费域名解析服务。免费额度:提供免费版云解析
  7. 云拨测 —— 基于全球服务质量监测网络,助力保障网站、域名、后台接口服务质量。免费使用
  8. 云监控 —— 多维度立体化云产品监控,智能化数据分析,定制化告警触达。免费使用

万象优图 —— 腾讯云为客户提供的专业一体化的图片解决方案,涵盖图片上传、下载、存储、处理、识别等功能,将 QQ 空间相册积累的十年图片服务运作经验开放给开发者。目前有图片处理、原图保护、跨域访问设置、样式预设等功能。
经工单咨询确认,万象优图依赖对象存储服务,但两者的免费额度分别计算。例如,COS的外网下行流量免费额度是10GB,万象优图的外网下行流量免费额度也是10GB。所以我可以先用COS的10个G,当检测到流量用尽时,切换到万象优图继续使用。

开发技术栈介绍

最近接到一个需求,关于某APP的push监控。需要实现:

  • 通过脚本自动化实现,对于PUSH消息的测试
  • 将测试结果通过web页面展示出来

自动化部分,根据实际情况,采用的是 python3 + uiautomator2
对于web部分,使用的是python3 + Django2 + material-dashboard-html-v2.1.0 + MySQL 5.6(腾讯云),部署时用到了nginx 1.15.0(自己编译,加入TLS1.3支持等) + uwsgi + supervisor。https证书:主站——Let’s Encrypt,CDN——腾讯云。

IDE使用Pycharm。

本地开发

目前自动化脚本是需要手动触发执行和上传结果的,之后还会继续优化。
web的开发,Django作为成熟的解决方案已经足够好了,要注意的就是各种安全方面的配置,严格按照文档来进行即可。对于一些敏感数据,如数据库账号密码等,我采取的措施是放在.env文件,然后把.env文件排除在git之外。这样还有一个好处:对于腾讯云的数据库不同环境使用不同配置,本地开发时使用外网端口(在腾讯云的防火墙只开通公司IP的访问权限),生产环境时配置为内网端口,保护数据库安全。
Pycharm作为最流行的IDE之一,除了开发调试的一些基本功能,database和Deployment功能十分强大,配置好以后提高效率很明显,强烈推荐。

上云之前的方案选择

对于测试结果,没有直接存储在服务器的硬盘中,而是采用了数据库(MySQL)和对象存储(COS)两部分。如果都存在单台服务器,对服务器的内存、硬盘和带宽(重要:带宽很贵!)都有一定的要求,不仅是成本,对于后续运维也是一个不小的挑战。如果分开使用腾讯云的各种基础服务,一方面可以利用各种免费额度降低成本,另一方面可以随时根据需要对各服务升降配/扩容,灵活性更高。

根据对数据访问频率的不同,分别存放到数据库和对象存储,各服务间是通过内网访问的,速度也可以接受。

结果存储——对象存储(COS)与万象优图

腾讯云对象存储(COS)的使用

基本概念

  • 存储桶 —— 即 Bucket ,在 COS 中用于存储对象。简单理解为文件夹或者本地的一块硬盘
  • 对象 —— 即 Object,COS 中存储的基本单元。
  • 地域 —— 即 Region,表示 COS 的数据中心所在的地域。根据地域选择,因为我的云服务器可用区是上海二区,根据就近原则这里选的是上海
  • APPID —— 腾讯云账户的账户标识之一,用于关联云资源。在用户成功申请腾讯云账户后,系统自动为用户分配一个 APPID。
  • API 密钥 —— 用户访问腾讯云 API 进行身份验证时需要用到的安全凭证,由 SecretId 和 SecretKey 一起组成。
  • 默认访问地址 —— 由存储桶名、COS 所属地标识和对象名组成,通过默认访问地址可寻址 COS 中唯一对应的对象。
  • CDN 加速访问地址 —— 由存储桶名、CDN 加速标识以及对象名组成,通过该地址可寻址 COS 中唯一对应的对象。在用户上传对象并且开启 CDN 加速后,腾讯云会自动为对象创建 CDN 加速访问地址。
  • 自定义域名 —— 用户在托管网站时,根据需要,会更倾向于类似www.example.com的域名, 而不希望类似example-1234567890.cosgz.myqcloud.com等域名显示在网站或服务上。用户可以通过 COS 控制台为存储桶绑定自定义域名,绑定后可通过自定义域名直接访问存储桶。绑定自定义域名时,需要通过 CDN 控制台创建 CNAME 记录将 www.example.com映射到 example-1234567890.cosgz.myqcloud.com

COS有V4、v5两个版本,两个不同的版本,API不同,这点需要注意!!!目前新用户注册一般是v5(如果不是可以开工单申请升级到v5,因为v4的sdk不支持python3)。

权限与安全

Bucket 和 Object 的权限可以设置为:私有读写、公有读私有写、公有读写,Object 默认继承 Bucket 的权限。

最开始的想法,为了安全肯定是设置私有读写(必须带签名才能访问),然后每次访问的时候通过SDK计算出签名再生成页面。但是这里如果想使用自定义域名或CDN,就遇上了个大坑,因为sdk中计算签名的接口写死了只支持默认访问地址。而签名的时候是把域名也算进去的,也就是说计算出签名以后,修改域名为自定义域名,签名失效会导致最终该资源无法访问。

PS:这里起初因为搞不清默认访问地址、CDN和自定义域名如何设置,开工单咨询几次也没解决,所以把这个问题绕过去了。现在想想其实可以根据签名算法自己实现来解决(当然了,有点麻烦)

最后,针对当前项目做了一番评估,通过修改权限为公有读私有写开启Referer防盗链结合,勉强算是解决了这个问题。

默认访问地址、CDN和自定义域名

理想情况下,我的期望是使用自定义域名并开启CDN。但是如果打开控制台就会发现,这里系统还分配了默认CDN加速域名。所以,我的自定义域名到底是绑在COS上,还是去CDN控制台绑定到默认CDN加速域名,文档中没有明确指引。

这里开了N多工单,最后还是自己一番摸索才找到解决方案:

  1. 关闭默认CDN加速域名(COS和CDN控制台都要关闭,正常情况这两个状态是同步的)
  2. 在COS控制台绑定自定义域名,并且绑定时开启CDN,等待CDN部署完成
  3. 在DNS服务商处,添加CNAME。CNAME的值,如果COS中看不到,可以到CDN控制台去查看

附上一张图片供参考:

开启HTTPS

如果是使用的默认CDN加速域名,CDN控制台中可以看到,HTTPS证书已经自动颁发和配置了,这一节可以略过。
但是如果是想对自定义域名开启HTTPS,那就必须得手动申请证书了。

申请HTTPS证书有三种方式:

  1. 腾讯云免费证书 —— 免费但有数量限制,但与腾讯云各产品已经打通,可以一键部署。
  2. 其它服务商申请免费证书 —— 免费,数量限制未知,但是部署时需要手动上传。
  3. Let’s Encrypt —— 免费,3个月过期但有自动续期脚本,部署到云需要手动上传。

按我个人来讲,Let’s Encrypt一般都是作为首选(可以颁发通配符证书、对各种HTTPS特性支持最好、可以自动续期)。主站服务器上使用问题不大,但是在CDN等产品上使用,续期的时候还需要手动上传就有点麻烦了,所以还是使用了腾讯云的免费证书。

这里先去SSL证书管理的控制台,新购一张免费证书。验证方式,选择DNS(因为此时还没部署服务器,不能使用file验证),然后按照指引马上去DNS服务商处添加TXT记录,并且把TTL设置的尽量短。为什么说马上,因为根据我的经验,添加TXT记录能赶上证书机构第一轮验证DNS的话,可以在5~10分钟内成功颁发;但是如果慢了,就只能保证24小时内颁发。—— 这条经验,后面证书续期的时候有用。

注意:CNAME记录和TXT记录一般是不能同时设置的,所以临时删除CNAME记录,证书颁发后再改回来。

证书颁发成功后,再去CDN控制台开启HTTPS,证书选择自有的,就能在列表中直接选择并部署了。

HTTP/2 能有效提高网站的访问速度。而常见浏览器和客户端的HTTP/2实现都依赖HTTPS。也就是说,要使用HTTP/2就必须配置HTTPS。

文件上传与下载

文件上传有两种方式:命令行工具和SDK。命令行工具可以直接上传整个文件夹,通过SDK的话得自己遍历文件上传。具体的差别就是,命令行工具上传不会对比文件,每次都是全量上传,不但费流量,还会导致文件的创建/修改时间发生变化;如果使用sdk,可以通过head_object接口(也就是HTTP HEAD请求)来和本地文件比对,实现“增量上传”,可以有效节省时间和带宽。

至于下载(也就是文件对应URL的生成),私有读写的问题前面已经提过了。如果是公有读 + 自定义域名的情况,使用list_objects接口获取到Key(也就是文件的相对路径),再和域名手动拼接即可。

list_objects接口有个Prefix参数,可以指定路径实现部分遍历。

万象优图

万象优图本身依赖对象存储,对于已经存在的Bucket直接绑定即可使用。

万象优图的主要使用场景是图片的处理,所以非图片类型的文件建议还是通过COS来访问。
万象优图只提供API,未提供SDK,所以图片的上传依然使用COS的SDK和配置即可,内部是互通的。

默认访问地址、CDN、自定义域名和HTTPS

参考COS即可,唯一需要注意的是自定义域名(和HTTPS证书)要再分配一个,不能与COS相同。
即为COS配置自定义域名:static.xxx.com,为万象优图配置域名:img.xxx.com

图片处理&样式

万象优图核心能力是图片处理,而图片处理是根据你提供的样式来执行的。
样式的设置有两种方式:通过控制台预定义样式名和通过API传递参数。

通过控制台预定义样式名,好处是操作便捷(通过鼠标点点点,而且还能实时预览),并且因为是通过别名来使用,更安全(参数都被隐藏起来,并且可以开启原图保护);缺点就是生效慢,最长遇到过将近半个小时才可用。
通过API,优点是能够实时生效,而且参数通过代码控制灵活性高;缺点就是不能开启原图保护,并且基于管道操作符复合使用多个API时也会导致URL太长的问题。

小提示: 如果是通过样式名的方式使用,建议样式名命名时以图片文件扩展名结尾(例如w320.png,h480.webp),并且样式分隔符使用中划线和下划线。否则,浏览器或代码中解析URL中的文件名容易出问题。
重要:webp格式非常小,但是兼容性比较差,像Safari、iOS一般都不支持,Chrome和Android则支持的比较好。可以通过UA判断来源,然后返回不同格式的链接。

结果存储——关系型数据库MySQL

数据库的配置,都是属于基本操作。这里列一些可能遇到的问题:

  • 数据库根据需求选配,为了保证速度,尽量与服务器在同一可用区
  • 正常情况下数据库是可以在控制台随时升降配的,但是活动促销产品可能不支持调整配置,购买时要注意
  • 为了调试方便,数据库可以开外网访问,开通时已自动分配域名和修改默认端口。但是要限制访问(创建账号时可以指定IP),注意公司有联通和电信两个固定IP的出口,都加上即可
  • 创建账号后如果遇到没有权限访问,控制台-数据库管理-账号管理-修改权限,可能是对象级特权没有分配
  • 如果想使用UTF-8编码,MySQL中的字符集要配置为UTF8MB4,而不是utf8。出处:《记住,永远不要在MySQL中使用“utf8”编码》
  • Django使用的MySQL驱动有点问题,我用的是pymysql(当前版本0.8.1)。在settings.py所在路径下的__init__.py文件中,插入如下代码即可:
1
2
import pymysql
pymysql.install_as_MySQLdb()

最后再强调一遍,MySQL的配置放在单独的文件中(此文件不要加入版本控制)。在本地开发时使用外网端口和地址,生产环境使用内网端口和地址。

部署云服务器

选购

腾讯云活动很多的,像最低配的1C1G1M的服务器,经常是600元/3年,合理搭配CDN和云数据库,搭个小网站没什么问题。如果性能不够用了,也可以单独调整CPU、内存或带宽。

一定要注意,如果是促销活动购买的,要仔细阅读活动说明,可能有限制条件。

安全

装系统以后,创建用户,改SSH端口,(通过控制台)配置SSH密钥,限制登录。配置安全组(即防火墙)。用好云硬盘快照和系统镜像,勤做备份。
对于一些基础的安全配置,腾讯云的官方文档都有最佳实践了,照做即可。

部署代码

服务器怎么装python3,Django2部署时的checklist,uwsgi和supervisor怎么配置,网上教程很多,我就不再赘述。

这里还是重点提一下nginx和https。如果是部署在内网,不存在劫持,没有各种安全问题,为了简单起见一般都不需要优化nginx和配置https。但是即然服务放在外网就不一样了,这些工作非常有必要!!!

Chrome 65 开始会默认开启并使用 TLSv1.3 Draft 23, 从 Chrome 68 开始支持 Draft 28

关于nginx,我参考了这篇文章《给 Nginx 添加 TLS1.3 支持 Love4Taylor’s Blog》,主要的特性有:

  • SPDY 补丁
  • HTTP2 HPACK 补丁
  • Dynamic TLS Record 补丁
  • PRIORITIZE_CHACHA 补丁
  • Fix Http2 Push Error 补丁
  • TLS1.3 Draft 23,26,28 补丁
  • Brotli

安全原因,我这里就不放具体的配置了。可以参考Jerry Qu的《本博客 Nginx 配置之完整篇》

PS:随着NGINX的更新和Let’s Encrypt的产品迭代,这里个别配置已经过时了,主要还是学习思路。
另外关于HTTPS的方方面面,Jerry Qu的博客作为启蒙教程真的非常不错。

对于HTTPS和提升网站安全,这里强烈推荐两篇文章:

附上本系统的 SSL Labs 评分(还在继续优化中):

其它

除了前面提到那些,目前还需要用到的腾讯云解决方案有:

  • 云拨测
  • 云监控
  • 大禹网络安全(DDos攻击和CC攻击防护)
  • 云API密钥
  • 域名注册
  • 云解析
  • 网站备案

这些产品基本照着文档做就可以了,有不明白的开工单,解答的迅速而且专业。

总结

最后再来说说成本问题。
目前云服务器,华东区1C1G1M,三年的费用是1386元;云数据库MySQL5.6最低配,三年的费用是1296元。
平均一年894元,这还是不参加任何活动的情况。像我去年双十一买的,不是最低配,云服务器+数据库八年左右加一起连500都不到。
这个成本,远低于我们用办公电脑搭的服务,并且用户体验是远超之前的。

所以,腾讯云这个羊毛,值得薅!