增加cache大小检查接口
This commit is contained in:
@@ -3,7 +3,7 @@ solon:
|
||||
add: ./app.yml
|
||||
app:
|
||||
name: neutrino-proxy-client
|
||||
version: 2.0.2
|
||||
version: 2.0.4.t1
|
||||
# 日志级别
|
||||
solon.logging.appender:
|
||||
console:
|
||||
|
||||
+3
@@ -22,6 +22,7 @@ import org.dromara.neutrinoproxy.server.proxy.core.UdpVisitorChannelHandler;
|
||||
import org.dromara.neutrinoproxy.server.proxy.security.TcpVisitorSecurityChannelHandler;
|
||||
import org.dromara.neutrinoproxy.server.proxy.security.UdpVisitorSecurityChannelHandler;
|
||||
import org.dromara.neutrinoproxy.server.proxy.security.VisitorFlowLimiterChannelHandler;
|
||||
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
|
||||
import org.noear.solon.Solon;
|
||||
import org.noear.solon.annotation.Bean;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
@@ -46,6 +47,8 @@ public class ProxyConfiguration implements LifecycleBean {
|
||||
null : ProxyDataTypeEnum.of((int)proxyMessage.getType()).getName());
|
||||
|
||||
Solon.context().wrapAndPut(Dispatcher.class, dispatcher);
|
||||
|
||||
ProxyUtil.init();
|
||||
}
|
||||
|
||||
@Bean("tcpServerBossGroup")
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package org.dromara.neutrinoproxy.server.controller;
|
||||
|
||||
import org.dromara.neutrinoproxy.server.base.rest.Authorization;
|
||||
import org.dromara.neutrinoproxy.server.controller.res.stats.StatsInfoRes;
|
||||
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
|
||||
import org.noear.solon.annotation.Controller;
|
||||
import org.noear.solon.annotation.Get;
|
||||
import org.noear.solon.annotation.Mapping;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: wen.y
|
||||
* @date: 2026/1/20
|
||||
*/
|
||||
@Mapping("/stats")
|
||||
@Controller
|
||||
public class StatsController {
|
||||
|
||||
@Authorization(login = false)
|
||||
@Get
|
||||
@Mapping("/info")
|
||||
public StatsInfoRes info() {
|
||||
return new StatsInfoRes().setCacheInfo(ProxyUtil.getCacheInfo());
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package org.dromara.neutrinoproxy.server.controller.res.stats;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: wen.y
|
||||
* @date: 2026/1/20
|
||||
*/
|
||||
@Accessors(chain = true)
|
||||
@Data
|
||||
public class StatsInfoRes {
|
||||
private CacheInfo cacheInfo;
|
||||
|
||||
@Data
|
||||
public static class CacheInfo {
|
||||
private Integer proxyInfoMapSize;
|
||||
private Integer serverPortToCmdChannelMapSize;
|
||||
private Integer licenseToCmdChannelMapSize;
|
||||
private Integer serverPortToVisitorChannelMapSize;
|
||||
private Integer proxyConnectAttachmentMapSize;
|
||||
private Integer fullDomainToServerPortMapSize;
|
||||
private Integer domainToDomainNameIdMapSize;
|
||||
private Integer licenseIdToClientIdMapSize;
|
||||
private Integer visitorIdToSocketAddressMapSize;
|
||||
private Integer socketAddressToVisitorIdMapSize;
|
||||
private Integer visitorIdToTunnelChannelMapSize;
|
||||
}
|
||||
|
||||
}
|
||||
+11
-10
@@ -79,14 +79,7 @@ public class ProxyMessageConnectHandler implements ProxyMessageHandler {
|
||||
ctx.channel().close();
|
||||
return;
|
||||
}
|
||||
// 获取代理附加对象
|
||||
Constants.ProxyAttachment proxyAttachment = visitorChannel.attr(Constants.PROXY_CONNECT_ATTACHMENT).get();
|
||||
if (null == proxyAttachment) {
|
||||
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.CONNECT_FAILED, "server error,visitor channel proxy attachment not found!"));
|
||||
ctx.channel().close();
|
||||
visitorChannel.close();
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.channel().attr(Constants.VISITOR_ID).set(visitorId);
|
||||
ctx.channel().attr(Constants.LICENSE_ID).set(licenseDO.getId());
|
||||
ctx.channel().attr(Constants.NEXT_CHANNEL).set(visitorChannel);
|
||||
@@ -95,8 +88,16 @@ public class ProxyMessageConnectHandler implements ProxyMessageHandler {
|
||||
// 代理客户端与后端服务器连接成功,修改用户连接为可读状态
|
||||
visitorChannel.config().setOption(ChannelOption.AUTO_READ, true);
|
||||
|
||||
// 转发来自visitor的首次代理数据
|
||||
proxyAttachment.execute(visitorChannel);
|
||||
|
||||
// 获取代理附加对象
|
||||
Constants.ProxyAttachment proxyAttachment = visitorChannel.attr(Constants.PROXY_CONNECT_ATTACHMENT).get();
|
||||
if (null != proxyAttachment) {
|
||||
// 转发来自visitor的首次代理数据
|
||||
proxyAttachment.execute(visitorChannel);
|
||||
|
||||
// 此处时TCP代理,不一定有代理附加对象,不能因为没有而直接释放visitorChannel
|
||||
}
|
||||
|
||||
|
||||
// // 获取代理附加对象
|
||||
// ProxyAttachment proxyAttachment = ProxyUtil.getProxyConnectAttachment(visitorId);
|
||||
|
||||
+61
@@ -6,16 +6,21 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.dromara.neutrinoproxy.core.ChannelAttribute;
|
||||
import org.dromara.neutrinoproxy.core.Constants;
|
||||
import org.dromara.neutrinoproxy.server.constant.NetworkProtocolEnum;
|
||||
import org.dromara.neutrinoproxy.server.controller.res.stats.StatsInfoRes;
|
||||
import org.dromara.neutrinoproxy.server.proxy.domain.CmdChannelAttachInfo;
|
||||
import org.dromara.neutrinoproxy.server.proxy.domain.ProxyMapping;
|
||||
import org.dromara.neutrinoproxy.server.proxy.domain.VisitorChannelAttachInfo;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import org.dromara.solonplugins.job.CustomThreadFactory;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
@@ -88,6 +93,46 @@ public class ProxyUtil {
|
||||
*/
|
||||
private static Map<String, Channel> visitorIdToTunnelChannelMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* cache扫描器
|
||||
*/
|
||||
private static final ScheduledExecutorService cacheScanner = Executors.newSingleThreadScheduledExecutor(new CustomThreadFactory("cacheScanner"));
|
||||
|
||||
|
||||
/**
|
||||
* 初始化,启动一个定时器,定时清理缓存
|
||||
*/
|
||||
public static void init() {
|
||||
cacheScanner.scheduleWithFixedDelay(ProxyUtil::cacheScan, 5, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public static synchronized void cacheScan() {
|
||||
for (Integer key : serverPortToCmdChannelMap.keySet()) {
|
||||
Channel channel = serverPortToCmdChannelMap.get(key);
|
||||
if (null == channel || !channel.isRegistered()) {
|
||||
serverPortToCmdChannelMap.remove(key);
|
||||
}
|
||||
}
|
||||
for (Integer key : licenseToCmdChannelMap.keySet()) {
|
||||
Channel channel = licenseToCmdChannelMap.get(key);
|
||||
if (null == channel || !channel.isRegistered()) {
|
||||
licenseToCmdChannelMap.remove(key);
|
||||
}
|
||||
}
|
||||
for (Integer key : serverPortToVisitorChannel.keySet()) {
|
||||
Channel channel = serverPortToVisitorChannel.get(key);
|
||||
if (null == channel || !channel.isRegistered()) {
|
||||
serverPortToVisitorChannel.remove(key);
|
||||
}
|
||||
}
|
||||
for (String key : visitorIdToTunnelChannelMap.keySet()) {
|
||||
Channel channel = visitorIdToTunnelChannelMap.get(key);
|
||||
if (null == channel || !channel.isRegistered()) {
|
||||
visitorIdToTunnelChannelMap.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化代理信息
|
||||
* @param licenseId licenseId
|
||||
@@ -524,4 +569,20 @@ public class ProxyUtil {
|
||||
return visitorIdToTunnelChannelMap.get(visitorId);
|
||||
}
|
||||
|
||||
public static StatsInfoRes.CacheInfo getCacheInfo() {
|
||||
return new StatsInfoRes.CacheInfo()
|
||||
.setProxyInfoMapSize(proxyInfoMap.size())
|
||||
.setServerPortToCmdChannelMapSize(serverPortToCmdChannelMap.size())
|
||||
.setLicenseToCmdChannelMapSize(licenseToCmdChannelMap.size())
|
||||
.setServerPortToVisitorChannelMapSize(serverPortToVisitorChannel.size())
|
||||
.setProxyConnectAttachmentMapSize(proxyConnectAttachmentMap.size())
|
||||
.setFullDomainToServerPortMapSize(fullDomainToServerPortMap.size())
|
||||
.setDomainToDomainNameIdMapSize(domainToDomainNameIdMap.size())
|
||||
.setLicenseIdToClientIdMapSize(licenseIdToClientIdMap.size())
|
||||
.setVisitorIdToSocketAddressMapSize(visitorIdToSocketAddressMap.size())
|
||||
.setSocketAddressToVisitorIdMapSize(socketAddressToVisitorIdMap.size())
|
||||
.setVisitorIdToTunnelChannelMapSize(visitorIdToTunnelChannelMap.size())
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ server:
|
||||
solon:
|
||||
app:
|
||||
name: neutrino-proxy-server
|
||||
version: 2.0.2
|
||||
version: 2.0.4.t1
|
||||
config:
|
||||
add: ./app.yml
|
||||
# 日志级别
|
||||
|
||||
Reference in New Issue
Block a user