如何对项目进行过载保护
来源:互联网 发布:提高网络安全意识 编辑:程序博客网 时间:2024/05/16 07:08
思路:
1、写一个定时器,定时检测系统的情况,设置一个标识,根据定时器得到的系统当前状态动态改变该标识
2、对于所有接口,可以写一个切面拦截所有请求,在处理请求之前,先判断当前系统是否处于负载状态,如果是,则进行逻辑处理,如果不是,直接放行
1、如何获取进程内存使用率:
public Double getRuntimeMemoryRate() { Double memoryRate = null; try { Runtime run = Runtime.getRuntime(); // 获取到最大内存 Long max = run.maxMemory(); LOGGER.info("maxMemory:" + max); // 获取到总内存 Long total = run.totalMemory(); LOGGER.info("totalMemory:" + total); // 获取到空闲内存 Long free = run.freeMemory(); LOGGER.info("freeMemory:" + free); // 计算得到未使用内存 Long usable = (total - free); // 计算得到未使用内存占比 memoryRate = usable.doubleValue() / max.doubleValue(); LOGGER.info("RuntimeMemoryRate=(totalMemory-freeMemory)/maxMemory=" + memoryRate); } catch (Exception e) { LOGGER.error(e); } return memoryRate; }
2、如何获取系统内存使用率:
public Double getSystemMemoryRate() { Double memoryRate = null; try { Mem mem = sigar.getMem(); Long total = mem.getTotal(); LOGGER.info("getTotal:" + total); Long used = mem.getUsed(); LOGGER.info("getUsed:" + used); Long free = mem.getFree(); LOGGER.info("getFree:" + free); LOGGER.info("mem actualUsed:" + mem.getActualUsed() + " B"); LOGGER.info("mem actualFree:" + mem.getActualFree() + " B"); LOGGER.info("mem usedPercent:" + mem.getUsedPercent() + "%"); LOGGER.info("mem freePercent:" + mem.getFreePercent() + "%"); memoryRate = mem.getUsedPercent(); LOGGER.info("SystemMemoryRate=used/total=" + used.doubleValue() / total.doubleValue()); } catch (Exception e) { LOGGER.error(e); } return memoryRate; }
3、获取CPU使用率:
public Double getCPURate() { Double combined = null; try { CpuPerc perc = sigar.getCpuPerc(); LOGGER.info("getCPURate:======================="); combined = perc.getCombined(); LOGGER.info("getCombined:" + combined); LOGGER.info("getIdle:" + perc.getIdle()); } catch (Exception e) { LOGGER.error(e); } return combined; }
如下:
定时器:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <bean id="sigarCollection" class="com.sowell.portalcore.common.sigar.SigarCollection"> </bean> <!-- 添加调度的任务bean 配置对应的class --> <bean id="myPrintSchedule" class="com.sowell.portalcore.timer.OverLoadCheckTimer"> <property name="sigarCollection" ref="sigarCollection" /> <property name="simpleMail" ref="simpleMail" /> </bean> <task:scheduled-tasks> <task:scheduled ref="myPrintSchedule" method="cheOverLoad" cron="${portalCore.overload.timer}" /> </task:scheduled-tasks></beans>
OverLoadCheckTime
package com.sowell.portalcore.timer;import java.util.Date;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.springframework.beans.BeansException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Service;import com.fasterxml.jackson.core.JsonProcessingException;import com.sowell.portalcore.common.json.JsonUtil;import com.sowell.portalcore.common.sigar.SigarCollection;import com.sowell.portalcore.common.util.CodeMessage;import com.sowell.portalcore.common.util.CommonConsts;import com.sowell.portalcore.common.util.EmailUtils;import com.sowell.portalcore.common.util.StringUtil;import com.sowell.portalcore.model.OverLoadItems;import com.sowell.portalcore.service.IParamConfigService;import com.sowell.portalcore.service.impl.OverloadProtection;@Servicepublic class OverLoadCheckTimer implements ApplicationContextAware{ /** * 日志 */ private final Logger logger = LogManager.getLogger(OverLoadCheckTimer.class); /** * 参数配置处理类 */ @Autowired private IParamConfigService paramConfigService; /** * 上下文对象 */ private ApplicationContext applicationContext; /** * 过载sigar采集对象 */ private SigarCollection sigarCollection; /** * 邮件处理对象 */ private EmailUtils simpleMail; /** * 定时采集任务状态 */ private static final String COLL_TIMER_STATUS = "overLoad_TimerStatus"; /** * 单机模式,避免多次触发手工采集 */ private static boolean isRun; /** * 过载采集间隔时间,用于过载后加快检测的频率 */ private long overLoadCollMilli = CommonConsts.NUMBER_ONE_MINUTE; /** * 触发马上执行 * * @param id * 可配置的访问路径 * @return 成功失败状态 * @see */ public boolean reCollection(String id) { // 对比配置路径是否和实际一致 String code = paramConfigService.getParamConfigVal("overLoad_reCollectionCode"); if (!StringUtil.isEmpty(id) && id.equals(code)) { cheOverLoad(); return true; } return false; } /** * 触发定时任务 * * @see */ public void cheOverLoad() { // 第一次执行时,因为默认是false,不会执行 if (isRun()) { return; } // 设置标识 setRun(true); // 获取定时任务是否开启 String cdmTimer = paramConfigService.getParamConfigVal("overLoad_Timer"); // ############如果定时任务开启############ if (CommonConsts.NUMBER_ZERO_STR.equals(cdmTimer)) { // 获取采集定时任务状态0准备,1运行中,3单机 String cdmCollectionTimer = paramConfigService.getParamConfigVal(COLL_TIMER_STATUS); // 采集状态锁:0准备,1运行中,3单机(单机不用处理该锁机制) if (CommonConsts.NUMBER_ZERO_STR.equals(cdmCollectionTimer) || CommonConsts.NUMBER_THREE_STR.equals(cdmCollectionTimer)) { logger.info("begin Collection Timer :" + new Date()); // 将运行状态修改为运行中 if (CommonConsts.NUMBER_ZERO_STR.equals(cdmCollectionTimer)) { paramConfigService.updateParamConfig(COLL_TIMER_STATUS, CommonConsts.NUMBER_ONE_STR); } // ############获取数据库中定义的界限############ // 进程内存使用率(JAVA监测老年代) String proMemory = paramConfigService.getParamConfigVal("overLoad_proMemory"); // 进程并发请求数 String proConcurrency = paramConfigService.getParamConfigVal( "overLoad_proConcurrency"); // 操作系统内存使用率 String sysMemory = paramConfigService.getParamConfigVal("overLoad_sysMemory"); // 操作系统CPU使用率 String sysCPU = paramConfigService.getParamConfigVal("overLoad_sysCPU"); // 采集次数 String collectionCount = paramConfigService.getParamConfigVal( "overLoad_collectionCount"); // 采集间隔时间 String collectionMilli = paramConfigService.getParamConfigVal( "overLoad_collectionMilli"); // 过载后采集间隔时间 String overLoadCollMilliStr = paramConfigService.getParamConfigVal( "overLoad_olCollectionMilli"); // 批量邮件 String mailForm = paramConfigService.getParamConfigVal("mailForm"); // 批量邮件 String mailTo = paramConfigService.getParamConfigVal("mailTo"); logger.info( "Collection Timer Config Set Info:==================================================="); logger.info("proMemory:" + proMemory); logger.info("proConcurrency:" + proConcurrency); logger.info("sysMemory:" + sysMemory); logger.info("sysCPU:" + sysCPU); logger.info("collectionCount:" + collectionCount); logger.info("collectionMilli:" + collectionMilli); logger.info("overLoadCollMilli:" + overLoadCollMilliStr); logger.info("mailForm:" + mailForm); logger.info("mailTo:" + mailTo); logger.info( "===================================================================="); try { // ############设置过载检查的相关参数############ // 设置邮件发送对象列表 simpleMail.setTo(null != mailTo ? mailTo.split(CommonConsts.COMMA) : null); // 设置邮件发送者 simpleMail.setFrom(mailForm); // 采集次数,默认5次 int cCount = null != collectionCount ? Integer.parseInt( collectionCount) : CommonConsts.NUMBER_FIVE; // 每次间隔多久默认 5秒 int cMilli = null != collectionMilli ? Integer.parseInt( collectionMilli) : CommonConsts.NUMBER_FIVE_Q; overLoadCollMilli = null != overLoadCollMilliStr ? Long.parseLong( overLoadCollMilliStr) : CommonConsts.NUMBER_ONE_MINUTE; // 进程内存使用率(JAVA监测老年代)范围 String[] proMemoryBetw = null != proMemory ? proMemory.split( CommonConsts.COMMA) : null; // 进程并发请求数 String[] proConcurrencyBetw = null != proConcurrency ? proConcurrency.split( CommonConsts.COMMA) : null; // 操作系统内存使用率 String[] sysMemoryBetw = null != sysMemory ? sysMemory.split( CommonConsts.COMMA) : null; // 操作系统CPU使用率 String[] sysCPUBetw = null != sysCPU ? sysCPU.split(CommonConsts.COMMA) : null; // 启动过载检测 startCheckOverLoad(proMemoryBetw, proConcurrencyBetw, sysMemoryBetw, sysCPUBetw, cCount, cMilli); } catch (Exception e) { resetLoad(); logger.error("collection Exception:" + e); } finally { logger.info("end Collenction Timer:" + new Date()); // 采集完成重置标识 setRun(false); if (CommonConsts.NUMBER_ZERO_STR.equals(cdmCollectionTimer)) { paramConfigService.updateParamConfig(COLL_TIMER_STATUS, CommonConsts.NUMBER_ZERO_STR); } } } else { logger.info("Timer Task Excuteing...... :" + cdmCollectionTimer); } } // ############定时任务未开启,提示相关信息############ else { resetLoad(); logger.info("Timer No Open:" + cdmTimer); } // 采集完成重置标识 setRun(false); } /** * 采集对比处理 * * @param proMemory * 进程内存阀值 * @param proConcurrency * 并发送阀值 * @param sysMemory * 系统内存阀值 * @param sysCPU * 系统cpu阀值 * @param cCount * 采集次数 * @param cMilli * 间隔时间 * @see */ private void startCheckOverLoad(String[] proMemory, String[] proConcurrency, String[] sysMemory, String[] sysCPU, int cCount, int cMilli) { // 采集指标数据 OverLoadItems overLoadItems = getCollectionData(cCount, cMilli); // 对比指标数据 if (!StringUtil.isArrayEmpty(proMemory, CommonConsts.NUMBER_TWO)) { // ############如果达到过载预警############ if (overLaodCompare(proMemory[CommonConsts.NUMBER_ZERO], proConcurrency[CommonConsts.NUMBER_ZERO], sysMemory[CommonConsts.NUMBER_ZERO], sysCPU[CommonConsts.NUMBER_ZERO], overLoadItems)) { // 组装指标值 StringBuilder sb = new StringBuilder("Threshold value:{"); sb.append("proMemory:").append(proMemory[CommonConsts.NUMBER_ZERO]).append( ",").append(proMemory[CommonConsts.NUMBER_ONE]).append( ",proConcurrency:").append( proConcurrency[CommonConsts.NUMBER_ZERO]).append(",").append( proConcurrency[CommonConsts.NUMBER_ONE]).append( ",sysMemory:").append( sysMemory[CommonConsts.NUMBER_ZERO]).append(",").append( sysMemory[CommonConsts.NUMBER_ONE]).append( ",sysCPU:").append( sysCPU[CommonConsts.NUMBER_ZERO]).append( ",").append( sysCPU[CommonConsts.NUMBER_ONE]).append( "}\t\n").append("Actual value:"); // 发送告警邮件和记录日志 try { sb.append(JsonUtil.writeObject2JSON(overLoadItems)); } catch (JsonProcessingException e) { logger.error(e); } // ############再判断是否已经达到流控预警############ if (overLaodCompare(proMemory[CommonConsts.NUMBER_ONE], proConcurrency[CommonConsts.NUMBER_ONE], sysMemory[CommonConsts.NUMBER_ONE], sysCPU[CommonConsts.NUMBER_ONE], overLoadItems)) { // 设置过载标识 OverloadProtection.setOverLoad(true); logger.error(sb.toString()); simpleMail.sendMail(CodeMessage.OVERLOAD_EMALL_TITEL_FLOW, sb.toString()); try { // 如果已过载,就每隔1分钟(默认)检测一次 Thread.sleep(overLoadCollMilli); } catch (Exception e) { logger.error(e); } // 马上启动过载密集检测 startCheckOverLoad(proMemory, proConcurrency, sysMemory, sysCPU, cCount, cMilli); } else { // 如果没有过载,修改标识 OverloadProtection.setOverLoad(false); logger.warn(sb.toString()); simpleMail.sendMail(CodeMessage.OVERLOAD_EMALL_TITEL, sb.toString()); } } else { // 如果没有过载,修改标识 OverloadProtection.setOverLoad(false); } } else { // 如果没有过载,修改标识 OverloadProtection.setOverLoad(false); } } /** * 过载判断 * * @param proMemory * 进程内存阀值 * @param proConcurrency * 并发送阀值 * @param sysMemory * 系统内存阀值 * @param sysCPU * 系统cpu阀值 * @param overLoadItems * 实际数据 * @return 返回对比结果 * @see */ private boolean overLaodCompare(String proMemory, String proConcurrency, String sysMemory, String sysCPU, OverLoadItems overLoadItems) { // 对比进程内存 if (StringUtil.compareDouble(Double.parseDouble(proMemory), overLoadItems.getProMemory())) { return true; } // 对比并数 else if (StringUtil.compareDouble(Double.parseDouble(proConcurrency), overLoadItems.getProConcurrency())) { return true; } // 对比系统内存 // else if (StringUtil.compareDouble(Double.parseDouble(sysMemory), // overLoadItems.getSysMemory())) // { // return true; // } // 对比系统CPU else if (StringUtil.compareDouble(Double.parseDouble(sysCPU), overLoadItems.getSysCPU())) { return true; } // 如果所有指标都正常,返回没有负载 else { return false; } } /** * 获取采集的指标数据 * * @param cCount * 采集次数 * @param cMilli * 每次间隔毫秒 * @return 采集结果 * @throws Exception * 异常 * @see */ private OverLoadItems getCollectionData(int cCount, long cMilli) { OverLoadItems olItems = new OverLoadItems(); double runtimeMemoryRate = 0L; double systemMemoryRate = 0L; double cpuRate = 0L; int proConcurrency = 0; for (int i = 0; i < cCount; i++ ) { // 进程内存使用率 runtimeMemoryRate += sigarCollection.getRuntimeMemoryRate(); // 系统内存使用率 systemMemoryRate += sigarCollection.getSystemMemoryRate(); // 系统CPU使用率 cpuRate += sigarCollection.getCPURate(); // 当前并发数 proConcurrency += OverloadProtection.getProConcurrency().get(); try { // 间隔多久再采集 Thread.sleep(cMilli); } catch (Exception e) { logger.error(e); } } // 进程内存使用率 olItems.setProMemory(runtimeMemoryRate / cCount); // 系统内存使用率 olItems.setSysMemory(systemMemoryRate / cCount); // 系统COU使用率 olItems.setSysCPU(cpuRate / cCount); // 当前并发数 olItems.setProConcurrency(proConcurrency / cCount); return olItems; } /** * 获取当前bean * * @param name * bean名称 * @return 对象实例 * @see */ public Object getBean(String name) { return applicationContext.getBean(name); } // 重置过载 private void resetLoad() { if (OverloadProtection.isOverLoad()) { OverloadProtection.setOverLoad(false); } } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public SigarCollection getSigarCollection() { return sigarCollection; } public void setSigarCollection(SigarCollection sigarCollection) { this.sigarCollection = sigarCollection; } public EmailUtils getSimpleMail() { return simpleMail; } public void setSimpleMail(EmailUtils simpleMail) { this.simpleMail = simpleMail; } public static boolean isRun() { return isRun; } public static void setRun(boolean isRun) { OverLoadCheckTimer.isRun = isRun; }}
SigarCollection:
package com.sowell.portalcore.common.sigar;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.hyperic.sigar.CpuPerc;import org.hyperic.sigar.Mem;import org.hyperic.sigar.Sigar;import com.sowell.portalcore.common.util.OsCheck;public class SigarCollection{ /** * 日志 */ private static final Logger LOGGER = LogManager.getLogger(Sigar.class); /** * 初始化sigar对象 */ private final Sigar sigar = initSigar(); /** * 获取当前进程内存使用率 * * @return 返回未做百分比处理的值 * @throws Exception * @see */ public Double getRuntimeMemoryRate() { Double memoryRate = null; try { Runtime run = Runtime.getRuntime(); Long max = run.maxMemory(); LOGGER.info("getRuntimeMemory:======================="); LOGGER.info("maxMemory:" + max); Long total = run.totalMemory(); LOGGER.info("totalMemory:" + total); Long free = run.freeMemory(); LOGGER.info("freeMemory:" + free); Long usable = (total - free); memoryRate = usable.doubleValue() / max.doubleValue(); LOGGER.info("RuntimeMemoryRate=(totalMemory-freeMemory)/maxMemory=" + memoryRate); } catch (Exception e) { LOGGER.error(e); } return memoryRate; } /** * 获取系统内存 * * @return 返回未做百分比处理的值 * @throws Exception * @see */ public Double getSystemMemoryRate() { Double memoryRate = null; try { Mem mem = sigar.getMem(); LOGGER.info("getSystemMemory:======================="); Long total = mem.getTotal(); LOGGER.info("getTotal:" + total); Long used = mem.getUsed(); LOGGER.info("getUsed:" + used); Long free = mem.getFree(); LOGGER.info("getFree:" + free); LOGGER.info("mem actualUsed:" + mem.getActualUsed() + " B"); LOGGER.info("mem actualFree:" + mem.getActualFree() + " B"); LOGGER.info("mem usedPercent:" + mem.getUsedPercent() + "%"); LOGGER.info("mem freePercent:" + mem.getFreePercent() + "%"); memoryRate = mem.getUsedPercent(); LOGGER.info("SystemMemoryRate=used/total=" + used.doubleValue() / total.doubleValue()); } catch (Exception e) { LOGGER.error(e); } return memoryRate; } /** * 获取CPU使用率 * * @return 返回未做百分比处理的值 * @throws Exception * @see */ public Double getCPURate() { Double combined = null; try { CpuPerc perc = sigar.getCpuPerc(); LOGGER.info("getCPURate:======================="); combined = perc.getCombined(); LOGGER.info("getCombined:" + combined); LOGGER.info("getIdle:" + perc.getIdle()); } catch (Exception e) { LOGGER.error(e); } return combined; } /** * 初始化sigar对象 * * @return 返回对象 * @see */ private Sigar initSigar() { try { // 在java.library.path环境中添加配置所需配置文件所在目录 String path = System.getProperty("java.library.path"); String pathFile = Sigar.class.getClassLoader().getResource("").getPath(); // windows和linux在环境变量中有分号和引号的区别 if (OsCheck.getOperatingSystemType() == OsCheck.OSType.Windows) { path += ";" + pathFile; } else { path += ":" + pathFile; } // 添加一层sigarUML,然后再追加到环境变量中去 path += "/sigar"; System.setProperty("java.library.path", path); return new Sigar(); } catch (Exception e) { LOGGER.error(e); } return null; }}
阅读全文
0 0
- 如何对项目进行过载保护
- 如何对颈椎进行保护.
- 过载保护
- 过载保护
- 过载保护
- 过载保护
- 浅谈过载保护
- 浅谈过载保护
- 浅谈过载保护
- 浅谈过载保护
- 浅谈过载保护
- 浅谈过载保护
- 浅谈过载保护
- 浅谈过载保护
- 浅谈过载保护
- 浅谈过载保护
- 服务器过载保护
- 浅谈过载保护
- 第三只眼企业计算机监控管理系统v7.3.0已注册破解版
- Ehcache配置详解及CacheManager使用
- iOS
- 解决axios在ie下的兼容性问题
- sql优化,数据库优化
- 如何对项目进行过载保护
- 客户端通过二维码扫码登陆web
- echarts 饼图实例
- 爬虫抓取的几个常见小问题
- OpenCV在移动端集成时注意的问题
- checkbox全选后刷新成全不选问题和阻止冒泡事件
- MySQL——修改root密码的4种方法(以windows为例)
- 使用国内源部署Ceph
- 使用python实现简单的加密解密机制