Spring Cloud 在国内中小型公司能用起来吗?从 2016 年初一直到现在,我们在这条路上已经走了一年多。
在使用 Spring Cloud 之前,我们对微服务实践是没有太多的体会和经验的。从最初的开源软件云收藏来熟悉 Spring Boot,到项目中的慢慢使用,再到最后全面拥抱 Spring Cloud。
这篇文章给大家介绍我们使用 Spring Boot / Cloud 一年多的经验总结。
在开始之前我们先介绍几个概念,什么是微服务,它的特点是什么? Spring Boot / Cloud 都做了那些事情?他们三者之间又有什么关系?
什么是微服务
微服务的概念源于 2014 年 3 月 Martin Fowler 所写的一篇文章“Microservices”。文中内容提到:微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。
每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的 RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。
另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。
微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。
微服务架构优势
01复杂度可控
在将应用分解的同时,规避了原本复杂度无止境的积累。每一个微服务专注于单一功能,并通过定义良好的接口清晰表述服务边界。
由于体积小、复杂度低,每个微服务可由一个小规模开发团队完全掌控,易于保持高可维护性和开发效率。
02独立部署
由于微服务具备独立的运行进程,所以每个微服务也可以独立部署。当某个微服务发生变更时无需编译、部署整个应用。
由微服务组成的应用相当于具备一系列可并行的发布流程,使得发布更加高效,同时降低对生产环境所造成的风险,最终缩短应用交付周期。
03技术选型灵活
微服务架构下,技术选型是去中心化的。每个团队可以根据自身服务的需求和行业发展的现状,自由选择最适合的技术栈。
由于每个微服务相对简单,所以需要对技术栈进行升级时所面临的风险就较低,甚至完全重构一个微服务也是可行的。
04容错
当某一组件发生故障时,在单一进程的传统架构下,故障很有可能在进程内扩散,形成应用全局性的不可用。
在微服务架构下,故障会被隔离在单个服务中。若设计良好,其他服务可通过重试、平稳退化等机制实现应用层面的容错。
05扩展
单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。当应用的不同组件在扩展需求上存在差异时,微服务架构便体现出其灵活性,因为每个服务可以根据实际需求独立进行扩展。
什么是 Spring Boot
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。
用我的话来理解,就是 Spring Boot 不是什么新的框架,它默认配置了很多框架的使用方式,就像 maven 整合了所有的 jar 包,Spring Boot 整合了所有的框架(不知道这样比喻是否合适)。
Spring Boot 简化了基于 Spring 的应用开发,通过少量的代码就能创建一个独立的、产品级别的 Spring 应用。Spring Boot 为 Spring 平台及第三方库提供开箱即用的设置,这样你就可以有条不紊地开始。
Spring Boot 的核心思想就是约定大于配置,多数 Spring Boot 应用只需要很少的 Spring 配置。采用 Spring Boot 可以大大的简化你的开发模式,所有你想集成的常用框架,它都有对应的组件支持。
Spring Cloud 都做了哪些事
Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。
Spring 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 Spring Boot 风格进行再封装、屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
以下为 Spring Cloud 的核心功能:
我们再来看一张图:
解释一下这张图中各组件的运行流程:
当然上面只是 Spring Cloud 体系的一部分,Spring Cloud 共集成了 19 个子项目,里面都包含一个或者多个第三方的组件或者框架!
Spring Cloud 工具框架:
这个数量还在一直增加...
三者之间的关系
微服务是一种架构的理念,提出了微服务的设计原则,从理论为具体的技术落地提供了指导思想。
Spring Boot 是一套快速配置脚手架,可以基于 Spring Boot 快速开发单个微服务。
Spring Cloud 是一个基于 Spring Boot 实现的服务治理工具包;Spring Boot 专注于快速、方便集成的单个微服务个体;Spring Cloud 关注全局的服务治理框架。
Spring Boot / Cloud 是微服务实践的最佳落地方案。
Spring Boot / Cloud 微服务实践背景
2015 年初的时候,因为公司业务的大量发展,我们开始对原有的业务进行拆分,新上的业务线也全部使用独立的项目来开发,项目和项目之间通过 http 接口进行访问。
2015 年的业务发展非常迅速,项目数量也就相应急剧扩大,到了年底的时候项目达 60 多个,当项目数达到 30 几个的时候,我们就遇到了问题,经常某个项目因为扩展增加了新的 IP 地址,就需要被动的更新好几个相关的项目。
服务越来越多,服务之间的调用关系也越来越复杂,有时候想画一张图来表示项目和项目之间的依赖关系,线条密密麻麻无法看清。下面有一张图可以表达我们的心情:
这个时候我们就想找一种方案,可以将我们这么多分布式的服务给管理起来,到网上进行了技术调研我们发现有两款开源软件比较适合我们,一个是 Dubbo,另一个是 Spring Cloud。
刚开始我们是走了一些弯路的,这两款框架我们都不熟悉,当时国内使用 Spring Cloud 进行开发的企业非常的少,我在网上也几乎没找到太多应用的案例。但是 Dubbo 在国内的使用还是挺普遍的,相关的资料各方面都比较完善。
因此在公司扩展新业务线众筹平台的时候,技术选型就先定了 Dubbo,因为也是全新的业务没有什么负担,这个项目我们大概开发了 6 个月投产,上线之初也遇到了一些问题,但最终还比较顺利。
在新业务线选型使用 Dubbo 的同时,我们也没有完全放弃 Spring Cloud,我们抽出了一两名开发人员学习 Spring Boot,我也参与其中。
为了验证 Spring Boot 是否可以到达实战的标准,我们在业余的时间使用 Spring Boot 开发了一款开源软件云收藏,经过这个项目的实战验证我们对 Spring Boot 就有了信心。
最重要的是大家体会到使用 Spring Boot 的各种便利之后,就再也不想使用传统的方式来进行开发了。
但是还有一个问题,在选择了 Spring Boot 进行新业务开发的同时,并没有解决我们上面的那个问题,服务与服务直接调用仍然比较复杂和传统,这时候我们就开始研究 Spring Cloud。
因为大家在前期对 Spring Boot 有了足够的了解,因此学习 Spring Cloud 就显得顺风顺水了。所以在使用 Dubbo 半年之后,我们又全面开始拥抱 Spring Cloud。
为什么选择使用 Spring Cloud 而放弃了 Dubbo
可能大家会问,为什么选择了使用 Dubbo 之后,又选择全面使用 Spring Cloud 呢?其中有如下四个原因:
01从两个公司的背景来谈
Dubbo,是阿里巴巴服务化治理的核心框架,并被广泛应用于中国各互联网公司;Spring Cloud 是大名鼎鼎的 Spring 家族的产品。
阿里巴巴是一个商业公司,虽然也开源了很多的顶级的项目,但从整体战略上来讲,仍然是服务于自身的业务为主。
Spring 专注于企业级开源框架的研发,不论是在中国还是在世界上使用都非常广泛,开发出通用、开源、稳健的开源框架是他们的主业。
02从社区活跃度这个角度来对比
Dubbo 虽然也是一个非常优秀的服务治理框架,并且在服务治理、灰度发布、流量分发这方面做的比 Spring Cloud 还好,除过当当网在此基础上增加了 rest 支持外,已有两年多的时间几乎没有任何更新了。
在使用过程中出现问题,开发者提交到 GitHub 的 Issue 也少有回复。相反 Spring Cloud 自从发展到现在,仍然在不断的高速发展。
从 GitHub 上提交代码的频度和发布版本的时间间隔就可以看出,现在 Spring Cloud 即将发布 2.0 版本,到了后期会更加完善和稳定。
03从整个大的平台架构来讲
Dubbo 框架只是专注于服务之间的治理,如果我们需要使用配置中心、分布式跟踪这些内容都需要自己去集成,这样无形中增加了使用 Dubbo 的难度。
Spring Cloud 几乎考虑了服务治理的方方面面,更有 Spring Boot 这个大将的支持,开发起来非常的便利和简单。
04从技术发展的角度来讲
Dubbo 刚出来的那会技术理念还是非常先进,解决了各大互联网公司服务治理的问题,中国的各中小公司也从中受益不少。
经过了这么多年的发展,互联网行业也是涌现了更多先进的技术和理念,Dubbo 一直停滞不前,自然有些掉队,有时候我个人也会感到有点可惜,如果 Dubbo 一直沿着当初的那个路线发展,并且延伸到周边,今天可能又是另一番景象了。
Spring 推出Spring Boot / Cloud 也是因为自身的很多原因。Spring 最初推崇的轻量级框架,随着不断的发展也越来越庞大,随着集成项目越来越多,配置文件也越来越混乱,慢慢的背离最初的理念。
随着这么多年的发展,微服务、分布式链路跟踪等更多新的技术理念的出现,Spring 急需一款框架来改善以前的开发模式,因此才会出现 Spring Boot / Cloud 项目。
我们现在访问 Spring 官网,会发现 Spring Boot 和 Spring Cloud 已经放到首页最重点突出的三个项目中的前两个,可见 Spring 对这两个框架的重视程度。
因此 Dubbo 曾经确实很牛逼,但是 Spring Cloud 是站在近些年技术发展之上进行的开发,因此更具技术代表性。
如何进行微服务架构演进
当我们将所有的新业务都使用 Spring Cloud 这套架构之后,就会出现这样一个现象:公司的系统被分成了两部分,一部分是传统架构的项目;另一部分是微服务架构的项目,如何让这两套配合起来使用就成为了关键。
这时候 Spring Cloud 里面的一个关键组件解决了我们的问题,就是 Zuul。在 Spring Cloud 架构体系内的所有微服务都通过 Zuul 来对外提供统一的访问入口,所有需要和微服务架构内部服务进行通讯的请求都走统一网关。如下图:
从上图可以看出我们对服务进行了四种分类,不同服务迁移的优先级不同:
组合服务,组合服务就是涉及到了具体的业务,比如买标过程,需要调用很多垂直的业务服务,这类的服务我们一般放到最后再进行微服务化架构来改造,因为这类服务最为复杂,除非涉及到大的业务逻辑变更,我们是不会轻易进行迁移。
在这四类服务之外,新上线的业务全部使用 Sprng Boot / Cloud 这套技术栈。
架构演化的步骤
架构演化的步骤如下:
传统项目和微服务项目共存是一个很常见的情况,除非公司业务有大的变化,不建议直接迁移核心项目。
服务拆分
服务拆分的两个原则:
要做好微服务的分层:梳理和抽取核心应用、公共应用,作为独立的服务下沉到核心和公共能力层,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
服务拆分是越小越好吗?微服务的大与小是相对的。比如在初期,我们把交易拆分为一个微服务,但是随着业务量的增大,可能一个交易系统已经慢慢变得很大,并且并发流量也不小。
为了支撑更多的交易量,我会把交易系统,拆分为订单服务、投标服务、转让服务等。因此微服务的拆分力度需与具体业务相结合,总的原则是服务内部高内聚,服务之间低耦合。
微服务 vs 传统开发
使用微服务有一段时间了,这种开发模式和传统的开发模式对比,有很大的不同,如下面几点:
给数据库带来的挑战
每个微服务都有自己独立的数据库,那么后台管理的联合查询怎么处理?这是大家普遍遇到的一个问题。
有如下三种处理方案:
三种方案在不同的公司我都使用过,第一种方案适合业务较为简单的小公司;第二种方案,适合想在原有系统之上,慢慢演化为微服务架构的公司;第三种适合大型高并发的互联网公司。
微服务的经验和建议
01建议尽量不要使用 Jsp,页面开发推荐使用 Thymeleaf
Web 项目建议独立部署 Tomcat,不要使用内嵌的 Tomcat,内嵌 Tomcat 部署 Jsp 项目会偶现龟速访问的情况。
02服务编排是个好东西,主要的作用是减少项目中的相互依赖
比如现在有项目 a 调用项目 b,项目 b 调用项目 c...一直到 h,是一个调用链,那么项目上线的时候需要先更新最底层的 h 再更新 g...更新 c 更新 b 最后是更新项目 a。
这只是一个调用链,在复杂的业务中有非常多的调用,如果要记住每一个调用链对开发运维人员来说就是灾难。
有一个好办法可以尽量的减少项目间的相互依赖,就是服务编排,一个核心的业务处理项目,负责和各个微服务打交道。
比如之前是 a 调用 b,b 掉用 c,c 调用 d,现在统一在一个核心项目 W 中来处理,W 服务使用 a 的时候去调用 b,使用 b 的时候W去调用 c。
举个例子:在第三方支付业务中,有一个核心支付项目是服务编排,负责处理支付的业务逻辑,W 项目使用商户信息的时候就去调用“商户系统”,需要校验设备的时候就去调用“终端系统”,需要风控的时候就调用“风控系统”,各个项目需要的依赖参数都由W来做主控。以后项目部署的时候,只需要最后启动服务编排项目即可。
03不要为了追求技术而追求技术
需要考虑以下几方面的因素:
总结
Spring Cloud 对于中小型互联网公司来说是一种福音,因为这类公司往往没有实力或者没有足够的资金投入去开发自己的分布式系统基础设施,使用 Spring Cloud 一站式解决方案能在从容应对业务发展的同时大大减少开发成本。
同时,随着近几年微服务架构和 Docker 容器概念的火爆,也会让 Spring Cloud 在未来越来越“云”化的软件开发风格中立有一席之地。
尤其是在目前五花八门的分布式解决方案中提供了标准化的、全站式的技术方案,意义可能堪比当前 Servlet 规范的诞生,有效推进服务端软件系统技术水平的进步。