feat: support springboot3 (#1570)

* feat: support springboot3

* fix:add interface InitializingBean
pull/1571/head
Han Lau 3 months ago committed by GitHub
parent 9b11c3b49a
commit 9bdb8102ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,4 @@
启动项添加JVM配置参数
```
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
```

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-config-nacos-spring-boot3</artifactId>
<version>${revision}</version>
<properties>
<revision>2.0.0-SNAPSHOT</revision>
<maven.deploy.skip>true</maven.deploy.skip>
<spring-boot.version>3.3.3</spring-boot.version>
<nacos-client.version>2.4.1</nacos-client.version>
<java.version>1.17</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- <dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2023.0.1.2</version>
</dependency>-->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>0.3.0-RC</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-web</artifactId>-->
<!-- </dependency>-->
<!-- jetty start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!-- jetty end -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-example-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-config-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.13.3</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.example.config.nacos;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Config nacos spring boot 3.x example application
*/
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = "cn.hippo4j.example.core")
public class ConfigNacosSpringBootExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigNacosSpringBootExampleApplication.class, args);
}
}

@ -0,0 +1,66 @@
#debug=true
server.port=8089
server.servlet.context-path=/example
management.security.enabled=false
management.context-path=/actuator
spring.profiles.active=dev
spring.application.name=hippo4j-config-nacos-spring-boot3-starter-example
## nacos spring-boot
nacos.config.server-addr=127.0.0.1:8848
nacos.config.ext-config[0].data-id=hippo4j-nacos.yaml
nacos.config.ext-config[0].group=DEFAULT_GROUP
nacos.config.ext-config[0].auto-refresh=true
spring.dynamic.thread-pool.enable=true
spring.dynamic.thread-pool.banner=true
spring.dynamic.thread-pool.check-state-interval=5
spring.dynamic.thread-pool.monitor.enable=true
spring.dynamic.thread-pool.monitor.collect-types=micrometer
spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic,web
spring.dynamic.thread-pool.monitor.initial-delay=10000
spring.dynamic.thread-pool.monitor.collect-interval=5000
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].token=ac0426a5-c712-474c-9bff-72b8b8f5caff
spring.dynamic.thread-pool.notify-platforms[1].platform=DING
spring.dynamic.thread-pool.notify-platforms[1].token=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55
spring.dynamic.thread-pool.notify-platforms[2].platform=LARK
spring.dynamic.thread-pool.notify-platforms[2].token=2cbf2808-3839-4c26-a04d-fd201dd51f9e
spring.dynamic.thread-pool.nacos.data-id=hippo4j-nacos.yaml
spring.dynamic.thread-pool.nacos.group=DEFAULT_GROUP
spring.dynamic.thread-pool.config-file-type=yaml
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[0].alarm=true
spring.dynamic.thread-pool.executors[0].active-alarm=80
spring.dynamic.thread-pool.executors[0].capacity-alarm=80
spring.dynamic.thread-pool.executors[0].notify.interval=8
spring.dynamic.thread-pool.executors[0].notify.receives=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -0,0 +1,52 @@
# \u4EE5\u4E0B\u5185\u5BB9\u590D\u5236\u5230 nacos \u914D\u7F6E\u6587\u4EF6\u4E2D
# Copy the following to the nacos configuration file
spring.dynamic.thread-pool.web.core-pool-size=64
spring.dynamic.thread-pool.web.maximum-pool-size=128
spring.dynamic.thread-pool.web.keep-alive-time=1000
spring.dynamic.thread-pool.web.enable=true
spring.dynamic.thread-pool.default-executor.core-pool-size=1
spring.dynamic.thread-pool.default-executor.maximum-pool-size=2
spring.dynamic.thread-pool.default-executor.blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.default-executor.execute-time-out=100
spring.dynamic.thread-pool.default-executor.keep-alive-time=6691
spring.dynamic.thread-pool.default-executor.queue-capacity=1
spring.dynamic.thread-pool.default-executor.rejected-handler=AbortPolicy
spring.dynamic.thread-pool.default-executor.active-alarm=90
spring.dynamic.thread-pool.default-executor.capacity-alarm=85
spring.dynamic.thread-pool.default-executor.alarm=true
spring.dynamic.thread-pool.default-executor.allow-core-thread-time-out=true
spring.dynamic.thread-pool.default-executor.notify.interval=5
spring.dynamic.thread-pool.default-executor.notify.receives=chen.ma
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ec3be378-6c99-45d2-a147-b400c7e94a08
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[0].alarm=true
spring.dynamic.thread-pool.executors[0].active-alarm=80
spring.dynamic.thread-pool.executors[0].capacity-alarm=80
spring.dynamic.thread-pool.executors[0].notify.interval=8
spring.dynamic.thread-pool.executors[0].notify.receives=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -23,5 +23,7 @@
<module>config-etcd</module>
<module>config-nacos-spring-boot-1x</module>
<module>config-apollo-spring-boot-1x</module>
<!-- <module>config-nacos-spring-boot3</module>-->
<!-- <module>config-apollo-spring-boot3</module>-->
</modules>
</project>

@ -0,0 +1,5 @@
## spring-boot3 仅支持jdk17以上版本
## 启动项添加JVM配置参数
```
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
```

@ -0,0 +1,118 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-adapter-dubbo-spring-boot3-example</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hippo4j-threadpool-adapter-dubbo-spring-boot3-consumer-example</artifactId>
<dependencies>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-adapter-dubbo-spring-boot3-interface-example</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-example-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-spring-boot-starter-monitor-micrometer</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper_version}</version>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
<version>${curator.version}</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.example.server.adapter.dubbo.springboot3.consumer;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Service;
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = {"cn.hippo4j.example.core", "cn.hippo4j.example.server"})
@EnableDubbo
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}

@ -0,0 +1,37 @@
package cn.hippo4j.example.server.adapter.dubbo.springboot3.consumer;
import cn.hippo4j.example.server.adapter.dubbo.springboot3.DemoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class DubboThreadTestService {
@DubboReference(timeout = 2000, version = "1.0.0")
private DemoService demoService;
@PostConstruct
public void init() {
ExecutorService executorService = Executors.newFixedThreadPool(10);
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(() ->
executorService.execute(() -> {
try {
String result = demoService.sayHello("world");
log.info("返回信息:{}", result);
} catch (Exception e) {
log.error("dubbo接口抛出错误", e);
}
}), 500, 500, TimeUnit.MILLISECONDS);
}
}

@ -0,0 +1,23 @@
server.port=8089
debug=true
spring.application.name=hippo4j-threadpool-adapter-dubbo-spring-boot3-consumer-example
spring.dynamic.thread-pool.server-addr=http://localhost:6691
### Use netty to report thread pool monitoring data. The default is http.
# spring.dynamic.thread-pool.report-type=netty
# spring.dynamic.thread-pool.netty-server-port=8899
spring.dynamic.thread-pool.namespace=prescription
spring.dynamic.thread-pool.item-id=dynamic-threadpool-example
spring.dynamic.thread-pool.username=admin
spring.dynamic.thread-pool.password=123456
dubbo.application.name=${spring.application.name}
dubbo.protocol.name=dubbo
dubbo.protocol.port=20881
# ??ip????????????????ip?localhost?127.0.x.x?
#dubbo.protocol.host=192.168.66.66
dubbo.registry.id=zk-registry
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.config-center.address=zookeeper://127.0.0.1:2181
dubbo.metadata-report.address=zookeeper://127.0.0.1:2181

@ -0,0 +1,40 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-adapter-dubbo-spring-boot3-example</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hippo4j-threadpool-adapter-dubbo-spring-boot3-interface-example</artifactId>
<build>
<finalName>${project.name}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.example.server.adapter.dubbo.springboot3;
import java.util.concurrent.CompletableFuture;
public interface DemoService {
String sayHello(String name);
default CompletableFuture<String> sayHelloAsync(String name) {
return CompletableFuture.completedFuture(sayHello(name));
}
}

@ -0,0 +1,140 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-adapter-dubbo-spring-boot3-example</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hippo4j-threadpool-adapter-dubbo-spring-boot3-provider-example</artifactId>
<dependencies>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-adapter-dubbo-spring-boot3-interface-example</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-example-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-spring-boot-starter-adapter-dubbo</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-spring-boot-starter-monitor-micrometer</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper_version}</version>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
<version>${curator.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.example.server.adapter.dubbo.springboot3;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.config.annotation.Method;
import org.apache.dubbo.rpc.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
@DubboService(interfaceClass = DemoService.class, version = "1.0.0", retries = 4, methods = {
@Method(name = "sayHello", retries = 6)
})
public class DemoServiceImpl implements DemoService {
private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);
@Override
public String sayHello(String name) {
logger.info("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "Hello " + name;
}
}

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.example.server.adapter.dubbo.springboot3;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import java.util.concurrent.CountDownLatch;
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = {"cn.hippo4j.example.core", "cn.hippo4j.example.server"})
@EnableDubbo(scanBasePackages = {"cn.hippo4j.example.server.adapter.dubbo.springboot3"})
public class ProviderApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(ProviderApplication.class, args);
System.out.println("dubbo service started");
new CountDownLatch(1).await();
}
}

@ -0,0 +1,23 @@
server.port=8088
debug=true
spring.application.name=hippo4j-threadpool-adapter-dubbo-spring-boot3-provider-example
spring.dynamic.thread-pool.server-addr=http://localhost:6691
### Use netty to report thread pool monitoring data. The default is http.
# spring.dynamic.thread-pool.report-type=netty
# spring.dynamic.thread-pool.netty-server-port=8899
spring.dynamic.thread-pool.namespace=prescription
spring.dynamic.thread-pool.item-id=dynamic-threadpool-example
spring.dynamic.thread-pool.username=admin
spring.dynamic.thread-pool.password=123456
dubbo.application.name=${spring.application.name}
dubbo.protocol.name=dubbo
dubbo.protocol.port= -1
# ??ip????????????????ip?localhost?127.0.x.x?
#dubbo.protocol.host=192.168.66.66
dubbo.registry.id=zk-registry
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.config-center.address=zookeeper://127.0.0.1:2181
dubbo.metadata-report.address=zookeeper://127.0.0.1:2181

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-adapter-dubbo-spring-boot3-example</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
<modules>
<module>adapter-dubbo-spring-boot3-consumer-example</module>
<module>adapter-dubbo-spring-boot3-provider-example</module>
<module>adapter-dubbo-spring-boot3-interface-example</module>
</modules>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
<revision>2.0.0-SNAPSHOT</revision>
<maven.deploy.skip>true</maven.deploy.skip>
<spring-boot.version>3.3.3</spring-boot.version>
<dubbo.version>3.2.15</dubbo.version>
<zookeeper_version>3.8.1</zookeeper_version>
<curator.version>5.1.0</curator.version>
<java.version>1.17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

@ -0,0 +1,5 @@
## spring-boot3 仅支持jdk17以上版本
## 启动项添加JVM配置参数
```
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
```

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-adapter-rabbitmq-spring-boot3-example</artifactId>
<version>${revision}</version>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
<revision>2.0.0-SNAPSHOT</revision>
<spring-boot.version>3.3.3</spring-boot.version>
<java.version>1.17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-spring-boot-starter-adapter-rabbitmq</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-spring-boot-starter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-example-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.adapter.rabbitmq.example;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Server Adapter RabbitMQ Example Application
*/
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = {"cn.hippo4j.example.core", "cn.hippo4j.springboot.starter.adapter.rabbitmq.example"})
public class ServerAdapterRabbitMQExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ServerAdapterRabbitMQExampleApplication.class, args);
}
}

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.adapter.rabbitmq.example.config;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* RabbitMQ template config.
*/
@Configuration
public class RabbitMQTemplateConfig {
@Bean
public RabbitTemplate rabbitTemplate(CachingConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(jackson2JsonMessageConverter());
return rabbitTemplate;
}
@Bean
public MessageConverter jackson2JsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
}

@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.adapter.rabbitmq.example.config;
import org.springframework.amqp.rabbit.config.AbstractRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.config.DirectRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* RabbitMQ thread-pool config.
*/
@Configuration
public class RabbitMQThreadPoolConfig {
private static final int MAX_POOL_SIZE = 5;
private static final int CORE_POOL_SIZE = 5;
private static final int QUEUE_CAPACITY = 1000;
private static final int CONSUMERS_PER_QUEUE = 10;
@Bean
public ThreadPoolTaskExecutor rabbitListenerTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// Specify the maximum number of threads.
executor.setMaxPoolSize(MAX_POOL_SIZE);
// Specifies the minimum number of thread pool maintenance threads.
executor.setCorePoolSize(CORE_POOL_SIZE);
// Specifies the number of tasks waiting to be processed.
executor.setQueueCapacity(QUEUE_CAPACITY);
executor.setThreadNamePrefix("RabbitListenerTaskExecutor-");
return executor;
}
@Bean
public AbstractRabbitListenerContainerFactory<?> defaultRabbitListenerContainerFactory(ThreadPoolTaskExecutor rabbitListenerTaskExecutor,
MessageConverter messageConverter, AbstractConnectionFactory abstractConnectionFactory) {
DirectRabbitListenerContainerFactory factory = new DirectRabbitListenerContainerFactory();
factory.setConnectionFactory(abstractConnectionFactory);
factory.setMessageConverter(messageConverter);
factory.setConsumersPerQueue(CONSUMERS_PER_QUEUE);
abstractConnectionFactory.setExecutor(rabbitListenerTaskExecutor);
return factory;
}
}

@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.adapter.rabbitmq.example.constants;
/**
* Simple MQ constant.
*/
public class SimpleMQConstant {
public static final String QUEUE_NAME = "framework_message-center_queue";
}

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.adapter.rabbitmq.example.consumer;
import cn.hippo4j.example.core.dto.SendMessageDTO;
import cn.hippo4j.springboot.starter.adapter.rabbitmq.example.constants.SimpleMQConstant;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* Message consume.
*/
@Slf4j
@Component
public class MessageConsumer {
@RabbitHandler
@RabbitListener(queuesToDeclare = @Queue(SimpleMQConstant.QUEUE_NAME), containerFactory = "defaultRabbitListenerContainerFactory")
public void receiveObject(SendMessageDTO simple) throws Exception {
TimeUnit.SECONDS.sleep(1);
ObjectMapper objectMapper = new ObjectMapper();
String message = objectMapper.writeValueAsString(simple);
log.info("consumer1 threadId {} Message: {}", Thread.currentThread().getName(), message);
}
}

@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.adapter.rabbitmq.example.producer;
import cn.hippo4j.common.toolkit.IdUtil;
import cn.hippo4j.example.core.dto.SendMessageDTO;
import cn.hippo4j.springboot.starter.adapter.rabbitmq.example.constants.SimpleMQConstant;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Message produce.
*/
@Slf4j
@Component
@RestController
@AllArgsConstructor
public class MessageProduce {
private final RabbitTemplate rabbitTemplate;
@GetMapping("/message/send")
public String sendMessage(@RequestParam(name = "count") Integer count) {
for (int i = 0; i < count; i++) {
String keys = IdUtil.randomUUID();
SendMessageDTO payload = SendMessageDTO.builder()
.receiver("156011xxx91")
.uid(keys)
.build();
rabbitTemplate.convertAndSend(SimpleMQConstant.QUEUE_NAME, payload);
}
return "success";
}
}

@ -0,0 +1,17 @@
server.port=8091
spring.profiles.active=dev
spring.application.name=hippo4j-spring-boot-starter-adapter-rabbitmq-spring-boot3-example
spring.dynamic.thread-pool.server-addr=http://localhost:6691
spring.dynamic.thread-pool.namespace=prescription
spring.dynamic.thread-pool.item-id=dynamic-threadpool-example
spring.dynamic.thread-pool.username=admin
spring.dynamic.thread-pool.password=123456
# Please replace the local configuration.
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/

@ -0,0 +1,5 @@
## spring-boot3 仅支持jdk17以上版本
## 启动项添加JVM配置参数
```
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
```

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-adapter-stream-rabbitmq-spring-boot3-example</artifactId>
<version>${revision}</version>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
<revision>2.0.0-SNAPSHOT</revision>
<spring-boot.version>3.3.3</spring-boot.version>
<spring-clound-stream.version>4.1.3</spring-clound-stream.version>
<java.version>1.17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-spring-boot-starter-adapter-stream-rabbitmq</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-spring-boot-starter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-example-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
<version>${spring-clound-stream.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.adapter.springcloud.stream.rabbitmq.example;
import cn.hippo4j.common.toolkit.IdUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.example.core.dto.SendMessageDTO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Message produce.
*/
@Slf4j
@RestController
@AllArgsConstructor
public class MessageProduce {
private final StreamBridge streamBridge;
private static final int MAX_SEND_SIZE = 10;
@GetMapping("/message/send")
public String sendMessage(@RequestParam(required = false,name = "maxSendSize") Integer maxSendSize) {
if (maxSendSize == null) {
maxSendSize = MAX_SEND_SIZE;
}
for (int i = 0; i < maxSendSize; i++) {
sendMessage0();
}
return "success";
}
private void sendMessage0() {
String keys = IdUtil.randomUUID();
SendMessageDTO payload = SendMessageDTO.builder()
.receiver("156011xxx91")
.uid(keys)
.build();
long startTime = System.currentTimeMillis();
boolean sendResult = false;
try {
sendResult = streamBridge.send("demoOutput", payload);
} finally {
log.info("Send status: {}, Keys: {}, Execute time: {} ms, Message: {}",
sendResult,
keys,
System.currentTimeMillis() - startTime,
JSONUtil.toJSONString(payload));
}
}
}

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.adapter.springcloud.stream.rabbitmq.example;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import java.util.function.Consumer;
/**
* Server Adapter Spring Cloud Stream RabbitMQ Application
*/
@Slf4j
@EnableDynamicThreadPool
@SpringBootApplication
public class ServerAdapterSpringCloudStreamRabbitMQApplication {
public static void main(String[] args) {
SpringApplication.run(ServerAdapterSpringCloudStreamRabbitMQApplication.class, args);
}
@Bean
public Consumer<Message<String>> demoInput() {
return message -> {
MessageHeaders headers = message.getHeaders();
log.info("Input current thread name: {} ,{} received from partition {}",
Thread.currentThread().getName(),
JSONUtil.toJSONString(message.getPayload()),
headers.get(AmqpHeaders.CONSUMER_QUEUE));
};
}
}

@ -0,0 +1,29 @@
server.port=8090
spring.application.name=hippo4j-spring-boot-starter-adapter-rabbitmq-spring-boot3-example
spring.profiles.active=dev
spring.dynamic.thread-pool.server-addr=http://localhost:6691
spring.dynamic.thread-pool.namespace=prescription
spring.dynamic.thread-pool.item-id=dynamic-threadpool-example
spring.dynamic.thread-pool.username=admin
spring.dynamic.thread-pool.password=123456
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=root
spring.rabbitmq.password=123456
spring.rabbitmq.virtual-host=/
# Please replace the local configuration.
spring.cloud.stream.binders.defaultRabbit.type=rabbit
# === produce ===
spring.cloud.stream.bindings.demoOutput.destination=exchange-demo
spring.cloud.stream.bindings.demoOutput.content-type=application/json
# === consume ===
spring.cloud.stream.bindings.demoInput-in-0.destination=exchange-demo
spring.cloud.stream.bindings.demoInput-in-0.content-type=application/json
spring.cloud.stream.bindings.demoInput-in-0.group=myGroup
spring.cloud.stream.bindings.demoInput-in-0.consumer.concurrency=1

@ -0,0 +1,4 @@
启动项添加JVM配置参数
```
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
```

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-server-spring-boot3-example</artifactId>
<version>${revision}</version>
<properties>
<revision>2.0.0-SNAPSHOT</revision>
<maven.deploy.skip>true</maven.deploy.skip>
<spring-boot.version>3.3.3</spring-boot.version>
<java.version>1.17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-example-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-threadpool-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-spring-boot-starter-monitor-micrometer</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>-->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>-->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>-->
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.example.server;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Server Example Application
*/
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = {"cn.hippo4j.example.core", "cn.hippo4j.example.server"})
public class ServerExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ServerExampleApplication.class, args);
}
}

@ -0,0 +1,26 @@
server.port=8088
debug=true
server.servlet.context-path=/example
management.prometheus.metrics.export.enabled=true
management.server.port=29901
management.endpoints.web.exposure.include=*
spring.profiles.active=dev
spring.application.name=hippo4j-spring-boot3-starter-example
spring.dynamic.thread-pool.server-addr=http://localhost:6691
### Use netty to report thread pool monitoring data. The default is http.
# spring.dynamic.thread-pool.report-type=netty
# spring.dynamic.thread-pool.netty-server-port=8899
spring.dynamic.thread-pool.namespace=prescription
spring.dynamic.thread-pool.item-id=dynamic-threadpool-example
spring.dynamic.thread-pool.username=admin
spring.dynamic.thread-pool.password=123456
# Enable server and micrometer monitoring at the same time
spring.dynamic.thread-pool.monitor.enable=true
spring.dynamic.thread-pool.monitor.collect-types=server,micrometer
spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic,web
spring.dynamic.thread-pool.monitor.initial-delay=10000
spring.dynamic.thread-pool.monitor.collect-interval=5000

@ -0,0 +1 @@
cn.hippo4j.springboot.starter.adapter.springcloud.stream.rabbitmq.SpringCloudStreamRabbitMQAdapterAutoConfiguration

@ -0,0 +1 @@
cn.hippo4j.springboot.starter.adapter.springcloud.stream.rocketmq.SpringCloudStreamRocketMQAdapterAutoConfiguration

@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot3.starter.adapter.web;
import cn.hippo4j.adapter.web.WebThreadPoolHandlerChoose;
import cn.hippo4j.adapter.web.WebThreadPoolRunStateHandler;
import cn.hippo4j.core.config.ApplicationContextHolder;
import cn.hippo4j.core.config.UtilAutoConfiguration;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import cn.hippo4j.core.toolkit.inet.InetUtils;
import cn.hippo4j.springboot.starter.adapter.web.WebThreadPoolHandlerConfiguration;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* Web adapter auto configuration.
*/
@Configuration
@Import({cn.hippo4j.springboot3.starter.adapter.web.WebThreadPoolHandlerConfiguration.EmbeddedTomcat.class,
cn.hippo4j.springboot3.starter.adapter.web.WebThreadPoolHandlerConfiguration.EmbeddedJetty.class,
cn.hippo4j.springboot3.starter.adapter.web.WebThreadPoolHandlerConfiguration.EmbeddedUndertow.class})
@RequiredArgsConstructor
@AutoConfigureAfter(UtilAutoConfiguration.class)
public class WebAdapterConfiguration {
private final ConfigurableEnvironment environment;
@Bean
@ConditionalOnMissingBean
public ApplicationContextHolder simpleApplicationContextHolder() {
return new ApplicationContextHolder();
}
@Bean
public WebThreadPoolRunStateHandler webThreadPoolRunStateHandler() {
return new WebThreadPoolRunStateHandler();
}
@Bean
@SuppressWarnings("all")
public ThreadPoolRunStateHandler threadPoolRunStateHandler(InetUtils hippo4jInetUtils) {
return new ThreadPoolRunStateHandler(hippo4jInetUtils, environment);
}
@Bean
public WebThreadPoolHandlerChoose webThreadPoolServiceChoose() {
return new WebThreadPoolHandlerChoose();
}
}

@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot3.starter.adapter.web;
import cn.hippo4j.adapter.web.WebThreadPoolRunStateHandler;
import cn.hippo4j.adapter.web.jetty.DefaultJettyWebThreadPoolHandler;
import cn.hippo4j.adapter.web.jetty.JettyWebThreadPoolHandlerAdapt;
import cn.hippo4j.adapter.web.tomcat.DefaultTomcatWebThreadPoolHandler;
import cn.hippo4j.adapter.web.tomcat.TomcatWebThreadPoolHandlerAdapt;
import cn.hippo4j.adapter.web.undertow.DefaultUndertowWebThreadPoolHandler;
import cn.hippo4j.adapter.web.undertow.UndertowWebThreadPoolHandlerAdapt;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory;
import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
import org.springframework.boot.web.embedded.undertow.ConfigurableUndertowWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Web Thread Pool Handler Configuration
**/
@Configuration(proxyBeanMethods = false)
public class WebThreadPoolHandlerConfiguration {
/**
* embedded tomcat
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(name = {"org.apache.catalina.startup.Tomcat", "org.apache.coyote.UpgradeProtocol", "jakarta.servlet.Servlet"})
@ConditionalOnBean(value = ConfigurableTomcatWebServerFactory.class, search = SearchStrategy.CURRENT)
@ConditionalOnMissingBean({DefaultTomcatWebThreadPoolHandler.class, TomcatWebThreadPoolHandlerAdapt.class})
static class EmbeddedTomcat {
@Bean
public TomcatWebThreadPoolHandlerAdapt tomcatWebThreadPoolHandler(WebThreadPoolRunStateHandler webThreadPoolRunStateHandler) {
return new DefaultTomcatWebThreadPoolHandler(webThreadPoolRunStateHandler);
}
}
/**
* embedded jetty
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(name = {"jakarta.servlet.Servlet", "org.eclipse.jetty.server.Server", "org.eclipse.jetty.util.Loader", "org.eclipse.jetty.ee10.webapp.WebAppContext"})
@ConditionalOnBean(value = ConfigurableJettyWebServerFactory.class, search = SearchStrategy.CURRENT)
@ConditionalOnMissingBean({DefaultJettyWebThreadPoolHandler.class, JettyWebThreadPoolHandlerAdapt.class})
static class EmbeddedJetty {
@Bean
public JettyWebThreadPoolHandlerAdapt jettyWebThreadPoolHandler() {
return new DefaultJettyWebThreadPoolHandler();
}
}
/**
* embedded undertow
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(name = {"jakarta.servlet.Servlet", "org.xnio.SslClientAuthMode", "io.undertow.Undertow"})
@ConditionalOnBean(value = ConfigurableUndertowWebServerFactory.class, search = SearchStrategy.CURRENT)
@ConditionalOnMissingBean({DefaultUndertowWebThreadPoolHandler.class, UndertowWebThreadPoolHandlerAdapt.class})
static class EmbeddedUndertow {
@Bean
public UndertowWebThreadPoolHandlerAdapt undertowWebThreadPoolHandler(WebThreadPoolRunStateHandler webThreadPoolRunStateHandler) {
return new DefaultUndertowWebThreadPoolHandler(webThreadPoolRunStateHandler);
}
}
}

@ -27,9 +27,9 @@ import cn.hippo4j.threadpool.dynamic.mode.config.parser.ConfigParserHandler;
import cn.hippo4j.threadpool.dynamic.mode.config.properties.BootstrapConfigProperties;
import cn.hippo4j.threadpool.dynamic.mode.config.refresher.BootstrapConfigPropertiesBinderAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.beans.factory.InitializingBean;
import java.util.HashMap;
import java.util.Map;
@ -40,7 +40,7 @@ import java.util.concurrent.ExecutorService;
* Abstract config thread-pool dynamic refresh.
*/
@Slf4j
public abstract class AbstractConfigThreadPoolDynamicRefresh implements ThreadPoolDynamicRefresh, InitializingBean, ApplicationRunner {
public abstract class AbstractConfigThreadPoolDynamicRefresh implements ThreadPoolDynamicRefresh, ApplicationRunner {
private final BootstrapConfigPropertiesBinderAdapter bootstrapConfigPropertiesBinderAdapter;
protected BootstrapPropertiesInterface bootstrapConfigProperties;
@ -76,17 +76,14 @@ public abstract class AbstractConfigThreadPoolDynamicRefresh implements ThreadPo
ApplicationContextHolder.getInstance().publishEvent(new ThreadPoolConfigDynamicRefreshEvent(this, configProperties));
}
@Override
public void afterPropertiesSet() {
public void run(ApplicationArguments args) {
try {
registerListener();
} catch (Exception ex) {
log.error("Hippo4j failed to initialize register listener.", ex);
}
}
@Override
public void run(ApplicationArguments args) {
try {
publishDynamicThreadPoolEvent((BootstrapConfigProperties) bootstrapConfigProperties);
} catch (Exception ex) {

@ -0,0 +1,4 @@
cn.hippo4j.config.springboot.starter.config.DynamicThreadPoolAutoConfiguration
cn.hippo4j.core.config.UtilAutoConfiguration
cn.hippo4j.message.config.MessageConfiguration
cn.hippo4j.config.springboot.starter.config.MonitorConfiguration

@ -86,5 +86,10 @@
<artifactId>hippo4j-threadpool-kernel-alarm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</dependency>
</dependencies>
</project>

@ -109,9 +109,9 @@ public class DubboThreadPoolAdapter implements ThreadPoolAdapter, ApplicationLis
return;
}
ExecutorRepository executorRepository = ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
ConcurrentMap<String, ConcurrentMap<Integer, ExecutorService>> data =
(ConcurrentMap<String, ConcurrentMap<Integer, ExecutorService>>) ReflectUtil.getFieldValue(executorRepository, "data");
ConcurrentMap<Integer, ExecutorService> executorServiceMap = data.get(poolKey);
ConcurrentMap<String, ConcurrentMap<Object, ExecutorService>> data =
(ConcurrentMap<String, ConcurrentMap<Object, ExecutorService>>) ReflectUtil.getFieldValue(executorRepository, "data");
ConcurrentMap<Object, ExecutorService> executorServiceMap = data.get(poolKey);
executorServiceMap.forEach((key, value) -> dubboProtocolExecutor.put(String.valueOf(key), (ThreadPoolExecutor) value));
} catch (Exception ex) {
log.error("Failed to get Dubbo {} protocol thread pool", Version.getVersion(), ex);

Loading…
Cancel
Save