高并发下的大数据处理——多线程数据分析实例

之前项目中遇到的问题:需要对单日告警量超过四百万条的数据进行逐条分析和逻辑处理,导致靠单一进程跑数据根本跑不完,无法满足系统和业务要求,因此决定采用开多线程方式实现大数据处理。
数据处理流程:
1、申明一个内存队列
2、从库中轮巡取数据放入内存队列
3、开多个线程逐条取内存队列中的数据,分析后在库中对该条数据打上标识,下次不取了。

main方法程序入口

/**
 * 
 */
package cn.com.starit.main;

import org.apache.log4j.Logger;

import cn.com.starit.ge.persistence.cache.AllCacheRefresh;

/**
 * ================================================= 
* 工程:GessAlarmAnalysis
* 类名:Main
* 作者:xt
* 时间:2019-10-08上午02:31:17
* 版本:Version 1.0

* 描述:告警解析入口
* =================================================
*/ public class Main { private static final Logger logger = Logger.getLogger(Main.class); private static Main instance = null; private Main(){} /** * 系统入口 * @param args */ public static void main(String[] args) { logger.info("进程当前内存占用量(兆):" + (int)(Runtime.getRuntime().totalMemory()/(1048576))); Main.getInstance().sysInit(); logger.info("系统初始化完毕:进程当前内存占用量(兆):" + (int)(Runtime.getRuntime().totalMemory()/(1048576))); logger.info("进程最大内存:" + (int)(Runtime.getRuntime().maxMemory()/(1048576))); //从库中取出活动告警存入内存队列 new LoadGesBsmThread().start(); //告警解析进程 new alarmAnalysis(10).start(); } /** * 系统初始化 */ public void sysInit() { // 加载静态数据 AllCacheRefresh.refreshAll(); } /** * @return the instance */ public static Main getInstance() { if(null == instance) instance = new Main(); return instance; } }

创建内存队列实例及方法

package cn.com.starit.ge.persistence.utils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.apache.log4j.Logger;

import cn.com.starit.ge.etec.model.GesAlarm;
import cn.com.starit.ge.gzpt.dto.GesAlarmDto;

/**
 * ================================================= 
* 工程:GessServiceEOMSServer
* 类名:SafeWorkContainer
* 时间:2014-9-15下午11:23:46
* 版本:Version 1.0

* 描述:TODO 描述该文件的作用
* =================================================
*/ public class SafeWorkContainer { private static final Logger logger = Logger.getLogger(SafeWorkContainer.class); private static SafeWorkContainer instance; SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** * @return the instance */ public synchronized static SafeWorkContainer getInstance() { if(null == instance) instance = new SafeWorkContainer(); return instance; } /** 告警队列 */ private ConcurrentLinkedQueue safeWorkQueue; private SafeWorkContainer(){ safeWorkQueue = new ConcurrentLinkedQueue(); } /** * 将GsmAlarm告警数据保存到内存队列 * @param safeWork */ public synchronized void putSafeWork(GesAlarmDto safeWork) { // 对象为null直接返回,ConcurrentLinkedQueue队列不允许添加null元素 if(null == safeWork) return; safeWorkQueue.offer(safeWork); logger.info("添加一条GesAlarm告警到内存队列成功"); notifyAll(); } /** * 将GsmAlarm告警数据保存到内存队列 * @param safeWork */ public synchronized void putSafeWork(List safeWorkList) { // 对象为null直接返回,ConcurrentLinkedQueue队列不允许添加null元素 if(null == safeWorkList) return; safeWorkQueue.addAll(safeWorkList); // for(GesAlarm alarm:safeWorkList){ // safeWorkQueue.offer(alarm); // } logger.info(String.format("添加%d条GesAlarm告警到内存队列成功",safeWorkList.size())); notifyAll(); } /** * 获取GsmAlarm告警数据 * @return GesAlarm * @throws InterruptedException */ public synchronized GesAlarmDto getSafeWork() throws InterruptedException { GesAlarmDto safeWork; if(safeWorkQueue.isEmpty()) { logger.info("SafeWorkContainer 队列中没有GsmAlarm告警数据,本线程挂起"); wait(); } safeWork = safeWorkQueue.poll(); //logger.info("取到一条重保工单信息,mainSn=" + safeWork); return safeWork; } /** * 获取GsmAlarm告警数据 * @return GesAlarm * @throws InterruptedException */ public synchronized List getSafeWork(int cnt){ try{ if(safeWorkQueue.isEmpty()) { logger.info("SafeWorkContainer 队列中没有GsmAlarm告警数据,本线程挂起 "); wait(); } List safeWorkList = new LinkedList(); for(int i=0;i(); } /** * @return 返回容器中信息数 */ public synchronized int size() { return safeWorkQueue.size(); } }

LoadGesBsmThread线程继承线程池

package cn.com.starit.main;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import cn.com.starit.ge.etec.model.GesAlarm;
import cn.com.starit.ge.gzpt.dto.GesAlarmDto;
import cn.com.starit.ge.persistence.dao.ServiceProvider;
import cn.com.starit.ge.persistence.utils.SafeWorkContainer;
import cn.com.starit.ge.persistence.utils.Static;

public class LoadGesBsmThread extends Thread {
    private static final Logger logger = Logger.getLogger(LoadGesBsmThread.class);
    private int flag = 1;
    private long maxId = 0L;

    public void run(){
        Long maxId = 0L;
        while(true){
            try{
                int queueSize = SafeWorkContainer.getInstance().size();
                logger.info("GesAlarm缓存队列告警数:"+queueSize);
                if(queueSize>1000){
                    Thread.sleep(1000);
                }
                if(maxId == 0L){
                    if(queueSize==0){
                        maxId = loadGesAlarm(maxId);
                        logger.info("reset maxId=0");
                    }else{
                        Thread.sleep(1000);
                    }
                }else {
                    Long maxIdTemp = loadGesAlarm(maxId);
                    if(maxIdTemp.longValue()!=0){
                        if(maxIdTemp-maxId<100){
                            loadGesAlarm(maxIdTemp);
                            maxId=0L;
                        }else
                            maxId = maxIdTemp;
                    }
                }
                try{
                    Thread.sleep(500*flag);
                }catch(Exception e){
                    logger.error("Thread.sleep异常:"+e.getMessage());
                }
            }catch(Exception e){
                logger.error("LoadGesActiveThread异常:"+e.getMessage());
            }
        }
    }
    private Long loadGesAlarm(Long maxAlarmId){
        List list = ServiceProvider.getGesAlarmDao().getGesAlarm(maxAlarmId);
        Long maxId = 0L;
        for(GesAlarmDto alarm:list){
            if(alarm.getAlarmid().longValue()>maxId.longValue()){
                maxId = alarm.getAlarmid();
            }
        }
        SafeWorkContainer.getInstance().putSafeWork(list);
        logger.info(String.format("load %d GesAlarm到队列",list.size()));
        if(list.size()<10){
            flag = 4;
        }else if(list.size()<50){
            flag = 3;
        }else if(list.size()<100){
            flag=2;
        }else{
            flag = 1;
        }
        return maxId;
    }
}

将内存队列中的数据取出,多线程方式逐条解析成告警对象

package cn.com.starit.main;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.BeanUtils;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;

import cn.com.starit.ge.etec.model.AzGesBsmAlarm;
import cn.com.starit.ge.etec.model.GesAlarm;
import cn.com.starit.ge.etec.model.GesAlarmClearCache;
import cn.com.starit.ge.etec.model.GesAlarmHis;
import cn.com.starit.ge.etec.model.GesBsmAlarm;
import cn.com.starit.ge.etec.model.GesBsmAlarmCirRel;
import cn.com.starit.ge.etec.model.GesBsmAlarmCirRelId;
import cn.com.starit.ge.etec.model.GesBsmAlarmClear;
import cn.com.starit.ge.etec.model.GesBsmAlarmHis;
import cn.com.starit.ge.etec.model.GesMonitorConfig2;
import cn.com.starit.ge.etec.model.ShortmessageInfo;
import cn.com.starit.ge.gzpt.dto.GesAlarmDto;
import cn.com.starit.ge.persistence.busi.AffectCustAnalysis;
import cn.com.starit.ge.persistence.cache.GesAlarmStrategyTypeDefCache;
import cn.com.starit.ge.persistence.dao.ServiceProvider;
import cn.com.starit.ge.persistence.dto.AffectCustDto;
import cn.com.starit.ge.persistence.dto.AlarmLevelDto;
import cn.com.starit.ge.persistence.dto.CustCircuitDto;
import cn.com.starit.ge.persistence.dto.DZWYDto;
import cn.com.starit.ge.persistence.utils.AlarmObjConvert;
import cn.com.starit.ge.persistence.utils.PropertiesLoadUtil;
import cn.com.starit.ge.persistence.utils.SafeWorkContainer;
import cn.com.starit.ge.persistence.utils.Static;

import cn.com.starit.ge.gzpt.service.WarRoomService;
/**
 * ================================================= 
* 工程:GessAlarmAnalysis
* 类名:alarmAnalysis
* 时间:2019-8-12下午01:13:10
* 版本:Version 1.0

* 描述:告警解析进程,将原始告警解析成我们系统内部的告警对象
* =================================================
*/ public class alarmAnalysis{ private static accessAndKeepOrder accessAndKeepOrder; private static WarRoomService warRoomService; private static final Logger logger = Logger.getLogger(alarmAnalysis.class); private List threadList = new ArrayList(); public alarmAnalysis(int n){ for(int i=0;i0){ for(AnalysisThread at:threadList){ at.start(); } } } class AnalysisThread extends Thread{ public AnalysisThread(String name) { super(name); } public void run(){ logger.info("告警解析线程"+this.getName()+"启动....."); while(true){ List list = SafeWorkContainer.getInstance().getSafeWork(50); logger.info(String.format("取%dGesAlarmDto告警处理", list.size())); if(null != list && list.size() > 0) { for(int i=0;i analyticalPostition(String alarmLocate,long alarmProftype){ String rack=null, shelf=null, slot=null, port=null, ontid=null; Map map = new HashMap(); if(2 == alarmProftype) {//传输专业告警 if(null != alarmLocate && !"".equals(alarmLocate)&&!"null".equals(alarmLocate)) { String[] locArry = alarmLocate.split("/"); Map locMap = new HashMap(); for(String loc : locArry) { if(null != loc && !"".equals(loc)) { if(loc.split("=").length>=2){ String k = loc.split("=")[0].toLowerCase(); String v = loc.split("=")[1]; locMap.put(k, v); } } } rack = locMap.get("rack"); shelf = locMap.get("shelf"); slot = locMap.get("slot"); // 端口, 有port 和 PhysicalPort ,不排除第三种 for(Iterator it=locMap.keySet().iterator(); it.hasNext();) { String k = it.next(); if(null != k && k.contains("port")) { port = locMap.get(k); } } }// end second if }// end first if ///数据网管告警,格式 0-0-2-2:4 else if(1 == alarmProftype) {//数据专业 if(null != alarmLocate && !"".equals(alarmLocate)) { String loc = alarmLocate.split(":")[0]; String[] locArry = loc.split("-"); if(locArry.length>0){ rack = locArry[0]; } if(locArry.length>1){ shelf = locArry[1]; } if(locArry.length>2){ slot = locArry[2]; } if(locArry.length>3){ port = locArry[3]; } if(alarmLocate.split(":").length>1) ontid = alarmLocate.split(":")[1]; } } map.put("rack", rack); map.put("shelf", shelf); map.put("slot", slot); map.put("port", port); map.put("ontid", ontid); return map; } /** * 将告警与电路关系保存到Ges_bsm_alarm_cir_rel表中 * @param gesBsmAlarmId,告警保存到GES_BSM_ALARM表后,自动生成的ID * @param cirId,电路ID */ public static void saveGesBsmAlarmCirRel(Long gesBsmAlarmId,String circuitIds){ if(null!=circuitIds&&gesBsmAlarmId!=null){ try{ String[] ids = circuitIds.split(","); for(String id:ids){ GesBsmAlarmCirRelId relId = new GesBsmAlarmCirRelId(gesBsmAlarmId,Long.parseLong(id)); GesBsmAlarmCirRel rel = new GesBsmAlarmCirRel(relId); ServiceProvider.getGesBsmAlarmCirRelDao().save(rel); } logger.debug(String.format("REL告警与电路关系入库成功,共%d条!", ids.length)); }catch(Exception e){ logger.debug(String.format("REL告警与电路关系入库异常!%s",e.getMessage())); e.printStackTrace(); } } } public static void removeGesBsmAlarmCirRel(Long gesBsmAlarmId,String circuitIds){ if(gesBsmAlarmId!=null&&circuitIds!=null){ logger.debug(String.format("REL准备删除告警与电路关系:[gesBsmAlarmId:%s,gesBsmAlarmCircuitIds:%s]", gesBsmAlarmId,circuitIds)); try{ String[] ids = circuitIds.split(","); for(String id:ids){ GesBsmAlarmCirRelId relId = new GesBsmAlarmCirRelId(gesBsmAlarmId,Long.parseLong(id));//存储告警与电路关联的类,属性有告警ID和关联的电路编码ID GesBsmAlarmCirRel rel = new GesBsmAlarmCirRel(relId); ServiceProvider.getGesBsmAlarmCirRelDao().delete(rel); } logger.debug(String.format("REL告警与电路关系删除成功,共%d条!", ids.length)); }catch(Exception e){ logger.debug(String.format("REL告警与电路关系删除异常!%s",e.getMessage())); e.printStackTrace(); } } } public void clearAlaarmSendShortMsg(GesBsmAlarm gesBsmAlarm){ List ccList = ServiceProvider.getGesAlarmDao().getCustCircuitByDevName(gesBsmAlarm.getDeviceName().trim()); AffectCustDto affectCustDto = new AffectCustDto(); affectCustDto.setMmeeids(gesBsmAlarm.getCustomCode()); affectCustDto.setCircuitIds(gesBsmAlarm.getCircuitIds()); affectCustDto.setCirCodes(gesBsmAlarm.getCirCodes()); } public void convertAreaId(String srcAreaId){ } /** * 向告警影响的客户发送短信 * @param gesAlarm 告警信息 * @param ccList 影响的客户及电路 * @param strategyType 影响的客户及电路 * @param affectCustDto 封装的与告警相关联的电路 路由信息和客户信息 */ public void newAlarmSendShortMsg(GesAlarm gesAlarm, AffectCustDto affectCustDto,List ccList,Integer strategyType){ try{ List configList = ServiceProvider.getGesMonitorConfig2Dao().queryConfig(affectCustDto.getMmeeids());//查询数据库中需要进行短信通知的客户 //<联系人电话,<客户名称,电路编码>MAP Map> customerMsgMap = new HashMap>();//电话号码,<客户名称,电路编码> Map> managerMsgMap = new HashMap>();//电话号码,电路编码 Map> engineerMsgMap = new HashMap>();//电话号码,电路编码 if(null!=configList&&configList.size()>0){ Map cirMap = new HashMap(); Map telMap = new HashMap(); for(CustCircuitDto dto:ccList){ if(null!=dto.getCircuitId()){ cirMap.put(dto.getCircuitId().toString(), dto); } if(null!=dto.getCustomerTel()){ telMap.put(dto.getCustomerTel(), dto); } if(null!=dto.getManagerTel()){ telMap.put(dto.getManagerTel(), dto); } if(null!=dto.getEngineerTel()){ telMap.put(dto.getEngineerTel(), dto); } } String custIds = affectCustDto.getMmeeids();//客户ID String cirIds = affectCustDto.getCircuitIds();//电路编码 for(GesMonitorConfig2 config:configList){ String noticeUsers = config.getNoticeUsers();//通知用户类型 //通知对象标记 boolean customerNotice = false; boolean managerNotice = false; boolean engineerNotice = false; if(null==noticeUsers||"".equals(noticeUsers)){ continue; } noticeUsers += ","; if(noticeUsers.contains("1,")){//通知客户联系人 customerNotice=true; } if(noticeUsers.contains("2,")){//通知客户经理 managerNotice=true; } if(noticeUsers.contains("3,")){//通知客户工程师 engineerNotice=true; } //判断告警影响的客户是否是主动监控客户 if(null!=affectCustDto.getMmeeids()&&affectCustDto.getMmeeids().contains(config.getCustId().toString())){ //分隔主动监控客户的电路ID,逐一处理 String[] cis = config.getCircuitIds().split(","); if(affectCustDto.getCircuitIds()!=null&&cis!=null){ //为避免长ID包含短ID,如32123与212,在ID后加逗号后进行比对 String cirIdsTemp = affectCustDto.getCircuitIds()+",";//告警影响的电路ID for(String str:cis){ if(null!=str&&!"".equals(str)&&cirIdsTemp.contains(str+",")){ //告警影响了主动监控电路 //根据电路ID,取客户及电路信息 CustCircuitDto d = cirMap.get(str); String cirCode = d.getCircode();//取电路编码 if(customerNotice&&null!=d.getCustomerTel()){ Map tempMap = customerMsgMap.get(d.getCustomerTel()); if(null==tempMap){ tempMap = new HashMap(); } if(null!=d.getCustName()&&!"".equals(d.getCustName())){ StringBuffer sb = tempMap.get(d.getCustName()); if(null==sb){ sb = new StringBuffer(512); } sb.append(cirCode).append(","); tempMap.put(d.getCustName(), sb); customerMsgMap.put(d.getCustomerTel(), tempMap); } } if(managerNotice&&null!=d.getManagerTel()){ Map tempMap = managerMsgMap.get(d.getManagerTel()); if(null==tempMap){ tempMap = new HashMap(); } if(null!=d.getCustName()&&!"".equals(d.getCustName())){ StringBuffer sb = tempMap.get(d.getCustName()); if(null==sb){ sb = new StringBuffer(512); } sb.append(cirCode).append(","); tempMap.put(d.getCustName(), sb); managerMsgMap.put(d.getManagerTel(), tempMap); } } if(engineerNotice&&null!=d.getEngineerTel()){ Map tempMap = engineerMsgMap.get(d.getEngineerTel()); if(null==tempMap){ tempMap = new HashMap(); } if(null!=d.getCustName()&&!"".equals(d.getCustName())){ StringBuffer sb = tempMap.get(d.getCustName()); if(null==sb){ sb = new StringBuffer(512); } sb.append(cirCode).append(","); tempMap.put(d.getCustName(), sb); engineerMsgMap.put(d.getEngineerTel(), tempMap); } } } } } } } //发送短信 int ppFlag = 0; SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); if(null!=strategyType){ ppFlag = strategyType.intValue(); } //客户联系人 for(String tel:customerMsgMap.keySet()){ Map m = customerMsgMap.get(tel); for(String custName:m.keySet()){ StringBuffer sb = m.get(custName); if(null==custName){ custName = ""; } if(null!=sb&&sb.length()>0){ StringBuffer msgSb = new StringBuffer(512); msgSb.append("尊敬的") .append(custName) .append("客户您好!于") .append(null==gesAlarm.getNealarmtime()?"":sdf.format(gesAlarm.getNealarmtime())) .append("时间【").append(gesAlarm.getReserve3())//告警设备 .append("】设备产生告警,可能会影响您的") .append(sb.substring(0, sb.length()-1)) .append("等电路的正常使用,我们正在修复故障,若给你带来不便,敬请谅解!【中国电信-大客户网管系统】"); if(2==ppFlag){ msgSb.append(gesAlarm.getAlarmname()).append("告警被屏蔽!"); } logger.info(String.format("向客户联系人%s(%s)发送短信:%s",custName,tel, msgSb.toString())); sendShortMsg(tel,msgSb.toString(),0); } } } //客户经理 for(String tel:managerMsgMap.keySet()){ Map m = managerMsgMap.get(tel); CustCircuitDto d = telMap.get(tel); String name = d.getManager(); if(null==name){ name = ""; } StringBuffer subSb = new StringBuffer(512); for(String custName:m.keySet()){ StringBuffer sb = m.get(custName); if(null==custName){ custName = ""; } if(null!=sb&&sb.length()>1){ if(subSb.length()>1){ subSb.append(","); } subSb.append("【").append(custName).append(":") .append(sb.substring(0, sb.length()-1)).append("】"); } } if(subSb.length()>1){ StringBuffer msgSb = new StringBuffer(512); msgSb.append("尊敬的") .append(name) .append("您好!于") .append(null==gesAlarm.getNealarmtime()?"":sdf.format(gesAlarm.getNealarmtime())) .append("时间【").append(gesAlarm.getReserve3())//告警设备 .append("】设备产生告警,可能会影响您的以下客户业务") .append(subSb.toString()) .append(",请注意查看故障修复进展。【中国电信-大客户网管系统】"); if(2==ppFlag){ msgSb.append(gesAlarm.getAlarmname()).append("告警被屏蔽!"); } sendShortMsg(tel,msgSb.toString(),0); logger.info(String.format("向客户经理%s(%s)发送短信:%s",name,tel, msgSb.toString())); } } //客户工程师 for(String tel:engineerMsgMap.keySet()){ Map m = engineerMsgMap.get(tel); CustCircuitDto d = telMap.get(tel); String name = d.getEngineer(); if(null==name){ name = ""; } StringBuffer subSb = new StringBuffer(512); for(String custName:m.keySet()){ StringBuffer sb = m.get(custName); if(null==custName){ custName = ""; } if(null!=sb&&sb.length()>1){ if(subSb.length()>1){ subSb.append(","); } subSb.append("【").append(custName).append(":") .append(sb.substring(0, sb.length()-1)).append("】"); } } if(subSb.length()>1){ StringBuffer msgSb = new StringBuffer(512); msgSb.append("尊敬的") .append(name) .append("客户您好!于") .append(null==gesAlarm.getNealarmtime()?"":sdf.format(gesAlarm.getNealarmtime())) .append("时间【").append(gesAlarm.getReserve3())//告警设备 .append("】设备产生通信故障,可能会影响您的以下客户业务") .append(subSb.toString()) .append(",请注意查看故障修复进展。【中国电信-大客户网管系统】"); if(2==ppFlag){ msgSb.append(gesAlarm.getAlarmname()).append("告警被屏蔽!"); } sendShortMsg(tel,msgSb.toString(),0); logger.info(String.format("向客户工程师%s(%s)发送短信:%s",name,tel, msgSb.toString())); } } } }catch(Exception e){ logger.info("分析告警推送对象异常:"+e.getMessage()); e.printStackTrace(); } } /** * 对比AZ端的端口信息是否正确 * @param gesAlarm * @return */ public boolean compareAZinfo(GesAlarm gesAlarm,Map mapString){ String circuitIds = ""; String cirCodes = ""; String alarmNet = gesAlarm.getReserve3();//告警设备 String alarmLocate = gesAlarm.getReserve5(); // 故障位置 long alarmProftype = gesAlarm.getAlarmproftype();//表示传输专业还是数据专业的告警 if(alarmNet!= null){ List azInfos = Static.cirCodeAzInfoMap.get(alarmNet); if(azInfos!=null){ boolean ifcompare = false; Map map = analyticalPostition(alarmLocate,alarmProftype);//告警的AZ端口信息 String rack = map.get("rack"); String shelf = map.get("shelf"); String slot = map.get("slot"); String port = map.get("port"); for(String azInfo:azInfos){ System.out.print(">>>>>>"+azInfo+"\n"); boolean portCompare = true;//如果定制了端口,则用来对比端口信息 Map aZmap = analyticalPostition(azInfo.split("//")[0],2);//对应的AZ端口的信息 String azRack = aZmap.get("rack"); String azShelf = aZmap.get("shelf"); String azSlot = aZmap.get("slot"); String azPort = aZmap.get("port"); if(!isEmptyIgnoreCase(azRack)){ if(rack!=null){ if(!azRack.trim().equals(rack.trim())){ portCompare=false; } }else{ portCompare=false; } } if(!isEmptyIgnoreCase(azShelf)){ if(shelf!=null){ if(!azShelf.trim().equals(shelf.trim())){ portCompare=false; } }else{ portCompare=false; } } if(!isEmptyIgnoreCase(azSlot)){ if(slot!=null){ if(!azSlot.trim().equals(slot.trim())){ portCompare=false; } }else{ portCompare=false; } } if(!isEmptyIgnoreCase(azPort)){ if(port!=null){ if(!azPort.trim().equals(port.trim())){ portCompare=false; } }else{ portCompare=false; } } if(portCompare){//端口相同 if(azInfo.split("//").length>2){ circuitIds += azInfo.split("//")[1]+",";//电路ID cirCodes += azInfo.split("//")[2]+",";//电路编码 System.out.print(">>>0"+circuitIds+">>>0"+cirCodes+"\n"); } ifcompare= true; } } mapString.put("prepareCircuitIds", circuitIds); mapString.put("prepareCirCodes", cirCodes); if(ifcompare){//如果有一个匹配上的话,就返回真 return true; } } } return false; } /** * 定制网元产生告警后,发送短信给指定人员 * @param tel * @param msg */ public void customizedNeSendMsg(GesAlarm gesAlarm,Integer strategyType){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); String alarmNet = gesAlarm.getReserve3();//告警设备 String alarmLocate = gesAlarm.getReserve5(); // 故障位置 List dzwyList = new ArrayList(); DZWYDto dzwy = new DZWYDto(); long alarmProftype = gesAlarm.getAlarmproftype();//表示传输专业还是数据专业的告警 int ppFlag = 0;//用来判断该告警是否可以被屏蔽 if(null!=strategyType){ ppFlag = strategyType.intValue(); } if(alarmNet!= null){ AlarmLevelDto alarmlev=null; String levName=null; List alarmLLevels=ServiceProvider.getGesAlarmDao().getCirAlarmLev(gesAlarm.getAlarmname());//获取告警内容级别 if(alarmLLevels!=null&&alarmLLevels.size()>0){ alarmlev=alarmLLevels.get(0); } if(alarmlev!=null&&alarmlev.getIsA()!=null&&alarmlev.getIsA().equals("1")){ levName="业务中断"; } else if(alarmlev!=null&&alarmlev.getIsB()!=null&&alarmlev.getIsB().equals("1")){ levName="性能劣化"; } else if(alarmlev!=null&&alarmlev.getIsC()!=null&&alarmlev.getIsC().equals("1")){ levName="风险增加"; }else levName=""; dzwyList = ServiceProvider.getGesAlarmDao().queryGESWY(alarmNet,alarmLocate); if(dzwyList.size()>0){ dzwy = dzwyList.get(0); } List costomizes = Static.customizedMap.get(gesAlarm.getReserve3()); if(costomizes!=null){ Map map = analyticalPostition(alarmLocate,alarmProftype); String rack = map.get("rack"); String shelf = map.get("shelf"); String slot = map.get("slot"); String port = map.get("port"); for(String costomized:costomizes){ boolean portCompare = true;//如果定制了端口,则用来对比端口信息 String[] strs = costomized.split("_"); String positions = "第"; String cRack = strs[0]; String cShelf = strs[1]; String cSlot = strs[2]; String cPort = strs[3]; String cNoticePeople = strs[4]; String cNoticeTelNum = strs[5]; if(!isEmptyIgnoreCase(cRack)){ positions +=cRack+"架"; if(rack!=null){ if(!cRack.trim().equals(rack.trim())){ portCompare=false; } }else{ portCompare=false; } } if(!isEmptyIgnoreCase(cShelf)){ positions +=cShelf+"框"; if(shelf!=null){ if(!cShelf.trim().equals(shelf.trim())){ portCompare=false; } }else{ portCompare=false; } } if(!isEmptyIgnoreCase(cSlot)){ positions +=cSlot+"槽"; if(slot!=null){ if(!cSlot.trim().equals(slot.trim())){ portCompare=false; } }else{ portCompare=false; } } if(!isEmptyIgnoreCase(cPort)){ positions +=cPort+"口"; if(port!=null){ if(!cPort.trim().equals(port.trim())){ portCompare=false; } }else{ portCompare=false; } } logger.info("1>>>>》》》》"+costomized+"》》"+alarmLocate+">>>"+portCompare+"\n"); if(portCompare&&ppFlag!=2){ logger.info("2>>>>》》》》"+costomized+"》》"+alarmLocate+">>>"+portCompare+"\n"); if(positions.trim().equals("第")){ positions=""; } StringBuffer msgSb = new StringBuffer(512); /*msgSb.append("尊敬的") .append(cNoticePeople) .append("您好!于") .append(null==gesAlarm.getNealarmtime()?"":sdf.format(gesAlarm.getNealarmtime())) .append(",定制网元【").append(gesAlarm.getReserve3())//告警设备 .append(positions+"】产生告警"); if(!isEmptyIgnoreCase(gesAlarm.getAlarmname())){ msgSb.append("("+gesAlarm.getAlarmname()+")"); } msgSb.append(",请注意查看故障修复进展。【中国电信-大客户网管系统】");*/ msgSb.append("您好,") .append(dzwy.getCustName()) .append(",于") .append(null==gesAlarm.getNealarmtime()?"":sdf.format(gesAlarm.getNealarmtime())) .append("时间,设备") .append(gesAlarm.getReserve3()) .append("产生告警,电路编码:") .append(dzwy.getCirCode()) .append(",告警描述:") .append(gesAlarm.getAlarmsummary()); if(!levName.equals("")){ msgSb.append(",产生影响:") .append(levName); } sendShortMsg(cNoticeTelNum,msgSb.toString(),1); logger.info(String.format("向客户经理%s(%s)发送短信:%s",cNoticePeople,cNoticeTelNum, msgSb.toString())); } } } } } /* * 忽视大小写的字符串非空比较 */ public static boolean isEmptyIgnoreCase(String str){ if(str!=null&&!str.equalsIgnoreCase("null")&&!(str.trim()).equals("") &&!str.equalsIgnoreCase("undefined")){ return false; }else{ return true; } } /** * * @param tel 电话号码 * @param msg 短信内容 * @param type 0表示普通告警1表示定制网元的告警 */ public void sendShortMsg(String tel,String msg,int type){ System.out.print(">>>>>发送测试短信!"); // msg+="【测试短信】"; Long ifSend = -1L; try{ if(type==0){ ifSend = Long.parseLong(PropertiesLoadUtil.getPro("ALARM_IF_SENDMSG")); System.out.print(">>>>>普通告警短信发送功能!发送类型》》"+ifSend); logger.info(">>>>>普通告警短信发送功能!发送类型》》"+ifSend); }else if(type==1){ logger.info(">>>>>>发现定制网元,发送短信!"); ifSend = Long.parseLong(PropertiesLoadUtil.getPro("CUSTOMIZED_IF_SENDMSG")); System.out.print(">>>>>定制网元告警短信发送功能!发送类型》》"+ifSend); logger.info(">>>>>定制网元告警短信发送功能!发送类型》》"+ifSend); }else if(type==2){//2019-07-20纳管电路告警 ifSend = Long.parseLong(PropertiesLoadUtil.getPro("CIRCUIT_ALARMS_SENDMSG")); System.out.print(">>>>>纳管电路告警短信发送功能!发送类型》》"+ifSend); } }catch(Exception e){ logger.info("从配置文件中读取短信发送配置信息失败!",e); } if(isEmptyIgnoreCase(tel)||isEmptyIgnoreCase(msg)){ return; } ShortmessageInfo msgInfo = new ShortmessageInfo(); msgInfo.setReceiveNo(tel);//接收短信的电话号码 //msgInfo.setMessage(msg+tel); msgInfo.setMessage(msg); //msgInfo.setSendFlag(0L); msgInfo.setSendFlag(ifSend);//测试用,暂时设置为-1,短信模块不会发送状态为-1的短信。 msgInfo.setSendTime(new Date(System.currentTimeMillis())); ServiceProvider.getShortMessageInfoDao().save(msgInfo); } // public static void main(String[] args) { // System.out.println(">>>>>>>>>>"+isEmptyIgnoreCase(null)+"\n"); // System.out.println(">>>>>>>>>>"+isEmptyIgnoreCase("nUll")+"\n"); // System.out.println(">>>>>>>>>>"+isEmptyIgnoreCase("UNDERFINed")+"\n"); // } /** * 使用反射机制将GesBsmAlarm对象映射至GesBsmAlarmClear
* 注:该方法的前提是GesBsmAlarmClear和GesBsmAlarm对象定义的get/set方法对一致
* @param gesBsmAlarm * @return */ public GesBsmAlarmClear transformBy(GesBsmAlarm gesBsmAlarm) { Field[] fields = gesBsmAlarm.getClass().getDeclaredFields(); GesBsmAlarmClear gesBsmAlarmClear = new GesBsmAlarmClear(); for(Field field : fields) { String fieldName = field.getName(); Class type = field.getType(); logger.debug("type=" + type); fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); Method m1, m2; String v1; try { m1 = gesBsmAlarm.getClass().getDeclaredMethod("get" + fieldName); v1 = (String)m1.invoke(gesBsmAlarm); m2 = gesBsmAlarmClear.getClass().getDeclaredMethod("set" + fieldName, type); m2.invoke(gesBsmAlarmClear, v1); } catch (Exception e) { logger.error(e.getMessage(), e); } } return gesBsmAlarmClear; } // /** // * 测试函数 // * @param args // */ // public static void main(String[] args) { // // 测试transformBy方法 --通过 // GesBsmAlarm gesBsmAlarm = new GesBsmAlarm(); // gesBsmAlarm.setAlarmName("这是一个测试"); // GesBsmAlarmClear gesBsmAlarmClear = new alarmAnalysis().transformBy(gesBsmAlarm); // System.out.println(gesBsmAlarmClear.getAlarmName()); // } /** * 预处理 * @param name * @param rack * @param shelf * @param slot * @param port * @param sx * @return */ public String pretreatment(String name,String rack,String shelf,String slot,String port,String sx){ return "信息不全"; // List routeAList = ServiceProvider.getGesAlarmDao().getRouteA(name,rack,shelf,slot,port,sx); // List routeZList = ServiceProvider.getGesAlarmDao().getRouteZ(name,rack,shelf,slot,port,sx); // String ipA = null, ipB = null; // if(routeAList!=null&&routeAList.size()>0){ // for(int i = 0;i0){ // for(int i = 0;i map = analyticalPostition(alarmLocate,alarmProftype); rack = map.get("rack"); shelf = map.get("shelf"); slot = map.get("slot"); port = map.get("port"); ontid = map.get("ontid"); String ponInfo = nvl(shelf)+"/"+nvl(slot)+"/"+nvl(port)+":"+nvl(ontid); boolean isFacility = ServiceProvider.getGesAlarmDao().impactVideoCir(oltIp, ponInfo); if(!isFacility){ return false; } //4.打印返回 logger.info(String.format("视频专线相关-华为ONU设备掉电告警[alarmId:%d,专业:%d,网管:%d,原始告警ID:%s]", gesAlarm.getAlarmid(),gesAlarm.getAlarmproftype(),gesAlarm.getSourceid(),gesAlarm.getSrcalarmId())); //5.更新对应电路的在线状态 this.reloadOnlineStatus(oltIp, ponInfo); return true; } private static void impactVideoAlarm(GesAlarm gesAlarm, String shelf, String slot, String port, String ontid){ //1.提取oltIp,ponInfo String oltIp = null, alarmDetail = gesAlarm.getAlarmdetail(); Matcher matcher = Pattern.compile("上联OLTIP:"+IP_REGEX).matcher(alarmDetail); if(matcher.find()) oltIp = matcher.group().substring("上联OLTIP:".length()); String ponInfo = nvl(shelf)+"/"+nvl(slot)+"/"+nvl(port)+":"+nvl(ontid); //2.保存关联关系 Long alarmproftype = gesAlarm.getAlarmproftype(); String emsId = gesAlarm.getSourceid()+""; String serial = gesAlarm.getSrcalarmId(); ServiceProvider.getGesAlarmDao().saveVideoAlarm(alarmproftype, emsId, serial, oltIp, ponInfo); } private static String nvl(String str){ return str==null?"":str; } //更新视频专线电路在线状态 public void reloadOnlineStatus(String oltIp, String ponInfo){ try { long id = ServiceProvider.getGesAlarmDao().queryCirId(oltIp, ponInfo); ReturnInfo returnInfo = this.queryVideoStatus(oltIp, ponInfo); String result = returnInfo.getMsg(); if(!returnInfo.isFlag()){ logger.info(String.format("[状态更新-失败]:{id:%d, errorInfo:%s}\n", id, result)); } Document dom = DocumentHelper.parseText(result.substring(result.indexOf(""), result.indexOf("")+7)); String resultCode = ((Element)dom.selectSingleNode("/root/msgHead/result")).attributeValue("code"); if("SUCCESS".equals(resultCode)){ String onlineStatus = ((Element)dom.selectSingleNode("/root/msgBody/block/fields/field[last()]/cusStatus")).attributeValue("status"); ServiceProvider.getGesAlarmDao().updateStatus(id, onlineStatus); logger.info(String.format("[状态更新-成功]:{id:%d, onlineStatus:%s}\n", id, onlineStatus)); }else{ String errorInfo = ((Element)dom.selectSingleNode("/root/msgHead/result")).getText(); logger.info(String.format("[状态更新-失败]:{id:%d, errorInfo:响应错误-%s}\n", id, errorInfo)); } } catch (Exception e) { logger.info("视频专线请求发生未知异常", e); } } private ReturnInfo queryVideoStatus(String ip, String ponInfo){ //1.构造报文 String result = null; int requestId = ServiceProvider.getGesAlarmDao().querySequence(); if(requestId <= 0){ return new ReturnInfo(false, "程序异常-序列化请求ID失败"); } String[] portAndOnt = ponInfo==null?null:ponInfo.split(":"); if(portAndOnt==null || portAndOnt.length!=2 || StringUtils.isEmpty(portAndOnt[0]) || StringUtils.isEmpty(portAndOnt[1])){ return new ReturnInfo(false, "数据异常-请检查PON口信息数据"); } String requestMsg = createReqMsg(requestId, ip, portAndOnt[0], portAndOnt[1]); //2.发送请求 try { Client client = Client.create(); WebResource resource = client.resource("http://135.224.253.28:8081/services/NEService"); logger.info("请求报文为"+requestMsg); ClientResponse resp = resource.entity(requestMsg.trim()).post(ClientResponse.class); result = resp.getEntity(String.class).replace("<", "<").replace(">", ">"); logger.info("响应报文为"+result+""); }catch(Exception e){ logger.info("失败信息为:\n"+result, e); return new ReturnInfo(false, "程序异常-请求IPOSS发生未知错误"); } return new ReturnInfo(true, result); } //构造请求报文 private String createReqMsg(int requestId, String ip, String port, String ontid){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String headMsg = ""+ ""+requestId+""+ ""+sdf.format(new Date())+""+ "KANMS"+ "IPOSS"+ ""; String bodyMsg = ""+ "selectPonCusStatus" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; StringBuffer sb = new StringBuffer("" + "" + headMsg + bodyMsg + "]]>"); return sb.toString(); } } class ReturnInfo{ private boolean flag; private String msg; public ReturnInfo(){} public ReturnInfo(boolean flag, String msg) { this.flag = flag; this.msg = msg; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }

备注:在开发过程中碰到一个问题:这样多线程方式处理数据会导致相同数据重复消费即重复分析问题,后改了取数据的逻辑。
即:每次取满内存队列后,等队列全部消费完后,再从数据库中取数据,而不是边分析数据边从库中取数据。

你可能感兴趣的:(线程池,大数据处理,多线程,高并发,数据分析)