查看原文
其他

经过一年的煎熬,我们还是决定把系统升级成基于Spring Cloud的微服务架构

# 前言


现在研发的项目启动今已近一年之久,期间从项目属性、人员规模、系统定位等方面都发生了很大的变化,而且是越变越好。不过也因为此,项目最初的架构设计已经不能满足现在的需求,并随着时间的推移,诟病越来越多、越来越严重。


为了解决这一问题,开发人员也在努力的尝试各种办法,但总的来说之前的方式更多是在打补丁,暂时或看上去是解决问题了,实质上并没有从本质的变化。基于这一情况,这一次我们下定决心,用一定的人力、物力去重新定义系统的架构——基于Spring Cloud实现微服务的架构。


本文简要介绍微服务及微服务架构的概念,并描述了Spring Cloud的功能,然后基于Spring Cloud的各个组件搭建微服务的整体架构,并对升级后的系统架构进行了设计、约定和说明。


特别说明:鉴于现在的开发模式采用的是前后端分离的模式,系统问题在后端也较为严重,Spring Cloud也只一个后端治理的框架,所以本文主要讲述的是后端微服务的架构设计,前端的架构调整等Spring Cloud雏形完成后进行组合设计。


# 微服务简述


1. 什么是微服务


微服务(MicroService)没有一个官方的标准定义,ThoughtWorks的首席科学家马丁·福勒这样说:“微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。



2. 微服务架构优势



1 复杂度可控


在将应用分解的同时,规避了原本复杂度无止境的积累。每一个微服务专注于单一功能,并通过定义良好的接口清晰表述服务边界。


由于体积小、复杂度低,每个微服务可由一个小规模开发团队完全掌控,易于保持高可维护性和开发效率。


2 独立部署


由于微服务具备独立的运行进程,所以每个微服务也可以独立部署。当某个微服务发生变更时无需编译、部署整个应用。


由微服务组成的应用相当于具备一系列可并行的发布流程,使得发布更加高效,同时降低对生产环境所造成的风险,最终缩短应用交付周期。


3 技术选型灵活


微服务架构下,技术选型是去中心化的。每个团队可以根据自身服务的需求和行业发展的现状,自由选择最适合的技术栈。


由于每个微服务相对简单,所以需要对技术栈进行升级时所面临的风险就较低,甚至完全重构一个微服务也是可行的。


4 容错


当某一组件发生故障时,在单一进程的传统架构下,故障很有可能在进程内扩散,形成应用全局性的不可用。


在微服务架构下,故障会被隔离在单个服务中。若设计良好,其他服务可通过重试、平稳退化等机制实现应用层面的容错。


5 扩展


单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。当应用的不同组件在扩展需求上存在差异时,微服务架构便体现出其灵活性,因为每个服务可以根据实际需求独立进行扩展。


简单来说,微服务是基于单体应用的新型架构模式,可以基于微服务更好的进行自动化测试、运维、监控,从而满足持续交付,最终实现高质量的用户价值。


3. 微服务 VS 当前开发


微服务的开发模式和传统开发模式有着很大的不同,大致有以下几点:


  • 分工不同 :现在一个组负责一个系统,一个人负责系统的一部分;微服务后可能是一人负责一个或多个系统。

  • 架构不同:现在更多的从模块上拆分、前后端上拆分开发;微服务后将同时从横向纵向上拆分。

  • 部署方式不同:现在是手工和半自动发布;微服务后得自动化运维。

  • 容灾不同:现在的系统是一个整体,并且是单点运行;微服务后可以多点负载,还可以隔离故障避免系统整体宕机。

  • 团队结构不同 2 pizza(6~10人)的小团队


分权机制

联邦分权制 -- 对结果负责
职能分权制 -- 对行为负责


#  技术选型


1. Dubbo


Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。


Dubbo服务的官方更新非常不确定,2014年10月30日停止更新后,最近几个月低调开始维护,发布了5个优化版本。


2. 为什么选择Spring Cloud


Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。


Spring Cloud的开发团队专注于企业级开源框架的研发,不论是在中国还是在世界上使用都非常广泛,开发出通用、开源、稳健的开源框架是他们的主业。


Spring Cloud是微服务架构的生态环境,考虑到了微服务的各个方面,不像阿里的Dubbo 框架只是专注于服务之间的治理。


Spring Cloud的社区热度非常好,问题修复也非常及时,未来会更加完善和稳定。


Spring Cloud也可以较好的兼容python、php等其他语言开发的微服务。因为采用RESTful。


Spring Cloud与Docker可以完美组合使用。


Spring Cloud 英文官网:http://projects.spring.io/spring-cloud/
Spring Cloud 中文文档:https://springcloud.cc/


3. Spring Boot的特性


Spring Boot是一个简化Spring使用的框架,可以使用少量的配置快速创建一个基于Spring的项目。


Spring Boot主要有如下核心功能:


  • 独立运行的Spring项目:Spring Boot可以以jar包的形式来运行,运行一个Spring Boot项目我们只需要通过java -jar xx.jar类运行。

  • 内嵌Servlet容器:Spring Boot可以内嵌Tomcat,这样我们无需以war包的形式部署项目。

  • 提供starter简化Maven配置:使用Spring或者SpringMVC我们需要添加大量的依赖,而这些依赖很多都是固定的,这里Spring Boot 通过starter能够帮助我们简化Maven配置。

  • 自动配置Spring

  • 提供生产就绪型功能,如指标,健康检查和外部配置

  • 无代码生成和xml配置


# 我们微服务架构约定


1. 技术栈


编程语言:Kotlin、JAVA、Python、PHP、SQL
构建工具:Gradle、Maven
数据库:MySQL、MongoDB、SQL Server
缓存:Redis
消息队列:RabbitMQ
IDE:IntelliJ IDEA、Eclipse
服务部署:Linux、Docker、Jenkins、Ansible
微服务框架:Spring Cloud
后端开发框架:Spring Boot
前端开发框架:VUE


2. Spring Cloud基础服务选型


  • 配置:Spring Cloud Config,统一配置管理

  • 总线:Spring Cloud Bus,可与Spring Cloud Config联合实现热部署

  • 发现:Eureka,微服务的注册与发现

  • 容错:Hystrix,断路器

  • 网关:Zuul,提供动态路由,监控,弹性,安全等边缘服务的框架

  • 负载:Ribbon,有多种负载均衡策略可供选择

  • 调用:Feign,一种声明式、模板化的HTTP客户端

  • 跟踪:Spring Cloud Sleuth, 日志收集工具包

  • 会话:Spring-Session


3. 工具版本约定


名称版本备注
Spring Boot2.0.0.M6-
Spirng CloudFinchley.M4-
Kotlin1.2需保持最新
JAVA1.8.0_151
Gradle4.4.1保持更新
Maven3.5.2-
MySQL5.7.17-
MongoDB3.6-
PHP7.2.0
Python3.6.4
Redis4.0.1-
Docker17.09-
Jenkins2.89.2-
CentOS7.4-
SQL Server2008历史系统
Ansible2.3.3.0-1-
Tomcat8.5.24-


4 微服务设计原则


  • 单一职责:


    每个服务都很小,且专注于做一件事情,并且把它做好。
    至于要多小,有人喜欢100行以内,有人赞成1000行以内,数字并不是最重要的,只要团队觉得合适就好。

  • 轻量通讯


    服务和服务之间通过轻量级的机制实现彼此间的通信。所谓轻量级通信机制,通常指基于语言无关、平台无关的这类协议,例如XML、JSON,而不是传统我们熟知的Java RMI或者.Net Remoting等。


  • 独立部署

    每个服务都运行在一个独立的操作系统进程中,这意味着不同的服务能被部署到不同的主机上。

  • 康威定律


    请读:https://yq.aliyun.com/articles/8611
    将1968年由梅尔.康威提出:产品反映了制造该产品的组织结构。



第一定律:Communication dictates design. 组织沟通方式会通过系统设计表达出来。


第二定律:There is never enough time to do something right, but there is always enough time to do it over.
时间再多一件事情也不可能做的完美,但总有时间做完一件事情。


第三定律:There is a homomorphism from the linear graph of a system to the linear graph of its design organization.
线型系统和线型组织架构间有潜在的异质同态特性。


第四定律:The structures of large systems tend to disintegrate during development, qualitatively more so than with small systems.
大的系统组织总是比小系统更倾向于分解。


5 微服务拆分


微服务的拆分是个复杂问题,简单来说需要从横向和纵向多刀去拆。


横向拆分


按照不同的业务域进行拆分,例如订单、营销、风控、积分资源等,形成独立的业务领域微服务集群。


  • 用户:

  • 订单:

  • 评论:

  • 组织:

  • 商品:

  • 交易:

  • 搜索:

  • 营销:

  • 消费者信息:

  • 消费者分布:

  • 消费者画像:

  • 积分:

  • 订货:

  • 账户:


纵向拆分


把一个业务功能里的不同模块或者组件进行拆分。例如把公共组件拆分成独立的原子服务,下沉到底层,形成相对独立的原子服务层。这样一纵一横,就可以实现业务的服务化拆分。


  • 短信:短信发送、记录、均衡、防漏、模板配置

  • 文件:文件上传、缩略、下载、打包、数据库记录

  • 微信:

  • 日志:

  • 支付:

  • 快递:快递查询、状态订阅

  • 地图:地址经纬度互转、距离计算、线路推荐

  • 计划任务:统一的计划任务配置及调度

  • 微信公众号配置:

  • 微信自动回复:


6 架构升级步骤


  1. 独立构建微服务框架,将现有系统的核心功能分离出来做成基础微服务。如短信模板消息发送、微信模板消息发送、文件上传下载等;

  2. 利用这些基础微服务,解耦现有系统,修改其调用关系和依赖方式;

  3. 通过不断的微服务化,逐渐将现有系统分解成多个独立的微服务;

  4. 废弃现有的系统,使用全新构建的微服务来替代。

7. 微服务总体架构图


构件一套完整的微服务架构需要考虑许多问题,包括API Gateway、服务间调用、服务发现、服务容错、服务部署、数据调用等。基于SpringCloud构建微服务架构可以通过自动配置和绑定Spring环境和其他Spring编程模型来实现微服务。采用Spring Boot应用程序提供的集成功能,通过几个简单的注释,开发人员可以快速配置和启用应用程序中的常见功能模块,并使用久经考验的Netflix组件构建大型分布式系统。 提供的微服务功能模块包括服务发现(Eureka),断路器(Hystrix),智能路由(Zuul)和客户端负载均衡(Ribbon)等。图2显示了采用Spring Cloud系列平台构建的微服务整体架构。



基于Spring Cloud系统的微服务架构平台


服务发现是microservice基础架构的关键原则之一。服务注册中心采用Spring CloudNetflix的项目可以自动注册服务,也可以通过HTTP接口手动注册。默认情况下,Eureka使用客户端心跳来确定一个客户端是否活着。也可以另指定DiscoveryClient来传播当前SpringBoot Actuator的应用性能的健康检查状态。


统一的接入服务接口采用Spring Cloud的Zuul组件,实现内外有别的微服务调用。该组件也实现了服务路由功能。采用Spring Cloud Netflix来实现服务的限流和降级。


为实现服务的高可用,保证服务的容错和负载均衡,本平台可采用客户端负载均衡(Ribbon)来实现。


Spring Cloud Netflix的Hystrix熔断器组件,具有容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。为保证核心服务的稳定性,可采用Spring Cloud Netflix的Hystrix组件来实现服务的服务的容错、限流和降级等功能。


微服务的安全控制和权限验证可采用Spring CloudSecurity来实现。对于RESTful,可采用Spring Cloud的Feign 组件,这是一个声明Web服务客户端。这便得编写web服务客户端更容易,使用Feign 创建一个接口并对它进行注解,它具有可插拔的注解支持包括Feign注解与JAX-RS注解,Feign还支持可插拔的编码器与解码器


# 微服务带来的新问题


  • 一个服务拆成多大才合适?

  • 多个微服务能否共享数据库?
    每个微服务都有自己独立的数据库,那么后台管理的联合查询怎么处理?这是大家普遍遇到的一个问题。


    有如下三种处理方案:

严格按照微服务的划分来做,微服务相互独立,各微服务数据库也独立,后台需要展示数据时,调用各微服务的接口来获取对应的数据,再进行数据处理后展示出来,这是标准的用法,也是最麻烦的用法。


将业务相关的表放到一个库中,将业务无关的表严格按照微服务模式来拆分,这样既可以使用微服务,也避免了数据库各种切换导致后台统计难以实现,是一个折中的方案。


数据库严格按照微服务的要求来切分,以满足业务高并发,实时或者准实时将各微服务数据库数据同步到 NoSQL 数据库中,在同步的过程中进行数据清洗,用来满足后台业务系统的使用,推荐使用 Mongodb、Hbase 等。


三种方案在不同的公司我都使用过,第一种方案适合业务较为简单的小公司;第二种方案,适合想在原有系统之上,慢慢演化为微服务架构的公司;第三种适合大型高并发的互联网公司。


  • 如何与现有系统结合使用、并行开发、最终替代?

  • 如何避免开发人员瞎子摸象、管中窥豹?

  • 服务调用流,服务编排如何使用?

  • 自动化运维的新挑战?


# 结束语


微服务架构不是绝对的好,它有一定的使用场景,也有一定的落地难度。结合我们目前的情景和未来的发展来说,微服务架构是适合我们的,并且能够解决很多现有系统的诟病,但是落地的难度也是比较大的,特别是要结合已有的各个系统进行使用。


Spring Cloud作为稳定的微服务的一站式解决方案,能快速高效地搭建微服务架构,并且能够结合多语言开发,这个正是我们所需要的。


从今天开始,微服务的架构升级正式开始,一部分人直接开始参与,一部分人员间接来参与,但最终我们所有人都会在一个统一的架构上进行持续交付,从而更大的实现用户价值。


作者:孙振强
链接:https://www.jianshu.com/p/f564be0cdb54



 往期推荐 

🔗



 

点击阅读原文,获得更多精彩内容

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存