SpringCloud学习笔记尚硅谷周阳2020版 下半场SpringCloud Alibaba

SpringCloud学习笔记

代码 gitee仓库地址

https://gitee.com/lu-yi1104/spring-cloud_-study.git/

上半场 (一)地址

https://blog.csdn.net/weixin_43691773/article/details/109167048

SpringCloud Alibaba 简介

在这里插入图片描述
在这里插入图片描述

官网地址

https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
依赖 父工程已经导入了
在这里插入图片描述
在这里插入图片描述

Spring Cloud Alibaba Nacos服务注册中心和配置中心

简介

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下载地址

https://github.com/alibaba/Nacos

中文地址
https://nacos.io/zh-cn/

nacos下载和安装

在这里插入图片描述
下载解压
修改startup.cmd MODE 由cluster改为单机版
在这里插入图片描述

启动
在这里插入图片描述
访问 localhost:8848/nacos 出现界面代表成功 默认账号密码 nacos/nacos
在这里插入图片描述

Nacos作为服务注册中心

Nacos之服务提供者注册

新建模块 9001
跟着官网来
https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/en-us/index.html#_spring_cloud_alibaba_nacos_discovery
pom文件
在父工程pom文件加入 springcloud alibaba的依赖

  <!--spring cloud alibaba 2.1.0.RELEASE-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

9001 pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.luyi.cloud</artifactId>
        <groupId>com.luyi.cloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloudalibaba-provider-payment9001</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

</project>

yml文件

server:
 port: 9001

spring:
  application:
    name: nacos-provider
  cloud:
   nacos:
    discovery:
     server-addr: 127.0.0.1:8848 #配置Nacos地址

# 暴露要监控的
management:
  endpoints:
   web:
    exposure:
      include: '*'


主启动类

package com.luyi.sprinhcloud.alibaba;

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

/**
 * @author 卢意
 * @create 2020-11-06 11:25
 */
@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain9001 {
	public static void main(String[] args) {
		SpringApplication.run(PaymentMain9001.class, args);
	}
}

controller层

package com.luyi.sprinhcloud.alibaba.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 卢意
 * @create 2020-11-06 11:27
 */
@RestController
public class PaymentController {
	@Value("${server.port}")
	private String serverPort;

	@GetMapping(value = "/payment/nacos/{id}")
	public String getPyment(@PathVariable("id") Integer id){
		return "nacos register ,serverPort: "+serverPort+"\t id: "+id;
	}
}

测试 首先启动nacos注册中心
再启动9001
在这里插入图片描述
为了演示nacos的负载均衡、参照9001侯建9002 (也可以直接拷贝9001的虚拟端口映射)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
启动
在这里插入图片描述

在这里插入图片描述

Nacos之服务消费者注册

新建order83模块

pom文件与上面相同

yml文件

server:
  port: 83

Spring:
  application:
    name: nacos-order-consumer

  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

# 消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-payment-privider

主启动类

package com.luyi.springcloud.alibaba;

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

/**
 * @author 卢意
 * @create 2020-11-06 11:56
 */
@EnableDiscoveryClient
@SpringBootApplication
public class OrderNacosMain83 {
	public static void main(String[] args) {
		SpringApplication.run(OrderNacosMain83.class, args);
	}
}

新建上下文配置类

package com.luyi.springcloud.alibaba.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @author 卢意
 * @create 2020-11-06 13:34
 */
@Configuration
public class ApplicationContextConfig {
	@Bean
	@LoadBalanced// resttemplate 结合ribbon做负载均衡的时候 要加入注解
	public RestTemplate getRestTemplate(){
		return new RestTemplate();
	}
}


controller类

package com.luyi.springcloud.alibaba.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @author 卢意
 * @create 2020-11-06 13:37
 */
@RestController
@Slf4j
public class OrderNacosController {
	@Resource
	private RestTemplate restTemplate;

	@Value("${service-url.nacos-user-service}")
	private String serverUrl;

	@GetMapping(value = "/consumer/payment/nacos/{id}")
	public String paymeentInfo(@PathVariable("id") Long id){
		return restTemplate.getForObject(serverUrl+"/payment/nacos/"+id,String.class );
	}
}

启动83
在这里插入图片描述
访问成功 并带有负载均衡效果
在这里插入图片描述
在这里插入图片描述

Nacos之自带负载均衡

在这里插入图片描述

Nacos 服务中心对比提升

在这里插入图片描述
Nacos支持Cp+Ap的切换

在这里插入图片描述
在这里插入图片描述

Nacos之服务配置中心–基础配置

新建配置中心 3377
pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.luyi.cloud</artifactId>
        <groupId>com.luyi.cloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloudalibaba-config-nacos-client3377</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--nacos-config-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <!-- nacos-discovery -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
</project>

两个yml文件
在这里插入图片描述
bootstrap文件

# nacos 配置
server:
  port: 3377

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # Nacos服务注册中心地址
      config:
          server-addr: localhost:8848 # Nacos作为服务中心的地址
          file-extension: yaml # 指定Yaml格式的配置  3377就可以去配置中心读指定后缀名是yaml的文件

# ${spring.application.name}-${spring.profile.active}.${Spring.cloud.nacos.config.file.extension}

application.yml

spring:
  profiles:
    active: dev # 表示开发环境

主启动类

package com.luyi.springcloud;

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

/**
 * @author 卢意
 * @create 2020-11-06 17:04
 */
@EnableDiscoveryClient
@SpringBootApplication
public class NacosClientConfigMain3377 {
	public static void main(String[] args) {
		SpringApplication.run(NacosClientConfigMain3377.class, args);
	}
}

重复投入

package com.luyi.springcloud.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 卢意
 * @create 2020-11-06 17:10
 */
@RestController
@RefreshScope //支持Nacos动态刷新功能
public class ConfigClientController {
	@Value("${config.info}")
	private String configInfo;

	@GetMapping("/config/info")
	public String getConfigInfo(){
		return configInfo;
	}

}

nacos中的配置规则



${spring.application.name}在这里插入图片描述
${spring.profile.active}
在这里插入图片描述
${Spring.cloud.nacos.config.file.extension}
在这里插入图片描述

配置新增

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试

在这里插入图片描述
启动发现报错了 我丢 但是不要紧张阳哥 也报了
在这里插入图片描述
原因
在这里插入图片描述
解决 吧yml 都改成yaml
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Nacos之服务配置中心–分类配置

问题
在这里插入图片描述

Nacos之命名空间分组和 Goup Data ID三者之间的关系

在这里插入图片描述

在这里插入图片描述
大致架构
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Data ID方案


新建dev 配置DataID
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
修改application.yml在这里插入图片描述

重启3377开测

Group方案

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Namespace命名空间方案

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对应 DEV命名空间ID在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Nacos集群和持久化配置 (重要)

官网说明

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Nacos持久化切换配置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456

在这里插入图片描述
在这里插入图片描述

Linux版本安装

在这里插入图片描述
官网下载tar包
在这里插入图片描述
在这里插入图片描述

Nacos集群配置

在这里插入图片描述
执行数据库文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以需要修改sh脚本和conf
在这里插入图片描述
在这里插入图片描述

编辑startup脚本
在这里插入图片描述
在这里插入图片描述
1.4的nacos -p 已经有了 所以我换成port
在这里插入图片描述
在这里插入图片描述
nginx配置
在这里插入图片描述
启动三个nacos
在这里插入图片描述

在这里插入图片描述
启动nginx
在这里插入图片描述
这里我测试失败了 应该是版本问题 1.4版本的太新了 伪集群会出现绑定的问题 有时间再去试一下 1.3版本的吧

Sentinel

介绍

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

下和安装

https://github.com/alibaba/Sentinel/releases
本次不搞七搞八的 V1.7就好了
在这里插入图片描述

在这里插入图片描述
localhost:8080
用户密码 sentinel/sentinel
在这里插入图片描述
在这里插入图片描述

初始化监控

新建模块8491
pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.luyi.cloud</artifactId>
        <groupId>com.luyi.cloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloudalibaba-sentinel-service8401</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <!-- nacos-discovery -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--sentinel datasource nacos  持久化会用到-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

</project>

yml文件

server:
  port: 8401
  
spring:
  application:
    name: cloudalibaba-sentinel-service
    
  cloud:
    nacos:
      discovery:
        # Nacos作为服务中心的地址
        server-addr: localhost:8848
    sentinel:
      transport:
        # 配置Sentinel dashboard地址
        dashboard: localhost:8080
        # 默认8719端口,加入被占用 自动+1寻找未被占用的端口
        port: 8719
     
  #监控   
management:
  endpoints:
    web:
      exposure:
        include: '*'

主启动类

package com.luyi.springcloud.alibaba;

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

/**
 * @author 卢意
 * @create 2020-11-22 13:48
 */
@SpringBootApplication
@EnableDiscoveryClient // 可以注册进注册中心
public class MainApp8401 {
	public static void main(String[] args) {
		SpringApplication.run(MainApp8401.class,args);
	}
}

controller层

package com.luyi.springcloud.alibaba.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 卢意
 * @create 2020-11-22 13:50
 */
@RestController
public class FlowLimitController {
	@GetMapping("/testA")
	public String testA()
	{
		return "------------------testA";
	}
	@GetMapping("/testB")
	public String testB()
	{
		return "------------------testB";
	}
}

启动nacos 启动sentinel 在启动8401
在这里插入图片描述
sentinel页面还没有东西 因为 它是懒加载模式
在这里插入图片描述
访问两次后 有流量通过 就会显示了 Sentinel正在监控8401
在这里插入图片描述
在这里插入图片描述

流控规则简介

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

QPS(每秒请求数)直接失败

直接失败

在这里插入图片描述
在这里插入图片描述
超过阈值(当前配置一秒一次) 就会失败
在这里插入图片描述

线程数直接失败

在这里插入图片描述
系统一次只能处理${单机阈值}个线程数 超过则新进来的线程请求失败
在这里插入图片描述
在这里插入图片描述

让线程睡0.8秒
在这里插入图片描述
在这里插入图片描述

关联失败

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

链路失败

设置资源路口 /testA /testB是统一个资源路口 testA被限制失败之后 testB也会失败
在这里插入图片描述
在这里插入图片描述
例如 开始设置的阈值为10 设置时间为5秒 冷加载因子(threshold迷人值是3)最初的阈值就是10/3 大致为3 五秒 之后 慢慢阈值升到10
在这里插入图片描述

预热

在这里插入图片描述
在这里插入图片描述

排队等待

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里用testA做 测试
在这里插入图片描述

在这里插入图片描述

降级规则

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
sentinel的断路器是没有半开状态的 而Hystrix有
在这里插入图片描述

RT

在这里插入图片描述
平均响应时间0.2秒 等待回复时间1秒
在这里插入图片描述
新建testD
在这里插入图片描述
测试
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

异常比例


设置异常率为20% 超过该异常率 则熔断降级
在这里插入图片描述
这边是100%的异常率
在这里插入图片描述
压测
在这里插入图片描述
停止则正常报错

在这里插入图片描述

异常数


在这里插入图片描述
在这里插入图片描述

启动五次时 就会熔断 过1分钟才会正常报错

热点key限流

操作

根据请求传入的参数进行限流

在这里插入图片描述
在这里插入图片描述
首先这是默认相应
在这里插入图片描述
第0个参数 的访问次数超过QPS的阈值 触发熔断降级
在这里插入图片描述

在这里插入图片描述
p2一直点则没事
在这里插入图片描述
不使用 b

如果将 blockHandler去掉
在这里插入图片描述
异常会显示到页面 blockHandler是一个兜底的方法
在这里插入图片描述

参数例外项

特殊情况
在这里插入图片描述
记得点添加
在这里插入图片描述

在这里插入图片描述

注意事项

加入异常
在这里插入图片描述
这个异常类无法被blockHandler 兜底
在这里插入图片描述

在这里插入图片描述

sentinel系统规则

在这里插入图片描述
在这里插入图片描述
总的系统规则 QPS 对cloudalibaba-sentinel-service系统中的所有请求应用都生效
在这里插入图片描述

@SentinelResource的配置

修改 8401的pom文件

 <!--引入自己定义的api通用包, 可以使用Payment支付Entity-->
        <dependency>
            <groupId>com.luyi.cloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>

新建一个Controller类

package com.luyi.springcloud.alibaba.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.luyi.consumer.api.entity.CommonResult;
import com.luyi.consumer.api.entity.Payment;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author 卢意
 * @create 2020-11-22 17:33
 */
 @RestController
public class RateLimitController {
	@GetMapping("/byResource")
	@SentinelResource(value="byResource",blockHandler = "handleException")
	public CommonResult byResource(){
		return new CommonResult(200,"按资源名称限流OK",new Payment());
	}
	public CommonResult handleException(BlockException exception){
		return new CommonResult(404,exception.getClass().getCanonicalName()+"\t 服务不可用");
	}
}

在这里插入图片描述
注意选择下面那个 资源名称
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
新增一个业务没有兜底的方法 使用系统默认
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

面临的一些问题

在这里插入图片描述

客户自定义限流处理逻辑

步骤
在这里插入图片描述

package com.luyi.springcloud.alibaba.myHandler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.luyi.consumer.api.entity.CommonResult;

/**
 * @author 卢意
 * @create 2020-11-23 13:50
 */
public class CustomerBlockHandler {
	public static CommonResult handlerException1(BlockException exception){
		return new CommonResult(444,"按客户自定义,global handlerException-----1");
	}
	public static CommonResult handlerException2(BlockException exception){
		return new CommonResult(444,"按客户自定义,global handlerException-----12");
	}
}


二号方法兜底
在这里插入图片描述
启动8401
正常访问一次http://localhost:8401/rateLimit/customerBlockHandler 让他被sentinel监控
在这里插入图片描述
sentinel新增流控规则

在这里插入图片描述
兜底的是自定义的方法2
在这里插入图片描述
进一步说明在这里插入图片描述

更多属性说明

详细看官网吧

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Sentinel服务熔断

Ribbon环境预说明

sentinel整合ribbon+openfeign+fallback
在这里插入图片描述

在这里插入图片描述
新建 9003 9004
pom文件

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <!-- nacos-discovery -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--sentinel datasource nacos  持久化会用到-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--引入自己定义的api通用包, 可以使用Payment支付Entity-->
        <dependency>
            <groupId>com.luyi.cloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

yml文件

server:
  port: 9003

spring:
  application:
    name: nacos-payment-provider

  cloud:
    nacos:
      discovery:
        # Nacos\u4F5C\u4E3A\u670D\u52A1\u4E2D\u5FC3\u7684\u5730\u5740
        server-addr: localhost:8848
  
management:
  endpoints:
    web:
      exposure:
        include: '*'

主启动类

package com.luyi.springcloud.alibaba;

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

/**
 * @author 卢意
 * @create 2020-11-23 14:30
 */
@SpringBootApplication
@EnableDiscoveryClient
public class Payment9003 {
	public static void main(String[] args) {
		SpringApplication.run(Payment9003.class, args);
	}
}

Controller层

package com.luyi.springcloud.alibaba.controller;

import com.luyi.consumer.api.entity.CommonResult;
import com.luyi.consumer.api.entity.Payment;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;

/**
 * @author 卢意
 * @create 2020-11-23 14:31
 */
@RestController
public class PaymentController {
	@Value("${server.port}")
	private String serverPort;

	public static HashMap<Long,Payment> hashMap=new HashMap<>();

	static {
		hashMap.put(1L, new Payment(1L,"199811046510"));
		hashMap.put(2L, new Payment(2L,"199811046511"));
		hashMap.put(3L, new Payment(3L,"199811046512"));
	}
	
	@GetMapping(value = "/payment/{id}")
	public CommonResult<Payment> paymentSQL(@PathVariable("id")Long id){
		Payment payment=hashMap.get(id);
		CommonResult<Payment> result=new CommonResult(200,"from mysql ,serverport: "+serverPort ,payment);
		return result;
	}
}

只有3条记录 当Id等于4时为null
在这里插入图片描述
在这里插入图片描述
新建 消费者 84
pom文件和上面一样
yml文件

server:
  port: 84

spring:
  application:
    name: nacos-order-consumer
  cloud:
      nacos:
        discovery:
          server-addr: localhost:8848
      sentinel:
        transport:
          dashboard: localhost:8080
          # 默认端口  加入8719被占用 会自动+1扫描直到找到没有被占用的端口
          port: 8719 
          
service-url:
  nacos-user-service: http://nacos-payment-provider
         

RestTemplate配置类

package com.luyi.springcloud.alibaba.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * @author 卢意
 * @create 2020-11-23 14:50
 */
@Configuration
public class ApplicationContextConfig {
	
	@Bean
	@LoadBalanced
	public RestTemplate getRestTemplate(){
		return new RestTemplate();
	}
}

controller类

package com.luyi.springcloud.alibaba.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.luyi.consumer.api.entity.CommonResult;
import com.luyi.consumer.api.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @author 卢意
 * @create 2020-11-23 14:51
 */
@RestController
@Slf4j
public class CircleBreakerController {
	public static final String SERVICE_URL="http://nacos-payment-provider";

	@Resource
	private RestTemplate restTemplate;
	@RequestMapping("/consumer/fallback/{id}")
	@SentinelResource(value = "fallback") //没有配置
	public CommonResult<Payment> fallback(@PathVariable Long id){
		CommonResult<Payment> result=restTemplate.getForObject(SERVICE_URL, "/payment/"+id,
				CommonResult.class,id);
		if(id == 4){
			throw  new IllegalArgumentException("IllegalArgumentException,非法参数异常.....");
		}else if(result.getData()==null){
			throw new NullPointerException("NullPointerException,该Id没有对应记录.空指针异常.....");
		}
		return  result;
	}
}

在这里插入图片描述
在这里插入图片描述

sentinel 服务熔断无配置

启动84 9003,9004
测试 业务类和 负载均衡无问题

在这里插入图片描述
没有设置blockHandler
id3以上都是异常页面
在这里插入图片描述
在这里插入图片描述

sentinel 服务熔断只配置fallback

修改业务类代码

package com.luyi.springcloud.alibaba.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.luyi.consumer.api.entity.CommonResult;
import com.luyi.consumer.api.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @author 卢意
 * @create 2020-11-23 14:51
 */
@RestController
@Slf4j
public class CircleBreakerController {
	public static final String SERVICE_URL="http://nacos-payment-provider";

	@Resource
	private RestTemplate restTemplate;
	@RequestMapping("/consumer/fallback/{id}")
	//@SentinelResource(value = "fallback") //没有配置
	@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
	public CommonResult<Payment> fallback(@PathVariable Long id){
		CommonResult<Payment> result=restTemplate.getForObject(SERVICE_URL+"/payment/"+id,
				CommonResult.class,id);
		if(id == 4){
			throw  new IllegalArgumentException("IllegalArgumentException,非法参数异常.....");
		}else if(result.getData()==null){
			throw new NullPointerException("NullPointerException,该Id没有对应记录.空指针异常.....");
		}
		return  result;
	}

	//本例是fallback的兜底
	public CommonResult handlerFallback(@PathVariable Long id,Throwable e){
		Payment payment = new Payment(id,"null");
		return new CommonResult<>(444,"兜底异常类handlerFallback,Exception内容: "+ e.getMessage(),payment);
	}
}

在这里插入图片描述

结论 fallback可以管理Java的运行异常

sentinel 服务熔断只配置blockHandler

修改业务类

package com.luyi.springcloud.alibaba.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.luyi.consumer.api.entity.CommonResult;
import com.luyi.consumer.api.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @author 卢意
 * @create 2020-11-23 14:51
 */
@RestController
@Slf4j
public class CircleBreakerController {
	public static final String SERVICE_URL="http://nacos-payment-provider";

	@Resource
	private RestTemplate restTemplate;
	@RequestMapping("/consumer/fallback/{id}")
	//@SentinelResource(value = "fallback") //没有配置
	//@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
	@SentinelResource(value = "fallback",blockHandler = "blockHandler") // blockHandler 只负责sentinel控制台配置违规
	public CommonResult<Payment> fallback(@PathVariable Long id){
		CommonResult<Payment> result=restTemplate.getForObject(SERVICE_URL+"/payment/"+id,
				CommonResult.class,id);
		if(id == 4){
			throw  new IllegalArgumentException("IllegalArgumentException,非法参数异常.....");
		}else if(result.getData()==null){
			throw new NullPointerException("NullPointerException,该Id没有对应记录.空指针异常.....");
		}
		return  result;
	}

	//本例是fallback的兜底
	/*public CommonResult handlerFallback(@PathVariable Long id,Throwable e){
		Payment payment = new Payment(id,"null");
		return new CommonResult<>(444,"兜底异常类handlerFallback,Exception内容: "+ e.getMessage(),payment);
	}*/

	//本例是blockHandler的兜底
	public CommonResult blockHandler(@PathVariable Long id, BlockException	 e){
		Payment payment = new Payment(id,"null");
		return new CommonResult<>(444,"blockHandler-sentinel限流,无此流水,BlockException: "+ e.getMessage(),payment);
	}

}

新增sentinel降级规则
在这里插入图片描述
错误两次以上降级
在这里插入图片描述
在这里插入图片描述

sentinel 服务熔断blockHandler和fallback都配置

修改业务类

package com.luyi.springcloud.alibaba.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.luyi.consumer.api.entity.CommonResult;
import com.luyi.consumer.api.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @author 卢意
 * @create 2020-11-23 14:51
 */
@RestController
@Slf4j
public class CircleBreakerController {
	public static final String SERVICE_URL="http://nacos-payment-provider";

	@Resource
	private RestTemplate restTemplate;
	@RequestMapping("/consumer/fallback/{id}")
	//@SentinelResource(value = "fallback") //没有配置
	//@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
	//@SentinelResource(value = "fallback",blockHandler = "blockHandler") // blockHandler 只负责sentinel控制台配置违规
	@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler")  //都配置
	public CommonResult<Payment> fallback(@PathVariable Long id){
		CommonResult<Payment> result=restTemplate.getForObject(SERVICE_URL+"/payment/"+id,
				CommonResult.class,id);
		if(id == 4){
			throw  new IllegalArgumentException("IllegalArgumentException,非法参数异常.....");
		}else if(result.getData()==null){
			throw new NullPointerException("NullPointerException,该Id没有对应记录.空指针异常.....");
		}
		return  result;
	}

	//本例是fallback的兜底
	public CommonResult handlerFallback(@PathVariable Long id,Throwable e){
		Payment payment = new Payment(id,"null");
		return new CommonResult<>(444,"兜底异常类handlerFallback,Exception内容: "+ e.getMessage(),payment);
	}

	//本例是blockHandler的兜底
	public CommonResult blockHandler(@PathVariable Long id, BlockException	 e){
		Payment payment = new Payment(id,"null");
		return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水,BlockException: "+ e.getMessage(),payment);
	}

}

新增流控规则
在这里插入图片描述
限流
在这里插入图片描述
fallback
在这里插入图片描述
点快了又走 blockHandler 流控规则
在这里插入图片描述

exceptionToIgnore(异常忽略属性)

在这里插入图片描述

OpenFeign

在这里插入图片描述
引入openfeign
在这里插入图片描述
application加入


主启动类
在这里插入图片描述
新增service接口

feign 接口+注解

package com.luyi.springcloud.alibaba.service;

import com.luyi.consumer.api.entity.CommonResult;
import com.luyi.consumer.api.entity.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * @author 卢意
 * @create 2020-11-23 15:58
 */

@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallBackService.class)
public interface PaymentService {
	@GetMapping("/payment/{id} ")
	public CommonResult<Payment> payment(@PathVariable("id") Long Id);
}


兜底 实现类

package com.luyi.springcloud.alibaba.service;

import com.luyi.consumer.api.entity.CommonResult;
import com.luyi.consumer.api.entity.Payment;
import org.springframework.stereotype.Component;

/**
 * @author 卢意
 * @create 2020-11-23 16:02
 */
@Component
public class PaymentFallBackService implements PaymentService{
	@Override
	public CommonResult<Payment> payment(Long id) {
		return new CommonResult<>(444444,"服务降级返回,----PaymentFallBackService",new Payment(id, "errorSerial"));
	}
}

controller类加入新代码
在这里插入图片描述
启动测试
正常测试无异常
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

熔断框架的比较

在这里插入图片描述

在这里插入图片描述

规则持久化

在这里插入图片描述
其实只要有持久化的文件都能保存 如redis等等 官方推荐nacos
在这里插入图片描述
修改 8401
pom文件 新增 下面依赖

 <!--sentinel datasource nacos  持久化会用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

application.yml文件加入下列配置

    datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

在这里插入图片描述
在这里插入图片描述

[
    {
        "resource":"/byResource",
        "limitApp":"default",
        "grade":1,
        "count":1,
        "strategy":0,
        "controlBehavior":0,
        "clusterMode":false
    }
]

json说明
在这里插入图片描述
启动8401 当前没有规则
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Seata处理分布式事务

分布式事务问题的由来

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一次业务操作需要跨多少个数据源或需要跨多少个系统进行远程调用,就会产生分布式事务问题

Seata术语


官网http://seata.io/zh-cn/
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

安装

1.1.0
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
修改file.conf
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建数据库seata
创建表

-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(
    `xid`                       VARCHAR(128) NOT NULL,
    `transaction_id`            BIGINT,
    `status`                    TINYINT      NOT NULL,
    `application_id`            VARCHAR(32),
    `transaction_service_group` VARCHAR(32),
    `transaction_name`          VARCHAR(128),
    `timeout`                   INT,
    `begin_time`                BIGINT,
    `application_data`          VARCHAR(2000),
    `gmt_create`                DATETIME,
    `gmt_modified`              DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(96),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

修改register.conf
在这里插入图片描述
启动nacos 在启动SeaTa
在这里插入图片描述

业务数据库准备

在这里插入图片描述
在这里插入图片描述

Create DATABASE seata_order;
CREATE DATABASE seata_storage;
CREATE DATABASE seata_account;

t_account
在这里插入图片描述
t_order
在这里插入图片描述
t_storage
在这里插入图片描述
在这里插入图片描述

-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
    `branch_id`     BIGINT(20)   NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(100) NOT NULL COMMENT 'global transaction id',
    `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
    `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',
    `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',
    `log_created`   DATETIME(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = INNODB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';

最终效果
在这里插入图片描述

业务微服务准备

order

在这里插入图片描述
在这里插入图片描述
pom 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.luyi.cloud</artifactId>
        <groupId>com.luyi.cloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>seata-order-service2001</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <!-- nacos-discovery -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--seata-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <exclusion>
                <artifactId>seata-all</artifactId>
                <groupId>io.seata</groupId>
            </exclusion>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>1.1.0</version>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--引入自己定义的api通用包, 可以使用Payment支付Entity-->
        <dependency>
            <groupId>com.luyi.cloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
           <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

</project>

Order 实体类

package com.luyi.springcloud.alibaba.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;

/**
 * @author 卢意
 * @create 2020-11-23 19:24
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
	private Long id;
	private Long userId;
	private Long ProductId;
	private Integer count;
	private BigDecimal money;
	/**
	 * 订单状态: 0创建中 1已完成
	 */
	private Integer status;
	
}

CommonResult.class

package com.luyi.springcloud.alibaba.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author 卢意
 * @create 2020-11-23 19:48
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
	private Integer code;
	private String message;
	private T data;
	
	public CommonResult(Integer code, String message){
		this(code,message,null);
	}
}

application.yml

server:
  port: 2001

spring:
   application:
     name: seata-order-service
   cloud:
     alibaba:
       seata:
         # 自定义事务组名称需要与seata-server中对应
         tx-service-group: luyi_tx_group
     nacos:
       discovery:
         server-addr: localhost:8848
   datasource:
     driver-class-name: com.mysql.jdbc.Driver
     url: jdbc:mysql://localhost:3306/seata_order
     username: root
     password: 123456

feign:
  hystrix:
    enabled: false

logging:
  level:
    io:
      seata: info

mybatis:
  mapper-locations: classpath:mapper/*.xml


新建 file.conf

  transport {
    # tcp udt unix-domain-socket
    type = "TCP"
    #NIO NATIVE
    server = "NIO"
    #enable heartbeat
    heartbeat = true
    # the client batch send request enable
    enableClientBatchSendRequest = false
    #thread factory for netty
    threadFactory {
      bossThreadPrefix = "NettyBoss"
      workerThreadPrefix = "NettyServerNIOWorker"
      serverExecutorThreadPrefix = "NettyServerBizHandler"
      shareBossWorker = false
      clientSelectorThreadPrefix = "NettyClientSelector"
      clientSelectorThreadSize = 1
      clientWorkerThreadPrefix = "NettyClientWorkerThread"
      # netty boss thread size,will not be used for UDT
      bossThreadSize = 1
      #auto default pin or 8
      workerThreadSize = "default"
    }
    shutdown {
      # when destroy server, wait seconds
      wait = 3
    }
    serialization = "seata"
    compressor = "none"
  }
  # service configuration, only used in client side
  service {
    #transaction service group mapping
   # vgroupMapping.my_test_tx_group = "default"
   vgroupMapping.luyi_tx_group = "default"
    #only support when registry.type=file, please don't set multiple addresses
    default.grouplist = "127.0.0.1:8091"
    #degrade, current not support
    enableDegrade = false
    #disable seata
    disableGlobalTransaction = false
  }
  #client transaction configuration, only used in client side
  client {
    rm {
      asyncCommitBufferLimit = 10000
      lock {
        retryInterval = 10
        retryTimes = 30
        retryPolicyBranchRollbackOnConflict = true
      }
      reportRetryCount = 5
      tableMetaCheckEnable = false
      reportSuccessEnable = false
      sqlParserType = druid
    }
    tm {
      commitRetryCount = 5
      rollbackRetryCount = 5
    }
    undo {
      dataValidation = true
      logSerialization = "jackson"
      logTable = "undo_log"
    }
    log {
      exceptionRate = 100
    }
  }

  ## transaction log store, only used in server side
  store {
    ## store mode: file、db
    mode = "db"
    ## file store property
    file {
      ## store location dir
      dir = "sessionStore"
      # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
      maxBranchSessionSize = 16384
      # globe session size , if exceeded throws exceptions
      maxGlobalSessionSize = 512
      # file buffer size , if exceeded allocate new buffer
      fileWriteBufferCacheSize = 16384
      # when recover batch read size
      sessionReloadReadSize = 100
      # async, sync
      flushDiskMode = async
    }

    ## database store property
    db {
      ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
      datasource = "dbcp"
      ## mysql/oracle/h2/oceanbase etc.
      dbType = "mysql"
      driverClassName = "com.mysql.jdbc.Driver"
      url = "jdbc:mysql://127.0.0.1:3306/seata"
      user = "root"
      password = "123456"
      minConn = 1
      maxConn = 10
      globalTable = "global_table"
      branchTable = "branch_table"
      lockTable = "lock_table"
      queryLimit = 100
    }
  }
  ## server configuration, only used in server side
  server {
    recovery {
      #schedule committing retry period in milliseconds
      committingRetryPeriod = 1000
      #schedule asyn committing retry period in milliseconds
      asynCommittingRetryPeriod = 1000
      #schedule rollbacking retry period in milliseconds
      rollbackingRetryPeriod = 1000
      #schedule timeout retry period in milliseconds
      timeoutRetryPeriod = 1000
    }
    undo {
      logSaveDays = 7
      #schedule delete expired undo_log in milliseconds
      logDeletePeriod = 86400000
    }
    #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
    maxCommitRetryTimeout = "-1"
    maxRollbackRetryTimeout = "-1"
    rollbackRetryTimeoutUnlockEnable = false
  }

  ## metrics configuration, only used in server side
  metrics {
    enabled = false
    registryType = "compact"
    # multi exporters use comma divided
    exporterList = "prometheus"
    exporterPrometheusPort = 9898
  }

注意这里
在这里插入图片描述
新建 register.conf

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"

  nacos {
    serverAddr = "localhost:8848"
    namespace = ""
    cluster = "default"
  }
  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    application = "default"
    weight = "1"
  }
  redis {
    serverAddr = "localhost:6379"
    db = "0"
  }
  zk {
    cluster = "default"
    serverAddr = "127.0.0.1:2181"
    session.timeout = 6000
    connect.timeout = 2000
  }
  consul {
    cluster = "default"
    serverAddr = "127.0.0.1:8500"
  }
  etcd3 {
    cluster = "default"
    serverAddr = "http://localhost:2379"
  }
  sofa {
    serverAddr = "127.0.0.1:9603"
    application = "default"
    region = "DEFAULT_ZONE"
    datacenter = "DefaultDataCenter"
    cluster = "default"
    group = "SEATA_GROUP"
    addressWaitTime = "3000"
  }
  file {
    name = "file.conf"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "file"

  nacos {
    serverAddr = "localhost"
    namespace = ""
    group = "SEATA_GROUP"
  }
  consul {
    serverAddr = "127.0.0.1:8500"
  }
  apollo {
    app.id = "seata-server"
    apollo.meta = "http://192.168.1.204:8801"
    namespace = "application"
  }
  zk {
    serverAddr = "127.0.0.1:2181"
    session.timeout = 6000
    connect.timeout = 2000
  }
  etcd3 {
    serverAddr = "http://localhost:2379"
  }
  file {
    name = "file.conf"
  }
}

dao接口及实现

package com.luyi.springcloud.alibaba.dao;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

/**
 * @author 卢意
 * @create 2020-11-23 19:52
 */
@Mapper
public interface Order {
	// 新建订单
	void create(Order order);

	// 更新订单状态  0变1
	void update(@Param("userId") Long userId,@Param("status") Integer status);


}

太多了我放弃了 无脑抓图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

storage

在这里插入图片描述
pom文件和2001一样
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Account

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@GlobalTransaction验证

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
数据库内容每错
在这里插入图片描述
在这里插入图片描述
openfeign会报超时异常
在这里插入图片描述
在这里插入图片描述
状态为0
在这里插入图片描述库存被扣了
在这里插入图片描述
账户也被扣钱了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试没有问题

seata原理简介

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
是什么
在这里插入图片描述
一阶段在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
debug看看
在这里插入图片描述
在这里插入图片描述
分支号不同 xid相同
在这里插入图片描述
rollback_info格式化查看一下
已经将前置和后置快照保存好,便于数据更新和回滚恢复
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
反向补偿或者正常提交 会批量删除相印的UNDO LOG记录

补充
在这里插入图片描述
在这里插入图片描述
ok结束 不得不说阳哥是我听过讲的最好的老师了 感谢指导 我会好好温故而知新 慢慢深入理解.


版权声明:本文为weixin_43691773原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。