|
|
package com.monitor.middleware.redis.service.impl;
|
|
|
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.model.MObjectInfo;
|
|
|
import com.model.RedisMonitor;
|
|
|
import com.model.TypeInfo;
|
|
|
import com.monitor.common.config.SnsMobileConfig;
|
|
|
import com.monitor.common.service.AlarmMsgService;
|
|
|
import com.monitor.common.util.HttpRestClient;
|
|
|
import com.monitor.common.util.RedisCommonUtil;
|
|
|
import com.monitor.common.util.TelnetUtils;
|
|
|
import com.monitor.middleware.redis.service.IRedisMonitorHandleService;
|
|
|
import com.monitor.mysql.mapper.MObjectInfoMapper;
|
|
|
import com.monitor.mysql.mapper.MTypeInfoMapper;
|
|
|
import com.monitor.mysql.mapper.RedisMonitorMapper;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.util.*;
|
|
|
|
|
|
@EnableScheduling
|
|
|
@Service
|
|
|
public class RedisMonitorHandleServiceImpl implements IRedisMonitorHandleService {
|
|
|
|
|
|
Logger log = LoggerFactory.getLogger(RedisMonitorHandleServiceImpl.class);
|
|
|
|
|
|
@Autowired
|
|
|
HttpRestClient httpRestClient;
|
|
|
|
|
|
@Autowired
|
|
|
MTypeInfoMapper mTypeInfoMapper;
|
|
|
|
|
|
@Autowired
|
|
|
MObjectInfoMapper mObjectInfoMapper;
|
|
|
|
|
|
@Autowired
|
|
|
RedisMonitorMapper redisMonitorMapper;
|
|
|
|
|
|
@Autowired
|
|
|
public AlarmMsgService alarmMsgService;
|
|
|
|
|
|
@Autowired
|
|
|
private SnsMobileConfig snsMobileConfig;
|
|
|
|
|
|
@Override
|
|
|
public void redisMonitor() {
|
|
|
List<RedisMonitor> redisInfoList=new ArrayList<RedisMonitor>();
|
|
|
List<String> twemproxyAlarmList=new ArrayList<String>();
|
|
|
List<String> redisAlarmList=new ArrayList<String>();
|
|
|
List<String> slaveAlarmList=new ArrayList<String>();
|
|
|
|
|
|
TypeInfo typeInfo=mTypeInfoMapper.selectTypeInfoByName("redis");
|
|
|
if(typeInfo==null){
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
List<TypeInfo> typeInfoList=mTypeInfoMapper.getChildTypesInfo(typeInfo.getTypeId());
|
|
|
if(CollectionUtils.isEmpty(typeInfoList)){
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
Map<Integer,String> redisTweproxyMap=new HashMap<Integer,String>();
|
|
|
List<Integer> querParamList=new ArrayList<Integer>();
|
|
|
for(TypeInfo tObj:typeInfoList){
|
|
|
List<TypeInfo> nextList=mTypeInfoMapper.getChildTypesInfo(tObj.getTypeId());
|
|
|
for(TypeInfo t1:nextList){
|
|
|
if(t1.getTypeIsLeaf()==1){
|
|
|
if("twemproxy".equals(t1.getTypeName())){
|
|
|
querParamList.add(t1.getTypeId());
|
|
|
redisTweproxyMap.put(t1.getTypeId(),tObj.getTypeName());
|
|
|
redisInfoList.add(new RedisMonitor(tObj.getTypeName(),tObj.getTypeName(),0,1,0,t1.getTypeId(),null));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if(CollectionUtils.isEmpty(querParamList)){
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
List<MObjectInfo> redisProxymList=mObjectInfoMapper.selectMObjectsInfoByTypes(querParamList);
|
|
|
|
|
|
/**********************************************************************
|
|
|
*1、处理twemproxy
|
|
|
***********************************************************************/
|
|
|
RedisMonitor redisMonitor=null;
|
|
|
if(CollectionUtils.isEmpty(redisProxymList)){
|
|
|
return;
|
|
|
}
|
|
|
StringBuffer paramMonitor=null;
|
|
|
//遍历twemproxy
|
|
|
Map<String,List<String>> tMap=new HashMap<String,List<String>>();
|
|
|
List<String> ipList=null;
|
|
|
|
|
|
for(MObjectInfo obj:redisProxymList){
|
|
|
paramMonitor=new StringBuffer();
|
|
|
String[] ports=obj.getMoTags().split(",");
|
|
|
log.info("two port is {}",obj.getMoTags());
|
|
|
String result= TelnetUtils.getResult(obj.getMoHostIp(),Integer.valueOf(ports[0]));
|
|
|
redisMonitor = new RedisMonitor();
|
|
|
if(StringUtils.isNotBlank(result)){
|
|
|
boolean proxyFlag=RedisCommonUtil.getRedisIsSlave(obj.getMoHostIp(),Integer.valueOf(ports[1]));
|
|
|
if(proxyFlag){
|
|
|
paramMonitor.append("探测成功;");
|
|
|
}else{
|
|
|
paramMonitor.append("探测失败;");
|
|
|
}
|
|
|
//取舍成功重新设为1
|
|
|
JSONObject response=JSONObject.parseObject(result);
|
|
|
|
|
|
//记录代理所有request的和
|
|
|
long requestCount = 0;
|
|
|
long upTime = -1;
|
|
|
int redisCount = 0;
|
|
|
|
|
|
//用ipString作为lastRequestCountMap lastUpTimeMap中的key
|
|
|
String ipString ="";
|
|
|
|
|
|
if(null != response){
|
|
|
int total_connections=(Integer)response.get("total_connections");
|
|
|
int curr_connections=(Integer)response.get("curr_connections");
|
|
|
upTime = Long.valueOf(response.get("uptime").toString());
|
|
|
if(total_connections>0){
|
|
|
//总连接数
|
|
|
paramMonitor.append("总连接数:"+total_connections+";");
|
|
|
}
|
|
|
if (total_connections > 0) {
|
|
|
paramMonitor.append("当前连接数:"+curr_connections+";");
|
|
|
}
|
|
|
|
|
|
//记录temproxy开启时间
|
|
|
if (upTime > 0) {
|
|
|
paramMonitor.append("upTime:" + upTime + ";");
|
|
|
log.info("upTime is : " + upTime);
|
|
|
}
|
|
|
|
|
|
//查看代理下的redis 求出所有代理request总量
|
|
|
JSONObject alpha=response.getJSONObject("alpha");
|
|
|
ipList=new ArrayList<String>();
|
|
|
|
|
|
for (Map.Entry<String, Object> entry : alpha.entrySet()) {
|
|
|
String key=entry.getKey();
|
|
|
if(key.indexOf(":")>1){
|
|
|
ipList.add(key+":"+obj.getMoTypeId());
|
|
|
JSONObject ipObj= alpha.getJSONObject(key);
|
|
|
|
|
|
// 取出requests的long值
|
|
|
requestCount += Long.valueOf(ipObj.get("requests").toString());
|
|
|
redisCount ++;
|
|
|
log.info("ip:" + key + "request:" + requestCount);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
ipString = obj.getMoHostIp()+":"+ports[1];
|
|
|
|
|
|
/**
|
|
|
* 计算caps值 (当前requestCount - lastRequestCount)/ (uptime - lastUpTime)/ 1000
|
|
|
* 在param_monitor字段数据中中添加 caps值 uptime值
|
|
|
* 将caps uptime数据存到全局map中,供下次计算使用
|
|
|
*/
|
|
|
double caps = -1;
|
|
|
|
|
|
//如果数据为0,即没有探测出数据,不记录该干扰数据
|
|
|
if (0 < requestCount) {
|
|
|
//twemproxy文档说明 request值为每30秒的汇总数据
|
|
|
caps = requestCount / 30 / redisCount;
|
|
|
}
|
|
|
|
|
|
paramMonitor.append("caps:" + caps + ";");
|
|
|
|
|
|
tMap.put(obj.getMoHostIp()+":"+ports[1],ipList);
|
|
|
redisMonitor.setIsFailed(1);
|
|
|
redisMonitor.setParamMonitor(paramMonitor.toString());
|
|
|
log.info("redisMonitor.setParaMonitor: " + paramMonitor.toString());
|
|
|
}
|
|
|
}else{
|
|
|
twemproxyAlarmList.add("失败:"+obj.getMoHostIp()+":"+ports[0]);
|
|
|
redisMonitor.setIsFailed(0);
|
|
|
redisMonitor.setParamMonitor(obj.getMoHostIp()+":"+obj.getMoTags());
|
|
|
}
|
|
|
redisMonitor.setNodeFrom(redisTweproxyMap.get(obj.getMoTypeId()));
|
|
|
redisMonitor.setNodeTo(obj.getMoHostIp()+":"+ports[1]);
|
|
|
redisMonitor.setLevel(1);
|
|
|
redisMonitor.setRedisType(obj.getMoTypeId());
|
|
|
redisInfoList.add(redisMonitor);
|
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
|
*2、处理Redis
|
|
|
***********************************************************************/
|
|
|
if(tMap.size()==0){
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
for (Map.Entry<String, List<String>> entry : tMap.entrySet()) {
|
|
|
String key = entry.getKey().toString();
|
|
|
List<String> rlist = entry.getValue();
|
|
|
log.info("loook twemproxy value {},redis list",key,rlist);
|
|
|
if(!CollectionUtils.isEmpty(rlist)){
|
|
|
for(String ipStr:rlist){
|
|
|
String[] ipConfig=ipStr.split(":");
|
|
|
Map<String,Object> result=null;
|
|
|
if(ipConfig.length==3){
|
|
|
log.info("redis info ip,port",ipConfig[0],ipConfig[1]);
|
|
|
int isFailed=0;
|
|
|
result= RedisCommonUtil.getRedisInfo(ipConfig[0], Integer.valueOf(ipConfig[1]));
|
|
|
paramMonitor=new StringBuffer();
|
|
|
if(null==result){
|
|
|
redisAlarmList.add(ipConfig[0]+":"+ipConfig[1]+",");
|
|
|
paramMonitor.append("0,");
|
|
|
}else{
|
|
|
isFailed=1;
|
|
|
paramMonitor.append("1,");
|
|
|
String role=(String)result.get("role");
|
|
|
paramMonitor.append(role+",");
|
|
|
try {
|
|
|
long maxmemory=RedisCommonUtil.getRedisMaxMemory(ipConfig[0], Integer.valueOf(ipConfig[1]));
|
|
|
if(maxmemory==0){
|
|
|
paramMonitor.append("最大内存为0");
|
|
|
}else{
|
|
|
BigDecimal byteDang=BigDecimal.valueOf(Long.valueOf(1024*1024));
|
|
|
BigDecimal maxMemoryMb = BigDecimal.valueOf(maxmemory).divide(byteDang,2,4);
|
|
|
paramMonitor.append(maxMemoryMb+"M,");
|
|
|
|
|
|
BigDecimal used_memory=BigDecimal.valueOf(Long.valueOf(result.get("used_memory").toString()));
|
|
|
BigDecimal useProportion = used_memory.divide(BigDecimal.valueOf(maxmemory),2,4);
|
|
|
paramMonitor.append(useProportion.multiply(new BigDecimal(100))+"%,");
|
|
|
}
|
|
|
}catch (Exception e){
|
|
|
log.error("计算Redis使用率错误",e);
|
|
|
paramMonitor.append("0.00%,");
|
|
|
}
|
|
|
paramMonitor.append(result.get("used_memory_human")+",");
|
|
|
paramMonitor.append(result.get("instantaneous_ops_per_sec")+",");
|
|
|
|
|
|
//计算命中率hitRate
|
|
|
long keyspaceHits = Long.valueOf(result.get("keyspace_hits").toString());
|
|
|
long keyspaceMisses = Long.valueOf(result.get("keyspace_misses").toString());
|
|
|
double hitRate = keyspaceHits * 1.0 / (keyspaceMisses + keyspaceHits);
|
|
|
paramMonitor.append(hitRate + ",");
|
|
|
|
|
|
if("slave".equals(role)){
|
|
|
//测试主从是否是好的
|
|
|
log.info("test master and slave info {}",result);
|
|
|
int flag = RedisCommonUtil.getRedisIsSlave(result.get("master_host").toString(),
|
|
|
Integer.valueOf(result.get("master_port").toString()),
|
|
|
ipConfig[0], Integer.valueOf(ipConfig[1]));
|
|
|
log.info("slave test result",flag);
|
|
|
String msg="";
|
|
|
|
|
|
switch (flag) {
|
|
|
case RedisCommonUtil.NORMAL:
|
|
|
msg = "OK";
|
|
|
break;
|
|
|
case RedisCommonUtil.READ_EXCEPTION:
|
|
|
slaveAlarmList.add("主"+result.get("master_host").toString()+":" +
|
|
|
result.get("master_port").toString() +
|
|
|
",从" + ipConfig[0]+":"+ipConfig[1]+",");
|
|
|
msg="ERROR";
|
|
|
break;
|
|
|
case RedisCommonUtil.WRITE_EXCEPTION:
|
|
|
// 主写数据失败
|
|
|
msg="ERROR";
|
|
|
slaveAlarmList.add("主"+result.get("master_host").toString()+":" +
|
|
|
result.get("master_port").toString() +
|
|
|
",从" + ipConfig[0]+":"+ipConfig[1]+",主Redis异常,塞值");
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
// if(RedisCommonUtil.NORMAL == flag){
|
|
|
// msg="OK";
|
|
|
// }else if (RedisCommonUtil.WRITE_EXCEPTION == flag){
|
|
|
// slaveAlarmList.add("主"+result.get("master_host").toString()+":"+result.get("master_port").toString()+",从"+ ipConfig[0]+":"+ipConfig[1]+",");
|
|
|
// msg="ERROR";
|
|
|
// }
|
|
|
redisInfoList.add(new RedisMonitor(ipConfig[0]+":" + ipConfig[1],
|
|
|
result.get("master_host").toString()+":"+result.get("master_port").toString(),
|
|
|
2,isFailed,1,Integer.valueOf(ipConfig[2]),msg));
|
|
|
}
|
|
|
}
|
|
|
redisInfoList.add(new RedisMonitor(key,ipConfig[0]+":"+ipConfig[1],2,isFailed,0,Integer.valueOf(ipConfig[2]),paramMonitor.toString()));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
|
*3、存储监控RedisInfo信息数据
|
|
|
***********************************************************************/
|
|
|
if(!CollectionUtils.isEmpty(redisInfoList)){
|
|
|
log.info("bachInsertRedisMonitor redis monitor:"+redisInfoList);
|
|
|
redisMonitorMapper.deleteAllRedisMonitor();
|
|
|
redisMonitorMapper.bachInsertRedisMonitor(redisInfoList);
|
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
|
*4、告警
|
|
|
***********************************************************************/
|
|
|
StringBuffer alrarmMsg=new StringBuffer("");
|
|
|
if(!CollectionUtils.isEmpty(twemproxyAlarmList)){
|
|
|
alrarmMsg.append("twemproxy:");
|
|
|
for(String str:twemproxyAlarmList){
|
|
|
alrarmMsg.append(str);
|
|
|
}
|
|
|
alrarmMsg.append("失败;");
|
|
|
}
|
|
|
|
|
|
if(!CollectionUtils.isEmpty(redisAlarmList)){
|
|
|
alrarmMsg.append("redis:");
|
|
|
for(String str:redisAlarmList){
|
|
|
alrarmMsg.append(str);
|
|
|
}
|
|
|
alrarmMsg.append("失败;");
|
|
|
}
|
|
|
|
|
|
if(!CollectionUtils.isEmpty(slaveAlarmList)){
|
|
|
alrarmMsg.append("主从:");
|
|
|
for(String str:slaveAlarmList){
|
|
|
alrarmMsg.append(str);
|
|
|
}
|
|
|
alrarmMsg.append("失败;");
|
|
|
}
|
|
|
|
|
|
log.info("sms redis start info {}",alrarmMsg.toString());
|
|
|
if(StringUtils.isNotBlank(alrarmMsg.toString())) {
|
|
|
alrarmMsg.append("请您及时查看!");
|
|
|
alarmMsgService.sendSms("redis", alrarmMsg.toString(), snsMobileConfig.getBaseMobile());
|
|
|
}
|
|
|
}
|
|
|
} |