forked from luyan/epmet-cloud-lingshan
				
			
				 5 changed files with 308 additions and 79 deletions
			
			
		| @ -0,0 +1,185 @@ | |||
| package com.epmet.commons.tools.utils; | |||
| 
 | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.epmet.commons.tools.dto.form.DingTalkTextMsg; | |||
| import com.google.common.cache.Cache; | |||
| import com.google.common.cache.CacheBuilder; | |||
| import com.google.common.collect.Lists; | |||
| import org.apache.commons.codec.binary.Base64; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.stereotype.Component; | |||
| 
 | |||
| import javax.annotation.PreDestroy; | |||
| import javax.crypto.Mac; | |||
| import javax.crypto.spec.SecretKeySpec; | |||
| import java.io.IOException; | |||
| import java.net.URLEncoder; | |||
| import java.util.concurrent.ArrayBlockingQueue; | |||
| import java.util.concurrent.TimeUnit; | |||
| import java.util.concurrent.atomic.AtomicInteger; | |||
| 
 | |||
| /** | |||
|  * desc: 发送消息工具类 | |||
|  * | |||
|  * @date: 2020/6/29 8:43 | |||
|  * @author: jianjun liu | |||
|  */ | |||
| @Component | |||
| public class DingdingMsgSender { | |||
| 
 | |||
| 	private final Logger logger = LoggerFactory.getLogger(DingdingMsgSender.class); | |||
| 	//如果不设置则为 开发环境机器人地址
 | |||
| 	private static final String webHook = "https://oapi.dingtalk.com/robot/send?access_token=90782b119f82a5b6bb8e0f819b6a77bbc2102b53aa2d7d2e24fa10b66d580b1c"; | |||
| 	private static final String secret = "SEC080aac67ff78e79fdaba132aa51e3fb3f6060dec99492feaac82cabf9f8b6a19"; | |||
| 	/** | |||
| 	 * 默认10 | |||
| 	 */ | |||
| 	private static Integer maxQueueSize = 10; | |||
| 
 | |||
| 	/** | |||
| 	 * 有序队列 | |||
| 	 */ | |||
| 	private ArrayBlockingQueue<DingTalkTextMsg> msgQueue = new ArrayBlockingQueue<>(maxQueueSize); | |||
| 
 | |||
| 
 | |||
| 	private volatile boolean running = false; | |||
| 
 | |||
| 	private Cache<String, AtomicInteger> limitCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).maximumSize(1000).build(); | |||
| 
 | |||
| 	public DingdingMsgSender() { | |||
| 
 | |||
| 	} | |||
| 
 | |||
| 
 | |||
| 	private void handleMsg() { | |||
| 		DingTalkTextMsg msg = null; | |||
| 		try { | |||
| 			//阻塞取元素
 | |||
| 			msg = msgQueue.take(); | |||
| 			if (msg != null) { | |||
| 				AtomicInteger limitCount = limitCache.getIfPresent(msg.getWebHook()); | |||
| 				if (limitCount == null) { | |||
| 					limitCount = new AtomicInteger(1); | |||
| 					limitCache.put(msg.getWebHook(), limitCount); | |||
| 				} | |||
| 				if (limitCount.intValue() > maxQueueSize) { | |||
| 					msgQueue.offer(msg); | |||
| 					Thread.sleep(1000); | |||
| 				} else { | |||
| 					sendPostByJSON(msg); | |||
| 					limitCount.addAndGet(1); | |||
| 				} | |||
| 			} else { | |||
| 				Thread.sleep(1000); | |||
| 			} | |||
| 		} catch (Exception e) { | |||
| 			logger.warn("handleMsg exception,serverUrl:" + msg.getWebHook() + ",msg:" + JSON.toJSONString(msg), e); | |||
| 		} | |||
| 	} | |||
| 
 | |||
| 
 | |||
| 	/** | |||
| 	 * desc:异步发送消息 | |||
| 	 * | |||
| 	 * @param messageParam | |||
| 	 * @return | |||
| 	 * @throws IOException | |||
| 	 */ | |||
| 	public boolean sendMsgAsync(DingTalkTextMsg messageParam) { | |||
| 		if (!running) { | |||
| 			running = true; | |||
| 			getThread().start(); | |||
| 		} | |||
| 		boolean flag = false; | |||
| 		int currentQueueSize = msgQueue.size(); | |||
| 		//非阻塞 添加/删除元素
 | |||
| 		if (currentQueueSize < maxQueueSize) { | |||
| 			flag = msgQueue.offer(messageParam); | |||
| 		} else { | |||
| 			msgQueue.poll(); | |||
| 
 | |||
| 			DingTalkTextMsg param = new DingTalkTextMsg(); | |||
| 			param.setContent("待发送消息队列已满,当前队列个数" + msgQueue.size() + "\n" + "最新消息内容:" + JSON.toJSONString(messageParam)); | |||
| 			param.setWebHook(messageParam.getWebHook()); | |||
| 			sendPostByJSON(param); | |||
| 		} | |||
| 		return flag; | |||
| 	} | |||
| 
 | |||
| 	/** | |||
| 	 * 同步发送报警 | |||
| 	 * | |||
| 	 * @param messageParam | |||
| 	 * @return | |||
| 	 * @throws IOException | |||
| 	 */ | |||
| 	public Result<String> sendMsgSync(DingTalkTextMsg messageParam) { | |||
| 		return sendPostByJSON(messageParam); | |||
| 	} | |||
| 
 | |||
| 	private Thread getThread() { | |||
| 		Thread sendMsgThread = new Thread("MsgSender-Thread") { | |||
| 			@Override | |||
| 			public void run() { | |||
| 				while (running) { | |||
| 					handleMsg(); | |||
| 				} | |||
| 			} | |||
| 		}; | |||
| 		return sendMsgThread; | |||
| 	} | |||
| 
 | |||
| 
 | |||
| 	@PreDestroy | |||
| 	public void destroy() { | |||
| 		running = false; | |||
| 	} | |||
| 
 | |||
| 	/** | |||
| 	 * 发送POST 请求 | |||
| 	 * | |||
| 	 * @param param 请求参数,JSON格式 | |||
| 	 * @return | |||
| 	 */ | |||
| 	private Result<String> sendPostByJSON(DingTalkTextMsg param) { | |||
| 		if (StringUtils.isBlank(param.getWebHook())) { | |||
| 			param.setWebHook(webHook); | |||
| 		} | |||
| 		if (StringUtils.isBlank(param.getSecret())) { | |||
| 			param.setSecret(secret); | |||
| 		} | |||
| 		Result<String> result = new Result<String>().error(); | |||
| 		Long timestamp = System.currentTimeMillis(); | |||
| 		try { | |||
| 			String stringToSign = timestamp + "\n" + param.getSecret(); | |||
| 			Mac mac = Mac.getInstance("HmacSHA256"); | |||
| 			mac.init(new SecretKeySpec(param.getSecret().getBytes("UTF-8"), "HmacSHA256")); | |||
| 			byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); | |||
| 			String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8"); | |||
| 			String url = param.getWebHook(); | |||
| 			url = url.concat("×tamp=" + timestamp + "&sign=" + sign); | |||
| 			String jsonStrParam = param.getMsgContent(); | |||
| 			result = HttpClientManager.getInstance().sendPostByJSON(url, jsonStrParam); | |||
| 		} catch (Exception e) { | |||
| 			logger.warn("sendPostByJSON error", e); | |||
| 		} | |||
| 		return result; | |||
| 	} | |||
| 
 | |||
| 
 | |||
| 	public static void main(String[] args) { | |||
| 		for (int i = 0; i < 50; i++) { | |||
| 
 | |||
| 			DingTalkTextMsg dingTalkTextMsg = new DingTalkTextMsg(); | |||
| 			dingTalkTextMsg.setWebHook(""); | |||
| 			dingTalkTextMsg.setContent("测试消息" + i); | |||
| 			dingTalkTextMsg.setAtMobiles(Lists.newArrayList()); | |||
| 			dingTalkTextMsg.setAtAll(false); | |||
| 			dingTalkTextMsg.setSecret(""); | |||
| 			DingdingMsgSender msgSender = new DingdingMsgSender(); | |||
| 			msgSender.sendMsgAsync(dingTalkTextMsg); | |||
| 		} | |||
| 	} | |||
| } | |||
					Loading…
					
					
				
		Reference in new issue