基于SpringCloud分布式架构
基于SpringCloud分布式架构
为什么要使用分布式架构
- Spring Cloud 专注于提供良好的开箱即用经验的典型用例和可扩展性机制覆盖
- 分布式/版本化配置
- 服务注册和发现
- 路由
- Service-to-Service 调用
- 负载均衡
- 断路器
- 分布式消息传递
这是分布式的优点,这样看起来可能比较抽象,举个例子来说,对于单体服务来说,如果我想更新订单中的某个功能,我是不是需要重启整个服务。
这个时候就会导致整个项目都处于不可用状态,或者在处理订单的时候由于程序代码写的有问题,导致死锁了,这个时候也会导致整个服务处于宕机专改,容错率很差。
但是分布式不同,如上图所示,订单服务、售后服务、用户服务都是独立的服务,如果需要更新订单服务或者订单服务发生死锁,受影响的只会是订单服务,售后服务与用户服务还是可以正常工作的,这就是分布式相对单体来说最大的优势之一。
分布式基础组件
Spring Cloud Config:配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git 以及 Subversion。
Spring Cloud Bus:事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与 Spring Cloud Config 联合实现热部署。
Eureka:云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
Hystrix:熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
Zuul:Zuul 是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。
Archaius:配置管理 API,包含一系列配置管理 API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。
Consul:封装了 Consul 操作,Consul 是一个服务发现与配置工具,与 Docker 容器可以无缝集成。
Spring Cloud for Cloud Foundry:通过 Oauth2 协议绑定服务到 CloudFoundry,CloudFoundry 是 VMware 推出的开源 PaaS 云平台。
Spring Cloud Sleuth:日志收集工具包,封装了 Dapper 和 log-based 追踪以及 Zipkin 和 HTrace 操作,为 Spring Cloud 应用实现了一种分布式追踪解决方案。
Spring Cloud Data Flow:大数据操作工具,作为 Spring XD 的替代产品,它是一个混合计算模型,结合了流数据与批量数据的处理方式。
Spring Cloud Security:基于 Spring Security 的安全工具包,为你的应用程序添加安全控制。
Spring Cloud Zookeeper:操作 Zookeeper 的工具包,用于使用 Zookeeper 方式的服务发现和配置管理。
Spring Cloud Stream:数据流操作开发包,封装了与 Redis、Rabbit、Kafka 等发送接收消息。
Spring Cloud CLI:基于 Spring Boot CLI,可以让你以命令行方式快速建立云组件。
Ribbon:提供云端负载均衡,有多种负载均衡策略可供选择,可配合服务发现和断路器使用。
Turbine:Turbine 是聚合服务器发送事件流数据的一个工具,用来监控集群下 Hystrix 的 Metrics 情况。
Feign:Feign 是一种声明式、模板化的 HTTP 客户端。
Spring Cloud Task:提供云端计划任务管理、任务调度。
Spring Cloud Connectors:便于云端应用程序在各种 PaaS 平台连接到后端,如:数据库和消息代理服务。
Spring Cloud Cluster:提供 Leadership 选举,如:Zookeeper,Redis,Hazelcast,Consul 等常见状态模式的抽象和实现。
Spring Cloud Starters:Spring Boot 式的启动项目,为 Spring Cloud 提供开箱即用的依赖管理。
我们常用的组件:
- Spring Cloud Config
- Spring Cloud Bus
- Hystrix
- Eureka
- Zuul
- Ribbon
- Feign
Eureka
Eureka 属于 Spring Cloud Netflix 下的组件之一,主要负责服务的注册与发现,何为注册与发现?
在刚刚我们分析的分布式中存在这一个问题,那就是订单服务与用户服务被独立了,那么他们怎么进行通信呢?比如在订单服务中获取用户的基础信息,这个时候我们需要怎么办?
如果按照上面的架构图,直接去数据库获取就可以了,因为服务虽然独立了,但是数据库还是共享的,所以直接查询数据库就能得到结果,如果我们将数据库也拆分了呢?这个时候我们该怎么办呢?
有人想到了,服务调用,服务调用是不是需要 IP 和端口才可以,那问题来了,对于订单服务来说,我怎么知道用户服务的 IP 和端口呢?在订单服务中写死吗?如果用户服务的端口发生改变了呢?
这个时候 Eureka 就出来了,他就是为了解决服务的通信问题,每个服务都可以将自己的信息注册到 Eureka 中,比如 IP、端口、服务名等信息,这个时候如果订单服务想要获取用户服务的信息,只需要去 Eureka 中获取即可。
请看下图:
这就是 Eureka 的主要功能,也是我们使用中的最值得注意的,他让服务之间的通信变得更加的简单灵活。
Spring Cloud Config
Spring Cloud Config 为分布式系统中的外部配置提供服务器和客户端支持。使用 Config Server,您可以在所有环境中管理应用程序的外部属性。
客户端和服务器上的概念映射与 Spring Environment 和 PropertySource 抽象相同,因此它们与 Spring 应用程序非常契合,但可以与任何以任何语言运行的应用程序一起使用。
随着应用程序通过从开发人员到测试和生产的部署流程,您可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切。
服务器存储后端的默认实现使用 Git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。可以轻松添加替代实现,并使用 Spring 配置将其插入。
简单点来说集中来管理每个服务的配置文件,将配置文件与服务分离,这么多的目的是什么?
举个简单的栗子,我们配置文件中肯定会存在数据库的连接信息,Redis 的连接信息,我们的环境是多样的,有开发环境、测试环境、预发布环境、生产环境。
每个环境对应的连接信息肯定是不相同的,难道每次发布的时候都要去修改一下服务中的配置文件?
我能不能将这些变动较大的配置集中管理,不同环境的管理者分别对他们进行修改,就不需要再服务中做改动了,Config 就做到了。
这就是 Config 的大致架构,所有的配置文件都集中交给 Config 管理,拿 Config 怎么管理这些配置文件呢?
你可以将每个环境的配置文件存放再一个位置,比如 Lgitlab、SVN、本地等等,Config 会根据根据你设置的位置读取配置文件进行管理,然后其他服务启动的时候直接到 Config 配置中心获取对应的配置文件即可。
这样开发人员只需要关注 -dev 的配置文件,测试人员只需要关注 -test 的配置文件,完全和服务解耦,你值得拥有。
Netflix Zuul(网关)
路由在微服务体系结构的一个组成部分。例如,/可以映射到您的 Web 应用程序,/api/users 映射到用户服务,并将 /api/shop 映射到商店服务。Zuul 是 Netflix 的基于 JVM 的路由器和服务器端负载均衡器。
Netflix 使用 Zuul 进行以下操作:
- 认证 -洞察
- 压力测试
- 金丝雀测试
- 动态路由
- 服务迁移
- 负载脱落
- 安全
- 静态响应处理
- 主动/主动流量管理
我们在日常开发过程中并不会使用那么多,基本上就是认证、动态路由、安全等等,我画了一张关于网关的架构图,请看:
注意:Nginx 只能为我们做反向代理,不能做到权限认证,网关不但可以做到代理,也能做到权限认证、甚至还能做限流,所以我们要做分布式项目,少了他可不行。
Spring Cloud Bus
application.yml
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/test
driver-class-name: com.mysql.cj.jdbc.Driver
比如上面这行配置大家都应该很熟悉,这是数据库的连接信息,如果它发生改变了怎么办呢?
我们都知道,服务启动的时候会去 Config 配置中心拉取配置信息,但是启动完成之后修改了配置文件我们应该怎么办呢,重启服务器吗?
我们可以通过 Spring Cloud Bus 来解决这个问题,Spring Cloud Bus 将轻量级消息代理链接到分布式系统的节点。然后可以将其用于广播状态更改(例如,配置更改)或其他管理指令。
我们可以通过 Spring Cloud Bus 来解决这个问题,Spring Cloud Bus 将轻量级消息代理链接到分布式系统的节点。然后可以将其用于广播状态更改(例如,配置更改)或其他管理指令。
这个需要我们有一点的 MQ 基础,不管是 RabbitMQ 还是 Kafka,都可以。
Bus 的基本原理就是:配置文件发生改变时,Config 会发出一个 MQ,告诉服务,配置文件发生改变了,并且还发出了改变的哪些信息,这个时候服务只需要根据 MQ 的信息做实时修改即可。
这是一个很简单的原理,理解起来可能也不会怎么难,画个图来理解一下:
大致流程就是这样,核心就是通过 MQ 机制实现不重启服务也能做到配置文件的改动,这方便了运维工程师,不用每次修改配置文件的时候都要去重启一遍服务的烦恼。
Feign
Feign 是一个声明式的 Web 服务客户端。这使得 Web 服务客户端的写入更加方便 要使用 Feign 创建一个界面并对其进行注释。
它具有可插入注释支持,包括 Feign 注释和 JAX-RS 注释。Feign 还支持可插拔编码器和解码器。
Spring Cloud 增加了对 Spring MVC 注释的支持,并使用 Spring Web 中默认使用的 HttpMessageConverters。
Spring Cloud 集成 Ribbon 和 Eureka 以在使用 Feign 时提供负载均衡的 HTTP 客户端。
Feign 基于 Rest 风格,简单易懂,他的底层是对 HttpClient 进行了一层封装,使用十分方便。
Netflix Hystrix(熔断)
Hystrix 支持回退的概念:当电路断开或出现错误时执行的默认代码路径。要为给定的 @FeignClient 启用回退,请将 Fallback 属性设置为实现回退的类名。
我们可以改造一下刚刚的调用架构:
在这里我部署了一台备用服务器,当用户服务宕机了之后,订单服务进行远程调用的时候可以进入备用服务,这样就不会导致系统崩溃。
MQ(消息中间件)
我现在这里有一个需求,修改密码,修改密码需要发送短信验证码,发送短信在短信服务中,修改密码在用户服务中,这个时候就会出现服务调用。
而且我们知道,发送短信一般都是调用第三方的接口,那比如阿里的,既然牵扯到调用,那么就会存在很多不确定因素,比如网络问题。
假如,用户再点击发送短信验证码到时候用户服务调用短信服务,但是在短信服务中执行调用阿里的接口花费了很长的时间。
这个时候就会导致用户服务调短信服务超时,会返回给用户失败,但是,短信最后又发出去了,这种问题怎么解决呢?
我们可以通过消息中间件来实现,使用异步讲给用户的反馈和发送短信分离,只要用户点了发送短信,直接返回成功,然后再启动发送验证码,60 秒重发一下,就算发送失败,用户还可以选择重新发送。
MQ 不但可以解耦服务,它还可以用来削峰,提高系统的性能,是一个不错的选择。
分布式事务
既然我们使用了分布式架构,那么有一点是我们必须要注意的,那就是事务问题。
如果一个服务的修改依赖另外一个服务的操作,这个时候如果操作不慎,就会导致可怕的后果。
举个例子,两个服务:钱包服务(用于充值提现)、交易钱包服务(用于交易),我现在想从钱包服务中转 1000 元到交易钱包服务中,我们应该如何保证他们数据的一致性呢?
我这里有两种方案,第一种是通过 MQ 来保证一致性,另外一种就是通过分布式事务来确保一致性。
MQ 确保一致性
- 生成一个订单表,记录着转入转出的状态。
- 向 MQ 发送一条确认消息。
- 开启本地事务,执行转出操操作,并且提交事务。
交易钱包服务:接收 MQ 的消息,进行转入操作(此操作需要 Ack 确认机制的支持)。
系统中会一直定时扫描订单中状态,没有成功的就做补偿机制或者重试机制,这个不是唯一要求。
以上就是 MQ 确保分布式事务的大致思路,不是唯一,仅供参考。
Seata(分布式事务)
Seata 有三个基本组成部分:
- 事务协调器(TC):维护全局事务和分支事务的状态,驱动全局提交或回滚。
- 事务管理器 TM:定义全局事务的范围:开始全局事务,提交或回滚全局事务。
- 资源管理器(RM):管理分支事务正在处理的资源,与 TC 进行对话以注册分支事务并报告分支事务的状态,并驱动分支事务的提交或回滚。
Seata 管理的分布式事务的典型生命周期:
- TM 要求 TC 开始一项新的全球交易。TC 生成代表全局事务的 XID。
- XID 通过微服务的调用链传播。
- RM 将本地事务注册为 XID 到 TC 的相应全局事务的分支。
- TM 要求 TC 提交或回滚 XID 的相应全局事务。
- TC 驱动 XID 对应的全局事务下的所有分支事务以完成分支提交或回滚。
完整的分布式架构
完整的分布式架构如下图:
这就是一套分布式基本的架构,请求从浏览器发出,经过 Nginx 反向代理到 Zuul 网关。
网关经过权限校验、然后分别转发到对应的服务中,每个服务都有自己独立的数据库,如果需要跨库查询的时候就需要用到分布式的远程调用(Feign)。
虽然这里我将服务拆分了,但是有一点需要注意的是网关,网关承载着所有的请求,如果请求过大会发生什么呢?
服务宕机,所以一般情况下,网关都是集群部署,不止网关可以集群,其他的服务都可以做集群配置,比如:注册中心、Redis、MQ 等等都可以。
那我们将这个流程图再改良一下:
现在这套架构就是比较程数的一套了,不管是性能还是稳定能,都是杠杠的,技术选择性的会也开得差不多了,最后技术总监做了一个总结。
总结
单体服务与分布式服务区别
区别 | 传统单体架构 | 分布式服务架构 |
---|---|---|
新功能开发 | 需要时间 | 容易开发和实现 |
部署 | 不经常且容易部署 | 经常发布,部署复杂 |
隔离性 | 故障影响范围大 | 故障影响范围小 |
架构设计 | 难度小 | 难度级数增大 |
系统性能 | 响应时间快,吞吐量小 | 响应时间慢,吞吐量大 |
系统运维 | 运维简单 | 运维复杂 |
新手上手 | 学习曲线大(业务逻辑) | 学习曲线大(构架逻辑) |
技术 | 技术单一且封闭 | 技术多样且开放 |
测试和查错 | 简单 | 复杂 |
系统扩展性 | 扩展性差 | 扩展性很好 |
系统管理 | 重点在于开放成本 | 重点在于服务治理和调度 |
什么时候使用分布式/集群?
总结如下几点:
- 单机无法支持的时候。
- 想要更好的隔离性(功能与功能)。
- 想要更好用户体验的时候。
- 想要更好的扩展性。
- 想要更快的响应,更搞得吞吐量。
使用分布式注意事项
虽然现在分布式技术已经十分成熟,但是里面的坑不是一点两点,比如:==如何保证分布式事务的一致性、如何保证服务调用的幂等性、如何保证消息的幂等性、如何设置熔断(服务的降级),如何保证服务的健壮性等等,==这些都是一直需要关注的问题,只有解决了这些问题,你的分布式架构才能真正的立于不败之地。
关于组件停更消息
目前注册中心 Eureka、网关 Zuul,Feign 都相继停更了,停更不代表不能使用,只是除了 Bug 可能不会主动修复,所以这个时候我们可能就需要选择另外的组件了。
注册中心可以使用 Consul、Nacos,Zookeeper,网关则可以通过 Gateway 替换,OpenFeign 替换 Fiegn。
所以也没必要听到组件停更的消息就担心 Cloud 会不会凉,放心,它至少最近几年是不会凉的。
基于SpringCloud分布式架构的更多相关文章
- was集群下基于接口分布式架构和开发经验谈
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/luozhonghua2014/article/details/34084935 某b项目是我首 ...
- SpringCloud分布式架构权限管理
概述 本文讨论分布式架构权限管理的两种情况,一种是针对统一授权访问的,一种是跨平台接口访问的. 虽然分布式架构会做业务的切割,将整体的业务切割为独立的子业务或者子平台,但是同一平台下往往会有统一的授权 ...
- 基于SOA分布式架构的dubbo框架基础学习篇
以需求用例为基,抽象接口,Case&Coding两条线并行,服务(M)&消费(VC)分离,单元.接口.功能.集成四层质量管理,自动化集成.测试.交付全程支持. 3个大阶段(需求分析阶段 ...
- 基于redis分布式缓存实现(新浪微博案例)
第一:Redis 是什么? Redis是基于内存.可持久化的日志型.Key-Value数据库 高性能存储系统,并提供多种语言的API. 第二:出现背景 数据结构(Data Structure)需求越来 ...
- 基于redis分布式缓存实现
Redis的复制功能是完全建立在之前我们讨论过的基 于内存快照的持久化策略基础上的,也就是说无论你的持久化策略选择的是什么,只要用到了Redis的复制功能,就一定会有内存快照发生,那么首先要注意你 的 ...
- 基于redis分布式缓存实现(新浪微博案例)转
第一:Redis 是什么? Redis是基于内存.可持久化的日志型.Key-Value数据库 高性能存储系统,并提供多种语言的API. 第二:出现背景 数据结构(Data Structure)需求越来 ...
- 基于SpringCloud的Microservices架构实战案例
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- 基于puppet分布式集群管理公有云多租户的架构浅谈
基于puppet分布式集群管理公有云多租户的架构浅谈 一.架构介绍 在此架构中,每个租户的业务集群部署一台puppet-master作为自己所在业务集群的puppet的主服务器,在每个业务集群所拥 ...
- 基于 dubbo 的分布式架构
前言 现在越来越多的互联网公司还是将自己公司的项目进行服务化,这确实是今后项目开发的一个趋势,就这个点再凭借之前的 SSM 项目来让第一次接触的同学能快速上手. 浅谈分布式架构 分布式架构单看这个名字 ...
随机推荐
- Intellij IDEA 使用Spring-boot-devTools
转载地址:https://blog.csdn.net/u013938484/article/details/77541050 转载于:https://blog.51cto.com/881206524/ ...
- TensorRT入门
本文转载于:子棐之GPGPU 的 TensorRT系列入门篇 学习一下加深印象 Why TensorRT 训练对于深度学习来说是为了获得一个性能优异的模型,其主要的关注点在与模型的准确度.精度等指标. ...
- linux 进程管理和内存分配
1.进程相关概念 进程:正在运行中的程序 内核功用:进程管理.文件系统.网络功能.内存管理.驱动程序.安全功能等 Process:运行中的程序的一个副本,是被载入内存的一个指令集合 进程 ID(Pro ...
- 面试中的volatile关键字
在Java的面试当中,面试官最爱问的就是volatile关键字相关的内容.经过多次面试之后,你是否思考过,为什么他们那么爱问volatile关键字相关的问题?而对于你,如果作为面试官,是否也会考虑采用 ...
- libevent(四)event_base 2
接上文libevent(三)event_base event_io_map event_list是双向链表,min_heap是小根堆,那event_io_map是什么呢? #ifdef WIN32 # ...
- Java——HTTP超详细总结
HTTP协议概述 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的 ...
- 如何写好、管好单元测试?基于Roslyn+CI分析单元测试,严控产品提测质量
上一篇文章中,我们谈到了通过Roslyn进行代码分析,通过自定义代码扫描规则,将有问题的代码.不符合编码规则的代码扫描出来,禁止签入,提升团队的代码质量. .NET Core技术研究-通过Roslyn ...
- Qt读写xml文件
写xml <root> <element> <sub id=-1></sub> </element> </root> //添加x ...
- 在微服务框架Demo.MicroServer中添加SkyWalking+SkyApm-dotnet分布式链路追踪系统
1.APM工具的选取 Apm监测工具很多,这里选用网上比较火的一款Skywalking. Skywalking是一个应用性能监控(APM)系统,Skywalking分为服务端Oap.管理界面UI.以及 ...
- Akko海洋之星
今天(2020.5.14)入手Akko海洋之星84茶轴,开心呀~~ 考虑方面: 价格>键线分离>接线接口>轴体>键帽>材质 价格: 200~500之间入门级cherry轴 ...