2021年,该上云了。
Shiny目前只有一台主服务器+一台国内Websocket中继,主服务器上跑了一堆服务,感觉有点混乱。分析一下,其实很多服务可以上一下云,成本未必会增加多少。
目前优先度最高的需求是把Shiny-Map生成的图片对外暴露并备份。目前打算开一个队列,在生成图片之后将图片上传并向数据库写入图片地址。本文以这一需求为例写一个接入AWS的流水账。
这一套流程打算使用AWS SQS+S3+Cloudfront做,一是因为AWS的产品足够齐全,如果之后要全面上云也可以在生态内解决,二是因为AWS有新加坡可用区,而Shiny的主服务位于新加坡Vultr。
AWS SQS是一个队列服务,使用也比较简单,开一个队列往里写,再整个Consumer轮询队列处理任务就好了。价格方面前 100 万个请求免费,只收0.12USD/G的流量(单向),这个也是AWS服务流量的标准价了。
接下来写一个简单的队列Comsumer脚本。
首先在AWS IAM创建一个子用户,给予AmazonSQSFullAccess
权限,并开启编程访问以生成密钥对。
创建完毕后会给一个AccessKeyId和SecretAccessKey,需要立即保存,因为只会显示一次。
引入@aws-sdk/sqs-client
包,写一个简单的小程序。
消息处理完毕之后需要使用获得消息时拿到的ReceiptHandle
去把消息从队列中删除。
以上只是个小示例,实际使用时把这些方法做个封装。
接下来创建一个S3 Bucket,S3是AWS的对象存储服务,标准存储价格是0.025USD/G/月,还不算贵。此外考虑到生成后的图片访问次数不会很多,或许在后期可以考虑更便宜的归档存储。
aws-sdk封装的基本都一样,再写个上传图片的脚本,封装一下,得到了下面的结果
作为一个常驻后台的队列consumer,我们需要监控它的运行状态,我选择使用pm2进行调度和日志手机,使用sentry进行错误监控。pm2的使用比较简单就不多说了,sentry也只用引入sdk即可,非常方便。加上一些log和错误监控后我们的脚本变成了
那么上传部分就完成了,接下来需要将上传完成的图片暴露给公网,我选择了AWS的CDN服务Cloudfront。Cloudfront回源S3是不计S3流量的,而Cloudfront的价格平均比直接使用S3要便宜一些,那么……
创建一个Cloudfront分配,选择回源到S3 Bucket。这个时候遇到一个问题,AWS S3默认是不允许公开访问的,而我们希望这个桶能被Cloudfront访问。
这需要在创建Cloudfront回源目标的时候进行配置,按下图
这样会自动为S3桶生成一个访问策略,为原先的默认行为(全禁止)漏出一个口子。
这里吐槽一下,想把S3桶直接设置成公开访问异常繁琐,需要设置一堆东西然后手动写个存储桶策略,不知道那么多日本网站设置成公开访问然后被日穿得有多心大。
<未完待续>