微服务架构基本原理学习笔记(一)
一、什么是微服务
微服务是一种技术架构,通常我们可以把它理解为一组可以相互之间协同工作的应用程序或服务,这些应用程序或服务能够被单独部署到不同的服务器中,并且能够自主运行和维护。
微服务技术只是一个名称而已,或许我们在日常工作中已经或多或少在使用其中的一种或几种技术和架构,但我们并没有将其称之为微服务。而且,对于微服务的大小和规模,也并没有严格的限制,也许几百行代码或者数个文件,也或者比这个规模更大一点,都没有关系。我们不应该在这一点上过多地纠结,而应该更多地去关心微服务到底解决了什么问题?这才是最主要的。
二、为什么需要微服务
换句话说,微服务架构到底解决了什么问题?要回答这个问题,我们先对比一下单体架构(Monolith)与微服务架构(MicroService)。
单体架构
在单体架构中,代码通常都放在一个代码库中,这就意味着所有的开发人员都必须基于同一个源代码库来工作。另外,单体架构的应用程序通常都运行在单一服务器或虚机中,并且数据被持久化到单个数据库。其优点是:
- 开发环境比较简单,所使用的技术栈统一。
- 所有的代码和资源都在同一个代码库中,容易查找和定位错误。
- 应用程序的部署和更新操作比较容易,我们只需要在一台服务器或虚机上替换掉旧的应用程序即可。
单体架构有其自身的优点,如果你的应用程序符合这一定位并且运行良好,那么其实你完全没有必要使用微服务架构,或者说目前暂时还不需要。但是,当应用程序的规模不断增加时,问题就会逐渐被暴露出来。随着代码库变得越来越大,复杂性也会显著增加,其中积累的技术债也会越来越多,最终会导致代码变得难以维护,而且各个模块间的依赖关系也会非常复杂,往往一个小的功能调整也会涉及到许多代码的改动。
另外一个问题就是单体应用程序的更新部署往往会导致服务的中断,从而影响到整个产品的用户体验和可用性。
最后就是单体应用程序的功能扩展往往比较困难。当访问量增加时,我们除了增加服务器的配置和数量外(垂直扩展),无法简单地对程序进行横向扩展和功能扩充。这个时候你会发现,无论你采用何种技术栈,都无法摆脱单体架构本身所带来的这些问题,你所要考虑的是调整整个应用程序的架构,使其更符合敏捷开发模式的思维。
有一点值得注意的是,我们需要将传统的分布式单体架构与微服务架构区别开来。
所谓分布式单体架构,是指将组成应用程序的各个不同的模块或服务部署在不同的服务器或虚机中,它们都共享同一个中央数据库,彼此之间相互关联,形成一个紧耦合的结构。任何一个模块或服务的缺失都会导致整个应用程序无法正常工作。同时,这种结构也会给更新和部署带来挑战。
微服务架构
在微服务架构中,我们将应用程序分解成足够小的部分,每一部分可以有自己独立的源代码库并且由不同的小型开发团队来进行开发和维护。就每一个微服务而言,其开发成本相对较低,随着项目的迭代,在必要的时候也可以丢弃某些微服务或者完全改写部分微服务。
项目中的每一个微服务都可以自由选择所使用的技术和开发工具。你完全可以在其中一个微服务中使用关系型数据库,而在另一个微服务中使用文档型数据库。也可以在一个微服务中使用函数式编程语言(例如JavaScript或者Python),而在另一个微服务中使用面向对象编程语言(例如C#或Java)。每一个微服务的开发团队都可以自由选择最合适的技术。
由于微服务之间是松耦合的,每一个微服务可以单独部署和运行,这样我们就可以实现整个应用程序的零宕机更新。而且如果有需要,每一个微服务也可以随时重新发布和更新,而不影响整个应用程序的运行。
另外,根据需要我们也可以非常方便地对单个微服务进行扩展,从而将成本控制在最低。
微服务架构的这些特性更加符合敏捷开发的原则,从而使得我们可以更快地适应不断变化的业务和需求。我想这也是为什么近年来微服务架构变得如此流行的原因之一。
不过,在使用微服务架构之前,你需要首先了解下面这些你将要面对的挑战:
- 初始化并运行每个微服务,然后在整个应用程序的上下文中进行测试。由于每个微服务所使用的技术不同,运行的环境也千差万别,所以从下载源代码开始,你可能需要花费比较多的时间才能让这些微服务运行起来。考虑使用容器来自动完成所有这些预备步骤是一个不错的选择。
- 由于微服务之间的交互往往非常复杂,如果处理不当,你会很容易地陷入到多个微服务之间大量低效而冗长的通信陷阱中,这会导致整个应用程序性能低下。
- 虽然单个微服务的部署较为容易,但是当大量微服务同时工作时,手动部署和更新将变得更加低效和繁琐。因此,自动化部署将变得至关重要。
- 最后一点就是监控微服务的运行。我们当然不希望逐个地去检查每个微服务当前的运行状态,而是希望这些微服务能够自动报告它们的运行状况。因此,我们需要一种监控机制,能够让系统管理员在一个集中的地方查看所有微服务的运行日志和数据。
不过,你不用太担心,有许多开源的软件和工具能够帮忙我们解决上述这些问题。
Github上一个非常好的例子eShopOnContainers可以用来帮助我们学习和理解微服务架构。下面是这个项目的微服务架构图: