基于Spring Cloud的微服务架构升级设计

0.793字数 4983阅读 5960

前言

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

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

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

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


[TOC]

1. 微服务简述

1.1. 什么是微服务

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

http://img.kuqin.com/upimg/allimg/141027/225ZB561-1.png

image_1c3fajgaov1dbt7132p1tu7jkc29.png-99.7kB
image_1c3fajgaov1dbt7132p1tu7jkc29.png-99.7kB

1.2. 微服务架构优势

http://www.primeton.com/img/insideout/jiagou.jpg

image_1c3fb07a11f47mnr1rdn13gn16a82m.png-180.7kB
image_1c3fb07a11f47mnr1rdn13gn16a82m.png-180.7kB

1 复杂度可控

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

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

2 独立部署

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

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

3 技术选型灵活

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

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

4 容错

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

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

5 扩展

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

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

1.3. 微服务 VS 当前开发

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

  • 分工不同 :现在一个组负责一个系统,一个人负责系统的一部分;微服务后可能是一人负责一个或多个系统。
  • 架构不同:现在更多的从模块上拆分、前后端上拆分开发;微服务后将同时从横向纵向上拆分。
  • 部署方式不同:现在是手工和半自动发布;微服务后得自动化运维。
  • 容灾不同:现在的系统是一个整体,并且是单点运行;微服务后可以多点负载,还可以隔离故障避免系统整体宕机。
  • 团队结构不同 2 pizza(6~10人)的小团队
此处输入图片的描述
此处输入图片的描述

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

2. 技术选型

2.1. Dubbo

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

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

2.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/

2.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配置

3. 我们微服务架构约定

3.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

3.2. Spring Cloud基础服务选型

  • 配置:Spring Cloud Config,统一配置管理
  • 总线:Spring Cloud Bus,可与Spring Cloud Config联合实现热部署
  • 发现:Eureka,微服务的注册与发现
  • 容错:Hystrix,断路器
  • 网关:Zuul,提供动态路由,监控,弹性,安全等边缘服务的框架
  • 负载:Ribbon,有多种负载均衡策略可供选择
  • 调用:Feign,一种声明式、模板化的HTTP客户端
  • 跟踪:Spring Cloud Sleuth, 日志收集工具包
  • 会话:Spring-Session

3.3. 工具版本约定

名称 版本 备注
Spring Boot 2.0.0.M6 -
Spirng Cloud Finchley.M4 -
Kotlin 1.2 需保持最新
JAVA 1.8.0_151
Gradle 4.4.1 保持更新
Maven 3.5.2 -
MySQL 5.7.17 -
MongoDB 3.6 -
PHP 7.2.0
Python 3.6.4
Redis 4.0.1 -
Docker 17.09 -
Jenkins 2.89.2 -
CentOS 7.4 -
SQL Server 2008 历史系统
Ansible 2.3.3.0-1 -
Tomcat 8.5.24 -

3.4 微服务设计原则

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

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

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

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

http://img2.tbcdn.cn/L1/461/1/74ab78cb5db601e5db68adf61e6dc58f437df4e0

image_1c3fahngk6qfu5l1adm5undoj1s.png-254.1kB
image_1c3fahngk6qfu5l1adm5undoj1s.png-254.1kB

第一定律: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.
大的系统组织总是比小系统更倾向于分解。

3.5 微服务拆分

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

3.5.1 横向拆分

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

  • 用户:
  • 订单:
  • 评论:
  • 组织:
  • 商品:
  • 交易:
  • 搜索:
  • 营销:
  • 消费者信息:
  • 消费者分布:
  • 消费者画像:
  • 积分:
  • 订货:
  • 账户:

3.5.2 纵向拆分

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

  • 短信:短信发送、记录、均衡、防漏、模板配置
  • 文件:文件上传、缩略、下载、打包、数据库记录
  • 微信:
  • 日志:
  • 支付:
  • 快递:快递查询、状态订阅
  • 地图:地址经纬度互转、距离计算、线路推荐
  • 计划任务:统一的计划任务配置及调度
  • 微信公众号配置:
  • 微信自动回复:

3.6 架构升级步骤

  1. 独立构建微服务框架,将现有系统的核心功能分离出来做成基础微服务。如短信模板消息发送、微信模板消息发送、文件上传下载等;
  2. 利用这些基础微服务,解耦现有系统,修改其调用关系和依赖方式;
  3. 通过不断的微服务化,逐渐将现有系统分解成多个独立的微服务;
  4. 废弃现有的系统,使用全新构建的微服务来替代。

3.7. 微服务总体架构图

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

Spring Cloud架构图.png-141.5kB
Spring Cloud架构图.png-141.5kB

基于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还支持可插拔的编码器与解码器

4. 微服务带来的新问题

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

严格按照微服务的划分来做,微服务相互独立,各微服务数据库也独立,后台需要展示数据时,调用各微服务的接口来获取对应的数据,再进行数据处理后展示出来,这是标准的用法,也是最麻烦的用法。
将业务相关的表放到一个库中,将业务无关的表严格按照微服务模式来拆分,这样既可以使用微服务,也避免了数据库各种切换导致后台统计难以实现,是一个折中的方案。
数据库严格按照微服务的要求来切分,以满足业务高并发,实时或者准实时将各微服务数据库数据同步到 NoSQL 数据库中,在同步的过程中进行数据清洗,用来满足后台业务系统的使用,推荐使用 Mongodb、Hbase 等。
三种方案在不同的公司我都使用过,第一种方案适合业务较为简单的小公司;第二种方案,适合想在原有系统之上,慢慢演化为微服务架构的公司;第三种适合大型高并发的互联网公司。

  • 如何与现有系统结合使用、并行开发、最终替代?
  • 如何避免开发人员瞎子摸象、管中窥豹?
  • 服务调用流,服务编排如何使用?
  • 自动化运维的新挑战?

5. 结束语

微服务架构不是绝对的好,它有一定的使用场景,也有一定的落地难度。结合我们目前的情景和未来的发展来说,微服务架构是适合我们的,并且能够解决很多现有系统的诟病,但是落地的难度也是比较大的,特别是要结合已有的各个系统进行使用。
Spring Cloud作为稳定的微服务的一站式解决方案,能快速高效地搭建微服务架构,并且能够结合多语言开发,这个正是我们所需要的。
从今天开始,微服务的架构升级正式开始,一部分人直接开始参与,一部分人员间接来参与,但最终我们所有人都会在一个统一的架构上进行持续交付,从而更大的实现用户价值。

6. 推荐阅读

《Spring Boot 2精髓:从构建小系统到架构分布式大系统》
《Spring Cloud与Docker微服务架构实战》
《Spring Cloud微服务实战》
《SpringBoot揭秘:快速构建微服务体系》

推荐阅读更多精彩内容