Spring cloud官网:Spring Cloud

1. Nacos Discovery 服务注册发现

Nacos

        一个更易于构建云原生应用的动态服务发现(Nacos Discovery )服务配置(Nacos Config)服务管理平台

Nacos 的关键特性包括:

  • 服务发现和服务健康监测
  • 动态配置服务
  • 动态 DNS 服务
  • 服务及其元数据管理

Nacos Discovery

管理服务之间错综复杂的调用关系。

Nginx 缺点:服务量(远程服务地址)很多,需要运维手动维护到Nginx, 这非常容易出错。

  

核心功能

1. 服务注册:Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。

2. 服务发现:服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册的服务清单,并且缓存在Nacos Client本地,同时会在Nacos Client本地开启一个定时任务定时拉取服务端最新的注册表信息更新到本地缓存

3. 服务心跳:在服务注册后,Nacos Client会维护一个定时心跳来持续通知Nacos Server,说明服务一直处于可用状态,防止被剔除。默认5s发送一次心跳。

4. 服务健康检查:Nacos Server会开启一个定时任务用来检查注册服务实例的健康情况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性置为false(客户端服务发现时不会发现),如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)

5.服务stop:当服务停止时,会向Nacos发送服务停止的请求。

6. 服务同步:Nacos Server集群之间会互相同步服务实例,用来保证服务信息的一致性。( leader raft)

补充说明:

// 查某个端口所属的进程

>netstat -aon | findstr "58883"

-- 结果会展示进程号,就可以进一步根据进程号查询进程详情。

2. Nacos Config服务配置中心

        使用 Spring Cloud Alibaba Nacos Config,可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。

没有统一的配置中心时,修改配置时的特点:

  • 维护性:比如很多服务使用redis, 如果有一台redis发生服务变更,ip地址有修改,则所有的微服务的配置文件都需要修改。
  • 时效性:修改后还需要重启
  • 安全性:如果服务使用redis或其他服务,需要在自己的配置文件中维护链接信息,比如用户名、密码登,不安全。

springcloud config 对比, 三大优势:

  1. springcloud config大部分场景结合git 使用, 动态变更还需要依赖Spring Cloud Bus 消息总线来通过所有的客户端变化。
  2. springcloud config不提供可视化界面。
  3. nacos config使用长轮询更新配置,一旦配置有变动后,通知Provider的过程非常的迅速, 从速度上秒杀springcloud。

3. 负载均衡器Ribbon

主流的负载均衡实现方案:

  1. 集中式负载均衡,在消费者和服务提供方中间使用独立的代理方式进行负载,有硬件的(比如 F5),也有软件的(比如Nginx) 【服务端负载均衡】

  2. 客户端根据自己的请求情况做负载均衡,Ribbon 就属于客户端自己做负载均衡。

客户端负载均衡:

        例如spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问。即在客户端就进行负载均衡算法分配。

服务端负载均衡

负载均衡算法:

  1. 随机,通过随机选择服务进行执行,一般这种方式使用较少;
  2. 轮训,负载均衡默认实现方式,请求来之后排队处理;
  3. 加权轮训,通过对服务器性能的分型,给高配置,低负载的服务器分配更高的权重,均衡各个服务器的压力;
  4. 地址Hash,通过客户端请求的地址的HASH值取模映射进行服务器调度。 ip --->hash
  5. 最小链接数,即使请求均衡了,压力不一定会均衡,最小连接数法就是根据服务器的情况,比如请求积压数等参数,将请求分配到当前压力最小的服务器上。 最小活跃数

Nacos使用Ribbon, nacos-discovery依赖了ribbon,可以不用再引入ribbon依赖。

4. 服务调用OpenFeign

Java项目中如何实现三方服务调用?

1. URLConnection:传统 JDK 自带的 URLConnection

2. HttpClient

        HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 Http 协议的客户端编程工具包,并且它支持 HTTP 协议最新版本和建议。HttpClient相比传统 JDK 自带的 URLConnection,提升了易用性和灵活性,使客户端发送 HTTP 请求变

得容易,提高了开发的效率。

3. Okhttp:一个处理网络请求的开源项目

4. HttpURLConnection:

        HttpURLConnection 是 Java 的标准类,它继承自 URLConnection,可用于向指定网站发送GET 请求、POST 请求。HttpURLConnection 使用比较复杂,不像 HttpClient 那样容易使用。

5. RestTemplate

        RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 HTTP 服务的方法,能够大大提高客户端的编写效率。

6. Feign : Feign是Netflix开发的声明式、模板化的HTTP客户端

OpenFeign

Spring Cloud openfeign对Feign进行了增强,使其支持Spring MVC注解,另外还整合了Ribbon和Nacos,从而使得Feign的使用更加方便。

Feign可以做到使用 HTTP 请求远程服务时就像调用本地方法一样的体验。它像 Dubbo 一样,consumer 直接调用接口方法调用 provider,而不需要通过常规的 Http Client 构造请求再解析返回数据。

Feign的底层用的是Ribbon,但超时时间以Feign配置为准。

 5. 服务高可用Sentinel

为了保证服务的高可用,常见的容错机制:

  1. 超时机制
  2. 服务限流
  3. 服务隔离+服务降级:
    1. 线程隔离:访问服务不直接访问,而是通过线程池访问,为不同的服务分配不同的线程数, 如果分配不到线程,进行降级处理;
    2. 信号隔离:为不同的服务配置不同的限流值
  4. 服务熔断 + 服务降级
  5. 服务降级

Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护 等多个维度来帮助开发者保障微服务的稳定性。

6. 分布式事务Seata

分布式事务就是为了保证不同资源服务器的数据一致性。

  • 跨库事务
  • 分库分表

常见分布式事务解决方案

  1. seata 阿里分布式事务框架
  2. 消息队列
  3. saga
  4. XA

他们有一个共同点,都是“两阶段(2PC)”。目前绝大多数分布式解决方案都是以两阶段提交协议2PC为基础的。实际上,这四种常见的分布式事务解决方案,分别对应着分布式事务的四种模式:AT、TCC、Saga、XA。

AT (Auto Transacion)

AT 模式是一种无侵入的分布式事务解决方案。Seta实现了AT模式。

在 AT 模式下,用户只需关注自己的“业务 SQL”,用户的 “业务 SQL” 作为一阶段,Seata 框架会自动生成事务的二阶段提交和回滚操作。

一阶段

二阶段提交

删除快照,删除行锁。

二阶段回滚

检查脏写,如果出现脏写就需要转人工处理。

TCC模式

特点:

1. 侵入性比较强, 并且得自己实现相关事务控制逻辑

2.在整个过程基本没有锁,只在单个方法中有锁,性能更强
 

用户接入 TCC 模式,最重要的事情就是考虑如何将业务模型拆成 2 阶段,实现成 TCC 的 3 个方法,并且保证 Try 成功 Confirm 一定能成功(try阶段做了数据库连接和操作,confirm阶段一般不容易出现问题,即使非常小的概率出现了问题,需要有重试机制)。

在下订单减库存的场景,try阶段是生成一个中间状态的订单,在confirm阶段再修正成用户可以看到的订单状态。

TCC需要考虑的问题:

  1. 允许空回滚:try未执行,cancel执行了
  2. 防悬挂控制:cancel比try先执行
  3. 幂等控制

Saga模式

Saga 是一种补偿协议,在 Saga 模式下,分布式事务内有多个参与者,每一个参与者都有一个冲正补偿服务,需要用户根据业务场景实现其正向操作和逆向回滚操作。

Saga核心思想是将长事务拆分成多个本地短事务。分布式事务执行过程中,依次执行各参与者的正向操作,如果所有正向操作均执行成功,那么分布式事务提交。如果任何一个正向操作执行失败,那么分布式事务会退回去执行前面各参与者的逆向回滚操作,回滚已提交的参与者,使分布式事务回到初始状态。

     

Saga的实现方式有两种:

  • 命令协调
  • 事件编排

命令协调:

如果单个服务执行异常,也是基于Saga协调器向每个参与方发送回滚的请求。

缺点:

  • 单点故障
  • 协调器逻辑容易变得庞大复杂,难以维护

优点:

  • 服务之间的关系简单,避免服务间的循环依赖
  • 程序开发简单,只需要执行命令/回复,降低参与者的复杂性
  • 易维护扩展,在添加新步骤时,是服务复杂性报纸线性,回滚更容易管理,更容易实施和测试

事件编排:

优点:

  • 避免单点故障
  • 当涉及的服务节点少时,容易实现

缺点:

  • 服务之间存在循环依赖的风险
  • 当涉及的服务节点比较多时,服务之间关系复杂,难以追踪

        Saga 正向服务与补偿服务也需要业务开发者实现。因此是业务入侵的。

        Saga 模式下分布式事务通常是由事件驱动的各个参与者之间是异步执行的,Saga 模式是一种长事务解决方案。

与TCC实践经验相同的是,Saga 模式中,每个事务参与者的冲正、逆向操作,需要支持:

  1. 空补偿:逆向操作早于正向操作时;
  2. 防悬挂控制:空补偿后要拒绝正向操作
  3. 幂等

XA模式

XA是X/Open DTP组织(X/Open DTP group)定义的两阶段提交协议。

XA规范的基础是两阶段提交协议2PC。

XA模式中的角色:

  • 事务协调者
  • 事务参与者

        分布式事务本身就是一个技术难题,业务中具体使用哪种方案还是需要不同的业务特点自行选择,但是我们也会发现,分布式事务会大大的提高流程的复杂度,会带来很多额外的开销工作,「代码量上去了,业务复杂了,性能下跌了」。

所以,当我们真实开发的过程中,能不用分布式事务就不用!(看了这么多,还不让用~)。

7. GateWay网关

API网关

        在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去用。 这无疑是非常复杂的。

这样的架构,会存在着诸多的问题:

  1. 每个业务都会需要鉴权、限流、权限校验、跨域等逻辑,如果每个业务都各自为战,自己造轮子实现一遍,会很很满发,完全可以抽出来,放到一个统一的地方去做。
  2. 如果业务量比较复杂,一个页面可能会涉及到数百个微服务协同工作,如果每一个微服务都分配一个域名的话,一方面客户端代码会很难维护,涉及到数百个域名,另一方面是连接数的瓶颈,想象一下你打开一个APP,通过抓包发现涉及到了数百个远程调用,这在移动端下会显得非常低效。
  3. 后期如果需要对微服务进行重构的话,也会变的非常麻烦,需要客户端配合你一起进行改造。

        所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,可以在这里实现,诸如认证、鉴权、监控、路由转发等等。

Spring Cloud Gateway

特点:

  • 基于Spring Framework 5, Project Reactor 和 Spring Boot 2.0 进行构建;
  • 动态路由:能够匹配任何请求属性;
  • 支持路径重写;
  • 集成 Spring Cloud 服务发现功能(Nacos、Eruka);
  • 可集成流控降级功能(Sentinel、Hystrix);
  • 可以对路由指定易于编写的 Predicate(断言)和 Filter(过滤器);

工作原理:

执行流程大体如下:

1. Gateway Client向Gateway Server发送请求

2. 请求首先会被HttpWebHandlerAdapter进行提取组装成网关上下文

3. 然后网关的上下文会传递到DispatcherHandler,它负责将请求分发给RoutePredicateHandlerMapping

4. RoutePredicateHandlerMapping负责路由查找,并根据路由断言判断路由是否可用

5. 如果过断言成功,由FilteringWebHandler创建过滤器链并调用

6. 请求会一次经过PreFilter--微服务--PostFilter的方法,最终返回响应

路由断言工厂

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

SpringCloud Gateway包括许多内置的断言工厂,所有这些断言都与HTTP请求的不同属性匹配:

  • 基于Datetime类型的断言工厂
  • 基于远程地址的断言工厂
  • 基于Cookie的断言工厂
  • ......
  • 也可以自定义断言工厂

过滤器工厂

通过一些过滤器工厂可以进行一些业务逻辑处理器,比如添加剔除响应头,添加去除参数等。

  • 添加请求头
  • 添加请求参数
  • 为匹配的路由添加统一前缀
  • 重定向操作
  • ......
  • 自定义过滤器工厂

全局过滤器配置

局部过滤器和全局过滤器区别:

  • 局部:局部针对某个路由, 需要在路由中进行配置
  • 全局:针对所有路由请求,一旦定义就会投入使用

也可以自定义全局过滤器。

8.Skywalking

是什么?

skywalking是一个国产开源框架,2015年由吴晟开源 , 2017年加入Apache孵化器。skywalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。它是一款优秀的APM(Application Performance Management)工具,包括了分布式追踪、性能指标分析、应用和服务依赖分析等。

 SkyWalking是本土开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能较强,接入端无代码侵入。目前已加入Apache孵化器。

环境搭建部署

  • skywalking agent和业务系统绑定在一起,负责收集各种监控数据
  • Skywalking oapservice是负责处理监控数据的,通常以集群的形式存在。
    • 比如接受skywalking agent的监控数据,并存储在数据库中;
    • 接受skywalking webapp的前端请求,从数据库查询数据,并返回数据给前端,
  • skywalking webapp,前端界面,用于展示数据。
  • 用于存储监控数据的数据库,比如mysql、elasticsearch等。

部署过程:

  1. 下载 SkyWalking
  2. 搭建SkyWalking OAP 服务:
    1. 启动脚本bin/startup.s

    2. 启动成功后会启动两个服务,一个是skywalking-oap-server,一个是skywalking-web-ui ,服务启动后会暴露11800 和 12800 两个端口,分别为收集监控数据的端口11800和接受前端请求的端口12800,修改端口可以修改config/applicaiton.yml

  3. 运行的程序配置jvm参数, 无需修改代码

skywalking接入微服务

运行的程序配置jvm参数, 无需修改代码

# skywalking‐agent.jar的本地磁盘的路径, 必须是本机

‐javaagent:D:\apache\apache‐skywalking‐apm‐es7‐8.4.0\apache‐skywalking‐apm‐bin‐es7\agent\skywalking‐agent.jar

# 在skywalking上显示的服务名

‐DSW_AGENT_NAME=springboot‐skywalking‐demo

# skywalking的collector服务的IP及端口, 可以指定远程地址

‐DSW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.3.100:11800

也可以通过shell脚本启动项目,在shell脚本中通过 -javaagent 参数进行配置SkyWalking Agent,

#!/bin/sh

# SkyWalking Agent配置

export SW_AGENT_NAME=springboot‐skywalking‐demo #Agent名字,一般使用`spring.application.name`

export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 #配置 Collector 地址。

export SW_AGENT_SPAN_LIMIT=2000 #配置链路的最大Span数量,默认为 300。

export JAVA_AGENT=‐javaagent:/usr/local/soft/apache‐skywalking‐apm‐bin‐es7/agent/skywalking‐agent.jar

java $JAVA_AGENT ‐jar springboot‐skywalking‐demo‐0.0.1‐SNAPSHOT.jar #jar启动

自定义skywalking链路追踪

1.添加依赖

    <!‐‐ SkyWalking 工具类 ‐‐>
            <dependency>
                <groupId>org.apache.skywalking</groupId>
                <artifactId>apm‐toolkit‐trace</artifactId>
               <version>8.4.0</version>
            </dependency>

2.添加注解

@Trace : 业务方法想在ui界面的跟踪链路上显示出来

@Tag:记录参数和返回信息; key = 方法名 ; value = returnedObj 返回值 arg[0] 参数

告警功能

        SkyWalking 告警功能是在6.x版本新增的,其核心由一组规则驱动,这些规则定义在config/alarm-settings.yml文件中。 告警规则的定义分为两部分:

1. 告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件。

2. Webhook(网络钩子):定义当警告触发时,哪些服务终端需要被告知.

Webhook(网络钩子):

        Webhook可以简单理解为是一种Web层面的回调机制,通常由一些事件触发,与代码中的事件回调类似,只不过是Web层面的。由于是Web层面的,所以当事件发生时,回调的不再是代码中的方法或函数,而是服务接口

        例如,在告警这个场景,告警就是一个事件。当该事件发生时,SkyWalking就会主动去调用一个配置好的接口,该接口就是所谓的Webhook。SkyWalking的告警消息会通过 HTTP 请求进行发送,请求方法为 POST,Content-Type 为 application/json,其JSON 数据实基于List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage进行序列化的.

        要实现自定义的告警,可以实现处理这个POST的请求的接口,然后将该接口配置到SkyWalking中,Webhook的配置位于config/alarm-settings.yml文件的末尾,格式为http://{ip}:{port}/{uri}。如下示例:

高可用

        集群管理是用于实现高可用、实现高吞吐的的方式。

        Skywalking集群是将skywalking oap作为一个服务注册到nacos上,只要skywalking oap服务没有全部宕机,保证有一个skywalking oap在运行,就能进行跟踪。

搭建一个skywalking oap集群需要:

(1)至少一个Nacos(也可以是nacos集群)

(2)至少一个ElasticSearch/mysql(也可以是es/msql集群)

(3)至少2个skywalking oap服务;

(4)至少1个UI(UI也可以集群多个,用Nginx代理统一入口)

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐