暗中观察

Spring之SpringCloud 组件介绍
一、微服务架构中常见概念服务注册与服务发现服务注册: 服务提供者将所提供服务的信息(服务器IP和端口、服务访问协议...
扫描右侧二维码阅读全文
19
2023/04

Spring之SpringCloud 组件介绍

一、微服务架构中常见概念

服务注册与服务发现

服务注册: 服务提供者将所提供服务的信息(服务器IP和端口、服务访问协议等) 注册/登记到注册中心。
服务发现: 服务消费者能够从注册中心获取到较为实时的服务列表,然后根究一定 的策略选择一个服务访问。

负载均衡
负载均衡即将请求压力分配到多个服务器(应用服务器、数据库服务器等),以此来提高服务的性能、可靠性。

熔断

即断路保护。微服务架构中,如果下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。

链路追踪

微服务架构越发流行,一个项目往往拆分成很多个服务,那么一次请求就需要涉及到很多个服务。不同的微服务可能是由不同的团队开发、可能使用不同的编程语言实现、整个项目也有可能部署在了很多服务器上(甚至百台、千台)横跨多个不同的数据中心。所谓链路追踪,就是对一次请求涉及的很多个服务链路进行日志记录、性能监控。

API 网关

API请求调用统一接入API网关层, 由网关转发请求。API网关更专注在安全、路由、流量等问题的处理上(微服务团队 专注于处理业务逻辑即可),它的功能:

统一接入(路由)
安全防护(统一鉴权,负责网关访问身份认证验证,与“访问认证中心”通信,实际认证业务逻辑交移“访问认证中心”处理)
黑白名单(实现通过IP地址控制禁止访问网关功能,控制访问)
协议适配(实现通信协议校验、适配转换的功能)
流量管控(限流)
⻓短链接支持
容错能力(负载均衡)

二、常见的组件

2.1 服务注册中心组件 Eureka

eureka.jpg

Eureka 交互流程及原理
eureka1.jpg
Eureka 包含两个组件:Eureka Server 和 Eureka Client,Eureka Client是一个 Java客户端,用于简化与Eureka Server的交互;Eureka Server提供服务发现的能力,各个微服务启动时,会通过Eureka Client向Eureka Server 进行注册自己 的信息(例如网络信息),Eureka Server会存储该服务的信息。

图中us-east-1c、us-east-1d,us-east-1e代表不同的区也就是不同的机房
图中每一个Eureka Server都是一个集群。
图中Application Service作为服务提供者向Eureka Server中注册服务, Eureka Server接受到注册事件会在集群和分区中进行数据同步,Application Client作为消费端(服务消费者)可以从Eureka Server中获取到服务注册信 息,进行服务调用。
微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒) 以续约自己的信息
Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服务节点(默认90秒)
每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复 制的方式完成服务注册列表的同步
Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节 点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者
Eureka通过心跳检测、健康检查和客户端缓存等机制,提高系统的灵活性、可 伸缩性和可用性。

Eureka集群:
eureka2.jpg
Eureka的 元数据 有两种:标准元数据和自定义元数据。

标准元数据: 主机名、IP地址、端口号等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用。

自定义元数据: 可以使用eureka.instance.metadata-map配置,符合KEY/VALUE的 存储格式。这 些元数据可以在远程客户端中访问。

2.2 Ribbon负载均衡

负载均衡一般分为服务器端负载均衡和客户端负载均衡 所谓服务器端负载均衡,比如Nginx、F5这些,请求到达服务器之后由这些负载均衡器根据一定的算法将请求路由到目标服务器处理。

所谓客户端负载均衡,比如我们要说的Ribbon,服务消费者客户端会有一个服务器 地址列表,调用方在请求前通过一定的负载均衡算法选择一个服务器进行访问,负载均衡算法的执行是在请求客户端进行。

Ribbon是Netflix发布的负载均衡器。Eureka一般配合Ribbon进行使用,Ribbon利 用从Eureka中读取到服务信息,在调用服务提供者提供的服务时,会根据一定的算法进行负载。
ribbon.png

2.3 Hystrix熔断器

Hystrix(豪猪),宣言“defend your app”是由Netflix开源的一个 延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而 提升系统的可用性与容错性。Hystrix主要通过以下几点实现延迟和容错。

包裹请求:使用HystrixCommand包裹对依赖的调用逻辑。
跳闸机制:当某服务的错误率超过一定的阈值时,Hystrix可以跳闸,停止请求 该服务一段时间。
资源隔离:Hystrix为每个依赖都维护了一个小型的线程池(舱壁模式)(或者信号 量)。如果该线程池已满, 发往该依赖的请求就被立即拒绝,而不是排队等待,从而加速失败判定。
监控:Hystrix可以近乎实时地监控运行指标和配置的变化,例如成功、失败、 超时、以及被拒绝 的请求等。
回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑由开发人员自行提供,例如返回一个缺省值。
自我修复:断路器打开一段时间后,会自动进入“半开”状态。
扇入、扇出概念:

扇入: 代表着该微服务被调用的次数,扇入大,说明该模块复用性好。

扇出: 该微服务调用其他微服务的个数,扇出大,说明业务逻辑复杂。

扇入大是一个好事,扇出大不一定是好事。

微服务架构中,一个应用可能会有多个微服务组成,微服务之间的数据交互通过 远程过程调用完成。这就带来一个问题,假设微服务A调用微服务B和微服务C,微 服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某 个微服务的调用响应时间过⻓或者不可用,对微服务A的调用就会占用越来越多的系 统资源,进而引起系统崩溃,所谓的“雪崩效应”。

Hystrix舱壁模式:
Hystrix.jpg

Hystrix工作流程:
Hystrix1.jpg

2.4 Feign远程调用组件

Feign是Netflix开发的一个轻量级RESTful的HTTP服务客户端(用它来发起请求, 远程调用的),是以Java接口注解的方式调用Http请求,而不用像Java中通过封装 HTTP请求报文的方式直接调用,Feign被广泛应用在Spring Cloud 的解决方案中。

类似于Dubbo,服务消费者拿到服务提供者的接口,然后像调用本地接口方法一样 去调用,实际发出的是远程的请求。

Feign可帮助我们更加便捷,优雅的调用HTTP API:不需要我们去拼接url调用restTemplate的api,在SpringCloud中,使用Feign非常简单,创建一个接口(在消费者服务调用方这一端),并在接口上添加一些注解,代码就完成了
SpringCloud对Feign进行了增强,使Feign支持了SpringMVC注解 (OpenFeign)
本质:封装了Http调用流程,更符合面向接口化的编程习惯,类似于Dubbo的服务调用。

Feign调用流程:
feign.jpg

2.5 GateWay网关组件

Spring Cloud GateWay是Spring Cloud的一个全新项目,目标是取代Netflix Zuul, 它基于Spring5.0+SpringBoot2.0+WebFlux(基于高性能的Reactor模式响应式通信 框架Netty,异步非阻塞模型)等技术开发,性能高于Zuul,官方测试,GateWay是 Zuul的1.6倍,旨在为微服务架构提供一种简单有效的统一的API路由管理方式。

Spring Cloud GateWay不仅提供统一的路由方式(反向代理)并且基于 Filter(定义 过滤器对请求过滤,完成一些功能) 链的方式提供了网关基本的功能,例如:鉴权、 流量控制、熔断、路径重写、日志监控等。

GateWay核心概念:
Zuul1.x 阻塞式IO 2.x 基于Netty
Spring Cloud GateWay天生就是异步非阻塞的,基于Reactor模型
一个请求到达网关根据一定的条件匹配—匹配成功之后可以将请求转发到指定的服务 地址;而在这个过程中,我们可以进行一些比较具体的控制(限流、日志、黑白名 单)
路由(route): 网关最基础的部分,也是网关比较基础的工作单元。路由由一 个ID、一个目标URL(最终路由到的地址)、一系列的断言(匹配条件判断)和 Filter过滤器(精细化控制)组成。如果断言为true,则匹配该路由。
断言(predicates):参考了Java8中的断言java.util.function.Predicate,开发 人员可以匹配Http请求中的所有内容(包括请求头、请求参数等)(类似于 nginx中的location匹配一样),如果断言与请求相匹配则路由。
过滤器(filter):一个标准的Spring webFilter,使用过滤器,可以在请求之前或者之后执行业务逻辑。
其中,Predicates断言就是我们的匹配条件,而Filter就可以理解为一个无所不能的拦截器,有了这两个元素,结合目标URL,就可以实现一个具体的路由转发。

GateWay工作过程:
gateway.jpg

客户端向Spring Cloud GateWay发出请求,然后在GateWay Handler Mapping中 找到与请求相匹配的路由,将其发送到GateWay Web Handler;Handler再通过指 定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之 间用虚线分开是因为过滤器可能会在发送代理请求之前(pre)或者之后(post)执 行业务逻辑。

Filter在“pre”类型过滤器中可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在“post”类型的过滤器中可以做响应内容、响应头的修改、日志的输出、流 量监控等。
核心逻辑: 路由转发+执行过滤器链。
GateWay路由规则详解:
gateway1.jpg

GateWay过滤器:
主要有两个pre和post:

pre:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份 验证、在集群中选择 请求的微服务、记录调试信息等。
post:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加 标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给 客户端等。
从过滤器类型的⻆度,Spring Cloud GateWay的过滤器分为GateWayFilter和 GlobalFilter两种:

GateWayFilter:应用到单个路由路由上
GlobalFilter:应用到所有的路由上

2.6 Spring Cloud Config 分布式配置中心

Spring Cloud Config是一个分布式配置管理方案,包含了 Server端和 Client端两个部分。

Server 端:提供配置文件的存储、以接口的形式将配置文件的内容提供出去, 通过使用@EnableConfigServer注解在 Spring boot 应用中非常简单的嵌入
Client 端:通过接口获取配置数据并初始化自己的应用
Spring Cloud Bus(基于MQ的,支持RabbitMq/Kafka) 是Spring Cloud中的消息 总线方案,Spring Cloud Config + Spring Cloud Bus 结合可以实现配置信息的自动更新。

2.7 Spring Cloud Stream消息驱动组件

Spring Cloud Stream 消息驱动组件帮助我们更快速,更方便,更友好的去构建消息 驱动微服务的。

当时定时任务和消息驱动的一个对比。(消息驱动:基于消息机制做一些事情) MQ:消息队列/消息中间件/消息代理,产品有很多,ActiveMQ、RabbitMQ、RocketMQ、Kafka。

本质:屏蔽掉了底层不同MQ消息中间件之间的差异,统一了MQ的编程模型,降低了学习、开发、维护MQ的成本。

Spring Cloud Stream 是一个构建消息驱动微服务的框架。应用程序通过inputs(相 当于消息消费者consumer)或者outputs(相当于消息生产者producer)来与 Spring Cloud Stream中的binder对象交互,而Binder对象是用来屏蔽底层MQ细节 的,它负责与具体的消息中间件交互。
SCSt-with-binder.png

Binder绑定器是Spring Cloud Stream 中非常核心的概念,就是通过它来屏蔽底层 不同MQ消息中间件的细节差异,当需要更换为其他消息中间件时,我们需要做的就 是更换对应的Binder绑定器而不需要修改任何应用逻辑(Binder绑定器的实现是框架内置的,Spring Cloud Stream目前支持Rabbit、Kafka等多种消息队列)。
SCSt-with-binder1.png

2.8 分布式链路追踪技术 Sleuth + Zipkin

分布式链路追踪技术核心思想:

记录日志,作为一个完整的技术,分布式链路追踪也有自己的理论和概念微服务架构中,针对请求处理的调用链可以展现为一棵树,示意如下:
sleuth.jpg

上图标识一个请求链路,一条链路通过TraceId唯一标识,span标识发起的请求信 息,各span通过parrentId关联起来 Trace:服务追踪的追踪单元是从客户发起请求(request)抵达被追踪系统的边界开始,到被追踪系统向客户返回响应(response)为止的过程。

Trace ID: 为了实现请求跟踪,当请求发送到分布式系统的入口端点时,只需要服 务跟踪框架为该请求创建一个唯一的跟踪标识Trace ID,同时在分布式系统内部流转 的时候,框架失踪保持该唯一标识,直到返回给请求方。一个Trace由一个或者多个Span组成,每一个Span都有一个SpanId,Span中会记录 TraceId,同时还有一个叫做ParentId,指向了另外一个Span的SpanId,表明父子 关系,其实本质表达了依赖关系。

Span ID: 为了统计各处理单元的时间延迟,当请求到达各个服务组件时,也是通过 一个唯一标识Span ID来标记它的开始,具体过程以及结束。对每一个Span来说, 它必须有开始和结束两个节点,通过记录开始Span和结束Span的时间戳,就能统计 出该Span的时间延迟,除了时间戳记录之外,它还可以包含一些其他元数据,比如 时间名称、请求信息等。

每一个Span都会有一个唯一跟踪标识 Span ID,若干个有序的 span 就组成了一个 trace。Span可以认为是一个日志数据结构,在一些特殊的时机点会记录了一些日志信息, 比如有时间戳、spanId、TraceId,parentIde等,Span中也抽象出了另外一个概 念,叫做事件,核心事件如下

CS :client send/start 客户端/消费者发出一个请求,描述的是一个span开始
SR: server received/start 服务端/生产者接收请求 SR-CS属于请求发送的网络延 迟
SS: server send/finish 服务端/生产者发送应答 SS-SR属于服务端消耗时间
CR:client received/finished 客户端/消费者接收应答 CR-SS表示回复需要的时 间(响应的网络延迟)
Spring Cloud Sleuth (追踪服务框架)可以追踪服务之间的调用,Sleuth可以记录 一个服务请求经过哪些服务、服务处理时⻓等,根据这些,我们能够理清各微服务 间的调用关系及进行问题追踪分析。

耗时分析:通过 Sleuth 了解采样请求的耗时,分析服务性能问题(哪些服务调 用比较耗时)
链路优化:发现频繁调用的服务,针对性优化等 Sleuth就是通过记录日志的方式来记录踪迹数据的
我们往往把Spring Cloud Sleuth 和 Zipkin 一起使用,把 Sleuth 的数据信 息发送给 Zipkin 进行聚合,利用 Zipkin 存储并展示数据。

2.9 Spring Cloud OAuth2 + JWT

微服务架构下统一认证思路

基于Session的认证方式: 在分布式的环境下,基于session的认证会出现一个问题,每个应用服务都需要 在session中存储用户身份信息,通过负载均衡将本地的请求分配到另一个应用 服务需要将session信息带过去,否则会重新认证。我们可以使用Session共享、 Session黏贴等方案。Session方案也有缺点,比如基于cookie,移动端不能有效使用等
基于token的认证方式: 服务端不用存储认证数据,易维护扩展性强, 客户端可 以把token 存在任意地方,并且可以实现web和app统一认证机制。其缺点也很 明显,token由于自包含信息,因此一般数据量较大,而且每次请求 都需要传 递,因此比较占带宽。另外,token的签名验签操作也会给cpu带来额外的处理 负担。
OAuth2开放授权协议/标准

OAuth(开放授权)是一个开放协议/标准,OAuth 2.0 的标准是 RFC 6749 文件。允许用户授权第三方应用访问他们存储 在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方应用或分享 他们数据的所有内容。

允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容

oauth2jwt.jpg

角色:

资源所有者(Resource Owner):可以理解为用户自己
客户端(Client):我们想登陆的网站或应用
认证服务器(Authorization Server):可以理解为微信或者QQ
资源服务器(Resource Server):可以理解为微信或者QQ
Resource Owner在Authorization Server注册Client信息,通过Client去访问Authorization Server拿到token凭证,通过token凭证去Resource Server获取自己的资源

OAuth2的颁发Token授权方式

授权码(authorization-code) :授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。

密码式(password):如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。

隐藏式(implicit):有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)"隐藏式"(implicit)。

客户端凭证(client credentials):最后一种方式是凭证式(client credentials),适用于没有前端的命令行应用,即在命令行下请求令牌。

JWT令牌

JSON Web Token(JWT)是一个开放的行业标准(RFC 7519),它定义了一种简介 的、自包含的协议格式,用于 在通信双方传递json对象,传递的信息经过数字签名 可以被验证和信任。JWT可以使用HMAC算法或使用RSA的公 钥/私钥对来签名,防止被篡改。

JWT令牌结构:

JWT令牌由三部分组成,每部分中间使用点(.)分隔,比如:xxxxx.yyyyy.zzzzz

Header:头部包括令牌的类型(即JWT)及使用的哈希算法(如HMAC SHA256或 RSA),例如

{ "alg" : "HS256" , "typ" : "JWT" }
将上边的内容使用Base64Url编码,得到一个字符串就是JWT令牌的第一部分。 Payload

第二部分是负载,内容也是一个json对象,它是存放有效信息的地方,它可以存 放jwt提供的现成字段,比 如:iss(签发者),exp(过期时间戳), sub(面向的 用户)等,也可自定义字段。 此部分不建议存放敏感信息,因为此部分可以解 码还原原始内容。 最后将第二部分负载使用Base64Url编码,得到一个字符串 就是JWT令牌的第二部分。 一个例子:

{ "sub" : "1234567890" , "name" : "John Doe" , "iat" : 1516239022 }
Signature

第三部分是签名,此部分用于防止jwt内容被篡改。 这个部分使用base64url将 前两部分进行编码,编码后使用点(.)连接组成字符串,最后使用header中声 明 签名算法进行签名。

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
base64UrlEncode(header):jwt令牌的第一部分。

base64UrlEncode(payload):jwt令牌的第二部分。

secret:签名所使用的密钥。

三、SpringCloudAlibaba微服务一站式解决方案

Spring Cloud Alibaba 是什么

springcloudalibaba1.png

微服务全景图

springcloudalibaba2.png

1 配置中心 Nacos
2 服务注册与发现 Nacos
3 分布式事务 Seata
4 分布式限流Sentinel
5 分布式消息 spring-cloud-starter-stream-rocketmq
6 异构服务 spring-cloud-starter-alibaba-sidecar
7 适配GraalVM

网址:https://sca.aliyun.com/zh-cn/

Last modification:November 29th, 2023 at 06:41 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment