关于 Nginx
Nginx 已诞生十余年,其作为一款开源的 Web 服务器软件,因其具有性能稳定、高并发、低内存耗用、高性能的处理能力等特点,被广泛应用到国内外各互联网厂商的实际生产架构中。其主要有如下场景应用:
- Web 服务应用,可实现静态资源、PHP、Python 等网站的架设
- 代理负载服务,支持 TCP/UDP、HTTP、HTTP/2、gRPC、FastCGI、SCGI、uWSGI 等协议的转发处理,并实现了相应通信协议的请求解析、长连接、代理转发、负载均衡、会话保持等互联网架构中常见的应用功能
- 缓存应用,基于其代理功能,实现正向或反向代理缓存功能
- API 网关应用,其提供了包括身份认证、路由转发、更基于支持 Lua 语言脚本模块扩展的可编程能力,使其可用于各种复杂环境的路由处理
Nginx 基于事件驱动架构,具有可支持数百万级别并发请求的处理能力,其通常被用于技术架构中的访问入口。近几年云计算、微服务、服务中台等架构及 DevOps 标准的快速发展,统一入口、智能路由、有效解耦、基础设施拆分等架构需求更使得 Nginx 被广泛应用其中。
Nginx 在 DevOps 中的应用
DevOps 已成为当前最流行的研发管理标准,其倡导的云计算、微服务曾被无数运维从业者视为洪水猛兽,认为是取代了运维的工作。然而当我们真正的理解云计算及微服务的架构时,也应深刻的认识到,这不是抢饭碗而是主动投喂。DevOps 标准也正在驱动我们运维工作者能更深入的参与到开发架构中,并与研发达成交织共存的状态。在我看来,这个纽带就是 Nginx。
1、业务架构中的应用
互联网产品的开发过程,都是先做一个当前需求的版本,然后再根据不断变更的需求,添加新的功能。这是非常符合现实的逻辑,但随着技术的迭代及业务需求的增加,也会给我们的工作带来诸多的挑战。比如,在某一功能比较少的时候,会由一个项目组去开发,由于业务的不断的发展,就会逐渐扩大到一个部门或事业部的人去共同协作开发。此时,原有的单体服务,就会面临因业务部门调整或业务产品的变化而进行拆分。
2015年我就遇到过这样的问题,商户服务曾是一个团队开发的,但由于业务部门拆分,就提出了部分分类商户独立开发的需求,如果拆分由开发完成,则会面临技术架构、技术栈迁移、业务开发成本增加等多方面的问题。基于实施的便捷性,所以我们运维就提供了一个基于 Nginx 实现动态路由的平滑拆分方案。访问架构如下所示:
该服务的URL只有域名和商户标识码(http://www.xxxxx.com/shop/111xxxxx),根据这个特点,我们设计了一个由 Nginx Lua Redis 构成的动态路由架构, 由 Nginx 做入口动态路由。为避免阻塞,所以我们本着最少路由判断逻辑的原则,将所有的商户标识码都以 Key 的形式存储在 Redis,每个 key 对应的 value 则是相应的被代理服务器组标识,当用户的访问进入 Nginx 后,由 lua 脚本快速的从 redis 中读取到对应的标识,并将用户的访问,路由到对应标识的被代理服务器组中。
开发同事开发了一个商户代码管理小工具,可以实现商户标识码的动态管理。这样我们就用很短的时间,将单一商户服务的代码按照业务的维度拆分成了商户、酒店、旅游、电影等多个服务,开发可以先将代码复制多套,再根据各自开发的进度进行逐商户或整体的进行替换。该方案在很短的时间内实现了服务拆分工作的实施,并为开发团队为日后商户服务的开发提供了更多的可能。
总之,无论是 Open API 、微服务亦或是中台架构,Nginx 总可以通过其强大的功能,为开发减负并实现架构变化的平滑过渡。通过 Nginx 做路由及数据处理可以灵活的解决开发架构多变的问题,并以不变应万变的能力,满足不同阶段开发架构的需求。
2、应急保障中的应用
在运维保障工作中,RTO(Recovery Time Objective,恢复时间目标)和 RPO(Recovery Point Objective,恢复点目标)是衡量运维保障工作的一个重要指标。RTO 指的是从业务故障发生到整个业务系统恢复所需的最大时长。而 RPO 则是指可能丢失数据的最大时长。这两个指标,都对运维架构的灾备、应急切换能力提出了严峻的挑战。
目前流行的做法是多活架构,但在实际实施中,多活架构投入成本高、实施周期长、对已有的技术架构变更的难度较大,且后期投入的维护工作也非常巨大。此时可以利用Nginx 设计一个动态降级的方案,对小规模且开发架构技术能力较低时期的应急保障工作起到有效的补充。该方案整体投入小,即可以快速实施落地,又可以在发生故障时实快速切换,并记录故障期间的用户变更数据的请求,最大化的避免数据的丢失。方案设计如下:
- 所有的静态资源交由 CDN 厂商提供访问服务
- 降级集群异地机房部署
- 正常访问时,Nginx 负载实时同步 GET 请求及响应结果到降级集群,降级集群的Nginx 将同步的数据处理后,存储到 Redis 集群中
- 当业务服务发生故障时,按照故障情况通过 DNS 或 Nginx 负载将用户访问切换到降级集群中
- 业务服务恢复后,通过 Nginx 负载逐步将用户访问切回
- 通过专用工具,将记录的 POST 数据中变更的数据恢复到数据库中
该方案只是个探讨模型,在实际实施中仍有诸多问题需要去考虑,例如:
- GET 方法的 URL 最小取值,以避免重复数据占用更多的存储空间
- 登录用户的处理及 GET 方法请求的个性化问题
- POST 方法数据与用户身份的绑定
- POST 记录数据的恢复准确性设计
- 访问切换的监控
- 前端用户的提示信息
3、运维的数据化运营
Nginx 通常被置于服务器访问的入口,其访问日志可以全局的记录用户访问的来源、响应时间、行为热点等数据,通过对访问日志的分析,可以清晰的了解用户来源、行为习惯及自身服务器性能等情况。借助 ELK 的高性能处理能力,可以实时的将数据分析结果展现给服务器的维护人员及应用的开发人员,进而不断提高业务的可用性及产品的用户体验。
对 Nginx 的日志可以从安全、性能、可用性及访问统计4个方面进行分类处理。安全方面的可以即时记录访问者IP,根据现阶段的实际情况进行人工或自动的屏蔽。性能方面可以结合基础资源监控分析原因并作出提前预判。可用性中若是业务设计方面的则可及时反馈给产品,以做出更友好的提示信息。访问统计方面的则可提供给相应的部门,进行进一步分析处理。运维的工作不仅是响应外部的需求,通过 Nginx 提供的强大功能,也可以主动的参与到企业的数据化运营工作中。
4、微服务中的 Nginx
微服务是 DevOps 水平的一个重要标志,微服务架构中的服务网格(Service Mesh)及serverless 的架构设计,其最大的理念就是将可复用的、基础的非业务功能从业务开发中剥离出来,例如服务发现、端到端认证、访问追踪、组件依赖等功能。在向服务网格迁移的过程中,Nginx 更是起到了重要的作用。
- 路由网格架构 ,这个架构是向服务网格过渡的初级架构,其无需对原有的单体应用和新的微服务应用做什么改造,可以很轻易的迁移进来,并为更复杂的改造积累经验。
- Sidecar 代理/Fabric 模型,该模型应用程序和代理被被放在了POD里,可以对应用程序的流量做更细粒度的控制。在该阶段可以自己开发控制平面,也可以选择直接切换到istio平台。
写在最后
2019年初,电影《流浪地球》让我们看到了中国科幻电影的希望,但导演郭帆则反复强调,“我们工业化不足的时候就是靠人肉填的,中国电影工业化还是处在一个非常早期的阶段”。这不禁让我想到了我从业的互联网行业,我们其实也一直是在一个非工业化环境中劳作着。工业化,自然是由自动化的“机器体系”来取代人肉的“手工劳动”,其生产过程中的每个阶段都必然是标准化、流程化的。当我看到由中国信息通信研究院牵头,联合云计算开源产业联盟、高效运维社区及国内多个互联网大厂编写的 DevOps 标准-研发运营一体化能力成熟度模型,并正式立项国际标准时,不禁尤感自豪,也深深对为推动我国互联网行业工业化进程努力的精英们深表敬佩。
作为互联网从业人员,也深刻认识到用好开源技术、推动工作内容标准化、流程化也是我们在互联网行业工业化进程中应尽的一份责任。
关于作者
王小东 ,资深运维专家,有十余年的互联网企业运维和架构经验,擅长服务器优化、大规模集群管理、开源工具应用和业务故障处理等。EXIN 认证 DevOps Master,专注于运维架构优化、自动化运维以及运维工作的 DevOps 治理。著有《Nginx应用与运维实战》一书。
《Nginx应用与运维实战》是一部基于 Nginx 新版本和云原生应用场景系统讲解Nginx的著作,是作者十余年运维经验的总结。从应用、运维以及与 Kubernetes 和微服务集成3个维度对 Nginx 的基础知识、工作原理、核心应用、运维管理、集成扩展等重点内容进行了全面、细致的讲解。完全以实战为导向,包含大量的配置案例和示例代码,能帮助读者快速掌握并在实际工作中熟练应用 Nginx。