微服务这几年很火,大家都在构建微服务。如果你对微服务相关技术一知半解,你会不好意思跟同行打招呼。图片来自Pexels。我也看到身边很多人踩过很多微服务的坑。2016年开始接触微服务,有多家大型企业的微服务分布式系统架构经验。但是,微服务和涉及到的分布式系统计算非常复杂,不可能一篇文章说清楚。本文只是向您介绍最简单概念的基本使用。如果对后续还有兴趣,可以参考相关文献和技术书籍进行深入学习。本文微服务共分为以下三个部分,大纲如下:微服务的概念和原理(理论)SpringCloud如何低成本实现微服务(实现)大型SpringCloud项目的架构解决方案(实战案例)概念微服务原理和原理什么是微服务?简单的例子:看过军事新闻的同学应该都知道,航母虽然作战能力很强,但是弱点太明显了,就是防御能力太差。一艘航空母舰很少单独行动。该集团是主要的军事力量。你可以把单个航母理解为一个单一的应用(防御差,机动性差),一个航母战斗群(调度复杂,维护成本高)理解为一个微服务。简单来说,特点是:单体应用:简单、脆弱(一个模块失效,整个系统不可用),战斗力弱,维护成本低。微服务架构:复杂健壮(某个模块出现问题不会影响系统整体可用性),战斗力强,维护成本高。应用单体实战(图)微服务战团(图)大多数开发者都经历过和开发过单体应用,无论是传统的SSM,还是现在的SpringBoot/Rails,都是单体应用。那么长期伴随我们的单体应用有哪些缺点呢?我们面临哪些问题导致我们放弃单体应用而转向微服务架构?我个人总结的主要问题如下:部署成本高(无论是修改1行代码还是10行代码都必须全部部署替换)。更改具有高影响、高风险和高测试成本(无论代码更改多小,成本都是一样的)。由于成本高、风险大,部署频率低(无法满足客户快速交付的需求)。当然,还存在无法满足快速扩展、弹性伸缩、无法适应云环境特点等问题,在此不一一详述。以上问题都是微服务架构要解决的问题。至于具体怎么解决,以后再说。过去几代应用程序(图)的架构变化解决了哪些问题,引入了哪些问题?我们先来看看微服务能给我们带来什么?微服务架构的特点:针对特定服务发布,影响小,风险低,成本低版本发布频繁,快速交付需要低成本扩展,弹性伸缩,适应云环境。我们知道一个简单的概念,没有什么是完美的,任何事情都有两个方面,都有得失。那么在选择微服务解决快速响应和弹性??伸缩的问题时,给我们带来了哪些问题呢?我个人总结如下:分布式系统部署的复杂性,测试和监控的成本分布式事务和CAP相关问题系统应用已经从原来的单体变成了几十个到上百个不同的项目,比如,服务间的依赖关系,如何解包服务,内部接口规范,数据传输等问题。特别是对于服务拆分,团队需要熟悉业务流程并知道权衡取舍。需要保证细粒度的服务拆分既符合“高内聚、低耦合”的基本原则,又要兼顾业务发展和公司愿景。说服团队成员为之努力并积极参与其中,以在多方之间取得平衡。对于分布式系统来说,部署、测试、监控都需要大量的中间件来支撑,中间件本身也需要维护。原本在单个应用中非常简单的事务问题,转移到分布式环境中就变得非常复杂。一个分布式事务是通过简单的重试+补偿机制来解决,还是通过两阶段提交协议等强一致性的方式来解决,需要依赖于对业务场景的熟悉和反复的权衡。同样的问题还包括CAP模型的权衡。总之,微服务对团队整体技术栈水平的整体要求更高。微服务应该遵循什么原则?古人云:兵马未动,粮草先行。微服务的建设需要建立长远的规划。不像写一个CMS建个数据库表然后开始工作。这很可能会失败。在我们进行微服务改造之前,架构师必须提前做好规划。我们把这个分为三个阶段,前期,设计阶段,技术阶段。前期大致要做以下几件事:与多方充分沟通,确保客户和组织的需求得到满足和认可。与团队沟通,让队友(开发/测试/运维)了解并积极参与。与业务部门沟通,明确版本计划和上线时间。在设计阶段,参考SamNewman的书《微服务设计》,单个微服务必须满足以下条件才能满足微服务的基本要求:标准的REST风格接口(基于HTTP和JSON格式)。独立部署,避免共享数据库(避免因为数据库影响整个分布式系统)。业务上高内聚,减少依赖(从设计上避免服务过大或过小)。庞大的分布式系统需要强大的基础设施来支撑。微服务涉及什么样的基础设施?CI/CD和自动化(分布式系统几乎不可能手动发布。)虚拟化技术(保证微服务运行环境的隔离性,目前业界主流是使用Docker容器)。日志聚合,全链路监控(高度可观察和分析诊断问题)。说了这么多,你的团队在什么情况下不适合搭建微服务呢?(请不要打卡)开发团队没有自主权,组织对开发团队有很多限制(详见康威定律)。团队对业务不熟悉,无法识别服务的边界并进行合理拆分(请参考DDD领域驱动设计)。微服务设计其实是一个很早的设计思想,因为随着虚拟化技术的兴起,可以低成本的实现微服务,所以也开始流行起来。微服务的内涵很深,包括自动化、去中心化、独立性等等,其中的细节不是一篇文章能概括清楚的。我们在做技术选型或者解决方案的时候,应该尽可能多地了解技术,根据我们业务本身的特点和出身,做出更好的选择。如何低成本实现微服务?为什么说SpringCloud是国内最流行的微服务框架?它提供了哪些开箱即用的组件?概览如下:SpringCloudConfig配置中心SpringCloudEureka服务发现SpringCloudHystrix熔断保护SpringCloudZuul服务网关SpringCloudOAuth2服务保护SpringCloudStream消息驱动分布式全链路跟踪微服务部署①SpringBoot微服务基石SpringBoot是构建微服务的理想框架,主要是因为SpringBoot可以打包成一个单一的可执行JAR文件来交付服务,而SpringActuator暴露服务健康信息是微服务的基石。你为什么这么说?我们先来看看构建微服务的四大重要原则:服务应该是独立的,可以独立部署从中枢(配置中心)读取配置,对客户端透明,传递健康信息。微服务有优点也有缺点。并非所有应用程序都适合微服务架构。架构师需要能够满足以下要求:分解业务问题:描述业务问题,注意动词,寻找数据凝聚力。建立服务粒度:谈论将大服务重构为更小的服务,重点关注服务如何相互交互,以及服务职责如何随时间变化。定义服务接口:拥抱REST的概念,使用URI来传达意图,使用HTTP状态代码来传达结果。糟糕的微服务有哪些特征?太粗粒度:服务承担太多责任,服务管理跨大量表的数据,太多测试用例。太细粒度:服务之间严重依赖,服务内部没有逻辑。什么时候不应该使用微服务?不愿投资(需要高度成熟的运营、规模化、复杂性问题)。管理/监控庞大的服务器的成本也很高。不适合小型应用,太贵了。数据事务(分布式系统很难处理事务)②SpringCloudConfig配置服务SpringConfig是Spring提供的配置中心的轻量级实现。基于Git存储,国内大部分用户推荐使用阿里巴巴开源的Nacos(集成配置中心和注册中心),都是非常好的配置中心实现。配置中心微服务程序的一些管理原则:应用的配置与部署的实际代码分离(配置中心与应用分离)。集中式(将配置中心集中在少数存储库中)。稳定(配置中心要保证高可用)。配置中心SpringConfig提供的核心功能:配置服务器允许使用特定于环境的值。使用SpringProfile区分环境值。可以使用基于文件或基于Git的存储属性。允许对称和非对称加密。③SpringCloudEurekaServiceDiscovery服务发现是微服务架构中一个很重要的概念,也称为注册中心,类似于我们生活中的房产中介的作用,通过它买卖房子。因此,它是所有微服务上线/下线的必由之路,也掌握着微服务的生死大权。注册中心会根据CAP策略和微服务的健康检查,淘汰特定的服务,下线,恢复上线。等等。还有以下核心功能:快速横向扩展环境中的服务数量(功能与K8s重叠,但也可以针对特定服务设置运行时数量)。抽象服务的物理位置(微服务通常运行在没有固定IP的Docker容器中,只能通过注册中心找到)。提高程序的灵活性,自动伸缩。信息共享,健康检测。在微服务架构中实现注册中心有哪些基本要求?高可用,注册信息共享(注册中心集群部署),不可能因为注册中心宕机导致所有集群不可用。负载均衡(服务间动态请求负载均衡),在服务间合理分配流量。弹性(客户端缓存服务信息)。容错、健康检查(检测到损坏的服务会自动删除,无需人工干预)。SpringEureka提供的服务发现实现有哪些特点?该服务发现抽象服务的物理位置。在不知情的情况下添加和删除服务。为服务之间的调用提供负载均衡。使用3种不同的机制来调用服务:DiscoveryClient、支持Ribbon的RestTemplate和Netflix的FeignClient。④SpringCloudHystrix熔断保护微服务为什么要熔断?当一个服务出现问题时:通常是从一小部分开始,然后在线程耗尽时彻底崩溃。服务之间的调用可能会阻塞很长时间。如果服务没有关闭,就会一直调用,造成连锁效应。一项性能不佳的服务可能会迅速导致整个应用程序崩溃。为什么熔断很重要?每个节点(调用服务和数据库)都实现了一个断路器,以避免服务崩溃的连锁效应。意识到只有有问题的服务受到影响,其余服务功能完备(影响范围最小化)。断路器是服务器的灵活基础。断路器提供的主要功能:快速失败。功能降级(备选)。无缝恢复(断路器定期检查,自动恢复服务)。Netflix开发生产的Hystrix实现是一个成熟稳定的熔断器实现。Netflix实践运营多年,非常靠谱。后来加入了SpringCloud体系,成为SpringCloud微服务生态链的一员。它也非常易于使用。简便。Hystrix支持四种断路器模式:客户端负载均衡模式(检测服务错误,移除服务)。断路器模式(超时抛出异常强制失败,所有超过阈值的调用强制失败)。回退模式(而不是抛出异常执行替代方案,例如排队,稍后再试等)。Bulkhead模式(将远程调用的资源分配到一个独立的线程池中,调用的问题只是线程池饱和,停止请求)。跳闸可能导致三种结果:服务B立即知道服务C有问题,并且不等待就立即失败。服务B执行服务C的替换代码以采取行动(回退模式)。服务C可以检查问题并在旅行后快速恢复。断路器的几个处理原则:设计分布式应用时必须考虑弹性。一个服务的完全失败很容易检测和处理,只是需要时间,断路器给出了这个时间窗口。性能不佳的服务可能会导致集群崩溃,因为相互调用会阻塞线程并耗尽资源。Hystrix支持两种隔离模型,THREAD和SEMAPHORE。⑤SpringCloudZuulGateway网关是整个微服务分布式集群的入口。对于用户来说,用户不需要知道你每一个服务的地址,只需要记住网关地址即可。这种理解可能是抽象的。举个生活中的例子,一个微服务集群就是一个大公司,有很多不同的职能部门(对应每一个微服务)。但如果要拜访具体的职能部门,必须先到前台登记,然后前台会带你到具体要拜访的职能部门办理实际业务(智能路由)。网关实现的微服务规范:一个服务,独立负责所有服务调用的过滤和路由。服务和客户端之间的中间人,简化客户端开发。网关通常做的事情:静态路由,从注册中心获取各个微服务的具体位置。动态路由(根据参数特性,调用特定服务,小部分用户体验新功能,通常用于灰度发布)。验证授权:验证访问者的身份信息(统一验证,服务只需要关注业务逻辑)。数据收集和记录(收集调用次数和响应时间等)。Zuul网关具体操作参考图:SpringCloudZuul是API网关实现的早期版本,提供如下功能:结合SpringCloudEureka将服务发现的注册地址添加到Zuul路由中。Zuul可以方便的为所有服务添加/API等前缀路由地址。全局自定义Zuul的SpringCloudHystrix和SpringCloudRibbon(调度策略)的超时时间。实施动态路由和A/B测试不同的版本。检查JWT、时间戳等参数的有效性等。⑥SpringCloudOAuth2服务保护Oauth2用于保证请求的合法性和正确性。为了让微服务本身更专注于业务,将类似于配置中心的OAuth2分离出来,作为基础组件的统一认证中心。OAuth2的作用类似于公安局在我们生活中的作用。当我们需要到正规机构办理业务时,需要提供有效身份证件(合法身份认证标志)。如果没有,需要在有效期内去公安局(OAuth)申请身份证(Token),然后我们就可以用这张身份证购买机票、酒店等社会服务(微服务)。社会服务机构收到您提供的身份证(Token)后,还会向公安局(OAuth)网络发送信息,验证您身份证的合法性(Token合法性验证)。将被拒绝服务,只有合法身份才能开展业务。关于OAuth的工作流程,可以结合下图来理解:微服务对于OAuth2规范有四种授权方式:密码/客户端凭证/授权码/隐式。SpringCloudOAuth2为我们提供了哪些便利?安全框架提供令牌生成和验证等逻辑。开箱即用并与其他服务无缝集成。行业标准,易于与云服务提供商集成。OAuth2:/auth/oauth/token的返回信息:access_token(OAuth2token,每次调用时出示)。token_type(令牌类型,commonbearertoken)。refresh_token(更新令牌)。expires_in(过期说明,默认12H)。范围(令牌有效范围)。OAuth2支持JWT(JSONWebToken)的规范,JWT的原理不做具体说明。一个简单的JWT具有以下特点:小(Base64编码)。加密签名(防篡改)。自包含(无需调用验证服务确认内容,通过同一密钥进行对称解密)。可扩展(附加信息可以包含在令牌中)。OAuth2简介:OAuth2是一个令牌认证框架。使用OAuth2需要建立OAuth2身份验证服务。对受保护资源的调用通过OAuth2进行身份验证。⑦SpringCloudStream消息驱动我们与世界的交互不是同步的。很多情况下,它是基于异步消息驱动的模型,比如email、ordering、booking等,想要了解SpringCloudStream,首先要了解基于事件(MQ)的编程模型,基于消息驱动,有利于开发和构建高度解耦的系统。因为SpringCloudStream本身并没有实现消息中间件,而是针对市场上主流的MQ产品(如RabbitMQ、KafKa)做了一层封装和抽象。SpringCloudStream所做的并不是什么新鲜事。它与ORM所做的非常相似。了解ORM框架的同学应该都知道抽象各种数据库(MySQL、Oracle、SQLServer)产品是多么重要。面向ORM的数据库访问,可以让你摆脱对特定数据库产品的深度依赖和束缚,无需学习不同数据库的本地化特性和方言,降低学习成本。如果你想从Oracle迁移到MySQL,你不需要更改一行代码,只需要更改ORM配置就可以实现。参考下图简单了解ORM:SpringCloudStream与ORM类似,你只需要基于SpringCloudStream提供的消息模型进行编程即可。底层消息组件是使用RabbitMQ、Kafka还是其他消息中间件产品并不重要。即使替换底层消息传递组件也不会对您的应用程序产生任何影响。这就是标准化的好处。为了更好的理解SpringCloudStream的工作模型,可以简单的参考下图:微服务中使用的两种服务通信方式比较:同步:通过REST端点接口请求:服务之间紧耦合(强依赖),添加新消费者之间的服务漏洞(连锁反应)是不灵活的。异步:基于消息的中间件通信:松耦合(依赖直接调用,无需接口),持久性(服务重启后可以消费历史消息),可扩展性(如果消息过多可以启动多个服务处理消息),灵活性(轻松添加新消费者)。消息传递架构的缺点:消息处理语义:消息序列处理、消息异常处理。消息可见性:消息不会被立即处理,消息中传递交易关联ID。消息中放置了哪些数据?消息体尽量小以降低传输成本:通常只返回actiontype和id,然后使用id获取最新的数据。Useonlymessagedeliverystate:在消息中包含一个版本号和一个时间戳,处理数据服务可以检查数据的版本号。SpringCloudStream的消息模型和概念:Transmitter(Source):接收一个对象(对象代表要发布的消息),序列化对象,将消息发布到通道。通道(Channel):队列的抽象,通道写在配置文件中,改变配置切换通道(读写队列)。Binder:与消息平台对话而不依赖特定API来发布和使用消息的Spring代码。Receiver(Sink):从队列中接收消息,并将消息反序列化为POJO。SpringCloudStream的快速总结:使用消息传递的异步通信是微服务架构的关键部分。使用消息传递可以使服务具有可伸缩性和更高的容错能力。SpringCloudStream通过简单的注解抽象出底层消息传递平台的细节。⑧Sleuth和Zipkin分布式追踪微服务分布式架构带来的复杂性,成本最高的是追踪检查和运维,分布式意味着在多个服务和机器中追踪一个事务,Sleuth和Zipkin都使用了SpringCloud用于服务的分布式追踪技术系统,我们直接看最后的效果。下图显示了一个简单的可视链接跟踪调用。ZipKin可以清楚地看到客户端请求处理每个服务所消耗的东西。点击查看具体的交易执行内容,方便排查问题。SpringCloudSleuth的工作流程:透明地创建关联ID并将其注入到服务调用中。管理相关ID到出站服务调用的传播。将关联信息添加到Spring的MDC日志记录(app/traceid/spanid/datasent)。将服务调用的跟踪信息发布到Zipkin跟踪平台。OpenZipkin简单概述:调用链使用干净简洁的图片,比一百万条日志要好得多。用于跨多个服务调用跟踪事务的分布式跟踪平台。以图形方式查看交易所花费的时间,细分每项服务所花费的时间。4种不同的数据存储:内存数据/MySQL/Cassandra/Elasticsearch。微服务全链路跟踪总结:SpringCloudSleuth可以无缝的为微服务添加关联ID。一个交易中涉及的所有服务行为都可以通过CorrelationID查看。关联ID需要与日志聚合结合使用。日志记录平台很重要,但交易的视觉跟踪也是一种有价值的工具。⑨部署微服务构建和部署流水线是微服务架构中最重要的部分。微服务的主要特点是快速构建、修改和发布。符合微服务特性的部署必须满足以下要求:Automatic(自动构建和部署代码。Complete(完成的软件是镜像),immutable(发布过程不能人为干预)。良好的微服务部署流水线应该允许在几分钟内部署新功能和修复bugSpringCloud大型项目架构解决方案这是国内某大型企业实际使用的微服务架构系统,支撑一个日均百万单的项目,因为已经过了2年的保密期,所以可以拿出来分享一下,大家可以结合之前乱七八糟的知识点,看看这套SpringCloud组件是如何搭建的。整套微服务架构图如下:各个组件的具体功能这里不再详述。在这个架构方案中,我们并没有完全照搬SpringCloud全家桶的搭建,但是我们还是根据自己的需要对组件进行了调整。替代品。例如:配置中心由SpringCloudConfig改为Apollo。除了更好的性能,还有更简化的操作页面,配置文件的修改毫秒级响应。服务发现Eureka官网已经停止维护,后续我们会更换为阿里巴巴Nacos。服务注册和心跳检测升级到毫秒级,Eureka是90秒轮询。分布式任务调度介绍XXL-JOB,是目前国内主流的分布式任务调度平台,没有特别说明。日志聚合也是采用主流的ELK技术方案来收集和检索日志。PS:另外值得补充的是,写这篇文章的时候官方已经不再推荐使用SpringCloudZuul了。替代方案是性能更好的SpringCloudGateway。看懂了就可以关注了。综上所述,微服务是未来大企业的必由之路。虽然成本高,但对于提高IT系统的健壮性和技术人员的广度和深度还是很有帮助的。作者:肖斌编辑:陶佳龙来源:转载自公众号肖二十七(ID:drak-phoenix)
