diff --git a/.gitignore b/.gitignore index 299431a6e..cbbd33adb 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,7 @@ target/** *.iml *ipr *.iws + +### IntelliJ IDEA +.idea +target \ No newline at end of file diff --git a/README.md b/README.md index cf164c666..fffbe0517 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ +一个涵盖五个主流技术栈的**正经**仓库: +* [《Spring Boot 专栏》](https://github.com/YunaiV/SpringBoot-Labs#spring-boot-%E4%B8%93%E6%A0%8F) +* [《Spring Cloud Alibaba 专栏》](https://github.com/YunaiV/SpringBoot-Labs#spring-cloud-alibaba-%E4%B8%93%E6%A0%8F) +* [《Spring Cloud 专栏》](https://github.com/YunaiV/SpringBoot-Labs#spring-cloud-%E4%B8%93%E6%A0%8F) +* [《Dubbo 专栏》](https://github.com/YunaiV/SpringBoot-Labs#Dubbo-%E4%B8%93%E6%A0%8F) +* [《消息队列 MQ 专栏》](https://github.com/YunaiV/SpringBoot-Labs#%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97-mq-%E4%B8%93%E6%A0%8F) +* [《分布式事务专栏》](https://github.com/YunaiV/SpringBoot-Labs#分布式事务专栏) + +作为一个热爱**深夜**撸码的 18 岁头发茂密的可爱小男孩,希望大佬能够**一键三连**。 + +![一间三连](http://static.iocoder.cn/github-star.jpg) + +> ~~交流~~**装逼群**,请点击[传送门](http://www.iocoder.cn/mall-user-group/?vip&gitee),进行引导加入。**亲,一键三连啊** # Spring Boot 专栏 @@ -32,6 +45,8 @@ * [《芋道 Spring Boot API 接口文档 Swagger 入门》](http://www.iocoder.cn/Spring-Boot/Swagger/?github) 对应 [lab-24](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-24) * [《芋道 Spring Boot 参数校验 Validation 入门》](http://www.iocoder.cn/Spring-Boot/Validation/?github) 对应 [lab-22](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-22) * [《芋道 Spring Boot WebSocket 入门》](http://www.iocoder.cn/Spring-Boot/WebSocket/?github) 对应 [lab-25](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-25) +* [《性能测试 —— Tomcat、Jetty、Undertow 基准测试》](http://www.iocoder.cn/Performance-Testing/Tomcat-Jetty-Undertow-benchmark/?github) 对应 [lab-05](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-05) +* [《性能测试 —— SpringMVC、Webflux 基准测试》](http://www.iocoder.cn/Performance-Testing/SpringMVC-Webflux-benchmark/?github) 对应 [lab-06](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-06) ## RPC 开发 @@ -51,11 +66,16 @@ * [《芋道 Spring Boot JPA 入门》](http://www.iocoder.cn/Spring-Boot/JPA/?github) 对应 [lab-13](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-13) * [《芋道 Spring Boot JdbcTemplate 入门》](http://www.iocoder.cn/Spring-Boot/JdbcTemplate/?github) 对应 [lab-14](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-14) * [《芋道 Spring Boot Elasticsearch 入门》](http://www.iocoder.cn/Spring-Boot/Elasticsearch/?github) 对应 [lab-15](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-15) +* 《芋道 Spring Boot Solr 入门》计划中... * [《芋道 Spring Boot MongoDB 入门》](http://www.iocoder.cn/Spring-Boot/MongoDB/?github) 对应 [lab-16](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-16) * [《芋道 Spring Boot 多数据源(读写分离)入门》](http://www.iocoder.cn/Spring-Boot/dynamic-datasource/?github) 对应 [lab-17](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-17) * [《芋道 Spring Boot 分库分表入门》](http://www.iocoder.cn/Spring-Boot/sharding-datasource/?github) 对应 [lab-18](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-18) * [《芋道 Spring Boot 数据库版本管理入门》](http://www.iocoder.cn/Spring-Boot/database-version-control/?github) 对应 [lab-20](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-20) +## 事务管理 + +* [《芋道 Spring Boot 分布式事务 Seata 入门》](http://www.iocoder.cn/Spring-Boot/Seata/?github) 对应 [lab-52](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-52) + ## 安全控制 * [《芋道 Spring Boot 安全框架 Spring Security 入门》](http://www.iocoder.cn/Spring-Boot/Spring-Security/?github) 对应 [lab-01](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-01) @@ -73,6 +93,7 @@ * [《芋道 Spring Boot 消息队列 Kafka 入门》](http://www.iocoder.cn/Spring-Boot/Kafka/?github) 对应 [lab-03](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-03) * [《芋道 Spring Boot 消息队列 RabbitMQ 入门》](http://www.iocoder.cn/Spring-Boot/RabbitMQ/?github) 对应 [lab-04](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-04) * [《芋道 Spring Boot 消息队列 ActiveMQ 入门》](http://www.iocoder.cn/Spring-Boot/ActiveMQ/?github) 对应 [lab-32](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-32) +* [《芋道 Spring Boot 事件机制 Event 入门》](http://www.iocoder.cn/Spring-Boot/Event/?github) 对应 对应 [lab-54](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-54) ## 配置中心 @@ -94,9 +115,11 @@ * [《芋道 Spring Boot 服务容错 Sentinel 入门》](http://www.iocoder.cn/Spring-Boot/Sentinel/?github) 对应 [lab-46](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-46) * 《芋道 Spring Boot 服务容错 Hystrix 入门》计划中... +* 《芋道 Spring Boot 服务容错 Resilience4j 入门》计划中... ## 监控管理 +* [《芋道 Spring Boot 异常管理平台 Sentry 入门》](http://www.iocoder.cn/Spring-Boot/Sentry/?github) 对应 [lab-51](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-51) * [《芋道 Spring Boot 监控端点 Actuator 入门》](http://www.iocoder.cn/Spring-Boot/Actuator/?github) 对应 [lab-34](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-34) * [《芋道 Spring Boot 监控工具 Admin 入门》](http://www.iocoder.cn/Spring-Boot/Admin/?github) 对应 [lab-35](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-35) * [《芋道 Spring Boot 监控平台 Prometheus + Grafana 入门》](http://www.iocoder.cn/Spring-Boot/Prometheus-and-Grafana/?github) 对应 [lab-36](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-36) @@ -114,51 +137,200 @@ * 《芋道 Spring Boot 链路追踪 Pinpoint 入门》计划中... * 《芋道 Spring Boot 链路追踪 Elastic APM 入门》计划中... -## 性能测试 - -* [《性能测试 —— Tomcat、Jetty、Undertow 基准测试》](http://www.iocoder.cn/Performance-Testing/Tomcat-Jetty-Undertow-benchmark/?github) 对应 [lab-05](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-05) -* [《性能测试 —— SpringMVC、Webflux 基准测试》](http://www.iocoder.cn/Performance-Testing/SpringMVC-Webflux-benchmark/?github) 对应 [lab-06](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-06) -* [《性能测试 —— Spring Cloud Gateway、Zuul 基准测试》](http://www.iocoder.cn/Performance-Testing/SpringCloudGateway-Zuul-benchmark/?github) 对应 [lab-07](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-07) - # Spring Cloud Alibaba 专栏 +## Spring Cloud Alibaba 全家桶 + +* [《芋道 Spring Cloud Alibaba 介绍》](http://www.iocoder.cn/Spring-Cloud-Alibaba/intro/?github) * [《芋道 Spring Cloud Alibaba 注册中心 Nacos 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Nacos-Discovery/?github) 对应 [labx-01](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-01) +* [《芋道 Spring Cloud Alibaba 服务调用 Dubbo 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Dubbo/?github) 对应 [labx-07](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-07) +* [《芋道 Spring Cloud Alibaba 服务容错 Sentinel 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Sentinel/?github) 对应 [labx-04](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-04) +* [《芋道 Spring Cloud Alibaba 消息队列 RocketMQ 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/RocketMQ/?github) 对应 [labx-06](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-06) +* [《芋道 Spring Cloud Alibaba 事件总线 Bus RocketMQ 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Bus-RocketMQ/?github) 对应 [labx-20](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-20) +* [《芋道 Spring Cloud Alibaba 配置中心 Nacos 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Nacos-Config/?github) 对应 [labx-05](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-05) +* [《芋道 Spring Cloud Alibaba 分布式事务 Seata 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Seata/?github) 对应 [labx-17](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-17) + +## 推荐搭配食用 + * [《芋道 Spring Cloud Netflix 负载均衡 Ribbon 入门》](http://www.iocoder.cn/Spring-Cloud-Netflix/Ribbon/?github) 对应 [labx-02](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-02) -* 《芋道 Spring Cloud 声明式调用 OpenFeign 入门》 -* 《芋道 Spring Cloud Alibaba 服务调用 Dubbo 入门》 -* 《芋道 Spring Cloud Alibaba 配置中心 Nacos 入门》 -* 《芋道 Spring Cloud Alibaba 服务容错 Sentinel 入门》 -* 《芋道 Spring Cloud Netflix 服务容错 Hystrix 入门》 -* 《芋道 Spring Cloud Alibaba 消息队列 RocketMQ 入门》 -* 《芋道 Spring Cloud 服务网关 Spring Cloud Gateway 入门》 -* 《芋道 Spring Cloud Netflix 服务网关 Zuul 入门》 -* 《芋道 Spring Cloud 链路追踪 Sleuth 入门》 -* 《芋道 Spring Cloud 链路追踪 SkyWalking 入门》 -* TODO 监控 +* [《芋道 Spring Cloud 声明式调用 Feign 入门》](http://www.iocoder.cn/Spring-Cloud/Feign/?github) 对应 [labx-03](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-03) +* [《芋道 Spring Cloud 服务网关 Spring Cloud Gateway 入门》](http://www.iocoder.cn/Spring-Cloud/Spring-Cloud-Gateway/?github) 对应 [labx-08](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-08) +* [《芋道 Spring Cloud 链路追踪 SkyWalking 入门》](http://www.iocoder.cn/Spring-Cloud/SkyWalking/?github) 对应 [labx-14](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-14) # Spring Cloud 专栏 ## 注册中心 * [《芋道 Spring Cloud Alibaba 注册中心 Nacos 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Nacos-Discovery/?github) 对应 [labx-01](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-01) +* 《芋道 Spring Cloud Netflix 注册中心 Eureka 入门》计划中... +* 《芋道 Spring Cloud 注册中心 Zookeeper 入门》计划中... +* 《芋道 Spring Cloud 注册中心 Consul 入门》计划中... +* 《芋道 Spring Cloud 注册中心 Etcd 入门》计划中... ## 服务调用 -* 《芋道 Spring Cloud Alibaba 服务调用 Dubbo 入门》 +* [《芋道 Spring Cloud Alibaba 服务调用 Dubbo 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Dubbo/?github) 对应 [labx-07](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-07) * [《芋道 Spring Cloud Netflix 负载均衡 Ribbon 入门》](http://www.iocoder.cn/Spring-Cloud-Netflix/Ribbon/?github) 对应 [labx-02](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-02) -* 《芋道 Spring Cloud 声明式调用 OpenFeign 入门》 +* [《芋道 Spring Cloud 声明式调用 Feign 入门》](http://www.iocoder.cn/Spring-Cloud/Feign/?github) 对应 [labx-03](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-03) ## 服务容错 ---------- +* [《芋道 Spring Cloud Alibaba 服务容错 Sentinel 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Sentinel/?github) 对应 [labx-04](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-04) +* 《芋道 Spring Cloud Netflix 服务容错 Hystrix 入门》计划中... +* 《芋道 Spring Cloud 服务容错 Resilience4j 入门》计划中... -如下是草稿目录,未来需要整理下 +## API 网关 + +* [《芋道 Spring Cloud 服务网关 Spring Cloud Gateway 入门》](http://www.iocoder.cn/Spring-Cloud/Spring-Cloud-Gateway/?github) 对应 [labx-08](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-08) +* 《芋道 Spring Cloud Netflix 服务网关 Zuul 入门》计划中... +* [《性能测试 —— Spring Cloud Gateway、Zuul 基准测试》](http://www.iocoder.cn/Performance-Testing/SpringCloudGateway-Zuul-benchmark/?github) 对应 [lab-07](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-07) + +## 配置中心 + +* [《芋道 Spring Cloud Alibaba 配置中心 Nacos 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Nacos-Config/?github) 对应 [labx-05](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-05) +* [《芋道 Spring Cloud 配置中心 Apollo 入门》](http://www.iocoder.cn/Spring-Cloud/Apollo/?github) 对应 [labx-09](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-09) +* [《芋道 Spring Cloud 配置中心 Spring Cloud Config 入门》](http://www.iocoder.cn/Spring-Cloud/Spring-Cloud-Config/?github) 对应 [labx-12](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-12) + +## 消息队列 + +**Spring Cloud Stream** +* [《芋道 Spring Cloud Alibaba 消息队列 RocketMQ 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/RocketMQ/?github) 对应 [labx-06](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-06) +* [《芋道 Spring Cloud 消息队列 RabbitMQ 入门》](http://www.iocoder.cn/Spring-Cloud/RabbitMQ/?github) 对应 [labx-10](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-10) +* [《芋道 Spring Cloud 消息队列 Kafka 入门》](http://www.iocoder.cn/Spring-Cloud/Kafka/?github) 对应 [labx-11](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-11) +* [《芋道 Spring Cloud 消息队列 ActiveMQ 入门》](http://www.iocoder.cn/Spring-Cloud/ActiveMQ/?github) + +**Spring Cloud Bus** +* [《芋道 Spring Cloud Alibaba 事件总线 Bus RocketMQ 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Bus-RocketMQ/?github) 对应 [labx-20](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-20) +* [《芋道 Spring Cloud 事件总线 Bus RabbitMQ 入门》](http://www.iocoder.cn/Spring-Cloud/Bus-RabbitMQ/?github) 对应 [labx-19](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-19) +* [《芋道 Spring Cloud 事件总线 Bus Kafka 入门》](http://www.iocoder.cn/Spring-Cloud/Bus-Kafka/?github) 对应 [labx-18](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-18) + +## 分布式事务 + +* [《芋道 Spring Cloud Alibaba 分布式事务 Seata 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Seata/?github) 对应 [labx-17](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-17) + +## 监控管理 + +* [《芋道 Spring Boot 异常管理平台 Sentry 入门》](http://www.iocoder.cn/Spring-Boot/Sentry/?github) 对应 [lab-51](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-51) +* [《芋道 Spring Boot 监控端点 Actuator 入门》](http://www.iocoder.cn/Spring-Boot/Actuator/?github) 对应 [lab-34](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-34) +* [《芋道 Spring Cloud 监控工具 Admin 入门》](http://www.iocoder.cn/Spring-Cloud/SB-Admin/?github) 对应 [labx-15](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-15) +* [《芋道 Spring Boot 监控平台 Prometheus + Grafana 入门》](http://www.iocoder.cn/Spring-Boot/Prometheus-and-Grafana/?github) 对应 [lab-36](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-36) + +## 持续交付 + +* [《芋道 Spring Cloud 持续交付 Jenkins 入门》](http://www.iocoder.cn/Spring-Cloud/Jenkins/?github) 对应 [labx-16](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-16) +* [《芋道 Spring Boot 单元测试 Test 入门》](http://www.iocoder.cn/Spring-Boot/Unit-Test/?github) 对应 [lab-42](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-42) +* 《芋道 Spring Cloud 容器 Docker 入门》计划中... + +## 链路追踪 + +* [《芋道 Spring Cloud 链路追踪 SkyWalking 入门》](http://www.iocoder.cn/Spring-Cloud/SkyWalking/?github) 对应 [labx-14](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-14) +* [《芋道 Spring Cloud 链路追踪 Spring Cloud Sleuth》](http://www.iocoder.cn/Spring-Cloud/Spring-Cloud-Sleuth/?github) 对应 [labx-13](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-13) + +# Dubbo 专栏 + +## 基础入门 -# lab-05 +* [《芋道 Spring Boot Dubbo 入门》](http://www.iocoder.cn/Spring-Boot/Dubbo/?github) 对应 [lab-30](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-30) +* [《芋道 Spring Cloud Alibaba 服务调用 Dubbo 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Dubbo/?github) 对应 [labx-07](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-07) +* [《性能测试 —— Dubbo 基准测试》](http://www.iocoder.cn/Performance-Testing/Dubbo-benchmark/?github) + +## 注册中心 + +**[Zookeeper](http://www.iocoder.cn/Zookeeper/install/?github)** +* [《芋道 Spring Boot Dubbo 入门》](http://www.iocoder.cn/Spring-Boot/Dubbo/?github)的[「2. XML 配置」](#)和[「3. 注解配置」](#)小节 + +**[Nacos](http://www.iocoder.cn/Nacos/install/?github)** +* [《芋道 Spring Cloud Alibaba 服务调用 Dubbo 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Dubbo/?github)的[「2. 快速入门」](#)小节 + +## 服务保障 + +**[Sentinel](http://www.iocoder.cn/Sentinel/install/?github)** +* [《芋道 Spring Cloud Alibaba 服务调用 Dubbo 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Dubbo/?github)的[「6. 整合 Sentinel」](#)小节 + +## 分布式事务 + +**[Seata](http://www.iocoder.cn/Seata/install/?github)** +* [《芋道 Dubbo 分布式事务 Seata 入门》](http://www.iocoder.cn/Dubbo/Seata/?github) 对应 [lab-53](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-53) +* [《芋道 Spring Cloud Alibaba 分布式事务 Seata 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Seata/?github)的[「2. AT 模式 + Dubbo」](#)小节 + +## 链路追踪 + +**[SkyWalking](http://www.iocoder.cn/SkyWalking/install/?github)** +* [《芋道 Spring Boot 链路追踪 SkyWalking 入门》](http://www.iocoder.cn/Spring-Boot/SkyWalking/?github) 的[「16. Dubbo 示例」](#)小节 +* [《芋道 Spring Cloud 链路追踪 SkyWalking 入门》](http://www.iocoder.cn/Spring-Cloud/SkyWalking/?github) 的[「7. Dubbo 示例」](#)小节 + +**[Zipkin](http://www.iocoder.cn/Zipkin/install/?github)** +* [《芋道 Spring Boot 链路追踪 Zipkin》](http://www.iocoder.cn/Spring-Cloud/Spring-Cloud-Sleuth/?github) 的[「13. Dubbo 示例」](#)小节 +* [《芋道 Spring Cloud 链路追踪 Spring Cloud Sleuth》](http://www.iocoder.cn/Spring-Cloud/Spring-Cloud-Sleuth/?github) 的[「7. Dubbo 示例」](#)小节 + +# 消息队列 MQ 专栏 + +## RocketMQ + +* [《RocketMQ 安装部署》](http://www.iocoder.cn/RocketMQ/install/?github) +* [《芋道 Spring Boot 消息队列 RocketMQ 入门》](http://www.iocoder.cn/Spring-Boot/RocketMQ/?github) 对应 [lab-31](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-31) +* [《芋道 Spring Cloud Alibaba 消息队列 RocketMQ 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/RocketMQ/?github) 对应 [labx-06](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-06) +* [《芋道 Spring Cloud Alibaba 事件总线 Bus RocketMQ 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Bus-RocketMQ/?github) 对应 [labx-20](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-20) +* [《芋道 RocketMQ 源码解析系列》](http://www.iocoder.cn/categories/RocketMQ/?github) +* [《性能测试 —— RocketMQ 基准测试》](http://www.iocoder.cn/Performance-Testing/RocketMQ-benchmark/?github) +* [《RocketMQ 书单整理》](http://www.iocoder.cn/Books/RocketMQ-books-recommended/?github) + +## RabbitMQ + +* [《RabbitMQ 安装部署》](http://www.iocoder.cn/RabbitMQ/install/?github) +* [《芋道 Spring Boot 消息队列 RabbitMQ 入门》](http://www.iocoder.cn/Spring-Boot/RabbitMQ/?github) 对应 [lab-04](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-04) +* [《芋道 Spring Cloud 消息队列 RabbitMQ 入门》](http://www.iocoder.cn/Spring-Cloud/RabbitMQ/?github) 对应 [labx-10](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-10) +* [《芋道 Spring Cloud 事件总线 Bus RabbitMQ 入门》](http://www.iocoder.cn/Spring-Cloud/Bus-RabbitMQ/?github) 对应 [labx-19](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-19) +* [《RabbitMQ 书单整理》](http://www.iocoder.cn/Books/RabbitMQ-books-recommended/?github) + +## Kafka -TODO +* [《Kafka 安装部署》](http://www.iocoder.cn/Kafka/install/?github) +* [《芋道 Spring Boot 消息队列 Kafka 入门》](http://www.iocoder.cn/Spring-Boot/Kafka/?github) 对应 [lab-03](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-03) +* [《芋道 Spring Cloud 消息队列 Kafka 入门》](http://www.iocoder.cn/Spring-Cloud/Kafka/?github) 对应 [labx-11](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-11) +* [《芋道 Spring Cloud 事件总线 Bus Kafka 入门》](http://www.iocoder.cn/Spring-Cloud/Bus-Kafka/?github) 对应 [labx-18](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-18) +* [《Kafka 书单整理》](http://www.iocoder.cn/Books/Kafka-books-recommended/?github) + +## ActiveMQ + +* [《ActiveMQ 安装部署》](http://www.iocoder.cn/ActiveMQ/install/?github) +* [《芋道 Spring Boot 消息队列 ActiveMQ 入门》](http://www.iocoder.cn/Spring-Boot/ActiveMQ/?github) 对应 [lab-32](https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-32) +* [《芋道 Spring Cloud 消息队列 ActiveMQ 入门》](http://www.iocoder.cn/Spring-Cloud/ActiveMQ/?github) + +# 分布式事务专栏 + +目前分布式事务的解决方案有 AT、TCC、Saga、MQ、XA、BED 六种。 + +## AT 方案 + +* [《芋道 Spring Boot 分布式事务 Seata 入门》](http://www.iocoder.cn/Spring-Boot/Seata/?github)的[「2. AT 模式 + 多数据源」](#)小节,实现单体 Spring Boot 项目在多数据源下的分布式事务 +* [《芋道 Spring Boot 分布式事务 Seata 入门》](http://www.iocoder.cn/Spring-Boot/Seata/?github)的[「AT 模式 + HttpClient 远程调用」](#)小节,实现多个 Spring Boot 项目的分布式事务 +* [《芋道 Dubbo 分布式事务 Seata 入门》](http://www.iocoder.cn/Dubbo/Seata/?github) 的[「2. AT 模式」](#)小节,实现多个 Dubbo 服务的分布式事务。 +* [《芋道 Spring Cloud Alibaba 分布式事务 Seata 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/Seata/?github)的[「3. AT 模式 + Feign」](#)小节,实现多个 Spring Cloud 服务下的分布式事务。 + +## TCC 方案 + +* [《TCC-Transaction 源码解析系列》](http://www.iocoder.cn/categories/TCC-Transaction/?github) + +## Saga 方案 -WEB 容器,后续优化掉 +## MQ 方案 + +* [《芋道 Spring Boot 消息队列 RocketMQ 入门》](http://www.iocoder.cn/Spring-Boot/RocketMQ/?github) 的[「9. 事务消息」](#)小节 +* [《芋道 Spring Cloud Alibaba 消息队列 RocketMQ 入门》](http://www.iocoder.cn/Spring-Cloud-Alibaba/RocketMQ/?github) 的[「10. 事务消息」](#)小节 +* [《RocketMQ 源码分析 —— 事务消息》](http://www.iocoder.cn/RocketMQ/message-transaction/?github) + +## XA 方案 + +* [《MyCAT 源码分析 —— XA分布式事务》](http://www.iocoder.cn/MyCAT/xa-distributed-transaction/?github) + +## BED 方案 + +* [《Sharding-JDBC 源码分析 —— 分布式事务(一)之最大努力型》](http://www.iocoder.cn/Sharding-JDBC/transaction-bed/?github) + +--------- + +如下是草稿目录,未来需要整理下 # lab-08 @@ -172,3 +344,6 @@ WEB 容器,后续优化掉 Spring Boot 优雅关闭示例。 +# lab-50 + +Email 示例 diff --git "a/lab-01/\343\200\212\350\212\213\351\201\223 Spring Boot \345\256\211\345\205\250\346\241\206\346\236\266 Spring Security \345\205\245\351\227\250\343\200\213.md" "b/lab-01/\343\200\212\350\212\213\351\201\223 Spring Boot \345\256\211\345\205\250\346\241\206\346\236\266 Spring Security \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..3fa673793 --- /dev/null +++ "b/lab-01/\343\200\212\350\212\213\351\201\223 Spring Boot \345\256\211\345\205\250\346\241\206\346\236\266 Spring Security \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-02/README.md b/lab-02/README.md deleted file mode 100644 index 243a11080..000000000 --- a/lab-02/README.md +++ /dev/null @@ -1 +0,0 @@ -oauth2 的集成 \ No newline at end of file diff --git "a/lab-02/\343\200\212\350\212\213\351\201\223 Spring Security OAuth2 \345\205\245\351\227\250\343\200\213.md" "b/lab-02/\343\200\212\350\212\213\351\201\223 Spring Security OAuth2 \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..3c12e4c7b --- /dev/null +++ "b/lab-02/\343\200\212\350\212\213\351\201\223 Spring Security OAuth2 \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-03/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 Kafka \345\205\245\351\227\250\343\200\213.md" "b/lab-03/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 Kafka \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..500c2d942 --- /dev/null +++ "b/lab-03/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 Kafka \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-04/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 RabbitMQ \345\205\245\351\227\250\343\200\213.md" "b/lab-04/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 RabbitMQ \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..756bcbc22 --- /dev/null +++ "b/lab-04/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 RabbitMQ \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-05/\343\200\212\346\200\247\350\203\275\346\265\213\350\257\225 \342\200\224\342\200\224 Tomcat\343\200\201Jetty\343\200\201Undertow \345\237\272\345\207\206\346\265\213\350\257\225\343\200\213.md" "b/lab-05/\343\200\212\346\200\247\350\203\275\346\265\213\350\257\225 \342\200\224\342\200\224 Tomcat\343\200\201Jetty\343\200\201Undertow \345\237\272\345\207\206\346\265\213\350\257\225\343\200\213.md" new file mode 100644 index 000000000..222a02c2b --- /dev/null +++ "b/lab-05/\343\200\212\346\200\247\350\203\275\346\265\213\350\257\225 \342\200\224\342\200\224 Tomcat\343\200\201Jetty\343\200\201Undertow \345\237\272\345\207\206\346\265\213\350\257\225\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-06/\343\200\212\346\200\247\350\203\275\346\265\213\350\257\225 \342\200\224\342\200\224 SpringMVC\343\200\201Webflux \345\237\272\345\207\206\346\265\213\350\257\225\343\200\213.md" "b/lab-06/\343\200\212\346\200\247\350\203\275\346\265\213\350\257\225 \342\200\224\342\200\224 SpringMVC\343\200\201Webflux \345\237\272\345\207\206\346\265\213\350\257\225\343\200\213.md" new file mode 100644 index 000000000..7a97811ba --- /dev/null +++ "b/lab-06/\343\200\212\346\200\247\350\203\275\346\265\213\350\257\225 \342\200\224\342\200\224 SpringMVC\343\200\201Webflux \345\237\272\345\207\206\346\265\213\350\257\225\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-07/\343\200\212\346\200\247\350\203\275\346\265\213\350\257\225 \342\200\224\342\200\224 Spring Cloud Gateway\343\200\201Zuul \345\237\272\345\207\206\346\265\213\350\257\225\343\200\213.md" "b/lab-07/\343\200\212\346\200\247\350\203\275\346\265\213\350\257\225 \342\200\224\342\200\224 Spring Cloud Gateway\343\200\201Zuul \345\237\272\345\207\206\346\265\213\350\257\225\343\200\213.md" new file mode 100644 index 000000000..7a97811ba --- /dev/null +++ "b/lab-07/\343\200\212\346\200\247\350\203\275\346\265\213\350\257\225 \342\200\224\342\200\224 Spring Cloud Gateway\343\200\201Zuul \345\237\272\345\207\206\346\265\213\350\257\225\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-08/\345\207\206\345\244\207\345\210\240\351\231\244" "b/lab-08/\345\207\206\345\244\207\345\210\240\351\231\244" new file mode 100644 index 000000000..e69de29bb diff --git "a/lab-09/\345\207\206\345\244\207\345\210\240\351\231\244" "b/lab-09/\345\207\206\345\244\207\345\210\240\351\231\244" new file mode 100644 index 000000000..e69de29bb diff --git "a/lab-10/\345\207\206\345\244\207\345\210\240\351\231\244" "b/lab-10/\345\207\206\345\244\207\345\210\240\351\231\244" new file mode 100644 index 000000000..e69de29bb diff --git "a/lab-11/\343\200\212\350\212\213\351\201\223 Spring Boot Redis \345\205\245\351\227\250\343\200\213.md" "b/lab-11/\343\200\212\350\212\213\351\201\223 Spring Boot Redis \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..b39e7daa3 --- /dev/null +++ "b/lab-11/\343\200\212\350\212\213\351\201\223 Spring Boot Redis \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-12/\343\200\212\350\212\213\351\201\223 Spring Boot MyBatis \345\205\245\351\227\250\343\200\213.md" "b/lab-12/\343\200\212\350\212\213\351\201\223 Spring Boot MyBatis \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..c592d7cd5 --- /dev/null +++ "b/lab-12/\343\200\212\350\212\213\351\201\223 Spring Boot MyBatis \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-13/\343\200\212\350\212\213\351\201\223 Spring Boot JPA \345\205\245\351\227\250\343\200\213.md" "b/lab-13/\343\200\212\350\212\213\351\201\223 Spring Boot JPA \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..99a2fab35 --- /dev/null +++ "b/lab-13/\343\200\212\350\212\213\351\201\223 Spring Boot JPA \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-14/\343\200\212\350\212\213\351\201\223 Spring Boot JdbcTemplate \345\205\245\351\227\250\343\200\213.md" "b/lab-14/\343\200\212\350\212\213\351\201\223 Spring Boot JdbcTemplate \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..ce76be1bc --- /dev/null +++ "b/lab-14/\343\200\212\350\212\213\351\201\223 Spring Boot JdbcTemplate \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-15/\343\200\212\350\212\213\351\201\223 Spring Boot Elasticsearch \345\205\245\351\227\250\343\200\213.md" "b/lab-15/\343\200\212\350\212\213\351\201\223 Spring Boot Elasticsearch \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..6ae85f4f3 --- /dev/null +++ "b/lab-15/\343\200\212\350\212\213\351\201\223 Spring Boot Elasticsearch \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-16/\343\200\212\350\212\213\351\201\223 Spring Boot MongoDB \345\205\245\351\227\250\343\200\213.md" "b/lab-16/\343\200\212\350\212\213\351\201\223 Spring Boot MongoDB \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..c678d864f --- /dev/null +++ "b/lab-16/\343\200\212\350\212\213\351\201\223 Spring Boot MongoDB \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-17/\343\200\212\350\212\213\351\201\223 Spring Boot \345\244\232\346\225\260\346\215\256\346\272\220\357\274\210\350\257\273\345\206\231\345\210\206\347\246\273\357\274\211\345\205\245\351\227\250\343\200\213.md" "b/lab-17/\343\200\212\350\212\213\351\201\223 Spring Boot \345\244\232\346\225\260\346\215\256\346\272\220\357\274\210\350\257\273\345\206\231\345\210\206\347\246\273\357\274\211\345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..548c9027a --- /dev/null +++ "b/lab-17/\343\200\212\350\212\213\351\201\223 Spring Boot \345\244\232\346\225\260\346\215\256\346\272\220\357\274\210\350\257\273\345\206\231\345\210\206\347\246\273\357\274\211\345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-18/\343\200\212\350\212\213\351\201\223 Spring Boot \345\210\206\345\272\223\345\210\206\350\241\250\345\205\245\351\227\250\343\200\213.md" "b/lab-18/\343\200\212\350\212\213\351\201\223 Spring Boot \345\210\206\345\272\223\345\210\206\350\241\250\345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..e6f9c0bb0 --- /dev/null +++ "b/lab-18/\343\200\212\350\212\213\351\201\223 Spring Boot \345\210\206\345\272\223\345\210\206\350\241\250\345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-19/\343\200\212\350\212\213\351\201\223 Spring Boot \346\225\260\346\215\256\345\272\223\350\277\236\346\216\245\346\261\240\345\205\245\351\227\250\343\200\213.md" "b/lab-19/\343\200\212\350\212\213\351\201\223 Spring Boot \346\225\260\346\215\256\345\272\223\350\277\236\346\216\245\346\261\240\345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..6d5d05d2e --- /dev/null +++ "b/lab-19/\343\200\212\350\212\213\351\201\223 Spring Boot \346\225\260\346\215\256\345\272\223\350\277\236\346\216\245\346\261\240\345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-20/\343\200\212\350\212\213\351\201\223 Spring Boot \346\225\260\346\215\256\345\272\223\347\211\210\346\234\254\347\256\241\347\220\206\345\205\245\351\227\250\343\200\213.md" "b/lab-20/\343\200\212\350\212\213\351\201\223 Spring Boot \346\225\260\346\215\256\345\272\223\347\211\210\346\234\254\347\256\241\347\220\206\345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..abdb1ee32 --- /dev/null +++ "b/lab-20/\343\200\212\350\212\213\351\201\223 Spring Boot \346\225\260\346\215\256\345\272\223\347\211\210\346\234\254\347\256\241\347\220\206\345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-21/\343\200\212\350\212\213\351\201\223 Spring Boot \347\274\223\345\255\230 Cache \345\205\245\351\227\250\343\200\213.md" "b/lab-21/\343\200\212\350\212\213\351\201\223 Spring Boot \347\274\223\345\255\230 Cache \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..866b8b6fc --- /dev/null +++ "b/lab-21/\343\200\212\350\212\213\351\201\223 Spring Boot \347\274\223\345\255\230 Cache \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-22/\343\200\212\350\212\213\351\201\223 Spring Boot \345\217\202\346\225\260\346\240\241\351\252\214 Validation \345\205\245\351\227\250\343\200\213.md" "b/lab-22/\343\200\212\350\212\213\351\201\223 Spring Boot \345\217\202\346\225\260\346\240\241\351\252\214 Validation \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..6692323e4 --- /dev/null +++ "b/lab-22/\343\200\212\350\212\213\351\201\223 Spring Boot \345\217\202\346\225\260\346\240\241\351\252\214 Validation \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-23/\343\200\212\350\212\213\351\201\223 Spring Boot SpringMVC \345\205\245\351\227\250\343\200\213.md" "b/lab-23/\343\200\212\350\212\213\351\201\223 Spring Boot SpringMVC \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..50154ce03 --- /dev/null +++ "b/lab-23/\343\200\212\350\212\213\351\201\223 Spring Boot SpringMVC \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-24/\343\200\212\350\212\213\351\201\223 Spring Boot API \346\216\245\345\217\243\346\226\207\346\241\243 Swagger \345\205\245\351\227\250\343\200\213.md" "b/lab-24/\343\200\212\350\212\213\351\201\223 Spring Boot API \346\216\245\345\217\243\346\226\207\346\241\243 Swagger \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..56f34bbaa --- /dev/null +++ "b/lab-24/\343\200\212\350\212\213\351\201\223 Spring Boot API \346\216\245\345\217\243\346\226\207\346\241\243 Swagger \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-25/\343\200\212\350\212\213\351\201\223 Spring Boot WebSocket \345\205\245\351\227\250\343\200\213.md" "b/lab-25/\343\200\212\350\212\213\351\201\223 Spring Boot WebSocket \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..0e95f5371 --- /dev/null +++ "b/lab-25/\343\200\212\350\212\213\351\201\223 Spring Boot WebSocket \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-26/\343\200\212\350\212\213\351\201\223 Spring Boot \345\210\206\345\270\203\345\274\217 Session \345\205\245\351\227\250\343\200\213.md" "b/lab-26/\343\200\212\350\212\213\351\201\223 Spring Boot \345\210\206\345\270\203\345\274\217 Session \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..80ff990ed --- /dev/null +++ "b/lab-26/\343\200\212\350\212\213\351\201\223 Spring Boot \345\210\206\345\270\203\345\274\217 Session \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-27/\343\200\212\350\212\213\351\201\223 Spring Boot \345\223\215\345\272\224\345\274\217 WebFlux \345\205\245\351\227\250\343\200\213.md" "b/lab-27/\343\200\212\350\212\213\351\201\223 Spring Boot \345\223\215\345\272\224\345\274\217 WebFlux \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..80cfc4fa6 --- /dev/null +++ "b/lab-27/\343\200\212\350\212\213\351\201\223 Spring Boot \345\223\215\345\272\224\345\274\217 WebFlux \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-28/\343\200\212\350\212\213\351\201\223 Spring Boot \345\256\232\346\227\266\344\273\273\345\212\241\345\205\245\351\227\250\343\200\213.md" "b/lab-28/\343\200\212\350\212\213\351\201\223 Spring Boot \345\256\232\346\227\266\344\273\273\345\212\241\345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..6e36138fc --- /dev/null +++ "b/lab-28/\343\200\212\350\212\213\351\201\223 Spring Boot \345\256\232\346\227\266\344\273\273\345\212\241\345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-29/\343\200\212\350\212\213\351\201\223 Spring Boot \345\274\202\346\255\245\344\273\273\345\212\241\345\205\245\351\227\250\343\200\213.md" "b/lab-29/\343\200\212\350\212\213\351\201\223 Spring Boot \345\274\202\346\255\245\344\273\273\345\212\241\345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..71bf9a5fd --- /dev/null +++ "b/lab-29/\343\200\212\350\212\213\351\201\223 Spring Boot \345\274\202\346\255\245\344\273\273\345\212\241\345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-30/lab-30-dubbo-annotations-demo/user-rpc-service-provider-02/src/main/resources/application.yaml b/lab-30/lab-30-dubbo-annotations-demo/user-rpc-service-provider-02/src/main/resources/application.yaml index aa61f2aa0..58798bdb5 100644 --- a/lab-30/lab-30-dubbo-annotations-demo/user-rpc-service-provider-02/src/main/resources/application.yaml +++ b/lab-30/lab-30-dubbo-annotations-demo/user-rpc-service-provider-02/src/main/resources/application.yaml @@ -14,7 +14,7 @@ dubbo: provider: timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒,胖友可以根据自己业务修改 UserRpcService: - version: 1.0. + version: 1.0.0 # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 scan: base-packages: cn.iocoder.springboot.lab30.rpc.service diff --git "a/lab-30/\343\200\212\350\212\213\351\201\223 Spring Boot Dubbo \345\205\245\351\227\250\343\200\213.md" "b/lab-30/\343\200\212\350\212\213\351\201\223 Spring Boot Dubbo \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..25a9080b0 --- /dev/null +++ "b/lab-30/\343\200\212\350\212\213\351\201\223 Spring Boot Dubbo \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-31/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 RocketMQ \345\205\245\351\227\250\343\200\213.md" "b/lab-31/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 RocketMQ \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..84d492a8a --- /dev/null +++ "b/lab-31/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 RocketMQ \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-32/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 ActiveMQ \345\205\245\351\227\250\343\200\213.md" "b/lab-32/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 ActiveMQ \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..6f1a25d3b --- /dev/null +++ "b/lab-32/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\346\201\257\351\230\237\345\210\227 ActiveMQ \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-33/\343\200\212\350\212\213\351\201\223 Spring Boot \345\256\211\345\205\250\346\241\206\346\236\266 Shiro \345\205\245\351\227\250\343\200\213.md" "b/lab-33/\343\200\212\350\212\213\351\201\223 Spring Boot \345\256\211\345\205\250\346\241\206\346\236\266 Shiro \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..389408927 --- /dev/null +++ "b/lab-33/\343\200\212\350\212\213\351\201\223 Spring Boot \345\256\211\345\205\250\346\241\206\346\236\266 Shiro \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-34/lab-34-actuator-demo-info/pom.xml b/lab-34/lab-34-actuator-demo-info/pom.xml index a5834d778..7583d9d9d 100644 --- a/lab-34/lab-34-actuator-demo-info/pom.xml +++ b/lab-34/lab-34-actuator-demo-info/pom.xml @@ -10,7 +10,7 @@ 4.0.0 - lab-34-acturator-demo-info + lab-34-actuator-demo-info diff --git a/lab-34/lab-34-actuator-demo/pom.xml b/lab-34/lab-34-actuator-demo/pom.xml index 887ee24a5..5fa9fe2d1 100644 --- a/lab-34/lab-34-actuator-demo/pom.xml +++ b/lab-34/lab-34-actuator-demo/pom.xml @@ -10,7 +10,7 @@ 4.0.0 - lab-34-acturator-demo + lab-34-actuator-demo diff --git a/lab-34/lab-34-actuator-test/pom.xml b/lab-34/lab-34-actuator-test/pom.xml index 84f2b53fd..0b87ad69a 100644 --- a/lab-34/lab-34-actuator-test/pom.xml +++ b/lab-34/lab-34-actuator-test/pom.xml @@ -10,7 +10,7 @@ 4.0.0 - lab-34-acturator-test + lab-34-actuator-test diff --git "a/lab-34/\343\200\212\350\212\213\351\201\223 Spring Boot \347\233\221\346\216\247\347\253\257\347\202\271 Actuator \345\205\245\351\227\250\343\200\213.md" "b/lab-34/\343\200\212\350\212\213\351\201\223 Spring Boot \347\233\221\346\216\247\347\253\257\347\202\271 Actuator \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..f2b17e4d6 --- /dev/null +++ "b/lab-34/\343\200\212\350\212\213\351\201\223 Spring Boot \347\233\221\346\216\247\347\253\257\347\202\271 Actuator \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-35/\343\200\212\350\212\213\351\201\223 Spring Boot \347\233\221\346\216\247\345\267\245\345\205\267 Admin \345\205\245\351\227\250\343\200\213.md" "b/lab-35/\343\200\212\350\212\213\351\201\223 Spring Boot \347\233\221\346\216\247\345\267\245\345\205\267 Admin \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..e742842df --- /dev/null +++ "b/lab-35/\343\200\212\350\212\213\351\201\223 Spring Boot \347\233\221\346\216\247\345\267\245\345\205\267 Admin \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-36/\343\200\212\350\212\213\351\201\223 Spring Boot \347\233\221\346\216\247\345\271\263\345\217\260 Prometheus + Grafana \345\205\245\351\227\250\343\200\213.md" "b/lab-36/\343\200\212\350\212\213\351\201\223 Spring Boot \347\233\221\346\216\247\345\271\263\345\217\260 Prometheus + Grafana \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..e69de29bb diff --git "a/lab-37/\343\200\212\350\212\213\351\201\223 Spring Boot \346\227\245\345\277\227\351\233\206\346\210\220 Logging \345\205\245\351\227\250\343\200\213.md" "b/lab-37/\343\200\212\350\212\213\351\201\223 Spring Boot \346\227\245\345\277\227\351\233\206\346\210\220 Logging \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..fa4d42971 --- /dev/null +++ "b/lab-37/\343\200\212\350\212\213\351\201\223 Spring Boot \346\227\245\345\277\227\351\233\206\346\210\220 Logging \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-38/\343\200\212\350\212\213\351\201\223 Spring Boot \346\227\245\345\277\227\345\271\263\345\217\260 ELK + Filebeat \345\205\245\351\227\250\343\200\213.md" "b/lab-38/\343\200\212\350\212\213\351\201\223 Spring Boot \346\227\245\345\277\227\345\271\263\345\217\260 ELK + Filebeat \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..6a17cd373 --- /dev/null +++ "b/lab-38/\343\200\212\350\212\213\351\201\223 Spring Boot \346\227\245\345\277\227\345\271\263\345\217\260 ELK + Filebeat \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-api/pom.xml b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-api/pom.xml new file mode 100644 index 000000000..5986c6599 --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-api/pom.xml @@ -0,0 +1,15 @@ + + + + lab-39-skywalking-dubbo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-39-skywalking-dubbo-api + + + diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-api/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/api/UserService.java b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-api/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/api/UserService.java new file mode 100644 index 000000000..dcecdcc1e --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-api/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/api/UserService.java @@ -0,0 +1,16 @@ +package cn.iocoder.springboot.lab39.skywalkingdemo.api; + +/** + * 用户服务 RPC Service 接口 + */ +public interface UserService { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + String get(Integer id); + +} diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-api/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/package-info.java b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-api/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/package-info.java new file mode 100644 index 000000000..7f0cd7c61 --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-api/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.springcloud.labx13; diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/pom.xml b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/pom.xml new file mode 100644 index 000000000..83c80b308 --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/pom.xml @@ -0,0 +1,54 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-39-skywalking-dubbo-consumer + + + + + cn.iocoder.springboot.labs + lab-39-skywalking-dubbo-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.apache.dubbo + dubbo + 2.7.4.1 + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.4.1 + + + + + org.apache.curator + curator-framework + 2.13.0 + + + org.apache.curator + curator-recipes + 2.13.0 + + + + diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/consumerdemo/ConsumerApplication.java b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..b66555a84 --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab39.skywalkingdemo.consumerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class); + } + +} diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/consumerdemo/controller/UserController.java b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/consumerdemo/controller/UserController.java new file mode 100644 index 000000000..b36e2ffe4 --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/consumerdemo/controller/UserController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springboot.lab39.skywalkingdemo.consumerdemo.controller; + +import cn.iocoder.springboot.lab39.skywalkingdemo.api.UserService; +import org.apache.dubbo.config.annotation.Reference; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Reference(protocol = "dubbo", version = "1.0.0") + private UserService userService; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + return userService.get(id); + } + +} diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/src/main/resources/application.yaml b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..07a16aa67 --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-consumer/src/main/resources/application.yaml @@ -0,0 +1,15 @@ +server: + port: 8079 + +spring: + application: + name: user-service-consumer + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 应用配置 + application: + name: ${spring.application.name} # 应用名 + # Dubbo 注册中心配置 + registry: + address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。 diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/pom.xml b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/pom.xml new file mode 100644 index 000000000..ec8e7928d --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/pom.xml @@ -0,0 +1,54 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-39-skywalking-dubbo-provider + + + + + cn.iocoder.springboot.labs + lab-39-skywalking-dubbo-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter + + + + + org.apache.dubbo + dubbo + 2.7.4.1 + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.4.1 + + + + + org.apache.curator + curator-framework + 2.13.0 + + + org.apache.curator + curator-recipes + 2.13.0 + + + + diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/providerdemo/ProviderApplication.java b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/providerdemo/ProviderApplication.java new file mode 100644 index 000000000..20f56e251 --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/providerdemo/ProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab39.skywalkingdemo.providerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(ProviderApplication.class); + } + +} diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/providerdemo/service/UserServiceImpl.java b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/providerdemo/service/UserServiceImpl.java new file mode 100644 index 000000000..ff0847cc8 --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/src/main/java/cn/iocoder/springboot/lab39/skywalkingdemo/providerdemo/service/UserServiceImpl.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab39.skywalkingdemo.providerdemo.service; + +import cn.iocoder.springboot.lab39.skywalkingdemo.api.UserService; + +@org.apache.dubbo.config.annotation.Service(version = "1.0.0") +public class UserServiceImpl implements UserService { + + @Override + public String get(Integer id) { + return "user:" + id; + } + +} diff --git a/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/src/main/resources/application.yaml b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..658ca0b4d --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/lab-39-skywalking-dubbo-provider/src/main/resources/application.yaml @@ -0,0 +1,19 @@ +spring: + application: + name: user-service-provider + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 应用配置 + application: + name: ${spring.application.name} # 应用名 + # Dubbo 注册中心配 + registry: + address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springboot.lab39.skywalkingdemo.providerdemo.service diff --git a/lab-39/lab-39-skywalking-dubbo/pom.xml b/lab-39/lab-39-skywalking-dubbo/pom.xml new file mode 100644 index 000000000..3d3383810 --- /dev/null +++ b/lab-39/lab-39-skywalking-dubbo/pom.xml @@ -0,0 +1,21 @@ + + + + lab-39 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-39-skywalking-dubbo + pom + + + lab-39-skywalking-dubbo-api + lab-39-skywalking-dubbo-provider + lab-39-skywalking-dubbo-consumer + + + diff --git a/lab-39/pom.xml b/lab-39/pom.xml index 2ee5e63e9..6bc0c89a8 100644 --- a/lab-39/pom.xml +++ b/lab-39/pom.xml @@ -27,6 +27,7 @@ lab-39-trace-annotations lab-39-opentracing lab-39-async + lab-39-skywalking-dubbo diff --git "a/lab-39/\343\200\212\350\212\213\351\201\223 Spring Boot \351\223\276\350\267\257\350\277\275\350\270\252 SkyWalking \345\205\245\351\227\250\343\200\213.md" "b/lab-39/\343\200\212\350\212\213\351\201\223 Spring Boot \351\223\276\350\267\257\350\277\275\350\270\252 SkyWalking \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..1d3d3713e --- /dev/null +++ "b/lab-39/\343\200\212\350\212\213\351\201\223 Spring Boot \351\223\276\350\267\257\350\277\275\350\270\252 SkyWalking \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-api/pom.xml b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-api/pom.xml new file mode 100644 index 000000000..634240f6e --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-api/pom.xml @@ -0,0 +1,15 @@ + + + + lab-40-zipkin-dubbo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-40-zipkin-dubbo-api + + + diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-api/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/api/UserService.java b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-api/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/api/UserService.java new file mode 100644 index 000000000..8dd1df339 --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-api/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/api/UserService.java @@ -0,0 +1,16 @@ +package cn.iocoder.springboot.lab40.zipkindemo.api; + +/** + * 用户服务 RPC Service 接口 + */ +public interface UserService { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + String get(Integer id); + +} diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-api/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/package-info.java b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-api/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/package-info.java new file mode 100644 index 000000000..7f0cd7c61 --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-api/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.springcloud.labx13; diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/pom.xml b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/pom.xml new file mode 100644 index 000000000..df663f00a --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/pom.xml @@ -0,0 +1,92 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-40-zipkin-dubbo-consumer + + + + + cn.iocoder.springboot.labs + lab-40-zipkin-dubbo-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.apache.dubbo + dubbo + 2.7.4.1 + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.4.1 + + + + + org.apache.curator + curator-framework + 2.13.0 + + + org.apache.curator + curator-recipes + 2.13.0 + + + + + + io.zipkin.brave + brave + + + io.zipkin.reporter2 + zipkin-sender-okhttp3 + + + + + + io.zipkin.brave + brave-instrumentation-spring-webmvc + + + + + io.zipkin.brave + brave-instrumentation-dubbo + 5.10.1 + + + + + + + + io.zipkin.brave + brave-bom + 5.9.1 + pom + import + + + + + diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/ConsumerApplication.java b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..a16fcee8f --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab40.zpkindemo.consumerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class); + } + +} diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/config/SpringMvcConfiguration.java b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/config/SpringMvcConfiguration.java new file mode 100644 index 000000000..304a394f4 --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/config/SpringMvcConfiguration.java @@ -0,0 +1,25 @@ +package cn.iocoder.springboot.lab40.zpkindemo.consumerdemo.config; + +import brave.spring.webmvc.SpanCustomizingAsyncHandlerInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@Import(SpanCustomizingAsyncHandlerInterceptor.class) +public class SpringMvcConfiguration implements WebMvcConfigurer { + + @Autowired + public SpanCustomizingAsyncHandlerInterceptor webMvcTracingCustomizer; + + /** + * Decorates server spans with application-defined web tags + */ + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(webMvcTracingCustomizer); + } + +} diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/config/ZipkinConfiguration.java b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/config/ZipkinConfiguration.java new file mode 100644 index 000000000..29903e32a --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/config/ZipkinConfiguration.java @@ -0,0 +1,84 @@ +package cn.iocoder.springboot.lab40.zpkindemo.consumerdemo.config; + +import brave.CurrentSpanCustomizer; +import brave.SpanCustomizer; +import brave.Tracing; +import brave.http.HttpTracing; +import brave.servlet.TracingFilter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import zipkin2.Span; +import zipkin2.reporter.AsyncReporter; +import zipkin2.reporter.Sender; +import zipkin2.reporter.okhttp3.OkHttpSender; + +import javax.servlet.Filter; + +@Configuration +public class ZipkinConfiguration { + + // ==================== 通用配置 ==================== + + /** + * Configuration for how to send spans to Zipkin + */ + @Bean + public Sender sender() { + return OkHttpSender.create("http://127.0.0.1:9411/api/v2/spans"); + } + + /** + * Configuration for how to buffer spans into messages for Zipkin + */ + @Bean + public AsyncReporter spanReporter() { + return AsyncReporter.create(sender()); + } + + /** + * Controls aspects of tracing such as the service name that shows up in the UI + */ + @Bean + public Tracing tracing(@Value("${spring.application.name}") String serviceName) { + return Tracing.newBuilder() + .localServiceName(serviceName) +// .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder() +// .addScopeDecorator(MDCScopeDecorator.create()) // puts trace IDs into logs +// .build() +// ) + .spanReporter(spanReporter()).build(); + } + + /** + * Allows someone to add tags to a span if a trace is in progress + */ + @Bean + public SpanCustomizer spanCustomizer(Tracing tracing) { + return CurrentSpanCustomizer.create(tracing); + } + + // ==================== HTTP 相关 ==================== + + /** + * Decides how to name and tag spans. By default they are named the same as the http method + */ + @Bean + public HttpTracing httpTracing(Tracing tracing) { + return HttpTracing.create(tracing); + } + + /** + * Creates server spans for http requests + */ + @Bean + public Filter tracingFilter(HttpTracing httpTracing) { + return TracingFilter.create(httpTracing); + } + + // ==================== SpringMVC 相关 ==================== + // @see SpringMvcConfiguration 类上的,@Import(SpanCustomizingAsyncHandlerInterceptor.class) + + + +} diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/controller/UserController.java b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/controller/UserController.java new file mode 100644 index 000000000..38711e656 --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/java/cn/iocoder/springboot/lab40/zpkindemo/consumerdemo/controller/UserController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springboot.lab40.zpkindemo.consumerdemo.controller; + +import cn.iocoder.springboot.lab40.zipkindemo.api.UserService; +import org.apache.dubbo.config.annotation.Reference; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Reference(protocol = "dubbo", version = "1.0.0") + private UserService userService; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + return userService.get(id); + } + +} diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/resources/application.yaml b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..ef960b5f9 --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-consumer/src/main/resources/application.yaml @@ -0,0 +1,15 @@ +spring: + application: + name: user-service-consumer + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 应用配置 + application: + name: ${spring.application.name} # 应用名 + # Dubbo 注册中心配置 + registry: + address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。 + # Dubbo 服务提供者的配置,对应 ConsumerConfig 类 + consumer: + filter: tracing diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/pom.xml b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/pom.xml new file mode 100644 index 000000000..c818e1087 --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/pom.xml @@ -0,0 +1,85 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-40-zipkin-dubbo-provider + + + + + cn.iocoder.springboot.labs + lab-40-zipkin-dubbo-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter + + + + + org.apache.dubbo + dubbo + 2.7.4.1 + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.4.1 + + + + + org.apache.curator + curator-framework + 2.13.0 + + + org.apache.curator + curator-recipes + 2.13.0 + + + + + + io.zipkin.brave + brave + + + io.zipkin.reporter2 + zipkin-sender-okhttp3 + + + + + io.zipkin.brave + brave-instrumentation-dubbo + 5.10.1 + + + + + + + + io.zipkin.brave + brave-bom + 5.9.1 + pom + import + + + + + diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/providerdemo/ProviderApplication.java b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/providerdemo/ProviderApplication.java new file mode 100644 index 000000000..4768a9978 --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/providerdemo/ProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab40.zipkindemo.providerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(ProviderApplication.class); + } + +} diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/providerdemo/config/ZipkinConfiguration.java b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/providerdemo/config/ZipkinConfiguration.java new file mode 100644 index 000000000..3348c7067 --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/providerdemo/config/ZipkinConfiguration.java @@ -0,0 +1,57 @@ +package cn.iocoder.springboot.lab40.zipkindemo.providerdemo.config; + +import brave.CurrentSpanCustomizer; +import brave.SpanCustomizer; +import brave.Tracing; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import zipkin2.Span; +import zipkin2.reporter.AsyncReporter; +import zipkin2.reporter.Sender; +import zipkin2.reporter.okhttp3.OkHttpSender; + +@Configuration +public class ZipkinConfiguration { + + // ==================== 通用配置 ==================== + + /** + * Configuration for how to send spans to Zipkin + */ + @Bean + public Sender sender() { + return OkHttpSender.create("http://127.0.0.1:9411/api/v2/spans"); + } + + /** + * Configuration for how to buffer spans into messages for Zipkin + */ + @Bean + public AsyncReporter spanReporter() { + return AsyncReporter.create(sender()); + } + + /** + * Controls aspects of tracing such as the service name that shows up in the UI + */ + @Bean + public Tracing tracing(@Value("${spring.application.name}") String serviceName) { + return Tracing.newBuilder() + .localServiceName(serviceName) +// .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder() +// .addScopeDecorator(MDCScopeDecorator.create()) // puts trace IDs into logs +// .build() +// ) + .spanReporter(spanReporter()).build(); + } + + /** + * Allows someone to add tags to a span if a trace is in progress + */ + @Bean + public SpanCustomizer spanCustomizer(Tracing tracing) { + return CurrentSpanCustomizer.create(tracing); + } + +} diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/providerdemo/service/UserServiceImpl.java b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/providerdemo/service/UserServiceImpl.java new file mode 100644 index 000000000..244c5482a --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/java/cn/iocoder/springboot/lab40/zipkindemo/providerdemo/service/UserServiceImpl.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab40.zipkindemo.providerdemo.service; + +import cn.iocoder.springboot.lab40.zipkindemo.api.UserService; + +@org.apache.dubbo.config.annotation.Service(version = "1.0.0") +public class UserServiceImpl implements UserService { + + @Override + public String get(Integer id) { + return "user:" + id; + } + +} diff --git a/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/resources/application.yaml b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..9fa121ee6 --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/lab-40-zipkin-dubbo-provider/src/main/resources/application.yaml @@ -0,0 +1,22 @@ +spring: + application: + name: user-service-provider + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 应用配置 + application: + name: ${spring.application.name} # 应用名 + # Dubbo 注册中心配 + registry: + address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springboot.lab40.zipkindemo.providerdemo.service + # Dubbo 服务提供者的配置,对应 ProviderConfig 类 + provider: + filter: tracing diff --git a/lab-40/lab-40-zipkin-dubbo/pom.xml b/lab-40/lab-40-zipkin-dubbo/pom.xml new file mode 100644 index 000000000..5fe8ebffb --- /dev/null +++ b/lab-40/lab-40-zipkin-dubbo/pom.xml @@ -0,0 +1,21 @@ + + + + lab-40 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-40-zipkin-dubbo + pom + + lab-40-zipkin-dubbo-api + lab-40-zipkin-dubbo-provider + lab-40-zipkin-dubbo-consumer + + + + diff --git a/lab-40/pom.xml b/lab-40/pom.xml index 66f0a911d..88978f84c 100644 --- a/lab-40/pom.xml +++ b/lab-40/pom.xml @@ -14,6 +14,8 @@ lab-40-demo lab-40-springmvc + lab-40-zipkin-dubbo + lab-40-mysql lab-40-redis lab-40-mongodb @@ -22,8 +24,10 @@ lab-40-kafka lab-40-rabbitmq lab-40-activemq + lab-40-logback lab-40-opentracing + diff --git "a/lab-40/\343\200\212\350\212\213\351\201\223 Spring Boot \351\223\276\350\267\257\350\277\275\350\270\252 Zipkin \345\205\245\351\227\250\343\200\213.md" "b/lab-40/\343\200\212\350\212\213\351\201\223 Spring Boot \351\223\276\350\267\257\350\277\275\350\270\252 Zipkin \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..36e016567 --- /dev/null +++ "b/lab-40/\343\200\212\350\212\213\351\201\223 Spring Boot \351\223\276\350\267\257\350\277\275\350\270\252 Zipkin \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-41/lab-41-demo01/src/main/resources/application-dev.yaml b/lab-41/lab-41-demo01/src/main/resources/application-dev.yaml index 5475f936b..e41dc5643 100644 --- a/lab-41/lab-41-demo01/src/main/resources/application-dev.yaml +++ b/lab-41/lab-41-demo01/src/main/resources/application-dev.yaml @@ -5,7 +5,7 @@ management: server: port: 8078 # 自定义端口,避免 Nginx 暴露出去 - endpoint: + endpoints: web: exposure: include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/lab-41/lab-41-demo01/src/main/resources/application-local.yaml b/lab-41/lab-41-demo01/src/main/resources/application-local.yaml index 5475f936b..e41dc5643 100644 --- a/lab-41/lab-41-demo01/src/main/resources/application-local.yaml +++ b/lab-41/lab-41-demo01/src/main/resources/application-local.yaml @@ -5,7 +5,7 @@ management: server: port: 8078 # 自定义端口,避免 Nginx 暴露出去 - endpoint: + endpoints: web: exposure: include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/lab-41/lab-41-demo01/src/main/resources/application-pre.yaml b/lab-41/lab-41-demo01/src/main/resources/application-pre.yaml index 5475f936b..e41dc5643 100644 --- a/lab-41/lab-41-demo01/src/main/resources/application-pre.yaml +++ b/lab-41/lab-41-demo01/src/main/resources/application-pre.yaml @@ -5,7 +5,7 @@ management: server: port: 8078 # 自定义端口,避免 Nginx 暴露出去 - endpoint: + endpoints: web: exposure: include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/lab-41/lab-41-demo01/src/main/resources/application-prod.yaml b/lab-41/lab-41-demo01/src/main/resources/application-prod.yaml index 5475f936b..e41dc5643 100644 --- a/lab-41/lab-41-demo01/src/main/resources/application-prod.yaml +++ b/lab-41/lab-41-demo01/src/main/resources/application-prod.yaml @@ -5,7 +5,7 @@ management: server: port: 8078 # 自定义端口,避免 Nginx 暴露出去 - endpoint: + endpoints: web: exposure: include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/lab-41/lab-41-demo01/src/main/resources/application-uat.yaml b/lab-41/lab-41-demo01/src/main/resources/application-uat.yaml index 5475f936b..e41dc5643 100644 --- a/lab-41/lab-41-demo01/src/main/resources/application-uat.yaml +++ b/lab-41/lab-41-demo01/src/main/resources/application-uat.yaml @@ -5,7 +5,7 @@ management: server: port: 8078 # 自定义端口,避免 Nginx 暴露出去 - endpoint: + endpoints: web: exposure: include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git "a/lab-41/\343\200\212\350\212\213\351\201\223 Spring Boot \346\214\201\347\273\255\344\272\244\344\273\230 Jenkins \345\205\245\351\227\250\343\200\213.md" "b/lab-41/\343\200\212\350\212\213\351\201\223 Spring Boot \346\214\201\347\273\255\344\272\244\344\273\230 Jenkins \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..547105888 --- /dev/null +++ "b/lab-41/\343\200\212\350\212\213\351\201\223 Spring Boot \346\214\201\347\273\255\344\272\244\344\273\230 Jenkins \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-42/\343\200\212\350\212\213\351\201\223 Spring Boot \345\215\225\345\205\203\346\265\213\350\257\225 Test \345\205\245\351\227\250\343\200\213.md" "b/lab-42/\343\200\212\350\212\213\351\201\223 Spring Boot \345\215\225\345\205\203\346\265\213\350\257\225 Test \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..310023850 --- /dev/null +++ "b/lab-42/\343\200\212\350\212\213\351\201\223 Spring Boot \345\215\225\345\205\203\346\265\213\350\257\225 Test \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-43/\343\200\212\350\212\213\351\201\223 Spring Boot \351\205\215\347\275\256\346\226\207\344\273\266\345\205\245\351\227\250\343\200\213.md" "b/lab-43/\343\200\212\350\212\213\351\201\223 Spring Boot \351\205\215\347\275\256\346\226\207\344\273\266\345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..6574f55da --- /dev/null +++ "b/lab-43/\343\200\212\350\212\213\351\201\223 Spring Boot \351\205\215\347\275\256\346\226\207\344\273\266\345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-44/\343\200\212\350\212\213\351\201\223 Spring Boot \346\263\250\345\206\214\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" "b/lab-44/\343\200\212\350\212\213\351\201\223 Spring Boot \346\263\250\345\206\214\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..f8d8346df --- /dev/null +++ "b/lab-44/\343\200\212\350\212\213\351\201\223 Spring Boot \346\263\250\345\206\214\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-44/\343\200\212\350\212\213\351\201\223 Spring Boot \351\205\215\347\275\256\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" "b/lab-44/\343\200\212\350\212\213\351\201\223 Spring Boot \351\205\215\347\275\256\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..f55290b77 --- /dev/null +++ "b/lab-44/\343\200\212\350\212\213\351\201\223 Spring Boot \351\205\215\347\275\256\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-45/lab-45-apollo-demo/src/main/resources/application.yaml b/lab-45/lab-45-apollo-demo/src/main/resources/application.yaml index ee0075796..ace5489d2 100644 --- a/lab-45/lab-45-apollo-demo/src/main/resources/application.yaml +++ b/lab-45/lab-45-apollo-demo/src/main/resources/application.yaml @@ -1,3 +1,6 @@ +server: + port: 7070 # 避免和本地的 Apollo Portal 端口冲突 + app: id: demo-application # 使用的 Apollo 的项目(应用)编号 apollo: diff --git "a/lab-45/\343\200\212\350\212\213\351\201\223 Spring Boot \351\205\215\347\275\256\344\270\255\345\277\203 Apollo \345\205\245\351\227\250\343\200\213.md" "b/lab-45/\343\200\212\350\212\213\351\201\223 Spring Boot \351\205\215\347\275\256\344\270\255\345\277\203 Apollo \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..66b4e0d2c --- /dev/null +++ "b/lab-45/\343\200\212\350\212\213\351\201\223 Spring Boot \351\205\215\347\275\256\344\270\255\345\277\203 Apollo \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-46/lab-46-sentinel-demo-file/target/classes/sentinel.properties b/lab-46/lab-46-sentinel-demo-file/target/classes/sentinel.properties deleted file mode 100644 index be3ba2284..000000000 --- a/lab-46/lab-46-sentinel-demo-file/target/classes/sentinel.properties +++ /dev/null @@ -1 +0,0 @@ -csp.sentinel.dashboard.server=127.0.0.1:7070 diff --git "a/lab-46/\343\200\212\350\212\213\351\201\223 Spring Boot \346\234\215\345\212\241\345\256\271\351\224\231 Sentinel \345\205\245\351\227\250\343\200\213.md" "b/lab-46/\343\200\212\350\212\213\351\201\223 Spring Boot \346\234\215\345\212\241\345\256\271\351\224\231 Sentinel \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..179c63e29 --- /dev/null +++ "b/lab-46/\343\200\212\350\212\213\351\201\223 Spring Boot \346\234\215\345\212\241\345\256\271\351\224\231 Sentinel \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-47/\343\200\212\350\212\213\351\201\223 Spring Boot \350\207\252\345\212\250\351\205\215\347\275\256\345\216\237\347\220\206\343\200\213.md" "b/lab-47/\343\200\212\350\212\213\351\201\223 Spring Boot \350\207\252\345\212\250\351\205\215\347\275\256\345\216\237\347\220\206\343\200\213.md" new file mode 100644 index 000000000..0b4b2b8cb --- /dev/null +++ "b/lab-47/\343\200\212\350\212\213\351\201\223 Spring Boot \350\207\252\345\212\250\351\205\215\347\275\256\345\216\237\347\220\206\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-48/\343\200\212\350\212\213\351\201\223 Spring Boot \347\203\255\351\203\250\347\275\262\345\205\245\351\227\250\343\200\213.md" "b/lab-48/\343\200\212\350\212\213\351\201\223 Spring Boot \347\203\255\351\203\250\347\275\262\345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..9bb1a9875 --- /dev/null +++ "b/lab-48/\343\200\212\350\212\213\351\201\223 Spring Boot \347\203\255\351\203\250\347\275\262\345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/lab-49/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\351\231\244\345\206\227\344\275\231\344\273\243\347\240\201 Lombok \345\205\245\351\227\250\343\200\213.md" "b/lab-49/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\351\231\244\345\206\227\344\275\231\344\273\243\347\240\201 Lombok \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..ed5938492 --- /dev/null +++ "b/lab-49/\343\200\212\350\212\213\351\201\223 Spring Boot \346\266\210\351\231\244\345\206\227\344\275\231\344\273\243\347\240\201 Lombok \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-50/lab-50-demo/pom.xml b/lab-50/lab-50-demo/pom.xml new file mode 100644 index 000000000..a9d20f914 --- /dev/null +++ b/lab-50/lab-50-demo/pom.xml @@ -0,0 +1,30 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-50-demo + + + + + org.springframework.boot + spring-boot-starter-mail + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/lab-50/lab-50-demo/src/main/java/cn/iocoder/springboot/lab50/maildemo/Application.java b/lab-50/lab-50-demo/src/main/java/cn/iocoder/springboot/lab50/maildemo/Application.java new file mode 100644 index 000000000..7c0b88db9 --- /dev/null +++ b/lab-50/lab-50-demo/src/main/java/cn/iocoder/springboot/lab50/maildemo/Application.java @@ -0,0 +1,7 @@ +package cn.iocoder.springboot.lab50.maildemo; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { +} diff --git a/lab-50/lab-50-demo/src/main/resources/application.yml b/lab-50/lab-50-demo/src/main/resources/application.yml new file mode 100644 index 000000000..bcbcb2d8c --- /dev/null +++ b/lab-50/lab-50-demo/src/main/resources/application.yml @@ -0,0 +1,30 @@ +#spring: +# mail: # 配置发送告警的邮箱 +# host: smtp.163.com +# port: 465 +# protocol: smtps +# username: yudaoyuanma@163.com +# password: '***' +# default-encoding: UTF-8 +## properties: +## smtp: +## auth: true +## starttls: +## enable: true +## required: true + + +spring: + mail: # 配置发送告警的邮箱 + host: smtp.exmail.qq.com + port: 465 + protocol: smtps + username: yunai.wang@medcloud.cn + password: '***' + default-encoding: UTF-8 + properties: + smtp: + auth: true + starttls: + enable: true + required: true diff --git a/lab-50/lab-50-demo/src/test/java/cn/iocoder/springboot/lab50/maildemo/ApplicationTests.java b/lab-50/lab-50-demo/src/test/java/cn/iocoder/springboot/lab50/maildemo/ApplicationTests.java new file mode 100644 index 000000000..4b24a04d5 --- /dev/null +++ b/lab-50/lab-50-demo/src/test/java/cn/iocoder/springboot/lab50/maildemo/ApplicationTests.java @@ -0,0 +1,33 @@ +package cn.iocoder.springboot.lab50.maildemo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class ApplicationTests { + + @Autowired + private JavaMailSender mailSender; + + @Value("${spring.mail.username}") + private String username; + + @Test + public void testSend() { + SimpleMailMessage message = new SimpleMailMessage(); + message.setFrom(username); + message.setTo("7685413@qq.com"); + message.setSubject("我是测试主题"); + message.setText("我是测试内容"); + + mailSender.send(message); + } + +} diff --git a/lab-50/pom.xml b/lab-50/pom.xml new file mode 100644 index 000000000..71e8efc7f --- /dev/null +++ b/lab-50/pom.xml @@ -0,0 +1,19 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-50 + pom + + lab-50-demo + + + + diff --git "a/lab-50/\350\256\241\345\210\222\344\270\255" "b/lab-50/\350\256\241\345\210\222\344\270\255" new file mode 100644 index 000000000..e69de29bb diff --git a/lab-51/lab-51-sentry-logback/pom.xml b/lab-51/lab-51-sentry-logback/pom.xml new file mode 100644 index 000000000..8f4af3a04 --- /dev/null +++ b/lab-51/lab-51-sentry-logback/pom.xml @@ -0,0 +1,30 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-51-sentry-logback + + + + + org.springframework.boot + spring-boot-starter-web + + + + + io.sentry + sentry-logback + 1.7.30 + + + + diff --git a/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/DemoApplication.java b/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/DemoApplication.java new file mode 100644 index 000000000..0c31346f5 --- /dev/null +++ b/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/DemoApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab51.sentrydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } + +} diff --git a/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/controller/DemoController.java b/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/controller/DemoController.java new file mode 100644 index 000000000..2c2efe2b3 --- /dev/null +++ b/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/controller/DemoController.java @@ -0,0 +1,27 @@ +package cn.iocoder.springboot.lab51.sentrydemo.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @GetMapping("/sentry") + public String sentry() { + logger.error("[main][我就是展示下异常!]"); + + return "success"; + } + + @GetMapping("/exception") + public String exception() { + throw new RuntimeException("直接抛出异常"); + } + +} diff --git a/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/core/package-info.java b/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/core/package-info.java new file mode 100644 index 000000000..a0de6bb95 --- /dev/null +++ b/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/core/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.springboot.lab51.sentrydemo.core; diff --git a/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/core/web/GlobalExceptionHandler.java b/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/core/web/GlobalExceptionHandler.java new file mode 100644 index 000000000..8b800d85d --- /dev/null +++ b/lab-51/lab-51-sentry-logback/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/core/web/GlobalExceptionHandler.java @@ -0,0 +1,30 @@ +package cn.iocoder.springboot.lab51.sentrydemo.core.web; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; + +@ControllerAdvice(basePackages = "cn.iocoder.springboot.lab51.sentrydemo.controller") +public class GlobalExceptionHandler { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + // ... 省略其它类型异常的处理 + + /** + * 处理其它 Exception 异常 + */ + @ResponseBody + @ExceptionHandler(value = Exception.class) + public String exceptionHandler(HttpServletRequest req, Exception e) { + // 记录异常日志 + logger.error("[exceptionHandler]", e); + // 返回 ERROR CommonResult + return "系统异常"; + } + +} diff --git a/lab-51/lab-51-sentry-logback/src/main/resources/logback-spring.xml b/lab-51/lab-51-sentry-logback/src/main/resources/logback-spring.xml new file mode 100644 index 000000000..0b9ef7c98 --- /dev/null +++ b/lab-51/lab-51-sentry-logback/src/main/resources/logback-spring.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + WARN + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + diff --git a/lab-51/lab-51-sentry-logback/src/main/resources/sentry.properties b/lab-51/lab-51-sentry-logback/src/main/resources/sentry.properties new file mode 100644 index 000000000..cc010474a --- /dev/null +++ b/lab-51/lab-51-sentry-logback/src/main/resources/sentry.properties @@ -0,0 +1,7 @@ +# Sentry 配置文件。每个配置 key,从 DefaultSentryClientFactory 类中寻找 +# DSN +dsn=http://b10468b71cd945358ff88ed975287194@47.56.150.64:9000/3 +# HTTP 请求建立连接超时时间 +timeout=60000 +# HTTP 请求等待结果超时时间 +readtimeout=60000 diff --git a/lab-51/lab-51-sentry-spring/pom.xml b/lab-51/lab-51-sentry-spring/pom.xml new file mode 100644 index 000000000..2764df1c5 --- /dev/null +++ b/lab-51/lab-51-sentry-spring/pom.xml @@ -0,0 +1,24 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-51-sentry-spring + + + + + io.sentry + sentry-spring-boot-starter + 1.7.30 + + + + diff --git a/lab-51/lab-51-sentry-spring/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/DemoApplication.java b/lab-51/lab-51-sentry-spring/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/DemoApplication.java new file mode 100644 index 000000000..5dde280ec --- /dev/null +++ b/lab-51/lab-51-sentry-spring/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/DemoApplication.java @@ -0,0 +1,14 @@ +package cn.iocoder.springboot.lab51.sentrydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) throws InterruptedException { + // 启动 Spring Boot 应用 + SpringApplication.run(DemoApplication.class, args); + } + +} diff --git a/lab-51/lab-51-sentry-spring/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/controller/DemoController.java b/lab-51/lab-51-sentry-spring/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/controller/DemoController.java new file mode 100644 index 000000000..c132be3b9 --- /dev/null +++ b/lab-51/lab-51-sentry-spring/src/main/java/cn/iocoder/springboot/lab51/sentrydemo/controller/DemoController.java @@ -0,0 +1,36 @@ +package cn.iocoder.springboot.lab51.sentrydemo.controller; + +import io.sentry.SentryClient; +import io.sentry.event.EventBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + @Autowired + private SentryClient sentryClient; + + @GetMapping("/sentry") + public String sentry() { + // 上传消息到 Sentry 中 + sentryClient.sendMessage("示例消息"); + + // 上传异常到 Sentry 中 + sentryClient.sendException(new RuntimeException("测试异常")); + + // 上传事件到 Sentry 中 + sentryClient.sendEvent(new EventBuilder().withMessage("示例事件").build()); + + return "success"; + } + + @GetMapping("/exception") + public String exception() { + throw new RuntimeException("直接抛出异常"); + } + +} diff --git a/lab-51/lab-51-sentry-spring/src/main/resources/application.yml b/lab-51/lab-51-sentry-spring/src/main/resources/application.yml new file mode 100644 index 000000000..a92789afa --- /dev/null +++ b/lab-51/lab-51-sentry-spring/src/main/resources/application.yml @@ -0,0 +1,7 @@ +# Sentry 配置项,对应 SentryProperties 配置类 +sentry: + dsn: http://b10468b71cd945358ff88ed975287194@47.56.150.64:9000/3 # DSN + timeout: 60000 # HTTP 请求建立连接超时时间 + +server: + port: 18080 diff --git a/lab-51/pom.xml b/lab-51/pom.xml new file mode 100644 index 000000000..b187569a7 --- /dev/null +++ b/lab-51/pom.xml @@ -0,0 +1,20 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-51 + pom + + lab-51-sentry-logback + lab-51-sentry-spring + + + + diff --git "a/lab-51/\343\200\212\350\212\213\351\201\223 Spring Boot \345\274\202\345\270\270\347\256\241\347\220\206\345\271\263\345\217\260 Sentry \345\205\245\351\227\250\343\200\213.md" "b/lab-51/\343\200\212\350\212\213\351\201\223 Spring Boot \345\274\202\345\270\270\347\256\241\347\220\206\345\271\263\345\217\260 Sentry \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..a6cb09dd4 --- /dev/null +++ "b/lab-51/\343\200\212\350\212\213\351\201\223 Spring Boot \345\274\202\345\270\270\347\256\241\347\220\206\345\271\263\345\217\260 Sentry \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-52/lab-52-multiple-datasource/pom.xml b/lab-52/lab-52-multiple-datasource/pom.xml new file mode 100644 index 000000000..69a1990bd --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/pom.xml @@ -0,0 +1,55 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-52-multiple-datasource + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + com.baomidou + dynamic-datasource-spring-boot-starter + 3.0.0 + + + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/MultipleDatasourceApplication.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/MultipleDatasourceApplication.java new file mode 100644 index 000000000..573deacb9 --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/MultipleDatasourceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab52.seatademo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MultipleDatasourceApplication { + + public static void main(String[] args) { + SpringApplication.run(MultipleDatasourceApplication.class, args); + } + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/controller/OrderController.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/controller/OrderController.java new file mode 100644 index 000000000..0d0a3b8dc --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/controller/OrderController.java @@ -0,0 +1,29 @@ +package cn.iocoder.springboot.lab52.seatademo.controller; + +import cn.iocoder.springboot.lab52.seatademo.service.OrderService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/order") +public class OrderController { + + private Logger logger = LoggerFactory.getLogger(OrderController.class); + + @Autowired + private OrderService orderService; + + @PostMapping("/create") + public Integer createOrder(@RequestParam("userId") Long userId, + @RequestParam("productId") Long productId, + @RequestParam("price") Integer price) throws Exception { + logger.info("[createOrder] 收到下单请求,用户:{}, 商品:{}, 价格:{}", userId, productId, price); + return orderService.createOrder(userId, productId, price); + } + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/dao/AccountDao.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/dao/AccountDao.java new file mode 100644 index 000000000..6dfed7fc9 --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/dao/AccountDao.java @@ -0,0 +1,32 @@ +package cn.iocoder.springboot.lab52.seatademo.dao; + + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface AccountDao { + + /** + * 获取账户余额 + * + * @param userId 用户 ID + * @return 账户余额 + */ + @Select("SELECT balance FROM account WHERE id = #{userId}") + Integer getBalance(@Param("userId") Long userId); + + /** + * 扣减余额 + * + * @param price 需要扣减的数目 + * @return 影响记录行数 + */ + @Update("UPDATE account SET balance = balance - #{price} WHERE id = 1 AND balance >= ${price}") + int reduceBalance(@Param("price") Integer price); + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/dao/OrderDao.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/dao/OrderDao.java new file mode 100644 index 000000000..f11927a27 --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/dao/OrderDao.java @@ -0,0 +1,21 @@ +package cn.iocoder.springboot.lab52.seatademo.dao; + +import cn.iocoder.springboot.lab52.seatademo.entity.OrderDO; +import org.apache.ibatis.annotations.*; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface OrderDao { + + /** + * 插入订单记录 + * + * @param order 订单 + * @return 影响记录数量 + */ + @Insert("INSERT INTO orders (user_id, product_id, pay_amount) VALUES (#{userId}, #{productId}, #{payAmount})") + @Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id") + int saveOrder(OrderDO order); + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/dao/ProductDao.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/dao/ProductDao.java new file mode 100644 index 000000000..89caadb5c --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/dao/ProductDao.java @@ -0,0 +1,33 @@ +package cn.iocoder.springboot.lab52.seatademo.dao; + + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface ProductDao { + + /** + * 获取库存 + * + * @param productId 商品编号 + * @return 库存 + */ + @Select("SELECT stock FROM product WHERE id = #{productId}") + Integer getStock(@Param("productId") Long productId); + + /** + * 扣减库存 + * + * @param productId 商品编号 + * @param amount 扣减数量 + * @return 影响记录行数 + */ + @Update("UPDATE product SET stock = stock - #{amount} WHERE id = #{productId} AND stock >= #{amount}") + int reduceStock(@Param("productId") Long productId, @Param("amount") Integer amount); + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/entity/OrderDO.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/entity/OrderDO.java new file mode 100644 index 000000000..af6e8ee31 --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/entity/OrderDO.java @@ -0,0 +1,56 @@ +package cn.iocoder.springboot.lab52.seatademo.entity; + +/** + * 订单实体 + */ +public class OrderDO { + + /** 订单编号 **/ + private Integer id; + + /** 用户编号 **/ + private Long userId; + + /** 产品编号 **/ + private Long productId; + + /** 支付金额 **/ + private Integer payAmount; + + public Integer getId() { + return id; + } + + public OrderDO setId(Integer id) { + this.id = id; + return this; + } + + public Long getUserId() { + return userId; + } + + public OrderDO setUserId(Long userId) { + this.userId = userId; + return this; + } + + public Long getProductId() { + return productId; + } + + public OrderDO setProductId(Long productId) { + this.productId = productId; + return this; + } + + public Integer getPayAmount() { + return payAmount; + } + + public OrderDO setPayAmount(Integer payAmount) { + this.payAmount = payAmount; + return this; + } + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/AccountService.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/AccountService.java new file mode 100644 index 000000000..74c762e7e --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/AccountService.java @@ -0,0 +1,17 @@ +package cn.iocoder.springboot.lab52.seatademo.service; + +/** + * 账户 Service + */ +public interface AccountService { + + /** + * 扣除余额 + * + * @param userId 用户编号 + * @param price 扣减金额 + * @throws Exception 失败时抛出异常 + */ + void reduceBalance(Long userId, Integer price) throws Exception; + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/OrderService.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/OrderService.java new file mode 100644 index 000000000..691029d85 --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/OrderService.java @@ -0,0 +1,19 @@ +package cn.iocoder.springboot.lab52.seatademo.service; + +/** + * 订单 Service + */ +public interface OrderService { + + /** + * 创建订单 + * + * @param userId 用户编号 + * @param productId 产品编号 + * @param price 价格 + * @return 订单编号 + * @throws Exception 创建订单失败,抛出异常 + */ + Integer createOrder(Long userId, Long productId, Integer price) throws Exception; + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/ProductService.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/ProductService.java new file mode 100644 index 000000000..fdba69c2d --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/ProductService.java @@ -0,0 +1,17 @@ +package cn.iocoder.springboot.lab52.seatademo.service; + +/** + * 商品 Service + */ +public interface ProductService { + + /** + * 扣减库存 + * + * @param productId 商品 ID + * @param amount 扣减数量 + * @throws Exception 扣减失败时抛出异常 + */ + void reduceStock(Long productId, Integer amount) throws Exception; + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/impl/AccountServiceImpl.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/impl/AccountServiceImpl.java new file mode 100644 index 000000000..5149eb1f2 --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/impl/AccountServiceImpl.java @@ -0,0 +1,51 @@ +package cn.iocoder.springboot.lab52.seatademo.service.impl; + +import cn.iocoder.springboot.lab52.seatademo.dao.AccountDao; +import cn.iocoder.springboot.lab52.seatademo.service.AccountService; +import com.baomidou.dynamic.datasource.annotation.DS; +import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class AccountServiceImpl implements AccountService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private AccountDao accountDao; + + @Override + @DS(value = "account-ds") + @Transactional(propagation = Propagation.REQUIRES_NEW) // 开启新事物 + public void reduceBalance(Long userId, Integer price) throws Exception { + logger.info("[reduceBalance] 当前 XID: {}", RootContext.getXID()); + + // 检查余额 + checkBalance(userId, price); + + logger.info("[reduceBalance] 开始扣减用户 {} 余额", userId); + // 扣除余额 + int updateCount = accountDao.reduceBalance(price); + // 扣除成功 + if (updateCount == 0) { + logger.warn("[reduceBalance] 扣除用户 {} 余额失败", userId); + throw new Exception("余额不足"); + } + logger.info("[reduceBalance] 扣除用户 {} 余额成功", userId); + } + + private void checkBalance(Long userId, Integer price) throws Exception { + logger.info("[checkBalance] 检查用户 {} 余额", userId); + Integer balance = accountDao.getBalance(userId); + if (balance < price) { + logger.warn("[checkBalance] 用户 {} 余额不足,当前余额:{}", userId, balance); + throw new Exception("余额不足"); + } + } + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/impl/OrderServiceImpl.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/impl/OrderServiceImpl.java new file mode 100644 index 000000000..1d0e633b4 --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/impl/OrderServiceImpl.java @@ -0,0 +1,53 @@ +package cn.iocoder.springboot.lab52.seatademo.service.impl; + +import cn.iocoder.springboot.lab52.seatademo.dao.OrderDao; +import cn.iocoder.springboot.lab52.seatademo.entity.OrderDO; +import cn.iocoder.springboot.lab52.seatademo.service.OrderService; +import cn.iocoder.springboot.lab52.seatademo.service.AccountService; +import cn.iocoder.springboot.lab52.seatademo.service.ProductService; +import com.baomidou.dynamic.datasource.annotation.DS; +import io.seata.core.context.RootContext; +import io.seata.spring.annotation.GlobalTransactional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class OrderServiceImpl implements OrderService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private OrderDao orderDao; + + @Autowired + private AccountService accountService; + + @Autowired + private ProductService productService; + + @Override + @DS(value = "order-ds") + @GlobalTransactional + public Integer createOrder(Long userId, Long productId, Integer price) throws Exception { + Integer amount = 1; // 购买数量,暂时设置为 1。 + + logger.info("[createOrder] 当前 XID: {}", RootContext.getXID()); + + // 扣减库存 + productService.reduceStock(productId, amount); + + // 扣减余额 + accountService.reduceBalance(userId, price); + + // 保存订单 + OrderDO order = new OrderDO().setUserId(userId).setProductId(productId).setPayAmount(amount * price); + orderDao.saveOrder(order); + logger.info("[createOrder] 保存订单: {}", order.getId()); + + // 返回订单编号 + return order.getId(); + } + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/impl/ProductServiceImpl.java b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/impl/ProductServiceImpl.java new file mode 100644 index 000000000..ac3c27a25 --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/java/cn/iocoder/springboot/lab52/seatademo/service/impl/ProductServiceImpl.java @@ -0,0 +1,52 @@ +package cn.iocoder.springboot.lab52.seatademo.service.impl; + +import cn.iocoder.springboot.lab52.seatademo.dao.ProductDao; +import cn.iocoder.springboot.lab52.seatademo.service.ProductService; +import com.baomidou.dynamic.datasource.annotation.DS; +import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class ProductServiceImpl implements ProductService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ProductDao productDao; + + @Override + @DS(value = "product-ds") + @Transactional(propagation = Propagation.REQUIRES_NEW) // 开启新事物 + public void reduceStock(Long productId, Integer amount) throws Exception { + logger.info("[reduceStock] 当前 XID: {}", RootContext.getXID()); + + // 检查库存 + checkStock(productId, amount); + + logger.info("[reduceStock] 开始扣减 {} 库存", productId); + // 扣减库存 + int updateCount = productDao.reduceStock(productId, amount); + // 扣除成功 + if (updateCount == 0) { + logger.warn("[reduceStock] 扣除 {} 库存失败", productId); + throw new Exception("库存不足"); + } + // 扣除失败 + logger.info("[reduceStock] 扣除 {} 库存成功", productId); + } + + private void checkStock(Long productId, Integer requiredAmount) throws Exception { + logger.info("[checkStock] 检查 {} 库存", productId); + Integer stock = productDao.getStock(productId); + if (stock < requiredAmount) { + logger.warn("[checkStock] {} 库存不足,当前库存: {}", productId, stock); + throw new Exception("库存不足"); + } + } + +} diff --git a/lab-52/lab-52-multiple-datasource/src/main/resources/application.yaml b/lab-52/lab-52-multiple-datasource/src/main/resources/application.yaml new file mode 100644 index 000000000..ae52f5fa8 --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/resources/application.yaml @@ -0,0 +1,44 @@ +server: + port: 8081 # 端口 + +spring: + application: + name: multi-datasource-service # 应用名 + + datasource: + # dynamic-datasource-spring-boot-starter 动态数据源的配配项,对应 DynamicDataSourceProperties 类 + dynamic: + primary: order-ds # 设置默认的数据源或者数据源组,默认值即为 master + datasource: + # 订单 order 数据源配置 + order-ds: + url: jdbc:mysql://127.0.0.1:3306/seata_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + # 账户 pay 数据源配置 + account-ds: + url: jdbc:mysql://127.0.0.1:3306/seata_account?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + # 商品 product 数据源配置 + product-ds: + url: jdbc:mysql://127.0.0.1:3306/seata_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + seata: true # 是否启动对 Seata 的集成 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + multi-datasource-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/lab-52/lab-52-multiple-datasource/src/main/resources/data.sql b/lab-52/lab-52-multiple-datasource/src/main/resources/data.sql new file mode 100644 index 000000000..422c46f74 --- /dev/null +++ b/lab-52/lab-52-multiple-datasource/src/main/resources/data.sql @@ -0,0 +1,83 @@ +# Order +DROP DATABASE IF EXISTS seata_order; +CREATE DATABASE seata_order; + +CREATE TABLE seata_order.orders +( + id INT(11) NOT NULL AUTO_INCREMENT, + user_id INT(11) DEFAULT NULL, + product_id INT(11) DEFAULT NULL, + pay_amount DECIMAL(10, 0) DEFAULT NULL, + add_time DATETIME DEFAULT CURRENT_TIMESTAMP, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +CREATE TABLE seata_order.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +# Product +DROP DATABASE IF EXISTS seata_product; +CREATE DATABASE seata_product; + +CREATE TABLE seata_product.product +( + id INT(11) NOT NULL AUTO_INCREMENT, + stock INT(11) DEFAULT NULL, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; +INSERT INTO seata_product.product (id, stock) VALUES (1, 10); # 插入一条产品的库存 + +CREATE TABLE seata_product.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +# Account +DROP DATABASE IF EXISTS seata_account; +CREATE DATABASE seata_account; + +CREATE TABLE seata_account.account +( + id INT(11) NOT NULL AUTO_INCREMENT, + balance DOUBLE DEFAULT NULL, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +CREATE TABLE seata_account.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; +INSERT INTO seata_account.account (id, balance) VALUES (1, 10); + diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/pom.xml b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/pom.xml new file mode 100644 index 000000000..b803d0e2f --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/pom.xml @@ -0,0 +1,61 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-52-seata-at-httpclient-demo-account-service + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + io.seata + seata-http + 1.1.0 + + + + + org.apache.httpcomponents + httpclient + 4.5.8 + + + + diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/AccountServiceApplication.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/AccountServiceApplication.java new file mode 100644 index 000000000..713a4c238 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/AccountServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab52.accountservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AccountServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(AccountServiceApplication.class, args); + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/controller/AccountController.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/controller/AccountController.java new file mode 100644 index 000000000..dd0eed2b2 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/controller/AccountController.java @@ -0,0 +1,36 @@ +package cn.iocoder.springboot.lab52.accountservice.controller; + +import cn.iocoder.springboot.lab52.accountservice.dto.AccountReduceBalanceDTO; +import cn.iocoder.springboot.lab52.accountservice.service.AccountService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/account") +public class AccountController { + + private Logger logger = LoggerFactory.getLogger(AccountController.class); + + @Autowired + private AccountService accountService; + + @PostMapping("/reduce-balance") + public Boolean reduceBalance(@RequestBody AccountReduceBalanceDTO accountReduceBalanceDTO) { + logger.info("[reduceBalance] 收到减少余额请求, 用户:{}, 金额:{}", accountReduceBalanceDTO.getUserId(), + accountReduceBalanceDTO.getPrice()); + try { + accountService.reduceBalance(accountReduceBalanceDTO.getUserId(), accountReduceBalanceDTO.getPrice()); + // 正常扣除余额,返回 true + return true; + } catch (Exception e) { + // 失败扣除余额,返回 false + return false; + } + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/dao/AccountDao.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/dao/AccountDao.java new file mode 100644 index 000000000..17ac59573 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/dao/AccountDao.java @@ -0,0 +1,32 @@ +package cn.iocoder.springboot.lab52.accountservice.dao; + + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface AccountDao { + + /** + * 获取账户余额 + * + * @param userId 用户 ID + * @return 账户余额 + */ + @Select("SELECT balance FROM account WHERE id = #{userId}") + Integer getBalance(@Param("userId") Long userId); + + /** + * 扣减余额 + * + * @param price 需要扣减的数目 + * @return 影响记录行数 + */ + @Update("UPDATE account SET balance = balance - #{price} WHERE id = 1 AND balance >= ${price}") + int reduceBalance(@Param("price") Integer price); + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/dto/AccountReduceBalanceDTO.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/dto/AccountReduceBalanceDTO.java new file mode 100644 index 000000000..be3ecdf50 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/dto/AccountReduceBalanceDTO.java @@ -0,0 +1,36 @@ +package cn.iocoder.springboot.lab52.accountservice.dto; + +/** + * 账户减少余额 DTO + */ +public class AccountReduceBalanceDTO { + + /** + * 用户编号 + */ + private Long userId; + + /** + * 扣减金额 + */ + private Integer price; + + public Long getUserId() { + return userId; + } + + public AccountReduceBalanceDTO setUserId(Long userId) { + this.userId = userId; + return this; + } + + public Integer getPrice() { + return price; + } + + public AccountReduceBalanceDTO setPrice(Integer price) { + this.price = price; + return this; + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/service/AccountService.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/service/AccountService.java new file mode 100644 index 000000000..c5eb66683 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/service/AccountService.java @@ -0,0 +1,17 @@ +package cn.iocoder.springboot.lab52.accountservice.service; + +/** + * 账户 Service + */ +public interface AccountService { + + /** + * 扣除余额 + * + * @param userId 用户编号 + * @param price 扣减金额 + * @throws Exception 失败时抛出异常 + */ + void reduceBalance(Long userId, Integer price) throws Exception; + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/service/AccountServiceImpl.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/service/AccountServiceImpl.java new file mode 100644 index 000000000..d63abb38a --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/java/cn/iocoder/springboot/lab52/accountservice/service/AccountServiceImpl.java @@ -0,0 +1,47 @@ +package cn.iocoder.springboot.lab52.accountservice.service; + +import cn.iocoder.springboot.lab52.accountservice.dao.AccountDao; +import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class AccountServiceImpl implements AccountService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private AccountDao accountDao; + + @Override + @Transactional // 开启新事物 + public void reduceBalance(Long userId, Integer price) throws Exception { + logger.info("[reduceBalance] 当前 XID: {}", RootContext.getXID()); + + // 检查余额 + checkBalance(userId, price); + + logger.info("[reduceBalance] 开始扣减用户 {} 余额", userId); + // 扣除余额 + int updateCount = accountDao.reduceBalance(price); + // 扣除成功 + if (updateCount == 0) { + logger.warn("[reduceBalance] 扣除用户 {} 余额失败", userId); + throw new Exception("余额不足"); + } + logger.info("[reduceBalance] 扣除用户 {} 余额成功", userId); + } + + private void checkBalance(Long userId, Integer price) throws Exception { + logger.info("[checkBalance] 检查用户 {} 余额", userId); + Integer balance = accountDao.getBalance(userId); + if (balance < price) { + logger.warn("[checkBalance] 用户 {} 余额不足,当前余额:{}", userId, balance); + throw new Exception("余额不足"); + } + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/resources/application.yaml b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/resources/application.yaml new file mode 100644 index 000000000..ea7faeaeb --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-account-service/src/main/resources/application.yaml @@ -0,0 +1,25 @@ +server: + port: 8083 + +spring: + application: + name: account-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_account?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + account-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/pom.xml b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/pom.xml new file mode 100644 index 000000000..43a785c60 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/pom.xml @@ -0,0 +1,61 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-52-seata-at-httpclient-demo-order-service + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + io.seata + seata-http + 1.1.0 + + + + + org.apache.httpcomponents + httpclient + 4.5.8 + + + + diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/OrderServiceApplication.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/OrderServiceApplication.java new file mode 100644 index 000000000..7f9ae1b5a --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/OrderServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab52.orderservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class OrderServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(OrderServiceApplication.class, args); + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/controller/OrderController.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/controller/OrderController.java new file mode 100644 index 000000000..51f4154e2 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/controller/OrderController.java @@ -0,0 +1,29 @@ +package cn.iocoder.springboot.lab52.orderservice.controller; + +import cn.iocoder.springboot.lab52.orderservice.service.OrderService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/order") +public class OrderController { + + private Logger logger = LoggerFactory.getLogger(OrderController.class); + + @Autowired + private OrderService orderService; + + @PostMapping("/create") + public Integer createOrder(@RequestParam("userId") Long userId, + @RequestParam("productId") Long productId, + @RequestParam("price") Integer price) throws Exception { + logger.info("[createOrder] 收到下单请求,用户:{}, 商品:{}, 价格:{}", userId, productId, price); + return orderService.createOrder(userId, productId, price); + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/dao/OrderDao.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/dao/OrderDao.java new file mode 100644 index 000000000..6001ee4f6 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/dao/OrderDao.java @@ -0,0 +1,23 @@ +package cn.iocoder.springboot.lab52.orderservice.dao; + +import cn.iocoder.springboot.lab53.orderservice.entity.OrderDO; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Options; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface OrderDao { + + /** + * 插入订单记录 + * + * @param order 订单 + * @return 影响记录数量 + */ + @Insert("INSERT INTO orders (user_id, product_id, pay_amount) VALUES (#{userId}, #{productId}, #{payAmount})") + @Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id") + int saveOrder(OrderDO order); + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/entity/OrderDO.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/entity/OrderDO.java new file mode 100644 index 000000000..4ff509e40 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/entity/OrderDO.java @@ -0,0 +1,56 @@ +package cn.iocoder.springboot.lab53.orderservice.entity; + +/** + * 订单实体 + */ +public class OrderDO { + + /** 订单编号 **/ + private Integer id; + + /** 用户编号 **/ + private Long userId; + + /** 产品编号 **/ + private Long productId; + + /** 支付金额 **/ + private Integer payAmount; + + public Integer getId() { + return id; + } + + public OrderDO setId(Integer id) { + this.id = id; + return this; + } + + public Long getUserId() { + return userId; + } + + public OrderDO setUserId(Long userId) { + this.userId = userId; + return this; + } + + public Long getProductId() { + return productId; + } + + public OrderDO setProductId(Long productId) { + this.productId = productId; + return this; + } + + public Integer getPayAmount() { + return payAmount; + } + + public OrderDO setPayAmount(Integer payAmount) { + this.payAmount = payAmount; + return this; + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/service/OrderService.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/service/OrderService.java new file mode 100644 index 000000000..1ca8d0103 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/service/OrderService.java @@ -0,0 +1,19 @@ +package cn.iocoder.springboot.lab52.orderservice.service; + +/** + * 订单 Service + */ +public interface OrderService { + + /** + * 创建订单 + * + * @param userId 用户编号 + * @param productId 产品编号 + * @param price 价格 + * @return 订单编号 + * @throws Exception 创建订单失败,抛出异常 + */ + Integer createOrder(Long userId, Long productId, Integer price) throws Exception; + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/service/OrderServiceImpl.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/service/OrderServiceImpl.java new file mode 100644 index 000000000..dd1d8c137 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/java/cn/iocoder/springboot/lab52/orderservice/service/OrderServiceImpl.java @@ -0,0 +1,76 @@ +package cn.iocoder.springboot.lab52.orderservice.service; + +import cn.iocoder.springboot.lab52.orderservice.dao.OrderDao; +import cn.iocoder.springboot.lab53.orderservice.entity.OrderDO; +import com.alibaba.fastjson.JSONObject; +import io.seata.core.context.RootContext; +import io.seata.integration.http.DefaultHttpExecutor; +import io.seata.spring.annotation.GlobalTransactional; +import org.apache.http.HttpResponse; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.IOException; + +@Service +public class OrderServiceImpl implements OrderService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private OrderDao orderDao; + + @Override + @GlobalTransactional + public Integer createOrder(Long userId, Long productId, Integer price) throws Exception { + Integer amount = 1; // 购买数量,暂时设置为 1。 + + logger.info("[createOrder] 当前 XID: {}", RootContext.getXID()); + + // 扣减库存 + this.reduceStock(productId, amount); + + // 扣减余额 + this.reduceBalance(userId, price); + + // 保存订单 + OrderDO order = new OrderDO().setUserId(userId).setProductId(productId).setPayAmount(amount * price); + orderDao.saveOrder(order); + logger.info("[createOrder] 保存订单: {}", order.getId()); + + // 返回订单编号 + return order.getId(); + } + + private void reduceStock(Long productId, Integer amount) throws IOException { + // 参数拼接 + JSONObject params = new JSONObject().fluentPut("productId", String.valueOf(productId)) + .fluentPut("amount", String.valueOf(amount)); + // 执行调用 + HttpResponse response = DefaultHttpExecutor.getInstance().executePost("http://127.0.0.1:8082", "/product/reduce-stock", + params, HttpResponse.class); + // 解析结果 + Boolean success = Boolean.valueOf(EntityUtils.toString(response.getEntity())); + if (!success) { + throw new RuntimeException("扣除库存失败"); + } + } + + private void reduceBalance(Long userId, Integer price) throws IOException { + // 参数拼接 + JSONObject params = new JSONObject().fluentPut("userId", String.valueOf(userId)) + .fluentPut("price", String.valueOf(price)); + // 执行调用 + HttpResponse response = DefaultHttpExecutor.getInstance().executePost("http://127.0.0.1:8083", "/account/reduce-balance", + params, HttpResponse.class); + // 解析结果 + Boolean success = Boolean.valueOf(EntityUtils.toString(response.getEntity())); + if (!success) { + throw new RuntimeException("扣除余额失败"); + } + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/resources/application.yaml b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/resources/application.yaml new file mode 100644 index 000000000..204bf93c4 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-order-service/src/main/resources/application.yaml @@ -0,0 +1,25 @@ +server: + port: 8081 # 端口 + +spring: + application: + name: order-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + order-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/pom.xml b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/pom.xml new file mode 100644 index 000000000..e9260443a --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/pom.xml @@ -0,0 +1,55 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-52-seata-at-httpclient-demo-product-service + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + io.seata + seata-http + 1.1.0 + + + + + diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/ProductServiceApplication.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/ProductServiceApplication.java new file mode 100644 index 000000000..4666d4bf9 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/ProductServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab52.productservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProductServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(ProductServiceApplication.class, args); + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/controller/ProductController.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/controller/ProductController.java new file mode 100644 index 000000000..9935006ad --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/controller/ProductController.java @@ -0,0 +1,33 @@ +package cn.iocoder.springboot.lab52.productservice.controller; + +import cn.iocoder.springboot.lab52.productservice.dto.ProductReduceStockDTO; +import cn.iocoder.springboot.lab52.productservice.service.ProductService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/product") +public class ProductController { + + private Logger logger = LoggerFactory.getLogger(ProductController.class); + + @Autowired + private ProductService productService; + + @PostMapping("/reduce-stock") + public Boolean reduceStock(@RequestBody ProductReduceStockDTO productReduceStockDTO) { + logger.info("[reduceStock] 收到减少库存请求, 商品:{}, 价格:{}", productReduceStockDTO.getProductId(), + productReduceStockDTO.getAmount()); + try { + productService.reduceStock(productReduceStockDTO.getProductId(), productReduceStockDTO.getAmount()); + // 正常扣除库存,返回 true + return true; + } catch (Exception e) { + // 失败扣除库存,返回 false + return false; + } + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/dao/ProductDao.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/dao/ProductDao.java new file mode 100644 index 000000000..2b8ad712f --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/dao/ProductDao.java @@ -0,0 +1,33 @@ +package cn.iocoder.springboot.lab52.productservice.dao; + + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface ProductDao { + + /** + * 获取库存 + * + * @param productId 商品编号 + * @return 库存 + */ + @Select("SELECT stock FROM product WHERE id = #{productId}") + Integer getStock(@Param("productId") Long productId); + + /** + * 扣减库存 + * + * @param productId 商品编号 + * @param amount 扣减数量 + * @return 影响记录行数 + */ + @Update("UPDATE product SET stock = stock - #{amount} WHERE id = #{productId} AND stock >= #{amount}") + int reduceStock(@Param("productId") Long productId, @Param("amount") Integer amount); + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/dto/ProductReduceStockDTO.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/dto/ProductReduceStockDTO.java new file mode 100644 index 000000000..4d195de11 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/dto/ProductReduceStockDTO.java @@ -0,0 +1,35 @@ +package cn.iocoder.springboot.lab52.productservice.dto; + +/** + * 商品减少库存 DTO + */ +public class ProductReduceStockDTO { + + /** + * 商品编号 + */ + private Long productId; + /** + * 数量 + */ + private Integer amount; + + public Long getProductId() { + return productId; + } + + public ProductReduceStockDTO setProductId(Long productId) { + this.productId = productId; + return this; + } + + public Integer getAmount() { + return amount; + } + + public ProductReduceStockDTO setAmount(Integer amount) { + this.amount = amount; + return this; + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/service/ProductService.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/service/ProductService.java new file mode 100644 index 000000000..388d408ae --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/service/ProductService.java @@ -0,0 +1,17 @@ +package cn.iocoder.springboot.lab52.productservice.service; + +/** + * 商品 Service + */ +public interface ProductService { + + /** + * 扣减库存 + * + * @param productId 商品 ID + * @param amount 扣减数量 + * @throws Exception 扣减失败时抛出异常 + */ + void reduceStock(Long productId, Integer amount) throws Exception; + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/service/ProductServiceImpl.java b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/service/ProductServiceImpl.java new file mode 100644 index 000000000..16899ed17 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/java/cn/iocoder/springboot/lab52/productservice/service/ProductServiceImpl.java @@ -0,0 +1,48 @@ +package cn.iocoder.springboot.lab52.productservice.service; + +import cn.iocoder.springboot.lab52.productservice.dao.ProductDao; +import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class ProductServiceImpl implements ProductService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ProductDao productDao; + + @Override + @Transactional // 开启事物 + public void reduceStock(Long productId, Integer amount) throws Exception { + logger.info("[reduceStock] 当前 XID: {}", RootContext.getXID()); + + // 检查库存 + checkStock(productId, amount); + + logger.info("[reduceStock] 开始扣减 {} 库存", productId); + // 扣减库存 + int updateCount = productDao.reduceStock(productId, amount); + // 扣除成功 + if (updateCount == 0) { + logger.warn("[reduceStock] 扣除 {} 库存失败", productId); + throw new Exception("库存不足"); + } + // 扣除失败 + logger.info("[reduceStock] 扣除 {} 库存成功", productId); + } + + private void checkStock(Long productId, Integer requiredAmount) throws Exception { + logger.info("[checkStock] 检查 {} 库存", productId); + Integer stock = productDao.getStock(productId); + if (stock < requiredAmount) { + logger.warn("[checkStock] {} 库存不足,当前库存: {}", productId, stock); + throw new Exception("库存不足"); + } + } + +} diff --git a/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/resources/application.yaml b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/resources/application.yaml new file mode 100644 index 000000000..ac63d302b --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/lab-52-seata-at-httpclient-demo-product-service/src/main/resources/application.yaml @@ -0,0 +1,25 @@ +server: + port: 8082 # 端口 + +spring: + application: + name: product-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + product-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/lab-52/lab-52-seata-at-httpclient-demo/pom.xml b/lab-52/lab-52-seata-at-httpclient-demo/pom.xml new file mode 100644 index 000000000..01b2c5d88 --- /dev/null +++ b/lab-52/lab-52-seata-at-httpclient-demo/pom.xml @@ -0,0 +1,20 @@ + + + + lab-52 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-52-seata-at-httpclient-demo + + + lab-52-seata-at-httpclient-demo-order-service + lab-52-seata-at-httpclient-demo-product-service + lab-52-seata-at-httpclient-demo-account-service + + + diff --git a/lab-52/pom.xml b/lab-52/pom.xml new file mode 100644 index 000000000..e3525458c --- /dev/null +++ b/lab-52/pom.xml @@ -0,0 +1,20 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-52 + pom + + + lab-52-multiple-datasource + lab-52-seata-at-httpclient-demo + + + diff --git "a/lab-52/\343\200\212\350\212\213\351\201\223 Spring Boot \345\210\206\345\270\203\345\274\217\344\272\213\345\212\241 Seata \345\205\245\351\227\250\343\200\213.md" "b/lab-52/\343\200\212\350\212\213\351\201\223 Spring Boot \345\210\206\345\270\203\345\274\217\344\272\213\345\212\241 Seata \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..0aa93ffdf --- /dev/null +++ "b/lab-52/\343\200\212\350\212\213\351\201\223 Spring Boot \345\210\206\345\270\203\345\274\217\344\272\213\345\212\241 Seata \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-53/lab-53-seata-at-dubbo-demo/data.sql b/lab-53/lab-53-seata-at-dubbo-demo/data.sql new file mode 100644 index 000000000..3b0ce0828 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/data.sql @@ -0,0 +1,82 @@ +# Order +DROP DATABASE IF EXISTS seata_order; +CREATE DATABASE seata_order; + +CREATE TABLE seata_order.orders +( + id INT(11) NOT NULL AUTO_INCREMENT, + user_id INT(11) DEFAULT NULL, + product_id INT(11) DEFAULT NULL, + pay_amount DECIMAL(10, 0) DEFAULT NULL, + add_time DATETIME DEFAULT CURRENT_TIMESTAMP, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +CREATE TABLE seata_order.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +# Product +DROP DATABASE IF EXISTS seata_product; +CREATE DATABASE seata_product; + +CREATE TABLE seata_product.product +( + id INT(11) NOT NULL AUTO_INCREMENT, + stock INT(11) DEFAULT NULL, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; +INSERT INTO seata_product.product (id, stock) VALUES (1, 10); # 插入一条产品的库存 + +CREATE TABLE seata_product.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +# Account +DROP DATABASE IF EXISTS seata_account; +CREATE DATABASE seata_account; + +CREATE TABLE seata_account.account +( + id INT(11) NOT NULL AUTO_INCREMENT, + balance DOUBLE DEFAULT NULL, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +CREATE TABLE seata_account.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; +INSERT INTO seata_account.account (id, balance) VALUES (1, 10); diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service-api/pom.xml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service-api/pom.xml new file mode 100644 index 000000000..f8deb4b0a --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service-api/pom.xml @@ -0,0 +1,14 @@ + + + + lab-53-seata-at-dubbo-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-53-seata-at-dubbo-demo-account-service-api + + diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service-api/src/main/java/cn/iocoder/springboot/lab53/accountservice/api/AccountService.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service-api/src/main/java/cn/iocoder/springboot/lab53/accountservice/api/AccountService.java new file mode 100644 index 000000000..178aa78ef --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service-api/src/main/java/cn/iocoder/springboot/lab53/accountservice/api/AccountService.java @@ -0,0 +1,17 @@ +package cn.iocoder.springboot.lab53.accountservice.api; + +/** + * 账户 Service + */ +public interface AccountService { + + /** + * 扣除余额 + * + * @param userId 用户编号 + * @param price 扣减金额 + * @throws Exception 失败时抛出异常 + */ + void reduceBalance(Long userId, Integer price) throws Exception; + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/pom.xml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/pom.xml new file mode 100644 index 000000000..f8ee16f95 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/pom.xml @@ -0,0 +1,73 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-53-seata-at-dubbo-demo-account-service + + + + cn.iocoder.springboot.labs + lab-53-seata-at-dubbo-demo-account-service-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + + org.apache.dubbo + dubbo + 2.7.4.1 + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.4.1 + + + + + com.alibaba + dubbo-registry-nacos + 2.7.6 + + + + diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springboot/lab53/accountservice/AccountServiceApplication.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springboot/lab53/accountservice/AccountServiceApplication.java new file mode 100644 index 000000000..91ce94eb1 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springboot/lab53/accountservice/AccountServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab53.accountservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AccountServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(AccountServiceApplication.class, args); + } + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springboot/lab53/accountservice/dao/AccountDao.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springboot/lab53/accountservice/dao/AccountDao.java new file mode 100644 index 000000000..3d800a4e9 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springboot/lab53/accountservice/dao/AccountDao.java @@ -0,0 +1,32 @@ +package cn.iocoder.springboot.lab53.accountservice.dao; + + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface AccountDao { + + /** + * 获取账户余额 + * + * @param userId 用户 ID + * @return 账户余额 + */ + @Select("SELECT balance FROM account WHERE id = #{userId}") + Integer getBalance(@Param("userId") Long userId); + + /** + * 扣减余额 + * + * @param price 需要扣减的数目 + * @return 影响记录行数 + */ + @Update("UPDATE account SET balance = balance - #{price} WHERE id = 1 AND balance >= ${price}") + int reduceBalance(@Param("price") Integer price); + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springboot/lab53/accountservice/service/AccountServiceImpl.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springboot/lab53/accountservice/service/AccountServiceImpl.java new file mode 100644 index 000000000..8c6a09d36 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springboot/lab53/accountservice/service/AccountServiceImpl.java @@ -0,0 +1,47 @@ +package cn.iocoder.springboot.lab53.accountservice.service; + +import cn.iocoder.springboot.lab53.accountservice.api.AccountService; +import cn.iocoder.springboot.lab53.accountservice.dao.AccountDao; +import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@org.apache.dubbo.config.annotation.Service +public class AccountServiceImpl implements AccountService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private AccountDao accountDao; + + @Override + @Transactional // 开启新事物 + public void reduceBalance(Long userId, Integer price) throws Exception { + logger.info("[reduceBalance] 当前 XID: {}", RootContext.getXID()); + + // 检查余额 + checkBalance(userId, price); + + logger.info("[reduceBalance] 开始扣减用户 {} 余额", userId); + // 扣除余额 + int updateCount = accountDao.reduceBalance(price); + // 扣除成功 + if (updateCount == 0) { + logger.warn("[reduceBalance] 扣除用户 {} 余额失败", userId); + throw new Exception("余额不足"); + } + logger.info("[reduceBalance] 扣除用户 {} 余额成功", userId); + } + + private void checkBalance(Long userId, Integer price) throws Exception { + logger.info("[checkBalance] 检查用户 {} 余额", userId); + Integer balance = accountDao.getBalance(userId); + if (balance < price) { + logger.warn("[checkBalance] 用户 {} 余额不足,当前余额:{}", userId, balance); + throw new Exception("余额不足"); + } + } + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/resources/application-file.yaml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/resources/application-file.yaml new file mode 100644 index 000000000..85d719706 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/resources/application-file.yaml @@ -0,0 +1,38 @@ +spring: + application: + name: account-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_account?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 应用配置 + application: + name: ${spring.application.name} # 应用名 + # Dubbo 注册中心配 + registry: + address: nacos://127.0.0.1:8848 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springboot.lab53.accountservice.service + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + account-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/resources/application.yaml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/resources/application.yaml new file mode 100644 index 000000000..80bf8785c --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-account-service/src/main/resources/application.yaml @@ -0,0 +1,42 @@ +spring: + application: + name: account-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_account?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 应用配置 + application: + name: ${spring.application.name} # 应用名 + # Dubbo 注册中心配 + registry: + address: nacos://127.0.0.1:8848 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springboot.lab53.accountservice.service + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # Seata 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + account-service-group: default + # Seata 注册中心配置项,对应 RegistryProperties 类 + registry: + type: nacos # 注册中心类型,默认为 file + nacos: + cluster: default # 使用的 Seata 分组 + namespace: # Nacos 命名空间 + serverAddr: localhost # Nacos 服务地址 diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service-api/pom.xml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service-api/pom.xml new file mode 100644 index 000000000..ec9ccab36 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service-api/pom.xml @@ -0,0 +1,14 @@ + + + + lab-53-seata-at-dubbo-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-53-seata-at-dubbo-demo-order-service-api + + diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service-api/src/main/java/cn/iocoder/springboot/lab53/orderservice/api/OrderService.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service-api/src/main/java/cn/iocoder/springboot/lab53/orderservice/api/OrderService.java new file mode 100644 index 000000000..34cb0eb8b --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service-api/src/main/java/cn/iocoder/springboot/lab53/orderservice/api/OrderService.java @@ -0,0 +1,19 @@ +package cn.iocoder.springboot.lab53.orderservice.api; + +/** + * 订单 Service + */ +public interface OrderService { + + /** + * 创建订单 + * + * @param userId 用户编号 + * @param productId 产品编号 + * @param price 价格 + * @return 订单编号 + * @throws Exception 创建订单失败,抛出异常 + */ + Integer createOrder(Long userId, Long productId, Integer price) throws Exception; + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/pom.xml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/pom.xml new file mode 100644 index 000000000..766f09709 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/pom.xml @@ -0,0 +1,83 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-53-seata-at-dubbo-demo-order-service + + + + cn.iocoder.springboot.labs + lab-53-seata-at-dubbo-demo-order-service-api + 1.0-SNAPSHOT + + + cn.iocoder.springboot.labs + lab-53-seata-at-dubbo-demo-account-service-api + 1.0-SNAPSHOT + + + cn.iocoder.springboot.labs + lab-53-seata-at-dubbo-demo-product-service-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + + org.apache.dubbo + dubbo + 2.7.4.1 + + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.4.1 + + + + com.alibaba + dubbo-registry-nacos + 2.7.6 + + + + diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/OrderServiceApplication.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/OrderServiceApplication.java new file mode 100644 index 000000000..bf9b2ddf4 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/OrderServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab53.orderservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class OrderServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(OrderServiceApplication.class, args); + } + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/controller/OrderController.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/controller/OrderController.java new file mode 100644 index 000000000..ccbef5c6f --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/controller/OrderController.java @@ -0,0 +1,29 @@ +package cn.iocoder.springboot.lab53.orderservice.controller; + +import cn.iocoder.springboot.lab53.orderservice.api.OrderService; +import org.apache.dubbo.config.annotation.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/order") +public class OrderController { + + private Logger logger = LoggerFactory.getLogger(OrderController.class); + + @Reference + private OrderService orderService; + + @PostMapping("/create") + public Integer createOrder(@RequestParam("userId") Long userId, + @RequestParam("productId") Long productId, + @RequestParam("price") Integer price) throws Exception { + logger.info("[createOrder] 收到下单请求,用户:{}, 商品:{}, 价格:{}", userId, productId, price); + return orderService.createOrder(userId, productId, price); + } + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/dao/OrderDao.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/dao/OrderDao.java new file mode 100644 index 000000000..2c0518bf7 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/dao/OrderDao.java @@ -0,0 +1,23 @@ +package cn.iocoder.springboot.lab53.orderservice.dao; + +import cn.iocoder.springboot.lab53.orderservice.entity.OrderDO; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Options; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface OrderDao { + + /** + * 插入订单记录 + * + * @param order 订单 + * @return 影响记录数量 + */ + @Insert("INSERT INTO orders (user_id, product_id, pay_amount) VALUES (#{userId}, #{productId}, #{payAmount})") + @Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id") + int saveOrder(OrderDO order); + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/entity/OrderDO.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/entity/OrderDO.java new file mode 100644 index 000000000..4ff509e40 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/entity/OrderDO.java @@ -0,0 +1,56 @@ +package cn.iocoder.springboot.lab53.orderservice.entity; + +/** + * 订单实体 + */ +public class OrderDO { + + /** 订单编号 **/ + private Integer id; + + /** 用户编号 **/ + private Long userId; + + /** 产品编号 **/ + private Long productId; + + /** 支付金额 **/ + private Integer payAmount; + + public Integer getId() { + return id; + } + + public OrderDO setId(Integer id) { + this.id = id; + return this; + } + + public Long getUserId() { + return userId; + } + + public OrderDO setUserId(Long userId) { + this.userId = userId; + return this; + } + + public Long getProductId() { + return productId; + } + + public OrderDO setProductId(Long productId) { + this.productId = productId; + return this; + } + + public Integer getPayAmount() { + return payAmount; + } + + public OrderDO setPayAmount(Integer payAmount) { + this.payAmount = payAmount; + return this; + } + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/service/OrderServiceImpl.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/service/OrderServiceImpl.java new file mode 100644 index 000000000..ddec43a92 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springboot/lab53/orderservice/service/OrderServiceImpl.java @@ -0,0 +1,50 @@ +package cn.iocoder.springboot.lab53.orderservice.service; + +import cn.iocoder.springboot.lab53.accountservice.api.AccountService; +import cn.iocoder.springboot.lab53.orderservice.api.OrderService; +import cn.iocoder.springboot.lab53.orderservice.dao.OrderDao; +import cn.iocoder.springboot.lab53.orderservice.entity.OrderDO; +import cn.iocoder.springboot.lab53.productservice.api.ProductService; +import io.seata.core.context.RootContext; +import io.seata.spring.annotation.GlobalTransactional; +import org.apache.dubbo.config.annotation.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +@org.apache.dubbo.config.annotation.Service +public class OrderServiceImpl implements OrderService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private OrderDao orderDao; + + @Reference + private AccountService accountService; + @Reference + private ProductService productService; + + @Override + @GlobalTransactional + public Integer createOrder(Long userId, Long productId, Integer price) throws Exception { + Integer amount = 1; // 购买数量,暂时设置为 1。 + + logger.info("[createOrder] 当前 XID: {}", RootContext.getXID()); + + // 扣减库存 + productService.reduceStock(productId, amount); + + // 扣减余额 + accountService.reduceBalance(userId, price); + + // 保存订单 + OrderDO order = new OrderDO().setUserId(userId).setProductId(productId).setPayAmount(amount * price); + orderDao.saveOrder(order); + logger.info("[createOrder] 保存订单: {}", order.getId()); + + // 返回订单编号 + return order.getId(); + } + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/resources/application-file.yaml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/resources/application-file.yaml new file mode 100644 index 000000000..b86163814 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/resources/application-file.yaml @@ -0,0 +1,41 @@ +server: + port: 8081 # 端口 + +spring: + application: + name: order-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 应用配置 + application: + name: ${spring.application.name} # 应用名 + # Dubbo 注册中心配 + registry: + address: nacos://127.0.0.1:8848 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springboot.lab53.orderservice.service + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + order-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/resources/application.yaml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/resources/application.yaml new file mode 100644 index 000000000..9ff3e7c8b --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-order-service/src/main/resources/application.yaml @@ -0,0 +1,45 @@ +server: + port: 8081 # 端口 + +spring: + application: + name: order-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 应用配置 + application: + name: ${spring.application.name} # 应用名 + # Dubbo 注册中心配 + registry: + address: nacos://127.0.0.1:8848 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springboot.lab53.orderservice.service + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # Seata 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + order-service-group: default + # Seata 注册中心配置项,对应 RegistryProperties 类 + registry: + type: nacos # 注册中心类型,默认为 file + nacos: + cluster: default # 使用的 Seata 分组 + namespace: # Nacos 命名空间 + serverAddr: localhost # Nacos 服务地址 diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service-api/pom.xml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service-api/pom.xml new file mode 100644 index 000000000..d242cb725 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service-api/pom.xml @@ -0,0 +1,14 @@ + + + + lab-53-seata-at-dubbo-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-53-seata-at-dubbo-demo-product-service-api + + diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service-api/src/main/java/cn/iocoder/springboot/lab53/productservice/api/ProductService.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service-api/src/main/java/cn/iocoder/springboot/lab53/productservice/api/ProductService.java new file mode 100644 index 000000000..86562f6e8 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service-api/src/main/java/cn/iocoder/springboot/lab53/productservice/api/ProductService.java @@ -0,0 +1,17 @@ +package cn.iocoder.springboot.lab53.productservice.api; + +/** + * 商品 Service + */ +public interface ProductService { + + /** + * 扣减库存 + * + * @param productId 商品 ID + * @param amount 扣减数量 + * @throws Exception 扣减失败时抛出异常 + */ + void reduceStock(Long productId, Integer amount) throws Exception; + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/pom.xml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/pom.xml new file mode 100644 index 000000000..05435d01a --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/pom.xml @@ -0,0 +1,73 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-53-seata-at-dubbo-demo-product-service + + + + cn.iocoder.springboot.labs + lab-53-seata-at-dubbo-demo-product-service-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + + org.apache.dubbo + dubbo + 2.7.4.1 + + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.4.1 + + + + com.alibaba + dubbo-registry-nacos + 2.7.6 + + + + diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springboot/lab53/productservice/ProductServiceApplication.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springboot/lab53/productservice/ProductServiceApplication.java new file mode 100644 index 000000000..0f286bb1c --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springboot/lab53/productservice/ProductServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab53.productservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProductServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(ProductServiceApplication.class, args); + } + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springboot/lab53/productservice/dao/ProductDao.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springboot/lab53/productservice/dao/ProductDao.java new file mode 100644 index 000000000..df404727c --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springboot/lab53/productservice/dao/ProductDao.java @@ -0,0 +1,33 @@ +package cn.iocoder.springboot.lab53.productservice.dao; + + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface ProductDao { + + /** + * 获取库存 + * + * @param productId 商品编号 + * @return 库存 + */ + @Select("SELECT stock FROM product WHERE id = #{productId}") + Integer getStock(@Param("productId") Long productId); + + /** + * 扣减库存 + * + * @param productId 商品编号 + * @param amount 扣减数量 + * @return 影响记录行数 + */ + @Update("UPDATE product SET stock = stock - #{amount} WHERE id = #{productId} AND stock >= #{amount}") + int reduceStock(@Param("productId") Long productId, @Param("amount") Integer amount); + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springboot/lab53/productservice/service/ProductServiceImpl.java b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springboot/lab53/productservice/service/ProductServiceImpl.java new file mode 100644 index 000000000..3304a6d03 --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springboot/lab53/productservice/service/ProductServiceImpl.java @@ -0,0 +1,48 @@ +package cn.iocoder.springboot.lab53.productservice.service; + +import cn.iocoder.springboot.lab53.productservice.dao.ProductDao; +import cn.iocoder.springboot.lab53.productservice.api.ProductService; +import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@org.apache.dubbo.config.annotation.Service +public class ProductServiceImpl implements ProductService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ProductDao productDao; + + @Override + @Transactional // 开启新事物 + public void reduceStock(Long productId, Integer amount) throws Exception { + logger.info("[reduceStock] 当前 XID: {}", RootContext.getXID()); + + // 检查库存 + checkStock(productId, amount); + + logger.info("[reduceStock] 开始扣减 {} 库存", productId); + // 扣减库存 + int updateCount = productDao.reduceStock(productId, amount); + // 扣除成功 + if (updateCount == 0) { + logger.warn("[reduceStock] 扣除 {} 库存失败", productId); + throw new Exception("库存不足"); + } + // 扣除失败 + logger.info("[reduceStock] 扣除 {} 库存成功", productId); + } + + private void checkStock(Long productId, Integer requiredAmount) throws Exception { + logger.info("[checkStock] 检查 {} 库存", productId); + Integer stock = productDao.getStock(productId); + if (stock < requiredAmount) { + logger.warn("[checkStock] {} 库存不足,当前库存: {}", productId, stock); + throw new Exception("库存不足"); + } + } + +} diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/resources/application-file.yaml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/resources/application-file.yaml new file mode 100644 index 000000000..63068ae2f --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/resources/application-file.yaml @@ -0,0 +1,38 @@ +spring: + application: + name: product-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 应用配置 + application: + name: ${spring.application.name} # 应用名 + # Dubbo 注册中心配 + registry: + address: nacos://127.0.0.1:8848 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springboot.lab53.productservice.service + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + product-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/resources/application.yaml b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/resources/application.yaml new file mode 100644 index 000000000..614d80a6d --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/lab-53-seata-at-dubbo-demo-product-service/src/main/resources/application.yaml @@ -0,0 +1,42 @@ +spring: + application: + name: product-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 应用配置 + application: + name: ${spring.application.name} # 应用名 + # Dubbo 注册中心配 + registry: + address: nacos://127.0.0.1:8848 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springboot.lab53.productservice.service + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # Seata 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + product-service-group: default + # Seata 注册中心配置项,对应 RegistryProperties 类 + registry: + type: nacos # 注册中心类型,默认为 file + nacos: + cluster: default # 使用的 Seata 分组 + namespace: # Nacos 命名空间 + serverAddr: localhost # Nacos 服务地址 diff --git a/lab-53/lab-53-seata-at-dubbo-demo/pom.xml b/lab-53/lab-53-seata-at-dubbo-demo/pom.xml new file mode 100644 index 000000000..e31344ded --- /dev/null +++ b/lab-53/lab-53-seata-at-dubbo-demo/pom.xml @@ -0,0 +1,24 @@ + + + + lab-53 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-53-seata-at-dubbo-demo + pom + + + lab-53-seata-at-dubbo-demo-order-service-api + lab-53-seata-at-dubbo-demo-order-service + lab-53-seata-at-dubbo-demo-account-service-api + lab-53-seata-at-dubbo-demo-account-service + lab-53-seata-at-dubbo-demo-product-service-api + lab-53-seata-at-dubbo-demo-product-service + + + diff --git a/lab-53/pom.xml b/lab-53/pom.xml new file mode 100644 index 000000000..6148e803f --- /dev/null +++ b/lab-53/pom.xml @@ -0,0 +1,20 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-53 + pom + + + lab-53-seata-at-dubbo-demo + + + + diff --git "a/lab-53/\343\200\212Dubbo \345\210\206\345\270\203\345\274\217\344\272\213\345\212\241 Seata \345\205\245\351\227\250\343\200\213.md" "b/lab-53/\343\200\212Dubbo \345\210\206\345\270\203\345\274\217\344\272\213\345\212\241 Seata \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..1f82e7340 --- /dev/null +++ "b/lab-53/\343\200\212Dubbo \345\210\206\345\270\203\345\274\217\344\272\213\345\212\241 Seata \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/lab-54/lab-54-demo/pom.xml b/lab-54/lab-54-demo/pom.xml new file mode 100644 index 000000000..de28bd64c --- /dev/null +++ b/lab-54/lab-54-demo/pom.xml @@ -0,0 +1,23 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.2.RELEASE + + + 4.0.0 + + lab-54-demo + + + + + org.springframework.boot + spring-boot-starter-web + + + + diff --git a/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/DemoApplication.java b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/DemoApplication.java new file mode 100644 index 000000000..d93718d94 --- /dev/null +++ b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/DemoApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springboot.lab54.eventdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; + +@SpringBootApplication +@EnableAsync // 开启 Spring 异步的功能 +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } + +} diff --git a/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/controller/DemoController.java b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/controller/DemoController.java new file mode 100644 index 000000000..64542d2ba --- /dev/null +++ b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/controller/DemoController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springboot.lab54.eventdemo.controller; + +import cn.iocoder.springboot.lab54.eventdemo.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + @Autowired + private UserService userService; + + @GetMapping("/register") + public String register(String username) { + userService.register(username); + return "success"; + } + +} diff --git a/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/event/UserRegisterEvent.java b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..4f40808be --- /dev/null +++ b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/event/UserRegisterEvent.java @@ -0,0 +1,28 @@ +package cn.iocoder.springboot.lab54.eventdemo.event; + +import org.springframework.context.ApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends ApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent(Object source) { + super(source); + } + + public UserRegisterEvent(Object source, String username) { + super(source); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/service/CouponService.java b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/service/CouponService.java new file mode 100644 index 000000000..1152dcc07 --- /dev/null +++ b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/service/CouponService.java @@ -0,0 +1,19 @@ +package cn.iocoder.springboot.lab54.eventdemo.service; + +import cn.iocoder.springboot.lab54.eventdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Service; + +@Service +public class CouponService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @EventListener + public void addCoupon(UserRegisterEvent event) { + logger.info("[addCoupon][给用户({}) 发放优惠劵]", event.getUsername()); + } + +} diff --git a/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/service/EmailService.java b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/service/EmailService.java new file mode 100644 index 000000000..eb3031ea0 --- /dev/null +++ b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/service/EmailService.java @@ -0,0 +1,21 @@ +package cn.iocoder.springboot.lab54.eventdemo.service; + +import cn.iocoder.springboot.lab54.eventdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +@Service +public class EmailService implements ApplicationListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + @Async + public void onApplicationEvent(UserRegisterEvent event) { + logger.info("[onApplicationEvent][给用户({}) 发送邮件]", event.getUsername()); + } + +} diff --git a/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/service/UserService.java b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/service/UserService.java new file mode 100644 index 000000000..1abf195b1 --- /dev/null +++ b/lab-54/lab-54-demo/src/main/java/cn/iocoder/springboot/lab54/eventdemo/service/UserService.java @@ -0,0 +1,30 @@ +package cn.iocoder.springboot.lab54.eventdemo.service; + +import cn.iocoder.springboot.lab54.eventdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.stereotype.Service; + +@Service +public class UserService implements ApplicationEventPublisherAware { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + private ApplicationEventPublisher applicationEventPublisher; + + @Override + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + this.applicationEventPublisher = applicationEventPublisher; + } + + public void register(String username) { + // ... 执行注册逻辑 + logger.info("[register][执行用户({}) 的注册逻辑]", username); + + // ... 发布 + applicationEventPublisher.publishEvent(new UserRegisterEvent(this, username)); + } + +} diff --git a/lab-54/pom.xml b/lab-54/pom.xml new file mode 100644 index 000000000..6d38dced5 --- /dev/null +++ b/lab-54/pom.xml @@ -0,0 +1,19 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + lab-54 + pom + + lab-54-demo + + + + diff --git "a/lab-54/\343\200\212\350\212\213\351\201\223 Spring Boot \344\272\213\344\273\266\346\234\272\345\210\266 Event \345\205\245\351\227\250\343\200\213.md" "b/lab-54/\343\200\212\350\212\213\351\201\223 Spring Boot \344\272\213\344\273\266\346\234\272\345\210\266 Event \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..4c4e4d65e --- /dev/null +++ "b/lab-54/\343\200\212\350\212\213\351\201\223 Spring Boot \344\272\213\344\273\266\346\234\272\345\210\266 Event \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git "a/labx-01/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\263\250\345\206\214\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" "b/labx-01/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\263\250\345\206\214\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..1ff848c95 --- /dev/null +++ "b/labx-01/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\263\250\345\206\214\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-02/labx-02-scn-ribbon-demo01-consumer/pom.xml b/labx-02/labx-02-scn-ribbon-demo01-consumer/pom.xml index d04e05d4b..89cbbab05 100644 --- a/labx-02/labx-02-scn-ribbon-demo01-consumer/pom.xml +++ b/labx-02/labx-02-scn-ribbon-demo01-consumer/pom.xml @@ -3,7 +3,7 @@ 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"> - labx-01 + labx-02 cn.iocoder.springboot.labs 1.0-SNAPSHOT diff --git a/labx-02/labx-02-scn-ribbon-demo01-provider/pom.xml b/labx-02/labx-02-scn-ribbon-demo01-provider/pom.xml index 480e0ee85..e20609af2 100644 --- a/labx-02/labx-02-scn-ribbon-demo01-provider/pom.xml +++ b/labx-02/labx-02-scn-ribbon-demo01-provider/pom.xml @@ -3,7 +3,7 @@ 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"> - labx-01 + labx-02 cn.iocoder.springboot.labs 1.0-SNAPSHOT diff --git a/labx-02/labx-02-scn-ribbon-demo01-provider/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/provider/DemoProviderApplication.java b/labx-02/labx-02-scn-ribbon-demo01-provider/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/provider/DemoProviderApplication.java index 46698510e..0e523abc0 100644 --- a/labx-02/labx-02-scn-ribbon-demo01-provider/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/provider/DemoProviderApplication.java +++ b/labx-02/labx-02-scn-ribbon-demo01-provider/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/provider/DemoProviderApplication.java @@ -1,9 +1,10 @@ package cn.iocoder.springcloudnetflix.labx02.ribbondemo.provider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -17,11 +18,19 @@ public static void main(String[] args) { @RestController static class TestController { + private Logger logger = LoggerFactory.getLogger(TestController.class); + @Value("${server.port}") private Integer serverPort; @GetMapping("/echo") - public String echo(String name) { + public String echo(String name) throws InterruptedException { + // 模拟执行 100ms 时长。方便后续我们测试请求超时 + Thread.sleep(100L); + + // 记录被调用的日志 + logger.info("[echo][被调用啦 name({})]", name); + return serverPort + "-provider:" + name; } diff --git a/labx-02/labx-02-scn-ribbon-demo02A-consumer/pom.xml b/labx-02/labx-02-scn-ribbon-demo02A-consumer/pom.xml index f5b38e292..f8e7d87b3 100644 --- a/labx-02/labx-02-scn-ribbon-demo02A-consumer/pom.xml +++ b/labx-02/labx-02-scn-ribbon-demo02A-consumer/pom.xml @@ -3,7 +3,7 @@ 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"> - labx-01 + labx-02 cn.iocoder.springboot.labs 1.0-SNAPSHOT diff --git a/labx-02/labx-02-scn-ribbon-demo02A-consumer/src/main/resources/application.yaml b/labx-02/labx-02-scn-ribbon-demo02A-consumer/src/main/resources/application.yaml index 27eb5d0a8..93819e91e 100644 --- a/labx-02/labx-02-scn-ribbon-demo02A-consumer/src/main/resources/application.yaml +++ b/labx-02/labx-02-scn-ribbon-demo02A-consumer/src/main/resources/application.yaml @@ -11,6 +11,8 @@ server: port: 28080 # 服务器端口。默认为 8080 # 设置 Ribbon 客户端的自定义配置 +#ribbon: +# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule demo-provider: ribbon: - NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule + NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则全类名 diff --git a/labx-02/labx-02-scn-ribbon-demo02B-consumer/pom.xml b/labx-02/labx-02-scn-ribbon-demo02B-consumer/pom.xml new file mode 100644 index 000000000..e44fe281d --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo02B-consumer/pom.xml @@ -0,0 +1,64 @@ + + + + labx-02 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-02-scn-ribbon-demo02B-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java b/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..f11871669 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,72 @@ +package cn.iocoder.springcloudnetflix.labx02.ribbondemo.consumer; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + + @Configuration + public class RestTemplateConfiguration { + + @Bean + @LoadBalanced + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + } + + @RestController + static class TestController { + + @Autowired + private RestTemplate restTemplate; + @Autowired + private LoadBalancerClient loadBalancerClient; + + @GetMapping("/hello") + public String hello(String name) { + // 获得服务 `demo-provider` 的一个实例 + ServiceInstance instance = loadBalancerClient.choose("demo-provider"); + // 发起调用 + String targetUrl = instance.getUri() + "/echo?name=" + name; + String response = restTemplate.getForObject(targetUrl, String.class); + // 返回结果 + return "consumer:" + response; + } + + @GetMapping("/hello02") + public String hello02(String name) { + // 直接使用 RestTemplate 调用服务 `demo-provider` + String targetUrl = "http://demo-provider/echo?name=" + name; + String response = restTemplate.getForObject(targetUrl, String.class); + // 返回结果 + return "consumer:" + response; + } + +// @GetMapping("/hello03") +// public String hello03(String name) { +// // 直接使用 RestTemplate 调用服务 `demo-provider` +// String targetUrl = "http://demo-provider-2/echo?name=" + name; +// String response = restTemplate.getForObject(targetUrl, String.class); +// // 返回结果 +// return "consumer:" + response; +// } + + } + +} diff --git a/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/config/RibbonConfiguration.java b/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/config/RibbonConfiguration.java new file mode 100644 index 000000000..703ce1de2 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/config/RibbonConfiguration.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloudnetflix.labx02.ribbondemo.consumer.config; + +import org.springframework.cloud.netflix.ribbon.RibbonClient; +import org.springframework.cloud.netflix.ribbon.RibbonClients; +import org.springframework.context.annotation.Configuration; +import ribbon.DefaultRibbonClientConfiguration; +import ribbon.UserProviderRibbonClientConfiguration; + +@Configuration +@RibbonClients( + value = { + @RibbonClient(name = "demo-provider", configuration = UserProviderRibbonClientConfiguration.class) // 客户端级别的配置 + }, + defaultConfiguration = DefaultRibbonClientConfiguration.class // 全局配置 +) +public class RibbonConfiguration { +} diff --git a/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/ribbon/DefaultRibbonClientConfiguration.java b/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/ribbon/DefaultRibbonClientConfiguration.java new file mode 100644 index 000000000..18daf546b --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/ribbon/DefaultRibbonClientConfiguration.java @@ -0,0 +1,16 @@ +package ribbon; + +import com.netflix.loadbalancer.IRule; +import com.netflix.loadbalancer.RoundRobinRule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class DefaultRibbonClientConfiguration { + + @Bean + public IRule ribbonDefaultRule() { + return new RoundRobinRule(); + } + +} diff --git a/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/ribbon/UserProviderRibbonClientConfiguration.java b/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/ribbon/UserProviderRibbonClientConfiguration.java new file mode 100644 index 000000000..2b815fda8 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/java/ribbon/UserProviderRibbonClientConfiguration.java @@ -0,0 +1,18 @@ +package ribbon; + +import com.netflix.loadbalancer.IRule; +import com.netflix.loadbalancer.RandomRule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +@Configuration +public class UserProviderRibbonClientConfiguration { + + @Bean + @Primary + public IRule ribbonCustomRule() { + return new RandomRule(); + } + +} diff --git a/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/resources/application.yaml b/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..98cac55ee --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo02B-consumer/src/main/resources/application.yaml @@ -0,0 +1,11 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 diff --git a/labx-02/labx-02-scn-ribbon-demo03-consumer/pom.xml b/labx-02/labx-02-scn-ribbon-demo03-consumer/pom.xml new file mode 100644 index 000000000..01297a022 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo03-consumer/pom.xml @@ -0,0 +1,64 @@ + + + + labx-02 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-02-scn-ribbon-demo03-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-02/labx-02-scn-ribbon-demo03-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java b/labx-02/labx-02-scn-ribbon-demo03-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..ec59a0213 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo03-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,63 @@ +package cn.iocoder.springcloudnetflix.labx02.ribbondemo.consumer; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + + @Configuration + public class RestTemplateConfiguration { + + @Bean + @LoadBalanced + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + } + + @RestController + static class TestController { + + @Autowired + private RestTemplate restTemplate; + @Autowired + private LoadBalancerClient loadBalancerClient; + + @GetMapping("/hello") + public String hello(String name) { + // 获得服务 `demo-provider` 的一个实例 + ServiceInstance instance = loadBalancerClient.choose("demo-provider"); + // 发起调用 + String targetUrl = instance.getUri() + "/echo?name=" + name; + String response = restTemplate.getForObject(targetUrl, String.class); + // 返回结果 + return "consumer:" + response; + } + + @GetMapping("/hello02") + public String hello02(String name) { + // 直接使用 RestTemplate 调用服务 `demo-provider` + String targetUrl = "http://demo-provider/echo?name=" + name; + String response = restTemplate.getForObject(targetUrl, String.class); + // 返回结果 + return "consumer:" + response; + } + + } + +} diff --git a/labx-02/labx-02-scn-ribbon-demo03-consumer/src/main/resources/application.yaml b/labx-02/labx-02-scn-ribbon-demo03-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..bf562711e --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo03-consumer/src/main/resources/application.yaml @@ -0,0 +1,17 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 + +demo-provider: + ribbon: + NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule +#ribbon: +# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule diff --git a/labx-02/labx-02-scn-ribbon-demo04-consumer/pom.xml b/labx-02/labx-02-scn-ribbon-demo04-consumer/pom.xml new file mode 100644 index 000000000..5d4800ff1 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo04-consumer/pom.xml @@ -0,0 +1,64 @@ + + + + labx-02 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-02-scn-ribbon-demo04-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-02/labx-02-scn-ribbon-demo04-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java b/labx-02/labx-02-scn-ribbon-demo04-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..ec59a0213 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo04-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,63 @@ +package cn.iocoder.springcloudnetflix.labx02.ribbondemo.consumer; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + + @Configuration + public class RestTemplateConfiguration { + + @Bean + @LoadBalanced + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + } + + @RestController + static class TestController { + + @Autowired + private RestTemplate restTemplate; + @Autowired + private LoadBalancerClient loadBalancerClient; + + @GetMapping("/hello") + public String hello(String name) { + // 获得服务 `demo-provider` 的一个实例 + ServiceInstance instance = loadBalancerClient.choose("demo-provider"); + // 发起调用 + String targetUrl = instance.getUri() + "/echo?name=" + name; + String response = restTemplate.getForObject(targetUrl, String.class); + // 返回结果 + return "consumer:" + response; + } + + @GetMapping("/hello02") + public String hello02(String name) { + // 直接使用 RestTemplate 调用服务 `demo-provider` + String targetUrl = "http://demo-provider/echo?name=" + name; + String response = restTemplate.getForObject(targetUrl, String.class); + // 返回结果 + return "consumer:" + response; + } + + } + +} diff --git a/labx-02/labx-02-scn-ribbon-demo04-consumer/src/main/resources/application.yaml b/labx-02/labx-02-scn-ribbon-demo04-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..4f1c7d440 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo04-consumer/src/main/resources/application.yaml @@ -0,0 +1,17 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 + +ribbon: + # Ribbon 饥饿加载配置项,对应 RibbonEagerLoadProperties 配置类 + eager-load: + enabled: true # 是否开启饥饿加载。默认为 false 不开启 + clients: user-provider # 开启饥饿加载的 Ribbon 客户端名字。如果有多个,使用 , 逗号分隔。 diff --git a/labx-02/labx-02-scn-ribbon-demo05-consumer/pom.xml b/labx-02/labx-02-scn-ribbon-demo05-consumer/pom.xml new file mode 100644 index 000000000..008b881c7 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo05-consumer/pom.xml @@ -0,0 +1,71 @@ + + + + labx-02 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-02-scn-ribbon-demo05-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + com.squareup.okhttp3 + okhttp + + + + + + diff --git a/labx-02/labx-02-scn-ribbon-demo05-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java b/labx-02/labx-02-scn-ribbon-demo05-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..ec59a0213 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo05-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,63 @@ +package cn.iocoder.springcloudnetflix.labx02.ribbondemo.consumer; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + + @Configuration + public class RestTemplateConfiguration { + + @Bean + @LoadBalanced + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + } + + @RestController + static class TestController { + + @Autowired + private RestTemplate restTemplate; + @Autowired + private LoadBalancerClient loadBalancerClient; + + @GetMapping("/hello") + public String hello(String name) { + // 获得服务 `demo-provider` 的一个实例 + ServiceInstance instance = loadBalancerClient.choose("demo-provider"); + // 发起调用 + String targetUrl = instance.getUri() + "/echo?name=" + name; + String response = restTemplate.getForObject(targetUrl, String.class); + // 返回结果 + return "consumer:" + response; + } + + @GetMapping("/hello02") + public String hello02(String name) { + // 直接使用 RestTemplate 调用服务 `demo-provider` + String targetUrl = "http://demo-provider/echo?name=" + name; + String response = restTemplate.getForObject(targetUrl, String.class); + // 返回结果 + return "consumer:" + response; + } + + } + +} diff --git a/labx-02/labx-02-scn-ribbon-demo05-consumer/src/main/resources/application.yaml b/labx-02/labx-02-scn-ribbon-demo05-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..f9661e272 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo05-consumer/src/main/resources/application.yaml @@ -0,0 +1,22 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 + +ribbon: +# okhttp: +# enabled: true # 设置使用 OkHttp,对应 OkHttpRibbonConfiguration 配置类 + restclient: + enabled: true # 设置使用 Jersey Client,对应 RestClientRibbonConfiguration 配置类 +# httpclient: +# enabled: true # 设置使用 Apache HttpClient,对应 HttpClientRibbonConfiguration 配置类 +# ConnectTimeout: 1 # 请求的连接超时时间,单位:毫秒。默认为 1000 +# ReadTimeout: 1 # 请求的读取超时时间,单位:毫秒。默认为 1000 + diff --git a/labx-02/labx-02-scn-ribbon-demo06-consumer/pom.xml b/labx-02/labx-02-scn-ribbon-demo06-consumer/pom.xml new file mode 100644 index 000000000..9256f304b --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo06-consumer/pom.xml @@ -0,0 +1,71 @@ + + + + labx-02 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-02-scn-ribbon-demo06-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + com.squareup.okhttp3 + okhttp + + + + + + diff --git a/labx-02/labx-02-scn-ribbon-demo06-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java b/labx-02/labx-02-scn-ribbon-demo06-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..ec59a0213 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo06-consumer/src/main/java/cn/iocoder/springcloudnetflix/labx02/ribbondemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,63 @@ +package cn.iocoder.springcloudnetflix.labx02.ribbondemo.consumer; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + + @Configuration + public class RestTemplateConfiguration { + + @Bean + @LoadBalanced + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + } + + @RestController + static class TestController { + + @Autowired + private RestTemplate restTemplate; + @Autowired + private LoadBalancerClient loadBalancerClient; + + @GetMapping("/hello") + public String hello(String name) { + // 获得服务 `demo-provider` 的一个实例 + ServiceInstance instance = loadBalancerClient.choose("demo-provider"); + // 发起调用 + String targetUrl = instance.getUri() + "/echo?name=" + name; + String response = restTemplate.getForObject(targetUrl, String.class); + // 返回结果 + return "consumer:" + response; + } + + @GetMapping("/hello02") + public String hello02(String name) { + // 直接使用 RestTemplate 调用服务 `demo-provider` + String targetUrl = "http://demo-provider/echo?name=" + name; + String response = restTemplate.getForObject(targetUrl, String.class); + // 返回结果 + return "consumer:" + response; + } + + } + +} diff --git a/labx-02/labx-02-scn-ribbon-demo06-consumer/src/main/resources/application.yaml b/labx-02/labx-02-scn-ribbon-demo06-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..68e788766 --- /dev/null +++ b/labx-02/labx-02-scn-ribbon-demo06-consumer/src/main/resources/application.yaml @@ -0,0 +1,27 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + loadbalancer: + # Spring Cloud Loadbalancer 重启配置,对应 LoadBalancerRetryProperties 配置类 + retry: + enabled: true # 是否开启重启,默认为 false 关闭重试。 + +server: + port: 28080 # 服务器端口。默认为 8080 + +ribbon: + restclient: + enabled: true # 设置使用 Jersey Client,对应 RestClientRibbonConfiguration 配置类 + +demo-provider: + ribbon: + ConnectTimeout: 1000 # 请求的连接超时时间,单位:毫秒。默认为 1000 + ReadTimeout: 1 # 请求的读取超时时间,单位:毫秒。默认为 1000 + OkToRetryOnAllOperations: true # 是否对所有操作都进行重试,默认为 false。 + MaxAutoRetries: 0 # 对当前服务的重试次数,默认为 0 次。 + MaxAutoRetriesNextServer: 1 # 重新选择服务实例的次数,默认为 1 次。注意,不包含第 1 次哈。 diff --git a/labx-02/pom.xml b/labx-02/pom.xml index 2ed9f34aa..138886233 100644 --- a/labx-02/pom.xml +++ b/labx-02/pom.xml @@ -10,12 +10,22 @@ 4.0.0 labx-02 + pom labx-02-scn-ribbon-demo01-provider labx-02-scn-ribbon-demo01-consumer labx-02-scn-ribbon-demo02A-consumer + labx-02-scn-ribbon-demo02B-consumer + + labx-02-scn-ribbon-demo03-consumer + + labx-02-scn-ribbon-demo04-consumer + + labx-02-scn-ribbon-demo05-consumer + + labx-02-scn-ribbon-demo06-consumer diff --git "a/labx-02/\343\200\212\350\212\213\351\201\223 Spring Cloud Netflix \350\264\237\350\275\275\345\235\207\350\241\241 Ribbon \345\205\245\351\227\250\343\200\213.md" "b/labx-02/\343\200\212\350\212\213\351\201\223 Spring Cloud Netflix \350\264\237\350\275\275\345\235\207\350\241\241 Ribbon \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..fe312e0e8 --- /dev/null +++ "b/labx-02/\343\200\212\350\212\213\351\201\223 Spring Cloud Netflix \350\264\237\350\275\275\345\235\207\350\241\241 Ribbon \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-03/labx-03-sc-feign-demo01-consumer/pom.xml b/labx-03/labx-03-sc-feign-demo01-consumer/pom.xml new file mode 100644 index 000000000..0be682a82 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo01-consumer/pom.xml @@ -0,0 +1,70 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo01-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java b/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..fdc51234d --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/FeignDemo.java b/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/FeignDemo.java new file mode 100644 index 000000000..93b976696 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/FeignDemo.java @@ -0,0 +1,31 @@ +/** + * 用于展示纯 Feign 的示例 + */ +package cn.iocoder.springcloud.labx03.feigndemo.consumer; + +import feign.Feign; +import feign.Param; +import feign.RequestLine; + +// 商品 API +interface ProductAPI { + + // 获得商品详情 + @RequestLine("POST /products/{id}") + String get(@Param("id") Integer id); + +} + +public class FeignDemo { + + public static void main(String[] args) { + // 创建 ProductAPI 对象 + ProductAPI productAPI = Feign.builder().target(ProductAPI.class, + "http://www.iocoder.cn"); // 目标地址 + + // 调用获得商品 + String product = productAPI.get(1); + System.out.println(product); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java b/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java new file mode 100644 index 000000000..0a692aa1e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.feign.DemoProviderFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ConsumerController { + + @Autowired + private DemoProviderFeignClient demoProviderFeignClient; + + @GetMapping("/hello02") + public String hello02(String name) { + // 使用 Feign 调用接口 + String response = demoProviderFeignClient.echo(name); + // 返回结果 + return "consumer:" + response; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java b/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java new file mode 100644 index 000000000..588cfff2f --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo01-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.feign; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "demo-provider") +public interface DemoProviderFeignClient { + + @GetMapping("/echo") + String echo(@RequestParam("name") String name); + +} diff --git a/labx-03/labx-03-sc-feign-demo01-consumer/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo01-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..98cac55ee --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo01-consumer/src/main/resources/application.yaml @@ -0,0 +1,11 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 diff --git a/labx-03/labx-03-sc-feign-demo01-provider/pom.xml b/labx-03/labx-03-sc-feign-demo01-provider/pom.xml new file mode 100644 index 000000000..20331f36d --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo01-provider/pom.xml @@ -0,0 +1,64 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo01-provider + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-03/labx-03-sc-feign-demo01-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/DemoProviderApplication.java b/labx-03/labx-03-sc-feign-demo01-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/DemoProviderApplication.java new file mode 100644 index 000000000..d6b316396 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo01-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/DemoProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx03.feigndemo.provider; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoProviderApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo01-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/controller/ProviderController.java b/labx-03/labx-03-sc-feign-demo01-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/controller/ProviderController.java new file mode 100644 index 000000000..92ed7c3df --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo01-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/controller/ProviderController.java @@ -0,0 +1,28 @@ +package cn.iocoder.springcloud.labx03.feigndemo.provider.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ProviderController { + + private Logger logger = LoggerFactory.getLogger(ProviderController.class); + + @Value("${server.port}") + private Integer serverPort; + + @GetMapping("/echo") + public String echo(String name) throws InterruptedException { + // 模拟执行 100ms 时长。方便后续我们测试请求超时 + Thread.sleep(100L); + + // 记录被调用的日志 + logger.info("[echo][被调用啦 name({})]", name); + + return serverPort + "-provider:" + name; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo01-provider/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo01-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..53225aa4a --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo01-provider/src/main/resources/application.yaml @@ -0,0 +1,12 @@ +spring: + application: + name: demo-provider # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: ${random.int[10000,19999]} # 服务器端口。默认为 8080 +# port: 18080 # 服务器端口。默认为 8080 diff --git a/labx-03/labx-03-sc-feign-demo02A-consumer/pom.xml b/labx-03/labx-03-sc-feign-demo02A-consumer/pom.xml new file mode 100644 index 000000000..b8ebcdb55 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02A-consumer/pom.xml @@ -0,0 +1,70 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo02A-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java b/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..fdc51234d --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java b/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java new file mode 100644 index 000000000..0a692aa1e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.feign.DemoProviderFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ConsumerController { + + @Autowired + private DemoProviderFeignClient demoProviderFeignClient; + + @GetMapping("/hello02") + public String hello02(String name) { + // 使用 Feign 调用接口 + String response = demoProviderFeignClient.echo(name); + // 返回结果 + return "consumer:" + response; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java b/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java new file mode 100644 index 000000000..588cfff2f --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.feign; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "demo-provider") +public interface DemoProviderFeignClient { + + @GetMapping("/echo") + String echo(@RequestParam("name") String name); + +} diff --git a/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..8ba9c7f62 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02A-consumer/src/main/resources/application.yaml @@ -0,0 +1,27 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 + +logging: + level: + cn.iocoder.springcloud.labx03.feigndemo.consumer.feign: DEBUG + +feign: + # Feign 客户端配置,对应 FeignClientProperties 配置属性类 + client: + # config 配置项是 Map 类型。key 为 Feign 客户端的名字,value 为 FeignClientConfiguration 对象 + config: + # 全局级别配置 + default: + logger-level: BASIC + # 客户端级别配置 + demo-provider: + logger-level: FULL diff --git a/labx-03/labx-03-sc-feign-demo02B-consumer/pom.xml b/labx-03/labx-03-sc-feign-demo02B-consumer/pom.xml new file mode 100644 index 000000000..d943e9a2e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02B-consumer/pom.xml @@ -0,0 +1,70 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo02B-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..17870b290 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.config.DefaultFeignClientConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients(defaultConfiguration = DefaultFeignClientConfiguration.class) +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/config/DefaultFeignClientConfiguration.java b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/config/DefaultFeignClientConfiguration.java new file mode 100644 index 000000000..508d8317d --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/config/DefaultFeignClientConfiguration.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.config; + +import feign.Logger; +import org.springframework.context.annotation.Bean; + +/** + * 全局 FeignClient 配置类 + */ +public class DefaultFeignClientConfiguration { + + @Bean + public Logger.Level defaultFeignClientLoggerLevel() { + return Logger.Level.BASIC; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/config/DemoProviderFeignClientConfiguration.java b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/config/DemoProviderFeignClientConfiguration.java new file mode 100644 index 000000000..688dfa935 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/config/DemoProviderFeignClientConfiguration.java @@ -0,0 +1,18 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.config; + +import feign.Logger; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +/** + * 服务 demo-provider 的 FeignClient 配置类 + */ +public class DemoProviderFeignClientConfiguration { + + @Bean + @Primary // 主 Bean + public Logger.Level feignClientLoggerLevel() { + return Logger.Level.FULL; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java new file mode 100644 index 000000000..0a692aa1e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.feign.DemoProviderFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ConsumerController { + + @Autowired + private DemoProviderFeignClient demoProviderFeignClient; + + @GetMapping("/hello02") + public String hello02(String name) { + // 使用 Feign 调用接口 + String response = demoProviderFeignClient.echo(name); + // 返回结果 + return "consumer:" + response; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java new file mode 100644 index 000000000..29b212ddb --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.feign; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.config.DemoProviderFeignClientConfiguration; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "demo-provider", configuration = DemoProviderFeignClientConfiguration.class) +public interface DemoProviderFeignClient { + + @GetMapping("/echo") + String echo(@RequestParam("name") String name); + +} diff --git a/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..5e3ef101e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo02B-consumer/src/main/resources/application.yaml @@ -0,0 +1,15 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 + +logging: + level: + cn.iocoder.springcloud.labx03.feigndemo.consumer.feign: DEBUG diff --git a/labx-03/labx-03-sc-feign-demo03-consumer/pom.xml b/labx-03/labx-03-sc-feign-demo03-consumer/pom.xml new file mode 100644 index 000000000..6c49e27d4 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-consumer/pom.xml @@ -0,0 +1,77 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo03-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-03-sc-feign-demo03-provider-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-03/labx-03-sc-feign-demo03-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java b/labx-03/labx-03-sc-feign-demo03-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..fdc51234d --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo03-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java b/labx-03/labx-03-sc-feign-demo03-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java new file mode 100644 index 000000000..0a692aa1e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.feign.DemoProviderFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ConsumerController { + + @Autowired + private DemoProviderFeignClient demoProviderFeignClient; + + @GetMapping("/hello02") + public String hello02(String name) { + // 使用 Feign 调用接口 + String response = demoProviderFeignClient.echo(name); + // 返回结果 + return "consumer:" + response; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo03-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java b/labx-03/labx-03-sc-feign-demo03-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java new file mode 100644 index 000000000..f32dac53a --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java @@ -0,0 +1,12 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.feign; + +import cn.iocoder.springcloud.labx03.feigndemo.provider.api.ProviderService; +import org.springframework.cloud.openfeign.FeignClient; + +@FeignClient(name = "demo-provider") +public interface DemoProviderFeignClient extends ProviderService { + +// @GetMapping("/echo") +// String echo(@RequestParam("name") String name); + +} diff --git a/labx-03/labx-03-sc-feign-demo03-consumer/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo03-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..98cac55ee --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-consumer/src/main/resources/application.yaml @@ -0,0 +1,11 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 diff --git a/labx-03/labx-03-sc-feign-demo03-provider-api/pom.xml b/labx-03/labx-03-sc-feign-demo03-provider-api/pom.xml new file mode 100644 index 000000000..2be91b189 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-provider-api/pom.xml @@ -0,0 +1,24 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo03-provider-api + + + + + org.springframework + spring-web + 5.2.3.RELEASE + provided + + + + diff --git a/labx-03/labx-03-sc-feign-demo03-provider-api/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/api/ProviderService.java b/labx-03/labx-03-sc-feign-demo03-provider-api/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/api/ProviderService.java new file mode 100644 index 000000000..ae23979a0 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-provider-api/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/api/ProviderService.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx03.feigndemo.provider.api; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +public interface ProviderService { + + @GetMapping("/echo") + String echo(@RequestParam("name") String name); + +} diff --git a/labx-03/labx-03-sc-feign-demo03-provider/pom.xml b/labx-03/labx-03-sc-feign-demo03-provider/pom.xml new file mode 100644 index 000000000..31d2200db --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-provider/pom.xml @@ -0,0 +1,71 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo03-provider + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-03-sc-feign-demo03-provider-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-03/labx-03-sc-feign-demo03-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/DemoProviderApplication.java b/labx-03/labx-03-sc-feign-demo03-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/DemoProviderApplication.java new file mode 100644 index 000000000..d6b316396 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/DemoProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx03.feigndemo.provider; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoProviderApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo03-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/controller/ProviderController.java b/labx-03/labx-03-sc-feign-demo03-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/controller/ProviderController.java new file mode 100644 index 000000000..4cd59e03e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/controller/ProviderController.java @@ -0,0 +1,43 @@ +package cn.iocoder.springcloud.labx03.feigndemo.provider.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.provider.api.ProviderService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ProviderController implements ProviderService { + + private Logger logger = LoggerFactory.getLogger(ProviderController.class); + + @Value("${server.port}") + private Integer serverPort; + + @Override + public String echo(String name) { + // 模拟执行 100ms 时长。方便后续我们测试请求超时 + try { + Thread.sleep(100L); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + // 记录被调用的日志 + logger.info("[echo][被调用啦 name({})]", name); + + return serverPort + "-provider:" + name; + } + +// @GetMapping("/echo") +// public String echo(String name) throws InterruptedException { +// // 模拟执行 100ms 时长。方便后续我们测试请求超时 +// Thread.sleep(100L); +// +// // 记录被调用的日志 +// logger.info("[echo][被调用啦 name({})]", name); +// +// return serverPort + "-provider:" + name; +// } + +} diff --git a/labx-03/labx-03-sc-feign-demo03-provider/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo03-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..53225aa4a --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo03-provider/src/main/resources/application.yaml @@ -0,0 +1,12 @@ +spring: + application: + name: demo-provider # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: ${random.int[10000,19999]} # 服务器端口。默认为 8080 +# port: 18080 # 服务器端口。默认为 8080 diff --git a/labx-03/labx-03-sc-feign-demo04-consumer/pom.xml b/labx-03/labx-03-sc-feign-demo04-consumer/pom.xml new file mode 100644 index 000000000..d6296809e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-consumer/pom.xml @@ -0,0 +1,70 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo04-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java b/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..fdc51234d --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java b/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java new file mode 100644 index 000000000..afbd74079 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java @@ -0,0 +1,48 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.dto.DemoDTO; +import cn.iocoder.springcloud.labx03.feigndemo.consumer.feign.DemoProviderFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +public class ConsumerController { + + @Autowired + private DemoProviderFeignClient demoProviderFeignClient; + + @GetMapping("/hello02") + public String hello02(String name) { + // 使用 Feign 调用接口 + String response = demoProviderFeignClient.echo(name); + // 返回结果 + return "consumer:" + response; + } + + @GetMapping("/test_get_demo") + public DemoDTO testGetDemo(@RequestParam("type") int type, DemoDTO demoDTO) { + // 方式一 + if (type == 1) { + return demoProviderFeignClient.getDemo(demoDTO); + } else if (type == 2) { + return demoProviderFeignClient.getDemo(demoDTO.getUsername(), demoDTO.getPassword()); + } else { + // 方式三 + Map params = new HashMap<>(); + params.put("username", demoDTO.getUsername()); + params.put("password", demoDTO.getPassword()); + return demoProviderFeignClient.getDemo(params); + } + } + + @GetMapping("/test_post_demo") + public DemoDTO testPostDemo(DemoDTO demoDTO) { + return demoProviderFeignClient.postDemo(demoDTO); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/dto/DemoDTO.java b/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/dto/DemoDTO.java new file mode 100644 index 000000000..7b6c1f08a --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/dto/DemoDTO.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.dto; + +public class DemoDTO { + + private String username; + private String password; + + public String getUsername() { + return username; + } + + public DemoDTO setUsername(String username) { + this.username = username; + return this; + } + + public String getPassword() { + return password; + } + + public DemoDTO setPassword(String password) { + this.password = password; + return this; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java b/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java new file mode 100644 index 000000000..62e478997 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java @@ -0,0 +1,31 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.feign; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.dto.DemoDTO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.cloud.openfeign.SpringQueryMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.Map; + +@FeignClient(name = "demo-provider") +public interface DemoProviderFeignClient { + + @GetMapping("/echo") + String echo(@RequestParam("name") String name); + + @GetMapping("/get_demo") // GET 方式一,最推荐 + DemoDTO getDemo(@SpringQueryMap DemoDTO demoDTO); + + @GetMapping("/get_demo") // GET 方式二,相对推荐 + DemoDTO getDemo(@RequestParam("username") String username, @RequestParam("password") String password); + + @GetMapping("/get_demo") // GET 方式三,不推荐 + DemoDTO getDemo(@RequestParam Map params); + + @PostMapping("/post_demo") // POST 方式 + DemoDTO postDemo(@RequestBody DemoDTO demoDTO); + +} diff --git a/labx-03/labx-03-sc-feign-demo04-consumer/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo04-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..98cac55ee --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-consumer/src/main/resources/application.yaml @@ -0,0 +1,11 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 diff --git a/labx-03/labx-03-sc-feign-demo04-provider/pom.xml b/labx-03/labx-03-sc-feign-demo04-provider/pom.xml new file mode 100644 index 000000000..53d60913c --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-provider/pom.xml @@ -0,0 +1,64 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo04-provider + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-03/labx-03-sc-feign-demo04-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/DemoProviderApplication.java b/labx-03/labx-03-sc-feign-demo04-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/DemoProviderApplication.java new file mode 100644 index 000000000..d6b316396 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/DemoProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx03.feigndemo.provider; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoProviderApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo04-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/controller/ProviderController.java b/labx-03/labx-03-sc-feign-demo04-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/controller/ProviderController.java new file mode 100644 index 000000000..2168b1d73 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/controller/ProviderController.java @@ -0,0 +1,41 @@ +package cn.iocoder.springcloud.labx03.feigndemo.provider.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.provider.dto.DemoDTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ProviderController { + + private Logger logger = LoggerFactory.getLogger(ProviderController.class); + + @Value("${server.port}") + private Integer serverPort; + + @GetMapping("/echo") + public String echo(String name) throws InterruptedException { + // 模拟执行 100ms 时长。方便后续我们测试请求超时 + Thread.sleep(100L); + + // 记录被调用的日志 + logger.info("[echo][被调用啦 name({})]", name); + + return serverPort + "-provider:" + name; + } + + @GetMapping("/get_demo") + public DemoDTO getDemo(DemoDTO demoDTO) { + return demoDTO; + } + + @PostMapping("/post_demo") + public DemoDTO postDemo(@RequestBody DemoDTO demoDTO) { + return demoDTO; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo04-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/dto/DemoDTO.java b/labx-03/labx-03-sc-feign-demo04-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/dto/DemoDTO.java new file mode 100644 index 000000000..de1d9b889 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-provider/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/provider/dto/DemoDTO.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloud.labx03.feigndemo.provider.dto; + +public class DemoDTO { + + private String username; + private String password; + + public String getUsername() { + return username; + } + + public DemoDTO setUsername(String username) { + this.username = username; + return this; + } + + public String getPassword() { + return password; + } + + public DemoDTO setPassword(String password) { + this.password = password; + return this; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo04-provider/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo04-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..53225aa4a --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo04-provider/src/main/resources/application.yaml @@ -0,0 +1,12 @@ +spring: + application: + name: demo-provider # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: ${random.int[10000,19999]} # 服务器端口。默认为 8080 +# port: 18080 # 服务器端口。默认为 8080 diff --git a/labx-03/labx-03-sc-feign-demo05-consumer/pom.xml b/labx-03/labx-03-sc-feign-demo05-consumer/pom.xml new file mode 100644 index 000000000..2eb1ed849 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo05-consumer/pom.xml @@ -0,0 +1,70 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo05-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-03/labx-03-sc-feign-demo05-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java b/labx-03/labx-03-sc-feign-demo05-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..fdc51234d --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo05-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo05-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java b/labx-03/labx-03-sc-feign-demo05-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java new file mode 100644 index 000000000..0a692aa1e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo05-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.feign.DemoProviderFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ConsumerController { + + @Autowired + private DemoProviderFeignClient demoProviderFeignClient; + + @GetMapping("/hello02") + public String hello02(String name) { + // 使用 Feign 调用接口 + String response = demoProviderFeignClient.echo(name); + // 返回结果 + return "consumer:" + response; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo05-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java b/labx-03/labx-03-sc-feign-demo05-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java new file mode 100644 index 000000000..1097669ac --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo05-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.feign; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +//@FeignClient(name = "demo-provider") +@FeignClient(name = "iocoder", url = "http://www.iocoder.cn") // 注意,保持 name 属性和 url 属性的 host 是一致的。 +public interface DemoProviderFeignClient { + +// @GetMapping("/echo") +// String echo(@RequestParam("name") String name); + + @GetMapping("/") // 请求首页 + String echo(@RequestParam("name") String name); + +} diff --git a/labx-03/labx-03-sc-feign-demo05-consumer/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo05-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..98cac55ee --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo05-consumer/src/main/resources/application.yaml @@ -0,0 +1,11 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 diff --git a/labx-03/labx-03-sc-feign-demo06A-consumer/pom.xml b/labx-03/labx-03-sc-feign-demo06A-consumer/pom.xml new file mode 100644 index 000000000..ae7f52e40 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo06A-consumer/pom.xml @@ -0,0 +1,77 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo06A-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + io.github.openfeign + feign-httpclient + + + + + diff --git a/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java b/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..fdc51234d --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java b/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java new file mode 100644 index 000000000..0a692aa1e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.feign.DemoProviderFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ConsumerController { + + @Autowired + private DemoProviderFeignClient demoProviderFeignClient; + + @GetMapping("/hello02") + public String hello02(String name) { + // 使用 Feign 调用接口 + String response = demoProviderFeignClient.echo(name); + // 返回结果 + return "consumer:" + response; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java b/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java new file mode 100644 index 000000000..588cfff2f --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.feign; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "demo-provider") +public interface DemoProviderFeignClient { + + @GetMapping("/echo") + String echo(@RequestParam("name") String name); + +} diff --git a/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..f816aab8a --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo06A-consumer/src/main/resources/application.yaml @@ -0,0 +1,19 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 + +feign: + # Feign Apache HttpClient 配置项,对应 FeignHttpClientProperties 配置属性类 + httpclient: + enabled: true # 是否开启。默认为 true + max-connections: 200 # 最大连接数。默认为 200 + max-connections-per-route: 50 # 每个路由的最大连接数。默认为 50。router = host + port + diff --git a/labx-03/labx-03-sc-feign-demo06B-consumer/pom.xml b/labx-03/labx-03-sc-feign-demo06B-consumer/pom.xml new file mode 100644 index 000000000..f7265736a --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo06B-consumer/pom.xml @@ -0,0 +1,77 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo06B-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + io.github.openfeign + feign-okhttp + + + + + diff --git a/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java b/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..fdc51234d --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java b/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java new file mode 100644 index 000000000..0a692aa1e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.feign.DemoProviderFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ConsumerController { + + @Autowired + private DemoProviderFeignClient demoProviderFeignClient; + + @GetMapping("/hello02") + public String hello02(String name) { + // 使用 Feign 调用接口 + String response = demoProviderFeignClient.echo(name); + // 返回结果 + return "consumer:" + response; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java b/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java new file mode 100644 index 000000000..588cfff2f --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.feign; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "demo-provider") +public interface DemoProviderFeignClient { + + @GetMapping("/echo") + String echo(@RequestParam("name") String name); + +} diff --git a/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..e7012a4f0 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo06B-consumer/src/main/resources/application.yaml @@ -0,0 +1,17 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 28080 # 服务器端口。默认为 8080 + +feign: + httpclient: + enabled: false # 是否开启。默认为 true + okhttp: + enabled: true # 是否开启。默认为 false diff --git a/labx-03/labx-03-sc-feign-demo07-consumer/pom.xml b/labx-03/labx-03-sc-feign-demo07-consumer/pom.xml new file mode 100644 index 000000000..a1574416a --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo07-consumer/pom.xml @@ -0,0 +1,76 @@ + + + + labx-03 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03-sc-feign-demo07-consumer + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + io.github.openfeign + feign-httpclient + + + + diff --git a/labx-03/labx-03-sc-feign-demo07-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java b/labx-03/labx-03-sc-feign-demo07-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java new file mode 100644 index 000000000..fdc51234d --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo07-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/DemoConsumerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-03/labx-03-sc-feign-demo07-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java b/labx-03/labx-03-sc-feign-demo07-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java new file mode 100644 index 000000000..0a692aa1e --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo07-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/controller/ConsumerController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.controller; + +import cn.iocoder.springcloud.labx03.feigndemo.consumer.feign.DemoProviderFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ConsumerController { + + @Autowired + private DemoProviderFeignClient demoProviderFeignClient; + + @GetMapping("/hello02") + public String hello02(String name) { + // 使用 Feign 调用接口 + String response = demoProviderFeignClient.echo(name); + // 返回结果 + return "consumer:" + response; + } + +} diff --git a/labx-03/labx-03-sc-feign-demo07-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java b/labx-03/labx-03-sc-feign-demo07-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java new file mode 100644 index 000000000..588cfff2f --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo07-consumer/src/main/java/cn/iocoder/springcloud/labx03/feigndemo/consumer/feign/DemoProviderFeignClient.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx03.feigndemo.consumer.feign; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "demo-provider") +public interface DemoProviderFeignClient { + + @GetMapping("/echo") + String echo(@RequestParam("name") String name); + +} diff --git a/labx-03/labx-03-sc-feign-demo07-consumer/src/main/resources/application.yaml b/labx-03/labx-03-sc-feign-demo07-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..25a3e49c0 --- /dev/null +++ b/labx-03/labx-03-sc-feign-demo07-consumer/src/main/resources/application.yaml @@ -0,0 +1,22 @@ +spring: + application: + name: demo-consumer # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 +# loadbalancer: +# # Spring Cloud Loadbalancer 重启配置,对应 LoadBalancerRetryProperties 配置类 +# retry: +# enabled: true # 是否开启重启,默认为 false 关闭重试。 + +server: + port: 28080 # 服务器端口。默认为 8080 + +ribbon: + ConnectTimeout: 1000 # 请求的连接超时时间,单位:毫秒。默认为 1000 + ReadTimeout: 1 # 请求的读取超时时间,单位:毫秒。默认为 1000 + OkToRetryOnAllOperations: true # 是否对所有操作都进行重试,默认为 false。 + MaxAutoRetries: 0 # 对当前服务的重试次数,默认为 0 次。 + MaxAutoRetriesNextServer: 1 # 重新选择服务实例的次数,默认为 1 次。注意,不包含第 1 次哈。 diff --git a/labx-03/pom.xml b/labx-03/pom.xml new file mode 100644 index 000000000..33edef2c5 --- /dev/null +++ b/labx-03/pom.xml @@ -0,0 +1,37 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-03 + pom + + + labx-03-sc-feign-demo01-provider + labx-03-sc-feign-demo01-consumer + + labx-03-sc-feign-demo02A-consumer + labx-03-sc-feign-demo02B-consumer + + labx-03-sc-feign-demo03-provider-api + labx-03-sc-feign-demo03-provider + labx-03-sc-feign-demo03-consumer + + labx-03-sc-feign-demo04-provider + labx-03-sc-feign-demo04-consumer + + labx-03-sc-feign-demo05-consumer + + labx-03-sc-feign-demo06A-consumer + labx-03-sc-feign-demo06B-consumer + + labx-03-sc-feign-demo07-consumer + + + diff --git "a/labx-03/\343\200\212\350\212\213\351\201\223 Spring Cloud \345\243\260\346\230\216\345\274\217\350\260\203\347\224\250 Feign \345\205\245\351\227\250\343\200\213.md" "b/labx-03/\343\200\212\350\212\213\351\201\223 Spring Cloud \345\243\260\346\230\216\345\274\217\350\260\203\347\224\250 Feign \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..501feb31c --- /dev/null +++ "b/labx-03/\343\200\212\350\212\213\351\201\223 Spring Cloud \345\243\260\346\230\216\345\274\217\350\260\203\347\224\250 Feign \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-04/labx-04-sca-sentinel-actuator-provider/pom.xml b/labx-04/labx-04-sca-sentinel-actuator-provider/pom.xml new file mode 100644 index 000000000..c22238e11 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-actuator-provider/pom.xml @@ -0,0 +1,72 @@ + + + + labx-04 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-04-sca-sentinel-actuator-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java new file mode 100644 index 000000000..569f4d28e --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoProviderApplication.class, args); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java new file mode 100644 index 000000000..5a008fab3 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java @@ -0,0 +1,84 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.controller; + +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.annotation.SentinelResource; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + // 测试【流量控制】 + @GetMapping("/echo") + public String echo() { + return "echo"; + } + + @GetMapping("/test") + public String test() { + return "test"; + } + + // 测试【熔断降级】 + @GetMapping("/sleep") + public String sleep() throws InterruptedException { + Thread.sleep(100L); + return "sleep"; + } + + // 测试【热点参数限流】 + @GetMapping("/product_info") + @SentinelResource("demo_product_info_hot") + public String productInfo(Integer id) { + return "商品编号:" + id; + } + + // 测试「Sentinel 客户端 API」 + @GetMapping("/entry_demo") + public String entryDemo() { + Entry entry = null; + try { + // <1> 访问资源 + entry = SphU.entry("entry_demo"); + + // <2> ... 执行业务逻辑 + + return "执行成功"; + } catch (BlockException ex) { // <3> + return "被拒绝"; + } finally { + // <4> 释放资源 + if (entry != null) { + entry.exit(); + } + } + } + + // 测试「Sentinel @SentinelResource 注解」 + @GetMapping("/annotations_demo") + @SentinelResource(value = "annotations_demo_resource", + blockHandler = "blockHandler", + fallback = "fallback") + public String annotationsDemo(@RequestParam(required = false) Integer id) throws InterruptedException { + if (id == null) { + throw new IllegalArgumentException("id 参数不允许为空"); + } + return "success..."; + } + + // BlockHandler 处理函数,参数最后多一个 BlockException,其余与原函数一致. + public String blockHandler(Integer id, BlockException ex) { + return "block:" + ex.getClass().getSimpleName(); + } + + // Fallback 处理函数,函数签名与原函数一致或加一个 Throwable 类型的参数. + public String fallback(Integer id, Throwable throwable) { + return "fallback:" + throwable.getMessage(); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java new file mode 100644 index 000000000..6431c62cc --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java @@ -0,0 +1,18 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Component +public class CustomBlockExceptionHandler implements BlockExceptionHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception { + throw e; + } + +} diff --git a/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java new file mode 100644 index 000000000..546fda816 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java @@ -0,0 +1,23 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +@Component +public class CustomRequestOriginParser implements RequestOriginParser { + + @Override + public String parseOrigin(HttpServletRequest request) { + // 从 Header 中,获得请求来源 + String origin = request.getHeader("s-user"); + // 如果为空,给一个默认的 + if (StringUtils.isEmpty(origin)) { + origin = "default"; + } + return origin; + } + +} diff --git a/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java new file mode 100644 index 000000000..f60b2fe69 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java @@ -0,0 +1,21 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.fastjson.JSONObject; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +@Component +@ControllerAdvice(basePackages = "cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider") +public class GlobalExceptionHandler { + + @ResponseBody + @ExceptionHandler(value = BlockException.class) // 因为这里是示例,所以暂时使用 JSONObject,实际项目最终定义一个 CommonResult。 + public JSONObject blockExceptionHandler(BlockException blockException) { + return new JSONObject().fluentPut("code", 1024) + .fluentPut("msg", "请求被拦截,拦截类型为 " + blockException.getClass().getSimpleName()); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/resources/application.yaml b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..4eafdd9f1 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-actuator-provider/src/main/resources/application.yaml @@ -0,0 +1,24 @@ +spring: + application: + name: demo-provider + + cloud: + # Sentinel 配置项,对应 SentinelProperties 配置属性类 + sentinel: + enabled: true # 是否开启。默认为 true 开启 + eager: true # 是否饥饿加载。默认为 false 关闭 + transport: + dashboard: 127.0.0.1:7070 # Sentinel 控制台地址 + filter: + url-patterns: /** # 拦截请求的地址。默认为 /* + +management: + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + endpoint: + # Health 端点配置项,对应 HealthProperties 配置类 + health: + enabled: true # 是否开启。默认为 true 开启。 + show-details: ALWAYS # 何时显示完整的健康信息。默认为 NEVER 都不展示。可选 WHEN_AUTHORIZED 当经过授权的用户;可选 ALWAYS 总是展示。 diff --git a/labx-04/labx-04-sca-sentinel-apollo-provider/pom.xml b/labx-04/labx-04-sca-sentinel-apollo-provider/pom.xml new file mode 100644 index 000000000..d4d5ceb6d --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-apollo-provider/pom.xml @@ -0,0 +1,72 @@ + + + + labx-04 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-04-sca-sentinel-apollo-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + com.alibaba.csp + sentinel-datasource-apollo + + + + diff --git a/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java new file mode 100644 index 000000000..569f4d28e --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoProviderApplication.class, args); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java new file mode 100644 index 000000000..5a008fab3 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java @@ -0,0 +1,84 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.controller; + +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.annotation.SentinelResource; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + // 测试【流量控制】 + @GetMapping("/echo") + public String echo() { + return "echo"; + } + + @GetMapping("/test") + public String test() { + return "test"; + } + + // 测试【熔断降级】 + @GetMapping("/sleep") + public String sleep() throws InterruptedException { + Thread.sleep(100L); + return "sleep"; + } + + // 测试【热点参数限流】 + @GetMapping("/product_info") + @SentinelResource("demo_product_info_hot") + public String productInfo(Integer id) { + return "商品编号:" + id; + } + + // 测试「Sentinel 客户端 API」 + @GetMapping("/entry_demo") + public String entryDemo() { + Entry entry = null; + try { + // <1> 访问资源 + entry = SphU.entry("entry_demo"); + + // <2> ... 执行业务逻辑 + + return "执行成功"; + } catch (BlockException ex) { // <3> + return "被拒绝"; + } finally { + // <4> 释放资源 + if (entry != null) { + entry.exit(); + } + } + } + + // 测试「Sentinel @SentinelResource 注解」 + @GetMapping("/annotations_demo") + @SentinelResource(value = "annotations_demo_resource", + blockHandler = "blockHandler", + fallback = "fallback") + public String annotationsDemo(@RequestParam(required = false) Integer id) throws InterruptedException { + if (id == null) { + throw new IllegalArgumentException("id 参数不允许为空"); + } + return "success..."; + } + + // BlockHandler 处理函数,参数最后多一个 BlockException,其余与原函数一致. + public String blockHandler(Integer id, BlockException ex) { + return "block:" + ex.getClass().getSimpleName(); + } + + // Fallback 处理函数,函数签名与原函数一致或加一个 Throwable 类型的参数. + public String fallback(Integer id, Throwable throwable) { + return "fallback:" + throwable.getMessage(); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java new file mode 100644 index 000000000..6431c62cc --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java @@ -0,0 +1,18 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Component +public class CustomBlockExceptionHandler implements BlockExceptionHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception { + throw e; + } + +} diff --git a/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java new file mode 100644 index 000000000..546fda816 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java @@ -0,0 +1,23 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +@Component +public class CustomRequestOriginParser implements RequestOriginParser { + + @Override + public String parseOrigin(HttpServletRequest request) { + // 从 Header 中,获得请求来源 + String origin = request.getHeader("s-user"); + // 如果为空,给一个默认的 + if (StringUtils.isEmpty(origin)) { + origin = "default"; + } + return origin; + } + +} diff --git a/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java new file mode 100644 index 000000000..f60b2fe69 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java @@ -0,0 +1,21 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.fastjson.JSONObject; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +@Component +@ControllerAdvice(basePackages = "cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider") +public class GlobalExceptionHandler { + + @ResponseBody + @ExceptionHandler(value = BlockException.class) // 因为这里是示例,所以暂时使用 JSONObject,实际项目最终定义一个 CommonResult。 + public JSONObject blockExceptionHandler(BlockException blockException) { + return new JSONObject().fluentPut("code", 1024) + .fluentPut("msg", "请求被拦截,拦截类型为 " + blockException.getClass().getSimpleName()); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/resources/application.yaml b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..7ddca62ba --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-apollo-provider/src/main/resources/application.yaml @@ -0,0 +1,38 @@ +server: + port: 18080 # 服务器端口,设置为 18080 避免和本地的 Apollo 端口冲突 + +# Apollo 相关配置项 +app: + id: ${spring.application.name} # 使用的 Apollo 的项目(应用)编号 +apollo: + meta: http://127.0.0.1:8080 # Apollo Meta Server 地址 + bootstrap: + enabled: true # 是否开启 Apollo 配置预加载功能。默认为 false。 + eagerLoad: + enable: true # 是否开启 Apollo 支持日志级别的加载时机。默认为 false。 + namespaces: application # 使用的 Apollo 的命名空间,默认为 application。 + +spring: + application: + name: demo-provider + + cloud: + # Sentinel 配置项,对应 SentinelProperties 配置属性类 + sentinel: + enabled: true # 是否开启。默认为 true 开启 + eager: true # 是否饥饿加载。默认为 false 关闭 + transport: + dashboard: 127.0.0.1:7070 # Sentinel 控制台地址 + filter: + url-patterns: /** # 拦截请求的地址。默认为 /* + # Sentinel 规则的数据源,是一个 Map 类型。key 为数据源名,可自定义;value 为数据源的具体配置 + datasource: + ds1: + # 对应 DataSourcePropertiesConfiguration 类 + apollo: + namespaceName: application # Apollo 命名空间 + flowRulesKey: sentinel.flow-rule # Apollo 配置 key + data-type: json # 数据格式 + rule-type: FLOW # 规则类型 + + diff --git a/labx-04/labx-04-sca-sentinel-demo01-provider/pom.xml b/labx-04/labx-04-sca-sentinel-demo01-provider/pom.xml new file mode 100644 index 000000000..839961257 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-demo01-provider/pom.xml @@ -0,0 +1,66 @@ + + + + labx-04 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-04-sca-sentinel-demo01-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + diff --git a/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java new file mode 100644 index 000000000..569f4d28e --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoProviderApplication.class, args); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java new file mode 100644 index 000000000..5a008fab3 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java @@ -0,0 +1,84 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.controller; + +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.annotation.SentinelResource; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + // 测试【流量控制】 + @GetMapping("/echo") + public String echo() { + return "echo"; + } + + @GetMapping("/test") + public String test() { + return "test"; + } + + // 测试【熔断降级】 + @GetMapping("/sleep") + public String sleep() throws InterruptedException { + Thread.sleep(100L); + return "sleep"; + } + + // 测试【热点参数限流】 + @GetMapping("/product_info") + @SentinelResource("demo_product_info_hot") + public String productInfo(Integer id) { + return "商品编号:" + id; + } + + // 测试「Sentinel 客户端 API」 + @GetMapping("/entry_demo") + public String entryDemo() { + Entry entry = null; + try { + // <1> 访问资源 + entry = SphU.entry("entry_demo"); + + // <2> ... 执行业务逻辑 + + return "执行成功"; + } catch (BlockException ex) { // <3> + return "被拒绝"; + } finally { + // <4> 释放资源 + if (entry != null) { + entry.exit(); + } + } + } + + // 测试「Sentinel @SentinelResource 注解」 + @GetMapping("/annotations_demo") + @SentinelResource(value = "annotations_demo_resource", + blockHandler = "blockHandler", + fallback = "fallback") + public String annotationsDemo(@RequestParam(required = false) Integer id) throws InterruptedException { + if (id == null) { + throw new IllegalArgumentException("id 参数不允许为空"); + } + return "success..."; + } + + // BlockHandler 处理函数,参数最后多一个 BlockException,其余与原函数一致. + public String blockHandler(Integer id, BlockException ex) { + return "block:" + ex.getClass().getSimpleName(); + } + + // Fallback 处理函数,函数签名与原函数一致或加一个 Throwable 类型的参数. + public String fallback(Integer id, Throwable throwable) { + return "fallback:" + throwable.getMessage(); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java new file mode 100644 index 000000000..6431c62cc --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java @@ -0,0 +1,18 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Component +public class CustomBlockExceptionHandler implements BlockExceptionHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception { + throw e; + } + +} diff --git a/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java new file mode 100644 index 000000000..546fda816 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java @@ -0,0 +1,23 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +@Component +public class CustomRequestOriginParser implements RequestOriginParser { + + @Override + public String parseOrigin(HttpServletRequest request) { + // 从 Header 中,获得请求来源 + String origin = request.getHeader("s-user"); + // 如果为空,给一个默认的 + if (StringUtils.isEmpty(origin)) { + origin = "default"; + } + return origin; + } + +} diff --git a/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java new file mode 100644 index 000000000..f60b2fe69 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java @@ -0,0 +1,21 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.fastjson.JSONObject; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +@Component +@ControllerAdvice(basePackages = "cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider") +public class GlobalExceptionHandler { + + @ResponseBody + @ExceptionHandler(value = BlockException.class) // 因为这里是示例,所以暂时使用 JSONObject,实际项目最终定义一个 CommonResult。 + public JSONObject blockExceptionHandler(BlockException blockException) { + return new JSONObject().fluentPut("code", 1024) + .fluentPut("msg", "请求被拦截,拦截类型为 " + blockException.getClass().getSimpleName()); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/resources/application.yaml b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..9e74da412 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-demo01-provider/src/main/resources/application.yaml @@ -0,0 +1,13 @@ +spring: + application: + name: demo-provider + + cloud: + # Sentinel 配置项,对应 SentinelProperties 配置属性类 + sentinel: + enabled: true # 是否开启。默认为 true 开启 + eager: true # 是否饥饿加载。默认为 false 关闭 + transport: + dashboard: 127.0.0.1:7070 # Sentinel 控制台地址 + filter: + url-patterns: /** # 拦截请求的地址。默认为 /* diff --git a/labx-04/labx-04-sca-sentinel-feign-consumer/pom.xml b/labx-04/labx-04-sca-sentinel-feign-consumer/pom.xml new file mode 100644 index 000000000..fe6d7efe6 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-feign-consumer/pom.xml @@ -0,0 +1,72 @@ + + + + labx-04 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-04-sca-sentinel-feign-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoConsumerApplication.java b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoConsumerApplication.java new file mode 100644 index 000000000..d1c7c3356 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoConsumerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/ConsumerController.java b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/ConsumerController.java new file mode 100644 index 000000000..9a847fb4b --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/ConsumerController.java @@ -0,0 +1,21 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.controller; + +import cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.feign.DemoProviderFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/consumer") +public class ConsumerController { + + @Autowired + private DemoProviderFeignClient demoProviderFeignClient; + + @GetMapping("/echo") + public String echo() { + return demoProviderFeignClient.echo(); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/fallback/DemoProviderFeignClientFallback.java b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/fallback/DemoProviderFeignClientFallback.java new file mode 100644 index 000000000..e40c3a480 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/fallback/DemoProviderFeignClientFallback.java @@ -0,0 +1,18 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.fallback; + +import cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.feign.DemoProviderFeignClient; + +public class DemoProviderFeignClientFallback implements DemoProviderFeignClient { + + private Throwable throwable; + + public DemoProviderFeignClientFallback(Throwable throwable) { + this.throwable = throwable; + } + + @Override + public String echo() { + return "fallback:" + throwable.getClass().getSimpleName(); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/fallback/DemoProviderFeignClientFallbackFactory.java b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/fallback/DemoProviderFeignClientFallbackFactory.java new file mode 100644 index 000000000..63b9bd9d5 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/fallback/DemoProviderFeignClientFallbackFactory.java @@ -0,0 +1,31 @@ +/* + * Copyright 2013-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.fallback; + +import feign.hystrix.FallbackFactory; +import org.springframework.stereotype.Component; + +@Component +public class DemoProviderFeignClientFallbackFactory implements FallbackFactory { + + @Override + public DemoProviderFeignClientFallback create(Throwable throwable) { + // 可以给 DemoProviderFeignClientFallback 提供具体的 throwable 异常 + return new DemoProviderFeignClientFallback(throwable); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/feign/DemoProviderFeignClient.java b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/feign/DemoProviderFeignClient.java new file mode 100644 index 000000000..7d975ef8a --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/feign/DemoProviderFeignClient.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.feign; + +import cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.fallback.DemoProviderFeignClientFallbackFactory; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; + +@FeignClient(name = "demo-provider", url = "http://127.0.0.1:8080", + fallbackFactory = DemoProviderFeignClientFallbackFactory.class) +public interface DemoProviderFeignClient { + + @GetMapping("/demo/echo") + String echo(); + +} diff --git a/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/resources/application.yaml b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..91c6044b5 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-feign-consumer/src/main/resources/application.yaml @@ -0,0 +1,20 @@ +spring: + application: + name: demo-consumer + + cloud: + # Sentinel 配置项,对应 SentinelProperties 配置属性类 + sentinel: + enabled: true # 是否开启。默认为 true 开启 + eager: true # 是否饥饿加载。默认为 false 关闭 + transport: + dashboard: 127.0.0.1:7070 # Sentinel 控制台地址 + filter: + url-patterns: /** # 拦截请求的地址。默认为 /* + +server: + port: 8081 + +feign: + sentinel: + enabled: true # 开启 Sentinel 对 Feign 的支持,默认为 false 关闭。 diff --git a/labx-04/labx-04-sca-sentinel-file-provider/pom.xml b/labx-04/labx-04-sca-sentinel-file-provider/pom.xml new file mode 100644 index 000000000..a46eaaca9 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-file-provider/pom.xml @@ -0,0 +1,66 @@ + + + + labx-04 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-04-sca-sentinel-file-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + diff --git a/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java b/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java new file mode 100644 index 000000000..569f4d28e --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoProviderApplication.class, args); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java b/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java new file mode 100644 index 000000000..5a008fab3 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java @@ -0,0 +1,84 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.controller; + +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.annotation.SentinelResource; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + // 测试【流量控制】 + @GetMapping("/echo") + public String echo() { + return "echo"; + } + + @GetMapping("/test") + public String test() { + return "test"; + } + + // 测试【熔断降级】 + @GetMapping("/sleep") + public String sleep() throws InterruptedException { + Thread.sleep(100L); + return "sleep"; + } + + // 测试【热点参数限流】 + @GetMapping("/product_info") + @SentinelResource("demo_product_info_hot") + public String productInfo(Integer id) { + return "商品编号:" + id; + } + + // 测试「Sentinel 客户端 API」 + @GetMapping("/entry_demo") + public String entryDemo() { + Entry entry = null; + try { + // <1> 访问资源 + entry = SphU.entry("entry_demo"); + + // <2> ... 执行业务逻辑 + + return "执行成功"; + } catch (BlockException ex) { // <3> + return "被拒绝"; + } finally { + // <4> 释放资源 + if (entry != null) { + entry.exit(); + } + } + } + + // 测试「Sentinel @SentinelResource 注解」 + @GetMapping("/annotations_demo") + @SentinelResource(value = "annotations_demo_resource", + blockHandler = "blockHandler", + fallback = "fallback") + public String annotationsDemo(@RequestParam(required = false) Integer id) throws InterruptedException { + if (id == null) { + throw new IllegalArgumentException("id 参数不允许为空"); + } + return "success..."; + } + + // BlockHandler 处理函数,参数最后多一个 BlockException,其余与原函数一致. + public String blockHandler(Integer id, BlockException ex) { + return "block:" + ex.getClass().getSimpleName(); + } + + // Fallback 处理函数,函数签名与原函数一致或加一个 Throwable 类型的参数. + public String fallback(Integer id, Throwable throwable) { + return "fallback:" + throwable.getMessage(); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java b/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java new file mode 100644 index 000000000..6431c62cc --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java @@ -0,0 +1,18 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Component +public class CustomBlockExceptionHandler implements BlockExceptionHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception { + throw e; + } + +} diff --git a/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java b/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java new file mode 100644 index 000000000..546fda816 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java @@ -0,0 +1,23 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +@Component +public class CustomRequestOriginParser implements RequestOriginParser { + + @Override + public String parseOrigin(HttpServletRequest request) { + // 从 Header 中,获得请求来源 + String origin = request.getHeader("s-user"); + // 如果为空,给一个默认的 + if (StringUtils.isEmpty(origin)) { + origin = "default"; + } + return origin; + } + +} diff --git a/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java b/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java new file mode 100644 index 000000000..f60b2fe69 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-file-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java @@ -0,0 +1,21 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.fastjson.JSONObject; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +@Component +@ControllerAdvice(basePackages = "cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider") +public class GlobalExceptionHandler { + + @ResponseBody + @ExceptionHandler(value = BlockException.class) // 因为这里是示例,所以暂时使用 JSONObject,实际项目最终定义一个 CommonResult。 + public JSONObject blockExceptionHandler(BlockException blockException) { + return new JSONObject().fluentPut("code", 1024) + .fluentPut("msg", "请求被拦截,拦截类型为 " + blockException.getClass().getSimpleName()); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-file-provider/src/main/resources/application.yaml b/labx-04/labx-04-sca-sentinel-file-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..b216c11d7 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-file-provider/src/main/resources/application.yaml @@ -0,0 +1,22 @@ +spring: + application: + name: demo-provider + + cloud: + # Sentinel 配置项,对应 SentinelProperties 配置属性类 + sentinel: + enabled: true # 是否开启。默认为 true 开启 + eager: true # 是否饥饿加载。默认为 false 关闭 + transport: + dashboard: 127.0.0.1:7070 # Sentinel 控制台地址 + filter: + url-patterns: /** # 拦截请求的地址。默认为 /* + # Sentinel 规则的数据源,是一个 Map 类型。key 为数据源名,可自定义;value 为数据源的具体配置 + datasource: + ds1: + # 对应 DataSourcePropertiesConfiguration 类 + file: + file: /Users/yunai/Sentinel/demo-provider/flow-rule.json # 配置规则所在文件。 + recommendRefreshMs: 3000 # 定时读取实现刷新,默认为 3000 毫秒。 + data-type: json # 数据格式 + rule-type: FLOW # 规则类型 diff --git a/labx-04/labx-04-sca-sentinel-nacos-provider/pom.xml b/labx-04/labx-04-sca-sentinel-nacos-provider/pom.xml new file mode 100644 index 000000000..fb6cdb06b --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-nacos-provider/pom.xml @@ -0,0 +1,72 @@ + + + + labx-04 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-04-sca-sentinel-nacos-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + com.alibaba.csp + sentinel-datasource-nacos + + + + diff --git a/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java new file mode 100644 index 000000000..569f4d28e --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoProviderApplication.class, args); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java new file mode 100644 index 000000000..5a008fab3 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/DemoController.java @@ -0,0 +1,84 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.controller; + +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.annotation.SentinelResource; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + // 测试【流量控制】 + @GetMapping("/echo") + public String echo() { + return "echo"; + } + + @GetMapping("/test") + public String test() { + return "test"; + } + + // 测试【熔断降级】 + @GetMapping("/sleep") + public String sleep() throws InterruptedException { + Thread.sleep(100L); + return "sleep"; + } + + // 测试【热点参数限流】 + @GetMapping("/product_info") + @SentinelResource("demo_product_info_hot") + public String productInfo(Integer id) { + return "商品编号:" + id; + } + + // 测试「Sentinel 客户端 API」 + @GetMapping("/entry_demo") + public String entryDemo() { + Entry entry = null; + try { + // <1> 访问资源 + entry = SphU.entry("entry_demo"); + + // <2> ... 执行业务逻辑 + + return "执行成功"; + } catch (BlockException ex) { // <3> + return "被拒绝"; + } finally { + // <4> 释放资源 + if (entry != null) { + entry.exit(); + } + } + } + + // 测试「Sentinel @SentinelResource 注解」 + @GetMapping("/annotations_demo") + @SentinelResource(value = "annotations_demo_resource", + blockHandler = "blockHandler", + fallback = "fallback") + public String annotationsDemo(@RequestParam(required = false) Integer id) throws InterruptedException { + if (id == null) { + throw new IllegalArgumentException("id 参数不允许为空"); + } + return "success..."; + } + + // BlockHandler 处理函数,参数最后多一个 BlockException,其余与原函数一致. + public String blockHandler(Integer id, BlockException ex) { + return "block:" + ex.getClass().getSimpleName(); + } + + // Fallback 处理函数,函数签名与原函数一致或加一个 Throwable 类型的参数. + public String fallback(Integer id, Throwable throwable) { + return "fallback:" + throwable.getMessage(); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java new file mode 100644 index 000000000..6431c62cc --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomBlockExceptionHandler.java @@ -0,0 +1,18 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Component +public class CustomBlockExceptionHandler implements BlockExceptionHandler { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception { + throw e; + } + +} diff --git a/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java new file mode 100644 index 000000000..546fda816 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/CustomRequestOriginParser.java @@ -0,0 +1,23 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +@Component +public class CustomRequestOriginParser implements RequestOriginParser { + + @Override + public String parseOrigin(HttpServletRequest request) { + // 从 Header 中,获得请求来源 + String origin = request.getHeader("s-user"); + // 如果为空,给一个默认的 + if (StringUtils.isEmpty(origin)) { + origin = "default"; + } + return origin; + } + +} diff --git a/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java new file mode 100644 index 000000000..f60b2fe69 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/web/GlobalExceptionHandler.java @@ -0,0 +1,21 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.web; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.fastjson.JSONObject; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +@Component +@ControllerAdvice(basePackages = "cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider") +public class GlobalExceptionHandler { + + @ResponseBody + @ExceptionHandler(value = BlockException.class) // 因为这里是示例,所以暂时使用 JSONObject,实际项目最终定义一个 CommonResult。 + public JSONObject blockExceptionHandler(BlockException blockException) { + return new JSONObject().fluentPut("code", 1024) + .fluentPut("msg", "请求被拦截,拦截类型为 " + blockException.getClass().getSimpleName()); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/resources/application.yaml b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..3aa4edcf1 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-nacos-provider/src/main/resources/application.yaml @@ -0,0 +1,26 @@ +spring: + application: + name: demo-provider + + cloud: + # Sentinel 配置项,对应 SentinelProperties 配置属性类 + sentinel: + enabled: true # 是否开启。默认为 true 开启 + eager: true # 是否饥饿加载。默认为 false 关闭 + transport: + dashboard: 127.0.0.1:7070 # Sentinel 控制台地址 + filter: + url-patterns: /** # 拦截请求的地址。默认为 /* + # Sentinel 规则的数据源,是一个 Map 类型。key 为数据源名,可自定义;value 为数据源的具体配置 + datasource: + ds1: + # 对应 DataSourcePropertiesConfiguration 类 + nacos: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 +# data-id: demo-application-flow-rule +# data-id: demo-provider-flow-rule + namespace: # Nacos 命名空间 + group-id: DEFAULT_GROUP # Nacos 分组 + data-id: ${spring.application.name}-flow-rule # Nacos 配置集编号 + data-type: json # 数据格式 + rule-type: FLOW # 规则类型 diff --git a/labx-04/labx-04-sca-sentinel-resttemplate-consumer/pom.xml b/labx-04/labx-04-sca-sentinel-resttemplate-consumer/pom.xml new file mode 100644 index 000000000..06c99c752 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-resttemplate-consumer/pom.xml @@ -0,0 +1,66 @@ + + + + labx-04 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-04-sca-sentinel-resttemplate-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + diff --git a/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoConsumerApplication.java b/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoConsumerApplication.java new file mode 100644 index 000000000..8b9b9aed9 --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/DemoConsumerApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoConsumerApplication.class, args); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/config/RestTemplateConfiguration.java b/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/config/RestTemplateConfiguration.java new file mode 100644 index 000000000..6f68b22aa --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/config/RestTemplateConfiguration.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.config; + +import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfiguration { + + @Bean + @SentinelRestTemplate + public RestTemplate restTemplate() { + return new RestTemplate(); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/ConsumerController.java b/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/ConsumerController.java new file mode 100644 index 000000000..ea116288f --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx04/sentineldemo/provider/controller/ConsumerController.java @@ -0,0 +1,21 @@ +package cn.iocoder.springcloudalibaba.labx04.sentineldemo.provider.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@RestController +@RequestMapping("/consumer") +public class ConsumerController { + + @Autowired + private RestTemplate restTemplate; + + @GetMapping("/echo") + public String echo() { + return restTemplate.getForObject("http://127.0.0.1:8080/demo/echo", String.class); + } + +} diff --git a/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/resources/application.yaml b/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..741008a5b --- /dev/null +++ b/labx-04/labx-04-sca-sentinel-resttemplate-consumer/src/main/resources/application.yaml @@ -0,0 +1,20 @@ +spring: + application: + name: demo-consumer + + cloud: + # Sentinel 配置项,对应 SentinelProperties 配置属性类 + sentinel: + enabled: true # 是否开启。默认为 true 开启 + eager: true # 是否饥饿加载。默认为 false 关闭 + transport: + dashboard: 127.0.0.1:7070 # Sentinel 控制台地址 + filter: + url-patterns: /** # 拦截请求的地址。默认为 /* + +server: + port: 8081 + +resttemplate: + sentinel: + enabled: true # 开启 Sentinel 对 Feign 的支持,默认为 true 开启。 diff --git a/labx-04/pom.xml b/labx-04/pom.xml new file mode 100644 index 000000000..7b2f4f61a --- /dev/null +++ b/labx-04/pom.xml @@ -0,0 +1,28 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-04 + pom + + labx-04-sca-sentinel-demo01-provider + + labx-04-sca-sentinel-nacos-provider + labx-04-sca-sentinel-apollo-provider + labx-04-sca-sentinel-file-provider + + labx-04-sca-sentinel-feign-consumer + labx-04-sca-sentinel-resttemplate-consumer + + labx-04-sca-sentinel-actuator-provider + + + + diff --git "a/labx-04/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\234\215\345\212\241\345\256\271\351\224\231 Sentinel \345\205\245\351\227\250\343\200\213.md" "b/labx-04/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\234\215\345\212\241\345\256\271\351\224\231 Sentinel \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..a6d13a300 --- /dev/null +++ "b/labx-04/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\234\215\345\212\241\345\256\271\351\224\231 Sentinel \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-05/labx-05-sca-nacos-config-auto-refresh/pom.xml b/labx-05/labx-05-sca-nacos-config-auto-refresh/pom.xml new file mode 100644 index 000000000..07cb3dbdf --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-auto-refresh/pom.xml @@ -0,0 +1,66 @@ + + + + labx-05 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-05-sca-nacos-config-auto-refresh + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + diff --git a/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java b/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java new file mode 100644 index 000000000..e57a51b98 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class); + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/config/OrderProperties.java b/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/config/OrderProperties.java new file mode 100644 index 000000000..d62ac63d7 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/config/OrderProperties.java @@ -0,0 +1,47 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +// public String getDesc() { +// return desc; +// } +// +// public OrderProperties setDesc(String desc) { +// this.desc = desc; +// return this; +// } + +} diff --git a/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java b/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java new file mode 100644 index 000000000..6222190f9 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java @@ -0,0 +1,53 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo.controller; + +import cn.iocoder.springcloudalibaba.labx5.nacosdemo.config.OrderProperties; +import com.alibaba.fastjson.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +@RequestMapping("/demo") +@RefreshScope +public class DemoController { + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + return new JSONObject().fluentPut("payTimeoutSeconds", payTimeoutSeconds) + .fluentPut("createFrequencySeconds", createFrequencySeconds); + } + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @GetMapping("/logger") + public void logger() { + logger.debug("[logger][测试一下]"); + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/listener/DemoEnvironmentChangeListener.java b/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/listener/DemoEnvironmentChangeListener.java new file mode 100644 index 000000000..9496af0e4 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/listener/DemoEnvironmentChangeListener.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo.listener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.context.environment.EnvironmentChangeEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.stereotype.Component; + +@Component +public class DemoEnvironmentChangeListener implements ApplicationListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ConfigurableEnvironment environment; + + @Override + public void onApplicationEvent(EnvironmentChangeEvent event) { + for (String key : event.getKeys()) { + logger.info("[onApplicationEvent][key({}) 最新 value 为 {}]", key, environment.getProperty(key)); + } + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/resources/bootstrap.yaml b/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/resources/bootstrap.yaml new file mode 100644 index 000000000..fb5bb9ec3 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-auto-refresh/src/main/resources/bootstrap.yaml @@ -0,0 +1,13 @@ +spring: + application: + name: demo-application + + cloud: + nacos: + # Nacos Config 配置项,对应 NacosConfigProperties 配置属性类 + config: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + namespace: # 使用的 Nacos 的命名空间,默认为 null + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + name: # 使用的 Nacos 配置集的 dataId,默认为 spring.application.name + file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties diff --git a/labx-05/labx-05-sca-nacos-config-demo-actuator/pom.xml b/labx-05/labx-05-sca-nacos-config-demo-actuator/pom.xml new file mode 100644 index 000000000..f70fe8765 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-actuator/pom.xml @@ -0,0 +1,70 @@ + + + + labx-05 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-05-sca-nacos-config-demo-actuator + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java b/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java new file mode 100644 index 000000000..e57a51b98 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class); + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/config/OrderProperties.java b/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/config/OrderProperties.java new file mode 100644 index 000000000..0dde305d5 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/config/OrderProperties.java @@ -0,0 +1,53 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +//@NacosConfigurationProperties(prefix = "order", dataId = "${nacos.config.data-id}", type = ConfigType.YAML) +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + +// /** +// * 配置描述 +// */ +// private String desc; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +// public String getDesc() { +// return desc; +// } +// +// public OrderProperties setDesc(String desc) { +// this.desc = desc; +// return this; +// } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java b/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java new file mode 100644 index 000000000..a5d470ae4 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java @@ -0,0 +1,42 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo.controller; + +import cn.iocoder.springcloudalibaba.labx5.nacosdemo.config.OrderProperties; +import com.alibaba.fastjson.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") // @NacosValue(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") // @NacosValue(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + return new JSONObject().fluentPut("payTimeoutSeconds", payTimeoutSeconds) + .fluentPut("createFrequencySeconds", createFrequencySeconds); + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/resources/application.yaml b/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/resources/application.yaml new file mode 100644 index 000000000..0b69ce7f2 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/resources/application.yaml @@ -0,0 +1,10 @@ +management: + endpoint: + # Health 端点配置项,对应 HealthProperties 配置类 + health: + show-details: ALWAYS # 何时显示完整的健康信息。默认为 NEVER 都不展示。可选 WHEN_AUTHORIZED 当经过授权的用户;可选 ALWAYS 总是展示。 + endpoints: + # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类 + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/resources/bootstrap.yaml b/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/resources/bootstrap.yaml new file mode 100644 index 000000000..fb5bb9ec3 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-actuator/src/main/resources/bootstrap.yaml @@ -0,0 +1,13 @@ +spring: + application: + name: demo-application + + cloud: + nacos: + # Nacos Config 配置项,对应 NacosConfigProperties 配置属性类 + config: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + namespace: # 使用的 Nacos 的命名空间,默认为 null + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + name: # 使用的 Nacos 配置集的 dataId,默认为 spring.application.name + file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties diff --git a/labx-05/labx-05-sca-nacos-config-demo-jasypt/pom.xml b/labx-05/labx-05-sca-nacos-config-demo-jasypt/pom.xml new file mode 100644 index 000000000..4ad20d4f1 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-jasypt/pom.xml @@ -0,0 +1,81 @@ + + + + labx-05 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-05-sca-nacos-config-demo-jasypt + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.github.ulisesbocchio + jasypt-spring-boot-starter + 3.0.2 + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java b/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java new file mode 100644 index 000000000..e57a51b98 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class); + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java b/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java new file mode 100644 index 000000000..da8361c84 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo.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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +@RefreshScope +public class DemoController { + + @Value("${xxx-password:}") + private String xxxPassword; + + @GetMapping("/test") + public String test() { + return xxxPassword; + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/listener/JasyptEnvironmentChangeListener.java b/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/listener/JasyptEnvironmentChangeListener.java new file mode 100644 index 000000000..c4980ea86 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/listener/JasyptEnvironmentChangeListener.java @@ -0,0 +1,45 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo.listener; + +import org.apache.commons.lang3.StringUtils; +import org.jasypt.encryption.StringEncryptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.context.environment.EnvironmentChangeEvent; +import org.springframework.cloud.context.environment.EnvironmentManager; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +@Component +public class JasyptEnvironmentChangeListener implements ApplicationListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + // Environment 管理器,可以实现配置项的获取和修改 + @Autowired + private EnvironmentManager environmentManager; + + // Jasypt 加密器,可以对配置项进行加密和加密 + @Autowired + private StringEncryptor encryptor; + + @Override + public void onApplicationEvent(EnvironmentChangeEvent event) { + for (String key : event.getKeys()) { + // 获得 value + Object valueObj = environmentManager.getProperty(key); + if (!(valueObj instanceof String)) { + continue; + } + String value = (String) valueObj; + // 判断 value 是否为加密。如果是,则进行解密 + if (value.startsWith("ENC(") && value.endsWith(")")) { + value = encryptor.decrypt(StringUtils.substringBetween(value, "ENC(", ")")); + logger.info("[onApplicationEvent][key({}) 解密后为 {}]", key, value); + // 设置到 Environment 中 + environmentManager.setProperty(key, value); + } + } + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/resources/bootstrap.yaml b/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/resources/bootstrap.yaml new file mode 100644 index 000000000..657fb353e --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/main/resources/bootstrap.yaml @@ -0,0 +1,13 @@ +spring: + application: + name: demo-application-jasypt + + cloud: + nacos: + # Nacos Config 配置项,对应 NacosConfigProperties 配置属性类 + config: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + namespace: # 使用的 Nacos 的命名空间,默认为 null + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + name: # 使用的 Nacos 配置集的 dataId,默认为 spring.application.name + file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties diff --git a/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/test/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/JasyptTest.java b/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/test/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/JasyptTest.java new file mode 100644 index 000000000..4df1b5814 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-jasypt/src/test/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/JasyptTest.java @@ -0,0 +1,40 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo; + +import org.jasypt.encryption.StringEncryptor; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class JasyptTest { + + @Autowired + private StringEncryptor encryptor; + + @Test + public void encode() { + // 第一个加密 + String password = "woshimima"; + System.out.println(encryptor.encrypt(password)); + + // 第二个加密 + password = "bushimima"; + System.out.println(encryptor.encrypt(password)); + } + + @Value("${xxx-password:}") + private String xxxPassword; + + @Test + public void print() { + System.out.println(xxxPassword); + } + +// @Value("${jasypt.encryptor.password}") +// private String password; + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo-multi/pom.xml b/labx-05/labx-05-sca-nacos-config-demo-multi/pom.xml new file mode 100644 index 000000000..74e7ca67c --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-multi/pom.xml @@ -0,0 +1,64 @@ + + + + labx-05 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-05-sca-nacos-config-demo-multi + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + diff --git a/labx-05/labx-05-sca-nacos-config-demo-multi/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java b/labx-05/labx-05-sca-nacos-config-demo-multi/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java new file mode 100644 index 000000000..a7619a08b --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-multi/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.Environment; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + // 启动 Spring Boot 应用 + ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args); + + // 查看 Environment + Environment environment = context.getEnvironment(); + System.out.println(environment); + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo-multi/src/main/resources/bootstrap.yaml b/labx-05/labx-05-sca-nacos-config-demo-multi/src/main/resources/bootstrap.yaml new file mode 100644 index 000000000..2f20c1f82 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-multi/src/main/resources/bootstrap.yaml @@ -0,0 +1,32 @@ +spring: + application: + name: demo-application + + cloud: + nacos: + # Nacos Config 配置项,对应 NacosConfigProperties 配置属性类 + config: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + namespace: # 使用的 Nacos 的命名空间,默认为 null + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId,默认为 spring.application.name + file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties + # 拓展配置集数组,对应 Config 数组 + extension-configs: + - data-id: extension-dataId-01.yaml + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + refresh: true # 是否自动刷新配置,默认为 false + - data-id: extension-dataId-02.yaml + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + refresh: true # 是否自动刷新配置,默认为 false + # 共享配置集数组,对应 Config 数组 + shared-configs: + - data-id: shared-dataId-01.yaml + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + refresh: true # 是否自动刷新配置,默认为 false + - data-id: shared-dataId-02.yaml + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + refresh: true # 是否自动刷新配置,默认为 false + + profiles: + active: dev # 设置开启的 Profiles diff --git a/labx-05/labx-05-sca-nacos-config-demo-profiles/pom.xml b/labx-05/labx-05-sca-nacos-config-demo-profiles/pom.xml new file mode 100644 index 000000000..e8827fb29 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-profiles/pom.xml @@ -0,0 +1,64 @@ + + + + labx-05 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-05-sca-nacos-config-demo-profiles + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + diff --git a/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/ProfilesApplication.java b/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/ProfilesApplication.java new file mode 100644 index 000000000..7d9a50c70 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/ProfilesApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProfilesApplication { + + public static void main(String[] args) { + SpringApplication.run(ProfilesApplication.class); + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/resources/bootstrap-dev.yaml b/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/resources/bootstrap-dev.yaml new file mode 100644 index 000000000..de8156fbc --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/resources/bootstrap-dev.yaml @@ -0,0 +1,10 @@ +spring: + cloud: + nacos: + # Nacos Config 配置项,对应 NacosConfigProperties 配置属性类 + config: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + namespace: 14226a0d-799f-424d-8905-162f6a8bf409 # 使用的 Nacos 的命名空间,默认为 null + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + name: # 使用的 Nacos 配置集的 dataId,默认为 spring.application.name + file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties diff --git a/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/resources/bootstrap-prod.yaml b/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/resources/bootstrap-prod.yaml new file mode 100644 index 000000000..77156330f --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/resources/bootstrap-prod.yaml @@ -0,0 +1,10 @@ +spring: + cloud: + nacos: + # Nacos Config 配置项,对应 NacosConfigProperties 配置属性类 + config: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + namespace: f1686f3b-a984-4cdf-8298-7caee3455d14 # 使用的 Nacos 的命名空间,默认为 null + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + name: # 使用的 Nacos 配置集的 dataId,默认为 spring.application.name + file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties diff --git a/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/resources/bootstrap.yaml b/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/resources/bootstrap.yaml new file mode 100644 index 000000000..d6e31da97 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo-profiles/src/main/resources/bootstrap.yaml @@ -0,0 +1,3 @@ +spring: + application: + name: demo-application diff --git a/labx-05/labx-05-sca-nacos-config-demo/pom.xml b/labx-05/labx-05-sca-nacos-config-demo/pom.xml new file mode 100644 index 000000000..aa9515763 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo/pom.xml @@ -0,0 +1,64 @@ + + + + labx-05 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-05-sca-nacos-config-demo + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + diff --git a/labx-05/labx-05-sca-nacos-config-demo/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java b/labx-05/labx-05-sca-nacos-config-demo/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java new file mode 100644 index 000000000..e57a51b98 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/DemoApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class); + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/config/OrderProperties.java b/labx-05/labx-05-sca-nacos-config-demo/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/config/OrderProperties.java new file mode 100644 index 000000000..0dde305d5 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/config/OrderProperties.java @@ -0,0 +1,53 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +//@NacosConfigurationProperties(prefix = "order", dataId = "${nacos.config.data-id}", type = ConfigType.YAML) +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + +// /** +// * 配置描述 +// */ +// private String desc; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +// public String getDesc() { +// return desc; +// } +// +// public OrderProperties setDesc(String desc) { +// this.desc = desc; +// return this; +// } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java b/labx-05/labx-05-sca-nacos-config-demo/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java new file mode 100644 index 000000000..a5d470ae4 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo/src/main/java/cn/iocoder/springcloudalibaba/labx5/nacosdemo/controller/DemoController.java @@ -0,0 +1,42 @@ +package cn.iocoder.springcloudalibaba.labx5.nacosdemo.controller; + +import cn.iocoder.springcloudalibaba.labx5.nacosdemo.config.OrderProperties; +import com.alibaba.fastjson.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") // @NacosValue(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") // @NacosValue(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + return new JSONObject().fluentPut("payTimeoutSeconds", payTimeoutSeconds) + .fluentPut("createFrequencySeconds", createFrequencySeconds); + } + +} diff --git a/labx-05/labx-05-sca-nacos-config-demo/src/main/resources/bootstrap.yaml b/labx-05/labx-05-sca-nacos-config-demo/src/main/resources/bootstrap.yaml new file mode 100644 index 000000000..fb5bb9ec3 --- /dev/null +++ b/labx-05/labx-05-sca-nacos-config-demo/src/main/resources/bootstrap.yaml @@ -0,0 +1,13 @@ +spring: + application: + name: demo-application + + cloud: + nacos: + # Nacos Config 配置项,对应 NacosConfigProperties 配置属性类 + config: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + namespace: # 使用的 Nacos 的命名空间,默认为 null + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + name: # 使用的 Nacos 配置集的 dataId,默认为 spring.application.name + file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties diff --git a/labx-05/pom.xml b/labx-05/pom.xml new file mode 100644 index 000000000..aa337fce1 --- /dev/null +++ b/labx-05/pom.xml @@ -0,0 +1,24 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-05 + pom + + labx-05-sca-nacos-config-demo + labx-05-sca-nacos-config-demo-profiles + labx-05-sca-nacos-config-auto-refresh + labx-05-sca-nacos-config-demo-jasypt + labx-05-sca-nacos-config-demo-actuator + labx-05-sca-nacos-config-demo-multi + + + + diff --git "a/labx-05/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \351\205\215\347\275\256\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" "b/labx-05/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \351\205\215\347\275\256\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..ce9049785 --- /dev/null +++ "b/labx-05/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \351\205\215\347\275\256\344\270\255\345\277\203 Nacos \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/pom.xml new file mode 100644 index 000000000..c104de4af --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/pom.xml @@ -0,0 +1,72 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-consumer-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..347c2a794 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..f70019e99 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..27fb09774 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7ac462831 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..b4e95debf --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/src/main/resources/application.yml @@ -0,0 +1,38 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-input: + # RocketMQ Consumer 配置项,对应 RocketMQConsumerProperties 类 + consumer: + enabled: true # 是否开启消费,默认为 true + broadcasting: false # 是否使用广播消费,默认为 false 使用集群消费 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 + +management: + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + endpoint: + # Health 端点配置项,对应 HealthProperties 配置类 + health: + enabled: true # 是否开启。默认为 true 开启。 + show-details: ALWAYS # 何时显示完整的健康信息。默认为 NEVER 都不展示。可选 WHEN_AUTHORIZED 当经过授权的用户;可选 ALWAYS 总是展示。 diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/pom.xml new file mode 100644 index 000000000..b2ec61352 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-consumer-aliyun + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..347c2a794 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..f70019e99 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..27fb09774 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7ac462831 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/resources/application.yml new file mode 100644 index 000000000..01b2c4d15 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-aliyun/src/main/resources/application.yml @@ -0,0 +1,29 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: TOPIC_YUNAI_TEST # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + group: GID_PRODUCER_GROUP_YUNAI_TEST # 消费者分组 + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: onsaddr.mq-internet-access.mq-internet.aliyuncs.com:80 # RocketMQ Namesrv 地址 + access-key: ${ALIYUN_ACCESS_KEY} # 阿里云账号 AccessKey + secret-key: ${ALIYUN_SECRET_KEY} # 阿里云账号 SecretKey + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-input: + # RocketMQ Consumer 配置项,对应 RocketMQConsumerProperties 类 + consumer: + enabled: true # 是否开启消费,默认为 true + broadcasting: false # 是否使用广播消费,默认为 false 使用集群消费 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/pom.xml new file mode 100644 index 000000000..7bd4d7468 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-consumer-broadcasting + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..347c2a794 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..f70019e99 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..27fb09774 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7ac462831 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/resources/application.yml new file mode 100644 index 000000000..7946506b7 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-broadcasting/src/main/resources/application.yml @@ -0,0 +1,27 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01-X # 消费者分组 + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-input: + # RocketMQ Consumer 配置项,对应 RocketMQConsumerProperties 类 + consumer: + enabled: true # 是否开启消费,默认为 true + broadcasting: true # 是否使用广播消费,默认为 false 使用集群消费 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/pom.xml new file mode 100644 index 000000000..183567629 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-consumer-demo + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..347c2a794 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..f70019e99 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..27fb09774 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7ac462831 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/resources/application.yml new file mode 100644 index 000000000..1aae47ecd --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-demo/src/main/resources/application.yml @@ -0,0 +1,27 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-input: + # RocketMQ Consumer 配置项,对应 RocketMQConsumerProperties 类 + consumer: + enabled: true # 是否开启消费,默认为 true + broadcasting: false # 是否使用广播消费,默认为 false 使用集群消费 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/pom.xml new file mode 100644 index 000000000..935bf4c83 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-consumer-error-handler + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..347c2a794 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..cee9fd13e --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,40 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message.Demo01Message; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.integration.context.IntegrationContextUtils; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.support.ErrorMessage; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) // 对应 DEMO-TOPIC-01.demo01-consumer-group-DEMO-TOPIC-01 + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + // 注意,此处抛出一个 RuntimeException 异常,模拟消费失败 + throw new RuntimeException("我就是故意抛出一个异常"); + } + + @ServiceActivator(inputChannel = "DEMO-TOPIC-01.demo01-consumer-group-DEMO-TOPIC-01.errors") + public void handleError(ErrorMessage errorMessage) { + logger.error("[handleError][payload:{}]", ExceptionUtils.getRootCauseMessage(errorMessage.getPayload())); + logger.error("[handleError][originalMessage:{}]", errorMessage.getOriginalMessage()); + logger.error("[handleError][headers:{}]", errorMessage.getHeaders()); + } + + @StreamListener(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME) // errorChannel + public void globalHandleError(ErrorMessage errorMessage) { + logger.error("[globalHandleError][payload:{}]", ExceptionUtils.getRootCauseMessage(errorMessage.getPayload())); + logger.error("[globalHandleError][originalMessage:{}]", errorMessage.getOriginalMessage()); + logger.error("[globalHandleError][headers:{}]", errorMessage.getHeaders()); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..27fb09774 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7ac462831 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/resources/application.yml new file mode 100644 index 000000000..4544fc74c --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/src/main/resources/application.yml @@ -0,0 +1,31 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + max-attempts: 1 + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-input: + # RocketMQ Consumer 配置项,对应 RocketMQConsumerProperties 类 + consumer: + enabled: true # 是否开启消费,默认为 true + broadcasting: false # 是否使用广播消费,默认为 false 使用集群消费 + delay-level-when-next-consume: 0 # 异步消费消息模式下消费失败重试策略,默认为 0 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/pom.xml new file mode 100644 index 000000000..fe13bfed2 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-consumer-filter + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..347c2a794 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..1d7bbbbef --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,25 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +// @StreamListener(value = MySink.DEMO01_INPUT, condition = "headers['rocketmq_TAGS'] == 'yunai'") +// public void onMessage(@Payload Demo01Message message) { +// logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); +// } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..27fb09774 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7ac462831 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/resources/application.yml new file mode 100644 index 000000000..7aef2c614 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-filter/src/main/resources/application.yml @@ -0,0 +1,29 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-input: + # RocketMQ Consumer 配置项,对应 RocketMQConsumerProperties 类 + consumer: + enabled: true # 是否开启消费,默认为 true + broadcasting: false # 是否使用广播消费,默认为 false 使用集群消费 + tags: yunai || yutou # 基于 Tag 订阅,多个 Tag 使用 || 分隔,默认为空 + sql: # 基于 SQL 订阅,默认为空 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/pom.xml new file mode 100644 index 000000000..989f8d565 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-consumer-orderly + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..347c2a794 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..4773cabf4 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,19 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.Message; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..27fb09774 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7ac462831 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/resources/application.yml new file mode 100644 index 000000000..e3672922c --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-input: + # RocketMQ Consumer 配置项,对应 RocketMQConsumerProperties 类 + consumer: + enabled: true # 是否开启消费,默认为 true + broadcasting: false # 是否使用广播消费,默认为 false 使用集群消费 + orderly: true # 是否顺序消费,默认为 false 并发消费。 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/pom.xml new file mode 100644 index 000000000..c526ec2ea --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-consumer-retry + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..347c2a794 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..8db71e37a --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + // 注意,此处抛出一个 RuntimeException 异常,模拟消费失败 + throw new RuntimeException("我就是故意抛出一个异常"); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..27fb09774 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7ac462831 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/resources/application.yml new file mode 100644 index 000000000..4544fc74c --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-consumer-retry/src/main/resources/application.yml @@ -0,0 +1,31 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + max-attempts: 1 + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-input: + # RocketMQ Consumer 配置项,对应 RocketMQConsumerProperties 类 + consumer: + enabled: true # 是否开启消费,默认为 true + broadcasting: false # 是否使用广播消费,默认为 false 使用集群消费 + delay-level-when-next-consume: 0 # 异步消费消息模式下消费失败重试策略,默认为 0 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/pom.xml new file mode 100644 index 000000000..2644b3f17 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/pom.xml @@ -0,0 +1,72 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-producer-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..a811da6a0 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..3394c0b89 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,69 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.MySource; +import org.apache.rocketmq.common.message.MessageConst; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + + @GetMapping("/send_delay") + public boolean sendDelay() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "3") // 设置延迟级别为 3,10 秒后消费。 + .build(); + // 发送消息 + boolean sendResult = mySource.demo01Output().send(springMessage); + logger.info("[sendDelay][发送消息完成, 结果 = {}]", sendResult); + return sendResult; + } + + @GetMapping("/send_tag") + public boolean sendTag() { + for (String tag : new String[]{"yunai", "yutou", "tudou"}) { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader(MessageConst.PROPERTY_TAGS, tag) // 设置 Tag + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + } + return true; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..c7d1e4cd8 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..33079a2ab --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..f09a68cab --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-actuator/src/main/resources/application.yml @@ -0,0 +1,37 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-output: + # RocketMQ Producer 配置项,对应 RocketMQProducerProperties 类 + producer: + group: test # 生产者分组 + sync: true # 是否同步发送消息,默认为 false 异步。 + +server: + port: 18080 + +management: + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + endpoint: + # Health 端点配置项,对应 HealthProperties 配置类 + health: + enabled: true # 是否开启。默认为 true 开启。 + show-details: ALWAYS # 何时显示完整的健康信息。默认为 NEVER 都不展示。可选 WHEN_AUTHORIZED 当经过授权的用户;可选 ALWAYS 总是展示。 diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/pom.xml new file mode 100644 index 000000000..18f3563dd --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-producer-aliyun + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..a811da6a0 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..3394c0b89 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,69 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.MySource; +import org.apache.rocketmq.common.message.MessageConst; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + + @GetMapping("/send_delay") + public boolean sendDelay() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "3") // 设置延迟级别为 3,10 秒后消费。 + .build(); + // 发送消息 + boolean sendResult = mySource.demo01Output().send(springMessage); + logger.info("[sendDelay][发送消息完成, 结果 = {}]", sendResult); + return sendResult; + } + + @GetMapping("/send_tag") + public boolean sendTag() { + for (String tag : new String[]{"yunai", "yutou", "tudou"}) { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader(MessageConst.PROPERTY_TAGS, tag) // 设置 Tag + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + } + return true; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..c7d1e4cd8 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..33079a2ab --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/resources/application.yml new file mode 100644 index 000000000..6e0ef9000 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-aliyun/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: TOPIC_YUNAI_TEST # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: onsaddr.mq-internet-access.mq-internet.aliyuncs.com:80 # RocketMQ Namesrv 地址 + access-key: ${ALIYUN_ACCESS_KEY} # 阿里云账号 AccessKey + secret-key: ${ALIYUN_SECRET_KEY} # 阿里云账号 SecretKey + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-output: + # RocketMQ Producer 配置项,对应 RocketMQProducerProperties 类 + producer: + group: GID_PRODUCER_GROUP_YUNAI_TEST # 生产者分组 + sync: true # 是否同步发送消息,默认为 false 异步。 + +server: + port: 18080 diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-demo/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/pom.xml new file mode 100644 index 000000000..8e06d684b --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-producer-demo + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..a811da6a0 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..3394c0b89 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,69 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.MySource; +import org.apache.rocketmq.common.message.MessageConst; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + + @GetMapping("/send_delay") + public boolean sendDelay() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "3") // 设置延迟级别为 3,10 秒后消费。 + .build(); + // 发送消息 + boolean sendResult = mySource.demo01Output().send(springMessage); + logger.info("[sendDelay][发送消息完成, 结果 = {}]", sendResult); + return sendResult; + } + + @GetMapping("/send_tag") + public boolean sendTag() { + for (String tag : new String[]{"yunai", "yutou", "tudou"}) { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader(MessageConst.PROPERTY_TAGS, tag) // 设置 Tag + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + } + return true; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..c7d1e4cd8 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..33079a2ab --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/resources/application.yml new file mode 100644 index 000000000..157206e14 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-demo/src/main/resources/application.yml @@ -0,0 +1,26 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-output: + # RocketMQ Producer 配置项,对应 RocketMQProducerProperties 类 + producer: + group: test # 生产者分组 + sync: true # 是否同步发送消息,默认为 false 异步。 + +server: + port: 18080 diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/pom.xml new file mode 100644 index 000000000..4736fdde9 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-producer-orderly + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..a811da6a0 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..434a4a353 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,69 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.MySource; +import org.apache.rocketmq.common.message.MessageConst; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + + @GetMapping("/send_delay") + public boolean sendDelay() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "3") // 设置延迟级别为 3,10 秒后消费。 + .build(); + // 发送消息 + boolean sendResult = mySource.demo01Output().send(springMessage); + logger.info("[sendDelay][发送消息完成, 结果 = {}]", sendResult); + return sendResult; + } + + @GetMapping("/send_orderly") + public boolean sendOrderly() { + // 发送 3 条相同 id 的消息 + int id = new Random().nextInt(); + for (int i = 0; i < 3; i++) { + // 创建 Message + Demo01Message message = new Demo01Message().setId(id); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + } + return true; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..c7d1e4cd8 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..33079a2ab --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/resources/application.yml new file mode 100644 index 000000000..897f4bd76 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/src/main/resources/application.yml @@ -0,0 +1,29 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + # Producer 配置项,对应 ProducerProperties 类 + producer: + partition-key-expression: payload['id'] # 分区 key 表达式。该表达式基于 Spring EL,从消息中获得分区 key。 + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-output: + # RocketMQ Producer 配置项,对应 RocketMQProducerProperties 类 + producer: + group: test # 生产者分组 + sync: true # 是否同步发送消息,默认为 false 异步。 + +server: + port: 18080 diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/pom.xml b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/pom.xml new file mode 100644 index 000000000..acb68595e --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/pom.xml @@ -0,0 +1,66 @@ + + + + labx-06 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06-sca-stream-rocketmq-producer-transaction + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..a811da6a0 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..b6d43eb06 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,118 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message.MySource; +import com.alibaba.fastjson.JSON; +import org.apache.rocketmq.common.message.MessageConst; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + + @GetMapping("/send_delay") + public boolean sendDelay() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, "3") // 设置延迟级别为 3,10 秒后消费。 + .build(); + // 发送消息 + boolean sendResult = mySource.demo01Output().send(springMessage); + logger.info("[sendDelay][发送消息完成, 结果 = {}]", sendResult); + return sendResult; + } + + @GetMapping("/send_tag") + public boolean sendTag() { + for (String tag : new String[]{"yunai", "yutou", "tudou"}) { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader(MessageConst.PROPERTY_TAGS, tag) // 设置 Tag + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + } + return true; + } + + @GetMapping("/send_transaction") + public boolean sendTransaction() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Args args = new Args().setArgs1(1).setArgs2("2"); + Message springMessage = MessageBuilder.withPayload(message) + .setHeader("args", JSON.toJSONString(args)) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + + public static class Args { + + private Integer args1; + + private String args2; + + public Integer getArgs1() { + return args1; + } + + public Args setArgs1(Integer args1) { + this.args1 = args1; + return this; + } + + public String getArgs2() { + return args2; + } + + public Args setArgs2(String args2) { + this.args2 = args2; + return this; + } + + @Override + public String toString() { + return "Args{" + + "args1=" + args1 + + ", args2='" + args2 + '\'' + + '}'; + } + + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/listener/TransactionListenerImpl.java b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/listener/TransactionListenerImpl.java new file mode 100644 index 000000000..fbd4d93ea --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/listener/TransactionListenerImpl.java @@ -0,0 +1,34 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.listener; + +import cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.controller.Demo01Controller; +import com.alibaba.fastjson.JSON; +import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener; +import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener; +import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.messaging.Message; + +@RocketMQTransactionListener(txProducerGroup = "test") +public class TransactionListenerImpl implements RocketMQLocalTransactionListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) { + // 从消息 Header 中解析到 args 参数,并使用 JSON 反序列化 + Demo01Controller.Args args = JSON.parseObject(msg.getHeaders().get("args", String.class), + Demo01Controller.Args.class); + // ... local transaction process, return rollback, commit or unknown + logger.info("[executeLocalTransaction][执行本地事务,消息:{} args:{}]", msg, args); + return RocketMQLocalTransactionState.UNKNOWN; + } + + @Override + public RocketMQLocalTransactionState checkLocalTransaction(Message msg) { + // ... check transaction status and return rollback, commit or unknown + logger.info("[checkLocalTransaction][回查消息:{}]", msg); + return RocketMQLocalTransactionState.COMMIT; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..c7d1e4cd8 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..33079a2ab --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/java/cn/iocoder/springcloudalibaba/labx6/rocketmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloudalibaba.labx6.rocketmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/resources/application.yml b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/resources/application.yml new file mode 100644 index 000000000..7d6894361 --- /dev/null +++ b/labx-06/labx-06-sca-stream-rocketmq-producer-transaction/src/main/resources/application.yml @@ -0,0 +1,27 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-output: + # RocketMQ Producer 配置项,对应 RocketMQProducerProperties 类 + producer: + group: test # 生产者分组 + sync: true # 是否同步发送消息,默认为 false 异步。 + transactional: true # 是否发送事务消息,默认为 false。 + +server: + port: 18080 diff --git a/labx-06/pom.xml b/labx-06/pom.xml new file mode 100644 index 000000000..72ece8e1d --- /dev/null +++ b/labx-06/pom.xml @@ -0,0 +1,38 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-06 + pom + + labx-06-sca-stream-rocketmq-consumer-demo + labx-06-sca-stream-rocketmq-producer-demo + + labx-06-sca-stream-rocketmq-consumer-retry + labx-06-sca-stream-rocketmq-consumer-error-handler + + labx-06-sca-stream-rocketmq-consumer-broadcasting + + labx-06-sca-stream-rocketmq-producer-orderly + labx-06-sca-stream-rocketmq-consumer-orderly + + labx-06-sca-stream-rocketmq-consumer-filter + + labx-06-sca-stream-rocketmq-producer-transaction + + labx-06-sca-stream-rocketmq-producer-actuator + labx-06-sca-stream-rocketmq-consumer-actuator + + labx-06-sca-stream-rocketmq-producer-aliyun + labx-06-sca-stream-rocketmq-consumer-aliyun + + + + diff --git "a/labx-06/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\266\210\346\201\257\351\230\237\345\210\227 RocketMQ \345\205\245\351\227\250\343\200\213.md" "b/labx-06/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\266\210\346\201\257\351\230\237\345\210\227 RocketMQ \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..b7957ba33 --- /dev/null +++ "b/labx-06/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\266\210\346\201\257\351\230\237\345\210\227 RocketMQ \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/pom.xml b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/pom.xml new file mode 100644 index 000000000..6cf89d13c --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/pom.xml @@ -0,0 +1,15 @@ + + + + labx-07-sca-dubbo-demo01 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo01-api + + + diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java new file mode 100644 index 000000000..0bf0261bc --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloudalibaba.labx7.api; + +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; + +/** + * 用户服务 RPC Service 接口 + */ +public interface UserService { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + UserDTO get(Integer id); + + /** + * 添加新用户,返回新添加的用户编号 + * + * @param addDTO 添加的用户信息 + * @return 用户编号 + */ + Integer add(UserAddDTO addDTO); + +} diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java new file mode 100644 index 000000000..85905efaa --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloudalibaba.labx7.dto; + +import java.io.Serializable; + +/** + * 用户添加 DTO + */ +public class UserAddDTO implements Serializable { + + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public String getName() { + return name; + } + + public UserAddDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserAddDTO setGender(Integer gender) { + this.gender = gender; + return this; + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java new file mode 100644 index 000000000..17a0b4572 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java @@ -0,0 +1,49 @@ +package cn.iocoder.springcloudalibaba.labx7.dto; + +import java.io.Serializable; + +/** + * 用户信息 DTO + */ +public class UserDTO implements Serializable { + + /** + * 用户编号 + */ + private Integer id; + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public Integer getId() { + return id; + } + + public UserDTO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public UserDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserDTO setGender(Integer gender) { + this.gender = gender; + return this; + } +} diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/pom.xml b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/pom.xml new file mode 100644 index 000000000..c2bf27ef2 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/pom.xml @@ -0,0 +1,79 @@ + + + + labx-07-sca-dubbo-demo01 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo01-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo01-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..d27e5af4e --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java new file mode 100644 index 000000000..bae4b56ea --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; +import org.apache.dubbo.config.annotation.Reference; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Reference(protocol = "dubbo", version = "1.0.0") + private UserService userService; + + @GetMapping("/get") + public UserDTO get(@RequestParam("id") Integer id) { + return userService.get(id); + } + + @PostMapping("/add") + public Integer add(UserAddDTO addDTO) { + return userService.add(addDTO); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..ca3778592 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-consumer/src/main/resources/application.yaml @@ -0,0 +1,17 @@ +spring: + application: + name: demo-consumer + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: demo-provider # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/pom.xml b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/pom.xml new file mode 100644 index 000000000..d34bd4dbc --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/pom.xml @@ -0,0 +1,73 @@ + + + + labx-07-sca-dubbo-demo01 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo01-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo01-api + 1.0-SNAPSHOT + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java new file mode 100644 index 000000000..454251b56 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(ProviderApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java new file mode 100644 index 000000000..ea285160f --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo.service; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; + +@org.apache.dubbo.config.annotation.Service(protocol = "dubbo", version = "1.0.0") +public class UserServiceImpl implements UserService { + + @Override + public UserDTO get(Integer id) { + return new UserDTO().setId(id) + .setName("没有昵称:" + id) + .setGender(id % 2 + 1); // 1 - 男;2 - 女 + } + + @Override + public Integer add(UserAddDTO addDTO) { + return (int) (System.currentTimeMillis() / 1000); // 嘿嘿,随便返回一个 id + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..a9d67ac92 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/labx-07-sca-dubbo-demo01-provider/src/main/resources/application.yaml @@ -0,0 +1,24 @@ +spring: + application: + name: demo-provider + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + scan: + base-packages: cn.iocoder.springcloudalibaba.labx7.providerdemo.service # 指定 Dubbo 服务实现类的扫描基准包 + # Dubbo 服务暴露的协议配置,对应 ProtocolConfig Map + protocols: + dubbo: + name: dubbo # 协议名称 + port: -1 # 协议端口,-1 表示自增端口,从 20880 开始 + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-07/labx-07-sca-dubbo-demo01/pom.xml b/labx-07/labx-07-sca-dubbo-demo01/pom.xml new file mode 100644 index 000000000..39b962a57 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo01/pom.xml @@ -0,0 +1,21 @@ + + + + labx-07 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo01 + pom + + labx-07-sca-dubbo-demo01-api + labx-07-sca-dubbo-demo01-provider + labx-07-sca-dubbo-demo01-consumer + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/pom.xml b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/pom.xml new file mode 100644 index 000000000..4cf73ba5e --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/pom.xml @@ -0,0 +1,15 @@ + + + + labx-07-sca-dubbo-demo02 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo02-api + + + diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java new file mode 100644 index 000000000..0bf0261bc --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloudalibaba.labx7.api; + +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; + +/** + * 用户服务 RPC Service 接口 + */ +public interface UserService { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + UserDTO get(Integer id); + + /** + * 添加新用户,返回新添加的用户编号 + * + * @param addDTO 添加的用户信息 + * @return 用户编号 + */ + Integer add(UserAddDTO addDTO); + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java new file mode 100644 index 000000000..85905efaa --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloudalibaba.labx7.dto; + +import java.io.Serializable; + +/** + * 用户添加 DTO + */ +public class UserAddDTO implements Serializable { + + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public String getName() { + return name; + } + + public UserAddDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserAddDTO setGender(Integer gender) { + this.gender = gender; + return this; + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java new file mode 100644 index 000000000..17a0b4572 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java @@ -0,0 +1,49 @@ +package cn.iocoder.springcloudalibaba.labx7.dto; + +import java.io.Serializable; + +/** + * 用户信息 DTO + */ +public class UserDTO implements Serializable { + + /** + * 用户编号 + */ + private Integer id; + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public Integer getId() { + return id; + } + + public UserDTO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public UserDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserDTO setGender(Integer gender) { + this.gender = gender; + return this; + } +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/pom.xml b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/pom.xml new file mode 100644 index 000000000..56bcfdc7d --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/pom.xml @@ -0,0 +1,85 @@ + + + + labx-07-sca-dubbo-demo02 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo02-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo02-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/FeignConsumerApplication.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/FeignConsumerApplication.java new file mode 100644 index 000000000..1e1da1421 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/FeignConsumerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class FeignConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(FeignConsumerApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/config/RestTemplateConfig.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/config/RestTemplateConfig.java new file mode 100644 index 000000000..b40f95b79 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/config/RestTemplateConfig.java @@ -0,0 +1,19 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.config; + +import com.alibaba.cloud.dubbo.annotation.DubboTransported; +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; + +@Configuration +public class RestTemplateConfig { + + @Bean + @LoadBalanced + @DubboTransported(protocol = "dubbo") + public RestTemplate restTemplate() { + return new RestTemplate(); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User01Controller.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User01Controller.java new file mode 100644 index 000000000..c6d6848d8 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User01Controller.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx7.consumerdemo.feign.UserFeignClient; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/user01") +public class User01Controller { + + @Autowired + private UserFeignClient userFeignClient; + + @GetMapping("/get") + public UserDTO get(@RequestParam("id") Integer id) { + return userFeignClient.get(id); + } + + @PostMapping("/add") + public Integer add(UserAddDTO addDTO) { + return userFeignClient.add(addDTO); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User02Controller.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User02Controller.java new file mode 100644 index 000000000..ddde52a6f --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User02Controller.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx7.consumerdemo.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.consumerdemo.dto.UserDTO; +import cn.iocoder.springcloudalibaba.labx7.consumerdemo.feign.UserFeignClient02; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/user02") +public class User02Controller { + + @Autowired + private UserFeignClient02 userFeignClient; + + @GetMapping("/get") + public UserDTO get(@RequestParam("id") Integer id) { + return userFeignClient.get(id); + } + + @PostMapping("/add") + public Integer add(UserAddDTO addDTO) { + return userFeignClient.add(addDTO); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User03Controller.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User03Controller.java new file mode 100644 index 000000000..2089bec79 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User03Controller.java @@ -0,0 +1,40 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; +import com.alibaba.fastjson.JSON; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestTemplate; + +@RestController +@RequestMapping("/user03") +public class User03Controller { + + @Autowired + private RestTemplate restTemplate; + + @GetMapping("/get") + public UserDTO get(@RequestParam("id") Integer id) { + String url = String.format("http://%s/user/get?id=%d", "demo-provider", id); + return restTemplate.getForObject(url, UserDTO.class); + } + + @PostMapping("/add") + public Integer add(UserAddDTO addDTO) { + // 请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + // 请求体 + String body = JSON.toJSONString(addDTO); + // 创建 HttpEntity 对象 + HttpEntity entity = new HttpEntity<>(body, headers); + // 执行请求 + String url = String.format("http://%s/user/add", "demo-provider"); + return restTemplate.postForObject(url, entity, Integer.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User04Controller.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User04Controller.java new file mode 100644 index 000000000..137f893e1 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/User04Controller.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; +import org.apache.dubbo.config.annotation.Reference; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/user04") +public class User04Controller { + + @Reference(version = "1.0.0", protocol = "dubbo") + private UserService userService; + + @GetMapping("/get") + public UserDTO get(@RequestParam("id") Integer id) { + return userService.get(id); + } + + @PostMapping("/add") + public Integer add(UserAddDTO addDTO) { + return userService.add(addDTO); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/dto/UserAddDTO.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/dto/UserAddDTO.java new file mode 100644 index 000000000..42fb2604b --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/dto/UserAddDTO.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.dto; + +import java.io.Serializable; + +/** + * 用户添加 DTO + */ +public class UserAddDTO implements Serializable { + + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public String getName() { + return name; + } + + public UserAddDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserAddDTO setGender(Integer gender) { + this.gender = gender; + return this; + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/dto/UserDTO.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/dto/UserDTO.java new file mode 100644 index 000000000..5bd3e03fa --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/dto/UserDTO.java @@ -0,0 +1,49 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.dto; + +import java.io.Serializable; + +/** + * 用户信息 DTO + */ +public class UserDTO implements Serializable { + + /** + * 用户编号 + */ + private Integer id; + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public Integer getId() { + return id; + } + + public UserDTO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public UserDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserDTO setGender(Integer gender) { + this.gender = gender; + return this; + } +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/feign/UserFeignClient.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/feign/UserFeignClient.java new file mode 100644 index 000000000..b5b7677c2 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/feign/UserFeignClient.java @@ -0,0 +1,35 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.feign; + +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; +import com.alibaba.cloud.dubbo.annotation.DubboTransported; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "demo-provider") +@DubboTransported(protocol = "dubbo") +// @DubboTransported(protocol = "rest") +public interface UserFeignClient { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + @GetMapping("/user/get") + UserDTO get(@RequestParam("id") Integer id); + + /** + * 添加新用户,返回新添加的用户编号 + * + * @param addDTO 添加的用户信息 + * @return 用户编号 + */ + @PostMapping("/user/add") + Integer add(@RequestBody UserAddDTO addDTO); + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/feign/UserFeignClient02.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/feign/UserFeignClient02.java new file mode 100644 index 000000000..3ebe32581 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/feign/UserFeignClient02.java @@ -0,0 +1,32 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.feign; + +import cn.iocoder.springcloudalibaba.labx7.consumerdemo.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.consumerdemo.dto.UserDTO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "demo-provider") +public interface UserFeignClient02 { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + @GetMapping("/user/get") + UserDTO get(@RequestParam("id") Integer id); + + /** + * 添加新用户,返回新添加的用户编号 + * + * @param addDTO 添加的用户信息 + * @return 用户编号 + */ + @PostMapping("/user/add") + Integer add(@RequestBody UserAddDTO addDTO); + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..ca3778592 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-consumer/src/main/resources/application.yaml @@ -0,0 +1,17 @@ +spring: + application: + name: demo-consumer + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: demo-provider # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/pom.xml b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/pom.xml new file mode 100644 index 000000000..ccff8b613 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/pom.xml @@ -0,0 +1,113 @@ + + + + labx-07-sca-dubbo-demo02 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo02-provider-rest + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + 2.7.4.1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + + + + + + + + + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo02-api + 1.0-SNAPSHOT + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + jsr311-api + javax.ws.rs + + + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + + org.jboss.resteasy + resteasy-netty4 + 3.0.19.Final + + + org.hibernate.validator + hibernate-validator + + + javax.servlet + javax.servlet-api + 3.1.0 + + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/RestProviderApplication.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/RestProviderApplication.java new file mode 100644 index 000000000..c4538cdfc --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/RestProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class RestProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(RestProviderApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java new file mode 100644 index 000000000..ba69bcb0b --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java @@ -0,0 +1,34 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo.service; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; + +import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE; + +@org.apache.dubbo.config.annotation.Service(version = "1.0.0", protocol = {"dubbo", "rest"}) +@Path("/user") +public class UserServiceImpl implements UserService { + + @Override + @GET + @Path("/get") + @Produces(APPLICATION_JSON_VALUE) + public UserDTO get(@QueryParam("id") Integer id) { + return new UserDTO().setId(id) + .setName("没有昵称:" + id) + .setGender(id % 2 + 1); // 1 - 男;2 - 女 + } + + @Override + @POST + @Path("/add") + @Consumes(MediaType.APPLICATION_JSON) + public Integer add(UserAddDTO addDTO) { + return (int) (System.currentTimeMillis() / 1000); // 嘿嘿,随便返回一个 id + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/src/main/resources/application.yaml new file mode 100644 index 000000000..88dc924e5 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-rest/src/main/resources/application.yaml @@ -0,0 +1,30 @@ +spring: + application: + name: demo-provider + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + main: + web-application-type: NONE # Web 应用类型,这里设置为 NONE + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + scan: + base-packages: cn.iocoder.springcloudalibaba.labx7.providerdemo.service # 指定 Dubbo 服务实现类的扫描基准包 + # Dubbo 服务暴露的协议配置,对应 ProtocolConfig Map + protocols: + dubbo: + name: dubbo # 协议名称 + port: -1 # 协议端口,-1 表示自增端口,从 20880 开始 + rest: + name: rest + port: 9090 # 协议端口 + server: netty # 使用的服务器 + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/pom.xml b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/pom.xml new file mode 100644 index 000000000..0beecf2dc --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/pom.xml @@ -0,0 +1,92 @@ + + + + labx-07-sca-dubbo-demo02 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo02-provider-springmvc + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo01-api + 1.0-SNAPSHOT + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.apache.dubbo + dubbo-spring-boot-actuator + 2.7.4.1 + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/SpringMVCProviderApplication.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/SpringMVCProviderApplication.java new file mode 100644 index 000000000..98d05d48b --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/SpringMVCProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringMVCProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringMVCProviderApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java new file mode 100644 index 000000000..2099ddb31 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo.service; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; +import org.springframework.web.bind.annotation.*; + +@org.apache.dubbo.config.annotation.Service(version = "1.0.0", protocol = {"dubbo"}) +@RestController +@RequestMapping("/user") +public class UserServiceImpl implements UserService { + + @Override + @GetMapping("/get") + public UserDTO get(@RequestParam("id") Integer id) { + return new UserDTO().setId(id) + .setName("没有昵称:" + id) + .setGender(id % 2 + 1); // 1 - 男;2 - 女 + } + + @Override + @PostMapping("/add") + public Integer add(@RequestBody UserAddDTO addDTO) { + return (int) (System.currentTimeMillis() / 1000); // 嘿嘿,随便返回一个 id + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/src/main/resources/application.yaml new file mode 100644 index 000000000..ef11342db --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/labx-07-sca-dubbo-demo02-provider-springmvc/src/main/resources/application.yaml @@ -0,0 +1,38 @@ +spring: + application: + name: demo-provider + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +server: + port: 18080 # 服务器端口,默认为 8080 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + scan: + base-packages: cn.iocoder.springcloudalibaba.labx7.providerdemo.service # 指定 Dubbo 服务实现类的扫描基准包 + # Dubbo 服务暴露的协议配置,对应 ProtocolConfig Map + protocols: + dubbo: + name: dubbo # 协议名称 + port: -1 # 协议端口,-1 表示自增端口,从 20880 开始 + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 + +management: + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + endpoint: + # Health 端点配置项,对应 HealthProperties 配置类 + health: + enabled: true # 是否开启。默认为 true 开启。 + show-details: ALWAYS # 何时显示完整的健康信息。默认为 NEVER 都不展示。可选 WHEN_AUTHORIZED 当经过授权的用户;可选 ALWAYS 总是展示。 diff --git a/labx-07/labx-07-sca-dubbo-demo02/pom.xml b/labx-07/labx-07-sca-dubbo-demo02/pom.xml new file mode 100644 index 000000000..0bc935906 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo02/pom.xml @@ -0,0 +1,23 @@ + + + + labx-07 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo02 + pom + + labx-07-sca-dubbo-demo02-api + + labx-07-sca-dubbo-demo02-provider-rest + labx-07-sca-dubbo-demo02-provider-springmvc + labx-07-sca-dubbo-demo02-consumer + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/pom.xml b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/pom.xml new file mode 100644 index 000000000..2624b5374 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/pom.xml @@ -0,0 +1,33 @@ + + + + labx-07-sca-dubbo-demo03-validation + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo03-api + + + + + javax.validation + validation-api + 2.0.1.Final + + + org.hibernate.validator + hibernate-validator + 6.0.18.Final + + + org.glassfish + javax.el + 3.0.1-b11 + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java new file mode 100644 index 000000000..374d6640f --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java @@ -0,0 +1,32 @@ +package cn.iocoder.springcloudalibaba.labx7.api; + +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; + +import javax.validation.ConstraintViolationException; +import javax.validation.constraints.NotNull; + +/** + * 用户服务 RPC Service 接口 + */ +public interface UserService { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + UserDTO get(@NotNull(message = "用户编号不能为空") Integer id) + throws ConstraintViolationException;; + + /** + * 添加新用户,返回新添加的用户编号 + * + * @param addDTO 添加的用户信息 + * @return 用户编号 + */ + Integer add(UserAddDTO addDTO) + throws ConstraintViolationException;; + +} diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java new file mode 100644 index 000000000..dd01bb7a2 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java @@ -0,0 +1,44 @@ +package cn.iocoder.springcloudalibaba.labx7.dto; + +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 用户添加 DTO + */ +public class UserAddDTO implements Serializable { + + /** + * 昵称 + */ + @NotEmpty(message = "昵称不能为空") + @Length(min = 5, max = 16, message = "账号长度为 5-16 位") + private String name; + /** + * 性别 + */ + @NotNull(message = "性别不能为空") + private Integer gender; + + public String getName() { + return name; + } + + public UserAddDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserAddDTO setGender(Integer gender) { + this.gender = gender; + return this; + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java new file mode 100644 index 000000000..17a0b4572 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java @@ -0,0 +1,49 @@ +package cn.iocoder.springcloudalibaba.labx7.dto; + +import java.io.Serializable; + +/** + * 用户信息 DTO + */ +public class UserDTO implements Serializable { + + /** + * 用户编号 + */ + private Integer id; + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public Integer getId() { + return id; + } + + public UserDTO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public UserDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserDTO setGender(Integer gender) { + this.gender = gender; + return this; + } +} diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/pom.xml b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/pom.xml new file mode 100644 index 000000000..ac907efc6 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/pom.xml @@ -0,0 +1,79 @@ + + + + labx-07-sca-dubbo-demo03-validation + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo03-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo03-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..d27e5af4e --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java new file mode 100644 index 000000000..9d115ab0f --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; +import org.apache.dubbo.config.annotation.Reference; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Reference(protocol = "dubbo", version = "1.0.0", validation = "true") + private UserService userService; + + @GetMapping("/get") + public UserDTO get(@RequestParam("id") Integer id) { + return userService.get(id); + } + + @PostMapping("/add") + public Integer add(UserAddDTO addDTO) { + return userService.add(addDTO); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..ca3778592 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-consumer/src/main/resources/application.yaml @@ -0,0 +1,17 @@ +spring: + application: + name: demo-consumer + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: demo-provider # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/pom.xml b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/pom.xml new file mode 100644 index 000000000..a5cfe696d --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/pom.xml @@ -0,0 +1,73 @@ + + + + labx-07-sca-dubbo-demo03-validation + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo03-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo03-api + 1.0-SNAPSHOT + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java new file mode 100644 index 000000000..454251b56 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(ProviderApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java new file mode 100644 index 000000000..578f96f8a --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo.service; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; + +@org.apache.dubbo.config.annotation.Service(protocol = "dubbo", version = "1.0.0", validation = "true") +public class UserServiceImpl implements UserService { + + @Override + public UserDTO get(Integer id) { + return new UserDTO().setId(id) + .setName("没有昵称:" + id) + .setGender(id % 2 + 1); // 1 - 男;2 - 女 + } + + @Override + public Integer add(UserAddDTO addDTO) { + return (int) (System.currentTimeMillis() / 1000); // 嘿嘿,随便返回一个 id + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..a9d67ac92 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/labx-07-sca-dubbo-demo03-provider/src/main/resources/application.yaml @@ -0,0 +1,24 @@ +spring: + application: + name: demo-provider + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + scan: + base-packages: cn.iocoder.springcloudalibaba.labx7.providerdemo.service # 指定 Dubbo 服务实现类的扫描基准包 + # Dubbo 服务暴露的协议配置,对应 ProtocolConfig Map + protocols: + dubbo: + name: dubbo # 协议名称 + port: -1 # 协议端口,-1 表示自增端口,从 20880 开始 + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-07/labx-07-sca-dubbo-demo03-validation/pom.xml b/labx-07/labx-07-sca-dubbo-demo03-validation/pom.xml new file mode 100644 index 000000000..65ac25d9a --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo03-validation/pom.xml @@ -0,0 +1,20 @@ + + + + labx-07 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo03-validation + pom + + labx-07-sca-dubbo-demo03-api + labx-07-sca-dubbo-demo03-provider + labx-07-sca-dubbo-demo03-consumer + + + diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/pom.xml b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/pom.xml new file mode 100644 index 000000000..4d6e964ae --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/pom.xml @@ -0,0 +1,33 @@ + + + + labx-07-sca-dubbo-demo04-filter + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo04-api + + + + + javax.validation + validation-api + 2.0.1.Final + + + org.hibernate.validator + hibernate-validator + 6.0.18.Final + + + org.glassfish + javax.el + 3.0.1-b11 + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java new file mode 100644 index 000000000..374d6640f --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java @@ -0,0 +1,32 @@ +package cn.iocoder.springcloudalibaba.labx7.api; + +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; + +import javax.validation.ConstraintViolationException; +import javax.validation.constraints.NotNull; + +/** + * 用户服务 RPC Service 接口 + */ +public interface UserService { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + UserDTO get(@NotNull(message = "用户编号不能为空") Integer id) + throws ConstraintViolationException;; + + /** + * 添加新用户,返回新添加的用户编号 + * + * @param addDTO 添加的用户信息 + * @return 用户编号 + */ + Integer add(UserAddDTO addDTO) + throws ConstraintViolationException;; + +} diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/core/ServiceException.java b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/core/ServiceException.java new file mode 100644 index 000000000..9593fb062 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/core/ServiceException.java @@ -0,0 +1,58 @@ +package cn.iocoder.springcloudalibaba.labx7.core; + +/** + * 服务异常 + * + * 参考 https://www.kancloud.cn/onebase/ob/484204 文章 + * + * 一共 10 位,分成四段 + * + * 第一段,1 位,类型 + * 1 - 业务级别异常 + * 2 - 系统级别异常 + * 第二段,3 位,系统类型 + * 001 - 用户系统 + * 002 - 商品系统 + * 003 - 订单系统 + * 004 - 支付系统 + * 005 - 优惠劵系统 + * ... - ... + * 第三段,3 位,模块 + * 不限制规则。 + * 一般建议,每个系统里面,可能有多个模块,可以再去做分段。以用户系统为例子: + * 001 - OAuth2 模块 + * 002 - User 模块 + * 003 - MobileCode 模块 + * 第四段,3 位,错误码 + * 不限制规则。 + * 一般建议,每个模块自增。 + */ +public final class ServiceException extends RuntimeException { + + /** + * 错误码 + */ + private Integer code; + + public ServiceException() { // 创建默认构造方法,用于反序列化的场景。 + } + + public ServiceException(ServiceExceptionEnum serviceExceptionEnum) { + // 使用父类的 message 字段 + super(serviceExceptionEnum.getMessage()); + // 设置错误码 + this.code = serviceExceptionEnum.getCode(); + } + + public ServiceException(ServiceExceptionEnum serviceExceptionEnum, String message) { + // 使用父类的 message 字段 + super(message); + // 设置错误码 + this.code = serviceExceptionEnum.getCode(); + } + + public Integer getCode() { + return code; + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/core/ServiceExceptionEnum.java b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/core/ServiceExceptionEnum.java new file mode 100644 index 000000000..dc91d7908 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/core/ServiceExceptionEnum.java @@ -0,0 +1,45 @@ +package cn.iocoder.springcloudalibaba.labx7.core; + +/** + * 业务异常枚举 + */ +public enum ServiceExceptionEnum { + + // ========== 系统级别 ========== + SUCCESS(0, "成功"), + SYS_ERROR(2001001000, "服务端发生异常"), + MISSING_REQUEST_PARAM_ERROR(2001001001, "参数缺失"), + INVALID_REQUEST_PARAM_ERROR(2001001002, "请求参数不合法"), + + // ========== 用户模块 ========== + USER_NOT_FOUND(1001002000, "用户不存在"), + USER_EXISTS(1001002001, "用户已存在"), + + // ========== 订单模块 ========== + + // ========== 商品模块 ========== + ; + + /** + * 错误码 + */ + private final int code; + /** + * 错误提示 + */ + private final String message; + + ServiceExceptionEnum(int code, String message) { + this.code = code; + this.message = message; + } + + public int getCode() { + return code; + } + + public String getMessage() { + return message; + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java new file mode 100644 index 000000000..dd01bb7a2 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java @@ -0,0 +1,44 @@ +package cn.iocoder.springcloudalibaba.labx7.dto; + +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 用户添加 DTO + */ +public class UserAddDTO implements Serializable { + + /** + * 昵称 + */ + @NotEmpty(message = "昵称不能为空") + @Length(min = 5, max = 16, message = "账号长度为 5-16 位") + private String name; + /** + * 性别 + */ + @NotNull(message = "性别不能为空") + private Integer gender; + + public String getName() { + return name; + } + + public UserAddDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserAddDTO setGender(Integer gender) { + this.gender = gender; + return this; + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java new file mode 100644 index 000000000..17a0b4572 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java @@ -0,0 +1,49 @@ +package cn.iocoder.springcloudalibaba.labx7.dto; + +import java.io.Serializable; + +/** + * 用户信息 DTO + */ +public class UserDTO implements Serializable { + + /** + * 用户编号 + */ + private Integer id; + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public Integer getId() { + return id; + } + + public UserDTO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public UserDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserDTO setGender(Integer gender) { + this.gender = gender; + return this; + } +} diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/pom.xml b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/pom.xml new file mode 100644 index 000000000..dd30b2824 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/pom.xml @@ -0,0 +1,79 @@ + + + + labx-07-sca-dubbo-demo04-filter + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo04-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo04-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..d27e5af4e --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java new file mode 100644 index 000000000..9d115ab0f --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; +import org.apache.dubbo.config.annotation.Reference; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Reference(protocol = "dubbo", version = "1.0.0", validation = "true") + private UserService userService; + + @GetMapping("/get") + public UserDTO get(@RequestParam("id") Integer id) { + return userService.get(id); + } + + @PostMapping("/add") + public Integer add(UserAddDTO addDTO) { + return userService.add(addDTO); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..ca3778592 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-consumer/src/main/resources/application.yaml @@ -0,0 +1,17 @@ +spring: + application: + name: demo-consumer + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: demo-provider # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/pom.xml b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/pom.xml new file mode 100644 index 000000000..135b0a42c --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/pom.xml @@ -0,0 +1,73 @@ + + + + labx-07-sca-dubbo-demo04-filter + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo04-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo04-api + 1.0-SNAPSHOT + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java new file mode 100644 index 000000000..454251b56 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(ProviderApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/filter/DubboExceptionFilter.java b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/filter/DubboExceptionFilter.java new file mode 100644 index 000000000..8e0cd994a --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/filter/DubboExceptionFilter.java @@ -0,0 +1,136 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo.filter; + +import cn.iocoder.springcloudalibaba.labx7.core.ServiceException; +import cn.iocoder.springcloudalibaba.labx7.core.ServiceExceptionEnum; +import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.logger.Logger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.ReflectUtils; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.rpc.*; +import org.apache.dubbo.rpc.service.GenericService; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import java.lang.reflect.Method; + +@Activate(group = CommonConstants.PROVIDER) +public class DubboExceptionFilter extends ListenableFilter { + + public DubboExceptionFilter() { + super.listener = new ExceptionListenerX(); + } + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + return invoker.invoke(invocation); + } + + static class ExceptionListenerX extends ExceptionListener { + + @Override + public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) { + // 发生异常,并且非泛化调用 + if (appResponse.hasException() && GenericService.class != invoker.getInterface()) { + Throwable exception = appResponse.getException(); + // <1> 如果是 ServiceException 异常,直接返回 + if (exception instanceof ServiceException) { + return; + } + // <2> 如果是参数校验的 ConstraintViolationException 异常,则封装返回 + if (exception instanceof ConstraintViolationException) { + appResponse.setException(this.handleConstraintViolationException((ConstraintViolationException) exception)); + return; + } + } + // <3> 其它情况,继续使用父类处理 + super.onResponse(appResponse, invoker, invocation); + } + + // 将 ConstraintViolationException 转换成 ServiceException + private ServiceException handleConstraintViolationException(ConstraintViolationException ex) { + // 拼接错误 + StringBuilder detailMessage = new StringBuilder(); + for (ConstraintViolation constraintViolation : ex.getConstraintViolations()) { + // 使用 ; 分隔多个错误 + if (detailMessage.length() > 0) { + detailMessage.append(";"); + } + // 拼接内容到其中 + detailMessage.append(constraintViolation.getMessage()); + } + // 返回异常 + return new ServiceException(ServiceExceptionEnum.INVALID_REQUEST_PARAM_ERROR, detailMessage.toString()); + } + + } + + static class ExceptionListener implements Listener { + + private Logger logger = LoggerFactory.getLogger(ExceptionListener.class); + + @Override + public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) { + if (appResponse.hasException() && GenericService.class != invoker.getInterface()) { + try { + Throwable exception = appResponse.getException(); + + // directly throw if it's checked exception + if (!(exception instanceof RuntimeException) && (exception instanceof Exception)) { + return; + } + // directly throw if the exception appears in the signature + try { + Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes()); + Class[] exceptionClassses = method.getExceptionTypes(); + for (Class exceptionClass : exceptionClassses) { + if (exception.getClass().equals(exceptionClass)) { + return; + } + } + } catch (NoSuchMethodException e) { + return; + } + + // for the exception not found in method's signature, print ERROR message in server's log. + logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception); + + // directly throw if exception class and interface class are in the same jar file. + String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface()); + String exceptionFile = ReflectUtils.getCodeBase(exception.getClass()); + if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)) { + return; + } + // directly throw if it's JDK exception + String className = exception.getClass().getName(); + if (className.startsWith("java.") || className.startsWith("javax.")) { + return; + } + // directly throw if it's dubbo exception + if (exception instanceof RpcException) { + return; + } + + // otherwise, wrap with RuntimeException and throw back to the client + appResponse.setException(new RuntimeException(StringUtils.toString(exception))); + return; + } catch (Throwable e) { + logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e); + return; + } + } + } + + @Override + public void onError(Throwable e, Invoker invoker, Invocation invocation) { + logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e); + } + + // For test purpose + public void setLogger(Logger logger) { + this.logger = logger; + } + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java new file mode 100644 index 000000000..83ea6ce2b --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java @@ -0,0 +1,28 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo.service; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.core.ServiceException; +import cn.iocoder.springcloudalibaba.labx7.core.ServiceExceptionEnum; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; + +@org.apache.dubbo.config.annotation.Service(protocol = "dubbo", version = "1.0.0", validation = "true", filter = "-exception") +public class UserServiceImpl implements UserService { + + @Override + public UserDTO get(Integer id) { + return new UserDTO().setId(id) + .setName("没有昵称:" + id) + .setGender(id % 2 + 1); // 1 - 男;2 - 女 + } + + @Override + public Integer add(UserAddDTO addDTO) { + // 【额外添加】这里,模拟用户已经存在的情况 + if ("yudaoyuanma".equals(addDTO.getName())) { + throw new ServiceException(ServiceExceptionEnum.USER_EXISTS); + } + return (int) (System.currentTimeMillis() / 1000); // 嘿嘿,随便返回一个 id + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter new file mode 100644 index 000000000..cac783d5a --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter @@ -0,0 +1 @@ +dubboExceptionFilter=cn.iocoder.springcloudalibaba.labx7.providerdemo.filter diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..a9d67ac92 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/labx-07-sca-dubbo-demo04-provider/src/main/resources/application.yaml @@ -0,0 +1,24 @@ +spring: + application: + name: demo-provider + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + scan: + base-packages: cn.iocoder.springcloudalibaba.labx7.providerdemo.service # 指定 Dubbo 服务实现类的扫描基准包 + # Dubbo 服务暴露的协议配置,对应 ProtocolConfig Map + protocols: + dubbo: + name: dubbo # 协议名称 + port: -1 # 协议端口,-1 表示自增端口,从 20880 开始 + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-07/labx-07-sca-dubbo-demo04-filter/pom.xml b/labx-07/labx-07-sca-dubbo-demo04-filter/pom.xml new file mode 100644 index 000000000..a9c52af81 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo04-filter/pom.xml @@ -0,0 +1,21 @@ + + + + labx-07 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo04-filter + pom + + labx-07-sca-dubbo-demo04-api + labx-07-sca-dubbo-demo04-provider + labx-07-sca-dubbo-demo04-consumer + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/pom.xml b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/pom.xml new file mode 100644 index 000000000..cda29f39a --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/pom.xml @@ -0,0 +1,15 @@ + + + + labx-07-sca-dubbo-demo05-sentinel + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo05-api + + + diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java new file mode 100644 index 000000000..0bf0261bc --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/api/UserService.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloudalibaba.labx7.api; + +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; + +/** + * 用户服务 RPC Service 接口 + */ +public interface UserService { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + UserDTO get(Integer id); + + /** + * 添加新用户,返回新添加的用户编号 + * + * @param addDTO 添加的用户信息 + * @return 用户编号 + */ + Integer add(UserAddDTO addDTO); + +} diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java new file mode 100644 index 000000000..85905efaa --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserAddDTO.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloudalibaba.labx7.dto; + +import java.io.Serializable; + +/** + * 用户添加 DTO + */ +public class UserAddDTO implements Serializable { + + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public String getName() { + return name; + } + + public UserAddDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserAddDTO setGender(Integer gender) { + this.gender = gender; + return this; + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java new file mode 100644 index 000000000..17a0b4572 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-api/src/main/java/cn/iocoder/springcloudalibaba/labx7/dto/UserDTO.java @@ -0,0 +1,49 @@ +package cn.iocoder.springcloudalibaba.labx7.dto; + +import java.io.Serializable; + +/** + * 用户信息 DTO + */ +public class UserDTO implements Serializable { + + /** + * 用户编号 + */ + private Integer id; + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public Integer getId() { + return id; + } + + public UserDTO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public UserDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserDTO setGender(Integer gender) { + this.gender = gender; + return this; + } +} diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/pom.xml b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/pom.xml new file mode 100644 index 000000000..8279d0478 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/pom.xml @@ -0,0 +1,89 @@ + + + + labx-07-sca-dubbo-demo05-sentinel + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo05-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo01-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + com.alibaba.csp + sentinel-apache-dubbo-adapter + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..d27e5af4e --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/ConsumerApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java new file mode 100644 index 000000000..bae4b56ea --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/src/main/java/cn/iocoder/springcloudalibaba/labx7/consumerdemo/controller/UserController.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloudalibaba.labx7.consumerdemo.controller; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; +import org.apache.dubbo.config.annotation.Reference; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Reference(protocol = "dubbo", version = "1.0.0") + private UserService userService; + + @GetMapping("/get") + public UserDTO get(@RequestParam("id") Integer id) { + return userService.get(id); + } + + @PostMapping("/add") + public Integer add(UserAddDTO addDTO) { + return userService.add(addDTO); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..f6a59d0d9 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-consumer/src/main/resources/application.yaml @@ -0,0 +1,22 @@ +spring: + application: + name: demo-consumer + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + # Sentinel 配置项 + sentinel: + eager: true # 是否饥饿加载。默认为 false 关闭 + transport: + dashboard: 127.0.0.1:7070 # Sentinel 控制台地址 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: demo-provider # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/pom.xml b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/pom.xml new file mode 100644 index 000000000..504bade8a --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/pom.xml @@ -0,0 +1,83 @@ + + + + labx-07-sca-dubbo-demo05-sentinel + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo05-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-07-sca-dubbo-demo01-api + 1.0-SNAPSHOT + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + com.alibaba.csp + sentinel-apache-dubbo-adapter + + + + diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java new file mode 100644 index 000000000..454251b56 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/ProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(ProviderApplication.class); + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java new file mode 100644 index 000000000..ea285160f --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/src/main/java/cn/iocoder/springcloudalibaba/labx7/providerdemo/service/UserServiceImpl.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloudalibaba.labx7.providerdemo.service; + +import cn.iocoder.springcloudalibaba.labx7.api.UserService; +import cn.iocoder.springcloudalibaba.labx7.dto.UserAddDTO; +import cn.iocoder.springcloudalibaba.labx7.dto.UserDTO; + +@org.apache.dubbo.config.annotation.Service(protocol = "dubbo", version = "1.0.0") +public class UserServiceImpl implements UserService { + + @Override + public UserDTO get(Integer id) { + return new UserDTO().setId(id) + .setName("没有昵称:" + id) + .setGender(id % 2 + 1); // 1 - 男;2 - 女 + } + + @Override + public Integer add(UserAddDTO addDTO) { + return (int) (System.currentTimeMillis() / 1000); // 嘿嘿,随便返回一个 id + } + +} diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/src/main/resources/application.yaml b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..8822e56ff --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/labx-07-sca-dubbo-demo05-provider/src/main/resources/application.yaml @@ -0,0 +1,29 @@ +spring: + application: + name: demo-provider + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + # Sentinel 配置项 + sentinel: + eager: true # 是否饥饿加载。默认为 false 关闭 + transport: + dashboard: 127.0.0.1:7070 # Sentinel 控制台地址 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + scan: + base-packages: cn.iocoder.springcloudalibaba.labx7.providerdemo.service # 指定 Dubbo 服务实现类的扫描基准包 + # Dubbo 服务暴露的协议配置,对应 ProtocolConfig Map + protocols: + dubbo: + name: dubbo # 协议名称 + port: -1 # 协议端口,-1 表示自增端口,从 20880 开始 + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-07/labx-07-sca-dubbo-demo05-sentinel/pom.xml b/labx-07/labx-07-sca-dubbo-demo05-sentinel/pom.xml new file mode 100644 index 000000000..02e6efb29 --- /dev/null +++ b/labx-07/labx-07-sca-dubbo-demo05-sentinel/pom.xml @@ -0,0 +1,21 @@ + + + + labx-07 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07-sca-dubbo-demo05-sentinel + pom + + labx-07-sca-dubbo-demo05-api + labx-07-sca-dubbo-demo05-provider + labx-07-sca-dubbo-demo05-consumer + + + + diff --git a/labx-07/pom.xml b/labx-07/pom.xml new file mode 100644 index 000000000..ed4b3bc0a --- /dev/null +++ b/labx-07/pom.xml @@ -0,0 +1,23 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-07 + pom + + labx-07-sca-dubbo-demo01 + labx-07-sca-dubbo-demo02 + labx-07-sca-dubbo-demo03-validation + labx-07-sca-dubbo-demo04-filter + labx-07-sca-dubbo-demo05-sentinel + + + + diff --git "a/labx-07/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\234\215\345\212\241\350\260\203\347\224\250 Dubbo \345\205\245\351\227\250\343\200\213.md" "b/labx-07/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\234\215\345\212\241\350\260\203\347\224\250 Dubbo \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..2f649be45 --- /dev/null +++ "b/labx-07/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \346\234\215\345\212\241\350\260\203\347\224\250 Dubbo \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-08/labx-08-sc-gateway-demo01-test/pom.xml b/labx-08/labx-08-sc-gateway-demo01-test/pom.xml new file mode 100644 index 000000000..7f948e8af --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo01-test/pom.xml @@ -0,0 +1,60 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo01-test + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + diff --git a/labx-08/labx-08-sc-gateway-demo01-test/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo01-test/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo01-test/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo01-test/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/config/GatewayConfig.java b/labx-08/labx-08-sc-gateway-demo01-test/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/config/GatewayConfig.java new file mode 100644 index 000000000..eca19a8af --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo01-test/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/config/GatewayConfig.java @@ -0,0 +1,45 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo.config; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.context.annotation.Bean; +import org.springframework.core.annotation.Order; +import reactor.core.publisher.Mono; + +//@Configuration +public class GatewayConfig { + + private Logger logger = LoggerFactory.getLogger(GatewayConfig.class); + + @Bean + @Order(1) + public GlobalFilter firstGlobalFilter() { + return (exchange, chain) -> { + logger.info("[first][pre]"); + return chain.filter(exchange) + .then(Mono.fromRunnable(() -> logger.info("[first][post]"))); + }; + } + + @Bean + @Order(2) + public GlobalFilter secondGatewayFilter() { + return (exchange, chain) -> { + logger.info("[second][pre]"); + return chain.filter(exchange) + .then(Mono.fromRunnable(() -> logger.info("[second][post]"))); + }; + } + + @Bean + @Order(3) + public GlobalFilter thirdGlobalFilter() { + return (exchange, chain) -> { + logger.info("[third][pre]"); + return chain.filter(exchange) + .then(Mono.fromRunnable(() -> logger.info("[third][post]"))); + }; + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo01-test/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo01-test/src/main/resources/application.yaml new file mode 100644 index 000000000..4f641b7fa --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo01-test/src/main/resources/application.yaml @@ -0,0 +1,40 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: yudaoyuanma # 路由的编号 + uri: http://www.iocoder.cn # 路由到的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/blog + filters: + - StripPrefix=1 + - id: oschina # 路由的编号 + uri: https://www.oschina.net # 路由的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/oschina + filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组 + - StripPrefix=100 +# - StripPrefix=200 +# default-filters: +# - StripPrefix=1 +# - StripPrefix=2 +# - StripPrefix=3 + +# httpserver: +# wiretap: true +# httpclient: +# wiretap: true + +logging: + level: + reactor.netty: DEBUG + org.springframework.cloud.gateway: TRACE +# org.springframework.web.reactive: TRACE diff --git a/labx-08/labx-08-sc-gateway-demo01/pom.xml b/labx-08/labx-08-sc-gateway-demo01/pom.xml new file mode 100644 index 000000000..c1d97988c --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo01/pom.xml @@ -0,0 +1,58 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo01 + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + diff --git a/labx-08/labx-08-sc-gateway-demo01/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo01/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo01/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo01/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo01/src/main/resources/application.yaml new file mode 100644 index 000000000..8e7ac23f8 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo01/src/main/resources/application.yaml @@ -0,0 +1,24 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: yudaoyuanma # 路由的编号 + uri: http://www.iocoder.cn # 路由到的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/blog + filters: + - StripPrefix=1 + - id: oschina # 路由的编号 + uri: https://www.oschina.net # 路由的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/oschina + filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组 + - StripPrefix=1 diff --git a/labx-08/labx-08-sc-gateway-demo02-registry/pom.xml b/labx-08/labx-08-sc-gateway-demo02-registry/pom.xml new file mode 100644 index 000000000..7ae7c8130 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo02-registry/pom.xml @@ -0,0 +1,64 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo02-registry + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-08/labx-08-sc-gateway-demo02-registry/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo02-registry/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo02-registry/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo02-registry/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo02-registry/src/main/resources/application.yaml new file mode 100644 index 000000000..29530ca34 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo02-registry/src/main/resources/application.yaml @@ -0,0 +1,34 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: yudaoyuanma # 路由的编号 + uri: http://www.iocoder.cn # 路由到的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/blog + filters: + - StripPrefix=1 + - id: oschina # 路由的编号 + uri: https://www.oschina.net # 路由的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/oschina + filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组 + - StripPrefix=1 + # 与 Spring Cloud 注册中心的集成,对应 DiscoveryLocatorProperties 类 + discovery: + locator: + enabled: true # 是否开启,默认为 false 关闭 + url-expression: "'lb://' + serviceId" # 路由的目标地址的表达式,默认为 "'lb://' + serviceId" + + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 diff --git a/labx-08/labx-08-sc-gateway-demo03-config-apollo/pom.xml b/labx-08/labx-08-sc-gateway-demo03-config-apollo/pom.xml new file mode 100644 index 000000000..c261dea5c --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo03-config-apollo/pom.xml @@ -0,0 +1,73 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo03-config-apollo + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.ctrip.framework.apollo + apollo-client + 1.5.1 + + + + diff --git a/labx-08/labx-08-sc-gateway-demo03-config-apollo/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo03-config-apollo/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo03-config-apollo/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo03-config-apollo/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayPropertiesRefresher.java b/labx-08/labx-08-sc-gateway-demo03-config-apollo/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayPropertiesRefresher.java new file mode 100644 index 000000000..54e4eec64 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo03-config-apollo/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayPropertiesRefresher.java @@ -0,0 +1,132 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import com.ctrip.framework.apollo.enums.PropertyChangeType; +import com.ctrip.framework.apollo.model.ConfigChange; +import com.ctrip.framework.apollo.model.ConfigChangeEvent; +import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.context.environment.EnvironmentChangeEvent; +import org.springframework.cloud.gateway.config.GatewayProperties; +import org.springframework.cloud.gateway.event.RefreshRoutesEvent; +import org.springframework.cloud.gateway.route.RouteDefinitionWriter; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; + +/** + * 由 https://github.com/ctripcorp/apollo-use-cases/tree/master/spring-cloud-gateway 提供代码,感谢~ + */ +@Component +public class GatewayPropertiesRefresher implements ApplicationContextAware, ApplicationEventPublisherAware { + + private static final Logger logger = LoggerFactory.getLogger(GatewayPropertiesRefresher.class); + + private static final String ID_PATTERN = "spring\\.cloud\\.gateway\\.routes\\[\\d+\\]\\.id"; + + private static final String DEFAULT_FILTER_PATTERN = "spring\\.cloud\\.gateway\\.default-filters\\[\\d+\\]\\.name"; + + private ApplicationContext applicationContext; + + private ApplicationEventPublisher publisher; + + @Autowired + private GatewayProperties gatewayProperties; + + @Autowired + private RouteDefinitionWriter routeDefinitionWriter; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @Override + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + this.publisher = applicationEventPublisher; + } + + @ApolloConfigChangeListener(interestedKeyPrefixes = "spring.cloud.gateway.") + public void onChange(ConfigChangeEvent changeEvent) { + refreshGatewayProperties(changeEvent); + } + + /*** + * 刷新org.springframework.cloud.gateway.config.PropertiesRouteDefinitionLocator中定义的routes + * + * @param changeEvent + * @return void + * @author ksewen + * @date 2019/5/21 2:13 PM + */ + private void refreshGatewayProperties(ConfigChangeEvent changeEvent) { + logger.info("Refreshing GatewayProperties!"); + // <1> + preDestroyGatewayProperties(changeEvent); + // <2> + this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys())); + // <3> + refreshGatewayRouteDefinition(); + logger.info("GatewayProperties refreshed!"); + } + + /*** + * GatewayProperties没有@PreDestroy和destroy方法 + * org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder#rebind(java.lang.String)中destroyBean时不会销毁当前对象 + * 如果把spring.cloud.gateway.前缀的配置项全部删除(例如需要动态删除最后一个路由的场景),initializeBean时也无法创建新的bean,则return当前bean + * 若仍保留有spring.cloud.gateway.routes[n]或spring.cloud.gateway.default-filters[n]等配置,initializeBean时会注入新的属性替换已有的bean + * 这个方法提供了类似@PreDestroy的操作,根据配置文件的实际情况把org.springframework.cloud.gateway.config.GatewayProperties#routes + * 和org.springframework.cloud.gateway.config.GatewayProperties#defaultFilters两个集合清空 + * + * @param + * @return void + * @author ksewen + * @date 2019/5/21 2:13 PM + */ + private synchronized void preDestroyGatewayProperties(ConfigChangeEvent changeEvent) { + logger.info("Pre Destroy GatewayProperties!"); + // 判断 `spring.cloud.gateway.routes` 配置项,是否被全部删除。如果是,则置空 GatewayProperties 的 `routes` 属性 + final boolean needClearRoutes = this.checkNeedClear(changeEvent, ID_PATTERN, this.gatewayProperties.getRoutes().size()); + if (needClearRoutes) { + this.gatewayProperties.setRoutes(new ArrayList<>()); + } + // 判断 `spring.cloud.gateway.default-filters` 配置项,是否被全部删除。如果是,则置空 GatewayProperties 的 `defaultFilters` 属性 + final boolean needClearDefaultFilters = this.checkNeedClear(changeEvent, DEFAULT_FILTER_PATTERN, this.gatewayProperties.getDefaultFilters().size()); + if (needClearDefaultFilters) { + this.gatewayProperties.setRoutes(new ArrayList<>()); + } + logger.info("Pre Destroy GatewayProperties finished!"); + } + + private void refreshGatewayRouteDefinition() { + logger.info("Refreshing Gateway RouteDefinition!"); + this.publisher.publishEvent(new RefreshRoutesEvent(this)); + logger.info("Gateway RouteDefinition refreshed!"); + } + + /*** + * 根据changeEvent和定义的pattern匹配key,如果所有对应PropertyChangeType为DELETED则需要清空GatewayProperties里相关集合 + * + * @param changeEvent + * @param pattern + * @param existSize + * @return boolean + * @author ksewen + * @date 2019/5/23 2:18 PM + */ + // 判断是否清除的标准,是通过指定配置项被删除的数量,是否和内存中的该配置项的数量一样。如果一样,说明被清空了 + private boolean checkNeedClear(ConfigChangeEvent changeEvent, String pattern, int existSize) { + return changeEvent.changedKeys().stream().filter(key -> key.matches(pattern)) + .filter(key -> { + ConfigChange change = changeEvent.getChange(key); + return PropertyChangeType.DELETED.equals(change.getChangeType()); + }).count() == existSize; + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo03-config-apollo/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo03-config-apollo/src/main/resources/application.yaml new file mode 100644 index 000000000..2de7aed3f --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo03-config-apollo/src/main/resources/application.yaml @@ -0,0 +1,26 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,全部配置在 Apollo 中 +# gateway: + + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + +# Apollo 相关配置项 +app: + id: ${spring.application.name} # 使用的 Apollo 的项目(应用)编号 +apollo: + meta: http://127.0.0.1:8080 # Apollo Meta Server 地址 + bootstrap: + enabled: true # 是否开启 Apollo 配置预加载功能。默认为 false。 + eagerLoad: + enable: true # 是否开启 Apollo 支持日志级别的加载时机。默认为 false。 + namespaces: application # 使用的 Apollo 的命名空间,默认为 application。 diff --git a/labx-08/labx-08-sc-gateway-demo03-config-nacos/pom.xml b/labx-08/labx-08-sc-gateway-demo03-config-nacos/pom.xml new file mode 100644 index 000000000..dbb8dd34a --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo03-config-nacos/pom.xml @@ -0,0 +1,72 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo03-config-nacos + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + diff --git a/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/resources/application.yaml new file mode 100644 index 000000000..c8a543ead --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/resources/application.yaml @@ -0,0 +1,13 @@ +server: + port: 8888 + +spring: + + cloud: + # Spring Cloud Gateway 配置项,全部配置在 Nacos 中 +# gateway: + + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 diff --git a/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/resources/bootstrap.yaml b/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/resources/bootstrap.yaml new file mode 100644 index 000000000..7c0386d7d --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/resources/bootstrap.yaml @@ -0,0 +1,13 @@ +spring: + application: + name: gateway-application + + cloud: + nacos: + # Nacos Config 配置项,对应 NacosConfigProperties 配置属性类 + config: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + namespace: # 使用的 Nacos 的命名空间,默认为 null + group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + name: # 使用的 Nacos 配置集的 dataId,默认为 spring.application.name + file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties diff --git a/labx-08/labx-08-sc-gateway-demo04/pom.xml b/labx-08/labx-08-sc-gateway-demo04/pom.xml new file mode 100644 index 000000000..a197b6ebe --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo04/pom.xml @@ -0,0 +1,58 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo04 + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + diff --git a/labx-08/labx-08-sc-gateway-demo04/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo04/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo04/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo04/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo04/src/main/resources/application.yaml new file mode 100644 index 000000000..ca7f104fb --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo04/src/main/resources/application.yaml @@ -0,0 +1,22 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: user-service-prod + uri: http://www.iocoder.cn + predicates: + - Path=/** + - Weight=user-service, 90 + - id: user-service-canary + uri: https://www.oschina.net + predicates: + - Path=/** + - Weight=user-service, 10 diff --git a/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/pom.xml b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/pom.xml new file mode 100644 index 000000000..860c0774e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/pom.xml @@ -0,0 +1,60 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo05-custom-gateway-filter + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + diff --git a/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/filter/AuthGatewayFilterFactory.java b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/filter/AuthGatewayFilterFactory.java new file mode 100644 index 000000000..f54c3e0b7 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/filter/AuthGatewayFilterFactory.java @@ -0,0 +1,98 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo.filter; + +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.HashMap; +import java.util.Map; + +@Component +public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory { + + public AuthGatewayFilterFactory() { + super(AuthGatewayFilterFactory.Config.class); + } + + @Override + public GatewayFilter apply(Config config) { + // token 和 userId 的映射 + Map tokenMap = new HashMap<>(); + tokenMap.put("yunai", 1); + + // 创建 GatewayFilter 对象 + return new GatewayFilter() { + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + // 获得 token + ServerHttpRequest request = exchange.getRequest(); + HttpHeaders headers = request.getHeaders(); + String token = headers.getFirst(config.getTokenHeaderName()); + + // 如果没有 token,则不进行认证。因为可能是无需认证的 API 接口 + if (!StringUtils.hasText(token)) { + return chain.filter(exchange); + } + + // 进行认证 + ServerHttpResponse response = exchange.getResponse(); + Integer userId = tokenMap.get(token); + + // 通过 token 获取不到 userId,说明认证不通过 + if (userId == null) { + // 响应 401 状态码 + response.setStatusCode(HttpStatus.UNAUTHORIZED); + // 响应提示 + DataBuffer buffer = exchange.getResponse().bufferFactory().wrap("认证不通过".getBytes()); + return response.writeWith(Flux.just(buffer)); + } + + // 认证通过,将 userId 添加到 Header 中 + request = request.mutate().header(config.getUserIdHeaderName(), String.valueOf(userId)) + .build(); + return chain.filter(exchange.mutate().request(request).build()); + } + + }; + } + + public static class Config { + + private static final String DEFAULT_TOKEN_HEADER_NAME = "token"; + private static final String DEFAULT_HEADER_NAME = "user-id"; + + private String tokenHeaderName = DEFAULT_TOKEN_HEADER_NAME; + private String userIdHeaderName = DEFAULT_HEADER_NAME; + + public String getTokenHeaderName() { + return tokenHeaderName; + } + + public String getUserIdHeaderName() { + return userIdHeaderName; + } + + public Config setTokenHeaderName(String tokenHeaderName) { + this.tokenHeaderName = tokenHeaderName; + return this; + } + + public Config setUserIdHeaderName(String userIdHeaderName) { + this.userIdHeaderName = userIdHeaderName; + return this; + } + + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/resources/application.yaml new file mode 100644 index 000000000..f9d50ef00 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/src/main/resources/application.yaml @@ -0,0 +1,29 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: yudaoyuanma # 路由的编号 + uri: http://www.iocoder.cn # 路由到的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/blog + filters: + - StripPrefix=1 + - id: oschina # 路由的编号 + uri: https://www.oschina.net # 路由的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/oschina + filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组 + - StripPrefix=1 + # 默认过滤器,对应 FilterDefinition 数组 + default-filters: + - name: Auth + args: + token-header-name: access-token diff --git a/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/target/classes/application.yaml b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/target/classes/application.yaml new file mode 100644 index 000000000..f9d50ef00 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo05-custom-gateway-filter/target/classes/application.yaml @@ -0,0 +1,29 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: yudaoyuanma # 路由的编号 + uri: http://www.iocoder.cn # 路由到的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/blog + filters: + - StripPrefix=1 + - id: oschina # 路由的编号 + uri: https://www.oschina.net # 路由的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/oschina + filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组 + - StripPrefix=1 + # 默认过滤器,对应 FilterDefinition 数组 + default-filters: + - name: Auth + args: + token-header-name: access-token diff --git a/labx-08/labx-08-sc-gateway-demo06-rate-limiter/pom.xml b/labx-08/labx-08-sc-gateway-demo06-rate-limiter/pom.xml new file mode 100644 index 000000000..0534a3460 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo06-rate-limiter/pom.xml @@ -0,0 +1,67 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo06-rate-limiter + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + diff --git a/labx-08/labx-08-sc-gateway-demo06-rate-limiter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo06-rate-limiter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo06-rate-limiter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo06-rate-limiter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/config/GatewayConfig.java b/labx-08/labx-08-sc-gateway-demo06-rate-limiter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/config/GatewayConfig.java new file mode 100644 index 000000000..9822fa879 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo06-rate-limiter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/config/GatewayConfig.java @@ -0,0 +1,25 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo.config; + +import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +@Configuration +public class GatewayConfig { + + @Bean + public KeyResolver ipKeyResolver() { + return new KeyResolver() { + + @Override + public Mono resolve(ServerWebExchange exchange) { + // 获取请求的 IP + return Mono.just(exchange.getRequest().getRemoteAddress().getHostName()); + } + + }; + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo06-rate-limiter/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo06-rate-limiter/src/main/resources/application.yaml new file mode 100644 index 000000000..80ebe8106 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo06-rate-limiter/src/main/resources/application.yaml @@ -0,0 +1,34 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: yudaoyuanma # 路由的编号 + uri: http://www.iocoder.cn # 路由到的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/blog + filters: + - StripPrefix=1 + - name: RequestRateLimiter + args: + redis-rate-limiter.replenishRate: 1 # 令牌桶的每秒放的数量 + redis-rate-limiter.burstCapacity: 2 # 令牌桶的最大令牌数 + key-resolver: "#{@ipKeyResolver}" # 获取限流 KEY 的 Bean 的名字 + - id: oschina # 路由的编号 + uri: https://www.oschina.net # 路由的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/oschina + filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组 + - StripPrefix=1 + + # Redis 配置项 + redis: + host: 127.0.0.1 + port: 6379 diff --git a/labx-08/labx-08-sc-gateway-demo07-hystrix/pom.xml b/labx-08/labx-08-sc-gateway-demo07-hystrix/pom.xml new file mode 100644 index 000000000..2d6ee395e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo07-hystrix/pom.xml @@ -0,0 +1,64 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo07-hystrix + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix + + + + diff --git a/labx-08/labx-08-sc-gateway-demo07-hystrix/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo07-hystrix/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo07-hystrix/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo07-hystrix/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/controller/FallbackController.java b/labx-08/labx-08-sc-gateway-demo07-hystrix/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/controller/FallbackController.java new file mode 100644 index 000000000..ad97a80c7 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo07-hystrix/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/controller/FallbackController.java @@ -0,0 +1,24 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ServerWebExchange; + +@RestController +public class FallbackController { + + private Logger logger = LoggerFactory.getLogger(FallbackController.class); + + @GetMapping("/fallback") + public String fallback(ServerWebExchange exchange) { +// URI requestUrl = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR); + Throwable executionException = exchange.getAttribute(ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR); + logger.error("[fallback][发生异常]", executionException); + + return "服务降级..." + executionException.getMessage(); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo07-hystrix/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo07-hystrix/src/main/resources/application.yaml new file mode 100644 index 000000000..cbe1dba3b --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo07-hystrix/src/main/resources/application.yaml @@ -0,0 +1,21 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: hystrix_test + uri: http://127.0.0.1:18181 + predicates: + - Path=/** + filters: + - name: Hystrix + args: + name: fallbackcmd # 对应的 Hystrix Command 名字 + fallbackUri: forward:/fallback # 处理 Hystrix fallback 的情况,重定向到指定地址 diff --git a/labx-08/labx-08-sc-gateway-demo07-sentinel/pom.xml b/labx-08/labx-08-sc-gateway-demo07-sentinel/pom.xml new file mode 100644 index 000000000..e2d82ac3d --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo07-sentinel/pom.xml @@ -0,0 +1,70 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo07-sentinel + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + com.alibaba.cloud + spring-cloud-alibaba-sentinel-gateway + + + + diff --git a/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/CustomBlockRequestHandler.java b/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/CustomBlockRequestHandler.java new file mode 100644 index 000000000..c3ec62cee --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/CustomBlockRequestHandler.java @@ -0,0 +1,23 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +@Component +public class CustomBlockRequestHandler implements BlockRequestHandler { + + private static final String DEFAULT_BLOCK_MSG_PREFIX = "HAHAHA ~ Blocked by Sentinel: "; + + @Override + public Mono handleRequest(ServerWebExchange exchange, Throwable ex) { + return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS) // 状态码 + .contentType(MediaType.TEXT_PLAIN) // 内容类型为 text/plain 纯文本 + .bodyValue(DEFAULT_BLOCK_MSG_PREFIX + ex.getClass().getSimpleName()); // 错误提示 + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..1ba74349f --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { +// System.setProperty(SentinelConfig.APP_TYPE, ConfigConstants.APP_TYPE_SCG_GATEWAY); +// System.setProperty(SentinelConfig.APP_TYPE, "1"); + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/resources/application.yaml new file mode 100644 index 000000000..52330eb88 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/resources/application.yaml @@ -0,0 +1,40 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: yudaoyuanma # 路由的编号 + uri: http://www.iocoder.cn # 路由到的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/** + + sentinel: + eager: true # 是否饥饿加载。默认为 false 关闭 + transport: + dashboard: localhost:7070 # 是否饥饿加载。默认为 false 关闭 +# # 数据源的配置项 +# datasource: +# ds1.file: +# file: "classpath: sentinel-gw-flow.json" +# ruleType: gw-flow +# ds2.file: +# file: "classpath: sentinel-gw-api-group.json" +# ruleType: gw-api-group + # Sentinel 对 Spring Cloud Gateway 的专属配置项,对应 SentinelGatewayProperties 类 + scg: + order: -2147483648 # 过滤器顺序,默认为 -2147483648 最高优先级 + fallback: + mode: # fallback 模式,目前有三种:response、redirect、空 + # 专属 response 模式 + response-status: 429 # 响应状态码,默认为 429 + response-body: 你被 block 了... # 响应内容,默认为空 + content-type: application/json # 内容类型,默认为 application/json + # 专属 redirect 模式 + redirect: http://www.baidu.com diff --git a/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/resources/sentinel-gw-api-group.json b/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/resources/sentinel-gw-api-group.json new file mode 100644 index 000000000..0e47591bc --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/resources/sentinel-gw-api-group.json @@ -0,0 +1,23 @@ +[ + { + "apiName": "yudaoyuanma_customized_api", + "predicateItems": [ + { + "pattern": "/categories/**", + "matchStrategy": 1 + }, + { + "items": [ + { + "pattern": "/Dubbo/good-collection/", + "matchStrategy": 0 + }, + { + "pattern": "/SkyWalking/**", + "matchStrategy": 1 + } + ] + } + ] + } +] diff --git a/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/resources/sentinel-gw-flow.json b/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/resources/sentinel-gw-flow.json new file mode 100644 index 000000000..8a53df34c --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo07-sentinel/src/main/resources/sentinel-gw-flow.json @@ -0,0 +1,10 @@ +[ + { + "resource": "yudaoyuanma", + "count": 3 + }, + { + "resource": "yudaoyuanma_customized_api", + "count": 1 + } +] diff --git a/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/pom.xml b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/pom.xml new file mode 100644 index 000000000..1b5b7b270 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/pom.xml @@ -0,0 +1,79 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo08-custom-global-filter + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + + + + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/User03Controller.java b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/User03Controller.java new file mode 100644 index 000000000..2e6923031 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/User03Controller.java @@ -0,0 +1,35 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@RestController +@RequestMapping("/user03") +public class User03Controller { + + @Autowired + private RestTemplate restTemplate; + +// @GetMapping("/get") +// public UserDTO get(@RequestParam("id") Integer id) { +// String url = String.format("http://%s/user/get?id=%d", "demo-provider", id); +// return restTemplate.getForObject(url, UserDTO.class); +// } +// +// @PostMapping("/add") +// public Integer add(UserAddDTO addDTO) { +// // 请求头 +// HttpHeaders headers = new HttpHeaders(); +// headers.setContentType(MediaType.APPLICATION_JSON); +// // 请求体 +// String body = JSON.toJSONString(addDTO); +// // 创建 HttpEntity 对象 +// HttpEntity entity = new HttpEntity<>(body, headers); +// // 执行请求 +// String url = String.format("http://%s/user/add", "demo-provider"); +// return restTemplate.postForObject(url, entity, Integer.class); +// } + +} diff --git a/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/config/RestTemplateConfig.java b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/config/RestTemplateConfig.java new file mode 100644 index 000000000..2f61f2479 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/config/RestTemplateConfig.java @@ -0,0 +1,19 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo.config; + +import com.alibaba.cloud.dubbo.annotation.DubboTransported; +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; + +@Configuration +public class RestTemplateConfig { + + @Bean + @LoadBalanced + @DubboTransported(protocol = "dubbo") + public RestTemplate restTemplate() { + return new RestTemplate(); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/filter/DubboFilter.java b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/filter/DubboFilter.java new file mode 100644 index 000000000..238c44b5d --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/filter/DubboFilter.java @@ -0,0 +1,42 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo.filter; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +import java.net.URI; + +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR; + +@Component +public class DubboFilter implements GlobalFilter, Ordered { + + @Autowired + private RestTemplate restTemplate; + + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR); + String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR); + if (url == null + || (!"dubbo".equals(url.getScheme()) && !"dubbo".equals(schemePrefix))) { + return chain.filter(exchange); + } + + String urlx = String.format("http://%s/user/get?id=%d", "demo-provider", 1); +// UserDTO result = restTemplate.getForObject(url, UserDTO.class); + String result = restTemplate.getForObject(url, String.class); + + return null; + } + + public int getOrder() { + return 10100; + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/resources/application.yaml new file mode 100644 index 000000000..96f5a421c --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo08-custom-global-filter/src/main/resources/application.yaml @@ -0,0 +1,39 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: +# - id: yudaoyuanma # 路由的编号 +# uri: http://www.iocoder.cn # 路由到的目标地址 +# predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 +# - Path=/blog +# filters: +# - StripPrefix=1 +# - id: oschina # 路由的编号 +# uri: https://www.oschina.net # 路由的目标地址 +# predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 +# - Path=/oschina +# filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组 +# - StripPrefix=1 + - id: yudaoyuanma # 路由的编号 + uri: dubbo://demo-provider # 路由到的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/user/** +# filters: +# - StripPrefix=1 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: demo-provider # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-08/labx-08-sc-gateway-demo09-actuator/pom.xml b/labx-08/labx-08-sc-gateway-demo09-actuator/pom.xml new file mode 100644 index 000000000..d3303ca6b --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo09-actuator/pom.xml @@ -0,0 +1,64 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo09-actuator + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-08/labx-08-sc-gateway-demo09-actuator/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo09-actuator/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo09-actuator/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo09-actuator/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo09-actuator/src/main/resources/application.yaml new file mode 100644 index 000000000..e7b53829e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo09-actuator/src/main/resources/application.yaml @@ -0,0 +1,35 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + +# cloud: +# # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 +# gateway: +# # 路由配置项,对应 RouteDefinition 数组 +# routes: +# - id: yudaoyuanma # 路由的编号 +# uri: http://www.iocoder.cn # 路由到的目标地址 +# predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 +# - Path=/blog +# filters: +# - StripPrefix=1 +# - id: oschina # 路由的编号 +# uri: https://www.oschina.net # 路由的目标地址 +# predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 +# - Path=/oschina +# filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组 +# - StripPrefix=1 + +management: + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + endpoint: + # Health 端点配置项,对应 HealthProperties 配置类 + health: + enabled: true # 是否开启。默认为 true 开启。 + show-details: ALWAYS # 何时显示完整的健康信息。默认为 NEVER 都不展示。可选 WHEN_AUTHORIZED 当经过授权的用户;可选 ALWAYS 总是展示。 diff --git a/labx-08/labx-08-sc-gateway-demo10-troubleshooting/pom.xml b/labx-08/labx-08-sc-gateway-demo10-troubleshooting/pom.xml new file mode 100644 index 000000000..5342efed2 --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo10-troubleshooting/pom.xml @@ -0,0 +1,58 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-gateway-demo10-troubleshooting + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + diff --git a/labx-08/labx-08-sc-gateway-demo10-troubleshooting/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java b/labx-08/labx-08-sc-gateway-demo10-troubleshooting/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..f9575ef3e --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo10-troubleshooting/src/main/java/cn/iocoder/springcloud/labx08/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-gateway-demo10-troubleshooting/src/main/resources/application.yaml b/labx-08/labx-08-sc-gateway-demo10-troubleshooting/src/main/resources/application.yaml new file mode 100644 index 000000000..8aaebf8de --- /dev/null +++ b/labx-08/labx-08-sc-gateway-demo10-troubleshooting/src/main/resources/application.yaml @@ -0,0 +1,35 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: yudaoyuanma # 路由的编号 + uri: http://www.iocoder.cn # 路由到的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/blog + filters: + - StripPrefix=1 + - id: oschina # 路由的编号 + uri: https://www.oschina.net # 路由的目标地址 + predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组 + - Path=/oschina + filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组 + - StripPrefix=1 + + # Reactor Netty 相关配置 + httpserver: + wiretap: true + httpclient: + wiretap: true + +logging: + level: + reactor.netty: DEBUG + org.springframework.cloud.gateway: TRACE diff --git a/labx-08/labx-08-sc-user-service/pom.xml b/labx-08/labx-08-sc-user-service/pom.xml new file mode 100644 index 000000000..3ed72ccec --- /dev/null +++ b/labx-08/labx-08-sc-user-service/pom.xml @@ -0,0 +1,64 @@ + + + + labx-08 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08-sc-user-service + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/UserServiceApplication.java b/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/UserServiceApplication.java new file mode 100644 index 000000000..94da95e83 --- /dev/null +++ b/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/UserServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx08.userservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} diff --git a/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/controller/UserController.java b/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/controller/UserController.java new file mode 100644 index 000000000..e576e5593 --- /dev/null +++ b/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/controller/UserController.java @@ -0,0 +1,23 @@ +package cn.iocoder.springcloud.labx08.userservice.controller; + +import cn.iocoder.springcloud.labx08.userservice.dto.UserAddDTO; +import cn.iocoder.springcloud.labx08.userservice.dto.UserDTO; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/user") +public class UserController { + + @GetMapping("/get") + public UserDTO get(@RequestParam("id") Integer id) { + return new UserDTO().setId(id) + .setName("没有昵称:" + id) + .setGender(id % 2 + 1); // 1 - 男;2 - 女 + } + + @PostMapping("/add") + public Integer add(UserAddDTO addDTO) { + return (int) (System.currentTimeMillis() / 1000); // 嘿嘿,随便返回一个 id + } + +} diff --git a/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/dto/UserAddDTO.java b/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/dto/UserAddDTO.java new file mode 100644 index 000000000..2dbfedce5 --- /dev/null +++ b/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/dto/UserAddDTO.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx08.userservice.dto; + +import java.io.Serializable; + +/** + * 用户添加 DTO + */ +public class UserAddDTO implements Serializable { + + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public String getName() { + return name; + } + + public UserAddDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserAddDTO setGender(Integer gender) { + this.gender = gender; + return this; + } + +} diff --git a/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/dto/UserDTO.java b/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/dto/UserDTO.java new file mode 100644 index 000000000..8c911e708 --- /dev/null +++ b/labx-08/labx-08-sc-user-service/src/main/java/cn/iocoder/springcloud/labx08/userservice/dto/UserDTO.java @@ -0,0 +1,49 @@ +package cn.iocoder.springcloud.labx08.userservice.dto; + +import java.io.Serializable; + +/** + * 用户信息 DTO + */ +public class UserDTO implements Serializable { + + /** + * 用户编号 + */ + private Integer id; + /** + * 昵称 + */ + private String name; + /** + * 性别 + */ + private Integer gender; + + public Integer getId() { + return id; + } + + public UserDTO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public UserDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getGender() { + return gender; + } + + public UserDTO setGender(Integer gender) { + this.gender = gender; + return this; + } +} diff --git a/labx-08/labx-08-sc-user-service/src/main/resources/application.yaml b/labx-08/labx-08-sc-user-service/src/main/resources/application.yaml new file mode 100644 index 000000000..e9b70d317 --- /dev/null +++ b/labx-08/labx-08-sc-user-service/src/main/resources/application.yaml @@ -0,0 +1,12 @@ +spring: + application: + name: user-service # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 "'lb://'+serviceId" + +server: + port: ${random.int[10000,19999]} # 服务器端口。默认为 8080 +# port: 18080 # 服务器端口。默认为 8080 diff --git a/labx-08/pom.xml b/labx-08/pom.xml new file mode 100644 index 000000000..fd190eed8 --- /dev/null +++ b/labx-08/pom.xml @@ -0,0 +1,42 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-08 + pom + + labx-08-sc-gateway-demo01 + labx-08-sc-gateway-demo01-test + + labx-08-sc-gateway-demo02-registry + + labx-08-sc-gateway-demo03-config-apollo + labx-08-sc-gateway-demo03-config-nacos + + labx-08-sc-gateway-demo04 + + labx-08-sc-gateway-demo05-custom-gateway-filter + + labx-08-sc-gateway-demo06-rate-limiter + + labx-08-sc-gateway-demo07-hystrix + labx-08-sc-gateway-demo07-sentinel + + labx-08-sc-gateway-demo08-custom-global-filter + + labx-08-sc-gateway-demo09-actuator + + labx-08-sc-gateway-demo10-troubleshooting + + labx-08-sc-user-service + + + + diff --git "a/labx-08/\343\200\212\350\212\213\351\201\223 Spring Cloud \347\275\221\345\205\263 Spring Cloud Gateway \345\205\245\351\227\250\343\200\213.md" "b/labx-08/\343\200\212\350\212\213\351\201\223 Spring Cloud \347\275\221\345\205\263 Spring Cloud Gateway \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..ba73afb2e --- /dev/null +++ "b/labx-08/\343\200\212\350\212\213\351\201\223 Spring Cloud \347\275\221\345\205\263 Spring Cloud Gateway \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-09/labx-09-sc-apollo-demo-auto-refresh/pom.xml b/labx-09/labx-09-sc-apollo-demo-auto-refresh/pom.xml new file mode 100644 index 000000000..1efbed715 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-auto-refresh/pom.xml @@ -0,0 +1,69 @@ + + + + labx-09 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-09-sc-apollo-demo-auto-refresh + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.cloud + spring-cloud-context + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.ctrip.framework.apollo + apollo-client + 1.5.1 + + + + diff --git a/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java b/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java new file mode 100644 index 000000000..0f011da93 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx09.apollodemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class); + } + +} diff --git a/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/config/OrderProperties.java b/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/config/OrderProperties.java new file mode 100644 index 000000000..f5349a41c --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/config/OrderProperties.java @@ -0,0 +1,52 @@ +package cn.iocoder.springcloud.labx09.apollodemo.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + +// /** +// * 配置描述 +// */ +// private String desc; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +// public String getDesc() { +// return desc; +// } +// +// public OrderProperties setDesc(String desc) { +// this.desc = desc; +// return this; +// } + +} diff --git a/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/controller/DemoController.java b/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/controller/DemoController.java new file mode 100644 index 000000000..6d950b396 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/controller/DemoController.java @@ -0,0 +1,53 @@ +package cn.iocoder.springcloud.labx09.apollodemo.controller; + +import cn.iocoder.springcloud.labx09.apollodemo.config.OrderProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + Map result = new HashMap<>(); + result.put("payTimeoutSeconds", payTimeoutSeconds); + result.put("createFrequencySeconds", createFrequencySeconds); + return result; + } + + @GetMapping("/logger") + public void logger() { + logger.debug("[logger][测试一下]"); + } + +} diff --git a/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/listener/ApolloPropertiesRefresher.java b/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/listener/ApolloPropertiesRefresher.java new file mode 100644 index 000000000..2472ae368 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/listener/ApolloPropertiesRefresher.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx09.apollodemo.listener; + +import com.ctrip.framework.apollo.core.ConfigConsts; +import com.ctrip.framework.apollo.model.ConfigChangeEvent; +import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener; +import org.springframework.beans.BeansException; +import org.springframework.cloud.context.environment.EnvironmentChangeEvent; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +@Component +public class ApolloPropertiesRefresher implements ApplicationContextAware { + + private ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @ApolloConfigChangeListener(value = ConfigConsts.NAMESPACE_APPLICATION) + public void onChange(ConfigChangeEvent changeEvent) { + this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys())); + } + +} diff --git a/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/resources/application.yaml b/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/resources/application.yaml new file mode 100644 index 000000000..ace5489d2 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-auto-refresh/src/main/resources/application.yaml @@ -0,0 +1,12 @@ +server: + port: 7070 # 避免和本地的 Apollo Portal 端口冲突 + +app: + id: demo-application # 使用的 Apollo 的项目(应用)编号 +apollo: + meta: http://127.0.0.1:8080 # Apollo Meta Server 地址 + bootstrap: + enabled: true # 是否开启 Apollo 配置预加载功能。默认为 false。 + eagerLoad: + enable: true # 是否开启 Apollo 支持日志级别的加载时机。默认为 false。 + namespaces: application # 使用的 Apollo 的命名空间,默认为 application。 diff --git a/labx-09/labx-09-sc-apollo-demo-jasypt/pom.xml b/labx-09/labx-09-sc-apollo-demo-jasypt/pom.xml new file mode 100644 index 000000000..ff9e09516 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-jasypt/pom.xml @@ -0,0 +1,85 @@ + + + + labx-09 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-09-sc-apollo-demo-jasypt + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.cloud + spring-cloud-context + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.ctrip.framework.apollo + apollo-client + 1.5.1 + + + + + com.github.ulisesbocchio + jasypt-spring-boot-starter + 3.0.2 + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + diff --git a/labx-09/labx-09-sc-apollo-demo-jasypt/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java b/labx-09/labx-09-sc-apollo-demo-jasypt/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java new file mode 100644 index 000000000..0f011da93 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-jasypt/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx09.apollodemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class); + } + +} diff --git a/labx-09/labx-09-sc-apollo-demo-jasypt/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/controller/DemoController.java b/labx-09/labx-09-sc-apollo-demo-jasypt/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/controller/DemoController.java new file mode 100644 index 000000000..2c01d0178 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-jasypt/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/controller/DemoController.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx09.apollodemo.controller; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + @Value("${xxx-password:}") + private String xxxPassword; + + @GetMapping("/test") + public String test() { + return xxxPassword; + } + +} diff --git a/labx-09/labx-09-sc-apollo-demo-jasypt/src/main/resources/application.yaml b/labx-09/labx-09-sc-apollo-demo-jasypt/src/main/resources/application.yaml new file mode 100644 index 000000000..32e595322 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-jasypt/src/main/resources/application.yaml @@ -0,0 +1,12 @@ +server: + port: 7070 # 避免和本地的 Apollo Portal 端口冲突 + +app: + id: demo-application-jasypt # 使用的 Apollo 的项目(应用)编号 +apollo: + meta: http://127.0.0.1:8080 # Apollo Meta Server 地址 + bootstrap: + enabled: true # 是否开启 Apollo 配置预加载功能。默认为 false。 + eagerLoad: + enable: true # 是否开启 Apollo 支持日志级别的加载时机。默认为 false。 + namespaces: application # 使用的 Apollo 的命名空间,默认为 application。 diff --git a/labx-09/labx-09-sc-apollo-demo-jasypt/src/test/java/cn/iocoder/springcloud/labx09/apollodemo/JasyptTest.java b/labx-09/labx-09-sc-apollo-demo-jasypt/src/test/java/cn/iocoder/springcloud/labx09/apollodemo/JasyptTest.java new file mode 100644 index 000000000..e384f3928 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-jasypt/src/test/java/cn/iocoder/springcloud/labx09/apollodemo/JasyptTest.java @@ -0,0 +1,40 @@ +package cn.iocoder.springcloud.labx09.apollodemo; + +import org.jasypt.encryption.StringEncryptor; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class JasyptTest { + + @Autowired + private StringEncryptor encryptor; + + @Test + public void encode() { + // 第一个加密 + String password = "woshimima"; + System.out.println(encryptor.encrypt(password)); + + // 第二个加密 + password = "bushimima"; + System.out.println(encryptor.encrypt(password)); + } + + @Value("${xxx-password:}") + private String xxxPassword; + + @Test + public void print() { + System.out.println(xxxPassword); + } + +// @Value("${jasypt.encryptor.password}") +// private String password; + +} diff --git a/labx-09/labx-09-sc-apollo-demo-multi/pom.xml b/labx-09/labx-09-sc-apollo-demo-multi/pom.xml new file mode 100644 index 000000000..4b9b56395 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-multi/pom.xml @@ -0,0 +1,69 @@ + + + + labx-09 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-09-sc-apollo-demo-multi + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.cloud + spring-cloud-context + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.ctrip.framework.apollo + apollo-client + 1.5.1 + + + + diff --git a/labx-09/labx-09-sc-apollo-demo-multi/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java b/labx-09/labx-09-sc-apollo-demo-multi/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java new file mode 100644 index 000000000..8867588bb --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-multi/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx09.apollodemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.Environment; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + // 启动 Spring Boot 应用 + ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class); + + // 查看 Environment + Environment environment = context.getEnvironment(); + System.out.println(environment); + } + +} diff --git a/labx-09/labx-09-sc-apollo-demo-multi/src/main/resources/application.yaml b/labx-09/labx-09-sc-apollo-demo-multi/src/main/resources/application.yaml new file mode 100644 index 000000000..cd26fa071 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-multi/src/main/resources/application.yaml @@ -0,0 +1,12 @@ +server: + port: 7070 # 避免和本地的 Apollo Portal 端口冲突 + +app: + id: demo-application-multi # 使用的 Apollo 的项目(应用)编号 +apollo: + meta: http://127.0.0.1:8080 # Apollo Meta Server 地址 + bootstrap: + enabled: true # 是否开启 Apollo 配置预加载功能。默认为 false。 + eagerLoad: + enable: true # 是否开启 Apollo 支持日志级别的加载时机。默认为 false。 + namespaces: application, db # 使用的 Apollo 的命名空间,默认为 application。 diff --git a/labx-09/labx-09-sc-apollo-demo-profiles/pom.xml b/labx-09/labx-09-sc-apollo-demo-profiles/pom.xml new file mode 100644 index 000000000..76d3e9ac7 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-profiles/pom.xml @@ -0,0 +1,69 @@ + + + + labx-09 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-09-sc-apollo-demo-profiles + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.cloud + spring-cloud-context + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.ctrip.framework.apollo + apollo-client + 1.5.1 + + + + diff --git a/labx-09/labx-09-sc-apollo-demo-profiles/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java b/labx-09/labx-09-sc-apollo-demo-profiles/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java new file mode 100644 index 000000000..0f011da93 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-profiles/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx09.apollodemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class); + } + +} diff --git a/labx-09/labx-09-sc-apollo-demo-profiles/src/main/resources/application-dev.yaml b/labx-09/labx-09-sc-apollo-demo-profiles/src/main/resources/application-dev.yaml new file mode 100644 index 000000000..1cd635811 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-profiles/src/main/resources/application-dev.yaml @@ -0,0 +1,9 @@ +app: + id: demo-application-profiles # 使用的 Apollo 的项目(应用)编号 +apollo: + meta: http://127.0.0.1:8080 # Apollo Meta Server 地址 + bootstrap: + enabled: true # 是否开启 Apollo 配置预加载功能。默认为 false。 + eagerLoad: + enable: true # 是否开启 Apollo 支持日志级别的加载时机。默认为 false。 + namespaces: application # 使用的 Apollo 的命名空间,默认为 application。 diff --git a/labx-09/labx-09-sc-apollo-demo-profiles/src/main/resources/application-prod.yaml b/labx-09/labx-09-sc-apollo-demo-profiles/src/main/resources/application-prod.yaml new file mode 100644 index 000000000..b017e5aa1 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-profiles/src/main/resources/application-prod.yaml @@ -0,0 +1,9 @@ +app: + id: demo-application-profiles # 使用的 Apollo 的项目(应用)编号 +apollo: + meta: http://127.0.0.1:18080 # Apollo Meta Server 地址 + bootstrap: + enabled: true # 是否开启 Apollo 配置预加载功能。默认为 false。 + eagerLoad: + enable: true # 是否开启 Apollo 支持日志级别的加载时机。默认为 false。 + namespaces: application # 使用的 Apollo 的命名空间,默认为 application。 diff --git a/labx-09/labx-09-sc-apollo-demo-profiles/src/main/resources/application.yaml b/labx-09/labx-09-sc-apollo-demo-profiles/src/main/resources/application.yaml new file mode 100644 index 000000000..001e788a5 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo-profiles/src/main/resources/application.yaml @@ -0,0 +1,6 @@ +#server: +# port: 7070 + +spring: + application: + name: demo-application diff --git a/labx-09/labx-09-sc-apollo-demo/pom.xml b/labx-09/labx-09-sc-apollo-demo/pom.xml new file mode 100644 index 000000000..e4c382ca2 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo/pom.xml @@ -0,0 +1,69 @@ + + + + labx-09 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-09-sc-apollo-demo + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-commons + + + org.springframework.cloud + spring-cloud-context + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.ctrip.framework.apollo + apollo-client + 1.5.1 + + + + diff --git a/labx-09/labx-09-sc-apollo-demo/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java b/labx-09/labx-09-sc-apollo-demo/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java new file mode 100644 index 000000000..0f011da93 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/DemoApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx09.apollodemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class); + } + +} diff --git a/labx-09/labx-09-sc-apollo-demo/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/config/OrderProperties.java b/labx-09/labx-09-sc-apollo-demo/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/config/OrderProperties.java new file mode 100644 index 000000000..f5349a41c --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/config/OrderProperties.java @@ -0,0 +1,52 @@ +package cn.iocoder.springcloud.labx09.apollodemo.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + +// /** +// * 配置描述 +// */ +// private String desc; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +// public String getDesc() { +// return desc; +// } +// +// public OrderProperties setDesc(String desc) { +// this.desc = desc; +// return this; +// } + +} diff --git a/labx-09/labx-09-sc-apollo-demo/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/controller/DemoController.java b/labx-09/labx-09-sc-apollo-demo/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/controller/DemoController.java new file mode 100644 index 000000000..eed5f2edc --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo/src/main/java/cn/iocoder/springcloud/labx09/apollodemo/controller/DemoController.java @@ -0,0 +1,44 @@ +package cn.iocoder.springcloud.labx09.apollodemo.controller; + +import cn.iocoder.springcloud.labx09.apollodemo.config.OrderProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + Map result = new HashMap<>(); + result.put("payTimeoutSeconds", payTimeoutSeconds); + result.put("createFrequencySeconds", createFrequencySeconds); + return result; + } + +} diff --git a/labx-09/labx-09-sc-apollo-demo/src/main/resources/application.yaml b/labx-09/labx-09-sc-apollo-demo/src/main/resources/application.yaml new file mode 100644 index 000000000..ace5489d2 --- /dev/null +++ b/labx-09/labx-09-sc-apollo-demo/src/main/resources/application.yaml @@ -0,0 +1,12 @@ +server: + port: 7070 # 避免和本地的 Apollo Portal 端口冲突 + +app: + id: demo-application # 使用的 Apollo 的项目(应用)编号 +apollo: + meta: http://127.0.0.1:8080 # Apollo Meta Server 地址 + bootstrap: + enabled: true # 是否开启 Apollo 配置预加载功能。默认为 false。 + eagerLoad: + enable: true # 是否开启 Apollo 支持日志级别的加载时机。默认为 false。 + namespaces: application # 使用的 Apollo 的命名空间,默认为 application。 diff --git a/labx-09/pom.xml b/labx-09/pom.xml new file mode 100644 index 000000000..9989469ee --- /dev/null +++ b/labx-09/pom.xml @@ -0,0 +1,22 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-09 + pom + + labx-09-sc-apollo-demo + labx-09-sc-apollo-demo-profiles + labx-09-sc-apollo-demo-auto-refresh + labx-09-sc-apollo-demo-jasypt + labx-09-sc-apollo-demo-multi + + + diff --git "a/labx-09/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\205\215\347\275\256\344\270\255\345\277\203 Apollo \345\205\245\351\227\250\343\200\213.md" "b/labx-09/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\205\215\347\275\256\344\270\255\345\277\203 Apollo \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..2beb3a654 --- /dev/null +++ "b/labx-09/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\205\215\347\275\256\344\270\255\345\277\203 Apollo \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/pom.xml new file mode 100644 index 000000000..2e3c1fe70 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-ack + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..42a776b18 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,39 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import com.rabbitmq.client.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.amqp.support.AmqpHeaders; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + private AtomicInteger index = new AtomicInteger(); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message, + @Header(AmqpHeaders.CHANNEL) Channel channel, + @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + // 提交消费进度 +// if (message.getId() % 2 == 1) { + if (index.incrementAndGet() == 1) { + // ack 确认消息 + // 第二个参数 multiple ,用于批量确认消息,为了减少网络流量,手动确认可以被批处。 + // 1. 当 multiple 为 true 时,则可以一次性确认 deliveryTag 小于等于传入值的所有消息 + // 2. 当 multiple 为 false 时,则只确认当前 deliveryTag 对应的消息 + channel.basicAck(deliveryTag, false); + } + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/resources/application.yml new file mode 100644 index 000000000..92bfb7427 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-ack/src/main/resources/application.yml @@ -0,0 +1,35 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + # RabbitMQ 自定义 Binding 配置项,对应 RabbitBindingProperties Map + rabbit: + bindings: + demo01-input: + # RabbitMQ Consumer 配置项,对应 RabbitConsumerProperties 类 + consumer: + acknowledge-mode: MANUAL # 消费消息的确认模式,默认为 AUTO 自动确认 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/pom.xml new file mode 100644 index 000000000..19c44ad13 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/pom.xml @@ -0,0 +1,64 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..885dad4bc --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..292a5e817 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-actuator/src/main/resources/application.yml @@ -0,0 +1,39 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 + +management: + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + endpoint: + # Health 端点配置项,对应 HealthProperties 配置类 + health: + enabled: true # 是否开启。默认为 true 开启。 + show-details: ALWAYS # 何时显示完整的健康信息。默认为 NEVER 都不展示。可选 WHEN_AUTHORIZED 当经过授权的用户;可选 ALWAYS 总是展示。 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/pom.xml new file mode 100644 index 000000000..ad603bd12 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-batch + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..15f5c2195 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload List message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/resources/application.yml new file mode 100644 index 000000000..83b3f7cd8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-batch/src/main/resources/application.yml @@ -0,0 +1,31 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + batch-mode: true # 是否批量消费默认,默认为 false + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/pom.xml new file mode 100644 index 000000000..61a9d8bfa --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-broadcasting + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..885dad4bc --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/resources/application.yml new file mode 100644 index 000000000..374e754e3 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-broadcasting/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON +# group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/pom.xml new file mode 100644 index 000000000..16832ae38 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-concurrency + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..1720a9b53 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,25 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); +// +// try { +// Thread.sleep(10 * 1000L); +// } catch (InterruptedException ignored) { +// } + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/resources/application.yml new file mode 100644 index 000000000..7fa5db66b --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-concurrency/src/main/resources/application.yml @@ -0,0 +1,38 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + concurrency: 2 # 每个 Consumer 消费线程数的初始大小,默认为 1 + # RabbitMQ 自定义 Binding 配置项,对应 RabbitBindingProperties Map + rabbit: + bindings: + demo01-input: + # RabbitMQ Consumer 配置项,对应 RabbitConsumerProperties 类 + consumer: + max-concurrency: 10 # 每个 Consumer 消费线程数的最大大小,默认为 1 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/pom.xml new file mode 100644 index 000000000..7be4226e0 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-delay + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..885dad4bc --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/resources/application.yml new file mode 100644 index 000000000..9bff11e17 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/src/main/resources/application.yml @@ -0,0 +1,35 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-02 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + # RabbitMQ 自定义 Binding 配置项,对应 RabbitBindingProperties Map + rabbit: + bindings: + demo01-input: + # RabbitMQ Consumer 配置项,对应 RabbitConsumerProperties 类 + consumer: + delayed-exchange: true # 是否使用 x-delayed-message 类型的 Exchange,即延迟消息,默认为 false + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/target/classes/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/target/classes/application.yml new file mode 100644 index 000000000..9bff11e17 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-delay/target/classes/application.yml @@ -0,0 +1,35 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-02 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + # RabbitMQ 自定义 Binding 配置项,对应 RabbitBindingProperties Map + rabbit: + bindings: + demo01-input: + # RabbitMQ Consumer 配置项,对应 RabbitConsumerProperties 类 + consumer: + delayed-exchange: true # 是否使用 x-delayed-message 类型的 Exchange,即延迟消息,默认为 false + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/pom.xml new file mode 100644 index 000000000..31ab48b95 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-demo + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..885dad4bc --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/resources/application.yml new file mode 100644 index 000000000..a5e027853 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-demo/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/pom.xml new file mode 100644 index 000000000..b0875e484 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-error-handler + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..e2b523746 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,39 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.integration.context.IntegrationContextUtils; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.support.ErrorMessage; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) // 对应 DEMO-TOPIC-01.demo01-consumer-group-DEMO-TOPIC-01 + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + // 注意,此处抛出一个 RuntimeException 异常,模拟消费失败 + throw new RuntimeException("我就是故意抛出一个异常"); + } + + @ServiceActivator(inputChannel = "DEMO-TOPIC-01.demo01-consumer-group-DEMO-TOPIC-01.errors") + public void handleError(ErrorMessage errorMessage) { + logger.error("[handleError][payload:{}]", errorMessage.getPayload().getMessage()); + logger.error("[handleError][originalMessage:{}]", errorMessage.getOriginalMessage()); + logger.error("[handleError][headers:{}]", errorMessage.getHeaders()); + } + + @StreamListener(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME) // errorChannel + public void globalHandleError(ErrorMessage errorMessage) { + logger.error("[globalHandleError][payload:{}]", errorMessage.getPayload().getMessage()); + logger.error("[globalHandleError][originalMessage:{}]", errorMessage.getOriginalMessage()); + logger.error("[globalHandleError][headers:{}]", errorMessage.getHeaders()); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/resources/application.yml new file mode 100644 index 000000000..31556aaf4 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-error-handler/src/main/resources/application.yml @@ -0,0 +1,42 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + max-attempts: 3 # 重试次数,默认为 3 次。 + back-off-initial-interval: 3000 # 重试间隔的初始值,单位毫秒,默认为 1000 + back-off-multiplier: 2.0 # 重试间隔的递乘系数,默认为 2.0 + back-off-max-interval: 10000 # 重试间隔的最大值,单位毫秒,默认为 10000 + # RabbitMQ 自定义 Binding 配置项,对应 RabbitBindingProperties Map + rabbit: + bindings: + demo01-input: + # RabbitMQ Consumer 配置项,对应 RabbitConsumerProperties 类 + consumer: + auto-bind-dlq: true # 是否创建对应的死信队列,并进行绑定,默认为 false。 + republish-to-dlq: true # 消费失败的消息发布到对应的死信队列时,是否添加异常异常的信息到消息头 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/pom.xml new file mode 100644 index 000000000..6739705d9 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-filter + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..2efed23f5 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(value = MySink.DEMO01_INPUT, condition = "headers['tag'] == 'yunai'") + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/resources/application.yml new file mode 100644 index 000000000..a5e027853 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-filter/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/pom.xml new file mode 100644 index 000000000..08ae197b5 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-partitioning + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..885dad4bc --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/resources/application.yml new file mode 100644 index 000000000..aa36252fd --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-partitioning/src/main/resources/application.yml @@ -0,0 +1,32 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-03 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + consumer: + partitioned: true + instance-index: 1 + + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/pom.xml new file mode 100644 index 000000000..b97e1a5cc --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-consumer-retry + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..85330de42 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..00e515859 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + // 注意,此处抛出一个 RuntimeException 异常,模拟消费失败 + throw new RuntimeException("我就是故意抛出一个异常"); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..7a894faaf --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..74c4255d8 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/resources/application.yml new file mode 100644 index 000000000..31556aaf4 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/src/main/resources/application.yml @@ -0,0 +1,42 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + max-attempts: 3 # 重试次数,默认为 3 次。 + back-off-initial-interval: 3000 # 重试间隔的初始值,单位毫秒,默认为 1000 + back-off-multiplier: 2.0 # 重试间隔的递乘系数,默认为 2.0 + back-off-max-interval: 10000 # 重试间隔的最大值,单位毫秒,默认为 10000 + # RabbitMQ 自定义 Binding 配置项,对应 RabbitBindingProperties Map + rabbit: + bindings: + demo01-input: + # RabbitMQ Consumer 配置项,对应 RabbitConsumerProperties 类 + consumer: + auto-bind-dlq: true # 是否创建对应的死信队列,并进行绑定,默认为 false。 + republish-to-dlq: true # 消费失败的消息发布到对应的死信队列时,是否添加异常异常的信息到消息头 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/pom.xml new file mode 100644 index 000000000..e1472d0d3 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/pom.xml @@ -0,0 +1,64 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-producer-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..c128d2f4f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..cfee040e1 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.controller; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7f015623f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..64d068343 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..3e3aef43d --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-actuator/src/main/resources/application.yml @@ -0,0 +1,38 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + binder: rabbit001 # 设置使用的 Binder 名字 + +server: + port: 18080 + +management: + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + endpoint: + # Health 端点配置项,对应 HealthProperties 配置类 + health: + enabled: true # 是否开启。默认为 true 开启。 + show-details: ALWAYS # 何时显示完整的健康信息。默认为 NEVER 都不展示。可选 WHEN_AUTHORIZED 当经过授权的用户;可选 ALWAYS 总是展示。 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/pom.xml new file mode 100644 index 000000000..81e8d8bef --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-producer-batch + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..c128d2f4f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..8b628dd3e --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,45 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.controller; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send_batch") + public boolean sendBatch() throws InterruptedException { + // 发送 3 条消息,每条中间间隔 10 秒 + for (int i = 0; i < 3; i++) { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + + // 故意每条消息之间,隔离 10 秒 + logger.info("[sendBatch][发送编号:[{}] 发送成功]", message.getId()); + Thread.sleep(10 * 1000L); + } + return true; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7f015623f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..64d068343 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/resources/application.yml new file mode 100644 index 000000000..b0c9825dc --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-batch/src/main/resources/application.yml @@ -0,0 +1,37 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + binder: rabbit001 # 设置使用的 Binder 名字 + # RabbitMQ 自定义 Binding 配置项,对应 RabbitBindingProperties Map + rabbit: + bindings: + demo01-output: + # RabbitMQ Producer 配置项,对应 RabbitProducerProperties 类 + producer: + batching-enabled: true # 是否开启批量发送功能,默认为 false + batch-size: 100 # 超过收集的消息数量的最大条数,默认为 100 + batch-buffer-limit: 10000 # 每次批量发送消息的最大内存,默认为 10000 + batch-timeout: 30000 # 超过收集的时间的最大等待时长,单位:毫秒,默认为 5000 + +server: + port: 18080 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/pom.xml new file mode 100644 index 000000000..c68b3e40c --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-producer-confirm + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..c128d2f4f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..cfee040e1 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.controller; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7f015623f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01ProducerConfirmCallback.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01ProducerConfirmCallback.java new file mode 100644 index 000000000..f2738f48b --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01ProducerConfirmCallback.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.messaging.Message; +import org.springframework.stereotype.Component; + +@Component +public class Demo01ProducerConfirmCallback { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @ServiceActivator(inputChannel = "demo01-producer-confirm") + public void onPublisherConfirm(Message message) { + logger.info("[onPublisherConfirm][headers:{}]", message.getHeaders()); + logger.info("[onPublisherConfirm][payload:{}]", message.getPayload()); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01ProducerReturnCallback.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01ProducerReturnCallback.java new file mode 100644 index 000000000..c1ca385eb --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01ProducerReturnCallback.java @@ -0,0 +1,30 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.integration.context.IntegrationContextUtils; +import org.springframework.messaging.support.ErrorMessage; +import org.springframework.stereotype.Component; + +@Component +public class Demo01ProducerReturnCallback { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @ServiceActivator(inputChannel = "DEMO-TOPIC-01.errors") + public void handleError(ErrorMessage errorMessage) { + logger.error("[handleError][headers:{}]", errorMessage.getHeaders()); + logger.error("[handleError][payload:{}]", errorMessage.getPayload().getMessage()); + logger.error("[handleError][originalMessage:{}]", errorMessage.getOriginalMessage()); + } + + @StreamListener(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME) // errorChannel + public void globalHandleError(ErrorMessage errorMessage) { + logger.error("[globalHandleError][payload:{}]", errorMessage.getPayload().getMessage()); + logger.error("[globalHandleError][originalMessage:{}]", errorMessage.getOriginalMessage()); + logger.error("[globalHandleError][headers:{}]", errorMessage.getHeaders()); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..64d068343 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/resources/application.yml new file mode 100644 index 000000000..470e5d3f5 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-confirm/src/main/resources/application.yml @@ -0,0 +1,38 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + publisher-returns: true # 设置消息是否回退,默认为 false + publisher-confirm-type: simple # 设置开启消息确认模型,默认为 null 不进行确认 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + binder: rabbit001 # 设置使用的 Binder 名字 + producer: + error-channel-enabled: true # 是否开启异常 Channel,默认为 false 关闭 + # RabbitMQ 自定义 Binding 配置项,对应 RabbitBindingProperties Map + rabbit: + bindings: + demo01-output: + # RabbitMQ Producer 配置项,对应 RabbitProducerProperties 类 + producer: + confirm-ack-channel: demo01-producer-confirm # 设置发送确认的 Channel,默认为 null + +server: + port: 18080 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/pom.xml new file mode 100644 index 000000000..6695ee1d5 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-producer-delay + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..c128d2f4f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..aeb8b65d3 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,40 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.controller; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send_delay") + public boolean sendDelay() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader("x-delay", 5000) // 设置延迟时间,单位:毫秒 + .build(); + // 发送消息 + boolean sendResult = mySource.demo01Output().send(springMessage); + logger.info("[sendDelay][发送消息完成, 结果 = {}]", sendResult); + return sendResult; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7f015623f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..64d068343 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/resources/application.yml new file mode 100644 index 000000000..ae5697939 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/src/main/resources/application.yml @@ -0,0 +1,34 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-02 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + binder: rabbit001 # 设置使用的 Binder 名字 + # RabbitMQ 自定义 Binding 配置项,对应 RabbitBindingProperties Map + rabbit: + bindings: + demo01-output: + # RabbitMQ Producer 配置项,对应 RabbitProducerProperties 类 + producer: + delayed-exchange: true # 是否使用 x-delayed-message 类型的 Exchange,即延迟消息,默认为 false + +server: + port: 18080 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/pom.xml new file mode 100644 index 000000000..105a076b1 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-producer-demo + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..c128d2f4f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..084dba7b5 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,53 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.controller; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + + @GetMapping("/send_tag") + public boolean sendTag() { + for (String tag : new String[]{"yunai", "yutou", "tudou"}) { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .setHeader("tag", tag) // 设置 Tag + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + } + return true; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7f015623f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..64d068343 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/resources/application.yml new file mode 100644 index 000000000..ae514a282 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-demo/src/main/resources/application.yml @@ -0,0 +1,27 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + binder: rabbit001 # 设置使用的 Binder 名字 + +server: + port: 18080 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/pom.xml new file mode 100644 index 000000000..98234315e --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-producer-partitioning + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..c128d2f4f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..89d23a23c --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.controller; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send_orderly") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7f015623f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..64d068343 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/resources/application.yml new file mode 100644 index 000000000..153a44797 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-partitioning/src/main/resources/application.yml @@ -0,0 +1,32 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-03 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + binder: rabbit001 # 设置使用的 Binder 名字 + # Producer 配置项,对应 ProducerProperties 类 + producer: + partition-key-expression: payload['id'] # 分区 key 表达式。该表达式基于 Spring EL,从消息中获得分区 key。 + partition-count: 2 # 分区大小,默认为 1 分区 +# required-groups: demo01-consumer-group-DEMO-TOPIC-01 #only applicable for rabbit + +server: + port: 18080 diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/pom.xml new file mode 100644 index 000000000..289cd5078 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/pom.xml @@ -0,0 +1,58 @@ + + + + labx-10 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10-sc-stream-rabbitmq-producer-transaction + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..c128d2f4f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/config/TransactionConfig.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/config/TransactionConfig.java new file mode 100644 index 000000000..bd2d2a75e --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/config/TransactionConfig.java @@ -0,0 +1,18 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.config; + +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.transaction.RabbitTransactionManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableTransactionManagement +public class TransactionConfig { + + @Bean + public RabbitTransactionManager rabbitTransactionManager(ConnectionFactory connectionFactory) { + return new RabbitTransactionManager(connectionFactory); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..007def82c --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,44 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.controller; + +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @Transactional + @GetMapping("/send_transaction") + public void sendTransaction() throws InterruptedException { + // 创建 Message + int id = new Random().nextInt(); + Demo01Message message = new Demo01Message() + .setId(id); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + logger.info("[syncSend][发送编号:[{}] 发送成功]", id); + + // 等待 + Thread.sleep(10 * 1000L); + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..7f015623f --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..64d068343 --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/java/cn/iocoder/springcloud/labx10/rabbitmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx10.rabbitmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/resources/application.yml b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/resources/application.yml new file mode 100644 index 000000000..2b120690a --- /dev/null +++ b/labx-10/labx-10-sc-stream-rabbitmq-producer-transaction/src/main/resources/application.yml @@ -0,0 +1,34 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + binder: rabbit001 # 设置使用的 Binder 名字 + # RabbitMQ 自定义 Binding 配置项,对应 RabbitBindingProperties Map + rabbit: + bindings: + demo01-output: + # RabbitMQ Producer 配置项,对应 RabbitProducerProperties 类 + producer: + transacted: true # 是否开启事务功能,默认为 false + +server: + port: 18080 diff --git a/labx-10/pom.xml b/labx-10/pom.xml new file mode 100644 index 000000000..fdcdbaf64 --- /dev/null +++ b/labx-10/pom.xml @@ -0,0 +1,59 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-10 + pom + + labx-10-sc-stream-rabbitmq-producer-demo + labx-10-sc-stream-rabbitmq-consumer-demo + + labx-10-sc-stream-rabbitmq-producer-delay + labx-10-sc-stream-rabbitmq-consumer-delay + + + labx-10-sc-stream-rabbitmq-consumer-retry + + + labx-10-sc-stream-rabbitmq-consumer-error-handler + + + labx-10-sc-stream-rabbitmq-consumer-broadcasting + + labx-10-sc-stream-rabbitmq-producer-partitioning + labx-10-sc-stream-rabbitmq-consumer-partitioning + + + labx-10-sc-stream-rabbitmq-consumer-concurrency + + + labx-10-sc-stream-rabbitmq-consumer-filter + + labx-10-sc-stream-rabbitmq-producer-transaction + + + + labx-10-sc-stream-rabbitmq-consumer-ack + + labx-10-sc-stream-rabbitmq-producer-confirm + + + labx-10-sc-stream-rabbitmq-producer-batch + + + + labx-10-sc-stream-rabbitmq-consumer-batch + + labx-10-sc-stream-rabbitmq-producer-actuator + labx-10-sc-stream-rabbitmq-consumer-actuator + + + + diff --git "a/labx-10/\343\200\212\350\212\213\351\201\223 Spring Cloud \346\266\210\346\201\257\351\230\237\345\210\227 RabbitMQ \345\205\245\351\227\250\343\200\213.md" "b/labx-10/\343\200\212\350\212\213\351\201\223 Spring Cloud \346\266\210\346\201\257\351\230\237\345\210\227 RabbitMQ \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..8c31250ce --- /dev/null +++ "b/labx-10/\343\200\212\350\212\213\351\201\223 Spring Cloud \346\266\210\346\201\257\351\230\237\345\210\227 RabbitMQ \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-ack/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-ack/pom.xml new file mode 100644 index 000000000..d29b1fd8a --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-ack/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-ack + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..dc6118d50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..53034d396 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,33 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.kafka.support.Acknowledgment; +import org.springframework.kafka.support.KafkaHeaders; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +import java.util.concurrent.atomic.AtomicInteger; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + private AtomicInteger index = new AtomicInteger(); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message, + @Header(KafkaHeaders.ACKNOWLEDGMENT) Acknowledgment acknowledgment) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + // 提交消费进度 +// if (message.getId() % 2 == 1) { + if (index.incrementAndGet() == 1) { + acknowledgment.acknowledge(); + } + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/resources/application.yml new file mode 100644 index 000000000..6c8cf5ac6 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-ack/src/main/resources/application.yml @@ -0,0 +1,29 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + # Kafka Binding 配置项,对应 KafkaBindingProperties 类 + bindings: + demo01-input: + # Kafka Consumer 配置项,对应 KafkaConsumerProperties 类 + consumer: + auto-commit-offset: false # 是否自动提交消费进度,默认为 true 自动提交。 + ack-each-record: true # 是否每一条消息都进行提交消费进度,默认为 false 在每一批消费完成后一起提交。 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-actuator/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/pom.xml new file mode 100644 index 000000000..9b2b4202d --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/pom.xml @@ -0,0 +1,64 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..dc6118d50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..979fb5430 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..d49990b84 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-actuator/src/main/resources/application.yml @@ -0,0 +1,33 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 + +management: + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + endpoint: + # Health 端点配置项,对应 HealthProperties 配置类 + health: + enabled: true # 是否开启。默认为 true 开启。 + show-details: ALWAYS # 何时显示完整的健康信息。默认为 NEVER 都不展示。可选 WHEN_AUTHORIZED 当经过授权的用户;可选 ALWAYS 总是展示。 diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-batch/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-batch/pom.xml new file mode 100644 index 000000000..1dc128fdb --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-batch/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-batch + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..dc6118d50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..c99912746 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload List messages) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), messages); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/resources/application.yml new file mode 100644 index 000000000..c429ebf34 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-batch/src/main/resources/application.yml @@ -0,0 +1,29 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + batch-mode: true # 是否批量消费默认,默认为 false + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + configuration: + fetch.max.wait.ms: 10000 # poll 一次拉取的阻塞的最大时长,单位:毫秒。这里指的是阻塞拉取需要满足至少 fetch-min-size 大小的消息 + fetch.min.bytes: 1024 # poll 一次消息拉取的最小数据量,单位:字节 + max.poll.records: 100 # poll 一次消息拉取的最大数量 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/pom.xml new file mode 100644 index 000000000..5a3cbaaa0 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-broadcasting + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..dc6118d50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..979fb5430 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/resources/application.yml new file mode 100644 index 000000000..99175a018 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-broadcasting/src/main/resources/application.yml @@ -0,0 +1,22 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON +# group: demo01-consumer-group # 消费者分组 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/pom.xml new file mode 100644 index 000000000..3eea5acd7 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-concurrency + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..dc6118d50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..979fb5430 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/resources/application.yml new file mode 100644 index 000000000..80cc70e98 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-concurrency/src/main/resources/application.yml @@ -0,0 +1,25 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + concurrency: 2 # 每个 Consumer 消费线程数的初始大小,默认为 1 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-demo/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-demo/pom.xml new file mode 100644 index 000000000..021d5a0de --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-demo/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-demo + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..dc6118d50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..979fb5430 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/resources/application.yml new file mode 100644 index 000000000..18a2a4d9a --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-demo/src/main/resources/application.yml @@ -0,0 +1,22 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/pom.xml new file mode 100644 index 000000000..f977b8d4b --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-error-handler + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..dc6118d50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..b621a5e66 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,39 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.integration.annotation.ServiceActivator; +import org.springframework.integration.context.IntegrationContextUtils; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.support.ErrorMessage; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) // 对应 DEMO-TOPIC-01.demo01-consumer-group + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + // 注意,此处抛出一个 RuntimeException 异常,模拟消费失败 + throw new RuntimeException("我就是故意抛出一个异常"); + } + + @ServiceActivator(inputChannel = "DEMO-TOPIC-01.demo01-consumer-group.errors") + public void handleError(ErrorMessage errorMessage) { + logger.error("[handleError][payload:{}]", errorMessage.getPayload().getMessage()); + logger.error("[handleError][originalMessage:{}]", errorMessage.getOriginalMessage()); + logger.error("[handleError][headers:{}]", errorMessage.getHeaders()); + } + + @StreamListener(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME) // errorChannel + public void globalHandleError(ErrorMessage errorMessage) { + logger.error("[globalHandleError][payload:{}]", errorMessage.getPayload().getMessage()); + logger.error("[globalHandleError][originalMessage:{}]", errorMessage.getOriginalMessage()); + logger.error("[globalHandleError][headers:{}]", errorMessage.getHeaders()); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/resources/application.yml new file mode 100644 index 000000000..5f9bc4b50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-error-handler/src/main/resources/application.yml @@ -0,0 +1,35 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + max-attempts: 3 # 重试次数,默认为 3 次。 + back-off-initial-interval: 3000 # 重试间隔的初始值,单位毫秒,默认为 1000 + back-off-multiplier: 2.0 # 重试间隔的递乘系数,默认为 2.0 + back-off-max-interval: 10000 # 重试间隔的最大值,单位毫秒,默认为 10000 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + # Kafka Binding 配置项,对应 KafkaBindingProperties 类 + bindings: + demo01-input: + # Kafka Consumer 配置项,对应 KafkaConsumerProperties 类 + consumer: + enable-dlq: true # 是否开启死信队列,默认为 false 关闭 + dlq-name: # 死信队列名,默认为 `errors.{topicName}.{consumerGroup}` + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-filter/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-filter/pom.xml new file mode 100644 index 000000000..1533110a4 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-filter/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-filter + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..dc6118d50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..a4a0d5be5 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(value = MySink.DEMO01_INPUT, condition = "headers['tag'] == 'yunai'") + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/resources/application.yml new file mode 100644 index 000000000..18a2a4d9a --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-filter/src/main/resources/application.yml @@ -0,0 +1,22 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/pom.xml new file mode 100644 index 000000000..438af7903 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-partitioning + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..dc6118d50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..1be848c78 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,19 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.Message; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/resources/application.yml new file mode 100644 index 000000000..80cc70e98 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-partitioning/src/main/resources/application.yml @@ -0,0 +1,25 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + concurrency: 2 # 每个 Consumer 消费线程数的初始大小,默认为 1 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-retry/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-retry/pom.xml new file mode 100644 index 000000000..d9cd9498e --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-retry/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-retry + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..dc6118d50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..c182f72e3 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + // 注意,此处抛出一个 RuntimeException 异常,模拟消费失败 + throw new RuntimeException("我就是故意抛出一个异常"); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/resources/application.yml new file mode 100644 index 000000000..5f9bc4b50 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-retry/src/main/resources/application.yml @@ -0,0 +1,35 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Consumer 配置项,对应 ConsumerProperties 类 + consumer: + max-attempts: 3 # 重试次数,默认为 3 次。 + back-off-initial-interval: 3000 # 重试间隔的初始值,单位毫秒,默认为 1000 + back-off-multiplier: 2.0 # 重试间隔的递乘系数,默认为 2.0 + back-off-max-interval: 10000 # 重试间隔的最大值,单位毫秒,默认为 10000 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + # Kafka Binding 配置项,对应 KafkaBindingProperties 类 + bindings: + demo01-input: + # Kafka Consumer 配置项,对应 KafkaConsumerProperties 类 + consumer: + enable-dlq: true # 是否开启死信队列,默认为 false 关闭 + dlq-name: # 死信队列名,默认为 `errors.{topicName}.{consumerGroup}` + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-transaction/pom.xml b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/pom.xml new file mode 100644 index 000000000..7f165c648 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-consumer-transaction + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..a780ba327 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,25 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + +// @Bean +// public ListenerContainerCustomizer> customizer() { +// return (container, dest, group) -> { +// KafkaTransactionManager tm = (KafkaTransactionManager) container.getContainerProperties() +// .getTransactionManager(); +// tm.setTransactionSynchronization(AbstractPlatformTransactionManager.SYNCHRONIZATION_ON_ACTUAL_TRANSACTION); +// }; +// } + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..979fb5430 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..1e510b798 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..cf57407a8 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/resources/application.yml new file mode 100644 index 000000000..ce42cb948 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-consumer-transaction/src/main/resources/application.yml @@ -0,0 +1,31 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + # Kafka Binding 配置项,对应 KafkaBindingProperties 类 + bindings: + demo01-input: + # Kafka Consumer 配置项,对应 KafkaConsumerProperties 类 + consumer: + configuration: + isolation: + level: read_committed # 读取已提交的消息 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-11/labx-11-sc-stream-kafka-producer-actuator/pom.xml b/labx-11/labx-11-sc-stream-kafka-producer-actuator/pom.xml new file mode 100644 index 000000000..179381ad0 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-actuator/pom.xml @@ -0,0 +1,64 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-producer-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java b/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java new file mode 100644 index 000000000..2dad60852 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo; + +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java b/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java new file mode 100644 index 000000000..cd198f259 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java @@ -0,0 +1,39 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.controller; + +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.Demo01Message; +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + boolean result = mySource.demo01Output().send(springMessage); + logger.info("[send][发送编号:[{}] 发送成功]", message.getId()); + return result; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java new file mode 100644 index 000000000..6efa42492 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java b/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java new file mode 100644 index 000000000..c1d582487 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..f01ea3bb5 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-actuator/src/main/resources/application.yml @@ -0,0 +1,38 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + # Kafka 自定义 Binding 配置项,对应 KafkaBindingProperties Map + bindings: + demo01-output: + # Kafka Producer 配置项,对应 KafkaProducerProperties 类 + producer: + sync: true # 是否同步发送消息,默认为 false 异步。 + +server: + port: 18080 + +management: + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + endpoint: + # Health 端点配置项,对应 HealthProperties 配置类 + health: + enabled: true # 是否开启。默认为 true 开启。 + show-details: ALWAYS # 何时显示完整的健康信息。默认为 NEVER 都不展示。可选 WHEN_AUTHORIZED 当经过授权的用户;可选 ALWAYS 总是展示。 diff --git a/labx-11/labx-11-sc-stream-kafka-producer-batch/pom.xml b/labx-11/labx-11-sc-stream-kafka-producer-batch/pom.xml new file mode 100644 index 000000000..579473ee6 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-batch/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-producer-batch + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java b/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java new file mode 100644 index 000000000..2dad60852 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo; + +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java b/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java new file mode 100644 index 000000000..54ecf1736 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java @@ -0,0 +1,42 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.controller; + +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.Demo01Message; +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send_batch") + public boolean sendBatch() { + for (int i = 0; i < 3; i++) { + // 创建 Message + int id = new Random().nextInt(); + Demo01Message message = new Demo01Message() + .setId(id); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + logger.info("[send_batch][发送编号:[{}] 发送成功]", id); + } + return true; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java new file mode 100644 index 000000000..6efa42492 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java b/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java new file mode 100644 index 000000000..c1d582487 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/resources/application.yml new file mode 100644 index 000000000..6075ffe37 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-batch/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + # Kafka 自定义 Binding 配置项,对应 KafkaBindingProperties Map + bindings: + demo01-output: + # Kafka Producer 配置项,对应 KafkaProducerProperties 类 + producer: + batch-timeout: 30000 # 批处理延迟时间上限。这里配置为 30 * 1000 ms 过后,不管是否消息数量是否到达 batch-size 或者消息大小到达 buffer-memory 后,都直接发送一次请求 + buffer-size: 33554432 # 每次批量发送消息的最大内存 + +server: + port: 18080 diff --git a/labx-11/labx-11-sc-stream-kafka-producer-demo/pom.xml b/labx-11/labx-11-sc-stream-kafka-producer-demo/pom.xml new file mode 100644 index 000000000..451b14ca0 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-demo/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-producer-demo + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java b/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java new file mode 100644 index 000000000..2dad60852 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo; + +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java b/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java new file mode 100644 index 000000000..cd198f259 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java @@ -0,0 +1,39 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.controller; + +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.Demo01Message; +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + boolean result = mySource.demo01Output().send(springMessage); + logger.info("[send][发送编号:[{}] 发送成功]", message.getId()); + return result; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java new file mode 100644 index 000000000..6efa42492 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java b/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java new file mode 100644 index 000000000..c1d582487 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/resources/application.yml new file mode 100644 index 000000000..75edacb5a --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-demo/src/main/resources/application.yml @@ -0,0 +1,27 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + # Kafka 自定义 Binding 配置项,对应 KafkaBindingProperties Map + bindings: + demo01-output: + # Kafka Producer 配置项,对应 KafkaProducerProperties 类 + producer: + sync: true # 是否同步发送消息,默认为 false 异步。 + +server: + port: 18080 diff --git a/labx-11/labx-11-sc-stream-kafka-producer-partitioning/pom.xml b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/pom.xml new file mode 100644 index 000000000..877a2cb78 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-producer-partitioning + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java new file mode 100644 index 000000000..2dad60852 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo; + +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java new file mode 100644 index 000000000..900fdfe3c --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java @@ -0,0 +1,41 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.controller; + +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.Demo01Message; +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send_orderly") + public boolean sendOrderly() { + // 发送 3 条相同 id 的消息 + int id = new Random().nextInt(); + for (int i = 0; i < 3; i++) { + // 创建 Message + Demo01Message message = new Demo01Message().setId(id); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + } + return true; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java new file mode 100644 index 000000000..6efa42492 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java new file mode 100644 index 000000000..c1d582487 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/resources/application.yml new file mode 100644 index 000000000..0300d455d --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-partitioning/src/main/resources/application.yml @@ -0,0 +1,30 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + # Producer 配置项,对应 ProducerProperties 类 + producer: + partition-key-expression: payload['id'] # 分区 key 表达式。该表达式基于 Spring EL,从消息中获得分区 key。 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + # Kafka 自定义 Binding 配置项,对应 KafkaBindingProperties Map + bindings: + demo01-output: + # Kafka Producer 配置项,对应 KafkaProducerProperties 类 + producer: + sync: true # 是否同步发送消息,默认为 false 异步。 + +server: + port: 18080 diff --git a/labx-11/labx-11-sc-stream-kafka-producer-transaction/pom.xml b/labx-11/labx-11-sc-stream-kafka-producer-transaction/pom.xml new file mode 100644 index 000000000..cdebac524 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-transaction/pom.xml @@ -0,0 +1,58 @@ + + + + labx-11 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11-sc-stream-kafka-producer-transaction + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java new file mode 100644 index 000000000..2dad60852 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo; + +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/config/TransactionConfig.java b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/config/TransactionConfig.java new file mode 100644 index 000000000..9acaf8677 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/config/TransactionConfig.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.config; + +import org.springframework.cloud.stream.binder.BinderFactory; +import org.springframework.cloud.stream.binder.kafka.KafkaMessageChannelBinder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.ProducerFactory; +import org.springframework.kafka.transaction.KafkaTransactionManager; +import org.springframework.messaging.MessageChannel; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableTransactionManagement +public class TransactionConfig { + + @Bean + public PlatformTransactionManager transactionManager(BinderFactory binders) { + // 获得 Kafka ProducerFactory 对象 + ProducerFactory pf = ((KafkaMessageChannelBinder) binders.getBinder(null, + MessageChannel.class)).getTransactionalProducerFactory(); + // 创建 KafkaTransactionManager 事务管理器 + assert pf != null; + return new KafkaTransactionManager<>(pf); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java new file mode 100644 index 000000000..0faa15818 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/controller/Demo01Controller.java @@ -0,0 +1,44 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.controller; + +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.Demo01Message; +import cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @Transactional + @GetMapping("/send_transaction") + public void sendTransaction() throws InterruptedException { + // 创建 Message + int id = new Random().nextInt(); + Demo01Message message = new Demo01Message() + .setId(id); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + mySource.demo01Output().send(springMessage); + logger.info("[send_transaction][发送编号:[{}] 发送成功]", id); + + // 等待 + Thread.sleep(10 * 1000L); + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java new file mode 100644 index 000000000..6efa42492 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java new file mode 100644 index 000000000..c1d582487 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/java/cn/iocoder/springcloud/labx11/kafkademo/kafkademo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx11.kafkademo.kafkademo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/resources/application.yml b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/resources/application.yml new file mode 100644 index 000000000..94e7061c6 --- /dev/null +++ b/labx-11/labx-11-sc-stream-kafka-producer-transaction/src/main/resources/application.yml @@ -0,0 +1,33 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map +# binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + transaction: + transaction-id-prefix: demo. # 事务编号前缀 + producer: + configuration: + retries: 1 # 发送失败时,重试发送的次数 + acks: all # 0-不应答。1-leader 应答。all-所有 leader 和 follower 应答。 + # Kafka 自定义 Binding 配置项,对应 KafkaBindingProperties Map + bindings: + demo01-output: + # Kafka Producer 配置项,对应 KafkaProducerProperties 类 + producer: + sync: true # 是否同步发送消息,默认为 false 异步。 + +server: + port: 18080 diff --git a/labx-11/pom.xml b/labx-11/pom.xml new file mode 100644 index 000000000..1d92ae6a9 --- /dev/null +++ b/labx-11/pom.xml @@ -0,0 +1,54 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-11 + pom + + + labx-11-sc-stream-kafka-producer-demo + labx-11-sc-stream-kafka-consumer-demo + + + labx-11-sc-stream-kafka-consumer-retry + + + labx-11-sc-stream-kafka-consumer-error-handler + + + labx-11-sc-stream-kafka-consumer-broadcasting + + + labx-11-sc-stream-kafka-consumer-concurrency + + labx-11-sc-stream-kafka-producer-partitioning + + labx-11-sc-stream-kafka-consumer-partitioning + + + labx-11-sc-stream-kafka-consumer-filter + + labx-11-sc-stream-kafka-producer-transaction + labx-11-sc-stream-kafka-consumer-transaction + + + labx-11-sc-stream-kafka-consumer-ack + + labx-11-sc-stream-kafka-producer-batch + + + + labx-11-sc-stream-kafka-consumer-batch + + labx-11-sc-stream-kafka-producer-actuator + labx-11-sc-stream-kafka-consumer-actuator + + + diff --git "a/labx-11/\343\200\212\350\212\213\351\201\223 Spring Cloud \346\266\210\346\201\257\351\230\237\345\210\227 Kafka \345\205\245\351\227\250\343\200\213.md" "b/labx-11/\343\200\212\350\212\213\351\201\223 Spring Cloud \346\266\210\346\201\257\351\230\237\345\210\227 Kafka \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..d798cce59 --- /dev/null +++ "b/labx-11/\343\200\212\350\212\213\351\201\223 Spring Cloud \346\266\210\346\201\257\351\230\237\345\210\227 Kafka \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-12/labx-12-sc-config-server-demo/pom.xml b/labx-12/labx-12-sc-config-server-demo/pom.xml new file mode 100644 index 000000000..f47ec6862 --- /dev/null +++ b/labx-12/labx-12-sc-config-server-demo/pom.xml @@ -0,0 +1,58 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-12-sc-config-server-demo + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-config-server + + + + diff --git a/labx-12/labx-12-sc-config-server-demo/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java b/labx-12/labx-12-sc-config-server-demo/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java new file mode 100644 index 000000000..d6b66ae12 --- /dev/null +++ b/labx-12/labx-12-sc-config-server-demo/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx12.configserverdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +@SpringBootApplication +@EnableConfigServer +public class ConfigServerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConfigServerApplication.class, args); + } + +} diff --git a/labx-12/labx-12-sc-config-server-demo/src/main/resources/application.yml b/labx-12/labx-12-sc-config-server-demo/src/main/resources/application.yml new file mode 100644 index 000000000..a707fbfb2 --- /dev/null +++ b/labx-12/labx-12-sc-config-server-demo/src/main/resources/application.yml @@ -0,0 +1,13 @@ +server: + port: 8888 + +spring: + application: + name: demo-config-server + profiles: + active: native # TODO 采用的方案 + cloud: + config: + server: + native: + search-locations: classpath:/shared diff --git a/labx-12/labx-12-sc-config-server-demo/src/main/resources/shared/user-application.yml b/labx-12/labx-12-sc-config-server-demo/src/main/resources/shared/user-application.yml new file mode 100644 index 000000000..497390b1e --- /dev/null +++ b/labx-12/labx-12-sc-config-server-demo/src/main/resources/shared/user-application.yml @@ -0,0 +1,3 @@ +order: + pay-timeout-seconds: 60 # 订单支付超时时长,单位:秒。 + create-frequency-seconds: 120 # 订单创建频率,单位:秒 diff --git a/labx-12/labx-12-sc-config-server-git-auto-refresh-by-bus/pom.xml b/labx-12/labx-12-sc-config-server-git-auto-refresh-by-bus/pom.xml new file mode 100644 index 000000000..e2f9b9212 --- /dev/null +++ b/labx-12/labx-12-sc-config-server-git-auto-refresh-by-bus/pom.xml @@ -0,0 +1,70 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-12-sc-config-server-git-auto-refresh-by-bus + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-config-server + + + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + + + org.springframework.cloud + spring-cloud-config-monitor + + + + diff --git a/labx-12/labx-12-sc-config-server-git-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java b/labx-12/labx-12-sc-config-server-git-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java new file mode 100644 index 000000000..d6b66ae12 --- /dev/null +++ b/labx-12/labx-12-sc-config-server-git-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx12.configserverdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +@SpringBootApplication +@EnableConfigServer +public class ConfigServerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConfigServerApplication.class, args); + } + +} diff --git a/labx-12/labx-12-sc-config-server-git-auto-refresh-by-bus/src/main/resources/application.yml b/labx-12/labx-12-sc-config-server-git-auto-refresh-by-bus/src/main/resources/application.yml new file mode 100644 index 000000000..fc64892b4 --- /dev/null +++ b/labx-12/labx-12-sc-config-server-git-auto-refresh-by-bus/src/main/resources/application.yml @@ -0,0 +1,27 @@ +server: + port: 8888 + +spring: + application: + name: demo-config-server + + profiles: + active: git # 使用的 Spring Cloud Config Server 的存储器方案 + # Spring Cloud Config 相关配置项 + cloud: + config: + server: + # Spring Cloud Config Server 的 Git 存储器的配置项,对应 MultipleJGitEnvironmentProperties 类 + git: + uri: https://github.com/YunaiV/demo-config-server.git # Git 仓库地址 + search-paths: / # 读取文件的根地址 + default-label: master # 使用的默认分支,默认为 master + # username: ${CODING_USERNAME} # 账号 + # password: ${CODING_PASSWORD} # 密码 + + # RabbitMQ 相关配置项 + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest diff --git a/labx-12/labx-12-sc-config-server-git-nacos/pom.xml b/labx-12/labx-12-sc-config-server-git-nacos/pom.xml new file mode 100644 index 000000000..17564feea --- /dev/null +++ b/labx-12/labx-12-sc-config-server-git-nacos/pom.xml @@ -0,0 +1,66 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-12-sc-config-server-git-nacos + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-config-server + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-12/labx-12-sc-config-server-git-nacos/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java b/labx-12/labx-12-sc-config-server-git-nacos/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java new file mode 100644 index 000000000..d6b66ae12 --- /dev/null +++ b/labx-12/labx-12-sc-config-server-git-nacos/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx12.configserverdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +@SpringBootApplication +@EnableConfigServer +public class ConfigServerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConfigServerApplication.class, args); + } + +} diff --git a/labx-12/labx-12-sc-config-server-git-nacos/src/main/resources/application.yml b/labx-12/labx-12-sc-config-server-git-nacos/src/main/resources/application.yml new file mode 100644 index 000000000..88a8db8ee --- /dev/null +++ b/labx-12/labx-12-sc-config-server-git-nacos/src/main/resources/application.yml @@ -0,0 +1,28 @@ +server: + port: 8888 + +spring: + application: + name: demo-config-server + + profiles: + active: git # 使用的 Spring Cloud Config Server 的存储器方案 + + # Spring Cloud Config 相关配置项 + cloud: + config: + server: + # Spring Cloud Config Server 的 Git 存储器的配置项,对应 MultipleJGitEnvironmentProperties 类 + git: + uri: https://github.com/YunaiV/demo-config-server.git # Git 仓库地址 + search-paths: / # 读取文件的根地址 + default-label: master # 使用的默认分支,默认为 master +# username: ${CODING_USERNAME} # 账号 +# password: ${CODING_PASSWORD} # 密码 + + # Spring Cloud Nacos Discovery 相关配置项 + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + service: ${spring.application.name} # 注册到 Nacos 的服务名。默认值为 ${spring.application.name}。 diff --git a/labx-12/labx-12-sc-config-server-git/pom.xml b/labx-12/labx-12-sc-config-server-git/pom.xml new file mode 100644 index 000000000..dff320d70 --- /dev/null +++ b/labx-12/labx-12-sc-config-server-git/pom.xml @@ -0,0 +1,78 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-12-sc-config-server-git + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-config-server + + + + + + + + + + + + + + + + + + + + src/main/resource + + **/*.yml + **/*.jks + + false + + + + + diff --git a/labx-12/labx-12-sc-config-server-git/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java b/labx-12/labx-12-sc-config-server-git/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java new file mode 100644 index 000000000..d6b66ae12 --- /dev/null +++ b/labx-12/labx-12-sc-config-server-git/src/main/java/cn/iocoder/springcloud/labx12/configserverdemo/ConfigServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx12.configserverdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +@SpringBootApplication +@EnableConfigServer +public class ConfigServerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConfigServerApplication.class, args); + } + +} diff --git a/labx-12/labx-12-sc-config-server-git/src/main/resources/application.yml b/labx-12/labx-12-sc-config-server-git/src/main/resources/application.yml new file mode 100644 index 000000000..bc2f66307 --- /dev/null +++ b/labx-12/labx-12-sc-config-server-git/src/main/resources/application.yml @@ -0,0 +1,19 @@ +server: + port: 8888 + +spring: + application: + name: demo-config-server + + profiles: + active: git # 使用的 Spring Cloud Config Server 的存储器方案 + cloud: + config: + server: + # Spring Cloud Config Server 的 Git 存储器的配置项,对应 MultipleJGitEnvironmentProperties 类 + git: + uri: https://github.com/YunaiV/demo-config-server.git # Git 仓库地址 + search-paths: / # 读取文件的根地址 + default-label: master # 使用的默认分支,默认为 master +# username: ${CODING_USERNAME} # 账号 +# password: ${CODING_PASSWORD} # 密码 diff --git a/labx-12/labx-12-sc-config-server-git/src/main/resources/bootstrap.yml b/labx-12/labx-12-sc-config-server-git/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..dd6b8961f --- /dev/null +++ b/labx-12/labx-12-sc-config-server-git/src/main/resources/bootstrap.yml @@ -0,0 +1,12 @@ +# 加密配置项,对应 KeyProperties 类 +encrypt: + # 对称加密 +# key: yudaoyuanma # 对称加密 key +# salt: dfaad7761f0729b35ec3b3543604eda7 # 对称加密 salt,默认为 "deadbeef",必须是 16 进制 + + # 非对应加密 + key-store: + location: classpath:/configserver.jks # jks 文件所在的路径 + password: buzhidao # 对应 storepass 参数 + alias: mytestkey # 对应 alias 参数 + secret: nicainicai # 对应 keypass 参数 diff --git a/labx-12/labx-12-sc-config-server-git/src/main/resources/configserver.jks b/labx-12/labx-12-sc-config-server-git/src/main/resources/configserver.jks new file mode 100644 index 000000000..12d8e82a5 Binary files /dev/null and b/labx-12/labx-12-sc-config-server-git/src/main/resources/configserver.jks differ diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/pom.xml b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/pom.xml new file mode 100644 index 000000000..66cc7efa3 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/pom.xml @@ -0,0 +1,64 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-12-sc-config-user-application-auto-refresh-by-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-config + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java new file mode 100644 index 000000000..008c5e3e0 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx12.userapplication; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserApplication { + + public static void main(String[] args) { + SpringApplication.run(UserApplication.class, args); + } + +} diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java new file mode 100644 index 000000000..4878e5f1b --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java @@ -0,0 +1,53 @@ +package cn.iocoder.springcloud.labx12.userapplication.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +//@NacosConfigurationProperties(prefix = "order", dataId = "${nacos.config.data-id}", type = ConfigType.YAML) +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + +// /** +// * 配置描述 +// */ +// private String desc; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +// public String getDesc() { +// return desc; +// } +// +// public OrderProperties setDesc(String desc) { +// this.desc = desc; +// return this; +// } + +} diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java new file mode 100644 index 000000000..99736bbc8 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java @@ -0,0 +1,55 @@ +package cn.iocoder.springcloud.labx12.userapplication.controller; + +import cn.iocoder.springcloud.labx12.userapplication.config.OrderProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/demo") +@RefreshScope +public class DemoController { + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") // @NacosValue(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") // @NacosValue(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + Map result = new HashMap<>(); + result.put("payTimeoutSeconds", payTimeoutSeconds); + result.put("createFrequencySeconds", createFrequencySeconds); + return result; + } + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @GetMapping("/logger") + public void logger() { + logger.debug("[logger][测试一下]"); + } + +} diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/listener/DemoEnvironmentChangeListener.java b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/listener/DemoEnvironmentChangeListener.java new file mode 100644 index 000000000..58640316f --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/java/cn/iocoder/springcloud/labx12/userapplication/listener/DemoEnvironmentChangeListener.java @@ -0,0 +1,26 @@ +package cn.iocoder.springcloud.labx12.userapplication.listener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.context.environment.EnvironmentChangeEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.stereotype.Component; + +@Component +public class DemoEnvironmentChangeListener implements ApplicationListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ConfigurableEnvironment environment; + + @Override + public void onApplicationEvent(EnvironmentChangeEvent event) { + for (String key : event.getKeys()) { + logger.info("[onApplicationEvent][key({}) 最新 value 为 {}]", key, environment.getProperty(key)); + } + } + +} diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/resources/application.yml b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..cad1a705f --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/resources/application.yml @@ -0,0 +1,6 @@ +management: + endpoints: + # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类 + web: + exposure: + include: refresh # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/resources/bootstrap.yml b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..90519d713 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-actuator/src/main/resources/bootstrap.yml @@ -0,0 +1,8 @@ +spring: + application: + name: user-application + cloud: + config: + uri: http://127.0.0.1:8888 + name: ${spring.application.name} + fail-fast: true # TODO diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/pom.xml b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/pom.xml new file mode 100644 index 000000000..34bda74a7 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/pom.xml @@ -0,0 +1,64 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-12-sc-config-user-application-auto-refresh-by-bus + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-config + + + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + + diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java new file mode 100644 index 000000000..008c5e3e0 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx12.userapplication; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserApplication { + + public static void main(String[] args) { + SpringApplication.run(UserApplication.class, args); + } + +} diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java new file mode 100644 index 000000000..c7369a53b --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java @@ -0,0 +1,38 @@ +package cn.iocoder.springcloud.labx12.userapplication.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +} diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java new file mode 100644 index 000000000..6f7ab2af1 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java @@ -0,0 +1,46 @@ +package cn.iocoder.springcloud.labx12.userapplication.controller; + +import cn.iocoder.springcloud.labx12.userapplication.config.OrderProperties; +import org.springframework.beans.factory.annotation.Autowired; +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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/demo") +@RefreshScope +public class DemoController { + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + Map result = new HashMap<>(); + result.put("payTimeoutSeconds", payTimeoutSeconds); + result.put("createFrequencySeconds", createFrequencySeconds); + return result; + } + +} diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/resources/application.yml b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/resources/application.yml new file mode 100644 index 000000000..f1d7c2334 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/resources/application.yml @@ -0,0 +1,7 @@ +spring: + # RabbitMQ 相关配置项 + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest diff --git a/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/resources/bootstrap.yml b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..6ae779eeb --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-auto-refresh-by-bus/src/main/resources/bootstrap.yml @@ -0,0 +1,9 @@ +spring: + application: + name: user-application + + cloud: + # Spring Cloud Config Client 配置项,对应 ConfigClientProperties 类 + config: + uri: http://127.0.0.1:8888 # Spring Cloud Config Server 的地址 + name: ${spring.application.name} # 读取的配置文件的名字,默认为 ${spring.application.name} diff --git a/labx-12/labx-12-sc-config-user-application-nacos/pom.xml b/labx-12/labx-12-sc-config-user-application-nacos/pom.xml new file mode 100644 index 000000000..6fbfeed8d --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-nacos/pom.xml @@ -0,0 +1,72 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-12-sc-config-user-application-nacos + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-12/labx-12-sc-config-user-application-nacos/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java b/labx-12/labx-12-sc-config-user-application-nacos/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java new file mode 100644 index 000000000..008c5e3e0 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-nacos/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx12.userapplication; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserApplication { + + public static void main(String[] args) { + SpringApplication.run(UserApplication.class, args); + } + +} diff --git a/labx-12/labx-12-sc-config-user-application-nacos/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java b/labx-12/labx-12-sc-config-user-application-nacos/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java new file mode 100644 index 000000000..c7369a53b --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-nacos/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java @@ -0,0 +1,38 @@ +package cn.iocoder.springcloud.labx12.userapplication.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +} diff --git a/labx-12/labx-12-sc-config-user-application-nacos/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java b/labx-12/labx-12-sc-config-user-application-nacos/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java new file mode 100644 index 000000000..765768c75 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-nacos/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java @@ -0,0 +1,60 @@ +package cn.iocoder.springcloud.labx12.userapplication.controller; + +import cn.iocoder.springcloud.labx12.userapplication.config.OrderProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + Map result = new HashMap<>(); + result.put("payTimeoutSeconds", payTimeoutSeconds); + result.put("createFrequencySeconds", createFrequencySeconds); + return result; + } + + @Value(value = "${xx-password:''}") + private String xxPassword; + + @GetMapping("/xx_password") + public String xxPassword() { + return xxPassword; + } + + @Value(value = "${yy-password:''}") + private String yyPassword; + + @GetMapping("/yy_password") + public String yyPassword() { + return yyPassword; + } + +} diff --git a/labx-12/labx-12-sc-config-user-application-nacos/src/main/resources/bootstrap.yml b/labx-12/labx-12-sc-config-user-application-nacos/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..253ce6039 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application-nacos/src/main/resources/bootstrap.yml @@ -0,0 +1,18 @@ +spring: + application: + name: user-application + + cloud: + # Spring Cloud Config Client 配置项,对应 ConfigClientProperties 类 + config: + name: ${spring.application.name} # 读取的配置文件的名字,默认为 ${spring.application.name} + discovery: + enabled: true # 是否使用注册发现,获取配置中心的地址,默认为 false + service-id: demo-config-server # 配置中心的服务名 + + # Spring Cloud Nacos Discovery 相关配置项 + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + service: ${spring.application.name} # 注册到 Nacos 的服务名。默认值为 ${spring.application.name}。 diff --git a/labx-12/labx-12-sc-config-user-application/pom.xml b/labx-12/labx-12-sc-config-user-application/pom.xml new file mode 100644 index 000000000..690d346b5 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application/pom.xml @@ -0,0 +1,58 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-12-sc-config-user-application + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-config + + + + diff --git a/labx-12/labx-12-sc-config-user-application/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java b/labx-12/labx-12-sc-config-user-application/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java new file mode 100644 index 000000000..008c5e3e0 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application/src/main/java/cn/iocoder/springcloud/labx12/userapplication/UserApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx12.userapplication; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserApplication { + + public static void main(String[] args) { + SpringApplication.run(UserApplication.class, args); + } + +} diff --git a/labx-12/labx-12-sc-config-user-application/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java b/labx-12/labx-12-sc-config-user-application/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java new file mode 100644 index 000000000..c7369a53b --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application/src/main/java/cn/iocoder/springcloud/labx12/userapplication/config/OrderProperties.java @@ -0,0 +1,38 @@ +package cn.iocoder.springcloud.labx12.userapplication.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +} diff --git a/labx-12/labx-12-sc-config-user-application/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java b/labx-12/labx-12-sc-config-user-application/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java new file mode 100644 index 000000000..765768c75 --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application/src/main/java/cn/iocoder/springcloud/labx12/userapplication/controller/DemoController.java @@ -0,0 +1,60 @@ +package cn.iocoder.springcloud.labx12.userapplication.controller; + +import cn.iocoder.springcloud.labx12.userapplication.config.OrderProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + Map result = new HashMap<>(); + result.put("payTimeoutSeconds", payTimeoutSeconds); + result.put("createFrequencySeconds", createFrequencySeconds); + return result; + } + + @Value(value = "${xx-password:''}") + private String xxPassword; + + @GetMapping("/xx_password") + public String xxPassword() { + return xxPassword; + } + + @Value(value = "${yy-password:''}") + private String yyPassword; + + @GetMapping("/yy_password") + public String yyPassword() { + return yyPassword; + } + +} diff --git a/labx-12/labx-12-sc-config-user-application/src/main/resources/bootstrap.yml b/labx-12/labx-12-sc-config-user-application/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..6ae779eeb --- /dev/null +++ b/labx-12/labx-12-sc-config-user-application/src/main/resources/bootstrap.yml @@ -0,0 +1,9 @@ +spring: + application: + name: user-application + + cloud: + # Spring Cloud Config Client 配置项,对应 ConfigClientProperties 类 + config: + uri: http://127.0.0.1:8888 # Spring Cloud Config Server 的地址 + name: ${spring.application.name} # 读取的配置文件的名字,默认为 ${spring.application.name} diff --git a/labx-12/pom.xml b/labx-12/pom.xml new file mode 100644 index 000000000..72c36965c --- /dev/null +++ b/labx-12/pom.xml @@ -0,0 +1,32 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-12 + pom + + + labx-12-sc-config-server-demo + labx-12-sc-config-user-application + + labx-12-sc-config-server-git + + + + labx-12-sc-config-user-application-auto-refresh-by-actuator + + labx-12-sc-config-server-git-auto-refresh-by-bus + labx-12-sc-config-user-application-auto-refresh-by-bus + + labx-12-sc-config-server-git-nacos + labx-12-sc-config-user-application-nacos + + + diff --git "a/labx-12/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\205\215\347\275\256\344\270\255\345\277\203 Spring Cloud Config \345\205\245\351\227\250\343\200\213.md" "b/labx-12/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\205\215\347\275\256\344\270\255\345\277\203 Spring Cloud Config \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..8a2a90e00 --- /dev/null +++ "b/labx-12/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\205\215\347\275\256\344\270\255\345\277\203 Spring Cloud Config \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-13/labx-13-sc-sleuth-db-elasticsearch/pom.xml b/labx-13/labx-13-sc-sleuth-db-elasticsearch/pom.xml new file mode 100644 index 000000000..686000577 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-elasticsearch/pom.xml @@ -0,0 +1,78 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-db-elasticsearch + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-data-elasticsearch + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + + io.opentracing.brave + brave-opentracing + 0.35.0 + + + + + io.opentracing.contrib + opentracing-elasticsearch6-client + 0.1.6 + + + + diff --git a/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java new file mode 100644 index 000000000..5386ea901 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/config/SleuthConfiguration.java b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/config/SleuthConfiguration.java new file mode 100644 index 000000000..d5974d811 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/config/SleuthConfiguration.java @@ -0,0 +1,35 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.config; + +import cn.iocoder.springcloud.labx13.springmvcdemo.spring.TracingTransportClientFactoryBean; +import io.opentracing.Tracer; +import org.elasticsearch.client.transport.TransportClient; +import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Properties; + +@Configuration +public class SleuthConfiguration { + + // ==================== Elasticsearch 相关 ==================== + + @Bean + public TransportClient elasticsearchClient(Tracer tracer, ElasticsearchProperties elasticsearchProperties) throws Exception { + // 创建 TracingTransportClientFactoryBean 对象 + TracingTransportClientFactoryBean factory = new TracingTransportClientFactoryBean(tracer); + // 设置其属性 + factory.setClusterNodes(elasticsearchProperties.getClusterNodes()); + factory.setProperties(this.createElasticsearch(elasticsearchProperties)); + // 创建 TransportClient 对象,并返回 + factory.afterPropertiesSet(); + return factory.getObject(); + } + + private Properties createElasticsearch(ElasticsearchProperties elasticsearchProperties) { + Properties properties = new Properties(); + properties.put("cluster.name", elasticsearchProperties.getClusterName()); + properties.putAll(elasticsearchProperties.getProperties()); + return properties; + } +} diff --git a/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java new file mode 100644 index 000000000..879dba8ff --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java @@ -0,0 +1,28 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.controller; + +import cn.iocoder.springcloud.labx13.springmvcdemo.dataobject.ESUserDO; +import cn.iocoder.springcloud.labx13.springmvcdemo.repository.ESUserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Autowired + private ESUserRepository userRepository; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + this.findById(id); + return "success"; + } + + public ESUserDO findById(Integer id) { + return userRepository.findById(id).orElse(null); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/dataobject/ESUserDO.java b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/dataobject/ESUserDO.java new file mode 100644 index 000000000..df9ab748d --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/dataobject/ESUserDO.java @@ -0,0 +1,41 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.dataobject; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; + +import java.util.Date; + +@Document(indexName = "user", // 索引名 + type = "user", // 类型。未来的版本即将废弃 + shards = 1, // 默认索引分区数 + replicas = 0, // 每个分区的备份数 + refreshInterval = "-1" // 刷新间隔 +) +public class ESUserDO { + + @Id + private Integer id; + /** + * 账号 + */ + private String username; + /** + * 密码 + */ + private String password; + /** + * 创建时间 + */ + private Date createTime; + + @Override + public String toString() { + return "UserDO{" + + "id=" + id + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", createTime=" + createTime + + '}'; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/repository/ESUserRepository.java b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/repository/ESUserRepository.java new file mode 100644 index 000000000..005a24b89 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/repository/ESUserRepository.java @@ -0,0 +1,8 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.repository; + +import cn.iocoder.springcloud.labx13.springmvcdemo.dataobject.ESUserDO; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; + +public interface ESUserRepository extends ElasticsearchRepository { + +} diff --git a/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/spring/ClusterNodes.java b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/spring/ClusterNodes.java new file mode 100644 index 000000000..ecc9d8314 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/spring/ClusterNodes.java @@ -0,0 +1,81 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.spring; + +import org.elasticsearch.common.transport.TransportAddress; +import org.springframework.data.util.Streamable; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +class ClusterNodes implements Streamable { + + public static ClusterNodes DEFAULT = ClusterNodes.of("127.0.0.1:9300"); + + private static final String COLON = ":"; + private static final String COMMA = ","; + + private final List clusterNodes; + + /** + * Creates a new {@link ClusterNodes} by parsing the given source. + * + * @param source must not be {@literal null} or empty. + */ + private ClusterNodes(String source) { + + Assert.hasText(source, "Cluster nodes source must not be null or empty!"); + + String[] nodes = StringUtils.delimitedListToStringArray(source, COMMA); + + this.clusterNodes = Arrays.stream(nodes).map(node -> { + + String[] segments = StringUtils.delimitedListToStringArray(node, COLON); + + Assert.isTrue(segments.length == 2, + () -> String.format("Invalid cluster node %s in %s! Must be in the format host:port!", node, source)); + + String host = segments[0].trim(); + String port = segments[1].trim(); + + Assert.hasText(host, () -> String.format("No host name given cluster node %s!", node)); + Assert.hasText(port, () -> String.format("No port given in cluster node %s!", node)); + + return new TransportAddress(toInetAddress(host), Integer.valueOf(port)); + + }).collect(Collectors.toList()); + } + + /** + * Creates a new {@link ClusterNodes} by parsing the given source. The expected format is a comma separated list of + * host-port-combinations separated by a colon: {@code host:port,host:port,…}. + * + * @param source must not be {@literal null} or empty. + * @return + */ + public static ClusterNodes of(String source) { + return new ClusterNodes(source); + } + + /* + * (non-Javadoc) + * @see java.lang.Iterable#iterator() + */ + @Override + public Iterator iterator() { + return clusterNodes.iterator(); + } + + private static InetAddress toInetAddress(String host) { + + try { + return InetAddress.getByName(host); + } catch (UnknownHostException o_O) { + throw new IllegalArgumentException(o_O); + } + } +} diff --git a/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/spring/TracingTransportClientFactoryBean.java b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/spring/TracingTransportClientFactoryBean.java new file mode 100644 index 000000000..27646b52e --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/spring/TracingTransportClientFactoryBean.java @@ -0,0 +1,138 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.spring; + +import io.opentracing.Tracer; +import io.opentracing.contrib.elasticsearch6.TracingPreBuiltTransportClient; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.settings.Settings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.data.elasticsearch.client.TransportClientFactoryBean; + +import java.util.Properties; + +/** + * 参考 {@link TransportClientFactoryBean} 来实现。 + */ +public class TracingTransportClientFactoryBean implements FactoryBean, InitializingBean, DisposableBean { + + private static final Logger logger = LoggerFactory.getLogger(TransportClientFactoryBean.class); + private ClusterNodes clusterNodes = ClusterNodes.of("127.0.0.1:9300"); + private String clusterName = "elasticsearch"; + private Boolean clientTransportSniff = true; + private Boolean clientIgnoreClusterName = Boolean.FALSE; + private String clientPingTimeout = "5s"; + private String clientNodesSamplerInterval = "5s"; + private TransportClient client; + private Properties properties; + + private Tracer tracer; + + public TracingTransportClientFactoryBean(Tracer tracer) { + this.tracer = tracer; + } + + @Override + public void destroy() throws Exception { + try { + logger.info("Closing elasticSearch client"); + if (client != null) { + client.close(); + } + } catch (final Exception e) { + logger.error("Error closing ElasticSearch client: ", e); + } + } + + @Override + public TransportClient getObject() throws Exception { + return client; + } + + @Override + public Class getObjectType() { + return TransportClient.class; + } + + @Override + public boolean isSingleton() { + return true; + } + + @Override + public void afterPropertiesSet() throws Exception { + buildClient(); + } + + protected void buildClient() throws Exception { + // 创建可追踪的 TracingPreBuiltTransportClient + client = new TracingPreBuiltTransportClient(tracer, settings()); + + clusterNodes.stream() // + .peek(it -> logger.info("Adding transport node : " + it.toString())) // + .forEach(client::addTransportAddress); + + client.connectedNodes(); + } + + private Settings settings() { + if (properties != null) { + Settings.Builder builder = Settings.builder(); + + properties.forEach((key, value) -> { + builder.put(key.toString(), value.toString()); + }); + + return builder.build(); + } + return Settings.builder() + .put("cluster.name", clusterName) + .put("client.transport.sniff", clientTransportSniff) + .put("client.transport.ignore_cluster_name", clientIgnoreClusterName) + .put("client.transport.ping_timeout", clientPingTimeout) + .put("client.transport.nodes_sampler_interval", clientNodesSamplerInterval) + .build(); + } + + public void setClusterNodes(String clusterNodes) { + this.clusterNodes = ClusterNodes.of(clusterNodes); + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public void setClientTransportSniff(Boolean clientTransportSniff) { + this.clientTransportSniff = clientTransportSniff; + } + + public String getClientNodesSamplerInterval() { + return clientNodesSamplerInterval; + } + + public void setClientNodesSamplerInterval(String clientNodesSamplerInterval) { + this.clientNodesSamplerInterval = clientNodesSamplerInterval; + } + + public String getClientPingTimeout() { + return clientPingTimeout; + } + + public void setClientPingTimeout(String clientPingTimeout) { + this.clientPingTimeout = clientPingTimeout; + } + + public Boolean getClientIgnoreClusterName() { + return clientIgnoreClusterName; + } + + public void setClientIgnoreClusterName(Boolean clientIgnoreClusterName) { + this.clientIgnoreClusterName = clientIgnoreClusterName; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } +} diff --git a/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/resources/application.yml new file mode 100644 index 000000000..3c812e670 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-elasticsearch/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring: + application: + name: user-service # 服务名 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + # Spring Cloud Sleuth 针对 Web 组件的配置项,例如说 SpringMVC + web: + enabled: true # 是否开启,默认为 true + + data: + # Elasticsearch 配置项 + elasticsearch: + cluster-name: elasticsearch # 集群名 + cluster-nodes: 127.0.0.1:9300 # 集群节点 diff --git a/labx-13/labx-13-sc-sleuth-db-mongodb/pom.xml b/labx-13/labx-13-sc-sleuth-db-mongodb/pom.xml new file mode 100644 index 000000000..890d82b01 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-mongodb/pom.xml @@ -0,0 +1,78 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-db-mongodb + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + + io.opentracing.brave + brave-opentracing + 0.35.0 + + + + + io.opentracing.contrib + opentracing-mongo-driver + 0.1.5 + + + + diff --git a/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java b/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java new file mode 100644 index 000000000..5386ea901 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/config/SleuthConfiguration.java b/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/config/SleuthConfiguration.java new file mode 100644 index 000000000..4ae5842ff --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/config/SleuthConfiguration.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.config; + +import com.mongodb.MongoClientOptions; +import io.opentracing.Tracer; +import io.opentracing.contrib.mongo.common.TracingCommandListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SleuthConfiguration { + + // ==================== MongoDB 相关 ==================== + + @Bean + public MongoClientOptions mongoClientOptions(Tracer tracer) { + // 创建 TracingCommandListener 对象 + TracingCommandListener listener = new TracingCommandListener.Builder(tracer).build(); + // 创建 MongoClientOptions 对象,并设置监听器 + return MongoClientOptions.builder().addCommandListener(listener).build(); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java b/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java new file mode 100644 index 000000000..dd617728e --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java @@ -0,0 +1,30 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.controller; + +import cn.iocoder.springcloud.labx13.springmvcdemo.dataobject.UserDO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Autowired + private MongoTemplate mongoTemplate; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + this.findById(1); + return "success"; + } + + public UserDO findById(Integer id) { + return mongoTemplate.findOne(new Query(Criteria.where("_id").is(id)), UserDO.class); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/dataobject/UserDO.java b/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/dataobject/UserDO.java new file mode 100644 index 000000000..6b045620b --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/dataobject/UserDO.java @@ -0,0 +1,39 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.dataobject; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.Date; + +/** + * 用户 DO + */ +@Document(collection = "User") +public class UserDO { + + @Id + private Integer id; + /** + * 账号 + */ + private String username; + /** + * 密码 + */ + private String password; + /** + * 创建时间 + */ + private Date createTime; + + @Override + public String toString() { + return "UserDO{" + + "id=" + id + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", createTime=" + createTime + + '}'; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/resources/application.yml new file mode 100644 index 000000000..fa4d608b0 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-mongodb/src/main/resources/application.yml @@ -0,0 +1,23 @@ +spring: + application: + name: user-service # 服务名 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + # Spring Cloud Sleuth 针对 Web 组件的配置项,例如说 SpringMVC + web: + enabled: true # 是否开启,默认为 true + + data: + # MongoDB 配置项,对应 MongoProperties 类 + mongodb: + host: 127.0.0.1 + port: 27017 + database: yourdatabase + username: test01 + password: password01 + # 上述属性,也可以只配置 uri diff --git a/labx-13/labx-13-sc-sleuth-db-mysql/pom.xml b/labx-13/labx-13-sc-sleuth-db-mysql/pom.xml new file mode 100644 index 000000000..063a23859 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-mysql/pom.xml @@ -0,0 +1,75 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-db-mysql + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.46 + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + + io.zipkin.brave + brave-instrumentation-mysql + + + + diff --git a/labx-13/labx-13-sc-sleuth-db-mysql/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java b/labx-13/labx-13-sc-sleuth-db-mysql/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java new file mode 100644 index 000000000..5386ea901 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-mysql/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-mysql/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java b/labx-13/labx-13-sc-sleuth-db-mysql/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java new file mode 100644 index 000000000..c06ff06ed --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-mysql/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java @@ -0,0 +1,30 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Autowired + private JdbcTemplate template; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + this.selectById(1); + return "success"; + } + + public Object selectById(Integer id) { + return template.queryForObject("SELECT id, username, password FROM t_user WHERE id = ?", + new BeanPropertyRowMapper<>(Object.class), // 结果转换成对应的对象。Object 理论来说是 UserDO.class ,这里偷懒了。 + id); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-mysql/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-db-mysql/src/main/resources/application.yml new file mode 100644 index 000000000..10c58b1e4 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-mysql/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + application: + name: user-service # 服务名 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + # Spring Cloud Sleuth 针对 Web 组件的配置项,例如说 SpringMVC + web: + enabled: true # 是否开启,默认为 true + + # datasource 数据源配置内容 + datasource: + url: jdbc:mysql://127.0.0.1:3306/lab-39-mysql?useSSL=false&useUnicode=true&characterEncoding=UTF-8&statementInterceptors=brave.mysql.TracingStatementInterceptor&zipkinServiceName=demo-db-mysql + driver-class-name: com.mysql.jdbc.Driver + username: root + password: diff --git a/labx-13/labx-13-sc-sleuth-db-redis/pom.xml b/labx-13/labx-13-sc-sleuth-db-redis/pom.xml new file mode 100644 index 000000000..14bc385c5 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-redis/pom.xml @@ -0,0 +1,95 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-db-redis + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + io.lettuce + lettuce-core + + + + + + redis.clients + jedis + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + + io.opentracing.brave + brave-opentracing + 0.35.0 + + + + + io.opentracing.contrib + opentracing-redis-jedis3 + 0.1.14 + + + io.opentracing.contrib + opentracing-redis-spring-data + 0.1.14 + + + + diff --git a/labx-13/labx-13-sc-sleuth-db-redis/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java b/labx-13/labx-13-sc-sleuth-db-redis/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java new file mode 100644 index 000000000..5386ea901 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-redis/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-redis/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/config/SleuthConfiguration.java b/labx-13/labx-13-sc-sleuth-db-redis/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/config/SleuthConfiguration.java new file mode 100644 index 000000000..f034519d3 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-redis/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/config/SleuthConfiguration.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.config; + +import io.opentracing.Tracer; +import io.opentracing.contrib.redis.common.TracingConfiguration; +import io.opentracing.contrib.redis.spring.data.connection.TracingRedisConnectionFactory; +import org.springframework.boot.autoconfigure.data.redis.RedisProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; + +@Configuration +public class SleuthConfiguration { + + // ==================== Redis 相关 ==================== + @Bean + public RedisConnectionFactory redisConnectionFactory(Tracer tracer, RedisProperties redisProperties) { + // 创建 JedisConnectionFactory 对象 + RedisConnectionFactory connectionFactory = new JedisConnectionFactory(); + // 创建 TracingConfiguration 对象 + TracingConfiguration tracingConfiguration = new TracingConfiguration.Builder(tracer) + // 设置拓展 Tag ,设置 Redis 服务器地址。因为默认情况下,不会在操作 Redis 链路的 Span 上记录 Redis 服务器的地址,所以这里需要设置。 + .extensionTag("Server Address", redisProperties.getHost() + ":" + redisProperties.getPort()) + .build(); + // 创建 TracingRedisConnectionFactory 对象 + return new TracingRedisConnectionFactory(connectionFactory, tracingConfiguration); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-redis/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java b/labx-13/labx-13-sc-sleuth-db-redis/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java new file mode 100644 index 000000000..eb4f0c47e --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-redis/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Autowired + private StringRedisTemplate redisTemplate; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + this.get("demo"); + return "success"; + } + + public void get(String key) { + redisTemplate.opsForValue().get(key); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-db-redis/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-db-redis/src/main/resources/application.yml new file mode 100644 index 000000000..e83fa3570 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-db-redis/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + application: + name: user-service # 服务名 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + # Spring Cloud Sleuth 针对 Web 组件的配置项,例如说 SpringMVC + web: + enabled: true # 是否开启,默认为 true + + # 对应 RedisProperties 类 + redis: + host: 127.0.0.1 + port: 6379 + password: # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码! + database: 0 # Redis 数据库号,默认为 0 。 + timeout: 0 # Redis 连接超时时间,单位:毫秒。 + # 对应 RedisProperties.Jedis 内部类 + jedis: + pool: + max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。 + max-idle: 8 # 默认连接数最小空闲的连接数,默认为 8 。使用负数表示没有限制。 + min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。 + max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制。 diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-api/pom.xml b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-api/pom.xml new file mode 100644 index 000000000..c213d00be --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-api/pom.xml @@ -0,0 +1,15 @@ + + + + labx-13-sc-sleuth-dubbo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-dubbo-api + + + diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-api/src/main/java/cn/iocoder/springcloud/labx13/api/UserService.java b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-api/src/main/java/cn/iocoder/springcloud/labx13/api/UserService.java new file mode 100644 index 000000000..5dab7509b --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-api/src/main/java/cn/iocoder/springcloud/labx13/api/UserService.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx13.api; + +/** + * 用户服务 RPC Service 接口 + */ +public interface UserService { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + String get(Integer id); + +} diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-api/src/main/java/cn/iocoder/springcloud/labx13/package-info.java b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-api/src/main/java/cn/iocoder/springcloud/labx13/package-info.java new file mode 100644 index 000000000..7f0cd7c61 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-api/src/main/java/cn/iocoder/springcloud/labx13/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.springcloud.labx13; diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/pom.xml b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/pom.xml new file mode 100644 index 000000000..377c9f6c0 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/pom.xml @@ -0,0 +1,92 @@ + + + + labx-13-sc-sleuth-dubbo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-dubbo-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-13-sc-sleuth-dubbo-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + + io.zipkin.brave + brave-instrumentation-dubbo + 5.10.1 + + + + diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx13/consumerdemo/ConsumerApplication.java b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx13/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..6d37fcc7b --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx13/consumerdemo/ConsumerApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.consumerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx13/consumerdemo/controller/UserController.java b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx13/consumerdemo/controller/UserController.java new file mode 100644 index 000000000..07e6083a1 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx13/consumerdemo/controller/UserController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx13.consumerdemo.controller; + +import cn.iocoder.springcloud.labx13.api.UserService; +import org.apache.dubbo.config.annotation.Reference; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Reference(protocol = "dubbo", version = "1.0.0") + private UserService userService; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + return userService.get(id); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/src/main/resources/application.yaml b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..45680e3ed --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-consumer/src/main/resources/application.yaml @@ -0,0 +1,24 @@ +spring: + application: + name: demo-consumer + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Dubbo 服务提供者的配置,对应 ConsumerConfig 类 + consumer: + filter: tracing + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: demo-provider # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/pom.xml b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/pom.xml new file mode 100644 index 000000000..6feae89e9 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/pom.xml @@ -0,0 +1,86 @@ + + + + labx-13-sc-sleuth-dubbo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-dubbo-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-13-sc-sleuth-dubbo-api + 1.0-SNAPSHOT + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + + io.zipkin.brave + brave-instrumentation-dubbo + 5.10.1 + + + + diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx13/providerdemo/ProviderApplication.java b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx13/providerdemo/ProviderApplication.java new file mode 100644 index 000000000..76e450726 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx13/providerdemo/ProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.providerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(ProviderApplication.class); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx13/providerdemo/service/UserServiceImpl.java b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx13/providerdemo/service/UserServiceImpl.java new file mode 100644 index 000000000..64e0b8dca --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx13/providerdemo/service/UserServiceImpl.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.providerdemo.service; + +import cn.iocoder.springcloud.labx13.api.UserService; + +@org.apache.dubbo.config.annotation.Service(protocol = "dubbo", version = "1.0.0") +public class UserServiceImpl implements UserService { + + @Override + public String get(Integer id) { + return "user:" + id; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/src/main/resources/application.yaml b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..30e71a72d --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/labx-13-sc-sleuth-dubbo-provider/src/main/resources/application.yaml @@ -0,0 +1,31 @@ +spring: + application: + name: demo-provider + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + scan: + base-packages: cn.iocoder.springcloud.labx13.providerdemo.service # 指定 Dubbo 服务实现类的扫描基准包 + # Dubbo 服务暴露的协议配置,对应 ProtocolConfig Map + protocols: + dubbo: + name: dubbo # 协议名称 + port: -1 # 协议端口,-1 表示自增端口,从 20880 开始 + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Dubbo 服务提供者的配置,对应 ProviderConfig 类 + provider: + filter: tracing + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-13/labx-13-sc-sleuth-dubbo/pom.xml b/labx-13/labx-13-sc-sleuth-dubbo/pom.xml new file mode 100644 index 000000000..2b4415953 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-dubbo/pom.xml @@ -0,0 +1,21 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-dubbo + pom + + labx-13-sc-sleuth-dubbo-api + labx-13-sc-sleuth-dubbo-provider + labx-13-sc-sleuth-dubbo-consumer + + + + diff --git a/labx-13/labx-13-sc-sleuth-feign/pom.xml b/labx-13/labx-13-sc-sleuth-feign/pom.xml new file mode 100644 index 000000000..3598d582a --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-feign/pom.xml @@ -0,0 +1,64 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-feign + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-13/labx-13-sc-sleuth-feign/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/FeignApplication.java b/labx-13/labx-13-sc-sleuth-feign/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/FeignApplication.java new file mode 100644 index 000000000..cc59b8511 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-feign/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/FeignApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class FeignApplication { + + public static void main(String[] args) { + SpringApplication.run(FeignApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-feign/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/FeignController.java b/labx-13/labx-13-sc-sleuth-feign/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/FeignController.java new file mode 100644 index 000000000..920a9593a --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-feign/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/FeignController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.controller; + +import cn.iocoder.springcloud.labx13.springmvcdemo.feign.UserServiceFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/feign") +public class FeignController { + + @Autowired + private UserServiceFeignClient userServiceFeignClient; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + return userServiceFeignClient.get(id); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-feign/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/feign/UserServiceFeignClient.java b/labx-13/labx-13-sc-sleuth-feign/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/feign/UserServiceFeignClient.java new file mode 100644 index 000000000..534e06a3f --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-feign/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/feign/UserServiceFeignClient.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.feign; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "user-service", url = "http://127.0.0.1:8080") +public interface UserServiceFeignClient { + + @GetMapping("/user/get") + String get(@RequestParam("id") Integer id); + +} diff --git a/labx-13/labx-13-sc-sleuth-feign/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-feign/src/main/resources/application.yml new file mode 100644 index 000000000..ac93ab08a --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-feign/src/main/resources/application.yml @@ -0,0 +1,19 @@ +server: + port: 8081 + +spring: + application: + name: feign-service # 服务名 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + # Spring Cloud Sleuth 针对 Web 组件的配置项,例如说 SpringMVC + web: + enabled: true # 是否开启,默认为 true + # Spring Cloud Sleuth 针对 Feign 组件的配置项,对应 SleuthFeignProperties 类 + feign: + enabled: true # 是否开启,默认为 true diff --git a/labx-13/labx-13-sc-sleuth-logback/pom.xml b/labx-13/labx-13-sc-sleuth-logback/pom.xml new file mode 100644 index 000000000..b8a2b80a5 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-logback/pom.xml @@ -0,0 +1,58 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-logback + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + diff --git a/labx-13/labx-13-sc-sleuth-logback/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java b/labx-13/labx-13-sc-sleuth-logback/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java new file mode 100644 index 000000000..5386ea901 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-logback/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-logback/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java b/labx-13/labx-13-sc-sleuth-logback/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java new file mode 100644 index 000000000..bc8cd0539 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-logback/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + logger.info("测试日志"); + return "user:" + id; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-logback/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-logback/src/main/resources/application.yml new file mode 100644 index 000000000..d3ee3efd4 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-logback/src/main/resources/application.yml @@ -0,0 +1,17 @@ +spring: + application: + name: user-service # 服务名 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + # Spring Cloud Sleuth 针对 Web 组件的配置项,例如说 SpringMVC + web: + enabled: true # 是否开启,默认为 true + # Spring Cloud Sleuth 针对 Slf4j 组件的配置项 + log: + slf4j: + enabled: true # 是否开启,默认为 true diff --git a/labx-13/labx-13-sc-sleuth-mq-activemq/pom.xml b/labx-13/labx-13-sc-sleuth-mq-activemq/pom.xml new file mode 100644 index 000000000..830275556 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-activemq/pom.xml @@ -0,0 +1,64 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-mq-activemq + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + + org.springframework.boot + spring-boot-starter-activemq + + + + diff --git a/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/ActiveMQApplication.java b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/ActiveMQApplication.java new file mode 100644 index 000000000..1e5a2725a --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/ActiveMQApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.labx13.activemqdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ActiveMQApplication { + + public static void main(String[] args) { + SpringApplication.run(ActiveMQApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/consumer/DemoConsumer.java b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/consumer/DemoConsumer.java new file mode 100644 index 000000000..ed4bfb9bf --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/consumer/DemoConsumer.java @@ -0,0 +1,19 @@ +package cn.iocoder.springboot.labx13.activemqdemo.consumer; + +import cn.iocoder.springboot.labx13.activemqdemo.message.DemoMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jms.annotation.JmsListener; +import org.springframework.stereotype.Component; + +@Component +public class DemoConsumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @JmsListener(destination = DemoMessage.QUEUE) + public void onMessage(DemoMessage message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/controller/DemoController.java b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/controller/DemoController.java new file mode 100644 index 000000000..d20de264a --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/controller/DemoController.java @@ -0,0 +1,26 @@ +package cn.iocoder.springboot.labx13.activemqdemo.controller; + +import cn.iocoder.springboot.labx13.activemqdemo.producer.DemoProducer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + @Autowired + private DemoProducer producer; + + @GetMapping("/activemq") + public String echo() { + this.sendMessage(1); + return "activemq"; + } + + public void sendMessage(Integer id) { + producer.syncSend(id); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/message/DemoMessage.java b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/message/DemoMessage.java new file mode 100644 index 000000000..8754fdb1e --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/message/DemoMessage.java @@ -0,0 +1,30 @@ +package cn.iocoder.springboot.labx13.activemqdemo.message; + +import java.io.Serializable; + +public class DemoMessage implements Serializable { + + public static final String QUEUE = "QUEUE_DEMO_"; + + /** + * 编号 + */ + private Integer id; + + public DemoMessage setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "DemoMessage{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/producer/DemoProducer.java b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/producer/DemoProducer.java new file mode 100644 index 000000000..ab2f3d326 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/java/cn/iocoder/springboot/labx13/activemqdemo/producer/DemoProducer.java @@ -0,0 +1,22 @@ +package cn.iocoder.springboot.labx13.activemqdemo.producer; + +import cn.iocoder.springboot.labx13.activemqdemo.message.DemoMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jms.core.JmsMessagingTemplate; +import org.springframework.stereotype.Component; + +@Component +public class DemoProducer { + + @Autowired + private JmsMessagingTemplate jmsTemplate; + + public void syncSend(Integer id) { + // 创建 DemoMessage 消息 + DemoMessage message = new DemoMessage(); + message.setId(id); + // 同步发送消息 + jmsTemplate.convertAndSend(DemoMessage.QUEUE, message); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/resources/application.yaml b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/resources/application.yaml new file mode 100644 index 000000000..7776f8539 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-activemq/src/main/resources/application.yaml @@ -0,0 +1,23 @@ +spring: + application: + name: demo-application-activemq + + # ActiveMQ 配置项,对应 ActiveMQProperties 配置类 + activemq: + broker-url: tcp://127.0.0.1:61616 # Activemq Broker 的地址 + user: admin # 账号 + password: admin # 密码 + packages: + trust-all: true # 可信任的反序列化包 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + messaging: + # Spring Cloud Sleuth 针对 JMS 组件的配置项 + jms: + enabled: true # 是否开启 + remote-service-name: jms # 远程服务名,默认为 jms diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/pom.xml b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/pom.xml new file mode 100644 index 000000000..81b9c7a6a --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/pom.xml @@ -0,0 +1,64 @@ + + + + labx-13-sc-sleuth-mq-kafka + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-mq-kafka-producer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/ProducerApplication.java b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..207c8e811 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx13.kafkademo.producerdemo; + +import cn.iocoder.springcloud.labx13.kafkademo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/controller/Demo01Controller.java b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..4f4bbe22a --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx13.kafkademo.producerdemo.controller; + +import cn.iocoder.springcloud.labx13.kafkademo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx13.kafkademo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/message/Demo01Message.java b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..a8a9e4a5b --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx13.kafkademo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/message/MySource.java b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/message/MySource.java new file mode 100644 index 000000000..20784a191 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx13.kafkademo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/resources/application.yml new file mode 100644 index 000000000..c87177258 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-sleuth-mq-kafka-producer/src/main/resources/application.yml @@ -0,0 +1,39 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + # binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + # Kafka 自定义 Binding 配置项,对应 KafkaBindingProperties Map + bindings: + demo01-output: + # Kafka Producer 配置项,对应 KafkaProducerProperties 类 + producer: + sync: true # 是否同步发送消息,默认为 false 异步。 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + messaging: + # Spring Cloud Sleuth 针对 Kafka 组件的配置项 + kafka: + enabled: true # 是否开启 + remote-service-name: kafka # 远程服务名,默认为 kafka + +server: + port: 18080 diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/pom.xml b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/pom.xml new file mode 100644 index 000000000..efbb2ed9a --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/pom.xml @@ -0,0 +1,64 @@ + + + + labx-13-sc-sleuth-mq-kafka + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-stream-mq-kafka-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/ConsumerApplication.java b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..908e50e06 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx13.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx13.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..5b2424d8d --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx13.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx13.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/listener/MySink.java b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..5390926fb --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/message/Demo01Message.java b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..83db696ab --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx13/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx13.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/resources/application.yml new file mode 100644 index 000000000..0459a71f8 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/labx-13-sc-stream-mq-kafka-consumer/src/main/resources/application.yml @@ -0,0 +1,34 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + # binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + messaging: + # Spring Cloud Sleuth 针对 kafka 组件的配置项kafka + kafka: + enabled: true # 是否开启 + remote-service-name: kafka # 远程服务名,默认为 kafka + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-13/labx-13-sc-sleuth-mq-kafka/pom.xml b/labx-13/labx-13-sc-sleuth-mq-kafka/pom.xml new file mode 100644 index 000000000..75d3edf5c --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-kafka/pom.xml @@ -0,0 +1,20 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-mq-kafka + pom + + + labx-13-sc-sleuth-mq-kafka-producer + labx-13-sc-stream-mq-kafka-consumer + + + diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/pom.xml b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/pom.xml new file mode 100644 index 000000000..7470ed74b --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/pom.xml @@ -0,0 +1,64 @@ + + + + labx-13-sc-sleuth-mq-rabbitmq + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-mq-rabbitmq-producer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/ProducerApplication.java b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..86f2cc5f0 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx13.rabbitmqdemo.producerdemo; + +import cn.iocoder.springcloud.labx13.rabbitmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/controller/Demo01Controller.java b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..5e3b3f488 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx13.rabbitmqdemo.producerdemo.controller; + +import cn.iocoder.springcloud.labx13.rabbitmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx13.rabbitmqdemo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/message/Demo01Message.java b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..c71da8e6f --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx13.rabbitmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/message/MySource.java b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..4b22b145b --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx13.rabbitmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/resources/application.yml new file mode 100644 index 000000000..9f5ea6fab --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-sleuth-mq-rabbitmq-producer/src/main/resources/application.yml @@ -0,0 +1,39 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + binder: rabbit001 # 设置使用的 Binder 名字 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + messaging: + # Spring Cloud Sleuth 针对 RabbitMQ 组件的配置项 + rabbit: + enabled: true # 是否开启 + remote-service-name: rabbitmq # 远程服务名,默认为 rabbitmq + +server: + port: 18080 diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/pom.xml b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/pom.xml new file mode 100644 index 000000000..2cec821d4 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/pom.xml @@ -0,0 +1,64 @@ + + + + labx-13-sc-sleuth-mq-rabbitmq + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-stream-mq-rabbitmq-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..c68a58027 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx13.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx13.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..7bf3e42d1 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx13.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx13.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..c7f6c3c0a --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..700063ff7 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx13/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx13.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/resources/application.yml new file mode 100644 index 000000000..20bdca020 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/labx-13-sc-stream-mq-rabbitmq-consumer/src/main/resources/application.yml @@ -0,0 +1,40 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + messaging: + # Spring Cloud Sleuth 针对 RabbitMQ 组件的配置项 + rabbit: + enabled: true # 是否开启 + remote-service-name: rabbitmq # 远程服务名,默认为 rabbitmq + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-13/labx-13-sc-sleuth-mq-rabbitmq/pom.xml b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/pom.xml new file mode 100644 index 000000000..1c1c3335e --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-mq-rabbitmq/pom.xml @@ -0,0 +1,20 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-mq-rabbitmq + pom + + + labx-13-sc-sleuth-mq-rabbitmq-producer + labx-13-sc-stream-mq-rabbitmq-consumer + + + diff --git a/labx-13/labx-13-sc-sleuth-opentracing/pom.xml b/labx-13/labx-13-sc-sleuth-opentracing/pom.xml new file mode 100644 index 000000000..70bc49b21 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-opentracing/pom.xml @@ -0,0 +1,65 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-opentracing + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + + io.opentracing.brave + brave-opentracing + 0.35.0 + + + + diff --git a/labx-13/labx-13-sc-sleuth-opentracing/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java b/labx-13/labx-13-sc-sleuth-opentracing/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java new file mode 100644 index 000000000..5386ea901 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-opentracing/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-opentracing/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java b/labx-13/labx-13-sc-sleuth-opentracing/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java new file mode 100644 index 000000000..15c92b974 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-opentracing/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java @@ -0,0 +1,25 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.controller; + +import io.opentracing.Tracer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Autowired + private Tracer tracer; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + // 创建一个 Span + tracer.buildSpan("custom_operation").withTag("mp", "芋道源码").start().finish(); + + return "user:" + id; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-opentracing/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-opentracing/src/main/resources/application.yml new file mode 100644 index 000000000..b8a5b9521 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-opentracing/src/main/resources/application.yml @@ -0,0 +1,16 @@ +spring: + application: + name: user-service # 服务名 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + # Spring Cloud Sleuth 针对 Web 组件的配置项,例如说 SpringMVC + web: + enabled: true # 是否开启,默认为 true + # Spring Cloud Sleuth 针对 OpenTracing 组件的配置项 + opentracing: + enabled: true # 是否开启,默认为 true diff --git a/labx-13/labx-13-sc-sleuth-sampler/pom.xml b/labx-13/labx-13-sc-sleuth-sampler/pom.xml new file mode 100644 index 000000000..02a452da4 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-sampler/pom.xml @@ -0,0 +1,58 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-sampler + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + diff --git a/labx-13/labx-13-sc-sleuth-sampler/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java b/labx-13/labx-13-sc-sleuth-sampler/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java new file mode 100644 index 000000000..5386ea901 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-sampler/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-sampler/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java b/labx-13/labx-13-sc-sleuth-sampler/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java new file mode 100644 index 000000000..01694b868 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-sampler/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + return "user:" + id; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-sampler/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-sampler/src/main/resources/application.yml new file mode 100644 index 000000000..af16b193c --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-sampler/src/main/resources/application.yml @@ -0,0 +1,17 @@ +spring: + application: + name: user-service # 服务名 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + # Spring Cloud Sleuth 针对 Web 组件的配置项,例如说 SpringMVC + web: + enabled: true # 是否开启,默认为 true + # Spring Cloud Sleuth 针对抽样收集的配置项 + sampler: + probability: 0.1 # 采样百分比,默认为空。 +# rate: 1 # 限流采样,即每秒可收集链路的数量,默认为 10。 diff --git a/labx-13/labx-13-sc-sleuth-springcloudgateway/pom.xml b/labx-13/labx-13-sc-sleuth-springcloudgateway/pom.xml new file mode 100644 index 000000000..aa2cf2ce9 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-springcloudgateway/pom.xml @@ -0,0 +1,64 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-springcloudgateway + + + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + diff --git a/labx-13/labx-13-sc-sleuth-springcloudgateway/src/main/java/cn/iocoder/springcloud/labx13/gatewaydemo/GatewayApplication.java b/labx-13/labx-13-sc-sleuth-springcloudgateway/src/main/java/cn/iocoder/springcloud/labx13/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..58c44dd74 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-springcloudgateway/src/main/java/cn/iocoder/springcloud/labx13/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-springcloudgateway/src/main/resources/application.yaml b/labx-13/labx-13-sc-sleuth-springcloudgateway/src/main/resources/application.yaml new file mode 100644 index 000000000..070d13a84 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-springcloudgateway/src/main/resources/application.yaml @@ -0,0 +1,26 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + # Spring Cloud Sleuth 针对 Web 组件的配置项,例如说 SpringMVC + web: + enabled: true # 是否开启,默认为 true + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: feign-service-route + uri: http://127.0.0.1:8081 + predicates: + - Path=/** diff --git a/labx-13/labx-13-sc-sleuth-springmvc/pom.xml b/labx-13/labx-13-sc-sleuth-springmvc/pom.xml new file mode 100644 index 000000000..a8348b656 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-springmvc/pom.xml @@ -0,0 +1,58 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-springmvc + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-zipkin + + + + diff --git a/labx-13/labx-13-sc-sleuth-springmvc/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java b/labx-13/labx-13-sc-sleuth-springmvc/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java new file mode 100644 index 000000000..5386ea901 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-springmvc/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/UserServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-springmvc/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java b/labx-13/labx-13-sc-sleuth-springmvc/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java new file mode 100644 index 000000000..01694b868 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-springmvc/src/main/java/cn/iocoder/springcloud/labx13/springmvcdemo/controller/UserController.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloud.labx13.springmvcdemo.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + return "user:" + id; + } + +} diff --git a/labx-13/labx-13-sc-sleuth-springmvc/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-springmvc/src/main/resources/application.yml new file mode 100644 index 000000000..c7f8de5e9 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-springmvc/src/main/resources/application.yml @@ -0,0 +1,13 @@ +spring: + application: + name: user-service # 服务名 + + # Zipkin 配置项,对应 ZipkinProperties 类 + zipkin: + base-url: http://127.0.0.1:9411 # Zipkin 服务的地址 + + # Spring Cloud Sleuth 配置项 + sleuth: + # Spring Cloud Sleuth 针对 Web 组件的配置项,例如说 SpringMVC + web: + enabled: true # 是否开启,默认为 true diff --git a/labx-13/labx-13-sc-sleuth-zipkin-server-demo-in-memory/pom.xml b/labx-13/labx-13-sc-sleuth-zipkin-server-demo-in-memory/pom.xml new file mode 100644 index 000000000..52bba1914 --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-zipkin-server-demo-in-memory/pom.xml @@ -0,0 +1,80 @@ + + + + labx-13 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13-sc-sleuth-zipkin-server-demo-in-memory + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.2.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + io.zipkin.java + zipkin-server + 2.12.9 + + + + io.zipkin.java + zipkin-autoconfigure-ui + 2.12.9 + + + + org.springframework.cloud + spring-cloud-starter-sleuth + 2.2.2.RELEASE + + + + + diff --git a/labx-13/labx-13-sc-sleuth-zipkin-server-demo-in-memory/src/main/java/cn/iocoder/springcloud/labx13/sleuthzipkinserverdemo/SleuthZipkinServerApplication.java b/labx-13/labx-13-sc-sleuth-zipkin-server-demo-in-memory/src/main/java/cn/iocoder/springcloud/labx13/sleuthzipkinserverdemo/SleuthZipkinServerApplication.java new file mode 100644 index 000000000..f41f1adbf --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-zipkin-server-demo-in-memory/src/main/java/cn/iocoder/springcloud/labx13/sleuthzipkinserverdemo/SleuthZipkinServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx13.sleuthzipkinserverdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import zipkin2.server.internal.EnableZipkinServer; + +@SpringBootApplication +@EnableZipkinServer +public class SleuthZipkinServerApplication { + + public static void main(String[] args) { + SpringApplication.run(SleuthZipkinServerApplication.class, args); + } + +} diff --git a/labx-13/labx-13-sc-sleuth-zipkin-server-demo-in-memory/src/main/resources/application.yml b/labx-13/labx-13-sc-sleuth-zipkin-server-demo-in-memory/src/main/resources/application.yml new file mode 100644 index 000000000..4e27b03fa --- /dev/null +++ b/labx-13/labx-13-sc-sleuth-zipkin-server-demo-in-memory/src/main/resources/application.yml @@ -0,0 +1,4 @@ +server: + port: 9411 + + diff --git a/labx-13/pom.xml b/labx-13/pom.xml new file mode 100644 index 000000000..cc4caab2f --- /dev/null +++ b/labx-13/pom.xml @@ -0,0 +1,38 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-13 + pom + + + labx-13-sc-sleuth-zipkin-server-demo-in-memory + + labx-13-sc-sleuth-springmvc + labx-13-sc-sleuth-feign + labx-13-sc-sleuth-springcloudgateway + labx-13-sc-sleuth-dubbo + + labx-13-sc-sleuth-db-mysql + labx-13-sc-sleuth-db-redis + labx-13-sc-sleuth-db-mongodb + labx-13-sc-sleuth-db-elasticsearch + + labx-13-sc-sleuth-mq-rabbitmq + labx-13-sc-sleuth-mq-kafka + labx-13-sc-sleuth-mq-activemq + + labx-13-sc-sleuth-logback + labx-13-sc-sleuth-opentracing + labx-13-sc-sleuth-sampler + + + + diff --git "a/labx-13/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\223\276\350\267\257\350\277\275\350\270\252 Spring Cloud Sleuth\343\200\213.md" "b/labx-13/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\223\276\350\267\257\350\277\275\350\270\252 Spring Cloud Sleuth\343\200\213.md" new file mode 100644 index 000000000..101743164 --- /dev/null +++ "b/labx-13/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\223\276\350\267\257\350\277\275\350\270\252 Spring Cloud Sleuth\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-api/pom.xml b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-api/pom.xml new file mode 100644 index 000000000..99535c26d --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-api/pom.xml @@ -0,0 +1,15 @@ + + + + labx-14-sc-skywalking-dubbo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-dubbo-api + + + diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-api/src/main/java/cn/iocoder/springcloud/labx14/api/UserService.java b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-api/src/main/java/cn/iocoder/springcloud/labx14/api/UserService.java new file mode 100644 index 000000000..3cdffa3f4 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-api/src/main/java/cn/iocoder/springcloud/labx14/api/UserService.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx14.api; + +/** + * 用户服务 RPC Service 接口 + */ +public interface UserService { + + /** + * 根据指定用户编号,获得用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + String get(Integer id); + +} diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-api/src/main/java/cn/iocoder/springcloud/labx14/package-info.java b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-api/src/main/java/cn/iocoder/springcloud/labx14/package-info.java new file mode 100644 index 000000000..7f0cd7c61 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-api/src/main/java/cn/iocoder/springcloud/labx14/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.springcloud.labx13; diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/pom.xml b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/pom.xml new file mode 100644 index 000000000..7729d5863 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/pom.xml @@ -0,0 +1,79 @@ + + + + labx-14-sc-skywalking-dubbo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-dubbo-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-14-sc-skywalking-dubbo-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx14/consumerdemo/ConsumerApplication.java b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx14/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..a387f71c0 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx14/consumerdemo/ConsumerApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx14.consumerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx14/consumerdemo/controller/UserController.java b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx14/consumerdemo/controller/UserController.java new file mode 100644 index 000000000..d915275b6 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/src/main/java/cn/iocoder/springcloud/labx14/consumerdemo/controller/UserController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx14.consumerdemo.controller; + +import cn.iocoder.springcloud.labx14.api.UserService; +import org.apache.dubbo.config.annotation.Reference; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @Reference(protocol = "dubbo", version = "1.0.0") + private UserService userService; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + return userService.get(id); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/src/main/resources/application.yaml b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/src/main/resources/application.yaml new file mode 100644 index 000000000..87a152ef4 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-consumer/src/main/resources/application.yaml @@ -0,0 +1,20 @@ +server: + port: 8079 + +spring: + application: + name: demo-consumer + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: demo-provider # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/pom.xml b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/pom.xml new file mode 100644 index 000000000..b2e5cba28 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/pom.xml @@ -0,0 +1,73 @@ + + + + labx-14-sc-skywalking-dubbo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-dubbo-provider + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + cn.iocoder.springboot.labs + labx-14-sc-skywalking-dubbo-api + 1.0-SNAPSHOT + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx14/providerdemo/ProviderApplication.java b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx14/providerdemo/ProviderApplication.java new file mode 100644 index 000000000..aedfed39a --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx14/providerdemo/ProviderApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx14.providerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProviderApplication { + + public static void main(String[] args) { + SpringApplication.run(ProviderApplication.class); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx14/providerdemo/service/UserServiceImpl.java b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx14/providerdemo/service/UserServiceImpl.java new file mode 100644 index 000000000..8cf11ea78 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/src/main/java/cn/iocoder/springcloud/labx14/providerdemo/service/UserServiceImpl.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloud.labx14.providerdemo.service; + + +import cn.iocoder.springcloud.labx14.api.UserService; + +@org.apache.dubbo.config.annotation.Service(protocol = "dubbo", version = "1.0.0") +public class UserServiceImpl implements UserService { + + @Override + public String get(Integer id) { + return "user:" + id; + } + +} diff --git a/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/src/main/resources/application.yaml b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/src/main/resources/application.yaml new file mode 100644 index 000000000..a27ce283a --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/labx-14-sc-skywalking-dubbo-provider/src/main/resources/application.yaml @@ -0,0 +1,19 @@ +spring: + application: + name: demo-provider + +# Dubbo 配置项,对应 DubboConfigurationProperties 类 +dubbo: + scan: + base-packages: cn.iocoder.springcloud.labx14.providerdemo.service # 指定 Dubbo 服务实现类的扫描基准包 + # Dubbo 服务暴露的协议配置,对应 ProtocolConfig Map + protocols: + dubbo: + name: dubbo # 协议名称 + port: -1 # 协议端口,-1 表示自增端口,从 20880 开始 + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 diff --git a/labx-14/labx-14-sc-skywalking-dubbo/pom.xml b/labx-14/labx-14-sc-skywalking-dubbo/pom.xml new file mode 100644 index 000000000..a6883d1b5 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-dubbo/pom.xml @@ -0,0 +1,21 @@ + + + + labx-14 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-dubbo + pom + + + labx-14-sc-skywalking-dubbo-api + labx-14-sc-skywalking-dubbo-provider + labx-14-sc-skywalking-dubbo-consumer + + + diff --git a/labx-14/labx-14-sc-skywalking-feign/pom.xml b/labx-14/labx-14-sc-skywalking-feign/pom.xml new file mode 100644 index 000000000..074d5b032 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-feign/pom.xml @@ -0,0 +1,58 @@ + + + + labx-14 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-feign + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-14/labx-14-sc-skywalking-feign/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/FeignApplication.java b/labx-14/labx-14-sc-skywalking-feign/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/FeignApplication.java new file mode 100644 index 000000000..e98aa6adb --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-feign/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/FeignApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx14.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class FeignApplication { + + public static void main(String[] args) { + SpringApplication.run(FeignApplication.class, args); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-feign/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/controller/FeignController.java b/labx-14/labx-14-sc-skywalking-feign/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/controller/FeignController.java new file mode 100644 index 000000000..5f76019e3 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-feign/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/controller/FeignController.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx14.springmvcdemo.controller; + +import cn.iocoder.springcloud.labx14.springmvcdemo.feign.UserServiceFeignClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/feign") +public class FeignController { + + @Autowired + private UserServiceFeignClient userServiceFeignClient; + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + return userServiceFeignClient.get(id); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-feign/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/feign/UserServiceFeignClient.java b/labx-14/labx-14-sc-skywalking-feign/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/feign/UserServiceFeignClient.java new file mode 100644 index 000000000..415c98e3c --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-feign/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/feign/UserServiceFeignClient.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx14.springmvcdemo.feign; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "user-service", url = "http://127.0.0.1:8079") +public interface UserServiceFeignClient { + + @GetMapping("/user/get") + String get(@RequestParam("id") Integer id); + +} diff --git a/labx-14/labx-14-sc-skywalking-feign/src/main/resources/application.yml b/labx-14/labx-14-sc-skywalking-feign/src/main/resources/application.yml new file mode 100644 index 000000000..fc511480c --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-feign/src/main/resources/application.yml @@ -0,0 +1,6 @@ +server: + port: 8081 + +spring: + application: + name: feign-service # 服务名 diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/pom.xml b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/pom.xml new file mode 100644 index 000000000..c5d735006 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/pom.xml @@ -0,0 +1,58 @@ + + + + labx-14-sc-skywalking-mq-kafka + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-mq-kafka-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/ConsumerApplication.java b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..b74f8d0fa --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx14.kafkademo.consumerdemo; + +import cn.iocoder.springcloud.labx14.kafkademo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/listener/Demo01Consumer.java b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..637ac9653 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx14.kafkademo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx14.kafkademo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/listener/MySink.java b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..53688de21 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx14.kafkademo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/message/Demo01Message.java b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..0a3de1bc7 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx14.kafkademo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/resources/application.yml b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/resources/application.yml new file mode 100644 index 000000000..c2fdc9453 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-consumer/src/main/resources/application.yml @@ -0,0 +1,22 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + # binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group # 消费者分组 + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/pom.xml b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/pom.xml new file mode 100644 index 000000000..e67c4a22f --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/pom.xml @@ -0,0 +1,58 @@ + + + + labx-14-sc-skywalking-mq-kafka + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-mq-kafka-producer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-kafka + + + + diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/ProducerApplication.java b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..ef22def04 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx14.kafkademo.producerdemo; + +import cn.iocoder.springcloud.labx14.kafkademo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/controller/Demo01Controller.java b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..ac6595833 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx14.kafkademo.producerdemo.controller; + +import cn.iocoder.springcloud.labx14.kafkademo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx14.kafkademo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/message/Demo01Message.java b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..8ef24cfe5 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx14.kafkademo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/message/MySource.java b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/message/MySource.java new file mode 100644 index 000000000..7cbea80e2 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/java/cn/iocoder/springcloud/labx14/kafkademo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx14.kafkademo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/resources/application.yml b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/resources/application.yml new file mode 100644 index 000000000..99b26e77f --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/labx-14-sc-skywalking-mq-kafka-producer/src/main/resources/application.yml @@ -0,0 +1,27 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + # binders: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 Kafka Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream Kafka 配置项 + kafka: + # Kafka Binder 配置项,对应 KafkaBinderConfigurationProperties 类 + binder: + brokers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + # Kafka 自定义 Binding 配置项,对应 KafkaBindingProperties Map + bindings: + demo01-output: + # Kafka Producer 配置项,对应 KafkaProducerProperties 类 + producer: + sync: true # 是否同步发送消息,默认为 false 异步。 + +server: + port: 18080 diff --git a/labx-14/labx-14-sc-skywalking-mq-kafka/pom.xml b/labx-14/labx-14-sc-skywalking-mq-kafka/pom.xml new file mode 100644 index 000000000..d1af0b0fe --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-kafka/pom.xml @@ -0,0 +1,20 @@ + + + + labx-14 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-mq-kafka + pom + + + labx-14-sc-skywalking-mq-kafka-producer + labx-14-sc-skywalking-mq-kafka-consumer + + + diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/pom.xml b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/pom.xml new file mode 100644 index 000000000..1ddb72a60 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/pom.xml @@ -0,0 +1,58 @@ + + + + labx-14-sc-skywalking-mq-rabbitmq + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-mq-rabbitmq-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/ConsumerApplication.java b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..800749f3e --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx14.rabbitmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx14.rabbitmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..63d074de7 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx14.rabbitmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx14.rabbitmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/listener/MySink.java b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..4960ab055 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx14.rabbitmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/message/Demo01Message.java b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..bef9e6bf9 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx14.rabbitmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/resources/application.yml b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/resources/application.yml new file mode 100644 index 000000000..a5e027853 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-consumer/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + binder: rabbit001 # 设置使用的 Binder 名字 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/pom.xml b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/pom.xml new file mode 100644 index 000000000..da7097d9e --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/pom.xml @@ -0,0 +1,58 @@ + + + + labx-14-sc-skywalking-mq-rabbitmq + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-mq-rabbitmq-producer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/ProducerApplication.java b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..e99af72bc --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx14.rabbitmqdemo.producerdemo; + +import cn.iocoder.springcloud.labx14.rabbitmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/controller/Demo01Controller.java b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..fb1ee1b59 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx14.rabbitmqdemo.producerdemo.controller; + +import cn.iocoder.springcloud.labx14.rabbitmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx14.rabbitmqdemo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/message/Demo01Message.java b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..89f93fcea --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx14.rabbitmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/message/MySource.java b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..2c71cba2d --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rabbitmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx14.rabbitmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/resources/application.yml b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/resources/application.yml new file mode 100644 index 000000000..ae514a282 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/labx-14-sc-skywalking-mq-rabbitmq-producer/src/main/resources/application.yml @@ -0,0 +1,27 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binder 配置项,对应 BinderProperties Map + binders: + rabbit001: + type: rabbit # 设置 Binder 的类型 + environment: # 设置 Binder 的环境配置 + # 如果是 RabbitMQ 类型的时候,则对应的是 RabbitProperties 类 + spring: + rabbitmq: + host: 127.0.0.1 # RabbitMQ 服务的地址 + port: 5672 # RabbitMQ 服务的端口 + username: guest # RabbitMQ 服务的账号 + password: guest # RabbitMQ 服务的密码 + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RabbitMQ Exchange + content-type: application/json # 内容格式。这里使用 JSON + binder: rabbit001 # 设置使用的 Binder 名字 + +server: + port: 18080 diff --git a/labx-14/labx-14-sc-skywalking-mq-rabbitmq/pom.xml b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/pom.xml new file mode 100644 index 000000000..d2a41f74f --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rabbitmq/pom.xml @@ -0,0 +1,20 @@ + + + + labx-14 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-mq-rabbitmq + pom + + + labx-14-sc-skywalking-mq-rabbitmq-producer + labx-14-sc-skywalking-mq-rabbitmq-consumer + + + diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/pom.xml b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/pom.xml new file mode 100644 index 000000000..6c87765ed --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/pom.xml @@ -0,0 +1,66 @@ + + + + labx-14-sc-skywalking-mq-rocketmq + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-mq-rocketmq-consumer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/ConsumerApplication.java b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/ConsumerApplication.java new file mode 100644 index 000000000..1f44bdaa6 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/ConsumerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx14.rocketmqdemo.consumerdemo; + +import cn.iocoder.springcloud.labx14.rocketmqdemo.consumerdemo.listener.MySink; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySink.class) +public class ConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConsumerApplication.class, args); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java new file mode 100644 index 000000000..66c3d0468 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/listener/Demo01Consumer.java @@ -0,0 +1,20 @@ +package cn.iocoder.springcloud.labx14.rocketmqdemo.consumerdemo.listener; + +import cn.iocoder.springcloud.labx14.rocketmqdemo.consumerdemo.message.Demo01Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; + +@Component +public class Demo01Consumer { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @StreamListener(MySink.DEMO01_INPUT) + public void onMessage(@Payload Demo01Message message) { + logger.info("[onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/listener/MySink.java b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/listener/MySink.java new file mode 100644 index 000000000..a64eb8a5c --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/listener/MySink.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx14.rocketmqdemo.consumerdemo.listener; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.messaging.SubscribableChannel; + +public interface MySink { + + String DEMO01_INPUT = "demo01-input"; + + @Input(DEMO01_INPUT) + SubscribableChannel demo01Input(); + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/message/Demo01Message.java b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/message/Demo01Message.java new file mode 100644 index 000000000..9e7ad1ee6 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/consumerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx14.rocketmqdemo.consumerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/resources/application.yml b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/resources/application.yml new file mode 100644 index 000000000..1aae47ecd --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-consumer/src/main/resources/application.yml @@ -0,0 +1,27 @@ +spring: + application: + name: demo-consumer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-input: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + group: demo01-consumer-group-DEMO-TOPIC-01 # 消费者分组 + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-input: + # RocketMQ Consumer 配置项,对应 RocketMQConsumerProperties 类 + consumer: + enabled: true # 是否开启消费,默认为 true + broadcasting: false # 是否使用广播消费,默认为 false 使用集群消费 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/pom.xml b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/pom.xml new file mode 100644 index 000000000..517b5160f --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/pom.xml @@ -0,0 +1,66 @@ + + + + labx-14-sc-skywalking-mq-rocketmq + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-mq-rocketmq-producer + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-stream-rocketmq + + + + diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/ProducerApplication.java b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/ProducerApplication.java new file mode 100644 index 000000000..16f737357 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/ProducerApplication.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.labx14.rocketmqdemo.producerdemo; + +import cn.iocoder.springcloud.labx14.rocketmqdemo.producerdemo.message.MySource; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; + +@SpringBootApplication +@EnableBinding(MySource.class) +public class ProducerApplication { + + public static void main(String[] args) { + SpringApplication.run(ProducerApplication.class, args); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/controller/Demo01Controller.java b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/controller/Demo01Controller.java new file mode 100644 index 000000000..b241bd591 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/controller/Demo01Controller.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx14.rocketmqdemo.producerdemo.controller; + +import cn.iocoder.springcloud.labx14.rocketmqdemo.producerdemo.message.Demo01Message; +import cn.iocoder.springcloud.labx14.rocketmqdemo.producerdemo.message.MySource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Random; + +@RestController +@RequestMapping("/demo01") +public class Demo01Controller { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private MySource mySource; + + @GetMapping("/send") + public boolean send() { + // 创建 Message + Demo01Message message = new Demo01Message() + .setId(new Random().nextInt()); + // 创建 Spring Message 对象 + Message springMessage = MessageBuilder.withPayload(message) + .build(); + // 发送消息 + return mySource.demo01Output().send(springMessage); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/message/Demo01Message.java b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/message/Demo01Message.java new file mode 100644 index 000000000..e4032a5b4 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/message/Demo01Message.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx14.rocketmqdemo.producerdemo.message; + +/** + * 示例 01 的 Message 消息 + */ +public class Demo01Message { + + /** + * 编号 + */ + private Integer id; + + public Demo01Message setId(Integer id) { + this.id = id; + return this; + } + + public Integer getId() { + return id; + } + + @Override + public String toString() { + return "Demo01Message{" + + "id=" + id + + '}'; + } + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/message/MySource.java b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/message/MySource.java new file mode 100644 index 000000000..086912acb --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/java/cn/iocoder/springcloud/labx14/rocketmqdemo/producerdemo/message/MySource.java @@ -0,0 +1,11 @@ +package cn.iocoder.springcloud.labx14.rocketmqdemo.producerdemo.message; + +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; + +public interface MySource { + + @Output("demo01-output") + MessageChannel demo01Output(); + +} diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/resources/application.yml b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/resources/application.yml new file mode 100644 index 000000000..157206e14 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/labx-14-sc-skywalking-mq-rocketmq-producer/src/main/resources/application.yml @@ -0,0 +1,26 @@ +spring: + application: + name: demo-producer-application + cloud: + # Spring Cloud Stream 配置项,对应 BindingServiceProperties 类 + stream: + # Binding 配置项,对应 BindingProperties Map + bindings: + demo01-output: + destination: DEMO-TOPIC-01 # 目的地。这里使用 RocketMQ Topic + content-type: application/json # 内容格式。这里使用 JSON + # Spring Cloud Stream RocketMQ 配置项 + rocketmq: + # RocketMQ Binder 配置项,对应 RocketMQBinderConfigurationProperties 类 + binder: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv 地址 + # RocketMQ 自定义 Binding 配置项,对应 RocketMQBindingProperties Map + bindings: + demo01-output: + # RocketMQ Producer 配置项,对应 RocketMQProducerProperties 类 + producer: + group: test # 生产者分组 + sync: true # 是否同步发送消息,默认为 false 异步。 + +server: + port: 18080 diff --git a/labx-14/labx-14-sc-skywalking-mq-rocketmq/pom.xml b/labx-14/labx-14-sc-skywalking-mq-rocketmq/pom.xml new file mode 100644 index 000000000..3ffea267f --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-mq-rocketmq/pom.xml @@ -0,0 +1,20 @@ + + + + labx-14 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-mq-rocketmq + pom + + + labx-14-sc-skywalking-mq-rocketmq-producer + labx-14-sc-skywalking-mq-rocketmq-consumer + + + diff --git a/labx-14/labx-14-sc-skywalking-springcloudgateway/pom.xml b/labx-14/labx-14-sc-skywalking-springcloudgateway/pom.xml new file mode 100644 index 000000000..3139308b8 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-springcloudgateway/pom.xml @@ -0,0 +1,50 @@ + + + + labx-14 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-springcloudgateway + + + 2.1.13.RELEASE + Greenwich.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + diff --git a/labx-14/labx-14-sc-skywalking-springcloudgateway/src/main/java/cn/iocoder/springcloud/labx14/gatewaydemo/GatewayApplication.java b/labx-14/labx-14-sc-skywalking-springcloudgateway/src/main/java/cn/iocoder/springcloud/labx14/gatewaydemo/GatewayApplication.java new file mode 100644 index 000000000..15f2230ff --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-springcloudgateway/src/main/java/cn/iocoder/springcloud/labx14/gatewaydemo/GatewayApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx14.gatewaydemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-springcloudgateway/src/main/resources/application.yaml b/labx-14/labx-14-sc-skywalking-springcloudgateway/src/main/resources/application.yaml new file mode 100644 index 000000000..c200b68ed --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-springcloudgateway/src/main/resources/application.yaml @@ -0,0 +1,16 @@ +server: + port: 8888 + +spring: + application: + name: gateway-application + + cloud: + # Spring Cloud Gateway 配置项,对应 GatewayProperties 类 + gateway: + # 路由配置项,对应 RouteDefinition 数组 + routes: + - id: feign-service-route + uri: http://127.0.0.1:8081 + predicates: + - Path=/** diff --git a/labx-14/labx-14-sc-skywalking-springmvc/pom.xml b/labx-14/labx-14-sc-skywalking-springmvc/pom.xml new file mode 100644 index 000000000..5c5f880de --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-springmvc/pom.xml @@ -0,0 +1,52 @@ + + + + labx-14 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14-sc-skywalking-springmvc + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + diff --git a/labx-14/labx-14-sc-skywalking-springmvc/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/UserServiceApplication.java b/labx-14/labx-14-sc-skywalking-springmvc/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/UserServiceApplication.java new file mode 100644 index 000000000..ffae797e7 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-springmvc/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/UserServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx14.springmvcdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(UserServiceApplication.class, args); + } + +} diff --git a/labx-14/labx-14-sc-skywalking-springmvc/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/controller/UserController.java b/labx-14/labx-14-sc-skywalking-springmvc/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/controller/UserController.java new file mode 100644 index 000000000..4b4327227 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-springmvc/src/main/java/cn/iocoder/springcloud/labx14/springmvcdemo/controller/UserController.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloud.labx14.springmvcdemo.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + + @GetMapping("/get") + public String get(@RequestParam("id") Integer id) { + return "user:" + id; + } + +} diff --git a/labx-14/labx-14-sc-skywalking-springmvc/src/main/resources/application.yml b/labx-14/labx-14-sc-skywalking-springmvc/src/main/resources/application.yml new file mode 100644 index 000000000..f850a4dd5 --- /dev/null +++ b/labx-14/labx-14-sc-skywalking-springmvc/src/main/resources/application.yml @@ -0,0 +1,6 @@ +server: + port: 8079 + +spring: + application: + name: user-service # 服务名 diff --git a/labx-14/pom.xml b/labx-14/pom.xml new file mode 100644 index 000000000..92a6a8f46 --- /dev/null +++ b/labx-14/pom.xml @@ -0,0 +1,26 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-14 + pom + + + labx-14-sc-skywalking-springmvc + labx-14-sc-skywalking-feign + labx-14-sc-skywalking-springcloudgateway + labx-14-sc-skywalking-dubbo + + labx-14-sc-skywalking-mq-rocketmq + labx-14-sc-skywalking-mq-rabbitmq + labx-14-sc-skywalking-mq-kafka + + + diff --git "a/labx-14/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\223\276\350\267\257\350\277\275\350\270\252 SkyWalking\343\200\213.md" "b/labx-14/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\223\276\350\267\257\350\277\275\350\270\252 SkyWalking\343\200\213.md" new file mode 100644 index 000000000..d78a78c54 --- /dev/null +++ "b/labx-14/\343\200\212\350\212\213\351\201\223 Spring Cloud \351\223\276\350\267\257\350\277\275\350\270\252 SkyWalking\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-15/labx-15-admin-02-adminserver/pom.xml b/labx-15/labx-15-admin-02-adminserver/pom.xml new file mode 100644 index 000000000..5e6bcaed0 --- /dev/null +++ b/labx-15/labx-15-admin-02-adminserver/pom.xml @@ -0,0 +1,72 @@ + + + + labx-15 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-15-admin-02-adminserver + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + + de.codecentric + spring-boot-admin-starter-server + 2.2.2 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-15/labx-15-admin-02-adminserver/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java b/labx-15/labx-15-admin-02-adminserver/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java new file mode 100644 index 000000000..7f622d369 --- /dev/null +++ b/labx-15/labx-15-admin-02-adminserver/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx15.adminserver; + +import de.codecentric.boot.admin.server.config.EnableAdminServer; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableAdminServer +public class AdminServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AdminServerApplication.class, args); + } + +} diff --git a/labx-15/labx-15-admin-02-adminserver/src/main/resources/application.yaml b/labx-15/labx-15-admin-02-adminserver/src/main/resources/application.yaml new file mode 100644 index 000000000..55e0bcfdd --- /dev/null +++ b/labx-15/labx-15-admin-02-adminserver/src/main/resources/application.yaml @@ -0,0 +1,9 @@ +spring: + application: + name: demo-admin-server # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + service: ${spring.application.name} # 注册到 Nacos 的服务名。默认值为 ${spring.application.name}。 diff --git a/labx-15/labx-15-admin-02-demo-application/pom.xml b/labx-15/labx-15-admin-02-demo-application/pom.xml new file mode 100644 index 000000000..11e936f1c --- /dev/null +++ b/labx-15/labx-15-admin-02-demo-application/pom.xml @@ -0,0 +1,72 @@ + + + + labx-15 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-15-admin-02-demo-application + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-15/labx-15-admin-02-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo01Application.java b/labx-15/labx-15-admin-02-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo01Application.java new file mode 100644 index 000000000..c4e720ec5 --- /dev/null +++ b/labx-15/labx-15-admin-02-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo01Application.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloud.labx15.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Demo01Application { + + public static void main(String[] args) { + System.setProperty("server.port", "18081"); // 端口 18081 + SpringApplication.run(Demo01Application.class, args); + } + +} diff --git a/labx-15/labx-15-admin-02-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo02Application.java b/labx-15/labx-15-admin-02-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo02Application.java new file mode 100644 index 000000000..1f24151b9 --- /dev/null +++ b/labx-15/labx-15-admin-02-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo02Application.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloud.labx15.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Demo02Application { + + public static void main(String[] args) { + System.setProperty("server.port", "18082"); // 端口 18082 + SpringApplication.run(Demo02Application.class, args); + } + +} diff --git a/labx-15/labx-15-admin-02-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo03Application.java b/labx-15/labx-15-admin-02-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo03Application.java new file mode 100644 index 000000000..7d24867d0 --- /dev/null +++ b/labx-15/labx-15-admin-02-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo03Application.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx15.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Demo03Application { + + public static void main(String[] args) throws InterruptedException { + System.setProperty("server.port", "18083"); // 端口 18082 + SpringApplication.run(Demo03Application.class, args); + Thread.sleep(1000000L); + } + +} diff --git a/labx-15/labx-15-admin-02-demo-application/src/main/resources/application.yaml b/labx-15/labx-15-admin-02-demo-application/src/main/resources/application.yaml new file mode 100644 index 000000000..255a0957f --- /dev/null +++ b/labx-15/labx-15-admin-02-demo-application/src/main/resources/application.yaml @@ -0,0 +1,16 @@ +management: + endpoints: + # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类 + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + +spring: + application: + name: demo-application # 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + service: ${spring.application.name} # 注册到 Nacos 的服务名。默认值为 ${spring.application.name}。 diff --git a/labx-15/labx-15-admin-03-adminserver/pom.xml b/labx-15/labx-15-admin-03-adminserver/pom.xml new file mode 100644 index 000000000..5ef07012d --- /dev/null +++ b/labx-15/labx-15-admin-03-adminserver/pom.xml @@ -0,0 +1,78 @@ + + + + labx-15 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-15-admin-03-adminserver + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + + de.codecentric + spring-boot-admin-starter-server + 2.2.2 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.boot + spring-boot-starter-security + + + + diff --git a/labx-15/labx-15-admin-03-adminserver/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java b/labx-15/labx-15-admin-03-adminserver/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java new file mode 100644 index 000000000..7f622d369 --- /dev/null +++ b/labx-15/labx-15-admin-03-adminserver/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx15.adminserver; + +import de.codecentric.boot.admin.server.config.EnableAdminServer; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableAdminServer +public class AdminServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AdminServerApplication.class, args); + } + +} diff --git a/labx-15/labx-15-admin-03-adminserver/src/main/java/cn/iocoder/springcloud/labx15/adminserver/config/SecurityConfig.java b/labx-15/labx-15-admin-03-adminserver/src/main/java/cn/iocoder/springcloud/labx15/adminserver/config/SecurityConfig.java new file mode 100644 index 000000000..7c233810e --- /dev/null +++ b/labx-15/labx-15-admin-03-adminserver/src/main/java/cn/iocoder/springcloud/labx15/adminserver/config/SecurityConfig.java @@ -0,0 +1,46 @@ +package cn.iocoder.springcloud.labx15.adminserver.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.server.SecurityWebFilterChain; + +@Configuration +@EnableWebFluxSecurity // 开启 Security 对 WebFlux 的安全功能 +public class SecurityConfig { + + @Bean + public MapReactiveUserDetailsService userDetailsService() { + // 创建一个用户 + UserDetails user = User.withDefaultPasswordEncoder() + .username("user") + .password("user") + .roles("USER") + .build(); + + // 如果胖友有更多用户的诉求,这里可以继续创建 + + // 创建 MapReactiveUserDetailsService + return new MapReactiveUserDetailsService(user); + } + + @Bean + public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { + http.authorizeExchange(exchanges -> // 设置权限配置 + exchanges + .pathMatchers("/assets/**").permitAll() // 静态资源,允许匿名访问 + .pathMatchers("/login").permitAll() // 登陆接口,允许匿名访问 + .anyExchange().authenticated() // + ) + .formLogin().loginPage("/login") // 登陆页面 + .and().logout().logoutUrl("/logout") // 登出界面 + .and().httpBasic() // HTTP Basic 认证方式 + .and().csrf().disable(); // csrf 禁用 + return http.build(); + } + +} diff --git a/labx-15/labx-15-admin-03-adminserver/src/main/resources/application.yaml b/labx-15/labx-15-admin-03-adminserver/src/main/resources/application.yaml new file mode 100644 index 000000000..61e2dd640 --- /dev/null +++ b/labx-15/labx-15-admin-03-adminserver/src/main/resources/application.yaml @@ -0,0 +1,12 @@ +spring: + application: + name: demo-admin-server # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + service: ${spring.application.name} # 注册到 Nacos 的服务名。默认值为 ${spring.application.name}。 + metadata: + user.name: user # Spring Security 安全认证的账号 + user.password: user # Spring Security 安全认证的密码 diff --git a/labx-15/labx-15-admin-03-demo-application/pom.xml b/labx-15/labx-15-admin-03-demo-application/pom.xml new file mode 100644 index 000000000..8c4854844 --- /dev/null +++ b/labx-15/labx-15-admin-03-demo-application/pom.xml @@ -0,0 +1,78 @@ + + + + labx-15 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-15-admin-03-demo-application + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.boot + spring-boot-starter-security + + + + diff --git a/labx-15/labx-15-admin-03-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo01Application.java b/labx-15/labx-15-admin-03-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo01Application.java new file mode 100644 index 000000000..c4e720ec5 --- /dev/null +++ b/labx-15/labx-15-admin-03-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo01Application.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloud.labx15.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Demo01Application { + + public static void main(String[] args) { + System.setProperty("server.port", "18081"); // 端口 18081 + SpringApplication.run(Demo01Application.class, args); + } + +} diff --git a/labx-15/labx-15-admin-03-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo02Application.java b/labx-15/labx-15-admin-03-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo02Application.java new file mode 100644 index 000000000..1f24151b9 --- /dev/null +++ b/labx-15/labx-15-admin-03-demo-application/src/main/java/cn/iocoder/springcloud/labx15/demo/Demo02Application.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloud.labx15.demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Demo02Application { + + public static void main(String[] args) { + System.setProperty("server.port", "18082"); // 端口 18082 + SpringApplication.run(Demo02Application.class, args); + } + +} diff --git a/labx-15/labx-15-admin-03-demo-application/src/main/resources/application.yaml b/labx-15/labx-15-admin-03-demo-application/src/main/resources/application.yaml new file mode 100644 index 000000000..7b9f84a15 --- /dev/null +++ b/labx-15/labx-15-admin-03-demo-application/src/main/resources/application.yaml @@ -0,0 +1,27 @@ +management: + endpoints: + # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类 + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + +spring: + application: + name: demo-application # 应用名 + + # Spring Security 配置项,对应 SecurityProperties 配置类 + security: + # 配置默认的 InMemoryUserDetailsManager 的用户账号与密码。 + user: + name: test # 账号 + password: test # 密码 + + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + service: ${spring.application.name} # 注册到 Nacos 的服务名。默认值为 ${spring.application.name}。 + metadata: + user.name: ${spring.security.user.name} # Spring Security 认证账号 + user.password: ${spring.security.user.password} # Spring Security 认证密码 diff --git a/labx-15/labx-15-admin-04-adminserver-custom/pom.xml b/labx-15/labx-15-admin-04-adminserver-custom/pom.xml new file mode 100644 index 000000000..e43b00b0d --- /dev/null +++ b/labx-15/labx-15-admin-04-adminserver-custom/pom.xml @@ -0,0 +1,72 @@ + + + + labx-15 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-15-admin-04-adminserver-custom + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + + de.codecentric + spring-boot-admin-starter-server + 2.2.2 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-15/labx-15-admin-04-adminserver-custom/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java b/labx-15/labx-15-admin-04-adminserver-custom/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java new file mode 100644 index 000000000..7f622d369 --- /dev/null +++ b/labx-15/labx-15-admin-04-adminserver-custom/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx15.adminserver; + +import de.codecentric.boot.admin.server.config.EnableAdminServer; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableAdminServer +public class AdminServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AdminServerApplication.class, args); + } + +} diff --git a/labx-15/labx-15-admin-04-adminserver-custom/src/main/java/cn/iocoder/springcloud/labx15/adminserver/notify/LoggerNotifier.java b/labx-15/labx-15-admin-04-adminserver-custom/src/main/java/cn/iocoder/springcloud/labx15/adminserver/notify/LoggerNotifier.java new file mode 100644 index 000000000..b52868689 --- /dev/null +++ b/labx-15/labx-15-admin-04-adminserver-custom/src/main/java/cn/iocoder/springcloud/labx15/adminserver/notify/LoggerNotifier.java @@ -0,0 +1,34 @@ +package cn.iocoder.springcloud.labx15.adminserver.notify; + +import de.codecentric.boot.admin.server.domain.entities.Instance; +import de.codecentric.boot.admin.server.domain.entities.InstanceRepository; +import de.codecentric.boot.admin.server.domain.events.InstanceEvent; +import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent; +import de.codecentric.boot.admin.server.notify.AbstractEventNotifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +@Component +public class LoggerNotifier extends AbstractEventNotifier { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + public LoggerNotifier(InstanceRepository repository) { + super(repository); + } + + @Override + protected Mono doNotify(InstanceEvent event, Instance instance) { + return Mono.fromRunnable(() -> { + if (event instanceof InstanceStatusChangedEvent) { + logger.info("Instance {} ({}) is {}", instance.getRegistration().getName(), event.getInstance(), + ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus()); + } else { + logger.info("Instance {} ({}) {}", instance.getRegistration().getName(), event.getInstance(), event.getType()); + } + }); + } + +} diff --git a/labx-15/labx-15-admin-04-adminserver-custom/src/main/resources/application.yaml b/labx-15/labx-15-admin-04-adminserver-custom/src/main/resources/application.yaml new file mode 100644 index 000000000..55e0bcfdd --- /dev/null +++ b/labx-15/labx-15-admin-04-adminserver-custom/src/main/resources/application.yaml @@ -0,0 +1,9 @@ +spring: + application: + name: demo-admin-server # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + service: ${spring.application.name} # 注册到 Nacos 的服务名。默认值为 ${spring.application.name}。 diff --git a/labx-15/labx-15-admin-04-adminserver-mail/pom.xml b/labx-15/labx-15-admin-04-adminserver-mail/pom.xml new file mode 100644 index 000000000..03a1794ce --- /dev/null +++ b/labx-15/labx-15-admin-04-adminserver-mail/pom.xml @@ -0,0 +1,78 @@ + + + + labx-15 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-15-admin-04-adminserver-mail + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + + de.codecentric + spring-boot-admin-starter-server + 2.2.2 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.boot + spring-boot-starter-mail + + + + diff --git a/labx-15/labx-15-admin-04-adminserver-mail/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java b/labx-15/labx-15-admin-04-adminserver-mail/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java new file mode 100644 index 000000000..7f622d369 --- /dev/null +++ b/labx-15/labx-15-admin-04-adminserver-mail/src/main/java/cn/iocoder/springcloud/labx15/adminserver/AdminServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx15.adminserver; + +import de.codecentric.boot.admin.server.config.EnableAdminServer; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableAdminServer +public class AdminServerApplication { + + public static void main(String[] args) { + SpringApplication.run(AdminServerApplication.class, args); + } + +} diff --git a/labx-15/labx-15-admin-04-adminserver-mail/src/main/resources/application.yaml b/labx-15/labx-15-admin-04-adminserver-mail/src/main/resources/application.yaml new file mode 100644 index 000000000..ca80a278b --- /dev/null +++ b/labx-15/labx-15-admin-04-adminserver-mail/src/main/resources/application.yaml @@ -0,0 +1,22 @@ +spring: + application: + name: demo-admin-server # Spring 应用名 + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + service: ${spring.application.name} # 注册到 Nacos 的服务名。默认值为 ${spring.application.name}。 + + mail: # 配置发送告警的邮箱 + host: smtp.126.com + username: wwbmlhh@126.com + password: '******' + default-encoding: UTF-8 + + boot: + admin: + notify: + mail: + from: ${spring.mail.username} # 告警发件人 + to: 7685413@qq.com # 告警收件人 diff --git a/labx-15/pom.xml b/labx-15/pom.xml new file mode 100644 index 000000000..3f7d1513e --- /dev/null +++ b/labx-15/pom.xml @@ -0,0 +1,26 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-15 + pom + + + labx-15-admin-02-adminserver + labx-15-admin-02-demo-application + + labx-15-admin-03-adminserver + labx-15-admin-03-demo-application + + labx-15-admin-04-adminserver-mail + labx-15-admin-04-adminserver-custom + + + diff --git "a/labx-15/\343\200\212\350\212\213\351\201\223 Spring Cloud \347\233\221\346\216\247\345\267\245\345\205\267 Admin \345\205\245\351\227\250\343\200\213.md" "b/labx-15/\343\200\212\350\212\213\351\201\223 Spring Cloud \347\233\221\346\216\247\345\267\245\345\205\267 Admin \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..1a8ca827d --- /dev/null +++ "b/labx-15/\343\200\212\350\212\213\351\201\223 Spring Cloud \347\233\221\346\216\247\345\267\245\345\205\267 Admin \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-16/deploy.sh b/labx-16/deploy.sh new file mode 100644 index 000000000..60e23423e --- /dev/null +++ b/labx-16/deploy.sh @@ -0,0 +1,166 @@ +#!/bin/bash +set -e + +# 基础 +# export JAVA_HOME=/work/programs/jdk/jdk1.8.0_181 +# export PATH=PATH=$PATH:$JAVA_HOME/bin +# export CLASSPATH=$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar + +DATE=$(date +%Y%m%d%H%M) +# 基础路径 +BASE_PATH=/work/projects/labx-16-demo-01 +# 编译后 jar 的地址。部署时,Jenkins 会上传 jar 包到该目录下 +SOURCE_PATH=$BASE_PATH/build +# 服务名称。同时约定部署服务的 jar 包名字也为它。 +SERVER_NAME=labx-16-demo-01 +# 环境 +PROFILES_ACTIVE=prod +# 健康检查 URL +HEALTH_CHECK_URL=http://127.0.0.1:8078/actuator/health/ +# 修改状态 URL +STATUS_URL=http://127.0.0.1:8078/actuator/service-registry/ + +# heapError 存放路径 +HEAP_ERROR_PATH=$BASE_PATH/heapError +# JVM 参数 +JAVA_OPS="-Xms1024m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$HEAP_ERROR_PATH" +# JavaAgent 参数。可用于配置 SkyWalking 等链路追踪 +JAVA_AGENT= + +# 备份 +function backup() { + # 如果不存在,则无需备份 + if [ ! -f "$BASE_PATH/$SERVER_NAME.jar" ]; then + echo "[backup] $BASE_PATH/$SERVER_NAME.jar 不存在,跳过备份" + # 如果存在,则备份到 backup 目录下,使用时间作为后缀 + else + echo "[backup] 开始备份 $SERVER_NAME ..." + cp $BASE_PATH/$SERVER_NAME.jar $BASE_PATH/backup/$SERVER_NAME-$DATE.jar + echo "[backup] 备份 $SERVER_NAME 完成" + fi +} + +# 最新构建代码 移动到项目环境 +function transfer() { + echo "[transfer] 开始转移 $SERVER_NAME.jar" + + # 删除原 jar 包 + if [ ! -f "$BASE_PATH/$SERVER_NAME.jar" ]; then + echo "[transfer] $BASE_PATH/$SERVER_NAME.jar 不存在,跳过删除" + else + echo "[transfer] 移除 $BASE_PATH/$SERVER_NAME.jar 完成" + rm $BASE_PATH/$SERVER_NAME.jar + fi + + # 复制新 jar 包 + echo "[transfer] 从 $SOURCE_PATH 中获取 $SERVER_NAME.jar 并迁移至 $BASE_PATH ...." + cp $SOURCE_PATH/$SERVER_NAME.jar $BASE_PATH + + echo "[transfer] 转移 $SERVER_NAME.jar 完成" +} + +# 停止 +function stop() { + echo "[stop] 开始停止 $BASE_PATH/$SERVER_NAME" + PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}') + # 如果 Java 服务启动中,则进行关闭 + if [ -n "$PID" ]; then + # 从注册中心下线 + echo "[stop] 从注册中心下线当前实例,并 sleep 20 秒" + curl -X POST $STATUS_URL -d '{"status": "DOWN"}' -H 'content-type: application/json' + sleep 20 + # 正常关闭 + echo "[stop] $BASE_PATH/$SERVER_NAME 运行中,开始 kill [$PID]" + kill -15 $PID + # 等待最大 60 秒,直到关闭完成。 + for ((i = 0; i < 60; i++)) + do + sleep 1 + PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}') + if [ -n "$PID" ]; then + echo -e ".\c" + else + echo '[stop] 停止 $BASE_PATH/$SERVER_NAME 成功' + break + fi + done + + # 如果正常关闭失败,那么进行强制 kill -9 进行关闭 + if [ -n "$PID" ]; then + echo "[stop] $BASE_PATH/$SERVER_NAME 失败,强制 kill -9 $PID" + kill -9 $PID + fi + # 如果 Java 服务未启动,则无需关闭 + else + echo "[stop] $BASE_PATH/$SERVER_NAME 未启动,无需停止" + fi +} + +# 启动 +function start() { + # 开启启动前,打印启动参数 + echo "[start] 开始启动 $BASE_PATH/$SERVER_NAME" + echo "[start] JAVA_OPS: $JAVA_OPS" + echo "[start] JAVA_AGENT: $JAVA_AGENT" + echo "[start] PROFILES: $PROFILES_ACTIVE" + + # 开始启动 + BUILD_ID=dontKillMe nohup java -server $JAVA_OPS $JAVA_AGENT -jar $BASE_PATH/$SERVER_NAME.jar --spring.profiles.active=$PROFILES_ACTIVE & + echo "[start] 启动 $BASE_PATH/$SERVER_NAME 完成" +} + +# 健康检查 +function healthCheck() { + # 如果配置健康检查,则进行健康检查 + if [ -n "$HEALTH_CHECK_URL" ]; then + # 健康检查最大 60 秒,直到健康检查通过 + echo "[healthCheck] 开始通过 $HEALTH_CHECK_URL 地址,进行健康检查"; + for ((i = 0; i < 60; i++)) + do + # 请求健康检查地址,只获取状态码。 + result=`curl -I -m 10 -o /dev/null -s -w %{http_code} $HEALTH_CHECK_URL || echo "000"` + # 如果状态码为 200,则说明健康检查通过 + if [ "$result" == "200" ]; then + echo "[healthCheck] 健康检查通过"; + break + # 如果状态码非 200,则说明未通过。sleep 1 秒后,继续重试 + else + echo -e ".\c" + sleep 1 + fi + done + + # 健康检查未通过,则异常退出 shell 脚本,不继续部署。 + if [ ! "$result" == "200" ]; then + echo "[healthCheck] 健康检查不通过,可能部署失败。查看日志,自行判断是否启动成功"; + tail -n 10 nohup.out + exit 1; + # 健康检查通过,打印最后 10 行日志,可能部署的人想看下日志。 + else + tail -n 10 nohup.out + fi + # 如果未配置健康检查,则 slepp 60 秒,人工看日志是否部署成功。 + else + echo "[healthCheck] HEALTH_CHECK_URL 未配置,开始 sleep 60 秒"; + sleep 60 + echo "[healthCheck] sleep 60 秒完成,查看日志,自行判断是否启动成功"; + tail -n 50 nohup.out + fi +} + +# 部署 +function deploy() { + cd $BASE_PATH + # 备份原 jar + backup + # 停止 Java 服务 + stop + # 部署新 jar + transfer + # 启动 Java 服务 + start + # 健康检查 + healthCheck +} + +deploy diff --git a/labx-16/labx-16-demo-01/pom.xml b/labx-16/labx-16-demo-01/pom.xml new file mode 100644 index 000000000..30e5027db --- /dev/null +++ b/labx-16/labx-16-demo-01/pom.xml @@ -0,0 +1,94 @@ + + + + labx-16 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-16-demo-01 + + jar + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + + ${project.artifactId} + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + + + + + + diff --git a/labx-16/labx-16-demo-01/src/main/java/cn/iocoder/springcloud/lab16/jenkinsdemo/Application.java b/labx-16/labx-16-demo-01/src/main/java/cn/iocoder/springcloud/lab16/jenkinsdemo/Application.java new file mode 100644 index 000000000..e1755a583 --- /dev/null +++ b/labx-16/labx-16-demo-01/src/main/java/cn/iocoder/springcloud/lab16/jenkinsdemo/Application.java @@ -0,0 +1,36 @@ +package cn.iocoder.springcloud.lab16.jenkinsdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.stereotype.Component; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Component + public class Listener implements ApplicationListener { + + @Override + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof ContextClosedEvent) { + this.sleep(10); + } + } + + private void sleep(int seconds) { + try { + Thread.sleep(seconds * 1000L); + } catch (InterruptedException ignore) { + } + } + + } + +} diff --git a/labx-16/labx-16-demo-01/src/main/java/cn/iocoder/springcloud/lab16/jenkinsdemo/controller/DemoController.java b/labx-16/labx-16-demo-01/src/main/java/cn/iocoder/springcloud/lab16/jenkinsdemo/controller/DemoController.java new file mode 100644 index 000000000..455fd7acc --- /dev/null +++ b/labx-16/labx-16-demo-01/src/main/java/cn/iocoder/springcloud/lab16/jenkinsdemo/controller/DemoController.java @@ -0,0 +1,16 @@ +package cn.iocoder.springcloud.lab16.jenkinsdemo.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + @GetMapping("/echo") + public String echo() { + return "echo"; + } + +} diff --git a/labx-16/labx-16-demo-01/src/main/resources/application-dev.yaml b/labx-16/labx-16-demo-01/src/main/resources/application-dev.yaml new file mode 100644 index 000000000..b0355d15f --- /dev/null +++ b/labx-16/labx-16-demo-01/src/main/resources/application-dev.yaml @@ -0,0 +1,22 @@ +server: + port: 8079 + +management: + server: + port: 8078 # 自定义端口,避免 Nginx 暴露出去 + + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + +spring: + application: + name: demo-service + + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 + diff --git a/labx-16/labx-16-demo-01/src/main/resources/application-local.yaml b/labx-16/labx-16-demo-01/src/main/resources/application-local.yaml new file mode 100644 index 000000000..4a136ce70 --- /dev/null +++ b/labx-16/labx-16-demo-01/src/main/resources/application-local.yaml @@ -0,0 +1,21 @@ +server: + port: 8079 + +management: + server: + port: 8078 # 自定义端口,避免 Nginx 暴露出去 + + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + +spring: + application: + name: demo-service + + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 diff --git a/labx-16/labx-16-demo-01/src/main/resources/application-pre.yaml b/labx-16/labx-16-demo-01/src/main/resources/application-pre.yaml new file mode 100644 index 000000000..4a136ce70 --- /dev/null +++ b/labx-16/labx-16-demo-01/src/main/resources/application-pre.yaml @@ -0,0 +1,21 @@ +server: + port: 8079 + +management: + server: + port: 8078 # 自定义端口,避免 Nginx 暴露出去 + + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + +spring: + application: + name: demo-service + + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 diff --git a/labx-16/labx-16-demo-01/src/main/resources/application-prod.yaml b/labx-16/labx-16-demo-01/src/main/resources/application-prod.yaml new file mode 100644 index 000000000..4a136ce70 --- /dev/null +++ b/labx-16/labx-16-demo-01/src/main/resources/application-prod.yaml @@ -0,0 +1,21 @@ +server: + port: 8079 + +management: + server: + port: 8078 # 自定义端口,避免 Nginx 暴露出去 + + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + +spring: + application: + name: demo-service + + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 diff --git a/labx-16/labx-16-demo-01/src/main/resources/application-uat.yaml b/labx-16/labx-16-demo-01/src/main/resources/application-uat.yaml new file mode 100644 index 000000000..4a136ce70 --- /dev/null +++ b/labx-16/labx-16-demo-01/src/main/resources/application-uat.yaml @@ -0,0 +1,21 @@ +server: + port: 8079 + +management: + server: + port: 8078 # 自定义端口,避免 Nginx 暴露出去 + + endpoints: + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + +spring: + application: + name: demo-service + + cloud: + nacos: + # Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类 + discovery: + server-addr: 127.0.0.1:8848 # Nacos 服务器地址 diff --git a/labx-16/pom.xml b/labx-16/pom.xml new file mode 100644 index 000000000..4a9f09c8a --- /dev/null +++ b/labx-16/pom.xml @@ -0,0 +1,18 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-16 + pom + + labx-16-demo-01 + + + diff --git "a/labx-16/\343\200\212\350\212\213\351\201\223 Spring Cloud \346\214\201\347\273\255\344\272\244\344\273\230 Jenkins \345\205\245\351\227\250\343\200\213.md" "b/labx-16/\343\200\212\350\212\213\351\201\223 Spring Cloud \346\214\201\347\273\255\344\272\244\344\273\230 Jenkins \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..ddf1364cf --- /dev/null +++ "b/labx-16/\343\200\212\350\212\213\351\201\223 Spring Cloud \346\214\201\347\273\255\344\272\244\344\273\230 Jenkins \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/data.sql b/labx-17/labx-17-sc-seata-at-feign-demo/data.sql new file mode 100644 index 000000000..3b0ce0828 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/data.sql @@ -0,0 +1,82 @@ +# Order +DROP DATABASE IF EXISTS seata_order; +CREATE DATABASE seata_order; + +CREATE TABLE seata_order.orders +( + id INT(11) NOT NULL AUTO_INCREMENT, + user_id INT(11) DEFAULT NULL, + product_id INT(11) DEFAULT NULL, + pay_amount DECIMAL(10, 0) DEFAULT NULL, + add_time DATETIME DEFAULT CURRENT_TIMESTAMP, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +CREATE TABLE seata_order.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +# Product +DROP DATABASE IF EXISTS seata_product; +CREATE DATABASE seata_product; + +CREATE TABLE seata_product.product +( + id INT(11) NOT NULL AUTO_INCREMENT, + stock INT(11) DEFAULT NULL, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; +INSERT INTO seata_product.product (id, stock) VALUES (1, 10); # 插入一条产品的库存 + +CREATE TABLE seata_product.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +# Account +DROP DATABASE IF EXISTS seata_account; +CREATE DATABASE seata_account; + +CREATE TABLE seata_account.account +( + id INT(11) NOT NULL AUTO_INCREMENT, + balance DOUBLE DEFAULT NULL, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +CREATE TABLE seata_account.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; +INSERT INTO seata_account.account (id, balance) VALUES (1, 10); diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/pom.xml b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/pom.xml new file mode 100644 index 000000000..c643aad20 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/pom.xml @@ -0,0 +1,100 @@ + + + + labx-17-sc-seata-at-feign-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sc-seata-at-feign-demo-account-service + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + com.alibaba.cloud + spring-cloud-alibaba-seata + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/AccountServiceApplication.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/AccountServiceApplication.java new file mode 100644 index 000000000..710b9bfc8 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/AccountServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx17.accountservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AccountServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(AccountServiceApplication.class, args); + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/controller/AccountController.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/controller/AccountController.java new file mode 100644 index 000000000..9d8ef40c0 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/controller/AccountController.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx17.accountservice.controller; + +import cn.iocoder.springcloud.labx17.accountservice.dto.AccountReduceBalanceDTO; +import cn.iocoder.springcloud.labx17.accountservice.service.AccountService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/account") +public class AccountController { + + private Logger logger = LoggerFactory.getLogger(AccountController.class); + + @Autowired + private AccountService accountService; + + @PostMapping("/reduce-balance") + public void reduceBalance(@RequestBody AccountReduceBalanceDTO accountReduceBalanceDTO) throws Exception { + logger.info("[reduceBalance] 收到减少余额请求, 用户:{}, 金额:{}", accountReduceBalanceDTO.getUserId(), + accountReduceBalanceDTO.getPrice()); + accountService.reduceBalance(accountReduceBalanceDTO.getUserId(), accountReduceBalanceDTO.getPrice()); + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/dao/AccountDao.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/dao/AccountDao.java new file mode 100644 index 000000000..4599cba2f --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/dao/AccountDao.java @@ -0,0 +1,32 @@ +package cn.iocoder.springcloud.labx17.accountservice.dao; + + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface AccountDao { + + /** + * 获取账户余额 + * + * @param userId 用户 ID + * @return 账户余额 + */ + @Select("SELECT balance FROM account WHERE id = #{userId}") + Integer getBalance(@Param("userId") Long userId); + + /** + * 扣减余额 + * + * @param price 需要扣减的数目 + * @return 影响记录行数 + */ + @Update("UPDATE account SET balance = balance - #{price} WHERE id = 1 AND balance >= ${price}") + int reduceBalance(@Param("price") Integer price); + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/dto/AccountReduceBalanceDTO.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/dto/AccountReduceBalanceDTO.java new file mode 100644 index 000000000..d261873e4 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/dto/AccountReduceBalanceDTO.java @@ -0,0 +1,36 @@ +package cn.iocoder.springcloud.labx17.accountservice.dto; + +/** + * 账户减少余额 DTO + */ +public class AccountReduceBalanceDTO { + + /** + * 用户编号 + */ + private Long userId; + + /** + * 扣减金额 + */ + private Integer price; + + public Long getUserId() { + return userId; + } + + public AccountReduceBalanceDTO setUserId(Long userId) { + this.userId = userId; + return this; + } + + public Integer getPrice() { + return price; + } + + public AccountReduceBalanceDTO setPrice(Integer price) { + this.price = price; + return this; + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/service/AccountService.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/service/AccountService.java new file mode 100644 index 000000000..5783898ff --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/service/AccountService.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloud.labx17.accountservice.service; + +/** + * 账户 Service + */ +public interface AccountService { + + /** + * 扣除余额 + * + * @param userId 用户编号 + * @param price 扣减金额 + * @throws Exception 失败时抛出异常 + */ + void reduceBalance(Long userId, Integer price) throws Exception; + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/service/impl/AccountServiceImpl.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/service/impl/AccountServiceImpl.java new file mode 100644 index 000000000..4e5c744f2 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/java/cn/iocoder/springcloud/labx17/accountservice/service/impl/AccountServiceImpl.java @@ -0,0 +1,48 @@ +package cn.iocoder.springcloud.labx17.accountservice.service.impl; + +import cn.iocoder.springcloud.labx17.accountservice.dao.AccountDao; +import cn.iocoder.springcloud.labx17.accountservice.service.AccountService; +import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class AccountServiceImpl implements AccountService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private AccountDao accountDao; + + @Override + @Transactional // 开启新事物 + public void reduceBalance(Long userId, Integer price) throws Exception { + logger.info("[reduceBalance] 当前 XID: {}", RootContext.getXID()); + + // 检查余额 + checkBalance(userId, price); + + logger.info("[reduceBalance] 开始扣减用户 {} 余额", userId); + // 扣除余额 + int updateCount = accountDao.reduceBalance(price); + // 扣除成功 + if (updateCount == 0) { + logger.warn("[reduceBalance] 扣除用户 {} 余额失败", userId); + throw new Exception("余额不足"); + } + logger.info("[reduceBalance] 扣除用户 {} 余额成功", userId); + } + + private void checkBalance(Long userId, Integer price) throws Exception { + logger.info("[checkBalance] 检查用户 {} 余额", userId); + Integer balance = accountDao.getBalance(userId); + if (balance < price) { + logger.warn("[checkBalance] 用户 {} 余额不足,当前余额:{}", userId, balance); + throw new Exception("余额不足"); + } + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/resources/application-file.yaml b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/resources/application-file.yaml new file mode 100644 index 000000000..69030f4f0 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/resources/application-file.yaml @@ -0,0 +1,31 @@ +server: + port: 8083 + +spring: + application: + name: account-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_account?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + account-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/resources/application.yaml b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/resources/application.yaml new file mode 100644 index 000000000..cccfcece1 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-account-service/src/main/resources/application.yaml @@ -0,0 +1,35 @@ +server: + port: 8083 + +spring: + application: + name: account-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_account?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # Seata 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + account-service-group: default + # Seata 注册中心配置项,对应 RegistryProperties 类 + registry: + type: nacos # 注册中心类型,默认为 file + nacos: + cluster: default # 使用的 Seata 分组 + namespace: # Nacos 命名空间 + serverAddr: localhost # Nacos 服务地址 diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/pom.xml b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/pom.xml new file mode 100644 index 000000000..43c1871ba --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/pom.xml @@ -0,0 +1,106 @@ + + + + labx-17-sc-seata-at-feign-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sc-seata-at-feign-demo-order-service + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + com.alibaba.cloud + spring-cloud-alibaba-seata + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/OrderServiceApplication.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/OrderServiceApplication.java new file mode 100644 index 000000000..ac1fb0221 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/OrderServiceApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx17.orderservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.openfeign.EnableFeignClients; + +@SpringBootApplication +@EnableFeignClients +public class OrderServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(OrderServiceApplication.class, args); + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/controller/OrderController.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/controller/OrderController.java new file mode 100644 index 000000000..cb199a450 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/controller/OrderController.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloud.labx17.orderservice.controller; + +import cn.iocoder.springcloud.labx17.orderservice.service.OrderService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/order") +public class OrderController { + + private Logger logger = LoggerFactory.getLogger(OrderController.class); + + @Autowired + private OrderService orderService; + + @PostMapping("/create") + public Integer createOrder(@RequestParam("userId") Long userId, + @RequestParam("productId") Long productId, + @RequestParam("price") Integer price) throws Exception { + logger.info("[createOrder] 收到下单请求,用户:{}, 商品:{}, 价格:{}", userId, productId, price); + return orderService.createOrder(userId, productId, price); + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/dao/OrderDao.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/dao/OrderDao.java new file mode 100644 index 000000000..7d15ca8cf --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/dao/OrderDao.java @@ -0,0 +1,23 @@ +package cn.iocoder.springcloud.labx17.orderservice.dao; + +import cn.iocoder.springcloud.labx17.orderservice.entity.OrderDO; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Options; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface OrderDao { + + /** + * 插入订单记录 + * + * @param order 订单 + * @return 影响记录数量 + */ + @Insert("INSERT INTO orders (user_id, product_id, pay_amount) VALUES (#{userId}, #{productId}, #{payAmount})") + @Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id") + int saveOrder(OrderDO order); + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/entity/OrderDO.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/entity/OrderDO.java new file mode 100644 index 000000000..2ff2f897b --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/entity/OrderDO.java @@ -0,0 +1,56 @@ +package cn.iocoder.springcloud.labx17.orderservice.entity; + +/** + * 订单实体 + */ +public class OrderDO { + + /** 订单编号 **/ + private Integer id; + + /** 用户编号 **/ + private Long userId; + + /** 产品编号 **/ + private Long productId; + + /** 支付金额 **/ + private Integer payAmount; + + public Integer getId() { + return id; + } + + public OrderDO setId(Integer id) { + this.id = id; + return this; + } + + public Long getUserId() { + return userId; + } + + public OrderDO setUserId(Long userId) { + this.userId = userId; + return this; + } + + public Long getProductId() { + return productId; + } + + public OrderDO setProductId(Long productId) { + this.productId = productId; + return this; + } + + public Integer getPayAmount() { + return payAmount; + } + + public OrderDO setPayAmount(Integer payAmount) { + this.payAmount = payAmount; + return this; + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/AccountServiceFeignClient.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/AccountServiceFeignClient.java new file mode 100644 index 000000000..a4c3239a8 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/AccountServiceFeignClient.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloud.labx17.orderservice.feign; + +import cn.iocoder.springcloud.labx17.orderservice.feign.dto.AccountReduceBalanceDTO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +/** + * `account-service` 服务的 Feign 客户端 + */ +@FeignClient(name = "account-service") +public interface AccountServiceFeignClient { + + @PostMapping("/account/reduce-balance") + void reduceBalance(@RequestBody AccountReduceBalanceDTO accountReduceBalanceDTO); + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/ProductServiceFeignClient.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/ProductServiceFeignClient.java new file mode 100644 index 000000000..9a81cc9dd --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/ProductServiceFeignClient.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloud.labx17.orderservice.feign; + +import cn.iocoder.springcloud.labx17.orderservice.feign.dto.ProductReduceStockDTO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +/** + * `product-service` 服务的 Feign 客户端 + */ +@FeignClient(name = "product-service") +public interface ProductServiceFeignClient { + + @PostMapping("/product/reduce-stock") + void reduceStock(@RequestBody ProductReduceStockDTO productReduceStockDTO); + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/dto/AccountReduceBalanceDTO.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/dto/AccountReduceBalanceDTO.java new file mode 100644 index 000000000..d221cbf11 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/dto/AccountReduceBalanceDTO.java @@ -0,0 +1,36 @@ +package cn.iocoder.springcloud.labx17.orderservice.feign.dto; + +/** + * 账户减少余额 DTO + */ +public class AccountReduceBalanceDTO { + + /** + * 用户编号 + */ + private Long userId; + + /** + * 扣减金额 + */ + private Integer price; + + public Long getUserId() { + return userId; + } + + public AccountReduceBalanceDTO setUserId(Long userId) { + this.userId = userId; + return this; + } + + public Integer getPrice() { + return price; + } + + public AccountReduceBalanceDTO setPrice(Integer price) { + this.price = price; + return this; + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/dto/ProductReduceStockDTO.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/dto/ProductReduceStockDTO.java new file mode 100644 index 000000000..bd9b721ab --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/feign/dto/ProductReduceStockDTO.java @@ -0,0 +1,35 @@ +package cn.iocoder.springcloud.labx17.orderservice.feign.dto; + +/** + * 商品减少库存 DTO + */ +public class ProductReduceStockDTO { + + /** + * 商品编号 + */ + private Long productId; + /** + * 数量 + */ + private Integer amount; + + public Long getProductId() { + return productId; + } + + public ProductReduceStockDTO setProductId(Long productId) { + this.productId = productId; + return this; + } + + public Integer getAmount() { + return amount; + } + + public ProductReduceStockDTO setAmount(Integer amount) { + this.amount = amount; + return this; + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/service/OrderService.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/service/OrderService.java new file mode 100644 index 000000000..03d6cbe8c --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/service/OrderService.java @@ -0,0 +1,19 @@ +package cn.iocoder.springcloud.labx17.orderservice.service; + +/** + * 订单 Service + */ +public interface OrderService { + + /** + * 创建订单 + * + * @param userId 用户编号 + * @param productId 产品编号 + * @param price 价格 + * @return 订单编号 + * @throws Exception 创建订单失败,抛出异常 + */ + Integer createOrder(Long userId, Long productId, Integer price) throws Exception; + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/service/impl/OrderServiceImpl.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/service/impl/OrderServiceImpl.java new file mode 100644 index 000000000..776a605b4 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/java/cn/iocoder/springcloud/labx17/orderservice/service/impl/OrderServiceImpl.java @@ -0,0 +1,50 @@ +package cn.iocoder.springcloud.labx17.orderservice.service.impl; + +import cn.iocoder.springcloud.labx17.orderservice.dao.OrderDao; +import cn.iocoder.springcloud.labx17.orderservice.entity.OrderDO; +import cn.iocoder.springcloud.labx17.orderservice.feign.*; +import cn.iocoder.springcloud.labx17.orderservice.feign.dto.*; +import cn.iocoder.springcloud.labx17.orderservice.service.OrderService; +import io.seata.core.context.RootContext; +import io.seata.spring.annotation.GlobalTransactional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class OrderServiceImpl implements OrderService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private OrderDao orderDao; + + @Autowired + private AccountServiceFeignClient accountService; + @Autowired + private ProductServiceFeignClient productService; + + @Override + @GlobalTransactional + public Integer createOrder(Long userId, Long productId, Integer price) { + Integer amount = 1; // 购买数量,暂时设置为 1。 + + logger.info("[createOrder] 当前 XID: {}", RootContext.getXID()); + + // 扣减库存 + productService.reduceStock(new ProductReduceStockDTO().setProductId(productId).setAmount(amount)); + + // 扣减余额 + accountService.reduceBalance(new AccountReduceBalanceDTO().setUserId(userId).setPrice(price)); + + // 保存订单 + OrderDO order = new OrderDO().setUserId(userId).setProductId(productId).setPayAmount(amount * price); + orderDao.saveOrder(order); + logger.info("[createOrder] 保存订单: {}", order.getId()); + + // 返回订单编号 + return order.getId(); + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/resources/application-file.yaml b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/resources/application-file.yaml new file mode 100644 index 000000000..1edfa5d05 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/resources/application-file.yaml @@ -0,0 +1,31 @@ +server: + port: 8081 # 端口 + +spring: + application: + name: order-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + order-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/resources/application.yaml b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/resources/application.yaml new file mode 100644 index 000000000..2a53c738d --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-order-service/src/main/resources/application.yaml @@ -0,0 +1,35 @@ +server: + port: 8081 # 端口 + +spring: + application: + name: order-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # Seata 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + order-service-group: default + # Seata 注册中心配置项,对应 RegistryProperties 类 + registry: + type: nacos # 注册中心类型,默认为 file + nacos: + cluster: default # 使用的 Seata 分组 + namespace: # Nacos 命名空间 + serverAddr: localhost # Nacos 服务地址 diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/pom.xml b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/pom.xml new file mode 100644 index 000000000..f97b6aae2 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/pom.xml @@ -0,0 +1,100 @@ + + + + labx-17-sc-seata-at-feign-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sc-seata-at-feign-demo-product-service + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + com.alibaba.cloud + spring-cloud-alibaba-seata + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/ProductServiceApplication.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/ProductServiceApplication.java new file mode 100644 index 000000000..ad3352c92 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/ProductServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx17.productservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProductServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(ProductServiceApplication.class, args); + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/controller/ProductController.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/controller/ProductController.java new file mode 100644 index 000000000..861226b1c --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/controller/ProductController.java @@ -0,0 +1,30 @@ +package cn.iocoder.springcloud.labx17.productservice.controller; + +import cn.iocoder.springcloud.labx17.productservice.dto.ProductReduceStockDTO; +import cn.iocoder.springcloud.labx17.productservice.service.ProductService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/product") +public class ProductController { + + private Logger logger = LoggerFactory.getLogger(ProductController.class); + + @Autowired + private ProductService productService; + + @PostMapping("/reduce-stock") + public void reduceStock(@RequestBody ProductReduceStockDTO productReduceStockDTO) + throws Exception { + logger.info("[reduceStock] 收到减少库存请求, 商品:{}, 价格:{}", productReduceStockDTO.getProductId(), + productReduceStockDTO.getAmount()); + productService.reduceStock(productReduceStockDTO.getProductId(), productReduceStockDTO.getAmount()); + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/dao/ProductDao.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/dao/ProductDao.java new file mode 100644 index 000000000..cdc6f88dc --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/dao/ProductDao.java @@ -0,0 +1,33 @@ +package cn.iocoder.springcloud.labx17.productservice.dao; + + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface ProductDao { + + /** + * 获取库存 + * + * @param productId 商品编号 + * @return 库存 + */ + @Select("SELECT stock FROM product WHERE id = #{productId}") + Integer getStock(@Param("productId") Long productId); + + /** + * 扣减库存 + * + * @param productId 商品编号 + * @param amount 扣减数量 + * @return 影响记录行数 + */ + @Update("UPDATE product SET stock = stock - #{amount} WHERE id = #{productId} AND stock >= #{amount}") + int reduceStock(@Param("productId") Long productId, @Param("amount") Integer amount); + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/dto/ProductReduceStockDTO.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/dto/ProductReduceStockDTO.java new file mode 100644 index 000000000..7ac7538d1 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/dto/ProductReduceStockDTO.java @@ -0,0 +1,35 @@ +package cn.iocoder.springcloud.labx17.productservice.dto; + +/** + * 商品减少库存 DTO + */ +public class ProductReduceStockDTO { + + /** + * 商品编号 + */ + private Long productId; + /** + * 数量 + */ + private Integer amount; + + public Long getProductId() { + return productId; + } + + public ProductReduceStockDTO setProductId(Long productId) { + this.productId = productId; + return this; + } + + public Integer getAmount() { + return amount; + } + + public ProductReduceStockDTO setAmount(Integer amount) { + this.amount = amount; + return this; + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/service/ProductService.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/service/ProductService.java new file mode 100644 index 000000000..006ec6189 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/service/ProductService.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloud.labx17.productservice.service; + +/** + * 商品 Service + */ +public interface ProductService { + + /** + * 扣减库存 + * + * @param productId 商品 ID + * @param amount 扣减数量 + * @throws Exception 扣减失败时抛出异常 + */ + void reduceStock(Long productId, Integer amount) throws Exception; + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/service/impl/ProductServiceImpl.java b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/service/impl/ProductServiceImpl.java new file mode 100644 index 000000000..876a37d2f --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/java/cn/iocoder/springcloud/labx17/productservice/service/impl/ProductServiceImpl.java @@ -0,0 +1,49 @@ +package cn.iocoder.springcloud.labx17.productservice.service.impl; + +import cn.iocoder.springcloud.labx17.productservice.dao.ProductDao; +import cn.iocoder.springcloud.labx17.productservice.service.ProductService; +import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class ProductServiceImpl implements ProductService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ProductDao productDao; + + @Override + @Transactional // 开启新事物 + public void reduceStock(Long productId, Integer amount) throws Exception { + logger.info("[reduceStock] 当前 XID: {}", RootContext.getXID()); + + // 检查库存 + checkStock(productId, amount); + + logger.info("[reduceStock] 开始扣减 {} 库存", productId); + // 扣减库存 + int updateCount = productDao.reduceStock(productId, amount); + // 扣除成功 + if (updateCount == 0) { + logger.warn("[reduceStock] 扣除 {} 库存失败", productId); + throw new Exception("库存不足"); + } + // 扣除失败 + logger.info("[reduceStock] 扣除 {} 库存成功", productId); + } + + private void checkStock(Long productId, Integer requiredAmount) throws Exception { + logger.info("[checkStock] 检查 {} 库存", productId); + Integer stock = productDao.getStock(productId); + if (stock < requiredAmount) { + logger.warn("[checkStock] {} 库存不足,当前库存: {}", productId, stock); + throw new Exception("库存不足"); + } + } + +} diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/resources/application-file.yaml b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/resources/application-file.yaml new file mode 100644 index 000000000..f720ad299 --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/resources/application-file.yaml @@ -0,0 +1,31 @@ +server: + port: 8082 + +spring: + application: + name: product-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + product-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/resources/application.yaml b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/resources/application.yaml new file mode 100644 index 000000000..2474002cb --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/labx-17-sc-seata-at-feign-demo-product-service/src/main/resources/application.yaml @@ -0,0 +1,35 @@ +server: + port: 8082 + +spring: + application: + name: product-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # Seata 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + product-service-group: default + # Seata 注册中心配置项,对应 RegistryProperties 类 + registry: + type: nacos # 注册中心类型,默认为 file + nacos: + cluster: default # 使用的 Seata 分组 + namespace: # Nacos 命名空间 + serverAddr: localhost # Nacos 服务地址 diff --git a/labx-17/labx-17-sc-seata-at-feign-demo/pom.xml b/labx-17/labx-17-sc-seata-at-feign-demo/pom.xml new file mode 100644 index 000000000..13f23290c --- /dev/null +++ b/labx-17/labx-17-sc-seata-at-feign-demo/pom.xml @@ -0,0 +1,20 @@ + + + + labx-17 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sc-seata-at-feign-demo + + + labx-17-sc-seata-at-feign-demo-account-service + labx-17-sc-seata-at-feign-demo-product-service + labx-17-sc-seata-at-feign-demo-order-service + + + diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/data.sql b/labx-17/labx-17-sca-seata-at-dubbo-demo/data.sql new file mode 100644 index 000000000..3b0ce0828 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/data.sql @@ -0,0 +1,82 @@ +# Order +DROP DATABASE IF EXISTS seata_order; +CREATE DATABASE seata_order; + +CREATE TABLE seata_order.orders +( + id INT(11) NOT NULL AUTO_INCREMENT, + user_id INT(11) DEFAULT NULL, + product_id INT(11) DEFAULT NULL, + pay_amount DECIMAL(10, 0) DEFAULT NULL, + add_time DATETIME DEFAULT CURRENT_TIMESTAMP, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +CREATE TABLE seata_order.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +# Product +DROP DATABASE IF EXISTS seata_product; +CREATE DATABASE seata_product; + +CREATE TABLE seata_product.product +( + id INT(11) NOT NULL AUTO_INCREMENT, + stock INT(11) DEFAULT NULL, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; +INSERT INTO seata_product.product (id, stock) VALUES (1, 10); # 插入一条产品的库存 + +CREATE TABLE seata_product.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +# Account +DROP DATABASE IF EXISTS seata_account; +CREATE DATABASE seata_account; + +CREATE TABLE seata_account.account +( + id INT(11) NOT NULL AUTO_INCREMENT, + balance DOUBLE DEFAULT NULL, + last_update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; + +CREATE TABLE seata_account.undo_log +( + id BIGINT(20) NOT NULL AUTO_INCREMENT, + branch_id BIGINT(20) NOT NULL, + xid VARCHAR(100) NOT NULL, + context VARCHAR(128) NOT NULL, + rollback_info LONGBLOB NOT NULL, + log_status INT(11) NOT NULL, + log_created DATETIME NOT NULL, + log_modified DATETIME NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY ux_undo_log (xid, branch_id) +) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8; +INSERT INTO seata_account.account (id, balance) VALUES (1, 10); diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service-api/pom.xml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service-api/pom.xml new file mode 100644 index 000000000..75b203756 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service-api/pom.xml @@ -0,0 +1,14 @@ + + + + labx-17-sca-seata-at-dubbo-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sca-seata-at-dubbo-demo-account-service-api + + diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service-api/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/api/AccountService.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service-api/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/api/AccountService.java new file mode 100644 index 000000000..b4f8b2295 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service-api/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/api/AccountService.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloudalibaba.labx17.accountservice.api; + +/** + * 账户 Service + */ +public interface AccountService { + + /** + * 扣除余额 + * + * @param userId 用户编号 + * @param price 扣减金额 + * @throws Exception 失败时抛出异常 + */ + void reduceBalance(Long userId, Integer price) throws Exception; + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/pom.xml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/pom.xml new file mode 100644 index 000000000..88413883b --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/pom.xml @@ -0,0 +1,112 @@ + + + + labx-17-sca-seata-at-dubbo-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sca-seata-at-dubbo-demo-account-service + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + cn.iocoder.springboot.labs + labx-17-sca-seata-at-dubbo-demo-account-service-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + com.alibaba.cloud + spring-cloud-alibaba-seata + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/AccountServiceApplication.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/AccountServiceApplication.java new file mode 100644 index 000000000..3e86cc58e --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/AccountServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx17.accountservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AccountServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(AccountServiceApplication.class, args); + } + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/dao/AccountDao.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/dao/AccountDao.java new file mode 100644 index 000000000..0b3081c69 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/dao/AccountDao.java @@ -0,0 +1,32 @@ +package cn.iocoder.springcloudalibaba.labx17.accountservice.dao; + + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface AccountDao { + + /** + * 获取账户余额 + * + * @param userId 用户 ID + * @return 账户余额 + */ + @Select("SELECT balance FROM account WHERE id = #{userId}") + Integer getBalance(@Param("userId") Long userId); + + /** + * 扣减余额 + * + * @param price 需要扣减的数目 + * @return 影响记录行数 + */ + @Update("UPDATE account SET balance = balance - #{price} WHERE id = 1 AND balance >= ${price}") + int reduceBalance(@Param("price") Integer price); + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/service/AccountServiceImpl.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/service/AccountServiceImpl.java new file mode 100644 index 000000000..2f5c3cbf9 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/accountservice/service/AccountServiceImpl.java @@ -0,0 +1,47 @@ +package cn.iocoder.springcloudalibaba.labx17.accountservice.service; + +import cn.iocoder.springcloudalibaba.labx17.accountservice.api.AccountService; +import cn.iocoder.springcloudalibaba.labx17.accountservice.dao.AccountDao; +import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@org.apache.dubbo.config.annotation.Service +public class AccountServiceImpl implements AccountService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private AccountDao accountDao; + + @Override + @Transactional // 开启新事物 + public void reduceBalance(Long userId, Integer price) throws Exception { + logger.info("[reduceBalance] 当前 XID: {}", RootContext.getXID()); + + // 检查余额 + checkBalance(userId, price); + + logger.info("[reduceBalance] 开始扣减用户 {} 余额", userId); + // 扣除余额 + int updateCount = accountDao.reduceBalance(price); + // 扣除成功 + if (updateCount == 0) { + logger.warn("[reduceBalance] 扣除用户 {} 余额失败", userId); + throw new Exception("余额不足"); + } + logger.info("[reduceBalance] 扣除用户 {} 余额成功", userId); + } + + private void checkBalance(Long userId, Integer price) throws Exception { + logger.info("[checkBalance] 检查用户 {} 余额", userId); + Integer balance = accountDao.getBalance(userId); + if (balance < price) { + logger.warn("[checkBalance] 用户 {} 余额不足,当前余额:{}", userId, balance); + throw new Exception("余额不足"); + } + } + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/resources/application-file.yaml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/resources/application-file.yaml new file mode 100644 index 000000000..90b8d55ff --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/resources/application-file.yaml @@ -0,0 +1,44 @@ +spring: + application: + name: account-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_account?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springcloudalibaba.labx17.accountservice.service + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + account-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/resources/application.yaml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/resources/application.yaml new file mode 100644 index 000000000..5bf1b266b --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-account-service/src/main/resources/application.yaml @@ -0,0 +1,48 @@ +spring: + application: + name: account-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_account?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springcloudalibaba.labx17.accountservice.service + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # Seata 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + account-service-group: default + # Seata 注册中心配置项,对应 RegistryProperties 类 + registry: + type: nacos # 注册中心类型,默认为 file + nacos: + cluster: default # 使用的 Seata 分组 + namespace: # Nacos 命名空间 + serverAddr: localhost # Nacos 服务地址 diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service-api/pom.xml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service-api/pom.xml new file mode 100644 index 000000000..b7c4c049f --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service-api/pom.xml @@ -0,0 +1,14 @@ + + + + labx-17-sca-seata-at-dubbo-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sca-seata-at-dubbo-demo-order-service-api + + diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service-api/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/api/OrderService.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service-api/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/api/OrderService.java new file mode 100644 index 000000000..cb82ece6b --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service-api/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/api/OrderService.java @@ -0,0 +1,19 @@ +package cn.iocoder.springcloudalibaba.labx17.orderservice.api; + +/** + * 订单 Service + */ +public interface OrderService { + + /** + * 创建订单 + * + * @param userId 用户编号 + * @param productId 产品编号 + * @param price 价格 + * @return 订单编号 + * @throws Exception 创建订单失败,抛出异常 + */ + Integer createOrder(Long userId, Long productId, Integer price) throws Exception; + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/pom.xml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/pom.xml new file mode 100644 index 000000000..07116e241 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/pom.xml @@ -0,0 +1,122 @@ + + + + labx-17-sca-seata-at-dubbo-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sca-seata-at-dubbo-demo-order-service + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + cn.iocoder.springboot.labs + labx-17-sca-seata-at-dubbo-demo-order-service-api + 1.0-SNAPSHOT + + + cn.iocoder.springboot.labs + labx-17-sca-seata-at-dubbo-demo-account-service-api + 1.0-SNAPSHOT + + + cn.iocoder.springboot.labs + labx-17-sca-seata-at-dubbo-demo-product-service-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + com.alibaba.cloud + spring-cloud-alibaba-seata + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/OrderServiceApplication.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/OrderServiceApplication.java new file mode 100644 index 000000000..4cc8a7fc4 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/OrderServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx17.orderservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class OrderServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(OrderServiceApplication.class, args); + } + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/controller/OrderController.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/controller/OrderController.java new file mode 100644 index 000000000..578f29944 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/controller/OrderController.java @@ -0,0 +1,29 @@ +package cn.iocoder.springcloudalibaba.labx17.orderservice.controller; + +import cn.iocoder.springcloudalibaba.labx17.orderservice.api.OrderService; +import org.apache.dubbo.config.annotation.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/order") +public class OrderController { + + private Logger logger = LoggerFactory.getLogger(OrderController.class); + + @Reference + private OrderService orderService; + + @PostMapping("/create") + public Integer createOrder(@RequestParam("userId") Long userId, + @RequestParam("productId") Long productId, + @RequestParam("price") Integer price) throws Exception { + logger.info("[createOrder] 收到下单请求,用户:{}, 商品:{}, 价格:{}", userId, productId, price); + return orderService.createOrder(userId, productId, price); + } + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/dao/OrderDao.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/dao/OrderDao.java new file mode 100644 index 000000000..a0b5cbd81 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/dao/OrderDao.java @@ -0,0 +1,23 @@ +package cn.iocoder.springcloudalibaba.labx17.orderservice.dao; + +import cn.iocoder.springcloudalibaba.labx17.orderservice.entity.OrderDO; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Options; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface OrderDao { + + /** + * 插入订单记录 + * + * @param order 订单 + * @return 影响记录数量 + */ + @Insert("INSERT INTO orders (user_id, product_id, pay_amount) VALUES (#{userId}, #{productId}, #{payAmount})") + @Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id") + int saveOrder(OrderDO order); + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/entity/OrderDO.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/entity/OrderDO.java new file mode 100644 index 000000000..590290ed7 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/entity/OrderDO.java @@ -0,0 +1,56 @@ +package cn.iocoder.springcloudalibaba.labx17.orderservice.entity; + +/** + * 订单实体 + */ +public class OrderDO { + + /** 订单编号 **/ + private Integer id; + + /** 用户编号 **/ + private Long userId; + + /** 产品编号 **/ + private Long productId; + + /** 支付金额 **/ + private Integer payAmount; + + public Integer getId() { + return id; + } + + public OrderDO setId(Integer id) { + this.id = id; + return this; + } + + public Long getUserId() { + return userId; + } + + public OrderDO setUserId(Long userId) { + this.userId = userId; + return this; + } + + public Long getProductId() { + return productId; + } + + public OrderDO setProductId(Long productId) { + this.productId = productId; + return this; + } + + public Integer getPayAmount() { + return payAmount; + } + + public OrderDO setPayAmount(Integer payAmount) { + this.payAmount = payAmount; + return this; + } + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/service/OrderServiceImpl.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/service/OrderServiceImpl.java new file mode 100644 index 000000000..d91a17902 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/orderservice/service/OrderServiceImpl.java @@ -0,0 +1,50 @@ +package cn.iocoder.springcloudalibaba.labx17.orderservice.service; + +import cn.iocoder.springcloudalibaba.labx17.accountservice.api.AccountService; +import cn.iocoder.springcloudalibaba.labx17.orderservice.api.OrderService; +import cn.iocoder.springcloudalibaba.labx17.orderservice.dao.OrderDao; +import cn.iocoder.springcloudalibaba.labx17.orderservice.entity.OrderDO; +import cn.iocoder.springcloudalibaba.labx17.producctservice.api.ProductService; +import io.seata.core.context.RootContext; +import io.seata.spring.annotation.GlobalTransactional; +import org.apache.dubbo.config.annotation.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +@org.apache.dubbo.config.annotation.Service +public class OrderServiceImpl implements OrderService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private OrderDao orderDao; + + @Reference + private AccountService accountService; + @Reference + private ProductService productService; + + @Override + @GlobalTransactional + public Integer createOrder(Long userId, Long productId, Integer price) throws Exception { + Integer amount = 1; // 购买数量,暂时设置为 1。 + + logger.info("[createOrder] 当前 XID: {}", RootContext.getXID()); + + // 扣减库存 + productService.reduceStock(productId, amount); + + // 扣减余额 + accountService.reduceBalance(userId, price); + + // 保存订单 + OrderDO order = new OrderDO().setUserId(userId).setProductId(productId).setPayAmount(amount * price); + orderDao.saveOrder(order); + logger.info("[createOrder] 保存订单: {}", order.getId()); + + // 返回订单编号 + return order.getId(); + } + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/resources/application-file.yaml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/resources/application-file.yaml new file mode 100644 index 000000000..719a99566 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/resources/application-file.yaml @@ -0,0 +1,47 @@ +server: + port: 8081 # 端口 + +spring: + application: + name: order-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springcloudalibaba.labx17.orderservice.service + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: account-service, product-service # 设置订阅的应用列表,默认为 * 订阅所有应用。 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + order-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/resources/application.yaml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/resources/application.yaml new file mode 100644 index 000000000..8bc338d08 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-order-service/src/main/resources/application.yaml @@ -0,0 +1,51 @@ +server: + port: 8081 # 端口 + +spring: + application: + name: order-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_order?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springcloudalibaba.labx17.orderservice.service + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: account-service, product-service # 设置订阅的应用列表,默认为 * 订阅所有应用。 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # Seata 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + order-service-group: default + # Seata 注册中心配置项,对应 RegistryProperties 类 + registry: + type: nacos # 注册中心类型,默认为 file + nacos: + cluster: default # 使用的 Seata 分组 + namespace: # Nacos 命名空间 + serverAddr: localhost # Nacos 服务地址 diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service-api/pom.xml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service-api/pom.xml new file mode 100644 index 000000000..61a9e55c3 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service-api/pom.xml @@ -0,0 +1,14 @@ + + + + labx-17-sca-seata-at-dubbo-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sca-seata-at-dubbo-demo-product-service-api + + diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service-api/src/main/java/cn/iocoder/springcloudalibaba/labx17/producctservice/api/ProductService.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service-api/src/main/java/cn/iocoder/springcloudalibaba/labx17/producctservice/api/ProductService.java new file mode 100644 index 000000000..e3eb4a3b6 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service-api/src/main/java/cn/iocoder/springcloudalibaba/labx17/producctservice/api/ProductService.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloudalibaba.labx17.producctservice.api; + +/** + * 商品 Service + */ +public interface ProductService { + + /** + * 扣减库存 + * + * @param productId 商品 ID + * @param amount 扣减数量 + * @throws Exception 扣减失败时抛出异常 + */ + void reduceStock(Long productId, Integer amount) throws Exception; + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/pom.xml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/pom.xml new file mode 100644 index 000000000..711a7edf2 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/pom.xml @@ -0,0 +1,112 @@ + + + + labx-17-sca-seata-at-dubbo-demo + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sca-seata-at-dubbo-demo-product-service + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + cn.iocoder.springboot.labs + labx-17-sca-seata-at-dubbo-demo-product-service-api + 1.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + 5.1.48 + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.2 + + + + + com.alibaba.cloud + spring-cloud-alibaba-seata + + + io.seata + seata-spring-boot-starter + 1.1.0 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-dubbo + + + + diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/productservice/ProductServiceApplication.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/productservice/ProductServiceApplication.java new file mode 100644 index 000000000..cfaabeab2 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/productservice/ProductServiceApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloudalibaba.labx17.productservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProductServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(ProductServiceApplication.class, args); + } + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/productservice/dao/ProductDao.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/productservice/dao/ProductDao.java new file mode 100644 index 000000000..935fd5eac --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/productservice/dao/ProductDao.java @@ -0,0 +1,33 @@ +package cn.iocoder.springcloudalibaba.labx17.productservice.dao; + + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface ProductDao { + + /** + * 获取库存 + * + * @param productId 商品编号 + * @return 库存 + */ + @Select("SELECT stock FROM product WHERE id = #{productId}") + Integer getStock(@Param("productId") Long productId); + + /** + * 扣减库存 + * + * @param productId 商品编号 + * @param amount 扣减数量 + * @return 影响记录行数 + */ + @Update("UPDATE product SET stock = stock - #{amount} WHERE id = #{productId} AND stock >= #{amount}") + int reduceStock(@Param("productId") Long productId, @Param("amount") Integer amount); + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/productservice/service/ProductServiceImpl.java b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/productservice/service/ProductServiceImpl.java new file mode 100644 index 000000000..f301f6cc0 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/java/cn/iocoder/springcloudalibaba/labx17/productservice/service/ProductServiceImpl.java @@ -0,0 +1,48 @@ +package cn.iocoder.springcloudalibaba.labx17.productservice.service; + +import cn.iocoder.springcloudalibaba.labx17.producctservice.api.ProductService; +import cn.iocoder.springcloudalibaba.labx17.productservice.dao.ProductDao; +import io.seata.core.context.RootContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +@org.apache.dubbo.config.annotation.Service +public class ProductServiceImpl implements ProductService { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ProductDao productDao; + + @Override + @Transactional // 开启新事物 + public void reduceStock(Long productId, Integer amount) throws Exception { + logger.info("[reduceStock] 当前 XID: {}", RootContext.getXID()); + + // 检查库存 + checkStock(productId, amount); + + logger.info("[reduceStock] 开始扣减 {} 库存", productId); + // 扣减库存 + int updateCount = productDao.reduceStock(productId, amount); + // 扣除成功 + if (updateCount == 0) { + logger.warn("[reduceStock] 扣除 {} 库存失败", productId); + throw new Exception("库存不足"); + } + // 扣除失败 + logger.info("[reduceStock] 扣除 {} 库存成功", productId); + } + + private void checkStock(Long productId, Integer requiredAmount) throws Exception { + logger.info("[checkStock] 检查 {} 库存", productId); + Integer stock = productDao.getStock(productId); + if (stock < requiredAmount) { + logger.warn("[checkStock] {} 库存不足,当前库存: {}", productId, stock); + throw new Exception("库存不足"); + } + } + +} diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/resources/application-file.yaml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/resources/application-file.yaml new file mode 100644 index 000000000..01de81712 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/resources/application-file.yaml @@ -0,0 +1,44 @@ +spring: + application: + name: product-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springcloudalibaba.labx17.productservice.service + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + product-service-group: default + # 分组和 Seata 服务的映射 + grouplist: + default: 127.0.0.1:8091 diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/resources/application.yaml b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/resources/application.yaml new file mode 100644 index 000000000..b420187f9 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/labx-17-sca-seata-at-dubbo-demo-product-service/src/main/resources/application.yaml @@ -0,0 +1,48 @@ +spring: + application: + name: product-service + + datasource: + url: jdbc:mysql://127.0.0.1:3306/seata_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: + + cloud: + # Nacos 作为注册中心的配置项 + nacos: + discovery: + server-addr: 127.0.0.1:8848 + +# dubbo 配置项,对应 DubboConfigurationProperties 配置类 +dubbo: + # Dubbo 服务注册中心配置,对应 RegistryConfig 类 + registry: + address: spring-cloud://127.0.0.1:8848 # 指定 Dubbo 服务注册中心的地址 + # Dubbo 服务提供者协议配置 + protocol: + port: -1 # 协议端口。使用 -1 表示随机端口。 + name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档 + # 配置扫描 Dubbo 自定义的 @Service 注解,暴露成 Dubbo 服务提供者 + scan: + base-packages: cn.iocoder.springcloudalibaba.labx17.productservice.service + # Spring Cloud Alibaba Dubbo 专属配置项,对应 DubboCloudProperties 类 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用。 + +# Seata 配置项,对应 SeataProperties 类 +seata: + application-id: ${spring.application.name} # Seata 应用编号,默认为 ${spring.application.name} + tx-service-group: ${spring.application.name}-group # Seata 事务组编号,用于 TC 集群名 + # Seata 服务配置项,对应 ServiceProperties 类 + service: + # 虚拟组和分组的映射 + vgroup-mapping: + product-service-group: default + # Seata 注册中心配置项,对应 RegistryProperties 类 + registry: + type: nacos # 注册中心类型,默认为 file + nacos: + cluster: default # 使用的 Seata 分组 + namespace: # Nacos 命名空间 + serverAddr: localhost # Nacos 服务地址 diff --git a/labx-17/labx-17-sca-seata-at-dubbo-demo/pom.xml b/labx-17/labx-17-sca-seata-at-dubbo-demo/pom.xml new file mode 100644 index 000000000..591dede92 --- /dev/null +++ b/labx-17/labx-17-sca-seata-at-dubbo-demo/pom.xml @@ -0,0 +1,23 @@ + + + + labx-17 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17-sca-seata-at-dubbo-demo + + + labx-17-sca-seata-at-dubbo-demo-account-service-api + labx-17-sca-seata-at-dubbo-demo-account-service + labx-17-sca-seata-at-dubbo-demo-product-service-api + labx-17-sca-seata-at-dubbo-demo-product-service + labx-17-sca-seata-at-dubbo-demo-order-service-api + labx-17-sca-seata-at-dubbo-demo-order-service + + + diff --git a/labx-17/pom.xml b/labx-17/pom.xml new file mode 100644 index 000000000..ed0e021cb --- /dev/null +++ b/labx-17/pom.xml @@ -0,0 +1,20 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-17 + pom + + labx-17-sca-seata-at-dubbo-demo + labx-17-sc-seata-at-feign-demo + + + + diff --git "a/labx-17/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \345\210\206\345\270\203\345\274\217\344\272\213\345\212\241 Seata \345\205\245\351\227\250\343\200\213.md" "b/labx-17/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \345\210\206\345\270\203\345\274\217\344\272\213\345\212\241 Seata \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..8921469af --- /dev/null +++ "b/labx-17/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \345\210\206\345\270\203\345\274\217\344\272\213\345\212\241 Seata \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/pom.xml b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/pom.xml new file mode 100644 index 000000000..bd3a1ebbd --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/pom.xml @@ -0,0 +1,64 @@ + + + + labx-18 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-18-sc-bus-rabbitmq-demo-listener-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/ListenerDemoApplication.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/ListenerDemoApplication.java new file mode 100644 index 000000000..c50fa8648 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/ListenerDemoApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx18.listenerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan; + +@SpringBootApplication +@RemoteApplicationEventScan +public class ListenerDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(ListenerDemoApplication.class, args); + } + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/event/UserRegisterEvent.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..7e12e67dd --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx18.listenerdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/listener/UserRegisterListener.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/listener/UserRegisterListener.java new file mode 100644 index 000000000..a16a5e41c --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/listener/UserRegisterListener.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx18.listenerdemo.listener; + +import cn.iocoder.springcloud.labx18.listenerdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +/** + * 用户注册事件的监听器 + */ +@Component +public class UserRegisterListener implements ApplicationListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + public void onApplicationEvent(UserRegisterEvent event) { + logger.info("[onApplicationEvent][监听到用户({}) 注册]", event.getUsername()); + } + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/resources/application.yml b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..05743d701 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener-actuator/src/main/resources/application.yml @@ -0,0 +1,20 @@ +spring: + application: + name: listener-demo + + # RabbitMQ 相关配置项 + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + +server: + port: 18080 # 随机端口,方便启动多个消费者 + +management: + endpoints: + # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类 + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/pom.xml b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/pom.xml new file mode 100644 index 000000000..479569ff3 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/pom.xml @@ -0,0 +1,58 @@ + + + + labx-18 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-18-sc-bus-rabbitmq-demo-listener + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + + diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/ListenerDemoApplication.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/ListenerDemoApplication.java new file mode 100644 index 000000000..c50fa8648 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/ListenerDemoApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx18.listenerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan; + +@SpringBootApplication +@RemoteApplicationEventScan +public class ListenerDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(ListenerDemoApplication.class, args); + } + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/event/UserRegisterEvent.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..7e12e67dd --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx18.listenerdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/listener/UserRegisterListener.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/listener/UserRegisterListener.java new file mode 100644 index 000000000..a16a5e41c --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/java/cn/iocoder/springcloud/labx18/listenerdemo/listener/UserRegisterListener.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx18.listenerdemo.listener; + +import cn.iocoder.springcloud.labx18.listenerdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +/** + * 用户注册事件的监听器 + */ +@Component +public class UserRegisterListener implements ApplicationListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + public void onApplicationEvent(UserRegisterEvent event) { + logger.info("[onApplicationEvent][监听到用户({}) 注册]", event.getUsername()); + } + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/resources/application.yml b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/resources/application.yml new file mode 100644 index 000000000..8f9f30849 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-listener/src/main/resources/application.yml @@ -0,0 +1,13 @@ +spring: + application: + name: listener-demo + + # RabbitMQ 相关配置项 + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/pom.xml b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/pom.xml new file mode 100644 index 000000000..fc302b7a9 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/pom.xml @@ -0,0 +1,64 @@ + + + + labx-18 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-18-sc-bus-rabbitmq-demo-publisher-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/PublisherDemoApplication.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/PublisherDemoApplication.java new file mode 100644 index 000000000..91e100cbd --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/PublisherDemoApplication.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloud.labx18.publisherdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +//@RemoteApplicationEventScan +public class PublisherDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(PublisherDemoApplication.class, args); + } + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/controller/DemoController.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/controller/DemoController.java new file mode 100644 index 000000000..aae2b09a5 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/controller/DemoController.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx18.publisherdemo.controller; + +import cn.iocoder.springcloud.labx18.publisherdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.bus.ServiceMatcher; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + + @Autowired + private ServiceMatcher busServiceMatcher; + + @GetMapping("/register") + public String register(String username) { + // ... 执行注册逻辑 + logger.info("[register][执行用户({}) 的注册逻辑]", username); + + // ... 发布 + applicationEventPublisher.publishEvent(new UserRegisterEvent(this, busServiceMatcher.getServiceId(), + null, username)); + return "success"; + } + + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/event/UserRegisterEvent.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..0e17f2827 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx18.publisherdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/resources/application.yml b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..1ea2852db --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher-actuator/src/main/resources/application.yml @@ -0,0 +1,17 @@ +spring: + application: + name: publisher-demo + + # RabbitMQ 相关配置项 + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + +management: + endpoints: + # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类 + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/pom.xml b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/pom.xml new file mode 100644 index 000000000..108201819 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/pom.xml @@ -0,0 +1,58 @@ + + + + labx-18 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-18-sc-bus-rabbitmq-demo-publisher + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + + + diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/PublisherDemoApplication.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/PublisherDemoApplication.java new file mode 100644 index 000000000..91e100cbd --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/PublisherDemoApplication.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloud.labx18.publisherdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +//@RemoteApplicationEventScan +public class PublisherDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(PublisherDemoApplication.class, args); + } + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/controller/DemoController.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/controller/DemoController.java new file mode 100644 index 000000000..aae2b09a5 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/controller/DemoController.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx18.publisherdemo.controller; + +import cn.iocoder.springcloud.labx18.publisherdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.bus.ServiceMatcher; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + + @Autowired + private ServiceMatcher busServiceMatcher; + + @GetMapping("/register") + public String register(String username) { + // ... 执行注册逻辑 + logger.info("[register][执行用户({}) 的注册逻辑]", username); + + // ... 发布 + applicationEventPublisher.publishEvent(new UserRegisterEvent(this, busServiceMatcher.getServiceId(), + null, username)); + return "success"; + } + + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/event/UserRegisterEvent.java b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..0e17f2827 --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/java/cn/iocoder/springcloud/labx18/publisherdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx18.publisherdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/resources/application.yml b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/resources/application.yml new file mode 100644 index 000000000..40308580c --- /dev/null +++ b/labx-18/labx-18-sc-bus-rabbitmq-demo-publisher/src/main/resources/application.yml @@ -0,0 +1,16 @@ +spring: + application: + name: publisher-demo + + # RabbitMQ 相关配置项 + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + + # Bus 相关配置项,对应 BusProperties + cloud: + bus: + enabled: true # 是否开启,默认为 true + destination: springCloudBus # 目标消息队列,默认为 springCloudBus diff --git a/labx-18/pom.xml b/labx-18/pom.xml new file mode 100644 index 000000000..836d2b282 --- /dev/null +++ b/labx-18/pom.xml @@ -0,0 +1,23 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-18 + pom + + labx-18-sc-bus-rabbitmq-demo-publisher + labx-18-sc-bus-rabbitmq-demo-listener + + labx-18-sc-bus-rabbitmq-demo-listener-actuator + labx-18-sc-bus-rabbitmq-demo-publisher-actuator + + + + diff --git "a/labx-18/\343\200\212\350\212\213\351\201\223 Spring Cloud \344\272\213\344\273\266\346\200\273\347\272\277 RabbitMQ \345\205\245\351\227\250\343\200\213.md" "b/labx-18/\343\200\212\350\212\213\351\201\223 Spring Cloud \344\272\213\344\273\266\346\200\273\347\272\277 RabbitMQ \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..8cb66e924 --- /dev/null +++ "b/labx-18/\343\200\212\350\212\213\351\201\223 Spring Cloud \344\272\213\344\273\266\346\200\273\347\272\277 RabbitMQ \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/pom.xml b/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/pom.xml new file mode 100644 index 000000000..653b242f0 --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/pom.xml @@ -0,0 +1,64 @@ + + + + labx-19 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-19-sc-bus-kafka-demo-listener-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-bus-kafka + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/ListenerDemoApplication.java b/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/ListenerDemoApplication.java new file mode 100644 index 000000000..f5022908b --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/ListenerDemoApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx19.listenerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan; + +@SpringBootApplication +@RemoteApplicationEventScan +public class ListenerDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(ListenerDemoApplication.class, args); + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/event/UserRegisterEvent.java b/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..0967036fb --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx19.listenerdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/listener/UserRegisterListener.java b/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/listener/UserRegisterListener.java new file mode 100644 index 000000000..318e0eace --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/listener/UserRegisterListener.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx19.listenerdemo.listener; + +import cn.iocoder.springcloud.labx19.listenerdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +/** + * 用户注册事件的监听器 + */ +@Component +public class UserRegisterListener implements ApplicationListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + public void onApplicationEvent(UserRegisterEvent event) { + logger.info("[onApplicationEvent][监听到用户({}) 注册]", event.getUsername()); + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/resources/application.yml b/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..9077fbeba --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-listener-actuator/src/main/resources/application.yml @@ -0,0 +1,17 @@ +spring: + application: + name: listener-demo + + # Kafka 配置项,对应 KafkaProperties 配置类 + kafka: + bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +server: + port: 18080 # 随机端口,方便启动多个消费者 + +management: + endpoints: + # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类 + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/labx-19/labx-19-sc-bus-kafka-demo-listener/pom.xml b/labx-19/labx-19-sc-bus-kafka-demo-listener/pom.xml new file mode 100644 index 000000000..59182d4de --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-listener/pom.xml @@ -0,0 +1,58 @@ + + + + labx-19 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-19-sc-bus-kafka-demo-listener + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-bus-kafka + + + + diff --git a/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/ListenerDemoApplication.java b/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/ListenerDemoApplication.java new file mode 100644 index 000000000..f5022908b --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/ListenerDemoApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx19.listenerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan; + +@SpringBootApplication +@RemoteApplicationEventScan +public class ListenerDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(ListenerDemoApplication.class, args); + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/event/UserRegisterEvent.java b/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..0967036fb --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx19.listenerdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/listener/UserRegisterListener.java b/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/listener/UserRegisterListener.java new file mode 100644 index 000000000..318e0eace --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/java/cn/iocoder/springcloud/labx19/listenerdemo/listener/UserRegisterListener.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx19.listenerdemo.listener; + +import cn.iocoder.springcloud.labx19.listenerdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +/** + * 用户注册事件的监听器 + */ +@Component +public class UserRegisterListener implements ApplicationListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + public void onApplicationEvent(UserRegisterEvent event) { + logger.info("[onApplicationEvent][监听到用户({}) 注册]", event.getUsername()); + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/resources/application.yml b/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/resources/application.yml new file mode 100644 index 000000000..e7f00583c --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-listener/src/main/resources/application.yml @@ -0,0 +1,10 @@ +spring: + application: + name: listener-demo + + # Kafka 配置项,对应 KafkaProperties 配置类 + kafka: + bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 diff --git a/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/pom.xml b/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/pom.xml new file mode 100644 index 000000000..bedeab16a --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/pom.xml @@ -0,0 +1,64 @@ + + + + labx-19 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-19-sc-bus-kafka-demo-publisher-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-bus-kafka + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/PublisherDemoApplication.java b/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/PublisherDemoApplication.java new file mode 100644 index 000000000..eb78d9f1c --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/PublisherDemoApplication.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloud.labx19.publisherdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +//@RemoteApplicationEventScan +public class PublisherDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(PublisherDemoApplication.class, args); + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/controller/DemoController.java b/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/controller/DemoController.java new file mode 100644 index 000000000..ddcb938fc --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/controller/DemoController.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloud.labx19.publisherdemo.controller; + +import cn.iocoder.springcloud.labx19.publisherdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.bus.ServiceMatcher; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + + @Autowired + private ServiceMatcher busServiceMatcher; + + @GetMapping("/register") + public String register(String username) { + // ... 执行注册逻辑 + logger.info("[register][执行用户({}) 的注册逻辑]", username); + + // ... 发布 + applicationEventPublisher.publishEvent(new UserRegisterEvent(this, busServiceMatcher.getServiceId(), + null, username)); + return "success"; + } + + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/event/UserRegisterEvent.java b/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..4057d1a1a --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx19.publisherdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/resources/application.yml b/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..8cef4a3f1 --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-publisher-actuator/src/main/resources/application.yml @@ -0,0 +1,14 @@ +spring: + application: + name: publisher-demo + + # Kafka 配置项,对应 KafkaProperties 配置类 + kafka: + bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + +management: + endpoints: + # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类 + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/labx-19/labx-19-sc-bus-kafka-demo-publisher/pom.xml b/labx-19/labx-19-sc-bus-kafka-demo-publisher/pom.xml new file mode 100644 index 000000000..9f784874f --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-publisher/pom.xml @@ -0,0 +1,58 @@ + + + + labx-19 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-19-sc-bus-kafka-demo-publisher + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-bus-kafka + + + + diff --git a/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/PublisherDemoApplication.java b/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/PublisherDemoApplication.java new file mode 100644 index 000000000..eb78d9f1c --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/PublisherDemoApplication.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloud.labx19.publisherdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +//@RemoteApplicationEventScan +public class PublisherDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(PublisherDemoApplication.class, args); + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/controller/DemoController.java b/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/controller/DemoController.java new file mode 100644 index 000000000..21148a95f --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/controller/DemoController.java @@ -0,0 +1,36 @@ +package cn.iocoder.springcloud.labx19.publisherdemo.controller; + +import cn.iocoder.springcloud.labx19.publisherdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.bus.ServiceMatcher; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + + @Autowired + private ServiceMatcher busServiceMatcher; + + @GetMapping("/register") + public String register(String username) { + // ... 执行注册逻辑 + logger.info("[register][执行用户({}) 的注册逻辑]", username); + + // ... 发布 + applicationEventPublisher.publishEvent(new UserRegisterEvent(this, busServiceMatcher.getServiceId(), + null, username)); + return "success"; + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/event/UserRegisterEvent.java b/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..4057d1a1a --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/java/cn/iocoder/springcloud/labx19/publisherdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloud.labx19.publisherdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/resources/application.yml b/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/resources/application.yml new file mode 100644 index 000000000..8be46e33d --- /dev/null +++ b/labx-19/labx-19-sc-bus-kafka-demo-publisher/src/main/resources/application.yml @@ -0,0 +1,13 @@ +spring: + application: + name: publisher-demo + + # Kafka 配置项,对应 KafkaProperties 配置类 + kafka: + bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 + + # Bus 相关配置项,对应 BusProperties + cloud: + bus: + enabled: true # 是否开启,默认为 true + destination: springCloudBus # 目标消息队列,默认为 springCloudBus diff --git a/labx-19/labx-19-sc-config-server-git-auto-refresh-by-bus/pom.xml b/labx-19/labx-19-sc-config-server-git-auto-refresh-by-bus/pom.xml new file mode 100644 index 000000000..fc504147d --- /dev/null +++ b/labx-19/labx-19-sc-config-server-git-auto-refresh-by-bus/pom.xml @@ -0,0 +1,70 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-19-sc-config-server-git-auto-refresh-by-bus + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-config-server + + + + + org.springframework.cloud + spring-cloud-starter-bus-kafka + + + + + org.springframework.cloud + spring-cloud-config-monitor + + + + diff --git a/labx-19/labx-19-sc-config-server-git-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/configserverdemo/ConfigServerApplication.java b/labx-19/labx-19-sc-config-server-git-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/configserverdemo/ConfigServerApplication.java new file mode 100644 index 000000000..3ed83bf87 --- /dev/null +++ b/labx-19/labx-19-sc-config-server-git-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/configserverdemo/ConfigServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx19.configserverdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +@SpringBootApplication +@EnableConfigServer +public class ConfigServerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConfigServerApplication.class, args); + } + +} diff --git a/labx-19/labx-19-sc-config-server-git-auto-refresh-by-bus/src/main/resources/application.yml b/labx-19/labx-19-sc-config-server-git-auto-refresh-by-bus/src/main/resources/application.yml new file mode 100644 index 000000000..48e490b20 --- /dev/null +++ b/labx-19/labx-19-sc-config-server-git-auto-refresh-by-bus/src/main/resources/application.yml @@ -0,0 +1,24 @@ +server: + port: 8888 + +spring: + application: + name: demo-config-server + + profiles: + active: git # 使用的 Spring Cloud Config Server 的存储器方案 + # Spring Cloud Config 相关配置项 + cloud: + config: + server: + # Spring Cloud Config Server 的 Git 存储器的配置项,对应 MultipleJGitEnvironmentProperties 类 + git: + uri: https://github.com/YunaiV/demo-config-server.git # Git 仓库地址 + search-paths: / # 读取文件的根地址 + default-label: master # 使用的默认分支,默认为 master + # username: ${CODING_USERNAME} # 账号 + # password: ${CODING_PASSWORD} # 密码 + + # Kafka 配置项,对应 KafkaProperties 配置类 + kafka: + bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 diff --git a/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/pom.xml b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/pom.xml new file mode 100644 index 000000000..e770a7bfa --- /dev/null +++ b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/pom.xml @@ -0,0 +1,64 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-19-sc-config-user-application-auto-refresh-by-bus + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-config + + + + + org.springframework.cloud + spring-cloud-starter-bus-kafka + + + + diff --git a/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/userapplication/UserApplication.java b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/userapplication/UserApplication.java new file mode 100644 index 000000000..6bca4235e --- /dev/null +++ b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/userapplication/UserApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx19.userapplication; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserApplication { + + public static void main(String[] args) { + SpringApplication.run(UserApplication.class, args); + } + +} diff --git a/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/userapplication/config/OrderProperties.java b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/userapplication/config/OrderProperties.java new file mode 100644 index 000000000..f5af4d272 --- /dev/null +++ b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/userapplication/config/OrderProperties.java @@ -0,0 +1,38 @@ +package cn.iocoder.springcloud.labx19.userapplication.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +} diff --git a/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/userapplication/controller/DemoController.java b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/userapplication/controller/DemoController.java new file mode 100644 index 000000000..f18f57ebb --- /dev/null +++ b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx19/userapplication/controller/DemoController.java @@ -0,0 +1,46 @@ +package cn.iocoder.springcloud.labx19.userapplication.controller; + +import cn.iocoder.springcloud.labx19.userapplication.config.OrderProperties; +import org.springframework.beans.factory.annotation.Autowired; +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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/demo") +@RefreshScope +public class DemoController { + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + Map result = new HashMap<>(); + result.put("payTimeoutSeconds", payTimeoutSeconds); + result.put("createFrequencySeconds", createFrequencySeconds); + return result; + } + +} diff --git a/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/resources/application.yml b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/resources/application.yml new file mode 100644 index 000000000..4a0385942 --- /dev/null +++ b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/resources/application.yml @@ -0,0 +1,3 @@ +# Kafka 配置项,对应 KafkaProperties 配置类 +kafka: + bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔 diff --git a/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/resources/bootstrap.yml b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..6ae779eeb --- /dev/null +++ b/labx-19/labx-19-sc-config-user-application-auto-refresh-by-bus/src/main/resources/bootstrap.yml @@ -0,0 +1,9 @@ +spring: + application: + name: user-application + + cloud: + # Spring Cloud Config Client 配置项,对应 ConfigClientProperties 类 + config: + uri: http://127.0.0.1:8888 # Spring Cloud Config Server 的地址 + name: ${spring.application.name} # 读取的配置文件的名字,默认为 ${spring.application.name} diff --git a/labx-19/pom.xml b/labx-19/pom.xml new file mode 100644 index 000000000..d0de5d67b --- /dev/null +++ b/labx-19/pom.xml @@ -0,0 +1,26 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-19 + pom + + labx-19-sc-bus-kafka-demo-publisher + labx-19-sc-bus-kafka-demo-listener + + labx-19-sc-bus-kafka-demo-listener-actuator + labx-19-sc-bus-kafka-demo-publisher-actuator + + labx-19-sc-config-server-git-auto-refresh-by-bus + labx-19-sc-config-user-application-auto-refresh-by-bus + + + + diff --git "a/labx-19/\343\200\212\350\212\213\351\201\223 Spring Cloud \344\272\213\344\273\266\346\200\273\347\272\277 Kafka \345\205\245\351\227\250\343\200\213.md" "b/labx-19/\343\200\212\350\212\213\351\201\223 Spring Cloud \344\272\213\344\273\266\346\200\273\347\272\277 Kafka \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..e10bf7e2a --- /dev/null +++ "b/labx-19/\343\200\212\350\212\213\351\201\223 Spring Cloud \344\272\213\344\273\266\346\200\273\347\272\277 Kafka \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/labx-20/labx-20-sc-config-server-git-auto-refresh-by-bus/pom.xml b/labx-20/labx-20-sc-config-server-git-auto-refresh-by-bus/pom.xml new file mode 100644 index 000000000..12be52485 --- /dev/null +++ b/labx-20/labx-20-sc-config-server-git-auto-refresh-by-bus/pom.xml @@ -0,0 +1,78 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-20-sc-config-server-git-auto-refresh-by-bus + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-config-server + + + + + com.alibaba.cloud + spring-cloud-starter-bus-rocketmq + + + + + org.springframework.cloud + spring-cloud-config-monitor + + + + diff --git a/labx-20/labx-20-sc-config-server-git-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/configserverdemo/ConfigServerApplication.java b/labx-20/labx-20-sc-config-server-git-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/configserverdemo/ConfigServerApplication.java new file mode 100644 index 000000000..8a941740e --- /dev/null +++ b/labx-20/labx-20-sc-config-server-git-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/configserverdemo/ConfigServerApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloud.labx20.configserverdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +@SpringBootApplication +@EnableConfigServer +public class ConfigServerApplication { + + public static void main(String[] args) { + SpringApplication.run(ConfigServerApplication.class, args); + } + +} diff --git a/labx-20/labx-20-sc-config-server-git-auto-refresh-by-bus/src/main/resources/application.yml b/labx-20/labx-20-sc-config-server-git-auto-refresh-by-bus/src/main/resources/application.yml new file mode 100644 index 000000000..0b07c33c9 --- /dev/null +++ b/labx-20/labx-20-sc-config-server-git-auto-refresh-by-bus/src/main/resources/application.yml @@ -0,0 +1,24 @@ +server: + port: 8888 + +spring: + application: + name: demo-config-server + + profiles: + active: git # 使用的 Spring Cloud Config Server 的存储器方案 + # Spring Cloud Config 相关配置项 + cloud: + config: + server: + # Spring Cloud Config Server 的 Git 存储器的配置项,对应 MultipleJGitEnvironmentProperties 类 + git: + uri: https://github.com/YunaiV/demo-config-server.git # Git 仓库地址 + search-paths: / # 读取文件的根地址 + default-label: master # 使用的默认分支,默认为 master + # username: ${CODING_USERNAME} # 账号 + # password: ${CODING_PASSWORD} # 密码 + +# rocketmq 配置项,对应 RocketMQProperties 配置类 +rocketmq: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv diff --git a/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/pom.xml b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/pom.xml new file mode 100644 index 000000000..4a7d09d5a --- /dev/null +++ b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/pom.xml @@ -0,0 +1,72 @@ + + + + labx-12 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-20-sc-config-user-application-auto-refresh-by-bus + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-config + + + + + com.alibaba.cloud + spring-cloud-starter-bus-rocketmq + + + + diff --git a/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/userapplication/UserApplication.java b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/userapplication/UserApplication.java new file mode 100644 index 000000000..246d51142 --- /dev/null +++ b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/userapplication/UserApplication.java @@ -0,0 +1,13 @@ +package cn.iocoder.springcloud.labx20.userapplication; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UserApplication { + + public static void main(String[] args) { + SpringApplication.run(UserApplication.class, args); + } + +} diff --git a/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/userapplication/config/OrderProperties.java b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/userapplication/config/OrderProperties.java new file mode 100644 index 000000000..48d3dd537 --- /dev/null +++ b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/userapplication/config/OrderProperties.java @@ -0,0 +1,38 @@ +package cn.iocoder.springcloud.labx20.userapplication.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "order") +public class OrderProperties { + + /** + * 订单支付超时时长,单位:秒。 + */ + private Integer payTimeoutSeconds; + + /** + * 订单创建频率,单位:秒 + */ + private Integer createFrequencySeconds; + + public Integer getPayTimeoutSeconds() { + return payTimeoutSeconds; + } + + public OrderProperties setPayTimeoutSeconds(Integer payTimeoutSeconds) { + this.payTimeoutSeconds = payTimeoutSeconds; + return this; + } + + public Integer getCreateFrequencySeconds() { + return createFrequencySeconds; + } + + public OrderProperties setCreateFrequencySeconds(Integer createFrequencySeconds) { + this.createFrequencySeconds = createFrequencySeconds; + return this; + } + +} diff --git a/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/userapplication/controller/DemoController.java b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/userapplication/controller/DemoController.java new file mode 100644 index 000000000..4dca3287d --- /dev/null +++ b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/java/cn/iocoder/springcloud/labx20/userapplication/controller/DemoController.java @@ -0,0 +1,46 @@ +package cn.iocoder.springcloud.labx20.userapplication.controller; + +import cn.iocoder.springcloud.labx20.userapplication.config.OrderProperties; +import org.springframework.beans.factory.annotation.Autowired; +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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/demo") +@RefreshScope +public class DemoController { + + @Autowired + private OrderProperties orderProperties; + + /** + * 测试 @ConfigurationProperties 注解的配置属性类 + */ + @GetMapping("/test01") + public OrderProperties test01() { + return orderProperties; + } + + @Value(value = "${order.pay-timeout-seconds}") + private Integer payTimeoutSeconds; + @Value(value = "${order.create-frequency-seconds}") + private Integer createFrequencySeconds; + + /** + * 测试 @Value 注解的属性 + */ + @GetMapping("/test02") + public Map test02() { + Map result = new HashMap<>(); + result.put("payTimeoutSeconds", payTimeoutSeconds); + result.put("createFrequencySeconds", createFrequencySeconds); + return result; + } + +} diff --git a/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/resources/application.yml b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/resources/application.yml new file mode 100644 index 000000000..4bb5b8a86 --- /dev/null +++ b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/resources/application.yml @@ -0,0 +1,6 @@ +# rocketmq 配置项,对应 RocketMQProperties 配置类 +rocketmq: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv + +server: + port: 8081 diff --git a/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/resources/bootstrap.yml b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..6ae779eeb --- /dev/null +++ b/labx-20/labx-20-sc-config-user-application-auto-refresh-by-bus/src/main/resources/bootstrap.yml @@ -0,0 +1,9 @@ +spring: + application: + name: user-application + + cloud: + # Spring Cloud Config Client 配置项,对应 ConfigClientProperties 类 + config: + uri: http://127.0.0.1:8888 # Spring Cloud Config Server 的地址 + name: ${spring.application.name} # 读取的配置文件的名字,默认为 ${spring.application.name} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/pom.xml b/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/pom.xml new file mode 100644 index 000000000..7f2b15e2c --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/pom.xml @@ -0,0 +1,72 @@ + + + + labx-20 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-20-sca-bus-rocketmq-demo-listener-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-bus-rocketmq + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/ListenerDemoApplication.java b/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/ListenerDemoApplication.java new file mode 100644 index 000000000..8b38c3012 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/ListenerDemoApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloudalibaba.labx20.listenerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan; + +@SpringBootApplication +@RemoteApplicationEventScan +public class ListenerDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(ListenerDemoApplication.class, args); + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/event/UserRegisterEvent.java b/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..34c4566b5 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloudalibaba.labx20.listenerdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/listener/UserRegisterListener.java b/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/listener/UserRegisterListener.java new file mode 100644 index 000000000..1b6ae6941 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/listener/UserRegisterListener.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloudalibaba.labx20.listenerdemo.listener; + +import cn.iocoder.springcloudalibaba.labx20.listenerdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +/** + * 用户注册事件的监听器 + */ +@Component +public class UserRegisterListener implements ApplicationListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + public void onApplicationEvent(UserRegisterEvent event) { + logger.info("[onApplicationEvent][监听到用户({}) 注册]", event.getUsername()); + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/resources/application.yml b/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..dfc572131 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-listener-actuator/src/main/resources/application.yml @@ -0,0 +1,17 @@ +spring: + application: + name: listener-demo + +server: + port: 18080 # 随机端口,方便启动多个消费者 + +# rocketmq 配置项,对应 RocketMQProperties 配置类 +rocketmq: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv + +management: + endpoints: + # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类 + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-listener/pom.xml b/labx-20/labx-20-sca-bus-rocketmq-demo-listener/pom.xml new file mode 100644 index 000000000..8b79f1e00 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-listener/pom.xml @@ -0,0 +1,66 @@ + + + + labx-20 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-20-sca-bus-rocketmq-demo-listener + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-bus-rocketmq + + + + diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/ListenerDemoApplication.java b/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/ListenerDemoApplication.java new file mode 100644 index 000000000..8b38c3012 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/ListenerDemoApplication.java @@ -0,0 +1,15 @@ +package cn.iocoder.springcloudalibaba.labx20.listenerdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan; + +@SpringBootApplication +@RemoteApplicationEventScan +public class ListenerDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(ListenerDemoApplication.class, args); + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/event/UserRegisterEvent.java b/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..34c4566b5 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloudalibaba.labx20.listenerdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/listener/UserRegisterListener.java b/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/listener/UserRegisterListener.java new file mode 100644 index 000000000..1b6ae6941 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/java/cn/iocoder/springcloudalibaba/labx20/listenerdemo/listener/UserRegisterListener.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloudalibaba.labx20.listenerdemo.listener; + +import cn.iocoder.springcloudalibaba.labx20.listenerdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +/** + * 用户注册事件的监听器 + */ +@Component +public class UserRegisterListener implements ApplicationListener { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + public void onApplicationEvent(UserRegisterEvent event) { + logger.info("[onApplicationEvent][监听到用户({}) 注册]", event.getUsername()); + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/resources/application.yml b/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/resources/application.yml new file mode 100644 index 000000000..f2df894a9 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-listener/src/main/resources/application.yml @@ -0,0 +1,10 @@ +spring: + application: + name: listener-demo + +server: + port: ${random.int[10000,19999]} # 随机端口,方便启动多个消费者 + +# rocketmq 配置项,对应 RocketMQProperties 配置类 +rocketmq: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/pom.xml b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/pom.xml new file mode 100644 index 000000000..1d0b7b305 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/pom.xml @@ -0,0 +1,72 @@ + + + + labx-20 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-20-sca-bus-rocketmq-demo-publisher-actuator + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-bus-rocketmq + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/PublisherDemoApplication.java b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/PublisherDemoApplication.java new file mode 100644 index 000000000..425782e92 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/PublisherDemoApplication.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloudalibaba.labx20.publisherdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +//@RemoteApplicationEventScan +public class PublisherDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(PublisherDemoApplication.class, args); + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/controller/DemoController.java b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/controller/DemoController.java new file mode 100644 index 000000000..47f9e03af --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/controller/DemoController.java @@ -0,0 +1,37 @@ +package cn.iocoder.springcloudalibaba.labx20.publisherdemo.controller; + +import cn.iocoder.springcloudalibaba.labx20.publisherdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.bus.ServiceMatcher; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + + @Autowired + private ServiceMatcher busServiceMatcher; + + @GetMapping("/register") + public String register(String username) { + // ... 执行注册逻辑 + logger.info("[register][执行用户({}) 的注册逻辑]", username); + + // ... 发布 + applicationEventPublisher.publishEvent(new UserRegisterEvent(this, busServiceMatcher.getServiceId(), + null, username)); + return "success"; + } + + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/event/UserRegisterEvent.java b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..df4800c7d --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloudalibaba.labx20.publisherdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/resources/application.yml b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/resources/application.yml new file mode 100644 index 000000000..5c54e90e6 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher-actuator/src/main/resources/application.yml @@ -0,0 +1,17 @@ +server: + port: 8081 + +spring: + application: + name: publisher-demo + +# rocketmq 配置项,对应 RocketMQProperties 配置类 +rocketmq: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv + +management: + endpoints: + # Actuator HTTP 配置项,对应 WebEndpointProperties 配置类 + web: + exposure: + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/pom.xml b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/pom.xml new file mode 100644 index 000000000..8772b7d28 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/pom.xml @@ -0,0 +1,66 @@ + + + + labx-20 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-20-sca-bus-rocketmq-demo-publisher + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + 2.2.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring.cloud.alibaba.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.alibaba.cloud + spring-cloud-starter-bus-rocketmq + + + + diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/PublisherDemoApplication.java b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/PublisherDemoApplication.java new file mode 100644 index 000000000..425782e92 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/PublisherDemoApplication.java @@ -0,0 +1,14 @@ +package cn.iocoder.springcloudalibaba.labx20.publisherdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +//@RemoteApplicationEventScan +public class PublisherDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(PublisherDemoApplication.class, args); + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/controller/DemoController.java b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/controller/DemoController.java new file mode 100644 index 000000000..83ceef5a7 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/controller/DemoController.java @@ -0,0 +1,36 @@ +package cn.iocoder.springcloudalibaba.labx20.publisherdemo.controller; + +import cn.iocoder.springcloudalibaba.labx20.publisherdemo.event.UserRegisterEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.bus.ServiceMatcher; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + + @Autowired + private ServiceMatcher busServiceMatcher; + + @GetMapping("/register") + public String register(String username) { + // ... 执行注册逻辑 + logger.info("[register][执行用户({}) 的注册逻辑]", username); + + // ... 发布 + applicationEventPublisher.publishEvent(new UserRegisterEvent(this, busServiceMatcher.getServiceId(), + null, username)); + return "success"; + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/event/UserRegisterEvent.java b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/event/UserRegisterEvent.java new file mode 100644 index 000000000..df4800c7d --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/java/cn/iocoder/springcloudalibaba/labx20/publisherdemo/event/UserRegisterEvent.java @@ -0,0 +1,27 @@ +package cn.iocoder.springcloudalibaba.labx20.publisherdemo.event; + +import org.springframework.cloud.bus.event.RemoteApplicationEvent; + +/** + * 用户注册事件 + */ +public class UserRegisterEvent extends RemoteApplicationEvent { + + /** + * 用户名 + */ + private String username; + + public UserRegisterEvent() { // 序列化 + } + + public UserRegisterEvent(Object source, String originService, String destinationService, String username) { + super(source, originService); + this.username = username; + } + + public String getUsername() { + return username; + } + +} diff --git a/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/resources/application.yml b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/resources/application.yml new file mode 100644 index 000000000..2ecee2f58 --- /dev/null +++ b/labx-20/labx-20-sca-bus-rocketmq-demo-publisher/src/main/resources/application.yml @@ -0,0 +1,16 @@ +server: + port: 8081 + +spring: + application: + name: publisher-demo + + # Bus 相关配置项,对应 BusProperties + cloud: + bus: + enabled: true # 是否开启,默认为 true + destination: springCloudBus # 目标消息队列,默认为 springCloudBus + +# rocketmq 配置项,对应 RocketMQProperties 配置类 +rocketmq: + name-server: 127.0.0.1:9876 # RocketMQ Namesrv diff --git a/labx-20/pom.xml b/labx-20/pom.xml new file mode 100644 index 000000000..77eafd34f --- /dev/null +++ b/labx-20/pom.xml @@ -0,0 +1,25 @@ + + + + labs-parent + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-20 + + + labx-20-sca-bus-rocketmq-demo-publisher + labx-20-sca-bus-rocketmq-demo-listener + + labx-20-sca-bus-rocketmq-demo-publisher-actuator + labx-20-sca-bus-rocketmq-demo-listener-actuator + + labx-20-sc-config-server-git-auto-refresh-by-bus + labx-20-sc-config-user-application-auto-refresh-by-bus + + + diff --git "a/labx-20/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \344\272\213\344\273\266\346\200\273\347\272\277 Bus RocketMQ \345\205\245\351\227\250\343\200\213.md" "b/labx-20/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \344\272\213\344\273\266\346\200\273\347\272\277 Bus RocketMQ \345\205\245\351\227\250\343\200\213.md" new file mode 100644 index 000000000..60f0ef5c7 --- /dev/null +++ "b/labx-20/\343\200\212\350\212\213\351\201\223 Spring Cloud Alibaba \344\272\213\344\273\266\346\200\273\347\272\277 Bus RocketMQ \345\205\245\351\227\250\343\200\213.md" @@ -0,0 +1 @@ + diff --git a/pom.xml b/pom.xml index b76a850fc..e89acdfac 100644 --- a/pom.xml +++ b/pom.xml @@ -9,6 +9,8 @@ pom 1.0-SNAPSHOT + + lab-01 lab-02 lab-03 @@ -58,8 +60,34 @@ lab-47 lab-48 lab-49 + lab-50 + lab-51 + lab-52 + lab-53 + lab-54 + + labx-01 labx-02 + labx-03 + labx-04 + labx-05 + labx-06 + labx-07 + labx-08 + labx-09 + labx-10 + labx-11 + labx-12 + labx-13 + labx-14 + labx-15 + labx-16 + labx-17 + labx-18 + labx-19 + labx-20 +