feat(all): killSession支持pacs、lis

pull/544/head
dazer007 2025-03-12 11:06:28 +08:00
parent 9027055e7d
commit 04471c237b
5 changed files with 209 additions and 64 deletions

View File

@ -3,7 +3,9 @@ package com.neuhis.his.service;
import com.neuhis.his.domain.dto.DeadLock;
import com.neuhis.his.domain.dto.DeadLockRac;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public interface IOracleSysService {
@ -23,4 +25,55 @@ public interface IOracleSysService {
*
*/
void killSession(String sessionStr);
//进程列表本进程号SID、阻塞id 三列
//1、“阻塞id”有四种情况先找“的SQL阻塞了本语句”的取得“【SID=”的取值
//2、找到“本进程号SID” = “【SID=”的一行如果本行“阻塞id”是 情况3结束否则继续递归。
class DeadlockResolver {
public static final String BLOCK_FIND_TXT = "的SQL阻塞了本语句";
public static final String BLOCK_ROOT_TXT = "根锁为此会话杀我KILL ME or igore";
public static DeadLockRac findProblematicSession(List<DeadLockRac> deadlockList) {
Map<Integer, DeadLockRac> sidMap = new HashMap<>();
// First pass: build a map for quick lookup by SID
for (DeadLockRac deadlock : deadlockList) {
sidMap.put(deadlock.getSID(), deadlock);
}
// Second pass: look for entries that match the criteria
for (DeadLockRac deadlock : deadlockList) {
if (deadlock.getSID().contains(BLOCK_FIND_TXT)) {
// Extract the blocking SID
int blockingSID = extractBlockingSID(deadlock.getSID());
DeadLockRac blockingSession = sidMap.get(blockingSID);
// Check if the blocking session's 阻塞SID is of case 3
while (blockingSession != null && !isRootBlock(blockingSession.getSID())) {
// If not case 3, recursively check the blocker of this session
String sqlText = blockingSession.getSID();
if (sqlText.contains(BLOCK_FIND_TXT)) {
blockingSID = extractBlockingSID(sqlText);
blockingSession = sidMap.get(blockingSID);
} else {
break; // Exit loop if it doesn't match case 4 anymore
}
}
if (blockingSession != null && isRootBlock(blockingSession.getSID())) {
return blockingSession; // Found problematic session
}
}
}
return null; // No problematic session found
}
private static boolean isRootBlock(String sqlText) {
return sqlText.contains(BLOCK_ROOT_TXT);
}
private static int extractBlockingSID(String sqlText) {
// Assuming format is like "...【SID=4903】..."
String sidStr = sqlText.substring(sqlText.indexOf("【SID=") + 5, sqlText.indexOf("】"));
return Integer.parseInt(sidStr.trim());
}
}
}

View File

@ -22,7 +22,7 @@ import java.util.List;
import java.util.Map;
@Slf4j
@Service
@Service(value = "oracleSysService_his")
@DataSource(value = DataSourceType.SLAVE)
public class OracleSysServiceImpl implements IOracleSysService {
@Resource
@ -70,55 +70,4 @@ public class OracleSysServiceImpl implements IOracleSysService {
}
return Lists.newArrayList();
}
//进程列表本进程号SID、阻塞id 三列
//1、“阻塞id”有四种情况先找“的SQL阻塞了本语句”的取得“【SID=”的取值
//2、找到“本进程号SID” = “【SID=”的一行如果本行“阻塞id”是 情况3结束否则继续递归。
private static class DeadlockResolver {
public static final String BLOCK_FIND_TXT = "的SQL阻塞了本语句";
public static final String BLOCK_ROOT_TXT = "根锁为此会话杀我KILL ME or igore";
public static DeadLockRac findProblematicSession(List<DeadLockRac> deadlockList) {
Map<Integer, DeadLockRac> sidMap = new HashMap<>();
// First pass: build a map for quick lookup by SID
for (DeadLockRac deadlock : deadlockList) {
sidMap.put(deadlock.getSID(), deadlock);
}
// Second pass: look for entries that match the criteria
for (DeadLockRac deadlock : deadlockList) {
if (deadlock.getSID().contains(BLOCK_FIND_TXT)) {
// Extract the blocking SID
int blockingSID = extractBlockingSID(deadlock.getSID());
DeadLockRac blockingSession = sidMap.get(blockingSID);
// Check if the blocking session's 阻塞SID is of case 3
while (blockingSession != null && !isRootBlock(blockingSession.getSID())) {
// If not case 3, recursively check the blocker of this session
String sqlText = blockingSession.getSID();
if (sqlText.contains(BLOCK_FIND_TXT)) {
blockingSID = extractBlockingSID(sqlText);
blockingSession = sidMap.get(blockingSID);
} else {
break; // Exit loop if it doesn't match case 4 anymore
}
}
if (blockingSession != null && isRootBlock(blockingSession.getSID())) {
return blockingSession; // Found problematic session
}
}
}
return null; // No problematic session found
}
private static boolean isRootBlock(String sqlText) {
return sqlText.contains(BLOCK_ROOT_TXT);
}
private static int extractBlockingSID(String sqlText) {
// Assuming format is like "...【SID=4903】..."
String sidStr = sqlText.substring(sqlText.indexOf("【SID=") + 5, sqlText.indexOf("】"));
return Integer.parseInt(sidStr.trim());
}
}
}

View File

@ -0,0 +1,69 @@
package com.neuhis.his.service.impl;
import cn.hutool.core.collection.ListUtil;
import com.neuhis.his.domain.dto.DeadLock;
import com.neuhis.his.domain.dto.DeadLockRac;
import com.neuhis.his.mapper.OracleSysMapper;
import com.neuhis.his.service.IOracleSysService;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Slf4j
@Service(value = "oracleSysService_pacs")
@DataSource(value = DataSourceType.PACS)
public class OracleSysServicePacsImpl implements IOracleSysService {
@Resource
private OracleSysMapper oracleSysMapper;
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<DeadLock> getDeadLockSessionV1() {
return oracleSysMapper.getDeadLockSessionV1();
}
@Override
public List<DeadLockRac> getDeadLockSessionV2Rac() {
List<DeadLockRac> deadLockRacs = oracleSysMapper.getDeadLockSessionV2Rac();
/*deadLockRacs.add(new DeadLockRac(1, "根锁为此会话杀我KILL ME or igore", "001"));
deadLockRacs.add(new DeadLockRac(5728, "<根锁会话>4903 【SID=4903】的SQL阻塞了本语句[5728]杀掉他", "5728"));
deadLockRacs.add(new DeadLockRac(2222, "<根锁会话>1111 【SID=1111】的SQL阻塞了本语句[2222]杀掉他", "5728"));
deadLockRacs.add(new DeadLockRac(3333, "<根锁会话>1 【SID=1】的SQL阻塞了本语句[3333]杀掉他", "5728"));*/
return this.findV2DeadLockRacSessionId(deadLockRacs);
}
@Override
public List<DeadLock> getDeadLockSessionV3Slow() {
return oracleSysMapper.getDeadLockSessionV3Slow();
}
@Override
public void killSession(String sessionStr) {
try {
if (StringUtils.isNotEmpty(sessionStr)) {
log.info("查杀进程id:" + sessionStr);
oracleSysMapper.killSession(sessionStr);
}
}catch (Exception e){
log.error("数据库杀死锁异常:"+e.getMessage());
}
}
private List<DeadLockRac> findV2DeadLockRacSessionId(List<DeadLockRac> deadLockRacs) {
//找到有问题的进程
DeadLockRac problematicSession = DeadlockResolver.findProblematicSession(deadLockRacs);
if (problematicSession != null) {
return ListUtil.of(problematicSession);
}
return Lists.newArrayList();
}
}

View File

@ -0,0 +1,69 @@
package com.neuhis.his.service.impl;
import cn.hutool.core.collection.ListUtil;
import com.neuhis.his.domain.dto.DeadLock;
import com.neuhis.his.domain.dto.DeadLockRac;
import com.neuhis.his.mapper.OracleSysMapper;
import com.neuhis.his.service.IOracleSysService;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Slf4j
@Service(value = "oracleSysService_winlis")
@DataSource(value = DataSourceType.WINLIS)
public class OracleSysServiceWinlisImpl implements IOracleSysService {
@Resource
private OracleSysMapper oracleSysMapper;
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<DeadLock> getDeadLockSessionV1() {
return oracleSysMapper.getDeadLockSessionV1();
}
@Override
public List<DeadLockRac> getDeadLockSessionV2Rac() {
List<DeadLockRac> deadLockRacs = oracleSysMapper.getDeadLockSessionV2Rac();
/*deadLockRacs.add(new DeadLockRac(1, "根锁为此会话杀我KILL ME or igore", "001"));
deadLockRacs.add(new DeadLockRac(5728, "<根锁会话>4903 【SID=4903】的SQL阻塞了本语句[5728]杀掉他", "5728"));
deadLockRacs.add(new DeadLockRac(2222, "<根锁会话>1111 【SID=1111】的SQL阻塞了本语句[2222]杀掉他", "5728"));
deadLockRacs.add(new DeadLockRac(3333, "<根锁会话>1 【SID=1】的SQL阻塞了本语句[3333]杀掉他", "5728"));*/
return this.findV2DeadLockRacSessionId(deadLockRacs);
}
@Override
public List<DeadLock> getDeadLockSessionV3Slow() {
return oracleSysMapper.getDeadLockSessionV3Slow();
}
@Override
public void killSession(String sessionStr) {
try {
if (StringUtils.isNotEmpty(sessionStr)) {
log.info("查杀进程id:" + sessionStr);
oracleSysMapper.killSession(sessionStr);
}
}catch (Exception e){
log.error("数据库杀死锁异常:"+e.getMessage());
}
}
private List<DeadLockRac> findV2DeadLockRacSessionId(List<DeadLockRac> deadLockRacs) {
//找到有问题的进程
DeadLockRac problematicSession = DeadlockResolver.findProblematicSession(deadLockRacs);
if (problematicSession != null) {
return ListUtil.of(problematicSession);
}
return Lists.newArrayList();
}
}

View File

@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
@ -28,8 +29,12 @@ public class HisTask {
JobService jobService;
@Autowired
OracleSlaveDataAutoPushService oracleSlaveDataAutoPushService;
@Autowired
@Resource(name = "oracleSysService_his")
private IOracleSysService oracleSysService;
@Resource(name = "oracleSysService_winlis")
private IOracleSysService oracleSysWinlisService;
@Resource(name = "oracleSysService_pacs")
private IOracleSysService oracleSysPacsService;
@Autowired
private RuoYiConfig ruoYiConfig;
@Autowired
@ -66,11 +71,20 @@ public class HisTask {
if (ruoYiConfig.isQuzrtzTask()) {
log.info("杀oracle死锁开始" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
///List<DeadLock> deadLocks = oracleSysService.getDeadLockSessionV1();
///deadLocks.forEach(deadLock -> HisTask.this.oracleSysService.killSessionJdbc(deadLock.getSessionStr()));
//deadLocks.forEach(deadLock -> HisTask.this.oracleSysService.killSession(deadLock.getSessionStr()));
List<DeadLockRac> sessionV2Rac = oracleSysService.getDeadLockSessionV2Rac();
sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysService.killSession(deadLock.getSessionStr()));
log.info("杀oracle死锁结束被杀进程数量" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
log.info("杀lis oracle死锁结束被杀进程数量" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
sessionV2Rac = oracleSysWinlisService.getDeadLockSessionV2Rac();
sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysWinlisService.killSession(deadLock.getSessionStr()));
log.info("杀winlis oracle死锁结束被杀进程数量" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
sessionV2Rac = oracleSysPacsService.getDeadLockSessionV2Rac();
sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysPacsService.killSession(deadLock.getSessionStr()));
log.info("杀pacs oracle死锁结束被杀进程数量" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
}
}
@ -85,13 +99,4 @@ public class HisTask {
log.info("日志数据删除结束,共删除 "+num+" 条日志。" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
}
}
public void winlisCaTask(String testdateLike, Integer limit)
{
if (ruoYiConfig.isQuzrtzTask()) {
log.info("winlisCA数据推送开始" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
winLisService.winlistCaTask(testdateLike,limit);
log.info("winlisCA数据推送结束" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
}
}
}