mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-09-28 23:56:36 +08:00
修复bug
This commit is contained in:
Binary file not shown.
+1
-1
@@ -119,7 +119,7 @@ func main() {
|
||||
log := xlogger.NewLogger()
|
||||
logger.SetDefault(log)
|
||||
|
||||
wsReporter := socket.StartWebSocketReporterWithConfig(config.Addr, config.Secret, "1.1.0")
|
||||
wsReporter := socket.StartWebSocketReporterWithConfig(config.Addr, config.Secret, "1.1.1")
|
||||
defer wsReporter.Stop()
|
||||
|
||||
service.SetHTTPReportURL(config.Addr, config.Secret)
|
||||
|
||||
@@ -2,9 +2,9 @@ package port
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ func ForceClosePortConnections(addr string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, portStr, err := splitHostPort(addr)
|
||||
_, portStr, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
fmt.Printf("⚠️ 地址解析失败: %v\n", err)
|
||||
return nil
|
||||
@@ -56,18 +56,3 @@ func ForceClosePortConnections(addr string) (err error) {
|
||||
fmt.Printf("✅ 正在断开端口 %d 上的所有连接...\n", port)
|
||||
return nil
|
||||
}
|
||||
|
||||
func splitHostPort(addr string) (string, string, error) {
|
||||
if !strings.Contains(addr, ":") {
|
||||
return "", "", fmt.Errorf("missing port in address")
|
||||
}
|
||||
return netSplitHostPortCompat(addr)
|
||||
}
|
||||
|
||||
func netSplitHostPortCompat(addr string) (string, string, error) {
|
||||
lastColon := strings.LastIndex(addr, ":")
|
||||
if lastColon < 0 {
|
||||
return "", "", fmt.Errorf("missing port")
|
||||
}
|
||||
return addr[:lastColon], addr[lastColon+1:], nil
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableAsync
|
||||
@EnableScheduling
|
||||
public class AdminApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -1,546 +0,0 @@
|
||||
package com.admin.common.task;
|
||||
|
||||
|
||||
import com.admin.mapper.UserMapper;
|
||||
import com.admin.mapper.ForwardMapper;
|
||||
import com.admin.mapper.UserTunnelMapper;
|
||||
import com.admin.mapper.TunnelMapper;
|
||||
import com.admin.mapper.NodeMapper;
|
||||
import com.admin.service.UserService;
|
||||
import com.admin.service.UserTunnelService;
|
||||
import com.admin.entity.Forward;
|
||||
import com.admin.entity.Tunnel;
|
||||
import com.admin.entity.Node;
|
||||
import com.admin.entity.UserTunnel;
|
||||
import com.admin.common.dto.GostDto;
|
||||
import com.admin.common.utils.GostUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.DelayQueue;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DelayQueueManager implements CommandLineRunner {
|
||||
|
||||
private final DelayQueue<DelayTask> delayQueue = new DelayQueue<>();
|
||||
|
||||
@Autowired
|
||||
UserMapper userMapper;
|
||||
|
||||
@Resource
|
||||
ForwardMapper forwardMapper;
|
||||
|
||||
@Resource
|
||||
UserTunnelMapper userTunnelMapper;
|
||||
|
||||
@Resource
|
||||
TunnelMapper tunnelMapper;
|
||||
|
||||
@Resource
|
||||
NodeMapper nodeMapper;
|
||||
|
||||
/**
|
||||
* 加入到延时队列中
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
public void put(DelayTask task) {
|
||||
log.info("加入延时任务:{}", task);
|
||||
delayQueue.put(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消延时任务
|
||||
*
|
||||
* @param task
|
||||
* @return
|
||||
*/
|
||||
public boolean remove(DelayTask task) {
|
||||
log.info("取消延时任务:{}", task);
|
||||
return delayQueue.remove(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消延时任务
|
||||
*
|
||||
* @param taskid
|
||||
* @return
|
||||
*/
|
||||
public boolean remove(String taskid) {
|
||||
return remove(new DelayTask(new TaskBase(taskid), 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消延时任务
|
||||
*
|
||||
* @param taskid
|
||||
* @return
|
||||
*/
|
||||
public boolean remove_a(String taskid) {
|
||||
return remove(new DelayTask(new TaskBase(taskid), 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("初始化延时队列");
|
||||
Executors.newSingleThreadExecutor().execute(new Thread(this::excuteThread));
|
||||
|
||||
// 初始化用户账号到期延时任务
|
||||
initUserExpirationTasks();
|
||||
|
||||
// 初始化用户隧道到期延时任务
|
||||
initUserTunnelExpirationTasks();
|
||||
}
|
||||
|
||||
/**
|
||||
* 延时任务执行线程
|
||||
*/
|
||||
private void excuteThread() {
|
||||
while (true) {
|
||||
try {
|
||||
DelayTask task = delayQueue.take();
|
||||
processTask(task);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 内部执行延时任务
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
private void processTask(DelayTask task) {
|
||||
log.info("执行延时任务:{}", task.getData().toString());
|
||||
TaskBase data = task.getData();
|
||||
switch (data.getType()){
|
||||
case "1": // 账号到期延迟任务
|
||||
handleUserExpiration(data.getData());
|
||||
break;
|
||||
case "2": // 隧道到期延迟任务
|
||||
handleUserTunnelExpiration(data.getData());
|
||||
break;
|
||||
default:
|
||||
log.error("未知延时任务类型:{}", data.getType());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理用户账号到期
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
private void handleUserExpiration(String userId) {
|
||||
try {
|
||||
log.info("处理用户账号到期,用户ID:{}", userId);
|
||||
Long userIdLong = Long.parseLong(userId);
|
||||
|
||||
// 获取用户信息
|
||||
com.admin.entity.User user = userMapper.selectById(userIdLong);
|
||||
if (user == null) {
|
||||
log.warn("用户不存在,用户ID:{}", userId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查用户是否确实已过期
|
||||
if (user.getExpTime() != null && user.getExpTime() > System.currentTimeMillis()) {
|
||||
log.info("用户未过期,无需处理,用户ID:{},过期时间:{}", userId, user.getExpTime());
|
||||
return;
|
||||
}
|
||||
|
||||
// 禁用用户账号
|
||||
user.setStatus(0); // 设置为禁用状态
|
||||
user.setUpdatedTime(System.currentTimeMillis());
|
||||
|
||||
int i = userMapper.updateById(user);
|
||||
if (i != 0) {
|
||||
log.info("用户账号已禁用,用户ID:{}", userId);
|
||||
|
||||
// 清理用户相关的活跃连接和服务
|
||||
cleanupUserServices(userIdLong);
|
||||
} else {
|
||||
log.error("禁用用户账号失败,用户ID:{}", userId);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理用户账号到期异常,用户ID:{},错误:{}", userId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理用户相关服务
|
||||
*
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
private void cleanupUserServices(Long userId) {
|
||||
try {
|
||||
log.info("暂停用户相关转发服务,用户ID:{}", userId);
|
||||
|
||||
// 获取用户的所有转发
|
||||
QueryWrapper<Forward> forwardQuery = new QueryWrapper<>();
|
||||
forwardQuery.eq("user_id", userId);
|
||||
List<Forward> userForwards = forwardMapper.selectList(forwardQuery);
|
||||
|
||||
log.info("找到用户转发数量:{},用户ID:{}", userForwards.size(), userId);
|
||||
|
||||
for (Forward forward : userForwards) {
|
||||
try {
|
||||
// 暂停转发服务
|
||||
pauseForwardService(forward, userId);
|
||||
} catch (Exception e) {
|
||||
log.error("暂停转发服务失败,转发ID:{},用户ID:{},错误:{}", forward.getId(), userId, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("清理用户服务失败,用户ID:{},错误:{}", userId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停转发服务
|
||||
*
|
||||
* @param forward 转发对象
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
private void pauseForwardService(Forward forward, Long userId) {
|
||||
try {
|
||||
Tunnel tunnel = tunnelMapper.selectById(forward.getTunnelId());
|
||||
if (tunnel == null) {
|
||||
log.warn("隧道不存在,跳过暂停,转发ID:{},隧道ID:{}", forward.getId(), forward.getTunnelId());
|
||||
return;
|
||||
}
|
||||
|
||||
Node inNode = nodeMapper.selectById(tunnel.getInNodeId());
|
||||
if (inNode == null) {
|
||||
log.warn("入口节点不存在,跳过暂停,转发ID:{},节点ID:{}", forward.getId(), tunnel.getInNodeId());
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取用户隧道关系
|
||||
UserTunnel userTunnel = getUserTunnelRelation(userId, tunnel.getId());
|
||||
if (userTunnel == null) {
|
||||
log.warn("用户隧道关系不存在,跳过暂停,用户ID:{},隧道ID:{}", userId, tunnel.getId());
|
||||
return;
|
||||
}
|
||||
|
||||
String serviceName = buildServiceName(forward.getId(), userId, userTunnel.getId());
|
||||
|
||||
// 暂停主服务
|
||||
GostDto result = GostUtil.PauseService(inNode.getId(), serviceName);
|
||||
|
||||
// 隧道转发需要同时暂停远端服务
|
||||
if (tunnel.getType() == 2) { // TUNNEL_TYPE_TUNNEL_FORWARD
|
||||
Node outNode = nodeMapper.selectById(tunnel.getOutNodeId());
|
||||
if (outNode != null) {
|
||||
GostDto remoteResult = GostUtil.PauseRemoteService(outNode.getId(), serviceName);
|
||||
if (!"OK".equals(remoteResult.getMsg())) {
|
||||
log.warn("暂停远端服务失败,转发ID:{},用户ID:{},服务名:{},结果:{}",
|
||||
forward.getId(), userId, serviceName, remoteResult.getMsg());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( "OK".equals(result.getMsg())) {
|
||||
forward.setStatus(0);
|
||||
forwardMapper.updateById(forward);
|
||||
log.info("成功暂停转发服务,转发ID:{},用户ID:{},服务名:{}", forward.getId(), userId, serviceName);
|
||||
} else {
|
||||
log.warn("暂停转发服务失败,转发ID:{},用户ID:{},服务名:{},结果:{}",
|
||||
forward.getId(), userId, serviceName, result.getMsg());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("暂停转发服务异常,转发ID:{},用户ID:{},错误:{}", forward.getId(), userId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户隧道关系
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param tunnelId 隧道ID
|
||||
* @return 用户隧道关系对象
|
||||
*/
|
||||
private UserTunnel getUserTunnelRelation(Long userId, Long tunnelId) {
|
||||
try {
|
||||
QueryWrapper<UserTunnel> query = new QueryWrapper<>();
|
||||
query.eq("user_id", userId).eq("tunnel_id", tunnelId);
|
||||
return userTunnelMapper.selectOne(query);
|
||||
} catch (Exception e) {
|
||||
log.error("获取用户隧道关系失败,用户ID:{},隧道ID:{},错误:{}", userId, tunnelId, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建服务名称
|
||||
*
|
||||
* @param forwardId 转发ID
|
||||
* @param userId 用户ID
|
||||
* @param userTunnelId 用户隧道ID
|
||||
* @return 服务名称
|
||||
*/
|
||||
private String buildServiceName(Long forwardId, Long userId, Integer userTunnelId) {
|
||||
return forwardId + "_" + userId + "_" + userTunnelId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化用户账号到期延时任务
|
||||
* 查询所有非管理员的正常用户,为有到期时间且未过期的用户创建延时任务
|
||||
*/
|
||||
private void initUserExpirationTasks() {
|
||||
try {
|
||||
log.info("开始初始化用户账号到期延时任务");
|
||||
QueryWrapper<com.admin.entity.User> userQuery = new QueryWrapper<>();
|
||||
userQuery.ne("role_id", 0) // 排除管理员用户
|
||||
.eq("status", 1) // 只查询启用状态的用户
|
||||
.isNotNull("exp_time") // 只查询有到期时间的用户
|
||||
.orderBy(true, true, "exp_time"); // 按到期时间排序
|
||||
|
||||
List<com.admin.entity.User> users = userMapper.selectList(userQuery);
|
||||
|
||||
|
||||
|
||||
for (com.admin.entity.User user : users) {
|
||||
scheduleUserExpirationTask(user);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("初始化用户账号到期延时任务失败:{}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排用户到期延时任务
|
||||
*
|
||||
* @param user 用户对象
|
||||
*/
|
||||
private void scheduleUserExpirationTask(com.admin.entity.User user) {
|
||||
try {
|
||||
if (user.getExpTime() != null && user.getExpTime() > System.currentTimeMillis()) {
|
||||
// 创建延时任务
|
||||
TaskBase taskBase = new TaskBase(user.getId().toString());
|
||||
taskBase.setType("1"); // 账号到期延迟任务
|
||||
|
||||
long delayTime = user.getExpTime() - System.currentTimeMillis();
|
||||
DelayTask delayTask = new DelayTask(taskBase, delayTime);
|
||||
|
||||
put(delayTask);
|
||||
|
||||
log.debug("已添加用户到期延时任务,用户ID:{},到期时间:{},剩余时间:{}ms",
|
||||
user.getId(), user.getExpTime(), delayTime);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("添加用户到期延时任务失败,用户ID:{},错误:{}", user.getId(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理用户隧道到期
|
||||
*
|
||||
* @param userTunnelId 用户隧道ID
|
||||
*/
|
||||
private void handleUserTunnelExpiration(String userTunnelId) {
|
||||
try {
|
||||
log.info("处理用户隧道到期,用户隧道ID:{}", userTunnelId);
|
||||
Integer userTunnelIdInt = Integer.parseInt(userTunnelId);
|
||||
|
||||
// 获取用户隧道信息
|
||||
UserTunnel userTunnel = userTunnelMapper.selectById(userTunnelIdInt);
|
||||
if (userTunnel == null) {
|
||||
log.warn("用户隧道不存在,用户隧道ID:{}", userTunnelId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查用户隧道是否确实已过期
|
||||
if (userTunnel.getExpTime() != null && userTunnel.getExpTime() > System.currentTimeMillis()) {
|
||||
log.info("用户隧道未过期,无需处理,用户隧道ID:{},过期时间:{}", userTunnelId, userTunnel.getExpTime());
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("用户隧道已过期,开始处理,用户隧道ID:{},用户ID:{},隧道ID:{}",
|
||||
userTunnelId, userTunnel.getUserId(), userTunnel.getTunnelId());
|
||||
|
||||
// 暂停该用户在该隧道上的所有转发服务
|
||||
cleanupUserTunnelServices(userTunnel);
|
||||
|
||||
// 禁用过期的用户隧道权限(设置status为0)
|
||||
userTunnel.setStatus(0);
|
||||
int updateResult = userTunnelMapper.updateById(userTunnel);
|
||||
if (updateResult > 0) {
|
||||
log.info("已禁用过期的用户隧道权限,用户隧道ID:{}", userTunnelId);
|
||||
} else {
|
||||
log.error("禁用过期用户隧道权限失败,用户隧道ID:{}", userTunnelId);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理用户隧道到期异常,用户隧道ID:{},错误:{}", userTunnelId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理用户隧道相关服务
|
||||
*
|
||||
* @param userTunnel 用户隧道对象
|
||||
*/
|
||||
private void cleanupUserTunnelServices(UserTunnel userTunnel) {
|
||||
try {
|
||||
log.info("暂停用户隧道相关转发服务,用户ID:{},隧道ID:{}", userTunnel.getUserId(), userTunnel.getTunnelId());
|
||||
|
||||
// 获取该用户在该隧道上的所有转发
|
||||
QueryWrapper<Forward> forwardQuery = new QueryWrapper<>();
|
||||
forwardQuery.eq("user_id", userTunnel.getUserId())
|
||||
.eq("tunnel_id", userTunnel.getTunnelId());
|
||||
List<Forward> userTunnelForwards = forwardMapper.selectList(forwardQuery);
|
||||
|
||||
log.info("找到用户隧道转发数量:{},用户ID:{},隧道ID:{}",
|
||||
userTunnelForwards.size(), userTunnel.getUserId(), userTunnel.getTunnelId());
|
||||
|
||||
for (Forward forward : userTunnelForwards) {
|
||||
try {
|
||||
// 暂停转发服务
|
||||
pauseUserTunnelForwardService(forward, userTunnel);
|
||||
} catch (Exception e) {
|
||||
log.error("暂停用户隧道转发服务失败,转发ID:{},用户ID:{},隧道ID:{},错误:{}",
|
||||
forward.getId(), userTunnel.getUserId(), userTunnel.getTunnelId(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("清理用户隧道服务失败,用户ID:{},隧道ID:{},错误:{}",
|
||||
userTunnel.getUserId(), userTunnel.getTunnelId(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停用户隧道转发服务
|
||||
*
|
||||
* @param forward 转发对象
|
||||
* @param userTunnel 用户隧道对象
|
||||
*/
|
||||
private void pauseUserTunnelForwardService(Forward forward, UserTunnel userTunnel) {
|
||||
try {
|
||||
Tunnel tunnel = tunnelMapper.selectById(forward.getTunnelId());
|
||||
if (tunnel == null) {
|
||||
log.warn("隧道不存在,跳过暂停,转发ID:{},隧道ID:{}", forward.getId(), forward.getTunnelId());
|
||||
return;
|
||||
}
|
||||
|
||||
Node inNode = nodeMapper.selectById(tunnel.getInNodeId());
|
||||
if (inNode == null) {
|
||||
log.warn("入口节点不存在,跳过暂停,转发ID:{},节点ID:{}", forward.getId(), tunnel.getInNodeId());
|
||||
return;
|
||||
}
|
||||
|
||||
String serviceName = buildServiceName(forward.getId(), Long.valueOf(userTunnel.getUserId()), userTunnel.getId());
|
||||
|
||||
// 暂停服务
|
||||
GostDto result = GostUtil.PauseService(inNode.getId(), serviceName);
|
||||
|
||||
// 隧道转发需要同时暂停远端服务
|
||||
if (tunnel.getType() == 2) { // TUNNEL_TYPE_TUNNEL_FORWARD
|
||||
Node outNode = nodeMapper.selectById(tunnel.getOutNodeId());
|
||||
if (outNode != null) {
|
||||
GostDto remoteResult = GostUtil.PauseRemoteService(outNode.getId(), serviceName);
|
||||
if (!"OK".equals(remoteResult.getMsg())) {
|
||||
log.warn("暂停远端服务失败,转发ID:{},用户ID:{},隧道ID:{},服务名:{},结果:{}",
|
||||
forward.getId(), userTunnel.getUserId(), userTunnel.getTunnelId(), serviceName, remoteResult.getMsg());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("OK".equals(result.getMsg())) {
|
||||
forward.setStatus(0);
|
||||
forwardMapper.updateById(forward);
|
||||
log.info("成功暂停用户隧道转发服务,转发ID:{},用户ID:{},隧道ID:{},服务名:{}",
|
||||
forward.getId(), userTunnel.getUserId(), userTunnel.getTunnelId(), serviceName);
|
||||
} else {
|
||||
log.warn("暂停用户隧道转发服务失败,转发ID:{},用户ID:{},隧道ID:{},服务名:{},结果:{}",
|
||||
forward.getId(), userTunnel.getUserId(), userTunnel.getTunnelId(), serviceName, result.getMsg());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("暂停用户隧道转发服务异常,转发ID:{},用户ID:{},隧道ID:{},错误:{}",
|
||||
forward.getId(), userTunnel.getUserId(), userTunnel.getTunnelId(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化用户隧道到期延时任务
|
||||
* 查询所有有到期时间且未过期的用户隧道权限,为其创建延时任务
|
||||
*/
|
||||
private void initUserTunnelExpirationTasks() {
|
||||
try {
|
||||
log.info("开始初始化用户隧道到期延时任务");
|
||||
QueryWrapper<UserTunnel> userTunnelQuery = new QueryWrapper<>();
|
||||
userTunnelQuery.eq("status", 1); // 按到期时间排序
|
||||
|
||||
List<UserTunnel> userTunnels = userTunnelMapper.selectList(userTunnelQuery);
|
||||
|
||||
int taskCount = 0;
|
||||
|
||||
for (UserTunnel userTunnel : userTunnels) {
|
||||
scheduleUserTunnelExpirationTask(userTunnel);
|
||||
}
|
||||
|
||||
log.info("完成初始化用户隧道到期延时任务,总计查询:{},添加任务:{}", userTunnels.size(), taskCount);
|
||||
} catch (Exception e) {
|
||||
log.error("初始化用户隧道到期延时任务失败:{}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排用户隧道到期延时任务
|
||||
*
|
||||
* @param userTunnel 用户隧道对象
|
||||
*/
|
||||
private void scheduleUserTunnelExpirationTask(UserTunnel userTunnel) {
|
||||
// 创建延时任务
|
||||
TaskBase taskBase = new TaskBase(userTunnel.getId().toString());
|
||||
taskBase.setType("2"); // 隧道到期延迟任务
|
||||
|
||||
long delayTime = userTunnel.getExpTime() - System.currentTimeMillis();
|
||||
DelayTask delayTask = new DelayTask(taskBase, delayTime);
|
||||
|
||||
put(delayTask);
|
||||
|
||||
log.debug("已添加用户隧道到期延时任务,用户隧道ID:{},用户ID:{},隧道ID:{},到期时间:{},剩余时间:{}ms",
|
||||
userTunnel.getId(), userTunnel.getUserId(), userTunnel.getTunnelId(),
|
||||
userTunnel.getExpTime(), delayTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户隧道到期延时任务(公共方法,供其他服务调用)
|
||||
*
|
||||
* @param userTunnel 用户隧道对象
|
||||
*/
|
||||
public void addUserTunnelExpirationTask(UserTunnel userTunnel) {
|
||||
scheduleUserTunnelExpirationTask(userTunnel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除用户隧道到期延时任务(公共方法,供其他服务调用)
|
||||
*
|
||||
* @param userTunnelId 用户隧道ID
|
||||
*/
|
||||
public void removeUserTunnelExpirationTask(Integer userTunnelId) {
|
||||
String taskId = userTunnelId.toString();
|
||||
boolean removed = remove(taskId);
|
||||
if (removed) {
|
||||
log.info("已移除用户隧道到期延时任务,用户隧道ID:{}", userTunnelId);
|
||||
} else {
|
||||
log.debug("未找到需要移除的用户隧道到期延时任务,用户隧道ID:{}", userTunnelId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.admin.common.task;
|
||||
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* 延时任务
|
||||
*/
|
||||
public class DelayTask implements Delayed {
|
||||
//任务参数
|
||||
final private TaskBase data;
|
||||
//任务的延时时间,单位毫秒
|
||||
final private long expire;
|
||||
|
||||
/**
|
||||
* 构造延时任务
|
||||
*
|
||||
* @param data 业务数据
|
||||
* @param expire 任务延时时间(ms)
|
||||
*/
|
||||
public DelayTask(TaskBase data, long expire) {
|
||||
super();
|
||||
this.data = data;
|
||||
this.expire = expire + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public TaskBase getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public long getExpire() {
|
||||
return expire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof DelayTask) {
|
||||
return this.data.getData().equals(((DelayTask) obj).getData().getData());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + "data:" + data.toString() + "," + "延时时间:"+expire+"}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDelay(TimeUnit unit) {
|
||||
return unit.convert(this.expire - System.currentTimeMillis(), unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Delayed o) {
|
||||
long delta = getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
|
||||
return (int) delta;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
package com.admin.common.task;
|
||||
|
||||
import com.admin.common.utils.GostUtil;
|
||||
import com.admin.entity.Forward;
|
||||
import com.admin.entity.Tunnel;
|
||||
import com.admin.entity.User;
|
||||
import com.admin.entity.UserTunnel;
|
||||
import com.admin.service.ForwardService;
|
||||
import com.admin.service.TunnelService;
|
||||
import com.admin.service.UserService;
|
||||
import com.admin.service.UserTunnelService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
@@ -13,6 +18,7 @@ import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@@ -26,6 +32,12 @@ public class ResetFlowAsync {
|
||||
@Resource
|
||||
UserTunnelService userTunnelService;
|
||||
|
||||
@Resource
|
||||
ForwardService forwardService;
|
||||
|
||||
@Resource
|
||||
TunnelService tunnelService;
|
||||
|
||||
/**
|
||||
* 每天0点执行流量重置任务
|
||||
* 查询出用户和隧道的重置流量日期是今天的数据,将上下流量重置为0
|
||||
@@ -55,9 +67,18 @@ public class ResetFlowAsync {
|
||||
resetUserTunnelFlow(currentDay, lastDayOfMonth);
|
||||
|
||||
log.info("流量重置任务执行完成");
|
||||
|
||||
|
||||
// 处理过期账号
|
||||
user();
|
||||
|
||||
// 处理过期隧道
|
||||
userTunnel();
|
||||
|
||||
log.info("到期任务执行完成");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("流量重置任务执行失败", e);
|
||||
log.error("定时任务执行失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,4 +188,57 @@ public class ResetFlowAsync {
|
||||
log.error("重置用户隧道流量失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void user(){
|
||||
// 查询过期用户
|
||||
List<User> user_list = userService.list(new QueryWrapper<User>().ne("role_id", 0).eq("status", 1).isNotNull("exp_time").lt("exp_time", new Date().getTime()));
|
||||
for (User user : user_list) {
|
||||
// 查询对应转发
|
||||
List<Forward> forwardList = forwardService.list(new QueryWrapper<Forward>().eq("user_id", user.getId()).eq("status", 1));
|
||||
for (Forward forward : forwardList) {
|
||||
UserTunnel userTunnel = userTunnelService.getOne(new QueryWrapper<UserTunnel>().eq("user_id", forward.getUserId()).eq("tunnel_id", forward.getTunnelId()));
|
||||
if (userTunnel != null) {
|
||||
pauseForwardService(forward, userTunnel.getId());
|
||||
forward.setStatus(0);
|
||||
forwardService.updateById(forward);
|
||||
}
|
||||
}
|
||||
user.setStatus(0);
|
||||
userService.updateById(user);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void userTunnel(){
|
||||
// 查询过期隧道
|
||||
List<UserTunnel> user_tunnel_list = userTunnelService.list(new QueryWrapper<UserTunnel>().eq("status", 1).isNotNull("exp_time").lt("exp_time", new Date().getTime()));
|
||||
// 查询对应转发
|
||||
for (UserTunnel userTunnel : user_tunnel_list) {
|
||||
List<Forward> forwardList = forwardService.list(new QueryWrapper<Forward>().eq("tunnel_id", userTunnel.getTunnelId()).eq("status", 1));
|
||||
for (Forward forward : forwardList) {
|
||||
pauseForwardService(forward, userTunnel.getId());
|
||||
forward.setStatus(0);
|
||||
forwardService.updateById(forward);
|
||||
}
|
||||
userTunnel.setStatus(0);
|
||||
userTunnelService.updateById(userTunnel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void pauseForwardService(Forward forward, Integer userTunnelId) {
|
||||
Tunnel tunnel = tunnelService.getById(forward.getTunnelId());
|
||||
if (tunnel == null) return;
|
||||
|
||||
GostUtil.PauseService(tunnel.getInNodeId(), buildServiceName(forward.getId(), forward.getUserId(), userTunnelId));
|
||||
if (tunnel.getType() == 2){
|
||||
GostUtil.PauseRemoteService(tunnel.getOutNodeId(), buildServiceName(forward.getId(), forward.getUserId(), userTunnelId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String buildServiceName(Long forwardId, Integer userId, Integer userTunnelId) {
|
||||
return forwardId + "_" + userId + "_" + userTunnelId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.admin.common.task;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TaskBase {
|
||||
private String data;
|
||||
private String type;
|
||||
|
||||
public TaskBase(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@@ -131,6 +131,12 @@ public class ForwardServiceImpl extends ServiceImpl<ForwardMapper, Forward> impl
|
||||
public R updateForward(ForwardUpdateDto forwardUpdateDto) {
|
||||
// 1. 获取当前用户信息
|
||||
UserInfo currentUser = getCurrentUserInfo();
|
||||
if (currentUser.getRoleId() != ADMIN_ROLE_ID) {
|
||||
User user = userService.getById(currentUser.getUserId());
|
||||
if (user == null) return R.err("用户不存在");
|
||||
if (user.getStatus() == 0) return R.err("用户已到期或被禁用");
|
||||
}
|
||||
|
||||
|
||||
// 2. 检查转发是否存在
|
||||
Forward existForward = validateForwardExists(forwardUpdateDto.getId(), currentUser);
|
||||
@@ -321,7 +327,14 @@ public class ForwardServiceImpl extends ServiceImpl<ForwardMapper, Forward> impl
|
||||
private R changeForwardStatus(Long id, int targetStatus, String operation, String gostMethod) {
|
||||
// 1. 获取当前用户信息
|
||||
UserInfo currentUser = getCurrentUserInfo();
|
||||
|
||||
|
||||
if (currentUser.getRoleId() != ADMIN_ROLE_ID) {
|
||||
User user = userService.getById(currentUser.getUserId());
|
||||
if (user == null) return R.err("用户不存在");
|
||||
if (user.getStatus() == 0) return R.err("用户已到期或被禁用");
|
||||
}
|
||||
|
||||
|
||||
// 2. 检查转发是否存在
|
||||
Forward forward = validateForwardExists(id, currentUser);
|
||||
if (forward == null) {
|
||||
|
||||
@@ -4,9 +4,6 @@ import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.admin.common.dto.*;
|
||||
import com.admin.common.lang.R;
|
||||
import com.admin.common.task.DelayQueueManager;
|
||||
import com.admin.common.task.DelayTask;
|
||||
import com.admin.common.task.TaskBase;
|
||||
import com.admin.common.utils.GostUtil;
|
||||
import com.admin.common.utils.JwtUtil;
|
||||
import com.admin.common.utils.Md5Util;
|
||||
@@ -23,7 +20,6 @@ import com.admin.service.TunnelService;
|
||||
import com.admin.service.UserService;
|
||||
import com.admin.service.UserTunnelService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -53,7 +49,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
/** 用户角色常量 */
|
||||
private static final int ADMIN_ROLE_ID = 0; // 管理员角色ID
|
||||
private static final int USER_ROLE_ID = 1; // 普通用户角色ID
|
||||
private static final long ADMIN_USER_ID = 1L; // 管理员用户ID
|
||||
|
||||
/** 用户状态常量 */
|
||||
private static final int USER_STATUS_ACTIVE = 1; // 用户启用状态
|
||||
@@ -117,9 +112,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
@Resource
|
||||
UserTunnelService userTunnelService;
|
||||
|
||||
@Resource
|
||||
private DelayQueueManager delayQueueManager;
|
||||
|
||||
// ========== 公共接口实现 ==========
|
||||
|
||||
/**
|
||||
@@ -173,7 +165,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
|
||||
if (result) {
|
||||
// 3. 添加到期时间延时任务
|
||||
scheduleUserExpirationTask(user);
|
||||
return R.ok(SUCCESS_CREATE_MSG);
|
||||
} else {
|
||||
return R.err(ERROR_CREATE_FAILED);
|
||||
@@ -223,7 +214,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
|
||||
if (result) {
|
||||
// 5. 处理到期时间延时任务
|
||||
handleUserExpirationTaskUpdate(updateUser);
|
||||
return R.ok(SUCCESS_UPDATE_MSG);
|
||||
} else {
|
||||
return R.err(ERROR_UPDATE_FAILED);
|
||||
@@ -248,7 +238,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
try {
|
||||
// 2. 级联删除用户相关数据
|
||||
deleteUserRelatedData(id);
|
||||
delayQueueManager.remove("user_exp_" + id);
|
||||
// 3. 删除用户
|
||||
boolean result = this.removeById(id);
|
||||
return result ? R.ok(SUCCESS_DELETE_MSG) : R.err(ERROR_DELETE_FAILED);
|
||||
@@ -708,44 +697,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
return userMapper.getUserTunnelDetails(userId.intValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排用户到期延时任务
|
||||
*
|
||||
* @param user 用户对象
|
||||
*/
|
||||
private void scheduleUserExpirationTask(User user) {
|
||||
// 取消已存在的延时任务(如果有)
|
||||
delayQueueManager.remove("user_exp_" + user.getId());
|
||||
|
||||
// 创建新的延时任务
|
||||
TaskBase taskBase = new TaskBase(user.getId().toString());
|
||||
taskBase.setType("1"); // 账号到期延迟任务
|
||||
|
||||
long delayTime = user.getExpTime() - System.currentTimeMillis();
|
||||
DelayTask delayTask = new DelayTask(taskBase, delayTime);
|
||||
|
||||
delayQueueManager.put(delayTask);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理用户到期时间更新的延时任务
|
||||
*
|
||||
* @param newUser 新用户信息
|
||||
*/
|
||||
private void handleUserExpirationTaskUpdate(User newUser) {
|
||||
String taskId = "user_exp_" + newUser.getId();
|
||||
|
||||
// 先取消原有的延时任务
|
||||
delayQueueManager.remove(taskId);
|
||||
|
||||
TaskBase taskBase = new TaskBase(newUser.getId().toString());
|
||||
taskBase.setType("1"); // 账号到期延迟任务
|
||||
|
||||
long delayTime = newUser.getExpTime() - System.currentTimeMillis();
|
||||
DelayTask delayTask = new DelayTask(taskBase, delayTime);
|
||||
|
||||
delayQueueManager.put(delayTask);
|
||||
}
|
||||
|
||||
// ========== 内部数据类 ==========
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.admin.service.TunnelService;
|
||||
import com.admin.service.UserTunnelService;
|
||||
import com.admin.service.ForwardService;
|
||||
import com.admin.service.NodeService;
|
||||
import com.admin.common.task.DelayQueueManager;
|
||||
import com.admin.common.utils.GostUtil;
|
||||
import com.admin.entity.Forward;
|
||||
import com.admin.entity.Tunnel;
|
||||
@@ -61,9 +60,6 @@ public class UserTunnelServiceImpl extends ServiceImpl<UserTunnelMapper, UserTun
|
||||
|
||||
// ========== 依赖注入 ==========
|
||||
|
||||
@Autowired
|
||||
private DelayQueueManager delayQueueManager;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private ForwardService forwardService;
|
||||
@@ -98,15 +94,6 @@ public class UserTunnelServiceImpl extends ServiceImpl<UserTunnelMapper, UserTun
|
||||
boolean success = this.save(userTunnel);
|
||||
|
||||
if (success) {
|
||||
// 3. 如果是启用状态且有到期时间,添加延迟任务
|
||||
if (isEnabledAndHasExpTime(userTunnel)) {
|
||||
try {
|
||||
delayQueueManager.addUserTunnelExpirationTask(userTunnel);
|
||||
} catch (Exception e) {
|
||||
// 延迟任务添加失败不影响主业务逻辑
|
||||
// 可以考虑记录日志或其他处理方式
|
||||
}
|
||||
}
|
||||
return R.ok(SUCCESS_ASSIGN_MSG);
|
||||
}
|
||||
|
||||
@@ -146,13 +133,7 @@ public class UserTunnelServiceImpl extends ServiceImpl<UserTunnelMapper, UserTun
|
||||
} catch (Exception e) {
|
||||
// 转发删除失败,记录日志但不阻止权限删除
|
||||
}
|
||||
|
||||
// 3. 移除延迟任务
|
||||
try {
|
||||
delayQueueManager.removeUserTunnelExpirationTask(id);
|
||||
} catch (Exception e) {
|
||||
// 延迟任务移除失败不影响主业务逻辑
|
||||
}
|
||||
|
||||
|
||||
// 4. 删除用户隧道权限记录
|
||||
boolean success = this.removeById(id);
|
||||
@@ -206,9 +187,6 @@ public class UserTunnelServiceImpl extends ServiceImpl<UserTunnelMapper, UserTun
|
||||
boolean success = this.updateById(existingUserTunnel);
|
||||
|
||||
if (success) {
|
||||
// 5. 处理延迟任务更新
|
||||
handleDelayTaskUpdate(existingUserTunnel, updateDto);
|
||||
|
||||
// 6. 如果限速规则发生变化,更新该用户隧道下的所有转发
|
||||
if (speedChanged) {
|
||||
updateUserTunnelForwardsSpeed(existingUserTunnel.getUserId(), existingUserTunnel.getTunnelId(), updateDto.getSpeedId());
|
||||
@@ -290,29 +268,7 @@ public class UserTunnelServiceImpl extends ServiceImpl<UserTunnelMapper, UserTun
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理延迟任务更新
|
||||
*
|
||||
* @param userTunnel 更新后的用户隧道对象
|
||||
* @param updateDto 更新数据传输对象
|
||||
*/
|
||||
private void handleDelayTaskUpdate(UserTunnel userTunnel, UserTunnelUpdateDto updateDto) {
|
||||
try {
|
||||
// 如果更新了到期时间,需要重新处理延迟任务
|
||||
if (updateDto.getExpTime() != null) {
|
||||
// 先移除旧的延迟任务
|
||||
delayQueueManager.removeUserTunnelExpirationTask(userTunnel.getId());
|
||||
|
||||
// 如果是启用状态且有到期时间,添加新的延迟任务
|
||||
if (isEnabledAndHasExpTime(userTunnel)) {
|
||||
delayQueueManager.addUserTunnelExpirationTask(userTunnel);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 延迟任务处理失败不影响主业务逻辑
|
||||
// 可以考虑记录日志
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除用户在指定隧道下的所有转发
|
||||
|
||||
@@ -1,10 +1,35 @@
|
||||
package com.admin;
|
||||
|
||||
import com.admin.common.dto.GostDto;
|
||||
import com.admin.common.utils.GostUtil;
|
||||
import com.admin.entity.Forward;
|
||||
import com.admin.entity.Tunnel;
|
||||
import com.admin.entity.User;
|
||||
import com.admin.entity.UserTunnel;
|
||||
import com.admin.service.ForwardService;
|
||||
import com.admin.service.TunnelService;
|
||||
import com.admin.service.UserService;
|
||||
import com.admin.service.UserTunnelService;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@SpringBootTest
|
||||
class AdminApplicationTests {
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
VITE_API_BASE=http://192.168.100.8:6365
|
||||
VITE_API_BASE=http://127.0.0.1:6365
|
||||
|
||||
@@ -4,7 +4,7 @@ export type SiteConfig = typeof siteConfig;
|
||||
|
||||
// 缓存相关常量
|
||||
const CACHE_PREFIX = 'vite_config_';
|
||||
const VERSION = "1.2.4";
|
||||
const VERSION = "1.2.5";
|
||||
|
||||
// 缓存策略:
|
||||
// - 长期有效,不设置过期时间
|
||||
|
||||
Reference in New Issue
Block a user