1、第三方调用失败接口:
package com.ruoyi.framework.exception.service;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
@Component
public class DemoService {
@Retryable(value = Exception.class,maxAttempts = 2,backoff = @Backoff(delay = 1000,multiplier = 1.5))
public void hello() throws Exception {
Thread.sleep(1000);
System.out.println("失败了!!!");
throw new Exception();
}
}
2、失败处理接口:
package com.ruoyi.framework.exception.service;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.ruoyi.framework.exception.mail.MailService;
import com.ruoyi.framework.exception.mapper.ExceptionLogMapper;
import com.ruoyi.framework.rocketmq.service.RocketProducerClient;
@Component
public class ExceptionHandlerImpl implements ExceptionHandler {
@Autowired
private RocketProducerClient client;
@Autowired
private ExceptionLogMapper logMapper;
@Autowired
private MailService mailService;
private ExecutorService executor = Executors.newFixedThreadPool(10);
@Override
public void handler(Message message) {
// TODO Auto-generated method stub
try {
//序列化参数
String body = JSON.toJSONString(message.getRecord());
message.setBody(body);
/*
* 把失败信息写入数据库
* */
logMapper.insert(message);
/*
* 把失败数据发送到MQ
*/
client.pushMessage(message.getTopic(), message.getTag(), message.getBody());
/*
* 给负责人发送邮件通知
*/
executor.submit(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
mailService.send(message.getEmail(), "异常提醒", "类:"+message.getClass()+",方法:"+message.getMethod()+"发生异常");
}});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3、mq消息发送:
package com.ruoyi.framework.rocketmq.service;
import javax.annotation.PostConstruct;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* RocketMQProducerClient
* description:RocketMQ Producer instance
* time:2020-07-11.16:17
*
* @author shuang.chen
* @version 1.0.0
*/
@Component
public class RocketProducerClient {
/**
* 生产者的组名
*/
@Value("${apache.rocketmq.producer.producerGroup}")
private String producerGroup; //myGroup
/**
* NameServer 地址
*/
@Value("${apache.rocketmq.namesrvAddr}")
private String namesrvAddr; //127.0.0.1:9876
private RocketProducerPool rocketMQProducerPool;
@PostConstruct
public void defaultMQProducer() {
this.rocketMQProducerPool=new RocketProducerPool(producerGroup,namesrvAddr);
}
public void pushMessage(String topic,String tags,String body) throws Exception {
DefaultMQProducer producer=null;
try {
producer=rocketMQProducerPool.getResource();
Message message = new Message(topic, tags, body.getBytes(RemotingHelper.DEFAULT_CHARSET));
producer.send(message);
}catch (Exception e){
throw new Exception("rocketmq 写入失败!",e);
}finally {
if(producer!=null){
rocketMQProducerPool.returnResource(producer);
}
}
}
}
4、邮件发送:
package com.ruoyi.framework.exception.mail;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
@Component
public class MailServiceImpl implements MailService {
@Autowired
private JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String from;
@Override
public void send(String to, String subject, String text) {
// TODO Auto-generated method stub
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = null;
try {
helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(text, true);
mailSender.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
5、调用入口:
package com.ruoyi.web.controller.demo.controller;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.framework.exception.service.DemoService;
import com.ruoyi.framework.exception.service.ExceptionHandler;
import com.ruoyi.framework.exception.service.Message;
import com.ruoyi.framework.exception.service.Record;
import com.ruoyi.framework.redis.service.RedisService;
@RestController
@RequestMapping("/demo")
public class DemoRocketController {
@Autowired
private ExceptionHandler handler;
@Autowired
private RedisService service;
@Autowired
private DemoService demoService;
@RequestMapping("/hello")
public void hello() {
try {
service.set("hello", "chenshuang");
//模拟第三方调用失败重试2次
demoService.hello();
//
System.out.println("redis:"+service.get("hello"));
} catch (Exception e) {
/*
* 模拟异常处理
*/
Message message = new Message();
//mq的topic
message.setTopic("firstPushTopic");
//mq的tag
message.setTag("push");
//日志记录
message.setLog("hello");
//参数记录
Record record = new Record();
//入参
record.setParam("param");
//返回值
record.setReturnValue("returnValue");
message.setRecord(record);
//负责人邮箱
message.setEmail("1341984744@qq.com");
//异常class
message.setClassName(DemoRocketController.class.getName());
//异常方法
message.setMethod("hello");
//负责人
message.setPerson("shuang.chen");
//异常时间
message.setTime(new Date());
//处理异常
handler.handler(message);
}
}
}