增加cache大小检查接口
This commit is contained in:
@@ -3,7 +3,7 @@ solon:
|
|||||||
add: ./app.yml
|
add: ./app.yml
|
||||||
app:
|
app:
|
||||||
name: neutrino-proxy-client
|
name: neutrino-proxy-client
|
||||||
version: 2.0.2
|
version: 2.0.4.t1
|
||||||
# 日志级别
|
# 日志级别
|
||||||
solon.logging.appender:
|
solon.logging.appender:
|
||||||
console:
|
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.TcpVisitorSecurityChannelHandler;
|
||||||
import org.dromara.neutrinoproxy.server.proxy.security.UdpVisitorSecurityChannelHandler;
|
import org.dromara.neutrinoproxy.server.proxy.security.UdpVisitorSecurityChannelHandler;
|
||||||
import org.dromara.neutrinoproxy.server.proxy.security.VisitorFlowLimiterChannelHandler;
|
import org.dromara.neutrinoproxy.server.proxy.security.VisitorFlowLimiterChannelHandler;
|
||||||
|
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
|
||||||
import org.noear.solon.Solon;
|
import org.noear.solon.Solon;
|
||||||
import org.noear.solon.annotation.Bean;
|
import org.noear.solon.annotation.Bean;
|
||||||
import org.noear.solon.annotation.Configuration;
|
import org.noear.solon.annotation.Configuration;
|
||||||
@@ -46,6 +47,8 @@ public class ProxyConfiguration implements LifecycleBean {
|
|||||||
null : ProxyDataTypeEnum.of((int)proxyMessage.getType()).getName());
|
null : ProxyDataTypeEnum.of((int)proxyMessage.getType()).getName());
|
||||||
|
|
||||||
Solon.context().wrapAndPut(Dispatcher.class, dispatcher);
|
Solon.context().wrapAndPut(Dispatcher.class, dispatcher);
|
||||||
|
|
||||||
|
ProxyUtil.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean("tcpServerBossGroup")
|
@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();
|
ctx.channel().close();
|
||||||
return;
|
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.VISITOR_ID).set(visitorId);
|
||||||
ctx.channel().attr(Constants.LICENSE_ID).set(licenseDO.getId());
|
ctx.channel().attr(Constants.LICENSE_ID).set(licenseDO.getId());
|
||||||
ctx.channel().attr(Constants.NEXT_CHANNEL).set(visitorChannel);
|
ctx.channel().attr(Constants.NEXT_CHANNEL).set(visitorChannel);
|
||||||
@@ -95,8 +88,16 @@ public class ProxyMessageConnectHandler implements ProxyMessageHandler {
|
|||||||
// 代理客户端与后端服务器连接成功,修改用户连接为可读状态
|
// 代理客户端与后端服务器连接成功,修改用户连接为可读状态
|
||||||
visitorChannel.config().setOption(ChannelOption.AUTO_READ, true);
|
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);
|
// 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.ChannelAttribute;
|
||||||
import org.dromara.neutrinoproxy.core.Constants;
|
import org.dromara.neutrinoproxy.core.Constants;
|
||||||
import org.dromara.neutrinoproxy.server.constant.NetworkProtocolEnum;
|
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.CmdChannelAttachInfo;
|
||||||
import org.dromara.neutrinoproxy.server.proxy.domain.ProxyMapping;
|
import org.dromara.neutrinoproxy.server.proxy.domain.ProxyMapping;
|
||||||
import org.dromara.neutrinoproxy.server.proxy.domain.VisitorChannelAttachInfo;
|
import org.dromara.neutrinoproxy.server.proxy.domain.VisitorChannelAttachInfo;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.util.AttributeKey;
|
import io.netty.util.AttributeKey;
|
||||||
|
import org.dromara.solonplugins.job.CustomThreadFactory;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
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.atomic.AtomicLong;
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
@@ -88,6 +93,46 @@ public class ProxyUtil {
|
|||||||
*/
|
*/
|
||||||
private static Map<String, Channel> visitorIdToTunnelChannelMap = new HashMap<>();
|
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
|
* @param licenseId licenseId
|
||||||
@@ -524,4 +569,20 @@ public class ProxyUtil {
|
|||||||
return visitorIdToTunnelChannelMap.get(visitorId);
|
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:
|
solon:
|
||||||
app:
|
app:
|
||||||
name: neutrino-proxy-server
|
name: neutrino-proxy-server
|
||||||
version: 2.0.2
|
version: 2.0.4.t1
|
||||||
config:
|
config:
|
||||||
add: ./app.yml
|
add: ./app.yml
|
||||||
# 日志级别
|
# 日志级别
|
||||||
|
|||||||
Reference in New Issue
Block a user