diff --git a/main/manager-api/src/main/java/xiaozhi/common/config/AsyncConfig.java b/main/manager-api/src/main/java/xiaozhi/common/config/AsyncConfig.java new file mode 100644 index 00000000..d0cc2dfc --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/common/config/AsyncConfig.java @@ -0,0 +1,40 @@ +package xiaozhi.common.config; + +import java.util.concurrent.Executor; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadPoolExecutor; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +@Configuration +@EnableAsync +@EnableAspectJAutoProxy(exposeProxy = true) +public class AsyncConfig { + + @Bean(name = "taskExecutor") + public Executor taskExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(2); + executor.setMaxPoolSize(4); + executor.setQueueCapacity(1000); + executor.setThreadNamePrefix("AsyncThread-"); + // 设置拒绝策略:由调用线程执行 + executor.setRejectedExecutionHandler(new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + try { + // 如果线程池已满,则由调用线程执行 + r.run(); + } catch (Exception e) { + throw new RuntimeException("执行异步任务失败", e); + } + } + }); + executor.initialize(); + return executor; + } +} \ No newline at end of file diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java index 19ab7178..10546d76 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java @@ -9,6 +9,8 @@ import java.util.TimeZone; import java.util.UUID; import org.apache.commons.lang3.StringUtils; +import org.springframework.aop.framework.AopContext; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; @@ -54,6 +56,24 @@ public class DeviceServiceImpl extends BaseServiceImpl private final RedisUtils redisUtils; private final OtaService otaService; + @Async + public void updateDeviceConnectionInfo(String agentId, String deviceId, String appVersion) { + try { + DeviceEntity device = new DeviceEntity(); + device.setId(deviceId); + device.setLastConnectedAt(new Date()); + if (StringUtils.isNotBlank(appVersion)) { + device.setAppVersion(appVersion); + } + deviceDao.updateById(device); + if (StringUtils.isNotBlank(agentId)) { + redisUtils.set(RedisKeys.getAgentDeviceLastConnectedAtById(agentId), new Date()); + } + } catch (Exception e) { + log.error("异步更新设备连接信息失败", e); + } + } + @Override public Boolean deviceActivation(String agentId, String activationCode) { if (StringUtils.isBlank(activationCode)) { @@ -150,13 +170,12 @@ public class DeviceServiceImpl extends BaseServiceImpl response.setWebsocket(websocket); if (deviceById != null) { - // 如果设备存在,则更新上次连接时间 - deviceById.setLastConnectedAt(new Date()); - if (deviceReport.getApplication() != null - && StringUtils.isNotBlank(deviceReport.getApplication().getVersion())) { - deviceById.setAppVersion(deviceReport.getApplication().getVersion()); - } - deviceDao.updateById(deviceById); + // 如果设备存在,则异步更新上次连接时间和版本信息 + String appVersion = deviceReport.getApplication() != null ? deviceReport.getApplication().getVersion() + : null; + // 通过Spring代理调用异步方法 + ((DeviceServiceImpl) AopContext.currentProxy()).updateDeviceConnectionInfo(deviceById.getAgentId(), + deviceById.getId(), appVersion); } else { // 如果设备不存在,则生成激活码 DeviceReportRespDTO.Activation code = buildActivation(macAddress, deviceReport);