近期上线一个小项目,一个典型的前后端分离项目(Vue2+SpringBoot),通过阿里云效,完成了一个简单的前后端构建,镜像打包、上传、部署的 CICD 全流程,并通过 OSS(对象存储)+DCDN(全站加速)实现前端单页应用的部署。花费比想象中要低,本文将介绍整个缘由、过程与遇到的坑。
1M 小水管遇上“现代前端”
先说明一下为什么需要将前端部署到 OSS 并通过 CDN 进行加速。
其实一开始笔者也是很正常的使用:
1.
yarn build
前端打包2.
docker build
构建 Nginx 镜像3.
docker compose up -d
直接在 ECS 服务器上启动运行。
但作为带宽仅 1M 的廉价 ECS 服务器,遇到了一个用于快速开发的大而全的“现代前端”框架,只能说相当臃肿,在没有开启 Gzip 的情况下,居然首次加载需要下载10M左右的静态文件,页面要加载整整2 分钟。
并且每次重新 Build 上传之后,巨大的 JS 文件也需要重新下载。笔者也实在是前端苦手,当前这个项目被选择了 Vue2+WebPack。我简单搜索了一下如何做依赖升级、懒加载后,不久便放弃从这里下手了。不想更多的了解这个“快速开发”框架了。
缕清思路
随后了解到可以
1. 打包后的文件上传到 OSS(对象存储),并通过开通 OSS 的
静态网站托管功能
,就可以通过 Bucket 的域名进行网站的访问。2. 再将自己的域名添加 CNAME 记录,可以通过自定义域名实现 OSS 静态网站的访问。
至此,对于我这种轻度使用,其实已经是“能用”的水平了。之后的支出主要是存储的支出和流量费用的支出。其中前者是有补贴,40G 一年只需要 9 块钱。后者不是很清楚,用了几百兆似乎都还没产生费用。
但来都来了,还是尽量实践一下最佳实践吧。CDN 即内容分发网络
,属于是存在多年的概念了,要做加速,还是得靠 CDN 嘛,阿里云的 DCDN 服务,支持将回源地址直接设置为 OSS 的 Bucket,在 OSS 中的资源更新时刷新缓存。
并且 DCDN 对于流量加速包也是有优惠的,在我看来有羊毛可以薅的,都可以拿来玩一玩。(虽然后面发现这里有坑,见下文的动态加速)
并且通过 DCDN 实现静态资源分发
,应该是比直接访问某个特定区域的 OSS 来的经济实惠,效果也理应更好的。
最终效果
开启了全站加速的 Https+HTTP2+Brotli 压缩(类似于 Gzip 压缩)+页面优化(删除注释、空白字符等)。
访问效果如下:
提升真的过于明显了..由 2 分钟降为了 2 秒钟,我甚至都怀疑我是不是动了什么打包配置,这是多少倍的提升..Emmmm,整整 60 倍的提升..
当然这里有很多因素,如Brotli压缩
之类的通过 Nginx 等中间件当然也是可以实现的,只不过确实不如点一下按钮就开启来得方便。什么叫SaaS化
呀(后仰)
OSS 配置
1. 创建 Bucket
这里应该创建一个标准存储的 Bucket,读写权限设置为私有
和公有读
都行。但前者有一点点小坑,见下文的私有 Bucket。
2. 上传打包后的资源文件
我这里是直接通过云效,进行打包并上传到 OSS 的工作。
其中我将后端接口在 ECS 通过 nginx 反代出来并单独搞了一个域名,配置在.env
中,让前端进行调用。
3.配置静态网站托管
如果将 Bucket 设为公有读,则代表若我们开启了 OSS 的静态网站托管功能
,就可以直接通过 bucket 的域名直接访问网站了。
对于 SPA(单页应用),配置应该如下:
即将默认的 404 页面也指向了 index.html,并且返回码也改为了 200。全部交由“现代前端”来处理。
而 Bucket 若不开启公有读
的话,这个配置可以不用设置。
4.配置域名
Bucket 配置 -> 域名管理 中可以绑定自定义域名。
通过修改域名的 CNAME 记录,将域名指向 Bucket 的域名或者是 CDN 的域名。
虽然使用 CDN 的情况下,可以直接在 CDN 管理页面配置,但建议要在这里配置一下,主要是可以使用到一个“Webhook”功能,即 CDN 缓存自动刷新。
有了这个功能,我认为就可以将 CDN 的文件过期时间设为最长,通过 OSS 的事件机制主动更新 CDN 缓存,以达到效率、成本最优。
全站加速配置
1. 添加域名配置源站信息
在全站加速 DCDN 的管理页面,配置自己的域名,并将 OSS 的 Bucket 域名设置为源站。随后在自己的域名提供商的管理后台,增加一条 CNAME 的记录将其指向 CDN 的加速域名即可。
2. 配置 HTTPS
虽然 HTTPS 居然会根据请求数量单独计费,但 2023 年了,公网的网站不开 Https 属实是说不过去的,并且还可以享受到 Http2 的好处。
Https 的证书可以通过 ACME 进行免费证书的自动申请和续期。
开通 HTTPS 之后就可以开通:
1. HTTP/2
2. OCSP Stapling
3. HTTP -> HTTPS
4. TLSv1.2 & TLSv1.3
5. HSTS
3. 性能优化+WAF 等其他配置
Brotli 压缩 √ 建议开启~
页面优化 √ (删除页面冗余内容如 HTML 页面、内嵌 Javascript 和 CSS 中的注释以及重复的空白符)
WAF √ 有一个 0 元购套餐,不薅白不薅。虽然也就拦截一些僵尸网络扫描,但也很好啦。
缓存过期时间 因为我开启了 OSS 后台的 CDN 缓存自动刷新功能,这里我就设置了/目录的最长的 3 年过期时间。
Ipv6 随意啦
其他的一些配置:
Quic 可以理解为 Http3 ,底层使用了 UDP 协议,但会产生额外的费用,可以不用开。
Websocket × 没用到的话,不建议开启。
Referer 防盗链 × 如果不是图站的话,可以不用开启。
动静态加速规则 × 纯静态站别开,会产生没有必要的费用,下面会详说。
踩坑之路
私有 Bucket
CDN 的私有 Bucket 回源功能和 OSS 静态网站托管功能的默认首页配置冲突。可能会出现各种奇怪的 403、404 报错。
详见 开启私有 OSS Bucket 回源后,访问域名提示“You are forbidden to list buckets”错误
我略有不同的解决方案是:
增加一条重写规则为:待重写 URI 为^/$
,目标 URI 为/index
,执行规则选择 Redirect
注意,我这里没有配置为文档中所说的 index.html。如果配置为 index.html,我这边的“现代前端”会认为是 404 请求。这里我也不是很懂,可能和 Vue 的 Hash、History 的匹配规则有关。
动态加速
使用上述配置用了一天之后,突然发现一天就扣了我整整 0.49 元,经过各种审计日志翻查,甚至找无用的售后对峙,最终发现大头来自于一个叫做动态请求数(Http+Https)的扣费。
但这个名字真的就很让人困惑,我一个纯静态的网站,所有的后端接口指向了另一个域名,何来的动态请求呢?
经过认真的翻找,终于发现,我开启了动态加速,但是却没有配置任何的静态文件类型、路径、URI。
很坑的在于,他也没有默认配置。
什么意思呢?开启动态加速后,他会认为你的源站即有动态请求,也有静态文件。但动态请求,CDN 怎么能加速呢,我的理解是,他会用一个离源站比较近、比较快的服务器去转发动态请求,再返回给浏览器。甚至还可以开启回源的负载均衡。
他没有默认配置,而我又打开了这个动态加速开关,他就认为我的所有请求,哪怕是请求 Html、 CSS,也是动态请求,相当于缓存全部失效了...还产生了很多费用..emmm。
注意同区域
算是一个小 Tips,阿里云同区域内网之间,拉取 OSS 等操作,相当于是内网传输,没有产生公网流量,所以既可以保证更好的效能,还可以避免多花冤枉钱。嗯,选择区域时,尽可能都选同一个就是了。
云效实践
对于这种小项目,我曾经干过把 Jetbrains 的 TeamCity 安装到 ECS 中,来做 CICD 的事情。发现实际的业务程序占的 CPU 和内存都远远不足 TeamCity。
SaaS 化好呀,阿里的云效基本上还处于推广阶段,很多福利,基本看不到什么收费项。可以非常方便的搭建出一套 CICD 流水线,使用体验比 GitlabCi 要好上不少,Jenkins 就更不用说了。
我说一句暴论,只用 Jenkins 做 CICD 的,还不配叫做 DevOps。
搭建流水线
首先把代码仓库传到云效上,配置一个 SSH key 就好了,比较简单,这里略过。
流水线配置有非常多的模板,只需要填写参数即可。稍微需要注意的是,各种构建环境只提供了最常用的几个镜像,如果需要使用自定义镜像,拉取速度可能会比较慢。
官方建议是可以先 push 到自己的仓库中,但这也是我不爽的一个点,这样不就无法总是使用最新的上游镜像 Tag 了吗。
我这里就忽略了扫描、测试等阶段,主要是构建、上传和部署。
java 构建
没什么好说的,
1. 选择好参数,执行
maven package
。2. 然后配置好正确的打包路径将其上传到公共存储空间
3. 使用代码仓库里的 Dockerfile,打包镜像并推送。
前端构建
1. 使用 node:16 的自定义镜像执行
yarn build:prod
2. 上传 dist 文件夹到公共存储空间
3. 删除 OSS 根目录的所有文件(没有 sync 功能差评,明明 ossutils 是有这个功能的)
4. 上传 OSS 到 Bucket 根目录。
部署
前端的部署,OSS 更新后会自动通知 CDN 更新的,无需操心。
后端的部署,绑定主机后,执行一下docker compose up -d
就完事了。(没有 docker-compose.yml?那就不是本文的重点了 hhhh)
结语
后续我甚至还开通了云监控,对后端接口做了一些简单的 HealthCheck,ECS 机器的监控、并设置报警规则,确实简单易用。
然后做了一个主机的定时任务,将数据库备份到 OSS 的低频访问存储中。后面我发现,可以将 OSS 挂载为磁盘,将数据目录直接扔到 OSS 上就好了,即避免了 ECS 磁盘不够用的情况,也可以开启定时备份或版本管理之类的功能。但我为了避免额外的费用,并没有开启。嗯..
还有各类中间件日志的统一收集处理。
OSS、DCDN、云效以及以上的这些服务轻度使用,确实不会产生多高的费用,但实打实的享受到了 SaaS 化所带来的的便利。
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...