Просмотр исходного кода

失败短信重发定时任务

xiaof 4 лет назад
Родитель
Сommit
ee4cfdb33a

+ 76 - 32
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicMessageServiceImpl.java

@@ -5,6 +5,7 @@ import com.aliyuncs.DefaultAcsClient;
 import com.aliyuncs.IAcsClient;
 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
+import com.aliyuncs.exceptions.ClientException;
 import com.aliyuncs.http.MethodType;
 import com.aliyuncs.profile.DefaultProfile;
 import com.aliyuncs.profile.IClientProfile;
@@ -74,38 +75,7 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
                 throw ExceptionResultEnum.ERROR.exception("短信消息提示已关闭");
             }
 
-            System.setProperty("sun.net.client.defaultConnectTimeout", "180000");
-            System.setProperty("sun.net.client.defaultReadTimeout", "18000");
-            // 初始化ascClient需要的几个参数
-            final String product = "Dysmsapi";// 短信API产品名称(短信产品名固定,无需修改)
-            final String domain = "dysmsapi.aliyuncs.com";// 短信API产品域名(接口地址固定,无需修改)
-            // 替换成你的AK
-            final String accessKeyId = dictionaryConfig.smsDomain().getAliyunSMSKey();// 你的accessKeyId,参考本文档步骤2
-            final String accessKeySecret = dictionaryConfig.smsDomain().getAliyunSMSSecret();// 你的accessKeySecret,参考本文档步骤2
-            // 初始化ascClient,暂时不支持多region(请勿修改)
-            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
-            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
-            IAcsClient acsClient = new DefaultAcsClient(profile);
-            // 组装请求对象
-            SendSmsRequest request = new SendSmsRequest();
-            // 使用post提交
-            request.setMethod(MethodType.POST);
-            // 必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为00+国际区号+号码,如“0085200000000”
-            request.setPhoneNumbers(mobileNumber);
-            // 必填:短信签名-可在短信控制台中找到
-            request.setSignName(dictionaryConfig.smsDomain().getAliyunSMSSignName());
-            // 必填:短信模板-可在短信控制台中找到
-            request.setTemplateCode(templateCode);
-            // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
-            // 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
-            request.setTemplateParam(variableParams);
-            // 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
-            // request.setSmsUpExtendCode("90997");
-            // 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
-//             request.setOutId("yourOutId");
-            // 请求失败这里会抛ClientException异常
-
-            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
+            SendSmsResponse sendSmsResponse = sendSms(mobileNumber, templateCode, variableParams);
 
             if (sendSmsResponse.getCode() != null) {
 
@@ -141,6 +111,50 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
         }
     }
 
+    /**
+     * 发送短信
+     * @param mobileNumber
+     * @param templateCode
+     * @param variableParams
+     * @return
+     * @throws ClientException
+     */
+    private SendSmsResponse sendSms(String mobileNumber, String templateCode, String variableParams) throws ClientException {
+        System.setProperty("sun.net.client.defaultConnectTimeout", "180000");
+        System.setProperty("sun.net.client.defaultReadTimeout", "18000");
+        // 初始化ascClient需要的几个参数
+        final String product = "Dysmsapi";// 短信API产品名称(短信产品名固定,无需修改)
+        final String domain = "dysmsapi.aliyuncs.com";// 短信API产品域名(接口地址固定,无需修改)
+        // 替换成你的AK
+        final String accessKeyId = dictionaryConfig.smsDomain().getAliyunSMSKey();// 你的accessKeyId,参考本文档步骤2
+        final String accessKeySecret = dictionaryConfig.smsDomain().getAliyunSMSSecret();// 你的accessKeySecret,参考本文档步骤2
+        // 初始化ascClient,暂时不支持多region(请勿修改)
+        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
+        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
+        IAcsClient acsClient = new DefaultAcsClient(profile);
+        // 组装请求对象
+        SendSmsRequest request = new SendSmsRequest();
+        // 使用post提交
+        request.setMethod(MethodType.POST);
+        // 必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为00+国际区号+号码,如“0085200000000”
+        request.setPhoneNumbers(mobileNumber);
+        // 必填:短信签名-可在短信控制台中找到
+        request.setSignName(dictionaryConfig.smsDomain().getAliyunSMSSignName());
+        // 必填:短信模板-可在短信控制台中找到
+        request.setTemplateCode(templateCode);
+        // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
+        // 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
+        request.setTemplateParam(variableParams);
+        // 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
+        // request.setSmsUpExtendCode("90997");
+        // 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
+//             request.setOutId("yourOutId");
+        // 请求失败这里会抛ClientException异常
+
+        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
+        return sendSmsResponse;
+    }
+
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void noticeOfExamTaskAudit(List<Long> examTaskIdList, MessageEnum messageType, SysUser sysUser) {
@@ -242,8 +256,38 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
             queryWrapper.lambda().ne(BasicMessage::getSendStatus, "OK").lt(BasicMessage::getResendCount, resendCount);
             List<BasicMessage> basicMessageList = this.list(queryWrapper);
             if (basicMessageList != null && basicMessageList.size() > 0) {
+                for (BasicMessage basicMessage : basicMessageList) {
+                    this.saveMessageResendLog(basicMessage);
+                }
+            }
+        }
+    }
 
+    /**
+     * 自动重发
+     * @param basicMessage
+     */
+    private void saveMessageResendLog(BasicMessage basicMessage) {
+        String errorMessage = null;
+        try {
+            SendSmsResponse sendSmsResponse = sendSms(basicMessage.getMobileNumber(), basicMessage.getTemplateCode(), basicMessage.getVariableParams());
+            if (sendSmsResponse.getCode() != null) {
+                basicMessage.setSendStatus(sendSmsResponse.getCode());
+                basicMessage.setSendResult(sendSmsResponse.getMessage());
+            } else {
+                throw ExceptionResultEnum.ERROR.exception(sendSmsResponse.getMessage());
+            }
+        } catch (Exception e) {
+            errorMessage = e.getMessage();
+        } finally {
+            // 重试次数+1
+            basicMessage.setResendCount(basicMessage.getResendCount() + 1);
+            // 经过处理的新字段
+            if (errorMessage != null && errorMessage.length() > 0) {
+                basicMessage.setSendStatus("SYSTEM_ERROR");
+                basicMessage.setSendResult(errorMessage);
             }
+            this.updateById(basicMessage);
         }
     }
 

+ 5 - 1
distributed-print-task/src/main/java/com/qmth/distributed/print/task/enums/JobEnum.java

@@ -25,7 +25,11 @@ public enum JobEnum {
 
     SMS_NOTICE_TASK_OVERDUE_JOB("任务逾期提醒定时任务"),
 
-    SMS_NOTICE_TASK_OVERDUE_JOB_GROUP("任务逾期提醒定时任务job组");
+    SMS_NOTICE_TASK_OVERDUE_JOB_GROUP("任务逾期提醒定时任务job组"),
+
+    SMS_NOTICE_TASK_RESEND_JOB("短信发送失败重发定时任务"),
+
+    SMS_NOTICE_TASK_RESEND_JOB_GROUP("短信发送失败重发定时任务job组");
 
     private String title;
 

+ 10 - 1
distributed-print/src/main/java/com/qmth/distributed/print/start/StartRunning.java

@@ -4,6 +4,7 @@ import com.qmth.distributed.print.business.service.OrgCenterDataDisposeService;
 import com.qmth.distributed.print.business.service.TBTaskService;
 import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.task.enums.JobEnum;
+import com.qmth.distributed.print.task.job.ResendSmsJob;
 import com.qmth.distributed.print.task.job.ResetCreatePdfJob;
 import com.qmth.distributed.print.task.job.TimedSyncSchoolJob;
 import com.qmth.distributed.print.task.service.QuartzService;
@@ -73,9 +74,17 @@ public class StartRunning implements CommandLineRunner {
 //        orverdueJobMap.computeIfAbsent("name", v -> SendSmsOverdueJob.class.getName());
 //        quartzService.deleteJob(JobEnum.SMS_NOTICE_TASK_OVERDUE_JOB.name(), JobEnum.SMS_NOTICE_TASK_OVERDUE_JOB_GROUP.name());
 //        // 每天9点定时任务
-//        quartzService.addJob(SendSmsOverdueJob.class, JobEnum.SMS_NOTICE_TASK_OVERDUE_JOB.name(), JobEnum.SMS_NOTICE_TASK_OVERDUE_JOB_GROUP.name(), "0 */5 * * * ?", orverdueJobMap);
+//        quartzService.addJob(SendSmsOverdueJob.class, JobEnum.SMS_NOTICE_TASK_OVERDUE_JOB.name(), JobEnum.SMS_NOTICE_TASK_OVERDUE_JOB_GROUP.name(), "0 0 9 * * ?", orverdueJobMap);
 //        log.info("增加任务逾期提醒定时任务 end");
 
+//        log.info("增加短信发送失败重发定时任务 start");
+//        Map rensendJobMap = new HashMap();
+//        rensendJobMap.computeIfAbsent("name", v -> ResendSmsJob.class.getName());
+//        quartzService.deleteJob(JobEnum.SMS_NOTICE_TASK_RESEND_JOB.name(), JobEnum.SMS_NOTICE_TASK_RESEND_JOB_GROUP.name());
+//        // 每隔1小时定时任务
+//        quartzService.addJob(ResendSmsJob.class, JobEnum.SMS_NOTICE_TASK_RESEND_JOB.name(), JobEnum.SMS_NOTICE_TASK_RESEND_JOB_GROUP.name(), "0 */30 * * * ?", rensendJobMap);
+//        log.info("增加短信发送失败重发定时任务 end");
+
         log.info("服务器启动时执行 end");
     }
 }