springcloud-alibaba

nacosf​​​​什么是 Nacos

nacos config 官网:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config

nacos

springcloud提供了微服务治理的能力(服务注册与发现、服务降级、限流、熔断、网关、负载均衡、配置中心...),为微服务开发提供了全家桶服务

服务注册,将提供某个服务的模块信息(通常是这个服务的ip和端口)注册到1个公共的组件上去

服务发现,新注册的这个服务模块能够及时的被其他调用者发现。不管是服务新增和服务删减都能实现自动发现。

nacos功能

通过指定的名字来获取资源或者服务的地址,提供者的信息

Nacos配置中心

动态配置服务让您能够以中心化、外部化和动态化的方式管理所有环境的配置。动态配置消除了配置变更时重新部署应用和服务的需要。配置中心化管理让实现无状态服务更简单,也让按需弹性扩展服务更容易。

nacos工作流程

服务注册,通过rest请求方式注册子的服务,提供自生元素像ip地址,端口号,然后将信息存储在双层内存map中

服务心跳:在注册后,维护定时心跳来通知nacos server说明服务一致处于可用状态,默认5秒一次

服务同步:集群智能会项目同步,保证服务一致性

服务消费:服务消费者。调用提供者时 开启一个定时任务拉去最新的注册表到本地缓存

服务健康:开启定时检测,对于15秒没收到客户端心跳的实列会将他的healthy熟悉设置位false,30秒没有收到就剔除

nacos文档:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-discovery.adoc

pom.xml

<!-- web场景依赖       -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--  端点监控场景以来,开放服务健康检查的api      -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--  注册中心场景以来,当项目启动立即注册服务      -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
 

application.yml

spring:
  application:
    name: cloud-goods #服务名,保证唯一不能重复
  cloud:
    nacos:
      discovery:
        username: nacos
        password: nacos
        server-addr: localhost:8848
        ip: 127.0.0.1 #指定服务注册的ip地址

启动类加注解

package com.qf;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;


@SpringBootApplication
@EnableDiscoveryClient  //开关,开启服务的注册与发现功能
public class GoodsApp {

    public static void main(String[] args) {
        SpringApplication.run(GoodsApp.class, args);
    }
}

RestTemplate

是java模拟浏览器发送http请求的工具类

负载均衡器Ribbon

启动流程:拦截所有resttempalte远程端用,解析url获取servicename,根据servicename获取实例列表,(先判断内存中是否有对应的实列列表),有直接从本地内存获取,没有像nacos发送请求,通过负载均衡策略从实列列表中获取一个实列,发送http请求到目标服务器

负载均衡 都实现了irule

bestAvailableRule,选最小的

randomrule 随机

zoneavioddancerule,先过滤把不可用的过滤掉,再采用轮询

使用ribbonclient修改负载均衡

OpenFeign

使用 HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个 HTTP 请求。同时OpenFeign通过集成Ribbon实现客户端的负载均衡openfeign依赖

<!--在服务消费方依赖Openfeign-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

@enableFeignClients 在启动类中开启openfeign

@FeignClient

 接口调用

Openfeign配置

ribbon:
  eager-load:
    enabled: true #当服务启动立即加载实例列表
    clients:
      - cloud-jifen #服务的实例列表饥饿加载
feign:
  client:
    config:
      cloud-jifen:
        connect-timeout: 1000
        read-timeout: 1  #设置ali-jifen响应的超时时间为1毫秒
      default: #设置默认的超时时间
        connect-timeout: 1000
        read-timeout: 2000

Sentinel服务哨兵简介

中文文档:Home · alibaba/Sentinel Wiki · GitHub

下载地址:Releases · alibaba/Sentinel · GitHub

服务雪崩解决思想

1:限流 qps

2:仓壁模式 线程数

3:断路器

Sentinel 特征

  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。

  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 分为两个部分

  • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

  • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

添加依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

QPS 直接,快速失败

QPS:每秒资源被访问的次数

当每秒访问次数超过设定阈值,触发流控

正在工作的线程超过正在工作的线程

 

QPS关联失败

当定义的资源名每秒访问超过设定的阈值,关联资源被流控

 线程关联失败

当正在执行的线程数超过设定阈值,关联资源流控

链路失败

aa有两个入口,分别为/goods/test1和/goods/test2

当/goods/test1访问qps>1【阈值】 那么/goods/test1就不能访问受保护资源,其他入口照常访问

warm-up

冷启动,系统长期处于低水位情况下,流浪突然增大,系统直接到高水平状态可能吧系统压垮,warm在规定时间类缓慢的提升到最大阈值,默认最小值为设定最大值阈值/3

在10秒从300/3=100缓慢提升到300 

流控效果-匀速排队

让请求以均匀的速度通过,对应的是漏桶算法

例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求

匀速排队模式暂时不支持 QPS > 1000 的场景。

Sentinel服务熔断降级

调用第三方接口或数据库,远程服务时中途除了问题,导致线程堆积,

断路器的工作流程:

一旦熔断,断路器的状态是Open(所有的请求都不能进来)

当熔断时长结束,断路器的状态是half-Open(可以允许一个请求进来)

如果接下来的请求正常,断路器的状态是close(资源就自恢复)

如果接下来的请求不正常,断路器的状态是open

熔断降级- 慢调用比例

设置一个最大的RT时间(超过这个时间就是慢调用)和最小请求数,当最小请求数的慢调用超过设置的比例阈值,熔断(时间为设定的)

熔断降级-异常比例

最少1秒发5个,异常的请求除总请求比例值大于0.6发生熔断

 

熔断降级-异常数

发生最小请求数,当异常大与1则发生异常 

Sentinel-热点key规则

当访问商品为1时阈值为10,2为20,如果没有默认单机阈值唯1(只支持QPS)

Sentinel-权限规则

黑白名单

Sentinel-针对来源

系统规则

  • Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5

  • CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。

  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。

  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。

  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。

@SentinelResource("………………")

流控自定义异常处理

Sentinel规则持久化

原始模式,将规制更新在内存中,无任何依赖 重启及消失

pull模式,将规则存在文件中,简单无依赖,不能保证实时性

定时从指定文件中读取规则JSON文件【图中的本地文件】,如果发现文件发生变化,就更新规则缓存。

push模式。保存在nacos中,一致性快速,需要引入第三方依赖

gateway

  • Route(路由)

路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
  • Predicate(断言、谓词)

开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
  • Filter(过滤)

指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改

gateway的工作流程

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

pom依赖

不要依赖spring-boot-starter-web(使用的是Servlet编程模型,而gateway使用的是Reactor编程模型)

    <!--   spring-cloud gateway,底层基于netty     -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
      <!-- 端点监控 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--  nacos注册中心      -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

配置

server:
  #gateway的端口
  port: 8040

spring:
  application:
    name: cloud-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

引导类

package com.wfx;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;


@SpringBootApplication
@EnableDiscoveryClient
public class WfxGateway {

    public static void main(String[] args) {
        SpringApplication.run(WfxGateway.class,args);
    }

}

谓词工厂

谓词

after:在某个时间到达后发生

before:在某个时间到达之前发生

between:在某两个时间中间发生

cookie:入age,19代表必须带有某个数据

hearder:请求头是否包含某个值

host:指定网址是否包括

method,指定发送来的时什么请求

Query

示例:

spring:
  cloud:
    gateway:
      routes:
        - id: wfx-jifen
          uri: lb://wfx-goods
          predicates:
            - Path=/goods/detail/100
            - After=2020-10-29T22:26:40.626+08:00[Asia/Shanghai]
            - Cookie=name,jack
            - Header=token
            - Host=**.wfx.com,**.jd.com
            - Method=GET
            - Query=baz,123

RemoteAddr

示例:

spring:
  cloud:
    gateway:
      routes:
        - id: wfx-jifen
          uri: lb://wfx-goods
          predicates:
            - Path=/goods/detail/100
            - After=2020-10-29T22:26:40.626+08:00[Asia/Shanghai]
#            - Cookie=name,jack
            - Header=token
            - Host=**.wfx.com,**.jd.com
            - Query=baz
            - RemoteAddr=192.168.234.122,192.168.234.123

自定义RoutePredicateFactory

自定义谓词工厂的类名规范:后缀必须是RoutePredicateFactory

package com.qf.predicate;
​
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
​
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
​
/**
 * <p>title: com.qf.predicate</p>
 * description:
 *  - MyHeader=token,123456
 *  要求,请求头中必须要有 token,123456 键值对
 *  - MyHeader=token
 *  要求:只要包含token key  value可以任意
 */
@Component
public class MyHeaderRoutePredicateFactory extends AbstractRoutePredicateFactory<MyConfig> {
​
​
    public MyHeaderRoutePredicateFactory() {
        super(MyConfig.class);
    }
​
    @Override
    public Predicate<ServerWebExchange> apply(MyConfig config) {
​
​
​
​
​
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
​
                //从请求头中获取指定请求头信息
                ServerHttpRequest request = serverWebExchange.getRequest();
//                String token = request.getHeaders().getFirst(config.getKey());
//
//                if(StringUtils.isEmpty(token)){
//
//                    return false;
//                }
//
//
//                if(!token.equals(config.getValue())){
//                    return false;
//                }
                
                if(StringUtils.isEmpty(config.getValue())){
                  //- MyHeader=token
                    if(request.getHeaders().containsKey(config.getKey())){
                        return  true;
                    }else{
                        return false;
                    }
​
                }else{
                   String token = request.getHeaders().getFirst(config.getKey());
​
                    if(StringUtils.isEmpty(token)){
​
                        return false;
                    }
​
                    if(!token.equals(config.getValue())){
                        return false;
                    }
                    return true;
                }
​
            }
        };
    }
​
​
    // - MyHeader=token,123
    //token=>MyConfig#key
    //123=>MyConfig#value
    @Override
    public List<String> shortcutFieldOrder() {
​
        return Arrays.asList("key","value");
    }
}

server:
  #网关微服务的启动端口
  port: 8040
spring:
  application:
    name: wfx-gateway #微服务的应用名
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 #nacos-server的服务地址
    gateway:
      #配置路由规则
      routes:
        - id: wfx-goods
          #请求转发到微服务集群
          uri: lb://wfx-goods
          predicates:
            - Path=/goods/**    #http://localhost:8040/goods/hello ->lb://wfx-goods/goods/hello
            - After=2021-02-04T09:35:30.654+08:00[Asia/Shanghai]
            - Cookie=age,18
            - MyHeader=name,xx

过滤器工厂详解

内置过滤器

1 AddRequestHeader GatewayFilter Factory

2 AddRequestParameter GatewayFilter Factory

3 AddResponseHeader GatewayFilter Factory

4 DedupeResponseHeader GatewayFilter Factory

5 Hystrix GatewayFilter Factory

6 FallbackHeaders GatewayFilter Factory

7 PrefixPath GatewayFilter Factory

8 PreserveHostHeader GatewayFilter Factory

9 RequestRateLimiter GatewayFilter Factory

10 RedirectTo GatewayFilter Factory

11 RemoveHopByHopHeadersFilter GatewayFilter Factory

12 RemoveRequestHeader GatewayFilter Factory

13 RemoveResponseHeader GatewayFilter Factory

14 RewritePath GatewayFilter Factory

15 RewriteResponseHeader GatewayFilter Factory

16 SaveSession GatewayFilter Factory

17 SecureHeaders GatewayFilter Factory

18 SetPath GatewayFilter Factory

19 SetResponseHeader GatewayFilter Factory

20 SetStatus GatewayFilter Factory

21 StripPrefix GatewayFilter Factory

22 Retry GatewayFilter Factory

23 RequestSize GatewayFilter Factory

24 Modify Request Body GatewayFilter Factory

25 Modify Response Body GatewayFilter Factory

26 Default Filters

SeataAT模式工作原理

分为两个阶段

tm向tc发起开启全局事务,TC会向global_table生成记录维护全局事务的状态,同时生成全局事务id

一阶段:解析sql得到sql类型看是删除还是其他,

查看前镜像,根据解析得到信息

执行sql更改name为GTS

再次查询修改后的数据

将前镜像结果和后镜像结果转换为json 保存到undo_log日志表中

将本地事务结果汇报tc

二阶段

事务边界发生异常

TM向TC发起全局事务回滚,TC驱动RM进行全局事务回滚,找到undo_log日志,生成反向日志补偿sql

执行sql进行数据回滚,删除undo_log日子

没有发生异常, tm向tc发起全局事务提交,tc驱动rm进行删除undo_log日志

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值