@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
name: "需求建议"
|
||||||
|
about: 提出针对本项目的想法和建议
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature Request
|
||||||
|
|
||||||
|
请在提交问题之前回答这些问题,谢谢。
|
||||||
|
|
||||||
|
### 您的功能请求是否与问题有关?
|
||||||
|
|
||||||
|
### 描述你想要的功能
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
Fixes #ISSUSE_ID
|
||||||
|
|
||||||
|
Changes proposed in this pull request:
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
|
||||||
|
> Check mailbox configuration when submitting. https://hippo4j.cn/docs/other/contributor
|
@ -0,0 +1,6 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
@ -0,0 +1,67 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# This workflow will build a Java project with Maven
|
||||||
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||||
|
|
||||||
|
name: Continuous Integration
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ develop ]
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/ci.yml'
|
||||||
|
- '**/pom.xml'
|
||||||
|
- '**/src/main/**'
|
||||||
|
- '**/src/test/**'
|
||||||
|
- '!*.md'
|
||||||
|
- '!docs/**'
|
||||||
|
pull_request:
|
||||||
|
branches: [ develop ]
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/ci.yml'
|
||||||
|
- '**/pom.xml'
|
||||||
|
- '**/src/main/**'
|
||||||
|
- '**/src/test/**'
|
||||||
|
- '!*.md'
|
||||||
|
- '!docs/**'
|
||||||
|
repository_dispatch:
|
||||||
|
types: [rerun-ci]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.event_name }}-${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
unix:
|
||||||
|
name: JDK ${{ matrix.java.version }} - on ${{ matrix.os }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
timeout-minutes: 60
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ macos-latest ]
|
||||||
|
java:
|
||||||
|
- {
|
||||||
|
version: 11
|
||||||
|
}
|
||||||
|
- {
|
||||||
|
version: 17
|
||||||
|
}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Build with Maven
|
||||||
|
run: echo y | mvn clean install -Dskip.gpg=true -Dspotless.apply.skip=true
|
@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!--
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<profiles version="13">
|
||||||
|
<profile kind="CodeFormatterProfile" name="'Hippo4j Current'" version="13">
|
||||||
|
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="200"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="200"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="160"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="10"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="106"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="106"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="106"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call.count_dependent" value="16|5|80"/>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
## 启动
|
||||||
|
|
||||||
|
> 依赖 node 版本 16+
|
||||||
|
|
||||||
|
```shell script
|
||||||
|
npm i
|
||||||
|
npm run start
|
||||||
|
```
|
||||||
|
|
||||||
|
## 部署
|
||||||
|
|
||||||
|
```shell script
|
||||||
|
GIT_SSH_COMMAND="ssh -i ~/.ssh/hippo4j" USE_SSH=true docusaurus deploy
|
||||||
|
```
|
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||||
|
};
|
@ -0,0 +1,5 @@
|
|||||||
|
xiaomage:
|
||||||
|
name: 小马哥
|
||||||
|
title: hippo4j 作者
|
||||||
|
url: https://github.com/mabaiwan
|
||||||
|
image_url: https://avatars.githubusercontent.com/u/77398366?v=4
|
@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# 确保脚本抛出遇到的错误
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 生成静态文件
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# 进入生成的文件夹
|
||||||
|
cd build/
|
||||||
|
|
||||||
|
echo 'hippo4j.cn' > CNAME
|
||||||
|
|
||||||
|
git init
|
||||||
|
git add -A
|
||||||
|
git commit -m "auto commit"
|
||||||
|
|
||||||
|
# github
|
||||||
|
git branch -m master main
|
||||||
|
GIT_SSH_COMMAND="ssh -i ~/.ssh/hippo4j" git remote add origin git@github.com:hippo4j/hippo4j.github.io.git
|
||||||
|
GIT_SSH_COMMAND="ssh -i ~/.ssh/hippo4j" git push -u origin main -f
|
||||||
|
|
||||||
|
cd -
|
||||||
|
rm -rf build/
|
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"label": "快速开始",
|
||||||
|
"position": 3,
|
||||||
|
"link": {
|
||||||
|
"type": "generated-index"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
# hippo4j core 线程池监控
|
||||||
|
|
||||||
|
已完成 hippo4j-core 的 [接入工作](/docs/getting-started/hippo4j-core-start) 。
|
||||||
|
|
||||||
|
已安装 Grafana + Prometheus 服务。
|
||||||
|
|
||||||
|
## 线程池监控
|
||||||
|
|
||||||
|
1、引入 actuator。spring 2.x 一般都有版本指定,所以这里不用写版本号。
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.micrometer</groupId>
|
||||||
|
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
2、添加相关配置。
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
management:
|
||||||
|
metrics:
|
||||||
|
export:
|
||||||
|
prometheus:
|
||||||
|
enabled: true
|
||||||
|
server:
|
||||||
|
port: 29999 # 自选
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
exposure:
|
||||||
|
include: '*' # 测试使用,开启了所有端点,生产环境不建议 *
|
||||||
|
spring:
|
||||||
|
dynamic:
|
||||||
|
thread-pool:
|
||||||
|
collect-type: metric
|
||||||
|
```
|
||||||
|
|
||||||
|
3、Prometheus 配置任务,配置成功后需重启。
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- job_name: 'dynamic-thread-pool-job'
|
||||||
|
scrape_interval: 5s
|
||||||
|
metrics_path: '/actuator/prometheus'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['127.0.0.1:29999'] # 如果是 docker 部署,这里需要写本机的 IP
|
||||||
|
```
|
||||||
|
|
||||||
|
4、Grafana 导入数据源。
|
||||||
|
|
||||||
|
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220328231812090.png)
|
||||||
|
|
||||||
|
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220328231849537.png)
|
||||||
|
|
||||||
|
5、Grafana DashBoard 配置。
|
||||||
|
|
||||||
|
关注公众号 `龙台的技术笔记`,回复:`监控`,获取 DashBoard JSON。
|
||||||
|
|
||||||
|
![](https://images-machen.oss-cn-beijing.aliyuncs.com/43_65f6020ed111b6bb3808ec338576bd6b.png)
|
||||||
|
|
||||||
|
|
||||||
|
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220327171957444.png)
|
||||||
|
|
||||||
|
获取到 JSON 文件后,导入至 Grafana。
|
||||||
|
|
||||||
|
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220327171125638.png)
|
||||||
|
|
||||||
|
即可使用 Hippo4j 线程池监控大屏。
|
||||||
|
|
||||||
|
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220327173704982.png)
|
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 27 KiB |
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"label": "运维指南",
|
||||||
|
"position": 4,
|
||||||
|
"link": {
|
||||||
|
"type": "generated-index"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"label": "其它",
|
||||||
|
"position": 5,
|
||||||
|
"link": {
|
||||||
|
"type": "generated-index"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
# 贡献者指南
|
||||||
|
|
||||||
|
为了让您的 id 显示在 contributor 列表中,别忘了以下设置:
|
||||||
|
|
||||||
|
```shell script
|
||||||
|
git config --global user.name "username"
|
||||||
|
git config --global user.email "github账号邮箱"
|
||||||
|
```
|
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
# 加群沟通
|
||||||
|
|
||||||
|
|
||||||
|
对于这个项目,是否有什么不一样看法,欢迎在 Issue 一起沟通交流;或者添加小编微信进交流群。
|
||||||
|
|
||||||
|
![](https://images-machen.oss-cn-beijing.aliyuncs.com/64E583A0-B1DD-49A3-9AEC-8D246E9D5C12.PNG?x-oss-process=image/resize,h_500,w_800)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
# 支持开源
|
||||||
|
|
||||||
|
如果您正在使用这个项目并感觉良好,或者是想支持我继续开发,您可以通过如下 `任意` 方式支持我:
|
||||||
|
|
||||||
|
1. Github star 并分享动态线程池框架 [hippo4j](https://github.com/longtai-cn/hippo4j) :rocket:
|
||||||
|
2. 通过以下二维码 一次性捐款。 我多半会买一杯 ~~咖啡~~ 茶。:tea:
|
||||||
|
|
||||||
|
谢谢! :heart:
|
||||||
|
|
||||||
|
| 微信赞赏 | 支付宝 |
|
||||||
|
| :---: | :---: |
|
||||||
|
| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/IMG_6719_2.jpg?x-oss-process=image/resize,h_180,w_180) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/IMG_6720_3.jpg?x-oss-process=image/resize,h_180,w_180) |
|
||||||
|
|
||||||
|
### 致谢
|
||||||
|
|
||||||
|
感谢给予支持的朋友,您的支持是我前进的动力 🎉
|
||||||
|
|
||||||
|
|
||||||
|
| | ID | 赞赏金额 | 时间 | 备注 |
|
||||||
|
| ---- | ------- | ---- | ---------- | ------------------------------------ |
|
||||||
|
| 1 | 六月飞雪 | 30.00 | 2021-12-30 | 代码设计很优雅的一款框架,继续加油! |
|
||||||
|
| 2 | 孙大圣 | 26.6 | 2022-03-23 | 学习一下😁😁 |
|
||||||
|
| 3 | Easy 点 | 66.00 | 2022-04-09 | 好货好技术当加赏 |
|
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"label": "用户指南",
|
||||||
|
"position": 2,
|
||||||
|
"link": {
|
||||||
|
"type": "generated-index",
|
||||||
|
"description": "帮助想要了解 Hippo4J 的用户快速掌握核心开发理念。"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "website",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"docusaurus": "docusaurus",
|
||||||
|
"start": "docusaurus start",
|
||||||
|
"build": "docusaurus build",
|
||||||
|
"swizzle": "docusaurus swizzle",
|
||||||
|
"deploy": "docusaurus deploy",
|
||||||
|
"clear": "docusaurus clear",
|
||||||
|
"serve": "docusaurus serve",
|
||||||
|
"write-translations": "docusaurus write-translations",
|
||||||
|
"write-heading-ids": "docusaurus write-heading-ids"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@docusaurus/core": "2.0.0-beta.21",
|
||||||
|
"@docusaurus/preset-classic": "2.0.0-beta.21",
|
||||||
|
"@mdx-js/react": "^1.6.22",
|
||||||
|
"clsx": "^1.1.1",
|
||||||
|
"prism-react-renderer": "^1.3.3",
|
||||||
|
"react": "^17.0.2",
|
||||||
|
"react-dom": "^17.0.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@docusaurus/module-type-aliases": "2.0.0-beta.21"
|
||||||
|
},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.5%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 1 chrome version",
|
||||||
|
"last 1 firefox version",
|
||||||
|
"last 1 safari version"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Creating a sidebar enables you to:
|
||||||
|
- create an ordered group of docs
|
||||||
|
- render a sidebar for each doc of that group
|
||||||
|
- provide next/previous navigation
|
||||||
|
|
||||||
|
The sidebars can be generated from the filesystem, or explicitly defined here.
|
||||||
|
|
||||||
|
Create as many sidebars as you want.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||||
|
const sidebars = {
|
||||||
|
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||||
|
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||||
|
|
||||||
|
// But you can create a sidebar manually
|
||||||
|
/*
|
||||||
|
tutorialSidebar: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
label: 'Tutorial',
|
||||||
|
items: ['hello'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = sidebars;
|
@ -0,0 +1,11 @@
|
|||||||
|
.features {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 2rem 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureSvg {
|
||||||
|
height: 200px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
@ -0,0 +1,211 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/*
|
||||||
|
See css var + hsl color palette technique:
|
||||||
|
https://blog.maximeheckel.com/posts/the-power-of-composition-with-css-variables/
|
||||||
|
*/
|
||||||
|
--site-primary-hue-saturation: 167 68%;
|
||||||
|
--site-primary-hue-saturation-light: 167 56%; /* do we really need this extra one? */
|
||||||
|
--site-color-favorite-background: #f6fdfd;
|
||||||
|
--site-color-tooltip: #fff;
|
||||||
|
--site-color-tooltip-background: #353738;
|
||||||
|
--site-color-svg-icon-favorite: #e9669e;
|
||||||
|
--site-color-checkbox-checked-bg: hsl(167deg 56% 73% / 25%);
|
||||||
|
--site-color-feedback-background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-theme='dark'] {
|
||||||
|
--site-color-feedback-background: #f0f8ff;
|
||||||
|
--site-color-favorite-background: #1d1e1e;
|
||||||
|
--site-color-checkbox-checked-bg: hsl(167deg 56% 73% / 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='light'] {
|
||||||
|
--ifm-color-primary: hsl(var(--site-primary-hue-saturation) 30%);
|
||||||
|
--ifm-color-primary-dark: hsl(var(--site-primary-hue-saturation) 26%);
|
||||||
|
--ifm-color-primary-darker: hsl(var(--site-primary-hue-saturation) 23%);
|
||||||
|
--ifm-color-primary-darkest: hsl(var(--site-primary-hue-saturation) 17%);
|
||||||
|
|
||||||
|
--ifm-color-primary-light: hsl(var(--site-primary-hue-saturation-light) 39%);
|
||||||
|
--ifm-color-primary-lighter: hsl(
|
||||||
|
var(--site-primary-hue-saturation-light) 47%
|
||||||
|
);
|
||||||
|
--ifm-color-primary-lightest: hsl(
|
||||||
|
var(--site-primary-hue-saturation-light) 58%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] {
|
||||||
|
--ifm-color-primary: hsl(var(--site-primary-hue-saturation) 45%);
|
||||||
|
--ifm-color-primary-dark: hsl(var(--site-primary-hue-saturation) 41%);
|
||||||
|
--ifm-color-primary-darker: hsl(var(--site-primary-hue-saturation) 38%);
|
||||||
|
--ifm-color-primary-darkest: hsl(var(--site-primary-hue-saturation) 32%);
|
||||||
|
|
||||||
|
--ifm-color-primary-light: hsl(var(--site-primary-hue-saturation-light) 54%);
|
||||||
|
--ifm-color-primary-lighter: hsl(
|
||||||
|
var(--site-primary-hue-saturation-light) 62%
|
||||||
|
);
|
||||||
|
--ifm-color-primary-lightest: hsl(
|
||||||
|
var(--site-primary-hue-saturation-light) 73%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.docusaurus-highlight-code-line {
|
||||||
|
background-color: rgb(0 0 0 / 10%);
|
||||||
|
display: block;
|
||||||
|
margin: 0 calc(-1 * var(--ifm-pre-padding));
|
||||||
|
padding: 0 var(--ifm-pre-padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .docusaurus-highlight-code-line {
|
||||||
|
background-color: rgb(66 66 66 / 30%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-github-link:hover {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-github-link::before {
|
||||||
|
content: '';
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .header-github-link::before {
|
||||||
|
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer--dark {
|
||||||
|
--ifm-footer-background-color: #2b3137;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unique-tabs .tabs__item {
|
||||||
|
line-height: 16px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unique-tabs .tabs__item--active {
|
||||||
|
border: 0;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: var(--ifm-global-radius);
|
||||||
|
background-color: var(--ifm-tabs-color-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='light'] .themedDocusaurus [fill='#FFFF50'] {
|
||||||
|
fill: greenyellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .themedDocusaurus [fill='#FFFF50'] {
|
||||||
|
fill: seagreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='light'] .DocSearch {
|
||||||
|
/* --docsearch-primary-color: var(--ifm-color-primary); */
|
||||||
|
/* --docsearch-text-color: var(--ifm-font-color-base); */
|
||||||
|
--docsearch-muted-color: var(--ifm-color-emphasis-700);
|
||||||
|
--docsearch-container-background: rgb(94 100 112 / 70%);
|
||||||
|
/* Modal */
|
||||||
|
--docsearch-modal-background: var(--ifm-color-secondary-lighter);
|
||||||
|
/* Search box */
|
||||||
|
--docsearch-searchbox-background: var(--ifm-color-secondary);
|
||||||
|
--docsearch-searchbox-focus-background: var(--ifm-color-white);
|
||||||
|
/* Hit */
|
||||||
|
--docsearch-hit-color: var(--ifm-font-color-base);
|
||||||
|
--docsearch-hit-active-color: var(--ifm-color-white);
|
||||||
|
--docsearch-hit-background: var(--ifm-color-white);
|
||||||
|
/* Footer */
|
||||||
|
--docsearch-footer-background: var(--ifm-color-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .DocSearch {
|
||||||
|
--docsearch-text-color: var(--ifm-font-color-base);
|
||||||
|
--docsearch-muted-color: var(--ifm-color-secondary-darkest);
|
||||||
|
--docsearch-container-background: rgb(47 55 69 / 70%);
|
||||||
|
/* Modal */
|
||||||
|
--docsearch-modal-background: var(--ifm-background-color);
|
||||||
|
/* Search box */
|
||||||
|
--docsearch-searchbox-background: var(--ifm-background-color);
|
||||||
|
--docsearch-searchbox-focus-background: var(--ifm-color-black);
|
||||||
|
/* Hit */
|
||||||
|
--docsearch-hit-color: var(--ifm-font-color-base);
|
||||||
|
--docsearch-hit-active-color: var(--ifm-color-white);
|
||||||
|
--docsearch-hit-background: var(--ifm-color-emphasis-100);
|
||||||
|
/* Footer */
|
||||||
|
--docsearch-footer-background: var(--ifm-background-surface-color);
|
||||||
|
--docsearch-key-gradient: linear-gradient(
|
||||||
|
-26.5deg,
|
||||||
|
var(--ifm-color-emphasis-200) 0%,
|
||||||
|
var(--ifm-color-emphasis-100) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
div[class^='announcementBar_'] {
|
||||||
|
--site-announcement-bar-stripe-color1: hsl(
|
||||||
|
var(--site-primary-hue-saturation) 85%
|
||||||
|
);
|
||||||
|
--site-announcement-bar-stripe-color2: hsl(
|
||||||
|
var(--site-primary-hue-saturation) 95%
|
||||||
|
);
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
35deg,
|
||||||
|
var(--site-announcement-bar-stripe-color1),
|
||||||
|
var(--site-announcement-bar-stripe-color1) 20px,
|
||||||
|
var(--site-announcement-bar-stripe-color2) 10px,
|
||||||
|
var(--site-announcement-bar-stripe-color2) 40px
|
||||||
|
);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red > a {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen-reader-only {
|
||||||
|
border: 0;
|
||||||
|
clip: rect(0 0 0 0);
|
||||||
|
clip-path: polygon(0 0, 0 0, 0 0);
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='light'] img[src$='#gh-dark-mode-only'],
|
||||||
|
[data-theme='dark'] img[src$='#gh-light-mode-only'] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Used to test CSS insertion order */
|
||||||
|
.test-marker-site-custom-css-unique-rule {
|
||||||
|
content: 'site-custom-css-unique-rule';
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 996px) {
|
||||||
|
.video-container {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 560px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding-top: 56.25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-container iframe {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* CSS files with the .module.css suffix will be treated as CSS modules
|
||||||
|
* and scoped locally.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.heroBanner {
|
||||||
|
padding: 4rem 0;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 996px) {
|
||||||
|
.heroBanner {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Markdown page example
|
||||||
|
---
|
||||||
|
|
||||||
|
# Markdown page example
|
||||||
|
|
||||||
|
You don't need React to write simple standalone pages.
|
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 5.5 KiB |
@ -0,0 +1,51 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>hippo4j-adapter-base</artifactId>
|
||||||
|
<name>hippo4j-adapter-base</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
<Built-By>chen.ma</Built-By>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.base;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapt to the thread pool of the third-party framework.
|
||||||
|
*/
|
||||||
|
public interface ThreadPoolAdapter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Framework thread pool identification.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String mark();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the core parameters of the framework thread pool.
|
||||||
|
*
|
||||||
|
* @param identify Thread pool unique id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ThreadPoolAdapterState getThreadPoolState(String identify);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the core parameters of the framework thread pool.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
default List<ThreadPoolAdapterState> getThreadPoolStates() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify the core parameters of the framework thread pool.
|
||||||
|
*
|
||||||
|
* @param threadPoolAdapterParameter Thread pool parameters to be modified
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter);
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.base;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.config.ApplicationContextHolder;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-pool adapter bean container.
|
||||||
|
*/
|
||||||
|
public class ThreadPoolAdapterBeanContainer implements InitializingBean {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store three-party thread pool framework bean instances.
|
||||||
|
*/
|
||||||
|
public static final Map<String, ThreadPoolAdapter> THREAD_POOL_ADAPTER_BEAN_CONTAINER = Maps.newConcurrentMap();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
Map<String, ThreadPoolAdapter> threadPoolAdapterMap = ApplicationContextHolder.getBeansOfType(ThreadPoolAdapter.class);
|
||||||
|
threadPoolAdapterMap.forEach((key, val) -> THREAD_POOL_ADAPTER_BEAN_CONTAINER.put(val.mark(), val));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.base;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-pool adapter cache config.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ThreadPoolAdapterCacheConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark
|
||||||
|
*/
|
||||||
|
private String mark;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tenant item key
|
||||||
|
*/
|
||||||
|
private String tenantItemKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client identify
|
||||||
|
*/
|
||||||
|
private String clientIdentify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Active
|
||||||
|
*/
|
||||||
|
private String active;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client address
|
||||||
|
*/
|
||||||
|
private String clientAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-pool adapter states
|
||||||
|
*/
|
||||||
|
private List<ThreadPoolAdapterState> threadPoolAdapterStates;
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.base;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread pool adapter parameter info.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ThreadPoolAdapterParameter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark
|
||||||
|
*/
|
||||||
|
private String mark;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-pool key
|
||||||
|
*/
|
||||||
|
private String threadPoolKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core pool size
|
||||||
|
*/
|
||||||
|
private Integer corePoolSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum pool size
|
||||||
|
*/
|
||||||
|
private Integer maximumPoolSize;
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.base;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide registration for each adaptation
|
||||||
|
*/
|
||||||
|
public interface ThreadPoolAdapterRegisterAction {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getThreadPoolAdapterCacheConfigs
|
||||||
|
*
|
||||||
|
* @param threadPoolAdapterMap
|
||||||
|
* @return List<ThreadPoolAdapterCacheConfig>
|
||||||
|
*/
|
||||||
|
List<ThreadPoolAdapterCacheConfig> getThreadPoolAdapterCacheConfigs(Map<String, ThreadPoolAdapter> threadPoolAdapterMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* doRegister
|
||||||
|
*
|
||||||
|
* @param cacheConfigList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void doRegister(List<ThreadPoolAdapterCacheConfig> cacheConfigList);
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.base;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread pool adapter state info.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ThreadPoolAdapterState {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-pool keu
|
||||||
|
*/
|
||||||
|
private String threadPoolKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Active
|
||||||
|
*/
|
||||||
|
private String active;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* identify
|
||||||
|
*/
|
||||||
|
private String identify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client address
|
||||||
|
*/
|
||||||
|
private String clientAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core size
|
||||||
|
*/
|
||||||
|
private Integer coreSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum size
|
||||||
|
*/
|
||||||
|
private Integer maximumSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocking queue type
|
||||||
|
*/
|
||||||
|
private String blockingQueueType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocking queue capacity
|
||||||
|
*/
|
||||||
|
private Integer blockingQueueCapacity;
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>hippo4j-adapter-dubbo</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter-base</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.dubbo</groupId>
|
||||||
|
<artifactId>dubbo</artifactId>
|
||||||
|
<version>3.0.5</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
<Built-By>chen.ma</Built-By>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cn.hippo4j.adapter.dubbo;
|
||||||
|
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
|
||||||
|
import cn.hippo4j.common.toolkit.ReflectUtil;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.dubbo.common.Version;
|
||||||
|
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||||
|
import org.apache.dubbo.common.store.DataStore;
|
||||||
|
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dubbo thread-pool adapter.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class DubboThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
|
||||||
|
|
||||||
|
private final Map<String, ThreadPoolExecutor> DUBBO_PROTOCOL_EXECUTOR = Maps.newHashMap();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String mark() {
|
||||||
|
return "Dubbo";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolAdapterState getThreadPoolState(String identify) {
|
||||||
|
ThreadPoolAdapterState threadPoolAdapterState = new ThreadPoolAdapterState();
|
||||||
|
ThreadPoolExecutor executor = DUBBO_PROTOCOL_EXECUTOR.get(identify);
|
||||||
|
if (executor == null) {
|
||||||
|
log.warn("[{}] Dubbo consuming thread pool not found.", identify);
|
||||||
|
return threadPoolAdapterState;
|
||||||
|
}
|
||||||
|
threadPoolAdapterState.setThreadPoolKey(identify);
|
||||||
|
threadPoolAdapterState.setCoreSize(executor.getCorePoolSize());
|
||||||
|
threadPoolAdapterState.setMaximumSize(executor.getMaximumPoolSize());
|
||||||
|
return threadPoolAdapterState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ThreadPoolAdapterState> getThreadPoolStates() {
|
||||||
|
List<ThreadPoolAdapterState> threadPoolAdapterStates = new ArrayList<>();
|
||||||
|
DUBBO_PROTOCOL_EXECUTOR.forEach((kel, val) -> threadPoolAdapterStates.add(getThreadPoolState(String.valueOf(val))));
|
||||||
|
return threadPoolAdapterStates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) {
|
||||||
|
String threadPoolKey = threadPoolAdapterParameter.getThreadPoolKey();
|
||||||
|
ThreadPoolExecutor executor = DUBBO_PROTOCOL_EXECUTOR.get(threadPoolAdapterParameter.getThreadPoolKey());
|
||||||
|
if (executor == null) {
|
||||||
|
log.warn("[{}] Dubbo consuming thread pool not found.", threadPoolKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int originalCoreSize = executor.getCorePoolSize();
|
||||||
|
int originalMaximumPoolSize = executor.getMaximumPoolSize();
|
||||||
|
executor.setCorePoolSize(threadPoolAdapterParameter.getCorePoolSize());
|
||||||
|
executor.setMaximumPoolSize(threadPoolAdapterParameter.getMaximumPoolSize());
|
||||||
|
log.info("[{}] Dubbo consumption thread pool parameter change. coreSize :: {}, maximumSize :: {}",
|
||||||
|
threadPoolKey,
|
||||||
|
String.format(CHANGE_DELIMITER, originalCoreSize, executor.getCorePoolSize()),
|
||||||
|
String.format(CHANGE_DELIMITER, originalMaximumPoolSize, executor.getMaximumPoolSize()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||||
|
boolean is2xVersion = false;
|
||||||
|
String poolKey = ExecutorService.class.getName();
|
||||||
|
if (Version.getIntVersion(Version.getVersion()) < 3000000) {
|
||||||
|
is2xVersion = true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (is2xVersion) {
|
||||||
|
DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();
|
||||||
|
Map<String, Object> executors = dataStore.get(poolKey);
|
||||||
|
executors.forEach((key, value) -> DUBBO_PROTOCOL_EXECUTOR.put(key, (ThreadPoolExecutor) value));
|
||||||
|
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);
|
||||||
|
executorServiceMap.forEach((key, value) -> DUBBO_PROTOCOL_EXECUTOR.put(String.valueOf(key), (ThreadPoolExecutor) value));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to get Dubbo {}.X protocol thread pool", is2xVersion ? "2" : "3", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>hippo4j-adapter-hystrix</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter-base</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
|
||||||
|
<version>${spring-cloud-starter-netflix-hystrix.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
<Built-By>chen.ma</Built-By>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.hystrix;
|
||||||
|
|
||||||
|
import cn.hippo4j.adapter.base.*;
|
||||||
|
import cn.hippo4j.common.config.ApplicationContextHolder;
|
||||||
|
import cn.hippo4j.common.toolkit.CollectionUtil;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.netflix.hystrix.HystrixThreadPool;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hystrix thread-pool adapter.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
|
||||||
|
|
||||||
|
private static final String THREAD_POOL_FIELD = "threadPool";
|
||||||
|
|
||||||
|
private static final String THREAD_POOLS_FIELD = "threadPools";
|
||||||
|
|
||||||
|
private final Map<String, ThreadPoolExecutor> HYSTRIX_CONSUME_EXECUTOR = Maps.newHashMap();
|
||||||
|
|
||||||
|
private ThreadPoolAdapterScheduler threadPoolAdapterScheduler;
|
||||||
|
|
||||||
|
public HystrixThreadPoolAdapter(ThreadPoolAdapterScheduler threadPoolAdapterScheduler) {
|
||||||
|
this.threadPoolAdapterScheduler = threadPoolAdapterScheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String mark() {
|
||||||
|
return "Hystrix";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolAdapterState getThreadPoolState(String identify) {
|
||||||
|
ThreadPoolAdapterState result = new ThreadPoolAdapterState();
|
||||||
|
ThreadPoolExecutor threadPoolExecutor = HYSTRIX_CONSUME_EXECUTOR.get(identify);
|
||||||
|
if (threadPoolExecutor != null) {
|
||||||
|
result.setThreadPoolKey(identify);
|
||||||
|
result.setCoreSize(threadPoolExecutor.getCorePoolSize());
|
||||||
|
result.setMaximumSize(threadPoolExecutor.getMaximumPoolSize());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
log.warn("[{}] hystrix thread pool not found.", identify);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ThreadPoolAdapterState> getThreadPoolStates() {
|
||||||
|
List<ThreadPoolAdapterState> threadPoolAdapterStates = new ArrayList<>();
|
||||||
|
HYSTRIX_CONSUME_EXECUTOR.forEach((kel, val) -> threadPoolAdapterStates.add(getThreadPoolState(kel)));
|
||||||
|
return threadPoolAdapterStates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) {
|
||||||
|
String threadPoolKey = threadPoolAdapterParameter.getThreadPoolKey();
|
||||||
|
ThreadPoolExecutor threadPoolExecutor = HYSTRIX_CONSUME_EXECUTOR.get(threadPoolKey);
|
||||||
|
if (threadPoolExecutor == null) {
|
||||||
|
log.warn("[{}] hystrix thread pool not found.", threadPoolKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int originalCoreSize = threadPoolExecutor.getCorePoolSize();
|
||||||
|
int originalMaximumPoolSize = threadPoolExecutor.getMaximumPoolSize();
|
||||||
|
threadPoolExecutor.setCorePoolSize(threadPoolAdapterParameter.getCorePoolSize());
|
||||||
|
threadPoolExecutor.setMaximumPoolSize(threadPoolAdapterParameter.getMaximumPoolSize());
|
||||||
|
log.info("[{}] hystrix thread pool parameter change. coreSize :: {}, maximumSize :: {}",
|
||||||
|
threadPoolKey,
|
||||||
|
String.format(CHANGE_DELIMITER, originalCoreSize, threadPoolExecutor.getCorePoolSize()),
|
||||||
|
String.format(CHANGE_DELIMITER, originalMaximumPoolSize, threadPoolExecutor.getMaximumPoolSize()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||||
|
ScheduledExecutorService scheduler = threadPoolAdapterScheduler.getScheduler();
|
||||||
|
int taskIntervalSeconds = threadPoolAdapterScheduler.getTaskIntervalSeconds();
|
||||||
|
|
||||||
|
// Periodically update the Hystrix thread pool
|
||||||
|
HystrixThreadPoolRefreshTask hystrixThreadPoolRefreshTask = new HystrixThreadPoolRefreshTask(scheduler, taskIntervalSeconds);
|
||||||
|
scheduler.schedule(hystrixThreadPoolRefreshTask, taskIntervalSeconds, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
// Periodically refresh registration
|
||||||
|
ThreadPoolAdapterRegisterAction threadPoolAdapterRegisterAction = ApplicationContextHolder.getBean(ThreadPoolAdapterRegisterAction.class);
|
||||||
|
Map<String, ? extends HystrixThreadPoolAdapter> beansOfType = ApplicationContextHolder.getBeansOfType(this.getClass());
|
||||||
|
Map<String, ThreadPoolAdapter> map = Maps.newHashMap(beansOfType);
|
||||||
|
|
||||||
|
ThreadPoolAdapterRegisterTask threadPoolAdapterRegisterTask = new ThreadPoolAdapterRegisterTask(scheduler, taskIntervalSeconds, map, threadPoolAdapterRegisterAction);
|
||||||
|
scheduler.schedule(threadPoolAdapterRegisterTask, threadPoolAdapterScheduler.getTaskIntervalSeconds(), TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hystrixThreadPoolRefresh() {
|
||||||
|
try {
|
||||||
|
Class<HystrixThreadPool.Factory> factoryClass = HystrixThreadPool.Factory.class;
|
||||||
|
Field threadPoolsField = factoryClass.getDeclaredField(THREAD_POOLS_FIELD);
|
||||||
|
threadPoolsField.setAccessible(true);
|
||||||
|
ConcurrentHashMap<String, HystrixThreadPool> threadPools =
|
||||||
|
(ConcurrentHashMap<String, HystrixThreadPool>) threadPoolsField.get(factoryClass);
|
||||||
|
if (CollectionUtil.isNotEmpty(threadPools)) {
|
||||||
|
for (Map.Entry<String, HystrixThreadPool> stringHystrixThreadPoolEntry : threadPools.entrySet()) {
|
||||||
|
String key = stringHystrixThreadPoolEntry.getKey();
|
||||||
|
HystrixThreadPool value = stringHystrixThreadPoolEntry.getValue();
|
||||||
|
if (value instanceof HystrixThreadPool.HystrixThreadPoolDefault) {
|
||||||
|
HystrixThreadPool.HystrixThreadPoolDefault hystrixThreadPoolDefault =
|
||||||
|
(HystrixThreadPool.HystrixThreadPoolDefault) value;
|
||||||
|
Class<? extends HystrixThreadPool.HystrixThreadPoolDefault> hystrixThreadPoolDefaultClass = hystrixThreadPoolDefault.getClass();
|
||||||
|
Field threadPoolField = hystrixThreadPoolDefaultClass.getDeclaredField(THREAD_POOL_FIELD);
|
||||||
|
threadPoolField.setAccessible(true);
|
||||||
|
ThreadPoolExecutor threadPoolExecutor =
|
||||||
|
(ThreadPoolExecutor) threadPoolField.get(hystrixThreadPoolDefault);
|
||||||
|
HYSTRIX_CONSUME_EXECUTOR.put(key, threadPoolExecutor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to get Hystrix thread pool.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean compareThreadPoolAdapterCacheConfigs(List<ThreadPoolAdapterCacheConfig> newThreadPoolAdapterCacheConfigs,
|
||||||
|
List<ThreadPoolAdapterCacheConfig> oldThreadPoolAdapterCacheConfigs) {
|
||||||
|
boolean registerFlag = false;
|
||||||
|
Map<String, List<ThreadPoolAdapterState>> newThreadPoolAdapterCacheConfigMap =
|
||||||
|
newThreadPoolAdapterCacheConfigs.stream().collect(Collectors.toMap(
|
||||||
|
ThreadPoolAdapterCacheConfig::getMark, ThreadPoolAdapterCacheConfig::getThreadPoolAdapterStates, (k1, k2) -> k2));
|
||||||
|
Map<String, List<ThreadPoolAdapterState>> oldThreadPoolAdapterCacheConfigMap =
|
||||||
|
oldThreadPoolAdapterCacheConfigs.stream().collect(Collectors.toMap(
|
||||||
|
ThreadPoolAdapterCacheConfig::getMark, ThreadPoolAdapterCacheConfig::getThreadPoolAdapterStates, (k1, k2) -> k2));
|
||||||
|
for (Map.Entry<String, List<ThreadPoolAdapterState>> entry : newThreadPoolAdapterCacheConfigMap.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
List<ThreadPoolAdapterState> newValue = entry.getValue();
|
||||||
|
List<ThreadPoolAdapterState> oldValue = oldThreadPoolAdapterCacheConfigMap.get(key);
|
||||||
|
if (oldValue == null) {
|
||||||
|
registerFlag = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (newValue.size() != oldValue.size()) {
|
||||||
|
registerFlag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return registerFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hystrix Thread Pool Refresh Task
|
||||||
|
*/
|
||||||
|
class HystrixThreadPoolRefreshTask implements Runnable {
|
||||||
|
|
||||||
|
private ScheduledExecutorService scheduler;
|
||||||
|
|
||||||
|
private int taskIntervalSeconds;
|
||||||
|
|
||||||
|
public HystrixThreadPoolRefreshTask(ScheduledExecutorService scheduler, int taskIntervalSeconds) {
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
this.taskIntervalSeconds = taskIntervalSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
hystrixThreadPoolRefresh();
|
||||||
|
} finally {
|
||||||
|
if (!scheduler.isShutdown()) {
|
||||||
|
scheduler.schedule(this, taskIntervalSeconds, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreadPoolAdapterRegisterTask implements Runnable {
|
||||||
|
|
||||||
|
private ScheduledExecutorService scheduler;
|
||||||
|
|
||||||
|
private int taskIntervalSeconds;
|
||||||
|
|
||||||
|
Map<String, ThreadPoolAdapter> threadPoolAdapterMap;
|
||||||
|
|
||||||
|
ThreadPoolAdapterRegisterAction threadPoolAdapterRegisterAction;
|
||||||
|
|
||||||
|
private List<ThreadPoolAdapterCacheConfig> cacheConfigList = Lists.newArrayList();
|
||||||
|
|
||||||
|
public ThreadPoolAdapterRegisterTask(ScheduledExecutorService scheduler, int taskIntervalSeconds,
|
||||||
|
Map<String, ThreadPoolAdapter> threadPoolAdapterMap,
|
||||||
|
ThreadPoolAdapterRegisterAction threadPoolAdapterRegisterAction) {
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
this.taskIntervalSeconds = taskIntervalSeconds;
|
||||||
|
this.threadPoolAdapterMap = threadPoolAdapterMap;
|
||||||
|
this.threadPoolAdapterRegisterAction = threadPoolAdapterRegisterAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
List<ThreadPoolAdapterCacheConfig> newThreadPoolAdapterCacheConfigs = threadPoolAdapterRegisterAction.getThreadPoolAdapterCacheConfigs(threadPoolAdapterMap);
|
||||||
|
boolean registerFlag = compareThreadPoolAdapterCacheConfigs(newThreadPoolAdapterCacheConfigs, cacheConfigList);
|
||||||
|
cacheConfigList = newThreadPoolAdapterCacheConfigs;
|
||||||
|
if (registerFlag) {
|
||||||
|
threadPoolAdapterRegisterAction.doRegister(cacheConfigList);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Register Task Error", e);
|
||||||
|
} finally {
|
||||||
|
if (!scheduler.isShutdown()) {
|
||||||
|
scheduler.schedule(this, taskIntervalSeconds, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.hystrix;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* thread pool adapter schedule.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class ThreadPoolAdapterScheduler {
|
||||||
|
|
||||||
|
private static final int TASK_INTERVAL_SECONDS = 10;
|
||||||
|
|
||||||
|
private final ScheduledExecutorService scheduler;
|
||||||
|
|
||||||
|
public ThreadPoolAdapterScheduler() {
|
||||||
|
scheduler = new ScheduledThreadPoolExecutor(2,
|
||||||
|
new ThreadFactoryBuilder()
|
||||||
|
.setNameFormat("threadPoolAdapter")
|
||||||
|
.setDaemon(true)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScheduledExecutorService getScheduler() {
|
||||||
|
return scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTaskIntervalSeconds() {
|
||||||
|
return TASK_INTERVAL_SECONDS;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>hippo4j-adapter-kafka</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter-base</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
<Built-By>chen.ma</Built-By>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.kafka;
|
||||||
|
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kafka thread-pool adapter.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class KafkaThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String mark() {
|
||||||
|
return "Kafka";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolAdapterState getThreadPoolState(String identify) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>hippo4j-adapter-rabbitmq</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter-base</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
<Built-By>chen.ma</Built-By>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.rabbitmq;
|
||||||
|
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
|
||||||
|
import cn.hippo4j.common.toolkit.ReflectUtil;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RabbitMQ thread-pool adapter.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class RabbitMQThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
|
||||||
|
|
||||||
|
private static final String RABBITMQ = "RabbitMQ";
|
||||||
|
|
||||||
|
private static final String FiledName = "executorService";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO Configurable name
|
||||||
|
*/
|
||||||
|
private static final String RABBITMQ_EXECUTOR_SERVICE = "Rabbitmq_Executor_Service";
|
||||||
|
|
||||||
|
private final AbstractConnectionFactory abstractConnectionFactory;
|
||||||
|
|
||||||
|
private final Map<String, ThreadPoolExecutor> RABBITMQ_THREAD_POOL_TASK_EXECUTOR = Maps.newHashMap();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String mark() {
|
||||||
|
return RABBITMQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolAdapterState getThreadPoolState(String identify) {
|
||||||
|
ThreadPoolAdapterState threadPoolAdapterState = new ThreadPoolAdapterState();
|
||||||
|
ThreadPoolExecutor threadPoolTaskExecutor = RABBITMQ_THREAD_POOL_TASK_EXECUTOR.get(identify);
|
||||||
|
threadPoolAdapterState.setThreadPoolKey(identify);
|
||||||
|
if (Objects.nonNull(threadPoolTaskExecutor)) {
|
||||||
|
threadPoolAdapterState.setCoreSize(threadPoolTaskExecutor.getCorePoolSize());
|
||||||
|
threadPoolAdapterState.setMaximumSize(threadPoolTaskExecutor.getMaximumPoolSize());
|
||||||
|
}
|
||||||
|
return threadPoolAdapterState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ThreadPoolAdapterState> getThreadPoolStates() {
|
||||||
|
List<ThreadPoolAdapterState> adapterStateList = Lists.newArrayList();
|
||||||
|
RABBITMQ_THREAD_POOL_TASK_EXECUTOR.forEach(
|
||||||
|
(key, val) -> adapterStateList.add(getThreadPoolState(key)));
|
||||||
|
return adapterStateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) {
|
||||||
|
String threadPoolKey = threadPoolAdapterParameter.getThreadPoolKey();
|
||||||
|
ThreadPoolExecutor threadPoolTaskExecutor = RABBITMQ_THREAD_POOL_TASK_EXECUTOR.get(threadPoolKey);
|
||||||
|
if (Objects.nonNull(threadPoolTaskExecutor)) {
|
||||||
|
int originalCoreSize = threadPoolTaskExecutor.getCorePoolSize();
|
||||||
|
int originalMaximumPoolSize = threadPoolTaskExecutor.getMaximumPoolSize();
|
||||||
|
threadPoolTaskExecutor.setMaximumPoolSize(threadPoolAdapterParameter.getMaximumPoolSize());
|
||||||
|
threadPoolTaskExecutor.setCorePoolSize(threadPoolAdapterParameter.getCorePoolSize());
|
||||||
|
log.info("[{}] rabbitmq consumption thread pool parameter change. coreSize :: {}, maximumSize :: {}",
|
||||||
|
threadPoolKey,
|
||||||
|
String.format(CHANGE_DELIMITER, originalCoreSize, threadPoolAdapterParameter.getCorePoolSize()),
|
||||||
|
String.format(CHANGE_DELIMITER, originalMaximumPoolSize, threadPoolAdapterParameter.getMaximumPoolSize()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log.warn("[{}] rabbitmq consuming thread pool not found.", threadPoolKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||||
|
ExecutorService executor = (ExecutorService) ReflectUtil.getFieldValue(abstractConnectionFactory, FiledName);
|
||||||
|
if (Objects.nonNull(executor)) {
|
||||||
|
if (executor instanceof ThreadPoolExecutor) {
|
||||||
|
ThreadPoolExecutor threadPoolTaskExecutor = (ThreadPoolExecutor) executor;
|
||||||
|
RABBITMQ_THREAD_POOL_TASK_EXECUTOR.put(RABBITMQ_EXECUTOR_SERVICE, threadPoolTaskExecutor);
|
||||||
|
log.info("rabbitmq executor name {}", RABBITMQ_EXECUTOR_SERVICE);
|
||||||
|
} else {
|
||||||
|
log.warn("Custom thread pools only support ThreadPoolExecutor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>hippo4j-adapter-rocketmq</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter-base</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.rocketmq</groupId>
|
||||||
|
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||||
|
<version>${rocketmq.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
<Built-By>chen.ma</Built-By>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.rocketmq;
|
||||||
|
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
|
||||||
|
import cn.hippo4j.common.config.ApplicationContextHolder;
|
||||||
|
import cn.hippo4j.common.toolkit.ReflectUtil;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
|
||||||
|
import org.apache.rocketmq.client.impl.consumer.ConsumeMessageService;
|
||||||
|
import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RocketMQ thread-pool adapter.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class RocketMQThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
|
||||||
|
|
||||||
|
private final Map<String, ThreadPoolExecutor> ROCKET_MQ_CONSUME_EXECUTOR = Maps.newHashMap();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String mark() {
|
||||||
|
return "RocketMQ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolAdapterState getThreadPoolState(String identify) {
|
||||||
|
ThreadPoolAdapterState result = new ThreadPoolAdapterState();
|
||||||
|
ThreadPoolExecutor rocketMQConsumeExecutor = ROCKET_MQ_CONSUME_EXECUTOR.get(identify);
|
||||||
|
if (rocketMQConsumeExecutor != null) {
|
||||||
|
result.setThreadPoolKey(identify);
|
||||||
|
result.setCoreSize(rocketMQConsumeExecutor.getCorePoolSize());
|
||||||
|
result.setMaximumSize(rocketMQConsumeExecutor.getMaximumPoolSize());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
log.warn("[{}] RocketMQ consuming thread pool not found.", identify);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ThreadPoolAdapterState> getThreadPoolStates() {
|
||||||
|
List<ThreadPoolAdapterState> adapterStateList = Lists.newArrayList();
|
||||||
|
ROCKET_MQ_CONSUME_EXECUTOR.forEach(
|
||||||
|
(key, val) -> adapterStateList.add(getThreadPoolState(key)));
|
||||||
|
return adapterStateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) {
|
||||||
|
String threadPoolKey = threadPoolAdapterParameter.getThreadPoolKey();
|
||||||
|
ThreadPoolExecutor rocketMQConsumeExecutor = ROCKET_MQ_CONSUME_EXECUTOR.get(threadPoolKey);
|
||||||
|
if (rocketMQConsumeExecutor != null) {
|
||||||
|
int originalCoreSize = rocketMQConsumeExecutor.getCorePoolSize();
|
||||||
|
int originalMaximumPoolSize = rocketMQConsumeExecutor.getMaximumPoolSize();
|
||||||
|
rocketMQConsumeExecutor.setCorePoolSize(threadPoolAdapterParameter.getCorePoolSize());
|
||||||
|
rocketMQConsumeExecutor.setMaximumPoolSize(threadPoolAdapterParameter.getMaximumPoolSize());
|
||||||
|
log.info("[{}] RocketMQ consumption thread pool parameter change. coreSize :: {}, maximumSize :: {}",
|
||||||
|
threadPoolKey,
|
||||||
|
String.format(CHANGE_DELIMITER, originalCoreSize, rocketMQConsumeExecutor.getCorePoolSize()),
|
||||||
|
String.format(CHANGE_DELIMITER, originalMaximumPoolSize, rocketMQConsumeExecutor.getMaximumPoolSize()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log.warn("[{}] RocketMQ consuming thread pool not found.", threadPoolKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||||
|
Map<String, DefaultRocketMQListenerContainer> containerMap =
|
||||||
|
ApplicationContextHolder.getBeansOfType(DefaultRocketMQListenerContainer.class);
|
||||||
|
try {
|
||||||
|
for (DefaultRocketMQListenerContainer container : containerMap.values()) {
|
||||||
|
DefaultMQPushConsumer consumer = container.getConsumer();
|
||||||
|
if (consumer != null) {
|
||||||
|
ConsumeMessageService consumeMessageService = consumer.getDefaultMQPushConsumerImpl().getConsumeMessageService();
|
||||||
|
ThreadPoolExecutor consumeExecutor = (ThreadPoolExecutor) ReflectUtil.getFieldValue(consumeMessageService, "consumeExecutor");
|
||||||
|
ROCKET_MQ_CONSUME_EXECUTOR.put(container.getConsumerGroup(), consumeExecutor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to get RocketMQ thread pool.", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>hippo4j-adapter-spring-cloud-stream-kafka</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter-base</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
<Built-By>chen.ma</Built-By>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.springcloud.stream.kafka;
|
||||||
|
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring cloud stream kafka thread-pool adapter.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class SpringCloudStreamKafkaThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String mark() {
|
||||||
|
return "KafkaSpringCloudStream";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolAdapterState getThreadPoolState(String identify) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ThreadPoolAdapterState> getThreadPoolStates() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>hippo4j-adapter-spring-cloud-stream-rocketmq</artifactId>
|
||||||
|
<name>hippo4j-adapter-spring-cloud-stream-rocketmq</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter-base</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
|
||||||
|
<version>${spring-cloud-starter-stream-rocketmq.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
<Built-By>chen.ma</Built-By>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.springcloud.stream.rocketmq;
|
||||||
|
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
|
||||||
|
import cn.hippo4j.common.config.ApplicationContextHolder;
|
||||||
|
import cn.hippo4j.common.toolkit.CollectionUtil;
|
||||||
|
import cn.hippo4j.common.toolkit.ReflectUtil;
|
||||||
|
import com.alibaba.cloud.stream.binder.rocketmq.consuming.RocketMQListenerBindingContainer;
|
||||||
|
import com.alibaba.cloud.stream.binder.rocketmq.integration.RocketMQInboundChannelAdapter;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
|
||||||
|
import org.apache.rocketmq.client.impl.consumer.ConsumeMessageConcurrentlyService;
|
||||||
|
import org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
import org.springframework.cloud.stream.binder.Binding;
|
||||||
|
import org.springframework.cloud.stream.binder.DefaultBinding;
|
||||||
|
import org.springframework.cloud.stream.binding.InputBindingLifecycle;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring cloud stream rocketMQ thread-pool adapter.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class SpringCloudStreamRocketMQThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener<ApplicationStartedEvent> {
|
||||||
|
|
||||||
|
private final Map<String, ThreadPoolExecutor> ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR = Maps.newHashMap();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String mark() {
|
||||||
|
return "RocketMQSpringCloudStream";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolAdapterState getThreadPoolState(String identify) {
|
||||||
|
ThreadPoolAdapterState result = new ThreadPoolAdapterState();
|
||||||
|
ThreadPoolExecutor rocketMQConsumeExecutor = ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.get(identify);
|
||||||
|
if (rocketMQConsumeExecutor != null) {
|
||||||
|
result.setThreadPoolKey(identify);
|
||||||
|
result.setCoreSize(rocketMQConsumeExecutor.getCorePoolSize());
|
||||||
|
result.setMaximumSize(rocketMQConsumeExecutor.getMaximumPoolSize());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
log.warn("[{}] RocketMQ consuming thread pool not found.", identify);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ThreadPoolAdapterState> getThreadPoolStates() {
|
||||||
|
List<ThreadPoolAdapterState> adapterStateList = Lists.newArrayList();
|
||||||
|
ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.forEach(
|
||||||
|
(key, val) -> adapterStateList.add(getThreadPoolState(key)));
|
||||||
|
return adapterStateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) {
|
||||||
|
String threadPoolKey = threadPoolAdapterParameter.getThreadPoolKey();
|
||||||
|
ThreadPoolExecutor rocketMQConsumeExecutor = ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.get(threadPoolKey);
|
||||||
|
if (rocketMQConsumeExecutor != null) {
|
||||||
|
int originalCoreSize = rocketMQConsumeExecutor.getCorePoolSize();
|
||||||
|
int originalMaximumPoolSize = rocketMQConsumeExecutor.getMaximumPoolSize();
|
||||||
|
rocketMQConsumeExecutor.setCorePoolSize(threadPoolAdapterParameter.getCorePoolSize());
|
||||||
|
rocketMQConsumeExecutor.setMaximumPoolSize(threadPoolAdapterParameter.getMaximumPoolSize());
|
||||||
|
log.info("[{}] RocketMQ consumption thread pool parameter change. coreSize :: {}, maximumSize :: {}",
|
||||||
|
threadPoolKey,
|
||||||
|
String.format(CHANGE_DELIMITER, originalCoreSize, rocketMQConsumeExecutor.getCorePoolSize()),
|
||||||
|
String.format(CHANGE_DELIMITER, originalMaximumPoolSize, rocketMQConsumeExecutor.getMaximumPoolSize()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
log.warn("[{}] RocketMQ consuming thread pool not found.", threadPoolKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||||
|
InputBindingLifecycle bindingLifecycle = ApplicationContextHolder.getBean(InputBindingLifecycle.class);
|
||||||
|
Collection<Binding<Object>> inputBindings = Optional.ofNullable(ReflectUtil.getFieldValue(bindingLifecycle, "inputBindings")).map(each -> (Collection<Binding<Object>>) each).orElse(null);
|
||||||
|
if (CollectionUtil.isEmpty(inputBindings)) {
|
||||||
|
log.info("InputBindings record not found.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
for (Binding<Object> each : inputBindings) {
|
||||||
|
String bindingName = each.getBindingName();
|
||||||
|
DefaultBinding defaultBinding = (DefaultBinding) each;
|
||||||
|
RocketMQInboundChannelAdapter lifecycle = (RocketMQInboundChannelAdapter) ReflectUtil.getFieldValue(defaultBinding, "lifecycle");
|
||||||
|
RocketMQListenerBindingContainer rocketMQListenerContainer = (RocketMQListenerBindingContainer) ReflectUtil.getFieldValue(lifecycle, "rocketMQListenerContainer");
|
||||||
|
DefaultMQPushConsumer consumer = rocketMQListenerContainer.getConsumer();
|
||||||
|
DefaultMQPushConsumerImpl defaultMQPushConsumerImpl = consumer.getDefaultMQPushConsumerImpl();
|
||||||
|
ConsumeMessageConcurrentlyService consumeMessageService = (ConsumeMessageConcurrentlyService) defaultMQPushConsumerImpl.getConsumeMessageService();
|
||||||
|
ThreadPoolExecutor consumeExecutor = (ThreadPoolExecutor) ReflectUtil.getFieldValue(consumeMessageService, "consumeExecutor");
|
||||||
|
ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.put(bindingName, consumeExecutor);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to get input-bindings thread pool.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-adapter</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>hippo4j-adapter-web</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.tomcat.embed</groupId>
|
||||||
|
<artifactId>tomcat-embed-core</artifactId>
|
||||||
|
<version>${tomcat-embed-core.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
<Build-Time>${maven.build.timestamp}</Build-Time>
|
||||||
|
<Built-By>chen.ma</Built-By>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</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.adapter.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.config.ApplicationContextHolder;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.ApplicationArguments;
|
||||||
|
import org.springframework.boot.ApplicationRunner;
|
||||||
|
import org.springframework.boot.web.context.WebServerApplicationContext;
|
||||||
|
import org.springframework.boot.web.server.WebServer;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract web thread pool service.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public abstract class AbstractWebThreadPoolService implements WebThreadPoolService, ApplicationRunner {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread pool executor.
|
||||||
|
*/
|
||||||
|
protected volatile Executor executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get web thread pool by server.
|
||||||
|
*
|
||||||
|
* @param webServer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected abstract Executor getWebThreadPoolByServer(WebServer webServer);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Executor getWebThreadPool() {
|
||||||
|
if (executor == null) {
|
||||||
|
synchronized (AbstractWebThreadPoolService.class) {
|
||||||
|
if (executor == null) {
|
||||||
|
ApplicationContext applicationContext = ApplicationContextHolder.getInstance();
|
||||||
|
WebServer webServer = ((WebServerApplicationContext) applicationContext).getWebServer();
|
||||||
|
executor = getWebThreadPoolByServer(webServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(ApplicationArguments args) {
|
||||||
|
try {
|
||||||
|
getWebThreadPool();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
// ignore. Adaptation unit test.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.constant.ChangeThreadPoolConstants;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolBaseInfo;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolParameter;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
|
||||||
|
import cn.hippo4j.common.toolkit.ReflectUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||||
|
import org.springframework.boot.web.embedded.jetty.JettyWebServer;
|
||||||
|
import org.springframework.boot.web.server.WebServer;
|
||||||
|
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jetty web thread pool handler.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class JettyWebThreadPoolHandler extends AbstractWebThreadPoolService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Executor getWebThreadPoolByServer(WebServer webServer) {
|
||||||
|
JettyWebServer jettyWebServer = (JettyWebServer) webServer;
|
||||||
|
return jettyWebServer.getServer().getThreadPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolBaseInfo simpleInfo() {
|
||||||
|
ThreadPoolBaseInfo poolBaseInfo = new ThreadPoolBaseInfo();
|
||||||
|
QueuedThreadPool queuedThreadPool = (QueuedThreadPool) executor;
|
||||||
|
poolBaseInfo.setCoreSize(queuedThreadPool.getMinThreads());
|
||||||
|
poolBaseInfo.setMaximumSize(queuedThreadPool.getMaxThreads());
|
||||||
|
BlockingQueue jobs = (BlockingQueue) ReflectUtil.getFieldValue(queuedThreadPool, "_jobs");
|
||||||
|
int queueCapacity = jobs.remainingCapacity() + jobs.size();
|
||||||
|
poolBaseInfo.setQueueCapacity(queueCapacity);
|
||||||
|
poolBaseInfo.setQueueType(jobs.getClass().getSimpleName());
|
||||||
|
poolBaseInfo.setKeepAliveTime((long) queuedThreadPool.getIdleTimeout());
|
||||||
|
poolBaseInfo.setRejectedName("RejectedExecutionException");
|
||||||
|
return poolBaseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolParameter getWebThreadPoolParameter() {
|
||||||
|
ThreadPoolParameterInfo parameterInfo = null;
|
||||||
|
try {
|
||||||
|
parameterInfo = new ThreadPoolParameterInfo();
|
||||||
|
QueuedThreadPool jettyExecutor = (QueuedThreadPool) executor;
|
||||||
|
int minThreads = jettyExecutor.getMinThreads();
|
||||||
|
int maxThreads = jettyExecutor.getMaxThreads();
|
||||||
|
parameterInfo.setCoreSize(minThreads);
|
||||||
|
parameterInfo.setMaxSize(maxThreads);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to get the jetty thread pool parameter.", ex);
|
||||||
|
}
|
||||||
|
return parameterInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolRunStateInfo getWebRunStateInfo() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateWebThreadPool(ThreadPoolParameterInfo threadPoolParameterInfo) {
|
||||||
|
try {
|
||||||
|
QueuedThreadPool jettyExecutor = (QueuedThreadPool) executor;
|
||||||
|
int minThreads = jettyExecutor.getMinThreads();
|
||||||
|
int maxThreads = jettyExecutor.getMaxThreads();
|
||||||
|
Integer coreSize = threadPoolParameterInfo.corePoolSizeAdapt();
|
||||||
|
Integer maxSize = threadPoolParameterInfo.maximumPoolSizeAdapt();
|
||||||
|
jettyExecutor.setMinThreads(coreSize);
|
||||||
|
jettyExecutor.setMaxThreads(maxSize);
|
||||||
|
log.info("[JETTY] Changed web thread pool. corePoolSize :: [{}], maximumPoolSize :: [{}]",
|
||||||
|
String.format(ChangeThreadPoolConstants.CHANGE_DELIMITER, minThreads, jettyExecutor.getMinThreads()),
|
||||||
|
String.format(ChangeThreadPoolConstants.CHANGE_DELIMITER, maxThreads, jettyExecutor.getMaxThreads()));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to modify the jetty thread pool parameter.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.constant.ChangeThreadPoolConstants;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolBaseInfo;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolParameter;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
|
||||||
|
import cn.hippo4j.common.toolkit.CalculateUtil;
|
||||||
|
import cn.hippo4j.core.executor.state.AbstractThreadPoolRuntime;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
|
||||||
|
import org.springframework.boot.web.server.WebServer;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tomcat web thread pool handler.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TomcatWebThreadPoolHandler extends AbstractWebThreadPoolService {
|
||||||
|
|
||||||
|
private final AtomicBoolean cacheFlag = new AtomicBoolean(Boolean.FALSE);
|
||||||
|
|
||||||
|
private static String EXCEPTION_MESSAGE;
|
||||||
|
|
||||||
|
private final AbstractThreadPoolRuntime webThreadPoolRunStateHandler;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Executor getWebThreadPoolByServer(WebServer webServer) {
|
||||||
|
if (cacheFlag.get()) {
|
||||||
|
log.warn("Exception getting Tomcat thread pool. Exception message :: {}", EXCEPTION_MESSAGE);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Executor tomcatExecutor = null;
|
||||||
|
try {
|
||||||
|
tomcatExecutor = ((TomcatWebServer) webServer).getTomcat().getConnector().getProtocolHandler().getExecutor();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
cacheFlag.set(Boolean.TRUE);
|
||||||
|
EXCEPTION_MESSAGE = ex.getMessage();
|
||||||
|
log.error("Failed to get Tomcat thread pool. Message :: {}", EXCEPTION_MESSAGE);
|
||||||
|
}
|
||||||
|
return tomcatExecutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolBaseInfo simpleInfo() {
|
||||||
|
ThreadPoolBaseInfo poolBaseInfo = new ThreadPoolBaseInfo();
|
||||||
|
org.apache.tomcat.util.threads.ThreadPoolExecutor tomcatThreadPoolExecutor = (org.apache.tomcat.util.threads.ThreadPoolExecutor) executor;
|
||||||
|
int corePoolSize = tomcatThreadPoolExecutor.getCorePoolSize();
|
||||||
|
int maximumPoolSize = tomcatThreadPoolExecutor.getMaximumPoolSize();
|
||||||
|
long keepAliveTime = tomcatThreadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS);
|
||||||
|
BlockingQueue<?> blockingQueue = tomcatThreadPoolExecutor.getQueue();
|
||||||
|
int queueSize = blockingQueue.size();
|
||||||
|
int remainingCapacity = blockingQueue.remainingCapacity();
|
||||||
|
int queueCapacity = queueSize + remainingCapacity;
|
||||||
|
String rejectedExecutionHandlerName = executor instanceof ThreadPoolExecutor ? ((ThreadPoolExecutor) executor).getRejectedExecutionHandler().getClass().getSimpleName()
|
||||||
|
: tomcatThreadPoolExecutor.getRejectedExecutionHandler().getClass().getSimpleName();
|
||||||
|
poolBaseInfo.setCoreSize(corePoolSize);
|
||||||
|
poolBaseInfo.setMaximumSize(maximumPoolSize);
|
||||||
|
poolBaseInfo.setKeepAliveTime(keepAliveTime);
|
||||||
|
poolBaseInfo.setQueueType(blockingQueue.getClass().getSimpleName());
|
||||||
|
poolBaseInfo.setQueueCapacity(queueCapacity);
|
||||||
|
poolBaseInfo.setRejectedName(rejectedExecutionHandlerName);
|
||||||
|
return poolBaseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolParameter getWebThreadPoolParameter() {
|
||||||
|
ThreadPoolParameterInfo parameterInfo = new ThreadPoolParameterInfo();
|
||||||
|
try {
|
||||||
|
org.apache.tomcat.util.threads.ThreadPoolExecutor tomcatThreadPoolExecutor = (org.apache.tomcat.util.threads.ThreadPoolExecutor) executor;
|
||||||
|
int minThreads = tomcatThreadPoolExecutor.getCorePoolSize();
|
||||||
|
int maxThreads = tomcatThreadPoolExecutor.getMaximumPoolSize();
|
||||||
|
long keepAliveTime = tomcatThreadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS);
|
||||||
|
parameterInfo.setCoreSize(minThreads);
|
||||||
|
parameterInfo.setMaxSize(maxThreads);
|
||||||
|
parameterInfo.setKeepAliveTime((int) keepAliveTime);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to get the tomcat thread pool parameter.", ex);
|
||||||
|
}
|
||||||
|
return parameterInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolRunStateInfo getWebRunStateInfo() {
|
||||||
|
if (executor instanceof ThreadPoolExecutor) {
|
||||||
|
return webThreadPoolRunStateHandler.getPoolRunState(null, executor);
|
||||||
|
}
|
||||||
|
ThreadPoolRunStateInfo runStateInfo = new ThreadPoolRunStateInfo();
|
||||||
|
org.apache.tomcat.util.threads.ThreadPoolExecutor tomcatThreadPoolExecutor = (org.apache.tomcat.util.threads.ThreadPoolExecutor) executor;
|
||||||
|
// 核心线程数
|
||||||
|
int corePoolSize = tomcatThreadPoolExecutor.getCorePoolSize();
|
||||||
|
// 最大线程数
|
||||||
|
int maximumPoolSize = tomcatThreadPoolExecutor.getMaximumPoolSize();
|
||||||
|
// 线程池当前线程数 (有锁)
|
||||||
|
int poolSize = tomcatThreadPoolExecutor.getPoolSize();
|
||||||
|
// 活跃线程数 (有锁)
|
||||||
|
int activeCount = tomcatThreadPoolExecutor.getActiveCount();
|
||||||
|
// 同时进入池中的最大线程数 (有锁)
|
||||||
|
int largestPoolSize = tomcatThreadPoolExecutor.getLargestPoolSize();
|
||||||
|
// 线程池中执行任务总数量 (有锁)
|
||||||
|
long completedTaskCount = tomcatThreadPoolExecutor.getCompletedTaskCount();
|
||||||
|
// 当前负载
|
||||||
|
String currentLoad = CalculateUtil.divide(activeCount, maximumPoolSize) + "";
|
||||||
|
// 峰值负载
|
||||||
|
String peakLoad = CalculateUtil.divide(largestPoolSize, maximumPoolSize) + "";
|
||||||
|
BlockingQueue<Runnable> queue = tomcatThreadPoolExecutor.getQueue();
|
||||||
|
// 队列元素个数
|
||||||
|
int queueSize = queue.size();
|
||||||
|
// 队列类型
|
||||||
|
String queueType = queue.getClass().getSimpleName();
|
||||||
|
// 队列剩余容量
|
||||||
|
int remainingCapacity = queue.remainingCapacity();
|
||||||
|
// 队列容量
|
||||||
|
int queueCapacity = queueSize + remainingCapacity;
|
||||||
|
runStateInfo.setCoreSize(corePoolSize);
|
||||||
|
runStateInfo.setPoolSize(poolSize);
|
||||||
|
runStateInfo.setMaximumSize(maximumPoolSize);
|
||||||
|
runStateInfo.setActiveSize(activeCount);
|
||||||
|
runStateInfo.setCurrentLoad(currentLoad);
|
||||||
|
runStateInfo.setPeakLoad(peakLoad);
|
||||||
|
runStateInfo.setQueueType(queueType);
|
||||||
|
runStateInfo.setQueueSize(queueSize);
|
||||||
|
runStateInfo.setQueueCapacity(queueCapacity);
|
||||||
|
runStateInfo.setQueueRemainingCapacity(remainingCapacity);
|
||||||
|
runStateInfo.setLargestPoolSize(largestPoolSize);
|
||||||
|
runStateInfo.setCompletedTaskCount(completedTaskCount);
|
||||||
|
runStateInfo.setClientLastRefreshTime(DateUtil.formatDateTime(new Date()));
|
||||||
|
runStateInfo.setTimestamp(System.currentTimeMillis());
|
||||||
|
return webThreadPoolRunStateHandler.supplement(runStateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateWebThreadPool(ThreadPoolParameterInfo threadPoolParameterInfo) {
|
||||||
|
try {
|
||||||
|
org.apache.tomcat.util.threads.ThreadPoolExecutor tomcatThreadPoolExecutor = (org.apache.tomcat.util.threads.ThreadPoolExecutor) executor;
|
||||||
|
int originalCoreSize = tomcatThreadPoolExecutor.getCorePoolSize();
|
||||||
|
int originalMaximumPoolSize = tomcatThreadPoolExecutor.getMaximumPoolSize();
|
||||||
|
long originalKeepAliveTime = tomcatThreadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS);
|
||||||
|
tomcatThreadPoolExecutor.setCorePoolSize(threadPoolParameterInfo.corePoolSizeAdapt());
|
||||||
|
tomcatThreadPoolExecutor.setMaximumPoolSize(threadPoolParameterInfo.maximumPoolSizeAdapt());
|
||||||
|
tomcatThreadPoolExecutor.setKeepAliveTime(threadPoolParameterInfo.getKeepAliveTime(), TimeUnit.SECONDS);
|
||||||
|
log.info("[TOMCAT] Changed web thread pool. corePoolSize :: [{}], maximumPoolSize :: [{}], keepAliveTime :: [{}]",
|
||||||
|
String.format(ChangeThreadPoolConstants.CHANGE_DELIMITER, originalCoreSize, threadPoolParameterInfo.corePoolSizeAdapt()),
|
||||||
|
String.format(ChangeThreadPoolConstants.CHANGE_DELIMITER, originalMaximumPoolSize, threadPoolParameterInfo.maximumPoolSizeAdapt()),
|
||||||
|
String.format(ChangeThreadPoolConstants.CHANGE_DELIMITER, originalKeepAliveTime, threadPoolParameterInfo.getKeepAliveTime()));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to modify the Tomcat thread pool parameter.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.constant.ChangeThreadPoolConstants;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolBaseInfo;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolParameter;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
|
||||||
|
import cn.hippo4j.common.toolkit.CalculateUtil;
|
||||||
|
import cn.hippo4j.core.executor.DynamicThreadPoolExecutor;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import io.undertow.Undertow;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.web.embedded.undertow.UndertowWebServer;
|
||||||
|
import org.springframework.boot.web.server.WebServer;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
import org.xnio.Options;
|
||||||
|
import org.xnio.XnioWorker;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undertow web thread pool handler.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class UndertowWebThreadPoolHandler extends AbstractWebThreadPoolService {
|
||||||
|
|
||||||
|
private static final String UNDERTOW_NAME = "undertow";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Executor getWebThreadPoolByServer(WebServer webServer) {
|
||||||
|
// There is no need to consider reflection performance because the fetch is a singleton
|
||||||
|
UndertowWebServer undertowWebServer = (UndertowWebServer) webServer;
|
||||||
|
Field undertowField = ReflectionUtils.findField(UndertowWebServer.class, UNDERTOW_NAME);
|
||||||
|
ReflectionUtils.makeAccessible(undertowField);
|
||||||
|
|
||||||
|
Undertow undertow = (Undertow) ReflectionUtils.getField(undertowField, undertowWebServer);
|
||||||
|
return Objects.isNull(undertow) ? null : undertow.getWorker();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolBaseInfo simpleInfo() {
|
||||||
|
ThreadPoolBaseInfo poolBaseInfo = new ThreadPoolBaseInfo();
|
||||||
|
XnioWorker xnioWorker = (XnioWorker) executor;
|
||||||
|
try {
|
||||||
|
int coreSize = xnioWorker.getOption(Options.WORKER_TASK_CORE_THREADS);
|
||||||
|
int maximumPoolSize = xnioWorker.getOption(Options.WORKER_TASK_MAX_THREADS);
|
||||||
|
int keepAliveTime = xnioWorker.getOption(Options.WORKER_TASK_KEEPALIVE);
|
||||||
|
|
||||||
|
poolBaseInfo.setCoreSize(coreSize);
|
||||||
|
poolBaseInfo.setMaximumSize(maximumPoolSize);
|
||||||
|
poolBaseInfo.setKeepAliveTime((long) keepAliveTime);
|
||||||
|
poolBaseInfo.setRejectedName("-");
|
||||||
|
poolBaseInfo.setQueueType("-");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("The undertow container failed to get thread pool parameters.", ex);
|
||||||
|
}
|
||||||
|
return poolBaseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolParameter getWebThreadPoolParameter() {
|
||||||
|
ThreadPoolParameterInfo parameterInfo = null;
|
||||||
|
try {
|
||||||
|
parameterInfo = new ThreadPoolParameterInfo();
|
||||||
|
XnioWorker xnioWorker = (XnioWorker) executor;
|
||||||
|
int minThreads = xnioWorker.getOption(Options.WORKER_TASK_CORE_THREADS);
|
||||||
|
int maxThreads = xnioWorker.getOption(Options.WORKER_TASK_MAX_THREADS);
|
||||||
|
int keepAliveTime = xnioWorker.getOption(Options.WORKER_TASK_KEEPALIVE);
|
||||||
|
|
||||||
|
parameterInfo.setCoreSize(minThreads);
|
||||||
|
parameterInfo.setMaxSize(maxThreads);
|
||||||
|
parameterInfo.setKeepAliveTime(keepAliveTime);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to get the undertow thread pool parameter.", ex);
|
||||||
|
}
|
||||||
|
return parameterInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolRunStateInfo getWebRunStateInfo() {
|
||||||
|
ThreadPoolRunStateInfo stateInfo = new ThreadPoolRunStateInfo();
|
||||||
|
XnioWorker xnioWorker = (XnioWorker) executor;
|
||||||
|
|
||||||
|
Field field = ReflectionUtils.findField(XnioWorker.class, "taskPool");
|
||||||
|
ReflectionUtils.makeAccessible(field);
|
||||||
|
Object fieldObject = ReflectionUtils.getField(field, xnioWorker);
|
||||||
|
// 核心线程数
|
||||||
|
Method getCorePoolSize = ReflectionUtils.findMethod(fieldObject.getClass(), "getCorePoolSize");
|
||||||
|
ReflectionUtils.makeAccessible(getCorePoolSize);
|
||||||
|
int corePoolSize = (int) ReflectionUtils.invokeMethod(getCorePoolSize, fieldObject);
|
||||||
|
// 最大线程数
|
||||||
|
Method getMaximumPoolSize = ReflectionUtils.findMethod(fieldObject.getClass(), "getMaximumPoolSize");
|
||||||
|
ReflectionUtils.makeAccessible(getMaximumPoolSize);
|
||||||
|
int maximumPoolSize = (int) ReflectionUtils.invokeMethod(getMaximumPoolSize, fieldObject);
|
||||||
|
// 线程池当前线程数 (有锁)
|
||||||
|
Method getPoolSize = ReflectionUtils.findMethod(fieldObject.getClass(), "getPoolSize");
|
||||||
|
ReflectionUtils.makeAccessible(getPoolSize);
|
||||||
|
int poolSize = (int) ReflectionUtils.invokeMethod(getPoolSize, fieldObject);
|
||||||
|
// 活跃线程数 (有锁)
|
||||||
|
Method getActiveCount = ReflectionUtils.findMethod(fieldObject.getClass(), "getActiveCount");
|
||||||
|
ReflectionUtils.makeAccessible(getActiveCount);
|
||||||
|
int activeCount = (int) ReflectionUtils.invokeMethod(getActiveCount, fieldObject);
|
||||||
|
activeCount = Math.max(activeCount, 0);
|
||||||
|
// 当前负载
|
||||||
|
String currentLoad = CalculateUtil.divide(activeCount, maximumPoolSize) + "";
|
||||||
|
// 峰值负载
|
||||||
|
// 没有峰值记录,直接使用当前数据
|
||||||
|
String peakLoad = CalculateUtil.divide(activeCount, maximumPoolSize) + "";
|
||||||
|
|
||||||
|
stateInfo.setCoreSize(corePoolSize);
|
||||||
|
stateInfo.setPoolSize(poolSize);
|
||||||
|
stateInfo.setMaximumSize(maximumPoolSize);
|
||||||
|
stateInfo.setActiveSize(activeCount);
|
||||||
|
stateInfo.setCurrentLoad(currentLoad);
|
||||||
|
stateInfo.setPeakLoad(peakLoad);
|
||||||
|
|
||||||
|
long rejectCount = fieldObject instanceof DynamicThreadPoolExecutor
|
||||||
|
? ((DynamicThreadPoolExecutor) fieldObject).getRejectCountNum()
|
||||||
|
: -1L;
|
||||||
|
stateInfo.setRejectCount(rejectCount);
|
||||||
|
stateInfo.setClientLastRefreshTime(DateUtil.formatDateTime(new Date()));
|
||||||
|
stateInfo.setTimestamp(System.currentTimeMillis());
|
||||||
|
return stateInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateWebThreadPool(ThreadPoolParameterInfo threadPoolParameterInfo) {
|
||||||
|
try {
|
||||||
|
XnioWorker xnioWorker = (XnioWorker) executor;
|
||||||
|
Integer coreSize = threadPoolParameterInfo.corePoolSizeAdapt();
|
||||||
|
Integer maxSize = threadPoolParameterInfo.maximumPoolSizeAdapt();
|
||||||
|
Integer keepAliveTime = threadPoolParameterInfo.getKeepAliveTime();
|
||||||
|
int originalCoreSize = xnioWorker.getOption(Options.WORKER_TASK_CORE_THREADS);
|
||||||
|
int originalMaximumPoolSize = xnioWorker.getOption(Options.WORKER_TASK_MAX_THREADS);
|
||||||
|
int originalKeepAliveTime = xnioWorker.getOption(Options.WORKER_TASK_KEEPALIVE);
|
||||||
|
xnioWorker.setOption(Options.WORKER_TASK_CORE_THREADS, coreSize);
|
||||||
|
xnioWorker.setOption(Options.WORKER_TASK_MAX_THREADS, maxSize);
|
||||||
|
xnioWorker.setOption(Options.WORKER_TASK_KEEPALIVE, keepAliveTime);
|
||||||
|
log.info("[UNDERTOW] Changed web thread pool. corePoolSize :: [{}], maximumPoolSize :: [{}], keepAliveTime :: [{}]",
|
||||||
|
String.format(ChangeThreadPoolConstants.CHANGE_DELIMITER, originalCoreSize, coreSize),
|
||||||
|
String.format(ChangeThreadPoolConstants.CHANGE_DELIMITER, originalMaximumPoolSize, maxSize),
|
||||||
|
String.format(ChangeThreadPoolConstants.CHANGE_DELIMITER, originalKeepAliveTime, keepAliveTime));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to modify the undertow thread pool parameter.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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.adapter.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.config.ApplicationContextHolder;
|
||||||
|
import cn.hippo4j.common.web.exception.ServiceException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web thread pool handler choose.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class WebThreadPoolHandlerChoose {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Choose the web thread pool service bean.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public WebThreadPoolService choose() {
|
||||||
|
WebThreadPoolService webThreadPoolService;
|
||||||
|
try {
|
||||||
|
webThreadPoolService = ApplicationContextHolder.getBean(WebThreadPoolService.class);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new ServiceException("Web thread pool service bean not found.", ex);
|
||||||
|
}
|
||||||
|
return webThreadPoolService;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
|
||||||
|
import cn.hippo4j.common.toolkit.ByteConvertUtil;
|
||||||
|
import cn.hippo4j.core.executor.state.AbstractThreadPoolRuntime;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.system.RuntimeInfo;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web thread pool run state handler.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class WebThreadPoolRunStateHandler extends AbstractThreadPoolRuntime {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo poolRunStateInfo) {
|
||||||
|
RuntimeInfo runtimeInfo = new RuntimeInfo();
|
||||||
|
String memoryProportion = StrUtil.builder(
|
||||||
|
"已分配: ",
|
||||||
|
ByteConvertUtil.getPrintSize(runtimeInfo.getTotalMemory()),
|
||||||
|
" / 最大可用: ",
|
||||||
|
ByteConvertUtil.getPrintSize(runtimeInfo.getMaxMemory())).toString();
|
||||||
|
|
||||||
|
poolRunStateInfo.setCurrentLoad(poolRunStateInfo.getCurrentLoad() + "%");
|
||||||
|
poolRunStateInfo.setPeakLoad(poolRunStateInfo.getPeakLoad() + "%");
|
||||||
|
|
||||||
|
poolRunStateInfo.setMemoryProportion(memoryProportion);
|
||||||
|
poolRunStateInfo.setFreeMemory(ByteConvertUtil.getPrintSize(runtimeInfo.getFreeMemory()));
|
||||||
|
|
||||||
|
return poolRunStateInfo;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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.adapter.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolBaseInfo;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolParameter;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
|
||||||
|
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web thread pool service.
|
||||||
|
*/
|
||||||
|
public interface WebThreadPoolService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get web thread pool.
|
||||||
|
*
|
||||||
|
* @return Tomcat、Jetty、Undertow ThreadPoolExecutor
|
||||||
|
*/
|
||||||
|
Executor getWebThreadPool();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple info.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ThreadPoolBaseInfo simpleInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get web thread pool parameter.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ThreadPoolParameter getWebThreadPoolParameter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get web run state info.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ThreadPoolRunStateInfo getWebRunStateInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update web thread pool.
|
||||||
|
*
|
||||||
|
* @param threadPoolParameterInfo
|
||||||
|
*/
|
||||||
|
void updateWebThreadPool(ThreadPoolParameterInfo threadPoolParameterInfo);
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.hippo4j</groupId>
|
||||||
|
<artifactId>hippo4j-all</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>hippo4j-adapter</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>hippo4j-adapter-base</module>
|
||||||
|
<module>hippo4j-adapter-dubbo</module>
|
||||||
|
<module>hippo4j-adapter-kafka</module>
|
||||||
|
<module>hippo4j-adapter-rabbitmq</module>
|
||||||
|
<module>hippo4j-adapter-rocketmq</module>
|
||||||
|
<module>hippo4j-adapter-hystrix</module>
|
||||||
|
<module>hippo4j-adapter-spring-cloud-stream-rocketmq</module>
|
||||||
|
<module>hippo4j-adapter-spring-cloud-stream-kafka</module>
|
||||||
|
<module>hippo4j-adapter-web</module>
|
||||||
|
</modules>
|
||||||
|
</project>
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change thread-pool constants.
|
||||||
|
*/
|
||||||
|
public class ChangeThreadPoolConstants {
|
||||||
|
|
||||||
|
public static final String CHANGE_THREAD_POOL_TEXT = "[{}] Changing thread pool parameters. " +
|
||||||
|
"\n coreSize :: [{}]" +
|
||||||
|
"\n maximumSize :: [{}]" +
|
||||||
|
"\n queueType :: [{}]" +
|
||||||
|
"\n capacity :: [{}]" +
|
||||||
|
"\n keepAliveTime :: [{}]" +
|
||||||
|
"\n executeTimeOut :: [{}]" +
|
||||||
|
"\n rejectedType :: [{}]" +
|
||||||
|
"\n allowCoreThreadTimeOut :: [{}]";
|
||||||
|
|
||||||
|
public static final String CHANGE_DELIMITER = "%s => %s";
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Many pool run state info.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ManyThreadPoolRunStateInfo extends ThreadPoolRunStateInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* identify
|
||||||
|
*/
|
||||||
|
private String identify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* active
|
||||||
|
*/
|
||||||
|
private String active;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* state
|
||||||
|
*/
|
||||||
|
private String state;
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-pool base info.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class ThreadPoolBaseInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* coreSize
|
||||||
|
*/
|
||||||
|
private Integer coreSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* maximumSize
|
||||||
|
*/
|
||||||
|
private Integer maximumSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* queueType
|
||||||
|
*/
|
||||||
|
private String queueType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* queueCapacity
|
||||||
|
*/
|
||||||
|
private Integer queueCapacity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rejectedName
|
||||||
|
*/
|
||||||
|
private String rejectedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keepAliveTime
|
||||||
|
*/
|
||||||
|
private Long keepAliveTime;
|
||||||
|
}
|
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-pool parameter.
|
||||||
|
*/
|
||||||
|
public interface ThreadPoolParameter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tenantId
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getTenantId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* itemId
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getItemId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tpId
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getTpId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* coreSize
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer getCoreSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* maxSize
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer getMaxSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* queueType
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer getQueueType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* capacity
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer getCapacity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keepAliveTime
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer getKeepAliveTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rejectedType
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer getRejectedType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isAlarm
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer getIsAlarm();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* capacityAlarm
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer getCapacityAlarm();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* livenessAlarm
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer getLivenessAlarm();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* allowCoreThreadTimeOut
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer getAllowCoreThreadTimeOut();
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread pool parameter info.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class ThreadPoolParameterInfo implements ThreadPoolParameter, Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -7123935122108553864L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tenantId
|
||||||
|
*/
|
||||||
|
private String tenantId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* itemId
|
||||||
|
*/
|
||||||
|
private String itemId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tpId
|
||||||
|
*/
|
||||||
|
private String tpId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* content
|
||||||
|
*/
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* coreSize
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
private Integer coreSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* maxSize
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
private Integer maxSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core pool size
|
||||||
|
*/
|
||||||
|
private Integer corePoolSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum pool size
|
||||||
|
*/
|
||||||
|
private Integer maximumPoolSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* queueType
|
||||||
|
*/
|
||||||
|
private Integer queueType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* capacity
|
||||||
|
*/
|
||||||
|
private Integer capacity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keepAliveTime
|
||||||
|
*/
|
||||||
|
private Integer keepAliveTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rejectedType
|
||||||
|
*/
|
||||||
|
private Integer rejectedType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isAlarm
|
||||||
|
*/
|
||||||
|
private Integer isAlarm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* capacityAlarm
|
||||||
|
*/
|
||||||
|
private Integer capacityAlarm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* livenessAlarm
|
||||||
|
*/
|
||||||
|
private Integer livenessAlarm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* allowCoreThreadTimeOut
|
||||||
|
*/
|
||||||
|
private Integer allowCoreThreadTimeOut;
|
||||||
|
|
||||||
|
public Integer corePoolSizeAdapt() {
|
||||||
|
return this.corePoolSize == null ? this.coreSize : this.corePoolSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer maximumPoolSizeAdapt() {
|
||||||
|
return this.maximumPoolSize == null ? this.maxSize : this.maximumPoolSize;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.model;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pool run state info.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ThreadPoolRunStateInfo extends ThreadPoolBaseInfo implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* currentLoad
|
||||||
|
*/
|
||||||
|
private String currentLoad;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* peakLoad
|
||||||
|
*/
|
||||||
|
private String peakLoad;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tpId
|
||||||
|
*/
|
||||||
|
private String tpId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* activeCount
|
||||||
|
*/
|
||||||
|
private Integer activeCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* poolSize
|
||||||
|
*/
|
||||||
|
private Integer poolSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* activeSize
|
||||||
|
*/
|
||||||
|
private Integer activeSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of threads that enter the thread pool at the same time
|
||||||
|
*/
|
||||||
|
private Integer largestPoolSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* queueSize
|
||||||
|
*/
|
||||||
|
private Integer queueSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* queueRemainingCapacity
|
||||||
|
*/
|
||||||
|
private Integer queueRemainingCapacity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* completedTaskCount
|
||||||
|
*/
|
||||||
|
private Long completedTaskCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rejectCount
|
||||||
|
*/
|
||||||
|
private Long rejectCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* host
|
||||||
|
*/
|
||||||
|
private String host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* memoryProportion
|
||||||
|
*/
|
||||||
|
private String memoryProportion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* freeMemory
|
||||||
|
*/
|
||||||
|
private String freeMemory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clientLastRefreshTime
|
||||||
|
*/
|
||||||
|
private String clientLastRefreshTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* timestamp
|
||||||
|
*/
|
||||||
|
private Long timestamp;
|
||||||
|
|
||||||
|
public Integer getSimpleCurrentLoad() {
|
||||||
|
return Integer.parseInt(getCurrentLoad().replace("%", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSimplePeakLoad() {
|
||||||
|
return Integer.parseInt(getPeakLoad().replace("%", ""));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.notify;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.api.NotifyConfigBuilder;
|
||||||
|
import cn.hippo4j.common.config.ApplicationContextHolder;
|
||||||
|
import cn.hippo4j.common.notify.request.AlarmNotifyRequest;
|
||||||
|
import cn.hippo4j.common.notify.request.ChangeParameterNotifyRequest;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.CommandLineRunner;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hippo base send message service.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class HippoBaseSendMessageService implements HippoSendMessageService, CommandLineRunner {
|
||||||
|
|
||||||
|
private final NotifyConfigBuilder notifyConfigBuilder;
|
||||||
|
|
||||||
|
private final AlarmControlHandler alarmControlHandler;
|
||||||
|
|
||||||
|
private final Map<String, List<NotifyConfigDTO>> notifyConfigs = Maps.newHashMap();
|
||||||
|
|
||||||
|
private final Map<String, SendMessageHandler> sendMessageHandlers = Maps.newHashMap();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendAlarmMessage(NotifyTypeEnum typeEnum, AlarmNotifyRequest alarmNotifyRequest) {
|
||||||
|
String threadPoolId = alarmNotifyRequest.getThreadPoolId();
|
||||||
|
String buildKey = StrUtil.builder(threadPoolId, "+", "ALARM").toString();
|
||||||
|
List<NotifyConfigDTO> notifyList = notifyConfigs.get(buildKey);
|
||||||
|
if (CollUtil.isEmpty(notifyList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
notifyList.forEach(each -> {
|
||||||
|
try {
|
||||||
|
SendMessageHandler messageHandler = sendMessageHandlers.get(each.getPlatform());
|
||||||
|
if (messageHandler == null) {
|
||||||
|
log.warn("Please configure alarm notification on the server. key :: [{}]", threadPoolId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isSendAlarm(each.getTpId(), each.getPlatform(), typeEnum)) {
|
||||||
|
alarmNotifyRequest.setNotifyTypeEnum(typeEnum);
|
||||||
|
messageHandler.sendAlarmMessage(each, alarmNotifyRequest);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.warn("Failed to send thread pool alarm notification. key :: [{}]", threadPoolId, ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChangeMessage(ChangeParameterNotifyRequest changeParameterNotifyRequest) {
|
||||||
|
String threadPoolId = changeParameterNotifyRequest.getThreadPoolId();
|
||||||
|
String buildKey = StrUtil.builder(threadPoolId, "+", "CONFIG").toString();
|
||||||
|
List<NotifyConfigDTO> notifyList = notifyConfigs.get(buildKey);
|
||||||
|
if (CollUtil.isEmpty(notifyList)) {
|
||||||
|
log.warn("Please configure alarm notification on the server. key :: [{}]", threadPoolId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
notifyList.forEach(each -> {
|
||||||
|
try {
|
||||||
|
SendMessageHandler messageHandler = sendMessageHandlers.get(each.getPlatform());
|
||||||
|
if (messageHandler == null) {
|
||||||
|
log.warn("Please configure alarm notification on the server. key :: [{}]", threadPoolId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
messageHandler.sendChangeMessage(each, changeParameterNotifyRequest);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.warn("Failed to send thread pool change notification. key :: [{}]", threadPoolId, ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is send alarm.
|
||||||
|
*
|
||||||
|
* @param threadPoolId
|
||||||
|
* @param platform
|
||||||
|
* @param typeEnum
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isSendAlarm(String threadPoolId, String platform, NotifyTypeEnum typeEnum) {
|
||||||
|
AlarmControlDTO alarmControl = AlarmControlDTO.builder()
|
||||||
|
.threadPool(threadPoolId)
|
||||||
|
.platform(platform)
|
||||||
|
.typeEnum(typeEnum)
|
||||||
|
.build();
|
||||||
|
return alarmControlHandler.isSendAlarm(alarmControl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(String... args) throws Exception {
|
||||||
|
Map<String, SendMessageHandler> sendMessageHandlerMap =
|
||||||
|
ApplicationContextHolder.getBeansOfType(SendMessageHandler.class);
|
||||||
|
sendMessageHandlerMap.values().forEach(each -> sendMessageHandlers.put(each.getType(), each));
|
||||||
|
Map<String, List<NotifyConfigDTO>> buildNotify = notifyConfigBuilder.buildNotify();
|
||||||
|
notifyConfigs.putAll(buildNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put platform.
|
||||||
|
*
|
||||||
|
* @param notifyConfigs
|
||||||
|
*/
|
||||||
|
public synchronized void putPlatform(Map<String, List<NotifyConfigDTO>> notifyConfigs) {
|
||||||
|
this.notifyConfigs.putAll(notifyConfigs);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.toolkit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Byte conversion tool class
|
||||||
|
*/
|
||||||
|
public class ByteConvertUtil {
|
||||||
|
|
||||||
|
public static String getPrintSize(long size) {
|
||||||
|
long covertNum = 1024;
|
||||||
|
if (size < covertNum) {
|
||||||
|
return size + "B";
|
||||||
|
} else {
|
||||||
|
size = size / covertNum;
|
||||||
|
}
|
||||||
|
if (size < covertNum) {
|
||||||
|
return size + "KB";
|
||||||
|
} else {
|
||||||
|
size = size / covertNum;
|
||||||
|
}
|
||||||
|
if (size < covertNum) {
|
||||||
|
size = size * 100;
|
||||||
|
return (size / 100) + "." + (size % 100) + "MB";
|
||||||
|
} else {
|
||||||
|
size = size * 100 / covertNum;
|
||||||
|
return (size / 100) + "." + (size % 100) + "GB";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.toolkit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate util.
|
||||||
|
*
|
||||||
|
* @author chen.ma
|
||||||
|
* @date 2021/8/15 14:29
|
||||||
|
*/
|
||||||
|
public class CalculateUtil {
|
||||||
|
|
||||||
|
public static int divide(int num1, int num2) {
|
||||||
|
return ((int) (Double.parseDouble(num1 + "") / Double.parseDouble(num2 + "") * 100));
|
||||||
|
}
|
||||||
|
}
|
@ -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.common.web.exception;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract exception.
|
||||||
|
*/
|
||||||
|
public class AbstractException extends RuntimeException {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public final ErrorCode errorCode;
|
||||||
|
|
||||||
|
public AbstractException(String message, Throwable throwable, ErrorCode errorCode) {
|
||||||
|
super(message, throwable);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.web.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error code abstract interface.
|
||||||
|
*/
|
||||||
|
public interface ErrorCode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get code.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getCode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get message.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getMessage();
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.config;
|
||||||
|
|
||||||
|
import cn.hippo4j.config.netty.MonitorNettyServer;
|
||||||
|
import cn.hippo4j.config.service.biz.HisRunDataService;
|
||||||
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnProperty(name = "hippo4j.core.monitor.report-type", havingValue = "netty")
|
||||||
|
public class NettyServerConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public EventLoopGroup bossGroup() {
|
||||||
|
return new NioEventLoopGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public EventLoopGroup workGroup() {
|
||||||
|
return new NioEventLoopGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public MonitorNettyServer monitorNettyServer(ServerBootstrapProperties serverBootstrapProperties,
|
||||||
|
HisRunDataService hisRunDataService,
|
||||||
|
EventLoopGroup bossGroup,
|
||||||
|
EventLoopGroup workGroup) {
|
||||||
|
return new MonitorNettyServer(serverBootstrapProperties, hisRunDataService, bossGroup, workGroup);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.controller;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.constant.Constants;
|
||||||
|
import cn.hippo4j.common.monitor.Message;
|
||||||
|
import cn.hippo4j.common.monitor.MessageWrapper;
|
||||||
|
import cn.hippo4j.common.toolkit.MessageConvert;
|
||||||
|
import cn.hippo4j.common.web.base.Result;
|
||||||
|
import cn.hippo4j.common.web.base.Results;
|
||||||
|
import cn.hippo4j.config.model.biz.monitor.MonitorActiveRespDTO;
|
||||||
|
import cn.hippo4j.config.model.biz.monitor.MonitorQueryReqDTO;
|
||||||
|
import cn.hippo4j.config.model.biz.monitor.MonitorRespDTO;
|
||||||
|
import cn.hippo4j.config.monitor.QueryMonitorExecuteChoose;
|
||||||
|
import cn.hippo4j.config.service.biz.HisRunDataService;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor controller.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RequestMapping(Constants.BASE_PATH + "/monitor")
|
||||||
|
public class MonitorController {
|
||||||
|
|
||||||
|
private final HisRunDataService hisRunDataService;
|
||||||
|
|
||||||
|
private final QueryMonitorExecuteChoose queryMonitorExecuteChoose;
|
||||||
|
|
||||||
|
private final ThreadPoolTaskExecutor monitorThreadPoolTaskExecutor;
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public Result<List<MonitorRespDTO>> queryMonitor(MonitorQueryReqDTO reqDTO) {
|
||||||
|
List<MonitorRespDTO> monitorRespList = hisRunDataService.query(reqDTO);
|
||||||
|
return Results.success(monitorRespList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/info")
|
||||||
|
public Result<MonitorActiveRespDTO> queryInfoThreadPoolMonitor(@RequestBody MonitorQueryReqDTO reqDTO) {
|
||||||
|
MonitorActiveRespDTO monitorRespList = hisRunDataService.queryInfoThreadPoolMonitor(reqDTO);
|
||||||
|
return Results.success(monitorRespList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/last/task/count")
|
||||||
|
public Result<MonitorRespDTO> queryThreadPoolLastTaskCount(@RequestBody MonitorQueryReqDTO reqDTO) {
|
||||||
|
MonitorRespDTO resultDTO = hisRunDataService.queryThreadPoolLastTaskCount(reqDTO);
|
||||||
|
return Results.success(resultDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> dataCollect(@RequestBody MessageWrapper messageWrapper) {
|
||||||
|
return hisRunDataService.dataCollect(messageWrapper);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.controller;
|
||||||
|
|
||||||
|
import cn.hippo4j.adapter.base.ThreadPoolAdapterCacheConfig;
|
||||||
|
import cn.hippo4j.common.web.base.Result;
|
||||||
|
import cn.hippo4j.common.web.base.Results;
|
||||||
|
import cn.hippo4j.config.service.ThreadPoolAdapterService;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.hippo4j.common.constant.Constants.REGISTER_ADAPTER_PATH;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-pool adapter controller.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ThreadPoolAdapterController {
|
||||||
|
|
||||||
|
private final ThreadPoolAdapterService threadPoolAdapterService;
|
||||||
|
|
||||||
|
@PostMapping(REGISTER_ADAPTER_PATH)
|
||||||
|
public Result registerAdapterThreadPool(@RequestBody List<ThreadPoolAdapterCacheConfig> requestParameter) {
|
||||||
|
threadPoolAdapterService.register(requestParameter);
|
||||||
|
return Results.success();
|
||||||
|
}
|
||||||
|
}
|
@ -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.config.model.biz.adapter;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-pool adapter req DTO.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ThreadPoolAdapterReqDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark
|
||||||
|
*/
|
||||||
|
private String mark;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tenant
|
||||||
|
*/
|
||||||
|
private String tenant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item
|
||||||
|
*/
|
||||||
|
private String item;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread pool key
|
||||||
|
*/
|
||||||
|
private String threadPoolKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify
|
||||||
|
*/
|
||||||
|
private String identify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core pool size
|
||||||
|
*/
|
||||||
|
private Integer corePoolSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum pool size
|
||||||
|
*/
|
||||||
|
private Integer maximumPoolSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client address list
|
||||||
|
*/
|
||||||
|
private List<String> clientAddressList;
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.model.biz.adapter;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread-pool adapter resp DTO.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ThreadPoolAdapterRespDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify
|
||||||
|
*/
|
||||||
|
private String identify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Active
|
||||||
|
*/
|
||||||
|
private String active;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client address
|
||||||
|
*/
|
||||||
|
private String clientAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread pool key
|
||||||
|
*/
|
||||||
|
private String threadPoolKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core size
|
||||||
|
*/
|
||||||
|
private Integer coreSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum size
|
||||||
|
*/
|
||||||
|
private Integer maximumSize;
|
||||||
|
}
|