我想定期调用此方法来清理 EJB 上下文中的 Apache HTTP 连接池。为此,我创建了这个调度程序类:
@DependsOn("PoolingHttpClientConnectionManager")
public class IdleConnectionMonitor {
private static final Logger LOGGER = LoggerFactory.getLogger(IdleConnectionMonitor.class);
@Inject
private PoolingHttpClientConnectionManager poolingHttpClientConnectionManager;
public IdleConnectionMonitor(PoolingHttpClientConnectionManager poolingHttpClientConnectionManager) {
this.poolingHttpClientConnectionManager = poolingHttpClientConnectionManager;
}
@Schedule(second = "30")
public void cleanUpPool() {
LOGGER.debug("PoolStats counters meaning: max: total connections count; free: available to be reused/free/idle; leased: currently executing requests; waiting: the requests being blocked awaiting a free connection");
tracePoolStats("HTTP client pool stats in the beginning: ");
tracePoolStats("HTTP client pool stats before recycling:");
poolingHttpClientConnectionManager.closeExpiredConnections();
poolingHttpClientConnectionManager.closeIdleConnections(30, TimeUnit.SECONDS);
tracePoolStats("HTTP client pool stats after recycling:");
}
private void tracePoolStats(String messagePrefix) {
if (LOGGER.isDebugEnabled()) {
PoolStats poolStats = poolingHttpClientConnectionManager.getTotalStats();
LOGGER.debug(messagePrefix + "(max/free/leased/waiting): {} | {} | {} | {}",
poolStats.getMax(), poolStats.getAvailable(), poolStats.getLeased(), poolStats.getPending());
}
}
}
但它没有启动。我找不到日志。
如果我在上面加上
@Singleton
,JBoss EAP 会告诉我它必须有一个默认构造函数,但对我来说,它取决于连接管理器,缺少它当然无法工作。所以我不能将它定义为@Stateless
或@Singleton
。
我还应该做什么才能让它发挥作用?
PoolingHttpClientConnectionManager
来自另一个 Producer 类,该类是 @Produces
实例。
public class RestServiceProducer {
@Produces
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
if (poolingHttpClientConnectionManager == null) {
this.poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
poolingHttpClientConnectionManager.setMaxTotal(MAX_CONNECTIONS);
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(MAX_CONNECTIONS);
poolingHttpClientConnectionManager.setDefaultSocketConfig(
SocketConfig.copy(SocketConfig.DEFAULT)
.setSoTimeout(SOCKET_TIMEOUT_MS)
.build()
);
}
return poolingHttpClientConnectionManager;
}
}
当第一个请求启动时,它会延迟创建实例。不过,我可以毫无问题地添加
@StartUp
。
最后我发现可以像平常一样
@Inject
PoolingConnectionManager
,并且我需要将这个类定义为 @Startup @Singleton
。 PoolingConnectionManager
可以来自 @Produces
方法。
@Singleton
@Startup
public class IdleConnectionMonitor {
private static final Logger LOGGER = LoggerFactory.getLogger(IdleConnectionMonitor.class);
@Inject
private PoolingHttpClientConnectionManager poolingHttpClientConnectionManager;
@Schedule(second = "*/30", minute = "*", persistent = false, hour = "*")
public void cleanUpPool() {
LOGGER.debug("PoolStats counters meaning: max: total connections count; free: available to be reused/free/idle; leased: currently executing requests; waiting: the requests being blocked awaiting a free connection");
tracePoolStats("Job Manager HTTP client pool stats in the beginning: ", poolingHttpClientConnectionManager);
tracePoolStats("Job Manager HTTP client pool stats before recycling:", poolingHttpClientConnectionManager);
poolingHttpClientConnectionManager.closeExpiredConnections();
poolingHttpClientConnectionManager.closeIdleConnections(30, TimeUnit.SECONDS);
tracePoolStats("Job Manager HTTP client pool stats after recycling:", poolingHttpClientConnectionManager);
}
private void tracePoolStats(String messagePrefix, PoolingHttpClientConnectionManager poolingHttpClientConnectionManager) {
if (LOGGER.isDebugEnabled()) {
PoolStats poolStats = poolingHttpClientConnectionManager.getTotalStats();
LOGGER.debug(messagePrefix + "(max/free/leased/waiting): {} | {} | {} | {}",
poolStats.getMax(), poolStats.getAvailable(), poolStats.getLeased(), poolStats.getPending());
}
}
}
制作人:
@ApplicationScoped
public class RestServiceProducer {
...
@Produces
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
if (this.poolingHttpClientConnectionManager == null) { // this can be guarded better with `@ConcurrencyControl(CONTAINER)`
LOGGER.debug("Creating new PoolingHttpClientConnectionManager");
this.poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
poolingHttpClientConnectionManager.setMaxTotal(MAX_CONNECTIONS);
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(MAX_CONNECTIONS);
poolingHttpClientConnectionManager.setDefaultSocketConfig(
SocketConfig.copy(SocketConfig.DEFAULT)
.setSoTimeout(SOCKET_TIMEOUT_MS)
.build()
);
} else {
LOGGER.debug("Returning old PoolingHttpClientConnectionManager");
}
return poolingHttpClientConnectionManager;
}
}