这几年招聘Java工程师的时候,你会看到很多人的简历上都说用SpringCloud做微服务实现,用Docker做自动化部署,他们也会把这些作为自己的亮点。图片来自Pexels,比较有意思的大多是小公司的人,而大公司的人很少在简历中提到这些东西。对于我自己来说,我从2015年就开始关注这方面了,看了MartinFowler关于微服务的原论文,也看了很多关于微服务演示的英文文章和书籍。也研究过Cloud、Sofa、ServiceMesh等Spring开源实现。考虑到我们公司研发团队人手不足,基础设施不完善,一开始并没有实现微服务。但是随着越来越多的看到上面提到的那种简历,有时候我也在想:不使用微服务真的就落后了吗?如果公司的同事不掌握这些,他们真的没有竞争力吗?随着近期公司业务的逐步完善,研发人员越来越多。在梳理公司微服务落地方案的同时,也梳理了微服务的相关知识点,这也是本文的主要内容。主要从以下几个方面与大家分享:什么是微服务为什么要采用微服务微服务架构架构设计模式服务拆分微服务框架服务不是唯一的选择,也不是灵丹妙药。国内绝大多数中小企业在引入微服务时都是盲目追新,也可以看出做这种技术选型的工程师基础素质不足。“你必须足够高才能使用微服务”。微服务基础设施,尤其是容器技术、自动化部署、自动化测试不完善。微服务是没有用的,不会带来任何质的提升。微服务架构的关键不在于具体实现,而在于如何合理划分服务边界,组织结构是否匹配。不考虑研发团队的规模和构成,一味采用微服务是一种糟糕的技术选择。SpringBoot是Spring全家桶的上层包。它不是什么新技术,也不配成为自己的杀手锏。SpringCloud中SpringCloudNetflix的组件已经在生产环境中经过验证,其他的建议慎重选择。什么是微服务?微服务起源于2005年云计算博览会上PeterRodgers博士提出的Micro-Web-Service,其基本思想类似于Unix的流水线设计理念。2014年,MartinFowler和JamesLewis共同提出微服务的概念,将微服务架构风格定义为通过一组小型服务开发单个应用程序的方法,每个服务运行在自己的进程中,并通过轻量级机制进行通信(HTTPAPI)。三个关键点是:小型自动化轻量级与SOA相比,微服务可以看作是SOA的一个子集,是一种轻量级的SOA,更细粒度的服务,独立的流程,数据分离,更强调敏捷性,持续交付,和DevOps和去中心化实践。其共同的架构原则:单一职责关注点分离:控制和逻辑分离模块化和分而治之的特点:服务组件化围绕业务能力的组织是产品而不是项目端点智能和哑管道:控制逻辑在最后,流水线只是对完全自动化的部署语言和数据传输的去中心化控制Failure-orienteddesignProgressivedesign总的来说,它的优缺点如下:优点:模块边界强;独立部署;技术选择的多样性。缺点:分布式带来编程的复杂性和远程调用的消耗;放弃强一致性,实现最终一致性;运维复杂性需要成熟的运维团队或运维基础设施。为什么使用微服务是否选择微服务取决于你要设计的系统的复杂程度。微服务是用来控制复杂系统的,下面介绍的是微服务本身的复杂性。其他分布式系统面临的问题,包括自动化部署、监控、容错、最终一致性等都需要解决。尽管已经有一些常用的解决方案,但仍然存在相当大的成本。生产力和复杂性之间的关系如图所示。可见,越是复杂的系统,微服务带来的好处就越大。另外,无论是单体应用还是微服务,都需要团队的技能能够驾驭。MartinFowler的观点之一是:除非管理单体应用的成本已经太复杂(大到难以修改和部署),否则不要考虑微服务。大多数应用应该选择单体架构,做好单体应用的模块化,而不是拆分成服务。因此,系统一开始就采用了单体架构,并做好了模块化工作。后来随着系统越来越复杂,模块/服务之间的界限越来越清晰,重构为微服务架构是一种合理的架构演进。小路。微服务可以考虑的四种情况:多人开发一个模块/项目,代码提交时经常发生冲突。这些模块是高度耦合的并且相互依赖。每个更改都需要涉及多个团队。单次发射要求太多,风险大。主辅业务耦合,横向扩展过程复杂。电路降级是关于if-else的。微服务的三个阶段:微服务1.0:只使用注册发现,基于SpringCloud或Dubbo开发。微服务2.0:采用熔断、限流、降级等服务治理策略,配备完备的服务工具和平台。微服务3.0:ServiceMesh将服务治理作为一个通用组件,下沉到平台层去实现。应用层只关注业务逻辑,平台层可以根据业务监控自动调度调整参数,实现AIOps和智能调度。微服务架构先决条件微服务的先决条件如下:快速环境提供能力:依托云计算和容器技术快速交付环境。基础监控能力:包括基础技术监控和业务监控。应用快速部署能力:要求部署流水线提供快速部署能力。Devops文化:需要具备良好的持续交付能力,包括全链路跟踪、快速环境提供和部署等,还需要快速响应能力(对问题和故障的快速响应),以及开发和运维之间的协同工作。此外,根据康威定律和逆康威定律(技术结构迫使组织结构改善),组织结构也是一个关键因素。对应微服务架构,组织架构需要遵循以下原则:一个微服务由一个团队维护,团队成员最好是三人。单个团队的任务和发展是独立的,独立于其他因素。团队是全功能的、全栈的、自治的、扁平的和自我管理的。基础设施微服务的实现需要依赖很多底层基础设施,包括微服务的编译、集成、打包、部署、配置等。PaaS平台用于解决微服务从开发到运行的全生命周期管理。架构环境管理、容器资源隔离与互通、服务伸缩与漂移、服务升级与回滚、服务熔断与降级、服务注册与发现。①最基本的基础设施进程间通信机制:微服务是独立的进程,需要确定它们之间的通信方式。服务发现+服务路由:提供服务注册中心,服务提供者和消费者通过服务发现获取服务信息调用服务,实现服务负载均衡。服务容错:在微服务架构中,由于服务数量众多,往往一个服务挂掉,影响整个请求链路的服务。因此需要服务容错,当服务调用失败时,能够快速处理错误或失败,包括熔断、Fallbacks、重试、流控、服务隔离等。分布式事务支持:由于业务拆分成服务,有时跨服务事务,即分布式事务是不可避免的。原则是尽量避免分布式事务。如果无法避免,可以使用消息系统或者CQRS和EventSourcing方案来实现最终一致性。如果需要强一致性,有两阶段提交、三阶段提交、TCC等分布式事务方案。②提高对外服务对接和内部开发API网关的效率:负责外部系统的接入和跨部门的公共层面工作,包括安全、日志、权限控制、传输加密、请求转发、流量控制等一个典型的网关功能就是对外暴露一个域名xx.com,根据一级目录进行反向路由xx.com/user,xx.com/trade。每一级目录,如user、trade,对应一个服务的域名。另外API网关还可以有服务编排的功能(不推荐)。接口框架:规范服务间通信的数据格式、解析包、自解释文档,便于服务使用者快速上手。③提高测试和运维效率配置中心:运行时配置管理,解决动态修改配置,批量生效的问题。包括配置版本管理、配置项管理、节点管理、配置同步等。持续交付:包括持续集成、自动化部署等流程。目的是小步迭代,快速交付。持续集成:这部分不是微服务特有的,对于以前的单体应用来说一般都是必须的。主要是指通过自动化手段对代码过程进行持续的编译、构建和自动化测试,以获得快速有效的质量反馈,从而保证代码的顺利交付。自动化测试包括代码层面的单元测试、单个系统的集成测试和系统间的接口测试。自动化部署:微服务架构,节点数可以是几百甚至上千,自动化部署可以提高部署的速度和频率,从而保证持续交付。包括版本管理、资源管理、部署操作、回滚操作等功能。至于微服务的部署方式,有蓝绿部署、滚动部署、金丝雀部署等。④进一步提升运维效率服务监控:微服务架构下节点众多,需要监控的机器、网络、进程、接口等数量大大增加。需要一个强大的监控系统,能够实时采集信息进行分析,实时分析预警。包括监控服务请求次数、响应时间分布、最大/最小响应值、错误码分布等服务跟踪:跟踪一个请求的完整路径,包括请求发起时间、响应时间、响应码、请求参数、返回结果和其他信息,也称为全链接跟踪。公共服务可以结合服务监控,通过服务跟踪呈现宏观信息,通过服务监控呈现单个服务/节点的微观信息。目前服务跟踪的实现理论基本上是Google的Dapperpaper。服务安全:原则上内网之间的微服务调用应该可以互相访问和写入。一般不需要权限控制,但有时限于业务需求,对接口、数据等方面有安全控制需求。这部分可以以配置的形式存在于服务注册中心,与服务绑定,在请求时作为服务提供者受服务节点的安全策略控制。配置可以保存在配置中心,方便动态修改。在微服务数量较少的情况下,上述基础设施的优先级从上到下递减。否则,仅靠人工操作,投入产出比会很低。另外值得一提的是Docker容器技术。虽然这对微服务来说不是必需的,但容器技术的轻量、灵活、依赖应用、屏蔽环境差异等特性对于实现持续交付至关重要,即使对于传统的单体应用也是如此。带来交付效率的大幅提升。在架构设计模式中引入微服务后,传统的单体应用变成了一个个服务,以前一个应用直接提供接口供客户端访问的架构不再适用。在微服务架构下,针对不同设备的接口被用作BFF层(BackendForFrontend),也称为用户体验适配层,负责将微服务的数据转换为前端需要的数据进行聚合整理.服务之间的调用尽可能使用异步消息传递(允许延迟),从而形成面向用户体验的微服务架构设计模式。如下图所示:Client→APIGateway→BFF(BackendForFrontend)→DownstreamMicroservices:后台采用微服务架构,微服务可以使用不同的编程语言和不同的存储机制。前台采用BFF模式,以适应不同的用户体验(如桌面浏览器、NativeApps、平板响应式Web)。BFF、APIOrchestrationLayer、EdgeServiceLayer、DeviceWrapperLayer是同一个概念。BFF不能太多,太多会导致代码逻辑冗余。网关所承担的功能,如Geoip、限流、安全认证等横切功能,可以与BFF同层完成。虽然增加了BFF层的复杂度,但可以获得性能优势。服务拆分微服务架构的核心环节是服务的水平拆分。服务拆分就是将一个完整的业务系统解耦为服务。服务需要职责单一,相互之间没有耦合关系,可以独立开发和维护。服务拆分不是一蹴而就的,需要在发展过程中不断厘清边界。尽量推迟拆分服务,尤其是数据库,直到你完全解决它们。拆分方式如下:基于业务逻辑的拆分基于可扩展性的拆分基于可靠性的拆分基于性能的拆分其中,对于不能修改的遗留系统,采用扼杀者模式:在遗留系统之外添加新功能做微服务它不是直接修改原有系统,而是逐步取代旧系统。拆分过程遵循的规范如下:先少后多,先粗后细(粒度)服务可以垂直拆分到三层,有两个调用:Controller,combinedservice,和basicservice只在一个方向调用,禁止循环调用serial调用改为并行调用或者异步接口应该是幂等的。接口数据定义严禁嵌入,标准化项目名称透传先拆分为服务,确定服务粒度后再拆分数据库。上面的微服务框架描述了微服务架构的诸多基础设施。如果每个基础设施都需要自己开发,那将是一个巨大的开发工作。市场上已经有很多开源微服务框架可供选择。SpringBootSpringBoot用于简化新Spring应用程序的初始构建和开发过程。虽然它不是微服务框架,但其最初的设计本质上是微应用的底层框架,因此非常适合微服务基础设施的开发和微服务的应用开发。尤其是对于Spring技术栈团队来说,基于SpringBoot开发微服务框架和应用更是自然而然的选择。Dubbo&MotanDubbo是阿里巴巴开源的服务治理框架。它出现在微服务概念兴起之前,堪称SOA框架的杰作。但它只包含了微服务基础设施的一些功能,如断路器、服务跟踪、网关等没有实现:服务发现:服务发布、订阅、通知。高可用性策略:故障转移、failfast、资源隔离-负载均衡:最少活跃连接、一致性哈希、随机请求、轮询等可扩展性:支持SPI扩展(服务提供者接口)。其他:调用统计、访问日志等。Motan是微博开源的一个类Dubbo的RPC框架,比Dubbo更轻量。SpringCloudSpringCloud是基于SpringBoot实现的微服务框架,也可以看作是一套微服务实现规范。基本涵盖了微服务基础设施的方方面面,包括配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话、集群状态管理等。它基于Spring生态,社区支持非常好。但是它的很多组件都没有经过生产环境的验证,需要慎重选择。SpringCloudNetflix是SpringCloud的一个子项目,是Spring对NetflixOSS的集成实现。基于Netflix的大规模使用,得到广泛应用的组件包括:Eureka:服务注册和服务发现Ribbon:弹性智能的进程间和服务通信机制,客户端负载均衡Hystrix:熔断器,运行时提供隔离Zuul:服务网关另外,SpringCloudAlibaba的另一个子项目是阿里巴巴开源的基于SpringBoot的微服务框架,主要支持阿里云服务。上述ServiceMesh的微服务框架都是有侵入性的,服务流程需要修改代码。ServiceMesh是下一代微服务架构,最明显的特点就是无入侵。采用Sidecar模型解决系统架构微服务化后的服务间通信和治理问题。如下图所示:目前主流的开源实现包括:Linkerd和Envoy:以Sidecar为核心,重点关注如何做好Proxy,完成一些通用的控制面功能。缺乏对这些边车的管理和控制。Istio和Conduit:目前最流行的ServiceMesh实现侧重于更强大的控制平面(Sidecar也叫数据平面)功能。前者是Google和IBM的合作,使用Envoy作为Sidecar实现的一部分;后者是Linkerd作者的作品。相比之下,Istio背景庞大,功能强大,但可用性和易用性一直不高,而Conduit则相对简单,专注于功能。受限于ServiceMesh带来的性能延迟开销和Sidecar带来的分发复杂度的增加,其对大规模部署(大量微服务)、异构复杂(多种交互协议/开发语言类型)微服务架构的影响好处会更大。SofastackAntFinancial是一套开源的中间件,用于构建金融级的分布式架构。一套完整的分布式应用开发工具,包括微服务开发框架、RPC框架、服务注册中心、全链路跟踪、服务监控、ServiceMesh等,尤其值得一提的是SOFAMesh。事实上,下一代微服务架构ServiceMesh的大规模落地,就是基于Istio的改进和扩展。应该是目前国内最成熟的开源ServiceMesh方案。另外需要说明的是,Kubernetes(K8s)本身提供了一些微服务特性支持(通过域名进行服务发现),对代码没有侵入性。但是服务调用和断路器需要自己实现。综上所述,公司技术团队目前的技术栈是Spring,现有服务的实现是基于Dubbo。因此,选择SpringCloudNetflix作为微服务基础框架,将不成熟或缺乏的组件替换为业界较为成熟的组件:APIGateway:Zuul。服务注册中心:Dubbo。配置中心:Disconf。服务监控和全链路跟踪:CAT。服务开发框架:SpringBoot。日志监控告警:ELK+Elasalert。流量控制:哨兵。消息队列:卡夫卡。参考资料:无论如何,整体式应用有什么不好……?!微服务MicroservicePremium微服务权衡MicroservicePrerequisites如何拆解MonolithFirst服务?BFF@SoundCloudServiceMesh及其主流开源实现分析作者:SaranHang简介:《Java 工程师修炼之道》作者。重度Java用户,关注JavaEE、三高系统架构、分布式等后端技术。
