跳到主要内容

静态资源托管

将网站部署上线了,但我们此时仍然将静态资源部署在 Nginx 服务器目录下, 然后新的问题来了,随着时间推移,非覆盖部署导致文件逐渐增加多,硬盘逐渐吃紧

将文件存储在 Nginx Web 服务器内某目录下,导致 Nginx、网站、部署过程强耦合在一起,无法使用 CDN 技术。

如何将 CDN 与 Nginx 等 Web 服务器结合呢?

答案是将静态资源部署到 CDN 上,再将 Nginx 上的流量转发到 CDN 上,这种技术我们称之为『反向代理』。 此时,用户访问时流量走向 & 研发构建部署过程大致如下: 此时,我们总体部署方案需要进一步做三步改造。

三步

  1. 构建时依据环境变量,将 HTML 中的静态资源地址加上 CDN 域名。
  2. 构建完成后将静态资源上传到 CDN 。
  3. 配置 Nginx 的反向代理,将静态资源流量转发到 CDN。

其中,第 1、2 条涉及构建过程调整,以 Webpack 为例,我们需要做以下配置改造:

第一步:构建时静态资源进行分割和重命名

这里的资源在物理层面目录分隔,并以 Hash 做区分

  1. 配置 构建 output 的命名方式为 content-hash & publicPath 动态构造的 publicPath 里,严格的将产物按环境 + 发布版本做了隔离 & 收敛。 我们往往会将一套代码部署到多套前端环境,还需要在构建时注入当前部署相关环境变量(如 staging、prod、dev、pre 等),以便动态构建 publicPath
  2. 配置 Webpack-HTML-Plugin
// webpack.config.js
const CDN_HOST = process.env.CDN_HOST; // CDN 域名
const CDN_PATH = process.env.CDN_PATH; // CDN 路径
const ENV = process.env.ENV; // 当前的环境等等
const VERSION = process.env.VERSION; // 当前发布的版本

const getPublicPath = () => {
// Some code here
return `${CDN_HOST}/${CDN_PATH}/${ENV}/`; // 依据 ENV 等动态构造 publicPath
};

const publicPath =
process.env.NODE_ENV === "production" ? getPublicPath() : ".";

module.exports = {
output: {
filename: "bundle.[name][contenthash:8].js",
publicPath,
},
plugins: [new HtmlWebpackPlugin()],
};

关于 publicpath 字段 https://webpack.docschina.org/configuration/output/#outputpublicpath

第二步:构建完成后静态资源上传 CDN 源站

上传 CDN 源站往往通过 CLI 调用各种客户端工具上传,此时要注意的是上传 CDN 依赖配置鉴权信息(如 文件存储的 Bucket Name/accessKey、ftp 的账号密码)。这些鉴权信息不能直接写代码里,否则可能会有事故风险!

第三步: Nginx 层反向代理改造

反向代理(reverse proxy):是指以代理服务器来接受网络请求,并将请求转发给内部的服务器,并且将内部服务器的返回,就像是二房东一样。 一句话解释反向代理 & 正向代理:反向代理隐藏了真正的服务器(cdn 服务器),正向代理隐藏了真正的客户端。

Nginx 可通过设置 proxy_pass 配置代理转发,如

location ^~/static/ {
proxy_pass $cdn;
}

具体详见

https://www.jianshu.com/p/b010c9302cd0

总结

至此实现:静态资源隔离完后上传 cdn,nginx 将原资源 url 通过反向代理映射成 cdn 资源 url