Browse Source

添加定时器处理同步失败问题

wangmh 7 năm trước cách đây
mục cha
commit
dbe75c1714

+ 3 - 21
sso-server/src/main/java/com/uas/sso/controller/BaseController.java

@@ -5,11 +5,11 @@ import com.uas.message.mail.service.MailService;
 import com.uas.message.sms.service.SmsService;
 import com.uas.sso.SSOConfig;
 import com.uas.sso.core.Const;
-import com.uas.sso.entity.Setting;
 import com.uas.sso.entity.Token;
 import com.uas.sso.exception.VisibleError;
 import com.uas.sso.service.SettingService;
 import com.uas.sso.service.TokenService;
+import com.uas.sso.util.MessageUtils;
 import com.uas.sso.util.StringUtil;
 import com.uas.sso.util.encry.HmacUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -305,16 +305,7 @@ public class BaseController {
      * @param data 发送短信适配数据,按顺序添加
      */
     protected void sendSms(String templateId, String mobile, Object... data) {
-        try {
-            if (!StringUtils.isEmpty(mobile)) {
-                Setting smsTplId = settingService.findOne(templateId);
-                if (!StringUtils.isEmpty(smsTplId)) {
-                    smsService.send(smsTplId.getValue(), mobile, data);
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+        MessageUtils.sendSms(templateId, mobile, data);
     }
 
     /**
@@ -324,16 +315,7 @@ public class BaseController {
      * @param data 发送邮件适配数据,以键值对的形式添加
      */
     protected void sendEmail(String templateId, String email, Map<String, Object> data) {
-        try {
-            if (!StringUtils.isEmpty(email)) {
-                Setting mailTplId = settingService.findOne(templateId);
-                if (!StringUtils.isEmpty(mailTplId)) {
-                    mailService.send(mailTplId.getValue(), email, data);
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+        MessageUtils.sendEmail(templateId, email, data);
     }
 
     protected String[] getFrontAllUrl() {

+ 73 - 0
sso-server/src/main/java/com/uas/sso/entity/SyncFailInfo.java

@@ -0,0 +1,73 @@
+package com.uas.sso.entity;
+
+import java.util.Map;
+
+/**
+ * @author wangmh
+ * @create 2018-06-05 15:51
+ * @desc 同步失败信息
+ **/
+public class SyncFailInfo {
+
+    /**
+     * 日志Id
+     */
+    private long logId;
+
+    /**
+     * 提交信息
+     */
+    private Map<String, Object> formData;
+
+    /**
+     * 同步接口
+     */
+    private String syncUrl;
+
+    /**
+     * 同步应用
+     */
+    private String toApp;
+
+    public SyncFailInfo() {
+    }
+
+    public SyncFailInfo(long logId, Map<String, Object> formData, String syncUrl, String toApp) {
+        this.logId = logId;
+        this.formData = formData;
+        this.syncUrl = syncUrl;
+        this.toApp = toApp;
+    }
+
+    public long getLogId() {
+        return logId;
+    }
+
+    public void setLogId(long logId) {
+        this.logId = logId;
+    }
+
+    public Map<String, Object> getFormData() {
+        return formData;
+    }
+
+    public void setFormData(Map<String, Object> formData) {
+        this.formData = formData;
+    }
+
+    public String getSyncUrl() {
+        return syncUrl;
+    }
+
+    public void setSyncUrl(String syncUrl) {
+        this.syncUrl = syncUrl;
+    }
+
+    public String getToApp() {
+        return toApp;
+    }
+
+    public void setToApp(String toApp) {
+        this.toApp = toApp;
+    }
+}

+ 3 - 2
sso-server/src/main/java/com/uas/sso/logging/Logger.java

@@ -24,9 +24,10 @@ public abstract class Logger<T extends BaseLog> {
      * 保存日志
      * @param logger 日志
      */
-    protected void log(T logger) {
+    protected T log(T logger) {
         if(this.logService != null) {
-            this.logService.save(logger);
+            return this.logService.save(logger);
         }
+        return null;
     }
 }

+ 8 - 8
sso-server/src/main/java/com/uas/sso/logging/SyncBufferedLogger.java

@@ -21,19 +21,19 @@ public class SyncBufferedLogger extends Logger<SyncLog> {
         super(ContextUtils.getBean(SyncLogService.class));
     }
 
-    public void error(String appId, String msg, String msgDetail, String returnMsg) {
-        log(new SyncLog(appId, msg, msgDetail, Level.ERROR.getValue(), returnMsg));
+    public SyncLog error(String appId, String msg, String msgDetail, String returnMsg) {
+        return log(new SyncLog(appId, msg, msgDetail, Level.ERROR.getValue(), returnMsg));
     }
 
-    public void info(String appId, String msg, String msgDetail, String returnMsg) {
-        log(new SyncLog(appId, msg, msgDetail, Level.INFO.getValue(), returnMsg));
+    public SyncLog info(String appId, String msg, String msgDetail, String returnMsg) {
+        return log(new SyncLog(appId, msg, msgDetail, Level.INFO.getValue(), returnMsg));
     }
 
-    public void info(String appId, String msg, String msgDetail) {
-        log(new SyncLog(appId, msg, msgDetail, Level.INFO.getValue()));
+    public SyncLog info(String appId, String msg, String msgDetail) {
+        return info(appId, msg, msgDetail, null);
     }
 
-    public void info(String appId, User user) {
-        info(appId, "同步用户信息", JSON.toJSONString(user));
+    public SyncLog info(String appId, User user) {
+        return info(appId, "同步用户信息", JSON.toJSONString(user));
     }
 }

+ 20 - 17
sso-server/src/main/java/com/uas/sso/service/impl/UserServiceImpl.java

@@ -16,6 +16,7 @@ import com.uas.sso.logging.LoggerManager;
 import com.uas.sso.logging.SyncBufferedLogger;
 import com.uas.sso.logging.UserBufferedLogger;
 import com.uas.sso.service.*;
+import com.uas.sso.support.SyncFail;
 import com.uas.sso.util.AccountTypeUtils;
 import com.uas.sso.util.ExecuteUtils;
 import com.uas.sso.util.PasswordLevelUtils;
@@ -62,9 +63,9 @@ public class UserServiceImpl implements UserService {
     @Autowired
     private UserQuestionService userQuestionService;
 
-    private UserBufferedLogger userLog = LoggerManager.getLogger(UserBufferedLogger.class);
+    private UserBufferedLogger userLogger = LoggerManager.getLogger(UserBufferedLogger.class);
 
-    private SyncBufferedLogger syncLog = LoggerManager.getLogger(SyncBufferedLogger.class);
+    private SyncBufferedLogger syncLogger = LoggerManager.getLogger(SyncBufferedLogger.class);
 
     @Override
     public User findByMobile(String mobile, String mobileArea) {
@@ -125,7 +126,7 @@ public class UserServiceImpl implements UserService {
         user.getUserRecord().setUserUU(user.getUserUU());
 
         userDao.save(user);
-        userLog.info(user, Type.UPDATE_REGISTER.getValue());
+        userLogger.info(user, Type.UPDATE_REGISTER.getValue());
 
         // 同步到各个应用
         return syncUserInfo(user.getUserUU(), noEncryPwd, "个人注册");
@@ -311,7 +312,7 @@ public class UserServiceImpl implements UserService {
         userDao.save(user);
 
         // 保存日志
-        userLog.info(user, Type.UPDATE_MOBILE.getValue());
+        userLogger.info(user, Type.UPDATE_MOBILE.getValue());
 
         // 同步到各个应用
         syncUserInfo(user.getUserUU(), null, "修改手机号");
@@ -333,7 +334,7 @@ public class UserServiceImpl implements UserService {
         userDao.save(user);
 
         // 保存日志
-        userLog.info(user, Type.UPDATE_EMAIL.getValue());
+        userLogger.info(user, Type.UPDATE_EMAIL.getValue());
 
         // 同步信息到各应用
         syncUserInfo(user.getUserUU(), null, "修改邮箱");
@@ -375,7 +376,7 @@ public class UserServiceImpl implements UserService {
         syncUserBindSpace(userUU, spaceUU);
 
         // 保存日志
-        userLog.info(user, Type.BIND_USERSPACE.getValue()+spaceUU);
+        userLogger.info(user, Type.BIND_USERSPACE.getValue()+spaceUU);
     }
 
     /**
@@ -421,12 +422,13 @@ public class UserServiceImpl implements UserService {
                     try {
                         res = HttpUtil.doPost(url, formData, 10000);
                         if (!res.isSuccess()) {
-                            syncLog.error(appId, "同步绑定信息失败", JSON.toJSONString(formData), res.getContent());
+                            SyncLog syncLog = syncLogger.error(appId, "同步绑定信息失败", JSON.toJSONString(formData), res.getContent());
+                            SyncFail.add(syncLog.getId(), formData, url, appId);
                         } else {
-                            syncLog.info(appId, "同步绑定信息成功", JSON.toJSONString(formData));
+                            syncLogger.info(appId, "同步绑定信息成功", JSON.toJSONString(formData));
                         }
                     } catch (Exception e) {
-                        syncLog.error(appId, "同步绑定信息失败", JSON.toJSONString(formData), e.getMessage());
+                        syncLogger.error(appId, "同步绑定信息失败", JSON.toJSONString(formData), e.getMessage());
                     }
                 }
                 return null;
@@ -460,7 +462,7 @@ public class UserServiceImpl implements UserService {
         syncUserUnbindSpace(userUU, spaceUU);
 
         // 保存日志
-        userLog.info(user, Type.UNBIND_USERSPACE.getValue()+spaceUU);
+        userLogger.info(user, Type.UNBIND_USERSPACE.getValue()+spaceUU);
     }
 
     @Override
@@ -487,7 +489,7 @@ public class UserServiceImpl implements UserService {
         // 保存并添加日志
         user = userDao.save(user);
         syncUserInfo(user, null, "修改密保");
-        userLog.info(user, Type.UPDATE_QUESTION.getValue(), JSON.toJSONString(user.getQuestions()));
+        userLogger.info(user, Type.UPDATE_QUESTION.getValue(), JSON.toJSONString(user.getQuestions()));
     }
 
     @Override
@@ -657,12 +659,13 @@ public class UserServiceImpl implements UserService {
                     try {
                         res = HttpUtil.doPost(url, formData, 10000);
                         if (!res.isSuccess()) {
-                            syncLog.error(appId, msg + ",同步用户信息失败", JSON.toJSONString(formData), res.getContent());
+                            SyncLog syncLog = syncLogger.error(appId, msg + ",同步用户信息失败", JSON.toJSONString(formData), res.getContent());
+                            SyncFail.add(syncLog.getId(), formData, url, appId);
                         } else {
-                            syncLog.info(appId, msg + ",同步用户信息成功", JSON.toJSONString(formData));
+                            syncLogger.info(appId, msg + ",同步用户信息成功", JSON.toJSONString(formData));
                         }
                     } catch (Exception e) {
-                        syncLog.error(appId, msg + ",同步用户信息失败", JSON.toJSONString(formData), e.getMessage());
+                        syncLogger.error(appId, msg + ",同步用户信息失败", JSON.toJSONString(formData), e.getMessage());
                     }
                 }
                 return null;
@@ -685,14 +688,14 @@ public class UserServiceImpl implements UserService {
             formData.put("mobile", user.getMobile());
             res = HttpUtil.doPost(url, formData, 10000);
             if (!res.isSuccess()) {
-                syncLog.error(appId, msg + ",同步用户信息失败", formData.toString(), res.getContent());
+                syncLogger.error(appId, msg + ",同步用户信息失败", formData.toString(), res.getContent());
                 throw new Exception(res.getContent());
             } else {
                 JSONObject obj = JSON.parseObject(res.getContent());
                 if (obj.getString("resultMsg") != null) {
-                    syncLog.error(appId, msg + ",同步用户信息失败", formData.toString(), res.getContent());
+                    syncLogger.error(appId, msg + ",同步用户信息失败", formData.toString(), res.getContent());
                 }
-                syncLog.info(appId, msg + ",同步用户信息成功", formData.toString(), res.getContent());
+                syncLogger.info(appId, msg + ",同步用户信息成功", formData.toString(), res.getContent());
                 return obj.getString("dialectUID");
             }
         }

+ 6 - 4
sso-server/src/main/java/com/uas/sso/service/impl/UserspaceServiceImpl.java

@@ -11,6 +11,7 @@ import com.uas.sso.exception.VisibleError;
 import com.uas.sso.logging.LoggerManager;
 import com.uas.sso.logging.SyncBufferedLogger;
 import com.uas.sso.service.*;
+import com.uas.sso.support.SyncFail;
 import com.uas.sso.util.ChineseUtils;
 import com.uas.sso.util.ExecuteUtils;
 import com.uas.sso.util.StringUtil;
@@ -51,7 +52,7 @@ public class UserspaceServiceImpl implements UserspaceService {
     @Autowired
     private PartnershipService partnershipService;
 
-    SyncBufferedLogger syncLog = LoggerManager.getLogger(SyncBufferedLogger.class);
+    SyncBufferedLogger syncLogger = LoggerManager.getLogger(SyncBufferedLogger.class);
 
     /**
      * 企业初始uu号
@@ -135,12 +136,13 @@ public class UserspaceServiceImpl implements UserspaceService {
                     try {
                         res = HttpUtil.doPost(url, formData, 10000);
                         if (!res.isSuccess()) {
-                            syncLog.error(appId, msg + ",同步企业信息失败", JSON.toJSONString(formData), res.getContent());
+                            SyncLog syncLog = syncLogger.error(appId, msg + ",同步企业信息失败", JSON.toJSONString(formData), res.getContent());
+                            SyncFail.add(syncLog.getId(), formData, url, appId);
                         } else {
-                            syncLog.info(appId, msg + ",同步企业信息成功", JSON.toJSONString(formData));
+                            syncLogger.info(appId, msg + ",同步企业信息成功", JSON.toJSONString(formData));
                         }
                     } catch (Exception e) {
-                        syncLog.error(appId, msg + ",同步企业信息失败", JSON.toJSONString(formData), e.getMessage());
+                        syncLogger.error(appId, msg + ",同步企业信息失败", JSON.toJSONString(formData), e.getMessage());
                     }
                 }
                 return null;

+ 33 - 0
sso-server/src/main/java/com/uas/sso/support/SyncFail.java

@@ -0,0 +1,33 @@
+package com.uas.sso.support;
+
+import com.uas.sso.entity.SyncFailInfo;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author wangmh
+ * @create 2018-06-05 16:00
+ * @desc 同步失败记录
+ **/
+public class SyncFail {
+
+    private static Set<SyncFailInfo> infos;
+
+    static {
+        infos = new HashSet<>();
+    }
+
+    public static void add(SyncFailInfo info) {
+        infos.add(info);
+    }
+
+    public static void add(long logId, Map<String, Object> formData, String syncUrl, String toApp) {
+        add(new SyncFailInfo(logId, formData, syncUrl, toApp));
+    }
+
+    public static Set<SyncFailInfo> getInfos() {
+        return infos;
+    }
+}

+ 78 - 0
sso-server/src/main/java/com/uas/sso/timertask/SyncTimerTask.java

@@ -0,0 +1,78 @@
+package com.uas.sso.timertask;
+
+import com.uas.sso.common.util.HttpUtil;
+import com.uas.sso.entity.SyncFailInfo;
+import com.uas.sso.entity.SyncLog;
+import com.uas.sso.logging.LoggerManager;
+import com.uas.sso.logging.SyncBufferedLogger;
+import com.uas.sso.support.SyncFail;
+import com.uas.sso.util.ExecuteUtils;
+import com.uas.sso.util.MessageUtils;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.ui.ModelMap;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author wangmh
+ * @create 2018-06-05 15:02
+ * @desc 同步定时器
+ **/
+@Component
+public class SyncTimerTask {
+
+    private SyncBufferedLogger logger = LoggerManager.getLogger(SyncBufferedLogger.class);
+
+    private static final int TIME_RECONNECT = 5;
+
+    /**
+     * 30秒一次,查询并同步未同步成功数据
+     */
+    @Scheduled(cron = "0/30 * * * * *")
+    public void sync() {
+        Set<SyncFailInfo> infos = SyncFail.getInfos();
+        if (CollectionUtils.isEmpty(infos)) {
+            return;
+        }
+
+        for (final SyncFailInfo info : infos) {
+            ExecuteUtils.asyncExecute(new Runnable() {
+                @Override
+                public void run() {
+                    // 循环同步,如果成功则返回
+                    List<Long> logIds = new ArrayList<Long>();
+                    SyncLog syncLog;
+                    for (int i=1;i<=TIME_RECONNECT;i++) {
+                        try {
+                            HttpUtil.ResponseWrap res = HttpUtil.doPost(info.getSyncUrl(), info.getFormData());
+                            if (res.isSuccess()) {
+                                String msg = String.format("%d,定时器同步第(%d)次同步成功", info.getLogId(), i);
+                                logger.info(info.getToApp(), msg, info.getFormData().toString());
+                                return;
+                            } else {
+                                String msg = String.format("%d,定时器同步第(%d)次同步失败", info.getLogId(), i);
+                                syncLog = logger.error(info.getToApp(), msg, info.getFormData().toString(), res.getContent());
+                                logIds.add(syncLog.getId());
+                            }
+                        } catch (Exception e) {
+                            String msg = String.format("%d,定时器同步第(%d)次同步失败", info.getLogId(), i);
+                            syncLog = logger.error(info.getToApp(), msg, info.getFormData().toString(), e.getMessage());
+                            logIds.add(syncLog.getId());
+                        }
+                    }
+
+                    // 循环同步失败后,发送邮件通知
+                    String email = "645295708@qq.com";
+                    ModelMap data = new ModelMap();
+                    data.addAttribute("ids", logIds).addAttribute("url", info.getSyncUrl());
+                    MessageUtils.sendEmail("templateForSendEmailAfterSyncFail", email, data);
+                }
+            });
+        }
+        infos.clear();
+    }
+}

+ 75 - 0
sso-server/src/main/java/com/uas/sso/util/MessageUtils.java

@@ -0,0 +1,75 @@
+package com.uas.sso.util;
+
+import com.uas.message.mail.service.MailService;
+import com.uas.message.sms.service.SmsService;
+import com.uas.sso.entity.Setting;
+import com.uas.sso.service.SettingService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.Map;
+
+/**
+ * @author wangmh
+ * @create 2018-06-05 17:17
+ * @desc 消息工具类
+ **/
+@Component
+public class MessageUtils {
+
+    @Autowired
+    private SmsService smsService;
+
+    @Autowired
+    private MailService mailService;
+
+    @Autowired
+    private SettingService settingService;
+
+    private static MessageUtils messageUtils;
+
+    @PostConstruct
+    public void init() {
+        messageUtils = this;
+    }
+
+    /**
+     * 发送短信
+     * @param templateId 模板id
+     * @param mobile 手机号
+     * @param data 发送短信适配数据,按顺序添加
+     */
+    public static void sendSms(String templateId, String mobile, Object... data) {
+        try {
+            if (!StringUtils.isEmpty(mobile)) {
+                Setting smsTplId = messageUtils.settingService.findOne(templateId);
+                if (!StringUtils.isEmpty(smsTplId)) {
+                    messageUtils.smsService.send(smsTplId.getValue(), mobile, data);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 发送邮件
+     * @param templateId 模板id
+     * @param email 邮箱
+     * @param data 发送邮件适配数据,以键值对的形式添加
+     */
+    public static void sendEmail(String templateId, String email, Map<String, Object> data) {
+        try {
+            if (!StringUtils.isEmpty(email)) {
+                Setting mailTplId = messageUtils.settingService.findOne(templateId);
+                if (!StringUtils.isEmpty(mailTplId)) {
+                    messageUtils.mailService.send(mailTplId.getValue(), email, data);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}