mirror of https://github.com/longtai-cn/hippo4j
扩展 Web Server 容器线程池动态调参、监控. (#68)
parent
42a13cd3a5
commit
1e912e2223
@ -0,0 +1,45 @@
|
|||||||
|
package cn.hippo4j.starter.controller;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.api.ThreadDetailState;
|
||||||
|
import cn.hippo4j.common.model.PoolParameterInfo;
|
||||||
|
import cn.hippo4j.common.model.PoolRunStateInfo;
|
||||||
|
import cn.hippo4j.common.web.base.Result;
|
||||||
|
import cn.hippo4j.common.web.base.Results;
|
||||||
|
import cn.hippo4j.starter.handler.web.WebThreadPoolRunStateHandler;
|
||||||
|
import cn.hippo4j.starter.handler.web.WebThreadPoolService;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web thread pool controller.
|
||||||
|
*
|
||||||
|
* @author chen.ma
|
||||||
|
* @date 2022/1/19 20:54
|
||||||
|
*/
|
||||||
|
@CrossOrigin
|
||||||
|
@RestController
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class WebThreadPoolController {
|
||||||
|
|
||||||
|
private final WebThreadPoolService webThreadPoolService;
|
||||||
|
|
||||||
|
private final ThreadDetailState threadDetailState;
|
||||||
|
|
||||||
|
private final WebThreadPoolRunStateHandler webThreadPoolRunStateHandler;
|
||||||
|
|
||||||
|
@GetMapping("/web/run/state")
|
||||||
|
public Result<PoolRunStateInfo> getPoolRunState() {
|
||||||
|
Executor webThreadPool = webThreadPoolService.getWebThreadPool();
|
||||||
|
PoolRunStateInfo poolRunState = webThreadPoolRunStateHandler.getPoolRunState(null, webThreadPool);
|
||||||
|
return Results.success(poolRunState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/web/update/pool")
|
||||||
|
public Result<Void> updateWebThreadPool(@RequestBody PoolParameterInfo poolParameterInfo) {
|
||||||
|
webThreadPoolService.updateWebThreadPool(poolParameterInfo);
|
||||||
|
return Results.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package cn.hippo4j.starter.handler.web;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract web thread pool service.
|
||||||
|
*
|
||||||
|
* @author chen.ma
|
||||||
|
* @date 2022/1/19 21:20
|
||||||
|
*/
|
||||||
|
public abstract class AbstractWebThreadPoolService implements WebThreadPoolService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread pool executor.
|
||||||
|
*/
|
||||||
|
protected volatile Executor executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get web thread pool by server.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected abstract Executor getWebThreadPoolByServer();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Executor getWebThreadPool() {
|
||||||
|
if (executor == null) {
|
||||||
|
synchronized (AbstractWebThreadPoolService.class) {
|
||||||
|
if (executor == null) {
|
||||||
|
executor = getWebThreadPoolByServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package cn.hippo4j.starter.handler.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.model.PoolParameterInfo;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
|
||||||
|
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
|
||||||
|
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @author chen.ma
|
||||||
|
* @date 2022/1/19 20:57
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class TomcatWebThreadPoolHandler extends AbstractWebThreadPoolService {
|
||||||
|
|
||||||
|
private final ServletWebServerApplicationContext applicationContext;
|
||||||
|
|
||||||
|
private final AtomicBoolean cacheFlag = new AtomicBoolean(Boolean.FALSE);
|
||||||
|
|
||||||
|
private static String EXCEPTION_MESSAGE;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Executor getWebThreadPoolByServer() {
|
||||||
|
if (cacheFlag.get()) {
|
||||||
|
log.warn("Exception getting Tomcat thread pool. Exception message :: {}", EXCEPTION_MESSAGE);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Executor tomcatExecutor = null;
|
||||||
|
try {
|
||||||
|
tomcatExecutor = ((TomcatWebServer) applicationContext.getWebServer()).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 void updateWebThreadPool(PoolParameterInfo poolParameterInfo) {
|
||||||
|
ThreadPoolExecutor tomcatExecutor = (ThreadPoolExecutor) executor;
|
||||||
|
try {
|
||||||
|
tomcatExecutor.setCorePoolSize(poolParameterInfo.getCoreSize());
|
||||||
|
tomcatExecutor.setMaximumPoolSize(poolParameterInfo.getMaxSize());
|
||||||
|
tomcatExecutor.setKeepAliveTime(poolParameterInfo.getKeepAliveTime(), TimeUnit.SECONDS);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Failed to modify the Tomcat thread pool parameter.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package cn.hippo4j.starter.handler.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.model.PoolParameterInfo;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undertow web thread pool handler.
|
||||||
|
*
|
||||||
|
* @author chen.ma
|
||||||
|
* @date 2022/1/19 21:19
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UndertowWebThreadPoolHandler extends AbstractWebThreadPoolService {
|
||||||
|
|
||||||
|
private final ServletWebServerApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Executor getWebThreadPoolByServer() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateWebThreadPool(PoolParameterInfo poolParameterInfo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package cn.hippo4j.starter.handler.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.model.PoolRunStateInfo;
|
||||||
|
import cn.hippo4j.starter.handler.AbstractThreadPoolRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web thread pool run state handler.
|
||||||
|
*
|
||||||
|
* @author chen.ma
|
||||||
|
* @date 2022/1/19 21:05
|
||||||
|
*/
|
||||||
|
public class WebThreadPoolRunStateHandler extends AbstractThreadPoolRuntime {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PoolRunStateInfo supplement(PoolRunStateInfo basePoolRunStateInfo) {
|
||||||
|
return basePoolRunStateInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package cn.hippo4j.starter.handler.web;
|
||||||
|
|
||||||
|
import cn.hippo4j.common.model.PoolParameterInfo;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web thread pool service.
|
||||||
|
*
|
||||||
|
* @author chen.ma
|
||||||
|
* @date 2022/1/19 20:51
|
||||||
|
*/
|
||||||
|
public interface WebThreadPoolService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get web thread pool.
|
||||||
|
*
|
||||||
|
* @return Tomcat、Jetty、Undertow ThreadPoolExecutor
|
||||||
|
*/
|
||||||
|
Executor getWebThreadPool();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update web thread pool.
|
||||||
|
*
|
||||||
|
* @param poolParameterInfo
|
||||||
|
*/
|
||||||
|
void updateWebThreadPool(PoolParameterInfo poolParameterInfo);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue