入门简介
概述
依赖
1 2 3 4 5 6 7 8
| <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>
|
产品


Nacos
简介
是什么

==服务注册==
下载安装

- 下载
https://github.com/alibaba/nacos/releases/tag/1.4.6
- 解压
E:\workspace\java\springcloud
- 修改配置
https://blog.csdn.net/qq_44377709/article/details/119154631
- bin 目录下
start.cmd
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> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <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>
|
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
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; } }
|
==拷贝启动第二个实例==

服务消费者
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> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.cyt.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <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>
|
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
service-url: nacos-user-service: http://nacos-payment-provider
|
配置中心

配置服务
建 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> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</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-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

application.yml
1 2 3 4 5
| spring: profiles: active: dev
|
boootstrap.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| server: port: 3377
spring: application: name: nacos-config-client cloud: nacos: discovery: server-addr: localhost:8848 config: server-addr: localhost:8848 file-extension: yaml group: DEV_GROUP namespace: 7d8f0f5a-6a53-4785-9686-dd460158e5d4
|
- 配置项说明
${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}

主启动
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 public class ConfigClientController { @Value("${config.info}") private String configInfo;
@GetMapping("/config/info") public String getConfigInfo() { return configInfo; } }
|
nacos 添加配置
- 点击+号

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


测试

命名空间-分组-DataID

DataID 配置
- 添加新配置

- 修改
application.yml
1 2 3 4
| spring: profiles: active: test
|
Group
- 配置 DEV 组

- 配置 TEST 组

- 修改配置

NameSpace
- 创建命名空间

- 拷贝 dev 命名空间 iD
0ecd3295-bc3d-40c8-9817-3fc1aebe3e56

- 回到配置列表 dev 中

- 新建配置

- 修改 yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| spring: application: name: nacos-config-client cloud: nacos: discovery: server-addr: localhost:8848 config: server-addr: localhost:8848 file-extension: yaml group: DEV_GROUP namespace: 0ecd3295-bc3d-40c8-9817-3fc1aebe3e56
spring: profiles: active: dev
|
==namespace 相当于 package==
==group 相当于文件夹 controller service==
==id 相当于类==
集群和持久化配置
Sentinel
概述
对比

主要特征

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


初始化演示工程

建 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> <groupId>com.cyt.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <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>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 sentinel: transport: dashboard: localhost:8080 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
|
主启动
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"; } }
|
查看监控

==流控规则==
基本介绍

流控模式
直接(默认)
- 给 testA 增加流控
- 1s 访问一次—>
快速失败


关联


链路
流控效果
直接
预热 Warm up
- 说明

- 配置

排队等待

服务降级
介绍


配置实战
RT
- 概念


- 测试代码
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");
return "------testD"; }
|
- 结论

异常比例
- 概念


异常数
- 概念

- 配置

热点 Key 限流
概述

案例
编码
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) { return "------testHotKey"; }
public String deal_testHotKey(String p1, String p2, BlockException exception) { return "------deal_testHotKey,o(╥﹏╥)o"; }
|
配置

测试

参数例外项
介绍
- 当
p1取特殊值时,阈值不一样 例如 vip 功能

配置

系统规则

==@SentinelResource==
按资源名称限流

业务类
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 服务不可用"); } }
|
配置

额外问题

按照 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")); }
|
配置

自定义方法
痛点


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
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"); } }
|
更多注解属性说明

服务熔断
环境搭建
- 提供模块
cloudalibaba-provider-payment9003 cloudalibaba-provider-payment9004
- 消费模块
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",fallback = "handlerFallback") 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; }
public CommonResult handlerFallback(@PathVariable Long id, Throwable e) { Payment payment = new Payment(id, "null"); return new CommonResult<>(444, "兜底异常handlerFallback,exception内容 " + e.getMessage(), payment); }
|
只配置 blockhandler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @SentinelResource(value = "fallback",blockHandler = "blockHandler") 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; }
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; }
|
忽略属性

熔断+openfeign
配置
- 对
cloudalibaba-consumer-nacos-order84 消费模块配置
1 2 3 4
| feign: sentinel: enabled: true
|
- 主启动类注解
@EnableFeignClients
业务类
service
- 接口
1 2 3 4 5 6 7
| @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
| service-url: nacos-user-service: http://nacos-payment-provider
|
- 实现类
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
| <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
概述
产生原因


概念

下载
使用

案例
