litefish 2020-09-16
最近几年微服务很火,大家都在建设微服务,如果不懂点微服务相关的技术,都不好意思跟同行打招呼了。
图片来自 Pexels
我也见过身边很多人在微服务踩过很多坑,我从 2016 年开始接触微服务,有多家大型企业的微服务分布式系统的架构经验,不过微服务和涉及的分布式计算非常的复杂,绝非是一篇文章就可以讲清楚的。
本文只是从最简单的概念的基本使用带你入门,如果后续还有兴趣的话,可以查阅相关的文献和技术书籍去深入学习。
本文的微服务分享以下三部分,总体大纲如下:
微服务的概念和原则
什么是微服务?
简单举例:看军事新闻的同学应该都知道,一艘航空母舰作战能力虽然很强,但是弱点太明显,就是防御能力太差,单艘的航空母舰很少单独行动,通常航空母舰战斗群才是主要军事力量。
你可以把单艘航母理解为的单体应用(防御差,机动性不好),把航母战斗群(调度复杂,维护费用高)理解为微服务。
简单讲特征就是:
单体作战的应用(图)
微服务战斗群(图)
大部分的开发者经历和开发过单体应用,无论是传统的 SSM,还是现在的 Spring Boot/Rails,它们都是单体应用。
那么长期陪伴我们的单体应用有什么弊端?我们是面临了什么问题,导致我们要抛弃单体应用转向微服务架构?
个人总结主要问题如下:
当然还有例如无法满足快速扩容,弹性伸缩,无法适应云环境特性等问题,但我们不一一详谈了,以上的问题,都是微服务架构要解决的问题,至于具体是怎么解决的,我们先放到后面再聊。
历代应用程序的架构变迁(图)
解决什么问题,又引入了什么问题?
我们先看看微服务能带给我们什么?微服务架构的特点:
我们知道一个朴素的理念,没有任何事物是完美的,任何东西都有两面性,有得必有失。
那么在选择微服务在解决了快速响应和弹性伸缩的问题同时,它又给我们带来了什么问题?
个人总结如下:
系统应用由原来的单体变成几十到几百个不同的工程,会所产生例如包括服务间的依赖,服务如何拆封,内部接口规范,数据传递等等问题。
尤其是服务拆分,需要团队熟悉业务流程,懂得取舍,要保证拆分的粒度服务既符合“高内聚,低耦合”的基本原则,还要兼顾业务的发展以及公司的愿景,要还要说服团队成员为之努力,并且积极投入,在多方中间取得平衡。
对于分布式系统,部署,测试和监控都需要大量的中间件来支撑,而且中间件本身也要维护。
原先单体应用很简单的事务问题 ,转到分布式环境就变得很复杂,分布式事务是采用简单的重试+补偿机制,还是采用二阶段提交协议等强一致性方法来解决,就要取决对业务场景的熟悉加上反复的权衡了。
相同问题还包括对 CAP 模型的权衡,总之微服务对团队整体的技术栈水平整体要求更高。
微服务有哪些应该遵循哪些原则?
古人云:兵马未动,粮草先行。建设微服务是需要建立长远规划,不是像写 CMS 那样建好数据库表,然后就开始干活,这样十有八九是会失败的。
我们要进行微服务改造前,架构师要提前做好规划,我们把这里分为三步,前期阶段,设计阶段,技术阶段。
前期阶段,大致要做好如下事情:
设计阶段,参考 Sam Newman 的著作《微服务设计》,单微服务必须要满足以下的条件,才符合微服务的基本要求:
庞大的分布式系统,需要强大基础设施来支撑,微服务涉及哪些基础设施?
说了那么多,那什么样的情况下,你的团队不适合建设微服务?(请勿对号入座)
微服务设计其实是很早就有的设计思想,因为随着虚拟化技术的崛起,微服务可以低成本的实现,所以也开始流行和兴起。
微服务的内涵很深,其中就包括,自动化,去中心化,独立性等等,其中细节无法用一篇文章概述清楚,我们在做技术选型或者方案的时候,尽可能多去了解技术的本身和起源再结合我们业务的特点,进行更好的选择。
如何低成本的实现微服务?
Spring Cloud 为什么是国内最流行的微服务框架,它提供哪些开箱即用的组件 ?
概览如下:
①Spring Boot 微服务基石
Spring Boot 是构建微服务的理想框架,主要得益于 Spring Boot 可以打包成为单个可执行JAR文件交付服务,Spring Actuator 公开服务健康信息都是微服务的基石,为什么这么说 ?
我们先看看构建微服务的四个重要原则:
微服务有优点和缺点,并非所有应用都适合用微服务架构,架构师需要能做到以下要求:
糟糕的微服务有哪些特征?
何时不应该使用微服务 ?
②Spring Cloud Config 配置服务
Spring Config 是 Spring 提供的配置中心轻量级实现,基于 Git 存储,国内用户大多推荐使用 Alibaba 开源的 Nacos(集成配置中心和注册中心)都是非常不错的配置中心的实现。
微服务程序对于配置中心的几点管理原则:
Spring Config 这款配置中心提供的核心功能:
③Spring Cloud Eureka 服务发现
服务发现是微服务架构中非常重要的概念,也称注册中心,类似我们生活中的房地产中介的角色,买房卖房都要通过它。
所以它是所有微服务上线/下线的必经之路,也掌握微服务的生杀大权,注册中心会根据 CAP 策略和对微服务的健康检查,作出对具体服务剔除,下线,恢复上线等操作。
主要还有以下几个核心功能:
微服务架构里面要实现注册中心,需要达到哪些基本要求?
Spring Eureka 提供的服务发现实现,具备哪些特点 ?
④Spring Cloud Hystrix 熔断保护
为什么微服务进行熔断 ?当一个服务出现问题:
为什么熔断很重要 ?
断路器提供的关键能力:
Netflix 研发和出品的 Hystrix 实现是一款成熟稳定的熔断实现,在 Netflix 在生产实践和运行多年,非常可靠,后面加入 Spring Cloud 体系,成为 Spring Cloud 微服务生态链的一员,使用起来也非常的简单和方便。
Hystrix 支持四种断路模式:
跳闸会导致的三种结果:
熔断的几个处理原则:
⑤Spring Cloud Zuul 网关
网关是整个微服务分布式集群的入口,对于用户来说,用户无需知道你每个服务的地址,只需要记住网关地址就可以了。
这样理解可能比较抽象,举一个生活的例子,微服务集群是一个大型公司,公司内部有很多个不同的职能部门(对应每个微服务)。
但是你如果要访问具体的职能部门,你必须先到前台登记,再由前台带你到你想访问的具体职能部门去办理实际的业务(智能路由)。
微服务对于网关实现的规范:
网关通常要做哪些事情:
Zuul 网关的具体运行参考图:
Spring Cloud Zuul 是初期版本的 API 网关实现,提供以下功能:
⑥Spring Cloud OAuth 2 服务保护
Oauth 2 是用于保证请求的合法和正确性,为了让微服务本身更加专注于业务,所以 OAuth 2 类似配置中心被单独抽离出来作为基础组件的统一认证中心来使用。
OAuth 2 的作用类似我们生活中的公安局的角色,当我们需要去正规机构办理业务的时候,我们需要提供有效的身份证(合法的身份认证标示)。
如果没有你就需要去公安局(OAuth)申请一张在有效期内的身份证(Token),然后带着这张身份证我们才能去购买机票,酒店等其他社会服务(微服务)。
社会服务机构在拿到你提供的身份证(Token)后,也会向公安局(OAuth)联网发送信息,来验证你的身份证的合法性(Token 合法性校验),身份认证不通过就会被拒绝服务,合法的身份才能进行业务的办理。
关于 OAuth 的工作流程,可以结合下图来理解:
微服务对于 OAuth2 规范的 4 种类型授权:密码/客户端凭据/授权码/隐式。
Spring Cloud OAuth 2 为我们提供哪些便利?
OAuth 2:/auth/oauth/token 的返回信息:
OAuth 2 支持 JWT (JSON Web Token)的规范,关于 JWT 的原理就不特别解释了。
简单的 JWT 有以下几个特点:
OAuth 2 的简单总结:
⑦Spring Cloud Stream 消息驱动
我们和世界的互动不是同步的,很多时候是基于消息异步驱动模型,比如邮件,点餐,订票等等,想要了解 Spring Cloud Stream,必须先要理解基于事件(MQ)编程的模型,基于消息驱动有利于开发构建高度解耦的系统。
因为 Spring Cloud Stream 并不是自己实现了消息中间件,而是对于市场上主流(例如 RabbitMQ,KafKa)的 MQ 产品做了一层封装和抽象。
Spring Cloud Stream 做的事情并不是什么新鲜的事情,非常类似 ORM 所做的事情,了解 ORM 框架的同学应该都熟悉对于多种数据库(MySQL,Oracle,SQL Server)产品的抽象是何等重要。
面向 ORM 进行数据库访问,可以让你脱离对于指定数据库产品的深度依赖和绑定,而且可以不用特意去学习不同数据库的本地化特性和方言,降低学习成本。
假如你想从 Oracle 迁移到 MySQL 上面,几乎是不需要改动一行代码,只需要改动 ORM 的配置就可以实现了。
参考下图简单了解一下 ORM:
Spring Cloud Stream 类似 ORM,你只需要基于 Spring Cloud Stream 提供的消息模型进行编程。
至于底层的消息组件是用的 RabbitMQ 还是 Kafka 还是其他的消息中间件产品,都没有关系,甚至更换底层消息组件也不会对你的应用产生任何影响,这就是标准化所带来的收益。
关于如何更好的理解 Spring Cloud Stream 工作模型可以简单参考下图:
微服务中使用的的两种服务通信方式对比:
消息传递架构的缺点:
消息中放置什么数据 ?
Spring Cloud Stream 的消息模型和概念:
Spring Cloud Stream 的简单总结:
⑧Sleuth 和 Zipkin 分布式跟踪
微服务分布式架构带来了复杂度,成本最高的就是跟踪检查和运维,分布式意味要在多个服务,机器跟踪一个事务,Sleuth 和 Zipkin 都是用于 Spring Cloud 服务体系的分布式跟踪技术,先直接看下最终效果。
下图一个简单的可视化链路跟踪调用,ZipKin 可以清晰的看到一个客户端请求在每个服务上面处理所消耗的事情,点击进去可以看到具体的事务执行内容,方便排查错误。
Spring Cloud Sleuth 的工作流程:
Open Zipkin 的简单概述:
关于微服务全链路跟踪的总结:
⑨部署微服务
构建和部署管道是微服务架构最重要的部分,微服务的主要特点是快速构建,修改,发布。
符合微服务特征的部署要达到以下几个要求:
Spring Cloud 大型项目的架构方案
这是一个真实用于国内某大型企业的微服务架构体系,支撑日均百万订单的项目,因为已经过了 2 年的保密期,所以可以拿出来分享。
刚好可以结合前面凌乱的知识点,看看 Spring Cloud 这套组件是如何搭建起来的。
整套微服务就是下面这张架构图:
具体每个组件的作用就不在这里详细说明了,在这套架构方案里面,我们没有完全照搬 Spring Cloud 全家桶的组建,还是根据自己的需求对其中组件进行的更换。
例如:
PS:另外在值得补充的是,在写这篇文章的时候 Spring Cloud Zuul 已经不被官方推荐使用了,替代品是性能更好的 Spring Cloud Gateway ,大家可以在了解的时候需要注意一下。
总结
微服务是未来大型企业的必经之路,虽然成本很高,但是可以提升 IT 系统的健壮性和提升技术人员的广度和深度都还是很有帮助的。
作者:肖斌
编辑:陶家龙