开发监控看板组管理CRUD

设计告警阈值配置功能
This commit is contained in:
gaoyutao
2026-01-23 18:39:20 +08:00
parent 493ecba0ba
commit 5564b03ed2
58 changed files with 1233 additions and 1986 deletions
@@ -0,0 +1,92 @@
package com.tongran.rocketmq.controller;
import com.tongran.common.core.web.controller.BaseController;
import com.tongran.common.core.web.domain.AjaxResult;
import com.tongran.common.log.annotation.Log;
import com.tongran.common.log.enums.BusinessType;
import com.tongran.common.security.annotation.RequiresPermissions;
import com.tongran.rocketmq.domain.RmAlarmThreshold;
import com.tongran.rocketmq.service.IRmAlarmThresholdService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 告警阈值配置Controller
*
* @author tongran
* @date 2026-01-23
*/
@RestController
@RequestMapping("/rmAlarmThreshold")
@RequiresPermissions("rocketmq:alarmLog")
public class RmAlarmThresholdController extends BaseController
{
@Autowired
private IRmAlarmThresholdService rmAlarmThresholdService;
/**
* 查询告警阈值配置列表
*/
@GetMapping("/list")
public AjaxResult list()
{
List<RmAlarmThreshold> list = rmAlarmThresholdService.selectRmAlarmThresholdList(new RmAlarmThreshold());
return success(list);
}
/**
* 获取告警阈值配置详细信息
*/
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(rmAlarmThresholdService.selectRmAlarmThresholdById(id));
}
/**
* 新增告警阈值配置
*/
@Log(title = "告警阈值配置", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody RmAlarmThreshold rmAlarmThreshold)
{
int rows = rmAlarmThresholdService.insertRmAlarmThreshold(rmAlarmThreshold);
if(rows == -1){
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.put(AjaxResult.CODE_TAG, 500);
ajaxResult.put(AjaxResult.MSG_TAG, "【告警类别】和【条件项】合起来不能重复");
return ajaxResult;
}
return toAjax(rows);
}
/**
* 修改告警阈值配置
*/
@Log(title = "告警阈值配置", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody RmAlarmThreshold rmAlarmThreshold)
{
int rows = rmAlarmThresholdService.updateRmAlarmThreshold(rmAlarmThreshold);
if(rows == -1){
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.put(AjaxResult.CODE_TAG, 500);
ajaxResult.put(AjaxResult.MSG_TAG, "【告警类别】和【条件项】合起来不能重复");
return ajaxResult;
}
return toAjax(rows);
}
/**
* 删除告警阈值配置
*/
@Log(title = "告警阈值配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(rmAlarmThresholdService.deleteRmAlarmThresholdByIds(ids));
}
}
@@ -0,0 +1,38 @@
package com.tongran.rocketmq.domain;
import com.tongran.common.core.annotation.Excel;
import com.tongran.common.core.web.domain.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
/**
* 告警阈值配置对象 rm_alarm_threshold
*
* @author tongran
* @date 2026-01-23
*/
@Data
public class RmAlarmThreshold extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 告警类型 */
@Excel(name = "告警类型")
private String alarmType;
/** 条件项 */
@Excel(name = "条件项")
private String conditionItem;
/** 比较运算符1大于,2小于,3等于 */
@Excel(name = "比较运算符")
private String compareOperator;
/** 阈值 */
@Excel(name = "阈值")
private BigDecimal thresholdValue;
}
@@ -5,7 +5,9 @@ import lombok.Getter;
@Getter
public enum AlarmTypeEnum {
服务器下线("1", "服务器下线"),
交换机下线("2", "交换机下线");
交换机下线("2", "交换机下线"),
CPU使用率高("4", "CPU使用率高"),
磁盘缺失("5", "磁盘缺失");
private final String code;
private final String msg;
AlarmTypeEnum(String code, String msg){
@@ -0,0 +1,14 @@
package com.tongran.rocketmq.enums;
import lombok.Getter;
@Getter
public enum ConditionItemEnum {
服务器CPU使用率("1", "服务器CPU使用率");
private final String code;
private final String msg;
ConditionItemEnum(String code, String msg){
this.code = code;
this.msg = msg;
}
}
@@ -4,7 +4,8 @@ import lombok.Getter;
@Getter
public enum PushMethodEnum {
企业微信("1", "企业微信");
企业微信("1", "企业微信"),
手机短信("2", "手机短信");
private final String code;
private final String msg;
PushMethodEnum(String code, String msg){
@@ -18,6 +18,7 @@ import com.tongran.rocketmq.producer.MessageProducer;
import com.tongran.rocketmq.service.*;
import com.tongran.rocketmq.utils.DataProcessUtil;
import com.tongran.rocketmq.utils.JsonDataParser;
import com.tongran.rocketmq.utils.SendAlarmPushUtil;
import com.tongran.rocketmq.utils.WeChatWorkBot;
import com.tongran.system.api.RemoteRevenueConfigService;
import com.tongran.system.api.domain.*;
@@ -129,6 +130,8 @@ public class MessageHandler {
private RedissonClient redissonClient;
@Autowired
private IRmOutboundTrafficStatisticsService rmOutboundTrafficStatisticsService;
@Autowired
private SendAlarmPushUtil sendAlarmPushUtil;
/**
@@ -1019,6 +1022,15 @@ public class MessageHandler {
allDiskName.setName(diskName);
allDiskNameService.updateAllDiskName(allDiskName);
disksToRemove.add(diskName);
// 磁盘缺失,触发告警
RmAlarmLog rmAlarmLog = new RmAlarmLog();
rmAlarmLog.setClientId(clientId);
rmAlarmLog.setAlarmTime(DateUtils.getNowDate());
rmAlarmLog.setAlarmType(AlarmTypeEnum.磁盘缺失.getCode());
rmAlarmLog.setAlarmContent("服务器" + clientId + "磁盘缺失,磁盘名称:" + diskName);
rmAlarmLogService.insertRmAlarmLog(rmAlarmLog);
sendAlarmPushUtil.sendAlarmPush(rmAlarmLog);
}
} catch (NumberFormatException e) {
disksToRemove.add(diskName);
@@ -1495,17 +1507,16 @@ public class MessageHandler {
updateData.setId(rmAlarmLog.getId());
if (alarmConfigList != null && !alarmConfigList.isEmpty()) {
try {
Map<String, Object> alarmMap = new HashMap<>();
alarmMap.put("告警时间", rmAlarmLog.getAlarmTime());
alarmMap.put("IP", rmAlarmLog.getMgmPublicIp());
alarmMap.put("告警类型", alarmTypeMsg);
alarmMap.put("告警设备", rmAlarmLog.getClientId());
alarmMap.put("告警内容", rmAlarmLog.getAlarmContent());
alarmMap.put("业务名称", rmAlarmLog.getBusinessName());
for (RmAlarmPushConfig alarmPushConfig : alarmConfigList) {
String contentTemplate = alarmPushConfig.getMessageContent();
String webhookUrl = alarmPushConfig.getPushAddress();
Map<String, Object> alarmMap = new HashMap<>();
alarmMap.put("告警时间", rmAlarmLog.getAlarmTime());
alarmMap.put("IP", rmAlarmLog.getMgmPublicIp());
alarmMap.put("告警类型", alarmTypeMsg);
alarmMap.put("告警设备", rmAlarmLog.getClientId());
alarmMap.put("告警内容", rmAlarmLog.getAlarmContent());
alarmMap.put("业务名称", rmAlarmLog.getBusinessName());
if (alarmPushConfig.getContactPhones() != null) {
String[] phones = alarmPushConfig.getContactPhones().split(",");
WeChatWorkBot.sendTemplateMessage(webhookUrl, contentTemplate, alarmMap, rmAlarmLog.getAlarmContent(), phones, false);
@@ -0,0 +1,61 @@
package com.tongran.rocketmq.mapper;
import java.util.List;
import com.tongran.rocketmq.domain.RmAlarmThreshold;
/**
* 告警阈值配置Mapper接口
*
* @author tongran
* @date 2026-01-23
*/
public interface RmAlarmThresholdMapper
{
/**
* 查询告警阈值配置
*
* @param id 告警阈值配置主键
* @return 告警阈值配置
*/
public RmAlarmThreshold selectRmAlarmThresholdById(Long id);
/**
* 查询告警阈值配置列表
*
* @param rmAlarmThreshold 告警阈值配置
* @return 告警阈值配置集合
*/
public List<RmAlarmThreshold> selectRmAlarmThresholdList(RmAlarmThreshold rmAlarmThreshold);
/**
* 新增告警阈值配置
*
* @param rmAlarmThreshold 告警阈值配置
* @return 结果
*/
public int insertRmAlarmThreshold(RmAlarmThreshold rmAlarmThreshold);
/**
* 修改告警阈值配置
*
* @param rmAlarmThreshold 告警阈值配置
* @return 结果
*/
public int updateRmAlarmThreshold(RmAlarmThreshold rmAlarmThreshold);
/**
* 删除告警阈值配置
*
* @param id 告警阈值配置主键
* @return 结果
*/
public int deleteRmAlarmThresholdById(Long id);
/**
* 批量删除告警阈值配置
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteRmAlarmThresholdByIds(Long[] ids);
}
@@ -0,0 +1,61 @@
package com.tongran.rocketmq.service;
import java.util.List;
import com.tongran.rocketmq.domain.RmAlarmThreshold;
/**
* 告警阈值配置Service接口
*
* @author tongran
* @date 2026-01-23
*/
public interface IRmAlarmThresholdService
{
/**
* 查询告警阈值配置
*
* @param id 告警阈值配置主键
* @return 告警阈值配置
*/
public RmAlarmThreshold selectRmAlarmThresholdById(Long id);
/**
* 查询告警阈值配置列表
*
* @param rmAlarmThreshold 告警阈值配置
* @return 告警阈值配置集合
*/
public List<RmAlarmThreshold> selectRmAlarmThresholdList(RmAlarmThreshold rmAlarmThreshold);
/**
* 新增告警阈值配置
*
* @param rmAlarmThreshold 告警阈值配置
* @return 结果
*/
public int insertRmAlarmThreshold(RmAlarmThreshold rmAlarmThreshold);
/**
* 修改告警阈值配置
*
* @param rmAlarmThreshold 告警阈值配置
* @return 结果
*/
public int updateRmAlarmThreshold(RmAlarmThreshold rmAlarmThreshold);
/**
* 批量删除告警阈值配置
*
* @param ids 需要删除的告警阈值配置主键集合
* @return 结果
*/
public int deleteRmAlarmThresholdByIds(Long[] ids);
/**
* 删除告警阈值配置信息
*
* @param id 告警阈值配置主键
* @return 结果
*/
public int deleteRmAlarmThresholdById(Long id);
}
@@ -3,14 +3,22 @@ package com.tongran.rocketmq.service.impl;
import com.tongran.common.core.utils.DateUtils;
import com.tongran.common.core.utils.EchartsDataUtils;
import com.tongran.rocketmq.domain.InitialCpuInfo;
import com.tongran.rocketmq.domain.RmAlarmLog;
import com.tongran.rocketmq.domain.RmAlarmThreshold;
import com.tongran.rocketmq.enums.AlarmTypeEnum;
import com.tongran.rocketmq.enums.ConditionItemEnum;
import com.tongran.rocketmq.mapper.InitialCpuInfoMapper;
import com.tongran.rocketmq.mapper.RmAlarmLogMapper;
import com.tongran.rocketmq.mapper.RmAlarmThresholdMapper;
import com.tongran.rocketmq.service.IInitialCpuInfoService;
import com.tongran.rocketmq.utils.SendAlarmPushUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -31,6 +39,12 @@ public class InitialCpuInfoServiceImpl implements IInitialCpuInfoService
{
@Autowired
private InitialCpuInfoMapper initialCpuInfoMapper;
@Autowired
private RmAlarmThresholdMapper rmAlarmThresholdMapper;
@Autowired
private RmAlarmLogMapper rmAlarmLogMapper;
@Autowired
private SendAlarmPushUtil sendAlarmPushUtil;
/**
* 查询CPU监控信息
@@ -116,6 +130,48 @@ public class InitialCpuInfoServiceImpl implements IInitialCpuInfoService
@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
public int batchInsertInitialCpuInfo(List<InitialCpuInfo> list) {
try {
// 查询告警阈值
RmAlarmThreshold thresholdQuery = new RmAlarmThreshold();
thresholdQuery.setAlarmType(AlarmTypeEnum.CPU使用率高.getCode());
thresholdQuery.setConditionItem(ConditionItemEnum.服务器CPU使用率.getCode());
List<RmAlarmThreshold> rmAlarmThresholdList = rmAlarmThresholdMapper.selectRmAlarmThresholdList(thresholdQuery);
if(rmAlarmThresholdList != null && !rmAlarmThresholdList.isEmpty()){
String operator = rmAlarmThresholdList.get(0).getCompareOperator();
BigDecimal threshold = rmAlarmThresholdList.get(0).getThresholdValue();
for (InitialCpuInfo initialCpuInfo : list) {
BigDecimal cpuUti = new BigDecimal(initialCpuInfo.getUti());
if(operator != null){
// 根据运算符1大于,2小于,3等于 判断是否进行告警
boolean shouldAlarm = false;
// 根据运算符判断是否进行告警
switch (operator) {
case "1": // 大于
shouldAlarm = cpuUti.compareTo(threshold) > 0;
break;
case "2": // 小于
shouldAlarm = cpuUti.compareTo(threshold) < 0;
break;
case "3": // 等于
shouldAlarm = cpuUti.compareTo(threshold) == 0;
break;
default:
log.warn("未知的运算符: {}", operator);
continue; // 跳过未知运算符的处理
}
if(shouldAlarm){
RmAlarmLog rmAlarmLog = new RmAlarmLog();
rmAlarmLog.setAlarmType(AlarmTypeEnum.CPU使用率高.getCode());
rmAlarmLog.setClientId(initialCpuInfo.getClientId());
rmAlarmLog.setAlarmTime(DateUtils.getNowDate());
rmAlarmLog.setAlarmContent("服务器" + initialCpuInfo.getClientId() + "的CPU使用率高");
rmAlarmLogMapper.insertRmAlarmLog(rmAlarmLog);
// 推送消息
sendAlarmPushUtil.sendAlarmPush(rmAlarmLog);
}
}
}
}
return initialCpuInfoMapper.batchInsertInitialCpuInfo(list);
}catch (Exception e){
log.error("批量插入CPU信息失败,失败数量:{}", list.size(), e);
@@ -0,0 +1,108 @@
package com.tongran.rocketmq.service.impl;
import com.tongran.common.core.utils.DateUtils;
import com.tongran.rocketmq.domain.RmAlarmThreshold;
import com.tongran.rocketmq.mapper.RmAlarmThresholdMapper;
import com.tongran.rocketmq.service.IRmAlarmThresholdService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 告警阈值配置Service业务层处理
*
* @author tongran
* @date 2026-01-23
*/
@Service
public class RmAlarmThresholdServiceImpl implements IRmAlarmThresholdService
{
@Autowired
private RmAlarmThresholdMapper rmAlarmThresholdMapper;
/**
* 查询告警阈值配置
*
* @param id 告警阈值配置主键
* @return 告警阈值配置
*/
@Override
public RmAlarmThreshold selectRmAlarmThresholdById(Long id)
{
return rmAlarmThresholdMapper.selectRmAlarmThresholdById(id);
}
/**
* 查询告警阈值配置列表
*
* @param rmAlarmThreshold 告警阈值配置
* @return 告警阈值配置
*/
@Override
public List<RmAlarmThreshold> selectRmAlarmThresholdList(RmAlarmThreshold rmAlarmThreshold)
{
return rmAlarmThresholdMapper.selectRmAlarmThresholdList(rmAlarmThreshold);
}
/**
* 新增告警阈值配置
*
* @param rmAlarmThreshold 告警阈值配置
* @return 结果
*/
@Override
public int insertRmAlarmThreshold(RmAlarmThreshold rmAlarmThreshold)
{
rmAlarmThreshold.setCreateTime(DateUtils.getNowDate());
try {
int rows = rmAlarmThresholdMapper.insertRmAlarmThreshold(rmAlarmThreshold);
}catch (DuplicateKeyException e){
return -1;
}
return 1;
}
/**
* 修改告警阈值配置
*
* @param rmAlarmThreshold 告警阈值配置
* @return 结果
*/
@Override
public int updateRmAlarmThreshold(RmAlarmThreshold rmAlarmThreshold)
{
rmAlarmThreshold.setUpdateTime(DateUtils.getNowDate());
try {
int rows = rmAlarmThresholdMapper.updateRmAlarmThreshold(rmAlarmThreshold);
}catch (DuplicateKeyException e){
return -1;
}
return 1;
}
/**
* 批量删除告警阈值配置
*
* @param ids 需要删除的告警阈值配置主键
* @return 结果
*/
@Override
public int deleteRmAlarmThresholdByIds(Long[] ids)
{
return rmAlarmThresholdMapper.deleteRmAlarmThresholdByIds(ids);
}
/**
* 删除告警阈值配置信息
*
* @param id 告警阈值配置主键
* @return 结果
*/
@Override
public int deleteRmAlarmThresholdById(Long id)
{
return rmAlarmThresholdMapper.deleteRmAlarmThresholdById(id);
}
}
@@ -0,0 +1,116 @@
package com.tongran.rocketmq.utils;
import com.tongran.rocketmq.domain.RmAlarmLog;
import com.tongran.rocketmq.domain.RmAlarmPushConfig;
import com.tongran.rocketmq.domain.RmNetworkInterface;
import com.tongran.rocketmq.enums.AlarmTypeEnum;
import com.tongran.rocketmq.enums.PushMethodEnum;
import com.tongran.rocketmq.service.IRmAlarmLogService;
import com.tongran.rocketmq.service.IRmAlarmPushConfigService;
import com.tongran.rocketmq.service.IRmNetworkInterfaceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
@Slf4j
public class SendAlarmPushUtil {
@Autowired
private IRmAlarmLogService rmAlarmLogService;
@Autowired
private IRmAlarmPushConfigService rmAlarmPushConfigService;
@Autowired
private IRmNetworkInterfaceService rmNetworkInterfaceService;
/**
* 发送告警推送
* @param rmAlarmLog 告警日志参数
*/
public void sendAlarmPush(RmAlarmLog rmAlarmLog) {
RmAlarmPushConfig rmAlarmPushConfig = new RmAlarmPushConfig();
rmAlarmPushConfig.setPushAlarmTypes(rmAlarmLog.getAlarmType());
List<RmAlarmPushConfig> alarmConfigList = rmAlarmPushConfigService.selectRmAlarmPushConfigList(rmAlarmPushConfig);
RmAlarmLog updateData = new RmAlarmLog();
updateData.setId(rmAlarmLog.getId());
if (alarmConfigList != null && !alarmConfigList.isEmpty()) {
try {
// 查询管理网公网ip
RmNetworkInterface rmNetworkInterface = new RmNetworkInterface();
rmNetworkInterface.setClientId(rmAlarmLog.getClientId());
rmNetworkInterface.setNewFlag(1);
List<RmNetworkInterface> interfaceList = rmNetworkInterfaceService.selectRmNetworkInterfaceList(rmNetworkInterface);
if (interfaceList != null && !interfaceList.isEmpty()) {
interfaceList.stream()
.filter(info -> "2".equals(info.getBindIp()) || "3".equals(info.getBindIp()))
.findFirst()
.ifPresent(networkInterface -> {
rmAlarmLog.setMgmPublicIp(networkInterface.getPublicIp());
});
}
Map<String, Object> alarmMap = new HashMap<>();
alarmMap.put("告警时间", rmAlarmLog.getAlarmTime());
alarmMap.put("IP", rmAlarmLog.getMgmPublicIp());
alarmMap.put("告警类型", AlarmTypeEnum.CPU使用率高.getMsg());
alarmMap.put("告警设备", rmAlarmLog.getClientId());
alarmMap.put("告警内容", rmAlarmLog.getAlarmContent());
for (RmAlarmPushConfig alarmPushConfig : alarmConfigList) {
if(PushMethodEnum.企业微信.getCode().equals(alarmPushConfig.getPushMethod())){
updateData.setPushFlag(processWeComPush(alarmPushConfig, alarmMap));
}else if(PushMethodEnum.手机短信.getCode().equals(alarmPushConfig.getPushMethod())){
updateData.setPushFlag(processTextMessagePush(alarmPushConfig, alarmMap));
}else{
log.info("暂无该推送方式:{}", alarmPushConfig.getPushMethod());
updateData.setPushFlag(2L);
}
}
} catch (Exception e){
updateData.setPushFlag(0L);
log.error("消息推送失败:{}", e.getMessage());
}
}else{
updateData.setPushFlag(2L);
}
rmAlarmLogService.updateRmAlarmLog(updateData);
}
/**
* 企业微信处理
*/
private Long processWeComPush(RmAlarmPushConfig alarmPushConfig, Map<String, Object> alarmMap){
String contentTemplate = alarmPushConfig.getMessageContent();
String webhookUrl = alarmPushConfig.getPushAddress();
if (alarmPushConfig.getContactPhones() != null) {
String[] phones = alarmPushConfig.getContactPhones().split(",");
WeChatWorkBot.sendTemplateMessage(webhookUrl, contentTemplate, alarmMap, alarmMap.get("告警内容"), phones, false);
} else {
WeChatWorkBot.sendTemplateMessage(webhookUrl, contentTemplate, alarmMap);
}
return 1L;
}
/**
* 手机短信处理
*/
private Long processTextMessagePush(RmAlarmPushConfig alarmPushConfig, Map<String, Object> alarmMap){
String contentTemplate = alarmPushConfig.getMessageContent();
String actualContent = WeChatWorkBot.processTemplate(contentTemplate, alarmMap, alarmMap.get("告警内容"));
if (alarmPushConfig.getContactPhones() != null) {
String[] phones = alarmPushConfig.getContactPhones().split(",");
SmsAlarmUtil smsAlarmUtil = new SmsAlarmUtil();
int successCount = smsAlarmUtil.sendAlarmToMultiple(alarmPushConfig.getContactPhones(), actualContent);
// 计算有效手机号数量(过滤空值)
long validPhoneCount = Arrays.stream(phones)
.map(String::trim)
.filter(phone -> !phone.isEmpty())
.count();
return validPhoneCount == successCount ? 1L : 0L;
}
return 0L;
}
}
@@ -0,0 +1,132 @@
package com.tongran.rocketmq.utils;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* 阿里云短信告警工具类
* 支持多个手机号同时发送相同内容
*/
@Slf4j
@Component
public class SmsAlarmUtil {
@Value("${aliyun.sms.access-key-id}")
private String accessKeyId;
@Value("${aliyun.sms.access-key-secret}")
private String accessKeySecret;
@Value("${aliyun.sms.sign-name}")
private String signName;
@Value("${aliyun.sms.template-code}")
private String templateCode;
private Client client;
/**
* 初始化阿里云短信客户端
*/
@PostConstruct
public void init() throws Exception {
Config config = new Config()
.setAccessKeyId(accessKeyId)
.setAccessKeySecret(accessKeySecret);
// 设置访问的域名
config.endpoint = "dysmsapi.aliyuncs.com";
this.client = new Client(config);
}
/**
* 发送短信告警(单个手机号)
* @param phoneNumber 手机号
* @param content 告警内容
* @return 是否发送成功
*/
public boolean sendAlarm(String phoneNumber, String content) {
if (!StringUtils.hasText(phoneNumber) || !StringUtils.hasText(content)) {
log.error("手机号或告警内容不能为空");
return false;
}
try {
SendSmsRequest request = new SendSmsRequest()
.setPhoneNumbers(phoneNumber)
.setSignName(signName)
.setTemplateCode(templateCode)
.setTemplateParam("{\"message_content\":\"" + content + "\"}");
SendSmsResponse response = client.sendSms(request);
if ("OK".equals(response.getBody().getCode())) {
log.info("短信发送成功,手机号:{},内容:{}", phoneNumber, content);
return true;
} else {
log.error("短信发送失败,手机号:{},错误码:{},错误信息:{}",
phoneNumber, response.getBody().getCode(), response.getBody().getMessage());
return false;
}
} catch (Exception e) {
log.error("发送短信异常,手机号:{},内容:{}", phoneNumber, content, e);
return false;
}
}
/**
* 发送短信告警(多个手机号)
* @param phoneNumbers 手机号列表
* @param content 告警内容
* @return 发送成功的手机号数量
*/
public int sendAlarmToMultiple(List<String> phoneNumbers, String content) {
if (phoneNumbers == null || phoneNumbers.isEmpty()) {
log.warn("手机号列表为空");
return 0;
}
int successCount = 0;
for (String phoneNumber : phoneNumbers) {
if (sendAlarm(phoneNumber, content)) {
successCount++;
}
}
log.info("批量发送完成,总手机号数:{},成功数:{}", phoneNumbers.size(), successCount);
return successCount;
}
/**
* 发送短信告警(多个手机号,逗号分隔)
* @param phoneNumbers 逗号分隔的手机号字符串
* @param content 告警内容
* @return 发送成功的手机号数量
*/
public int sendAlarmToMultiple(String phoneNumbers, String content) {
if (!StringUtils.hasText(phoneNumbers)) {
return 0;
}
String[] numbers = phoneNumbers.split(",");
int successCount = 0;
for (String number : numbers) {
String trimmedNumber = number.trim();
if (!trimmedNumber.isEmpty() && sendAlarm(trimmedNumber, content)) {
successCount++;
}
}
return successCount;
}
}