在 20 世纪 60 年代和 70 年代, monolithic architecture 因为计算资源有限,开发人员需要把所有功能集成到一个统一的单体应用中,所以这种架构很受欢迎。
直到90年代末和2000年代,单体架构开始显得力不从心。应用规模和复杂度不断增长,互联网和分布式系统的兴起更是加剧了这一问题。
这促使了更加模块化方案的发展,例如 面向服务的架构(SOA) and, later, 微服务架构(MSA),在2010年代初期逐渐崭露头角。
不过,这只是对微服务的基本概念和用法的简单介绍。接下来我们会讨论微服务如何取代单体架构、微服务的工作原理,以及一些微服务的实际例子。然后我们会深入讲解微服务部署的关键要素,以及如果你想要部署微服务的话应该如何做。
什么是微服务?它们如何运作?
正如我之前提到的,微服务应运而生,解决了应用程序日益增长的复杂性和规模问题,让企业能够将功能拆分为可独立部署的服务。
"微服务"这个术语由Martin Fowler和James Lewis等行业专家推广开来。他们在2014年的一篇博客文章中正式介绍了这一概念。他们的工作定义了关键原则和特征,包括服务独立可部署、数据管理去中心化,以及技术中立性。
从那时起,微服务已成为主流的架构选择,得到了以下技术进步的支持 容器化技术(如 Docker)、编排工具(如 Kubernetes)和无服务器计算平台的支持。但微服务是如何工作的呢?
微服务如何工作?
微服务架构的核心是将大型应用程序分解为较小的独立服务,每个服务负责特定的业务功能。这些服务通过网络相互通信,通常采用 REST API、gRPC 或消息代理(如 RabbitMQ 或 Apache Kafka)。
根据 Martin Fowler 和 James Lewis 的定义,微服务具有以下四个关键特征:
- Single Responsibility: 每个微服务设计用于执行特定的任务或功能,允许专业化并降低复杂性。
- Independence: 微服务可以独立开发、部署和扩展,从而提供灵活性和韧性。
- 分散式数据管理 微服务通常拥有自己的数据库,避免了对单一集中式数据库的需求。
- Technology Agnosticism: 团队可以为每个服务选择最适合的技术,而不受其他服务选择的限制。
这种方法与传统的整体式架构不同。在整体式架构中,所有应用程序组件都紧密集成为一个统一的单元。
微服务部署的关键阶段
虽然微服务架构提供了许多优势,如高可扩展性、灵活性、效率、故障隔离等,但它需要了解如何有效地部署微服务,并需要充分的规划才能成功。
这就是为什么全面了解微服务部署的关键概念、阶段和最佳实践对成功的微服务架构至关重要。让我们探索微服务部署的关键阶段及每个阶段涉及的内容。
微服务部署的规划和准备
所有好事都需要规划和耐心,成功部署微服务肯定也需要充分的规划和耐心。这就是为什么遵循微服务最佳实践并规划和准备部署微服务所需的一切很重要。
如我之前提到的,微服务的关键原则和特征之一是 单一职责原则。坚持这一原则,确保每个微服务专注于一个功能和能力并对其负责,这样你的团队可以独立开发、部署和扩展服务。
此外,这个原则的一个子类别是 松耦合设计原则。这意味着每个服务可以独立运行通信,并且最低程度地依赖其他服务。反过来,这允许对一个服务的更改或更新不会影响其他服务,从而实现独立的微服务扩展。
这降低了级联故障的风险,即系统某个部分的问题或故障会引发连锁反应,导致整个系统故障并使整个服务瘫痪。
部署微服务时的一个重要实践是为每个服务配置专用数据存储,这是松耦合设计原则的延伸,可防止冲突并提高服务可扩展性。
此外,你还需要采用异步微服务通信模式,如消息代理,确保每个服务都能通信而不需要直接依赖。
最后一步是为微服务实现持续集成和持续交付(CI/CD)管道。这些管道让团队能够部署新功能或修复,通过 CI/CD tools 如 Jenkins 和 GitLab,组织可以在频繁发布新功能的同时保持系统稳定性。
既然你已经了解了微服务部署所需的整体规划和准备工作,现在让我们来讨论微服务部署策略。
微服务部署策略
部署微服务时,选择哪种策略取决于服务功能、流量、基础设施设置、团队能力和成本考虑。一般来说,微服务部署策略如下:
- 每容器一个服务实例 采用这种方法,每个微服务在自己的容器中运行,相比单主机多实例模式提供更好的隔离。容器便于扩展,改进资源分配。
- 每虚拟机一个服务实例 每个服务运行在独立的虚拟机(VM)中,隔离度甚至比容器更高。虽然这提升了安全性和稳定性,但通常会带来更多开销。
- Phased Releases: 先将微服务版本部署给小部分用户,测试其稳定性后再全量发布。这样做能最小化问题影响,并允许快速回滚以保持系统完整性。
- 蓝绿部署 这种方法使用两个相同的生产环境,一个环境提供实际流量,另一个用于测试下个版本。蓝绿部署支持轻松回滚和零停机更新,因为流量可以在两个环境之间无缝切换。
- Staged Releases: 这种策略逐步向不同的用户段或环境发布更新。通常先从内部环境开始,再到生产环境,限制任何潜在问题的影响范围,让团队能够分阶段处理问题。
- Serverless Deployment: 这种方法利用 AWS Fargate 和 Go Google Cloud Run 等无服务器平台,它们通过自动管理基础设施来处理扩展和资源分配。采用无服务器部署,你无需管理底层服务器,可以专注于微服务本身。
选定微服务部署策略后,你还需要一个微服务编排工具。

Microservices Orchestration
选择了某个微服务部署策略后,你需要一个编排工具来协调微服务。微服务编排工具,如 Kubernetes,能自动化微服务部署、扩展、监控和容器化微服务管理。
比如 Airbnb 使用 Kubernetes,让工程师无需手动干预就能部署数百项微服务变更。Kubernetes 等微服务编排工具的一个重要功能是内置负载均衡。
完善的负载均衡功能能在微服务的多个实例间分散传入流量。这防止了单个实例成为瓶颈,增强了系统应对流量峰值的能力。
Kubernetes 通过自愈能力在管理微服务中发挥重要作用,故障容器会自动被替换和重启。纽约时报利用这一功能来维护微服务,同时不影响用户体验和产生停机时间。
此外,Kubernetes 还能通过 ConfigMaps 和 Secrets 改进微服务安全,管理配置和机密如数据库凭证或 API 密钥。这对处理敏感客户和用户信息的公司和服务(如 Uber)尤为重要。
最后,Kubernetes 等微服务编排工具对包含滚动更新和回滚的微服务策略(如分阶段发布)特别有益。滚动更新让新微服务版本能无中断部署,方式是保持旧版本的某些实例运行。
设置好微服务编排工具后,你需要构建和自动化 CI/CD pipelines 用于微服务部署。
微服务部署的 CI/CD 流水线
如前所述,微服务的持续集成和持续交付流水线是微服务部署的重要组成部分。CI/CD 流水线中的 CD 部分负责在代码变更通过测试和集成阶段后自动将其部署到生产环境。
然后,CI/CD 流水线的 CD 部分发挥作用,当代码变更通过测试和集成阶段时,服务被部署到微服务编排工具(如 Kubernetes 集群)。
此外,测试和集成阶段完全由 CI/CD 流水线自动执行,因为单元测试、集成测试和端到端测试都被集成到流水线中。
这允许团队在每个阶段验证更新,同时保持系统稳定性。另外,如果代码变更出现问题,尽管进行了各种测试,自动回滚可以恢复到先前的稳定版本。
最后,按照微服务最佳实践实现 CI/CD 流水线有助于组织加快开发速度、减少人为错误并保持高质量标准。
Spotify、Expedia、iRobot、Lufthansa、Pandora 等许多公司通过 CircleCI、AWS CodePipeline 和 GitLab 等 CI/CD 工具使用微服务 CI/CD 流水线,以自动化部署流程、确保代码质量一致,并在保持系统稳定性的同时快速交付新功能。
微服务通信模式
微服务之间如何通信完全取决于功能、整体架构、期望的可扩展性和微服务的可靠性。一般来说,微服务通常采用两种主要通信模式: synchronous and asynchronous 微服务通信模式。
在同步微服务通信模式中,服务实时交互,意味着一个服务会发送请求并等待响应后才继续。最常用的同步微服务通信模式有 REST(表述性状态转移)API, gRPC(Google 远程过程调用), and GraphQL.
通常,这类微服务通信模式用于那些需要实时数据处理和即时响应的行业和公司。金融、医疗和电子商务等行业经常使用同步通信模式,以确保交易、数据检索或交互瞬间完成,保持流畅和响应迅速的用户体验。
也就是说,虽然同步微服务通信模式提供了实时响应和简洁性等优势,但它们也存在一些缺点,如由紧密耦合导致的潜在瓶颈、高负载下可扩展性低、响应时间慢以及高流量情况下延迟高。
另一方面,异步微服务通信模式通常更适合微服务,因为它们基于我们之前讨论的松耦合原则。
这种微服务通信模式通过允许服务通过 Kafka 或 RabbitMQ 等代理发送和接收消息来解耦服务。通过将消息发送到充当缓冲区的队列,服务相互独立通信,而不是像同步通信模式那样等待响应。这个缓冲区使其他服务能够按照自己的节奏处理消息,允许发送者继续其工作而不必等待接收者。
异步微服务通信模式不仅为微服务部署提供了解耦结构,而且还提供了与同步微服务通信模式相同的实时响应。
这是由于异步事件驱动微服务通信模式的事件驱动架构,服务通过在特定操作发生时发出事件进行通信。其他服务可以订阅这些事件并做出相应反应。这允许构建高度响应迅速的系统,在不直接耦合服务的情况下实时对变化做出反应。
Furthermore, in asynchronous 发布-订阅(Pub/Sub) 在微服务通信模式中,服务(发布者)将消息发送到主题,其他服务(订阅者)监听该主题以接收更新。此模型支持多个订阅者,同时向许多服务广播消息。
最后,与事件驱动模式类似,异步 编排型 Saga 微服务通信模式也使用事件相互通信;但在这种模式中,存在特定的顺序,意味着事件触发下一步和特定的服务激活。
事件驱动模式与编排型传奇模式的区别在于:事件驱动没有固定的序列或工作流,多个服务可以对同一个事件做出反应,而编排型传奇模式则遵循特定的流程和顺序。
选择哪种异步微服务通信模式取决于任务性质和微服务的整体功能。消息队列(如RabbitMQ和Amazon SQS)通常用于任务调度、工作负载分发、电商订单处理和通知系统。
事件驱动消息代理(如Apache Kafka和AWS EventBridge)通常用于实时处理大规模事件流,以及在金融服务和AWS等领域中进行微服务间的事件路由。
发布-订阅(Pub/Sub)消息代理(如Google Cloud Pub/Sub和Redis Streams)通常用于分布式系统中的可扩展消息传递,适用于实时分析、事件采集、实时通知和聊天应用。
最后,编排型传奇消息代理主要用于电商订单处理、旅行预订系统,以及需要在多个服务间协调复杂的多步骤事务而无需中央控制的场景。

微服务服务发现
设置并实现了适合需求的通信模式后,还需要确保服务能够相互定位。正如之前提到的,Kubernetes等微服务编排工具在微服务发现中起重要作用。
这是通过Kubernetes DNS提供的内置服务发现实现的,它会在服务扩展或在集群内改变位置时动态更新IP地址和DNS记录。
这种微服务发现方法称为服务端发现,因为路由责任委托给了负载均衡器,后者查询注册表并将流量定向到相应的实例。
另一方面,还有客户端发现方法用于微服务发现,即服务或API网关查询服务注册表(如Consul或Eureka)来找到可用的实例。
选择哪种服务发现方法最适合微服务部署取决于系统的需求和规模。
使用客户端微服务发现时,客户端对与哪个实例通信拥有完全控制权。这不仅允许更多定制化,还降低了复杂性,因为无需中央发现服务。
例如,Netflix的微服务部署使用客户端发现和Eureka与Ribbon进行负载均衡,允许客户端根据延迟和服务器负载等标准选择最佳实例。
服务端微服务发现更适合较大规模的环境,因为集中式服务发现可以提高效率,并在分布式系统中实现一致的负载均衡。
服务端微服务发现解决方案(如Kubernetes、AWS Elastic Load Balancing和API网关(Kong、NGINX等))有助于高效路由流量、维持高可用性,被Airbnb、Pinterest、Expedia、Lyft等公司采用。
Microservice Security
虽然单体架构在大多数方面不如MSA,但在安全性上单体架构曾有优势。由于微服务基于松耦合原则构建且分布式部署,无法实施统一的通用安全措施。
每个服务都必须独立保护,额外的保障措施不可或缺,因为微服务的攻击面更大。为此,OAuth2和JSON Web Token(JWT)等标准被广泛用于身份认证和授权。
此外,API网关也经常被用来管理微服务间的安全,它在入口处强制执行身份认证和授权。网关API还可以实现速率限制、日志记录和监控,为微服务安全提供额外的防护层。
虽然这些措施保护了主入口,但微服务安全还需要额外措施来覆盖服务间通信。
这是服务网格发挥作用的地方,它为网络添加了微服务安全层,加密服务间的流量,强制执行相互TLS等策略。服务网格基本上建立了端到端的全面加密,显著提升了微服务安全。
Microservice Scaling
MSA最大的优势之一,也是它被开发来替代单体架构的根本原因,是其高可扩展性。微服务扩展通常有两种方式:纵向扩展和横向扩展。
纵向微服务扩展(扩容)是指为现有实例增加更多资源,如CPU或内存。横向微服务扩展(横向扩展)则是分散负载并增加容量。
在实现方面,纵向扩展更简单,只需修改单个实例,通过升级到更大的服务器、增加云实例的内存或处理能力,或添加更多存储即可。
这种扩展方式通常用于增加RAM或CPU能力能改进查询性能和数据处理的场景,比如负责内存缓存的服务。
不过,虽然微服务纵向扩展更简单,能立即提升性能,但也有缺点。纵向扩展受限于服务器硬件容量,到一定程度后,你需要改用横向扩展才能继续增长。
此外,纵向扩展成本很高,因为硬件和更大的实例通常价格不菲。最后,如果扩展后的实例故障,整个服务就会宕机,因为没有其他实例来承担负载。
横向微服务扩展不是升级单个实例的资源,而是部署该服务的新实例。这些实例虽然独立运行,但仍处理相同的服务和相同工作负载的各部分。
与纵向扩展不同,横向微服务扩展没有上限。你可以根据需要添加任意数量的实例来处理不断增加的工作负载和流量峰值,提供更强的扩展能力。
而且,由于有多个实例,当其中一个出现故障时,你不会被套住,因为其他实例仍能继续处理请求。最后,从长远看,横向扩展更划算,因为可以用多个小型廉价实例来构建更可靠、更强大的性能。
不过,横向扩展和添加更多实例需要更多负载均衡器、微服务发现机制和微服务编排工具,使微服务架构变得更加复杂。
横向扩展更适合网络服务和电商、社交媒体等应用场景,这些应用流量波动大,请求量高。
话虽如此,这并不是非此即彼的选择,两种扩展方式在微服务中都被支持,在很多情况下都是必需的。通常小型组织采用纵向扩展,因为它更简单易管理,但随着时间推移和应用增长,会引入横向扩展来应对高负载。
最后,云平台提供自动扩展服务,可根据实时需求自动添加或移除实例,这在很大程度上帮助组织平衡纵向和横向扩展。
Microservice Monitoring
到了这个阶段,微服务部署基本完成,剩下的就是确保它稳定可靠地运行。这正是微服务监控工具的用武之地,比如 Prometheus 和 Grafana step in.
这些工具提供服务指标的实时洞察,让团队能追踪资源使用情况、延迟和错误率。此外,这些工具还提供分布式追踪(Jaeger、Zipkin 等),帮助可视化请求在各服务间的流向,对诊断问题极其有用。
最后,由于微服务的分布式设计,故障可能会跨服务级联传播,所以日志聚合是微服务监控的关键实践。通过将日志汇总到一个中央平台并设置实时告警,你总能提前发现问题,在其影响用户之前主动响应。
Final Thoughts
虽然微服务的世界确实复杂,但理解基础概念和微服务部署的关键阶段能让整个过程轻松得多。而且随着时间推移,越来越多功能更强大的工具出现,使微服务部署比以往任何时候都更简单。
FAQ
微服务通常采用哪些部署策略?
微服务部署策略有很多,最常用的包括单容器单服务实例、分阶段发布、蓝绿部署和无服务器部署,各自在隔离、灵活性和扩展能力方面有不同的优势。
Kubernetes 在微服务编排中扮演什么角色?
微服务需要依赖 Kubernetes 等微服务编排工具来自动化部署、扩展和管理容器化服务,提供负载均衡、自动扩展和自我修复能力,确保微服务的可靠和高效运行。
如何确保微服务环境的安全性?
由于微服务的分布式特性,在安全性方面比单体架构更复杂。微服务安全涉及请求认证和授权、加密服务间通信,以及部署 API 网关和 Istio 等服务网格来实现集中的安全管理。