天天看点

微服务架构技术设计方案(WORD)

作者:优享智慧方案
原文《微服务架构技术设计方案》WORD格式,主要从微服务架构思维设计、微服务系统架构设计、开发阶段等进行建设。

来源网络,旨在交流学习,如有侵权,联系速删,更多参考公众号:优享智库

微服务的选用

微服务架构从本质上说其实就是分布式架构,与其说是一种新架构,不如说是一种微服务架构风格。

简单来说,微服务架构风格是要开发一种由多个小服务组成的应用。每个服务运行于独立的进程,并且采用轻量级交互。多数情况下是一个HTTP的资源API。这些服务具备独立业务能力并可以通过自动化部署方式独立部署。这种风格使最小化集中管理,从而可以使用多种不同的编程语言和数据存储技术。

对于微服务架构系统,由于其服务粒度小,模块化清晰,因此首先要做的是对系统整体进行功能、服务规划,优先考虑如何在交付过程中,从工程实践出发,组织好代码结构、配置、测试、部署、运维、监控的整个过程,从而有效体现微服务的独立性与可部署性。

为了与高速公路建设投资总公司的现有信息系统架构无缝连接,本系统采用微服务技术架构来实现。

架构设计

思维设计

微服务架构设计的根本目的是实现价值交付,系统遵循DevOps的开发理念。

微服务架构技术设计方案(WORD)

实现微服务技术架构,系统在技术上的要求以及相关配套服务的实现,主要包括如下:

一、技术上要求:

1、前后端分离,web前端通过Http/Https协议调用微服务的API网关,由API网关再经过路由服务调用相应的微服务

2、不同微服务之间通过REST方式互相调用

3、微服务之间通过消息中间件实现消息交互机制

二、配套服务与功能实现 :

1、需要进行相应的自动化服务实现,包括自动化构建、自动化安装部署、自动化测试、自动化平台发布(Docker实现)

2、管理服务,对于微服务架构,必须配套相应的监控与管理服务、日志管理服务等

3、协作服务,运用DevOps思想提升开发、测试、运维的高效沟通与协作,实现开发与运维的一体化

系统架构设计

微服务架构技术设计方案(WORD)

架构图1

1、我们把整个系统根据业务拆分成若干个子系统或微服务。

2、每个子系统可以部署多个应用,多个应用之间使用负载均衡。

3、需要一个服务注册中心Eureka,所有的服务都在注册中心注册,负载均衡也是通过在注册中心注册的服务来使用一定策略来实现。Eureka可部署多个,进行高可用保证。

4、所有的客户端都通过同一个网关地址访问后台的服务,通过路由配置ZUUL网关来判断一个URL请求由哪个服务处理。请求转发到服务上的时候使用负载均衡Ribbon。

5、服务之间采用feign进行调用。

6、使用断路器hystrix,及时处理服务调用时的超时和错误,防止由于其中一个服务的问题而导致整体系统的瘫痪。

7、还需要一个监控功能,监控每个服务调用花费的时间等。

8、使用SpringCloud Config进行统一的配置管理,需要考虑与高管局现有的spring Cloud平台的配置管理平台如何配合使用。

9、Hystrix,监控和断路器。需要在服务接口上添加Hystrix标签,就可以实现对这个接口的监控和断路器功能。

10、Hystrix Dashboard,监控面板,提供了一个界面,可以监控各个服务上的服务调用所消耗的时间等。

11、Turbine,监控聚合,使用Hystrix监控,我们需要打开每一个服务实例的监控信息来查看。而Turbine可以帮助我们把所有的服务实例的监控信息聚合到一个地方统一查看。这样就不需要挨个打开一个个的页面一个个查看。

架构的可靠性保证:

在关键节点做主备、集群部署,防止单点故障。

设计阶段

总体设计

1、功能规划:对产品功能进行拆分,拆分为若干个微服务;一个功能可以创建多个微服务并部署在多个服务器节点上,以便进行负载均衡。

2、设计原子服务层,梳理和抽取核心应用、公共应用,作为独立的服务下沉到核心和公共能力层,逐渐形成稳定的服务中心,使应用能更快速的响应多变的客户需求。

3、为每个服务设计API接口(REST方式)

4、为不同的服务进行分类,不同类型的服务需要的资源不同,可以配置不同的资源,包括CPU、内存、存储等。

服务拆分原则

1、粒度微小:

根据业务功能划分服务粒度,总的原则是服务内部高内聚,服务之间低耦合。

2、责任单一:

每个服务只做一件事,即单一职责原则。

3、隔离性原则:

每个服务相互隔离,且不互相影响

4、业务无关优先原则:

基础服务,是一些基础组件,与具体的业务无关。比如:短信服务、邮件服务。这里的服务最容易划分出来做微服务,也是我们第一优先级分离出来的服务。

服务规划

为实现负载均衡,允许相同的服务在多个节点注册相同的服务名,不同的端口。如果没有前期的规划,不同的服务提供者可能会注册相同的服务名,导致消费者调用服务时产生调用混乱。

因此,需进行服务名的统一规划:

1、规划期统一制定每个服务提供者的服务名或者模块标示。

2、服务名的命名规则:ModuleName_ServiceName,且所有字符小写,不同单词之间以下划线分隔。如用户管理模块提供了获取用户信息的服务,则命名为:user_get_info。

3、新增服务名时,需要提出申请,审批通过后方可使用,为减少审批复杂度,可只审批ModuleName,即在模块内部可以自由增加服务名,不需要进行审批。

开发策略

总体原则:不同的微服务需进行物理隔离。

1、编译策略:代码编译时,各个微服务独立编译、打包,杜绝直接的依赖;

2、工程构建:代码开发时,各微服务创建独立的工程,工程之间不能产生直接依赖

3、持续集成:每个微服务独立执行持续集成。

数据库设计原则

每个微服务都有自己独立的数据库,那么后台管理的联合查询会非常困难。目前通用有四种处理方案。

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

2) 将业务高度相关的表放到一个库中,将业务关系不是很紧密的表严格按照微服务模式来拆分,这样既可以使用微服务,也避免了数据库分散导致后台系统统计功能难以实现,是一个折中的方案。

3)MySQL+MHA高可用架构 、MySQL分布式Proxy水平扩展架构、 MySQL缓存高并发读架构、 MySQL小文件系统大字段存取架构、MySQL Inforbright/Greenplum统计分析架构。

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

根据系统的实际需求,我们当前采用第二种设计方案。

负载均衡

不再采用一般的增加负载均衡服务器的方式进行负载均衡,如F5、Nginx、LVS等,而是把负载均衡的功能以库的方式集成到服务消费方的进程内,这种方案称为软负载均衡(Soft Load Balancing)或者客户端负载均衡。在Spring Cloud中配合Eureka的服务注册功能,Ribbon子项目则为REST客户端实现了负载均衡。

微服务架构技术设计方案(WORD)

使用Ribbon进行负载均衡,其工作原理可以概括为下面四个步骤:

  1. Ribbon首先根据其所在Zone优先选择一个负载较少的Eureka Server;
  2. 定期从Eureka Server更新并过滤服务实例列表;
  3. 根据指定的负载均衡策略,从可用的服务器列表中选择一个服务实例的地址;
  4. 然后通过RestClient进行服务调用。

Ribbon本身提供了下面几种负载均衡策略:

  • RoundRobinRule: 轮询策略,Ribbon以轮询的方式选择服务器,这个是默认值。所以示例中所启动的两个服务会被循环访问;
  • RandomRule: 随机选择,也就是说Ribbon会随机从服务器列表中选择一个进行访问;
  • BestAvailableRule: 最大可用策略,即先过滤出故障服务器后,选择一个当前并发请求数最小的;
  • WeightedResponseTimeRule: 带有加权的轮询策略,对各个服务器响应时间进行加权处理,然后在采用轮询的方式来获取相应的服务器;
  • AvailabilityFilteringRule: 可用过滤策略,先过滤出故障的或并发请求大于阈值一部分服务实例,然后再以线性轮询的方式从过滤后的实例清单中选出一个;
  • ZoneAvoidanceRule: 区域感知策略,先使用主过滤条件(区域负载器,选择最优区域)对所有实例过滤并返回过滤后的实例清单,依次使用次过滤条件列表中的过滤条件对主过滤条件的结果进行过滤,判断最小过滤数(默认1)和最小过滤百分比(默认0),最后对满足条件的服务器则使用RoundRobinRule(轮询方式)选择一个服务器实例。

性能策略

1、网络优化:优化组网结构,提升网络间通讯性能;

2、配置优化:优化Spring Cloud组件集以及其他组件的配置信息,使得性能最大化。

开发阶段

服务的调用

AIP网关调用

所有服务通过Zuul网关进行调用,不允许直接调用微服务提供者。

Zuul可能会成为系统瓶颈,复杂时可考虑为Zuul进行主备或负载均衡处理。

微服务架构技术设计方案(WORD)

同步调用

采用HTTP REST方式进行调用,针对业务需求可以进行负载均衡,负载均衡的调用方式有两种:

1、FeignClient

2、RestTemplate

系统使用FeignClient方式进行服务调用。

不管是什么方式,都是通过REST接口调用服务的http接口,参数和结果默认都是通过Jackson序列化和反序列化。因为Spring MVC的RestController定义的接口,返回的数据都是通过Jackson序列化成JSON数据。

微服务架构技术设计方案(WORD)

异步调用

系统采用RabbitMQ消息中间件来实现。

RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用。

服务间调用的权限验证

系统中的API接口都需要某种授权才能访问,登陆成功以后,然后通过token或者cookie等方式才能调用接口。

系统在登录的时候,把登录请求转发到相应的用户服务上,登录成功后,会设置cookie或header token等。然后客户端接下来的请求就会带着这些验证信息,从Zuul网关传到相应的服务上进行验证。

服务的熔断处理

在服务之间进行调用时,由于各种原因会导致远程服务不可用或压力过载等异常导致的故障蔓延,此时需要有一种机制进行保护处理。系统通过Netflix的Hystrix组件实现熔断和降级处理解决此问题。断路器(Cricuit Breaker)是一种能够在远程服务不可用时自动熔断(打开开关),并在远程服务恢复时自动恢复(闭合开关)的设施,通过Netflix的Hystrix组件提供断路器、资源隔离与自我修复功能。

微服务架构技术设计方案(WORD)

统一日志管理

不同微服务部署在不同节点上,登录每个节点查看日志是比较麻烦的,同时对于需要关联多个微服务日志联合查看分析的情况将更加麻烦。伴随节点数量的增加,如果没有合适的管理机制与工具,定位问题、发现问题的复杂性将越来越大,将成指数级增长,因此需要进行统一日志管理。

1、建立统一的日志管理规范;

2、开发并使用统一的日志组件,为所有微服务提供统一的日志服务,由slf4j封装;

3、在每个服务节点上部署日志采集Agent组件,由此Agent进行日志的采集与转发;

4、建立统一的日志中心,所有日志写入日志中心。

统一监控管理

使用Hystrix组件进行服务的监控,使用Nagios进行服务器等资源的监控。

1、Hystrix,监控和断路器。我们只需要在服务接口上添加Hystrix标签,就可以实现对这个接口的监控和断路器功能。

2、Hystrix Dashboard,监控面板,他提供了一个界面,可以监控各个服务上的服务调用所消耗的时间等。

3、Turbine,监控聚合,使用Hystrix监控,我们需要打开每一个服务实例的监控信息来查看。而Turbine可以帮助我们把所有的服务实例的监控信息聚合到一个地方统一查看。这样就不需要挨个打开一个个的页面一个个查看。

统一配置管理

实现各微服务的统一参数配置以及版本管理,采用Spring Cloud Config配置中心。

Spring Cloud Config配置中心

微服务架构技术设计方案(WORD)

Spring Cloud Config就是我们通常意义上的配置中心。Spring Cloud Config-把应用原本放在本地文件的配置抽取出来放在中心服务器,本质是配置信息从本地迁移到云端。从而能够提供更好的管理、发布能力。

Spring Cloud Config分服务端和客户端,服务端负责将git中存储的配置文件发布成REST接口,客户端可以从服务端REST接口获取配置。但客户端并不能主动感知到配置的变化,从而主动去获取新的配置,这需要每个客户端通过POST方法触发各自的/refresh。

为解决配置信息能及时通知到各服务,同时减少每个微服务处理配置信息更新的复杂度,为此我们通过消息总线来解决此问题,方案如下:

微服务架构技术设计方案(WORD)
  1. Git仓库、Config Server、以及微服务“Service A”、 “Service B”的实例中都引入了Spring Cloud Bus,所以他们都连接到了RabbitMQ的消息总线上。
  2. 从Git仓库中配置的修改到发起/bus/refresh的POST请求这一步可以通过Git仓库的Web Hook来自动触发。
  3. /bus/refresh请求不再发送到具体服务实例上,而是发送给Config Server,并通过destination参数来指定需要更新配置的服务或实例。
  4. 由于所有连接到消息总线上的应用都会接受到更新请求,所以在Web Hook中就不需要维护所有节点内容来进行更新,从而解决了通过Web Hook来逐个进行刷新的问题。

分布式缓存

采用Redis作为缓存数据库,采用三主三从的集群模式,3个节点分担访问和计算压力,每个节点的主备双机,保证高可用。

REST资源响应结构

rest全称Representational State Transfer, 是一种实现web service构架方式, 在这种框架下面, 对资源的访问和操作都是通过URI(Uniform Resource Identifiers)来实现的。

rest service具有简单, 轻量, 快速等特点。主要体现在:

  • 对资源的访问通过URI来完成, 客户端的集成简单, 我们用浏览器就可以来对rest service进行访问操作。
  • 统一的接口, rest service的操作用的是统一的http请求请求方式: PUT,GET, POST and DELETE。PUT操作用来添加的资源GET操作用来获取已有的资源POST操作用来对资源进行状态转换DELETE用来删除已有的资源
  • 灵活的消息解释格式. rest service的框架让service的实现独立于消息格式. 我们对service的访问可以用xml格式, json格式甚至plain text格式, 只需要在http请求header说明即可。
  • 无状态请求. rest service提供的操作本身是无状态操作, 无状态的意思是每个操作自身是一个独立完整的操作, 框架不保留接下来的操作与之前的操作状态上的关系

测试

微服务架构技术设计方案(WORD)
  • 单元测试:

由开发人员实现。

采用Mock方式进行测试模拟,由持续集成进行自动化单元测试的执行以及结果输出。

  • 业务测试:

将多个服务或业务单元进行串联,测试一个完整的业务,甚至是不同业务之间组成的系统测试。

持续集成

1、持续集成:每个微服务独立执行持续集成。

2、版本集成:由统一的集成工具,将所有微服务集成到统一的版本发布包中。

3、持续集成可制作多种场景的版本,包括测试环境、开发环境、生产环境。

4、统计测试覆盖率等指标数据。

持续部署

1、通过持续集成自动制作发布版本的Docker镜像;

2、将docker镜像自动上传到docker容器中。

微服务架构技术设计方案(WORD)

继续阅读