diff --git a/README.md b/README.md index 968ab9b8..dc2fb302 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,14 @@ +一个涵盖四个主流技术栈的**正经**仓库: +* [《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) + +作为一个热爱**深夜**撸码的 18 岁秃头的可爱小男孩,希望大佬能够**一键三连**。 + +![一间三连](http://static.iocoder.cn/github-star.jpg) + +> ~~交流~~**装逼群**,请点击[传送门](http://www.iocoder.cn/mall-user-group/?vip&gitee),进行引导加入。**亲,一键三连啊** # Spring Boot 专栏 @@ -136,9 +147,8 @@ * [《芋道 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 声明式调用 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 入门》 +* [《芋道 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 入门》 - * TODO 监控 # Spring Cloud 专栏 @@ -166,19 +176,25 @@ ## 配置中心 * [《芋道 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 入门》 +* [《芋道 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 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 消息队列 RabbitMQ 入门》 -* 《芋道 Spring Cloud Alibaba 消息队列 Kafka 入门》 +* [《芋道 Spring Cloud 消息队列 RabbitMQ 入门》](http://www.iocoder.cn/Spring-Cloud/RabbitMQ/?github) 对应 [lab10-06](https://github.com/YunaiV/SpringBoot-Labs/tree/master/labx-10) +* 《芋道 Spring Cloud 消息队列 Kafka 入门》 ## 链路追踪 * 《芋道 Spring Cloud 链路追踪 Sleuth 入门》 * 《芋道 Spring Cloud 链路追踪 SkyWalking 入门》 +# Dubbo 专栏 + +* [《芋道 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) + --------- 如下是草稿目录,未来需要整理下 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 ee007579..ace5489d 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/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/target/classes/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/target/classes/application.yml deleted file mode 100644 index b4e95deb..00000000 --- a/labx-06/labx-06-sca-stream-rocketmq-consumer-actuator/target/classes/application.yml +++ /dev/null @@ -1,38 +0,0 @@ -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-error-handler/target/classes/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/target/classes/application.yml deleted file mode 100644 index 4544fc74..00000000 --- a/labx-06/labx-06-sca-stream-rocketmq-consumer-error-handler/target/classes/application.yml +++ /dev/null @@ -1,31 +0,0 @@ -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-orderly/target/classes/application.yml b/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/target/classes/application.yml deleted file mode 100644 index e3672922..00000000 --- a/labx-06/labx-06-sca-stream-rocketmq-consumer-orderly/target/classes/application.yml +++ /dev/null @@ -1,28 +0,0 @@ -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-producer-orderly/target/classes/application.yml b/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/target/classes/application.yml deleted file mode 100644 index 897f4bd7..00000000 --- a/labx-06/labx-06-sca-stream-rocketmq-producer-orderly/target/classes/application.yml +++ /dev/null @@ -1,29 +0,0 @@ -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-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 00000000..7f948e8a --- /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 00000000..f9575ef3 --- /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 00000000..eca19a8a --- /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 00000000..4f641b7f --- /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 00000000..c1d97988 --- /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 00000000..f9575ef3 --- /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 00000000..8e7ac23f --- /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 00000000..7ae7c813 --- /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 00000000..f9575ef3 --- /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 00000000..29530ca3 --- /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 00000000..c261dea5 --- /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 00000000..f9575ef3 --- /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 00000000..54e4eec6 --- /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 00000000..2de7aed3 --- /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 00000000..dbb8dd34 --- /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 00000000..f9575ef3 --- /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 00000000..c8a543ea --- /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-05/labx-05-sca-nacos-config-auto-refresh/target/classes/bootstrap.yaml b/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/resources/bootstrap.yaml similarity index 95% rename from labx-05/labx-05-sca-nacos-config-auto-refresh/target/classes/bootstrap.yaml rename to labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/resources/bootstrap.yaml index fb5bb9ec..7c0386d7 100644 --- a/labx-05/labx-05-sca-nacos-config-auto-refresh/target/classes/bootstrap.yaml +++ b/labx-08/labx-08-sc-gateway-demo03-config-nacos/src/main/resources/bootstrap.yaml @@ -1,6 +1,6 @@ spring: application: - name: demo-application + name: gateway-application cloud: nacos: 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 00000000..a197b6eb --- /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 00000000..f9575ef3 --- /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 00000000..ca7f104f --- /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 00000000..860c0774 --- /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 00000000..f9575ef3 --- /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 00000000..f54c3e0b --- /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 00000000..f9d50ef0 --- /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 00000000..f9d50ef0 --- /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 00000000..0534a346 --- /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 00000000..f9575ef3 --- /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 00000000..9822fa87 --- /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 00000000..80ebe810 --- /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 00000000..2d6ee395 --- /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 00000000..f9575ef3 --- /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 00000000..ad97a80c --- /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 00000000..cbe1dba3 --- /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 00000000..e2d82ac3 --- /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 00000000..c3ec62ce --- /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 00000000..1ba74349 --- /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 00000000..52330eb8 --- /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 00000000..0e47591b --- /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 00000000..8a53df34 --- /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 00000000..1b5b7b27 --- /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 00000000..f9575ef3 --- /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 00000000..2e692303 --- /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 00000000..2f61f247 --- /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 00000000..238c44b5 --- /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 00000000..96f5a421 --- /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 00000000..d3303ca6 --- /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 00000000..f9575ef3 --- /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 00000000..e7b53829 --- /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 00000000..5342efed --- /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 00000000..f9575ef3 --- /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 00000000..8aaebf8d --- /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 00000000..3ed72cce --- /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 00000000..94da95e8 --- /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 00000000..e576e559 --- /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 00000000..2dbfedce --- /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 00000000..8c911e70 --- /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 00000000..e9b70d31 --- /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 00000000..fd190eed --- /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-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 00000000..1efbed71 --- /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 00000000..0f011da9 --- /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 00000000..f5349a41 --- /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 00000000..6d950b39 --- /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 00000000..2472ae36 --- /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 00000000..ace5489d --- /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 00000000..ff9e0951 --- /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 00000000..0f011da9 --- /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 00000000..2c01d017 --- /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 00000000..32e59532 --- /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 00000000..e384f392 --- /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 00000000..4b9b5639 --- /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 00000000..8867588b --- /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 00000000..cd26fa07 --- /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 00000000..76d3e9ac --- /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 00000000..0f011da9 --- /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 00000000..1cd63581 --- /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 00000000..b017e5aa --- /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 00000000..001e788a --- /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 00000000..e4c382ca --- /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 00000000..0f011da9 --- /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 00000000..f5349a41 --- /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 00000000..eed5f2ed --- /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 00000000..ace5489d --- /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 00000000..9989469e --- /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-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 00000000..7be4226e --- /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 00000000..85330de4 --- /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 00000000..885dad4b --- /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 00000000..7a894faa --- /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 00000000..74c4255d --- /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 00000000..9bff11e1 --- /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 00000000..9bff11e1 --- /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 00000000..31ab48b9 --- /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 00000000..85330de4 --- /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 00000000..885dad4b --- /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 00000000..7a894faa --- /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 00000000..74c4255d --- /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 00000000..a5e02785 --- /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 00000000..b0875e48 --- /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 00000000..85330de4 --- /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 00000000..b19346cd --- /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) + 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 00000000..7a894faa --- /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 00000000..74c4255d --- /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 00000000..31556aaf --- /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-retry/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-consumer-retry/pom.xml new file mode 100644 index 00000000..b97e1a5c --- /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 00000000..85330de4 --- /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 00000000..00e51585 --- /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 00000000..7a894faa --- /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 00000000..74c4255d --- /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 00000000..31556aaf --- /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-delay/pom.xml b/labx-10/labx-10-sc-stream-rabbitmq-producer-delay/pom.xml new file mode 100644 index 00000000..6695ee1d --- /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 00000000..c128d2f4 --- /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 00000000..aeb8b65d --- /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 00000000..7f015623 --- /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 00000000..64d06834 --- /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 00000000..ae569793 --- /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 00000000..105a076b --- /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 00000000..c128d2f4 --- /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 00000000..cfee040e --- /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,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-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 00000000..7f015623 --- /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 00000000..64d06834 --- /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 00000000..ae514a28 --- /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/pom.xml b/labx-10/pom.xml new file mode 100644 index 00000000..c41ffe46 --- /dev/null +++ b/labx-10/pom.xml @@ -0,0 +1,26 @@ + + + + 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 + + + + diff --git a/pom.xml b/pom.xml index 8601221e..b94e27de 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,9 @@ labx-05 labx-06 labx-07 + labx-08 + labx-09 + labx-10