这是一个传统意义上的静态站点 , 简单 , 纯粹 , 一眼看得见底 。NetScaler 和 F5 是业界知名的硬件 , Windows 是天下闻名的软件 , 这样的强强联合 , 自然没有什么不好 , 只是稍贵罢了 。之所以 SLB(软件负载均衡)替代了NetScaler 和 F5 , 而服务端去 Windows 化也呈大势所趋 , 显现的软硬件成本只是一个因素 , 更重要的原因是虚拟化技术和弹性计算解决方案日益成熟 , 颠覆了原有的基础设施结构和运维模式 。

文章插图
实施迁移前的源服务架构
迁移势在必行 。
首节结尾已经明确 , 服务端采用什么样的技术 , 不影响静态资源服务的本质 。略为遗憾的是 , 此时我们依然将源站应用定位成静态 Web 应用 , 沿袭了中间件 + 本地文件系统的架构 , 只不过操作系统换成了 centos , 而中间件换成了 Nginx , 并按域名拆分成若干独立的应用 。从保证服务延续性和稳定性的角度来说无可厚非 , 但也就此错过了一次重构的契机 。

文章插图
实施迁移后的源服务架构
迁移中遇到的棘手问题之一 , 是 URL 的大小写兼容问题 。按照 RFC3986的描述 , URL 的路径部分应当是大小写敏感的 。然而 , Windows文件系统在缺省状态下是大小写不敏感的 , 结果就是 , 不管 HTTP 请求中的路径怎样颠倒大小 , 只要文件系统中存在不区分大小写的同名文件 , IIS 一概照单全收 。但是 linux 系统恰恰相反 , 不仅严格区分文名称中的大小写 , 而且允许大小写不同的同名文件并存 。延续过去的逻辑 , 且不说技术上的实现难度——请注意这是一个依赖本地文件系统的静态站点—— , 还会埋下引发歧义的隐患;若拒绝将错就错 , 又势必将导致大量 404 错误 。
进退两难间 , 我们不得不采取以空间换时间的办法 。在搬迁时 , 所有的文件一式两份 , 一份保持原有的大小写名称 , 放在常规目录下;另一份则采用全小写的名称 , 放在保底目录下 。通过 Nginx 的内部重定向 , 将路径大小写混淆的请求匹配至保底目录下的文件 , 以确保基于既有 URL 的请求仍可得到预期的响应内容 。保底目录中的文件不允许修改 , 也不作增删 , 希望随着静态资源的持续迭代 , 倒逼那些不规范的 URL 退出使用 。
上述策略即使在后来的重构中依然保留了下来 , 但它真的我们所能采取的最佳策略吗?也不尽然 。尽管事前作了充分的解释工作 , 依然有些开发人员不明就里 , 疑窦丛生 。“静态资源服务支持 URL 大小写混淆吗?”这个问题至今仍呆在我们的 FAQ 列表中 。

文章插图
实现 URL 大小写向后兼容的伪代码
大小写的混淆 , 并非是 URL 与文件系统映射关系问题的全部 。因为某种过于久远而不可考的原因 , 相当一部分文件路径中包含了特定的间缀 , 而这个间缀在 URL 中是不存在的 。为此 , IIS 中曾维护了大量的虚拟目录配置 。因为要与发布系统兼容的关系 , 服务迁移后 , 文件系统中必须继续保留这个间缀 。我们没有在 Nginx 配置中逐条堆砌 location 指令 , 而是通过正则匹配、文件探测和内部重定向等一系列指令的协作 , 解决了这一问题 。

文章插图
文件路径与资源路径不一定完全匹配
因为是静态 Web 应用 , 源服务端没有一行代码可供调遣 , Nginx 配置文件几乎是所能转圜的全部空间 , 我们也把这种以指令为核心的配置语言 , 当作一门领域脚本语言来学习和运用 。随着需求的累积 , 整个配置文件的有效行数达五百行之多 。
这一阶段 , 在携程的技术生态中 , 静态资源服务是一组非标准的 HTTP 应用 。它们在 Web 中间件之外没有一行服务端代码 , 同时又捆绑了大量资源文件 , 体型臃肿 , 根本没办法通过常规的应用发布系统对其进行全方位的管理 。为此 , 我们不得不基于 Ansible 建立了一个微型的服务器间协同系统 , 协调位于多个数据中心的数十台服务器 , 以应付诸如 Nginx 配置升级、资源文件批量管理、服务集群扩容等等任务 。
推荐阅读
- 一文理解HDFS
- 一文带你搞懂前端本地存储
- 一文带你了解不一样的SQL,惊喜多多
- iOS|iOS 16前的最后一个版本!iOS 15.5登场:一文了解详情
- 一文读懂Redis的dict字典数据结构
- 新疆维吾尔自治区|一文带你了解和田玉“前世今生”
- 为啥“不合格”却没有处罚 看懂路由器检测
- HDMI 2.0已淘汰!HDMI 2.1上位:一文看懂新接口优势
- 索尼|PS5存储扩容需要注意啥?一文读懂
- 一文读懂AI计算机视觉技术
