入门简介

概述

依赖

1
2
3
4
5
6
7
8
<!--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>

产品

image-20230830193857370

  • 资料

image-20230830194211784

Nacos

简介

是什么

  • eureka + config + bus

image-20230830194852200

==服务注册==

下载安装

  • nacos.io

image-20230830195410907

  1. 下载 https://github.com/alibaba/nacos/releases/tag/1.4.6
  2. 解压 E:\workspace\java\springcloud
  3. 修改配置 https://blog.csdn.net/qq_44377709/article/details/119154631
  4. bin 目录下 start.cmd
  5. startup.cmd -m standalone

服务提供者

建 module

  • cloudalibaba-provider-payment9001

pom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<dependencies>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<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>
<!--日常通用jar包配置-->
<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>
<scope>test</scope>
</dependency>
</dependencies>

yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server:
port: 9001

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

management:
endpoints:
web:
exposure:
include: "*"

主启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9001.class, args);
}

@RestController
public class EchoController {
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string) {
return "Hello Nacos Discovery " + string;
}
}
}

业务类

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
public class PaymentController
{
@Value("${server.port}")
private String serverPort;

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

==拷贝启动第二个实例==

  • 参数 -DServer.port=9011

image-20230830204639208

服务消费者

pom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<dependencies>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.cyt.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!-- SpringBoot整合Web组件 -->
<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>
<!--日常通用jar包配置-->
<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>
<scope>test</scope>
</dependency>
</dependencies>

yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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-provider

配置中心

image-20230831092406868

配置服务

建 module

  • cloudalibaba-config-nacos-client3377

pom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<dependencies>
<!--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>
<!--web + actuator-->
<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>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>
<scope>test</scope>
</dependency>
</dependencies>

yml

image-20230831092727463

  1. application.yml
1
2
3
4
5
spring:
profiles:
active: dev # 表示开发环境
#active: test # 表示测试环境
#active: info
  1. boootstrap.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 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格式的配置
group: DEV_GROUP
namespace: 7d8f0f5a-6a53-4785-9686-dd460158e5d4
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
# nacos-config-client-dev.yaml

# nacos-config-client-test.yaml ----> config.info
  1. 配置项说明

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

image-20230831093432973

主启动

1
2
3
4
5
6
7
@EnableDiscoveryClient
@SpringBootApplication
public class NacosConfigClientMain3377 {
public static void main(String[] args) {
SpringApplication.run(NacosConfigClientMain3377.class, args);
}
}

业务类

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
@RefreshScope //支持Nacos的动态刷新功能。
public class ConfigClientController
{
@Value("${config.info}")
private String configInfo;

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

nacos 添加配置

  1. 点击+号

image-20230831094000648

  1. 配置信息
  • 根据公式推出 ID: nacos-config-client-dev.yaml ==一定是 yaml!!==
  • image-20230831094336978
  • image-20230831094742829

测试

image-20230831094433416

命名空间-分组-DataID

image-20230831154504344

DataID 配置

  1. 添加新配置
  2. image-20230831160152881
  3. 修改 application.yml
1
2
3
4
spring:
profiles:
# active: dev # 表示开发环境
active: test # 表示测试环境

Group

  1. 配置 DEV 组

image-20230831161328931

  1. 配置 TEST 组

image-20230831161631951

  1. 修改配置

image-20230831161531406

NameSpace

  1. 创建命名空间

image-20230831171357737

  1. 拷贝 dev 命名空间 iD

0ecd3295-bc3d-40c8-9817-3fc1aebe3e56

image-20230831171629956

  1. 回到配置列表 dev 中

image-20230831172606477

  1. 新建配置

image-20230831172628614

  1. 修改 yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# bootstrap
spring:
application:
name: nacos-config-client
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos服务注册中心地址
config:
server-addr: localhost:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
group: DEV_GROUP
namespace: 0ecd3295-bc3d-40c8-9817-3fc1aebe3e56

# application
spring:
profiles:
# active: test # 表示测试环境
active: dev # 表示开发环境
# active: info

==namespace 相当于 package==

==group 相当于文件夹 controller service==

==id 相当于类==

集群和持久化配置

Sentinel

概述

对比

image-20230904150138400

主要特征

image-20230904150422952

安装 sentinel 控制台

  • 安装地址: E:\workspace\java\springcloud
  • -Dserver.port=XXX,指定端口

image-20230904151341069

  • id & password: sentinel

image-20230904151549527

初始化演示工程

image-20230904151827612

建 8401 服务

  • cloudalibaba-sentinel-service8401

POM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<dependencies>
<dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<groupId>com.cyt.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel -->
<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>
<!-- SpringBoot整合Web组件+actuator -->
<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>
<!--日常通用jar包配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.6.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>
<scope>test</scope>
</dependency>
</dependencies>

yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
server:
port: 8401

spring:
application:
name: cloudalibaba-sentinel-service
cloud:
nacos:
discovery:
server-addr: localhost:8848 #Nacos服务注册中心地址
sentinel:
transport:
dashboard: localhost:8080 #配置Sentinel dashboard地址
port: 8719
datasource:
ds1:
nacos:
server-addr: localhost:8848
dataId: cloudalibaba-sentinel-service
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow

management:
endpoints:
web:
exposure:
include: "*"

feign:
sentinel:
enabled: true # 激活Sentinel对Feign的支持

主启动

1
2
3
4
5
6
7
@SpringBootApplication
@EnableDiscoveryClient
public class MainApp8401 {
public static void main(String[] args) {
SpringApplication.run(MainApp8401.class, args);
}
}

业务类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RestController
@Slf4j
public class FlowLimitController
{
@GetMapping("/testA")
public String testA()
{
return "------testA";
}

@GetMapping("/testB")
public String testB()
{
log.info(Thread.currentThread().getName()+"\t"+"...testB");
return "------testB";
}
}

查看监控

image-20230904153306752

==流控规则==

基本介绍

image-20230904205634872

流控模式

直接(默认)

  • 给 testA 增加流控
  • 1s 访问一次—> 快速失败

image-20230904205146347

  • 失败场景

image-20230904205251932

关联

  • 设置

image-20230904210559519

  • 使用 postman 并发访问

image-20230904211354137

链路

  • 多个请求访问同一个资源

流控效果

直接

  • 直接快速失败

预热 Warm up

  1. 说明

image-20230904211958561

  1. 配置

image-20230904212306977

排队等待

image-20230904212916870

服务降级

介绍

image-20230904213703876

image-20230904213808795

配置实战

RT

  1. 概念

image-20230904214102516

image-20230904214225754

  1. 测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
@GetMapping("/testD")
public String testD() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("testD 测试RT");

// log.info("testD 异常比例");
// int age = 10 / 0;
return "------testD";
}
  1. 结论

image-20230904214825389

异常比例

  1. 概念

image-20230904215255500

image-20230904215345874

异常数

  1. 概念

image-20230904222057215

  1. 配置

image-20230904222233518

热点 Key 限流

概述

image-20230905123825875

案例

编码

  • 注意:blockHandler不管运行时异常
1
2
3
4
5
6
7
8
9
10
11
12
@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey", blockHandler = "deal_testHotKey")
public String testHotKey(@RequestParam(value = "p1", required = false) String p1,
@RequestParam(value = "p2", required = false) String p2) {
//int age = 10/0;
return "------testHotKey";
}

// testHotKey 的兜底方法
public String deal_testHotKey(String p1, String p2, BlockException exception) {
return "------deal_testHotKey,o(╥﹏╥)o"; //sentinel系统默认的提示:Blocked by Sentinel (flow limiting)
}

配置

image-20230905125228065

测试

image-20230905125312014

参数例外项

介绍

  • p1取特殊值时,阈值不一样 例如 vip 功能

image-20230905130119460

配置

image-20230905130411478

系统规则

  • 了解即可

image-20230905131950143

==@SentinelResource==

按资源名称限流

image-20230905180103260

业务类

1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
public class RateLimitController {
@GetMapping("/byResource")
@SentinelResource(value = "byResource", blockHandler = "handleException")
public CommonResult byResource() {
return new CommonResult(200, "按资源名称限流测试OK", new Payment(2020L, "serial001"));
}

// ***兜底方法
public CommonResult handleException(BlockException exception) {
return new CommonResult(444, exception.getClass().getCanonicalName() + "\t 服务不可用");
}
}

配置

image-20230905180713807

额外问题

  • 临时

image-20230905180640627

按照 url 地址限流

控制类

1
2
3
4
5
@GetMapping("/rateLimit/byUrl")
@SentinelResource(value = "byUrl")
public CommonResult byUrl() {
return new CommonResult(200, "按url限流测试OK", new Payment(2020L, "serial002"));
}

配置

image-20230905181306053

自定义方法

痛点

image-20230905201654516

  • 步骤

image-20230905201715671

controller

1
2
3
4
5
6
7
@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",
blockHandlerClass = CustomerBlockHandler.class,
blockHandler = "handlerException2")
public CommonResult customerBlockHandler() {
return new CommonResult(200, "按客戶自定义", new Payment(2020L, "serial003"));
}

myhandler

  • 创建 /myhandler
1
2
3
4
5
6
7
8
9
public class CustomerBlockHandler {
public static CommonResult handlerException(BlockException exception) {
return new CommonResult(4444, "按客戶自定义,global handlerException----1");
}

public static CommonResult handlerException2(BlockException exception) {
return new CommonResult(4444, "按客戶自定义,global handlerException----2");
}
}

更多注解属性说明

image-20230905213942436

服务熔断

环境搭建

  1. 提供模块
    • cloudalibaba-provider-payment9003 cloudalibaba-provider-payment9004
  2. 消费模块
    • cloudalibaba-consumer-nacos-order84

只配置 fallback

  • 用于 java 运行时异常兜底方法
    • id=4触发异常 访问兜底方法 handlerFallback
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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 + "/paymentSQL/" + 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

  • 用于 Sentinel 流量控制兜底方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
public CommonResult<Payment> fallback(@PathVariable Long id) {
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

if (id == 4) {
throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
} else if (result.getData() == null) {
throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
}
return result;
}

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

两个都配置

  • 若blockHandler和fallback都进行了配置,则被限流降级而抛出BlockException时只会进入blockHandler处理逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
@SentinelResource(value = "fallback", fallback = "handlerFallback", blockHandler = "blockHandler",
exceptionsToIgnore = {IllegalArgumentException.class})
public CommonResult<Payment> fallback(@PathVariable Long id) {
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

if (id == 4) {
throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
} else if (result.getData() == null) {
throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
}
return result;
}

忽略属性

image-20230907200142808

熔断+openfeign

配置

  1. cloudalibaba-consumer-nacos-order84 消费模块配置
1
2
3
4
# 激活Sentinel对Feign的支持
feign:
sentinel:
enabled: true
  1. 主启动类注解 @EnableFeignClients

业务类

service

  1. 接口
1
2
3
4
5
6
7
// value yml中 ; fallback 实现类
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)
public interface PaymentService
{
@GetMapping(value = "/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}
1
2
3
#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
nacos-user-service: http://nacos-payment-provider
  1. 实现类
1
2
3
4
5
6
7
8
9
@Component
public class PaymentFallbackService implements PaymentService
{
@Override
public CommonResult<Payment> paymentSQL(Long id)
{
return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial"));
}
}

controller

1
2
3
4
@GetMapping(value = "/consumer/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id) {
return paymentService.paymentSQL(id);
}

规则持久化

  • https://www.bilibili.com/video/BV18E411x7eT?p=137&vd_source=30924cc6debe913490fb34d7e3b62fdd

pom

1
2
3
4
5
<!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

yml

1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
sentinel:
datasource:
ds1:
nacos:
server-addr: localhost:8848
dataId: cloudalibaba-sentinel-service
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow

Seata

概述

产生原因

image-20230907220243729

  • 分布式之后

image-20230907220259936

概念

  • 3 + 1

image-20230907220936982

下载

  • 官网 seata.io/zh-cn

使用

image-20230907221657975

案例

image-20230907222447449