diff --git a/manager/src/main/java/com/usthe/manager/component/alerter/DispatcherAlarm.java b/manager/src/main/java/com/usthe/manager/component/alerter/DispatcherAlarm.java
index 9067cf4a818..30df98a0f3f 100644
--- a/manager/src/main/java/com/usthe/manager/component/alerter/DispatcherAlarm.java
+++ b/manager/src/main/java/com/usthe/manager/component/alerter/DispatcherAlarm.java
@@ -53,6 +53,25 @@ public void afterPropertiesSet() throws Exception {
         }
     }
 
+    /**
+     * send alert msg to receiver
+     * @param receiver receiver
+     * @param alert alert msg
+     * @return send success or failed
+     */
+    public boolean sendNoticeMsg(NoticeReceiver receiver, Alert alert){
+        if(receiver == null || receiver.getType() == null){
+            log.warn("DispatcherAlarm-sendNoticeMsg params is empty alert:[{}], receiver:[{}]", alert, receiver);
+            return false;
+        }
+        byte type = receiver.getType();
+        if (alertNotifyHandlerMap.containsKey(type)) {
+            alertNotifyHandlerMap.get(type).send(receiver, alert);
+            return true;
+        }
+        return false;
+    }
+
     private List<NoticeReceiver> matchReceiverByNoticeRules(Alert alert) {
         // todo use cache 使用缓存
         return noticeConfigService.getReceiverFilterRule(alert);
@@ -82,13 +101,9 @@ private void sendNotify(Alert alert) {
             List<NoticeReceiver> receivers = matchReceiverByNoticeRules(alert);
             // todo Send notification here temporarily single thread     发送通知这里暂时单线程
             for (NoticeReceiver receiver : receivers) {
-                byte type = receiver.getType();
-                if (alertNotifyHandlerMap.containsKey(type)) {
-                    alertNotifyHandlerMap.get(type).send(receiver, alert);
-                }
-                // 暂未支持的通知类型
+                sendNoticeMsg(receiver, alert);
             }
         }
-
     }
+
 }
diff --git a/manager/src/main/java/com/usthe/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java b/manager/src/main/java/com/usthe/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java
index d68eef1a9b6..89e40cf1ba8 100644
--- a/manager/src/main/java/com/usthe/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java
+++ b/manager/src/main/java/com/usthe/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java
@@ -4,6 +4,7 @@
 import com.usthe.common.entity.manager.NoticeReceiver;
 import com.usthe.manager.component.alerter.AlertNotifyHandler;
 import com.usthe.manager.service.MailService;
+import com.usthe.manager.support.exception.AlertNoticeException;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
@@ -46,6 +47,7 @@ public void send(NoticeReceiver receiver, Alert alert) {
             javaMailSender.send(mimeMessage);
         } catch (Exception e) {
             log.error("[Email Alert] Exception,Exception information={}", e.getMessage());
+            throw new AlertNoticeException("[Email Alert] failed: " + e.getMessage());
         }
     }
 
diff --git a/manager/src/main/java/com/usthe/manager/controller/NoticeConfigController.java b/manager/src/main/java/com/usthe/manager/controller/NoticeConfigController.java
index 0d067494f6a..c3689066df2 100644
--- a/manager/src/main/java/com/usthe/manager/controller/NoticeConfigController.java
+++ b/manager/src/main/java/com/usthe/manager/controller/NoticeConfigController.java
@@ -136,4 +136,12 @@ public ResponseEntity<Message<List<NoticeRule>>> getRules(
         return ResponseEntity.ok(message);
     }
 
+
+    @PostMapping(path = "/receiver/send-test-msg")
+    @ApiOperation(value = "Send test msg to receiver", notes = "给指定接收人发送测试消息")
+    public ResponseEntity<Message<Boolean>> sendTestMsg(@Valid @RequestBody NoticeReceiver noticeReceiver) {
+        boolean sendFlag = noticeConfigService.sendTestMsg(noticeReceiver);
+        return ResponseEntity.ok(new Message<>(sendFlag));
+    }
+
 }
diff --git a/manager/src/main/java/com/usthe/manager/service/NoticeConfigService.java b/manager/src/main/java/com/usthe/manager/service/NoticeConfigService.java
index 99db2c65a4b..2f3e9002005 100644
--- a/manager/src/main/java/com/usthe/manager/service/NoticeConfigService.java
+++ b/manager/src/main/java/com/usthe/manager/service/NoticeConfigService.java
@@ -108,4 +108,12 @@ public interface NoticeConfigService {
      * @return Notification Rule Entity    通知规则实体
      */
     NoticeRule getNoticeRulesById(Long ruleId);
+
+    /**
+     * alert Send test message
+     * 告警 发送测试消息
+     * @param noticeReceiver recipient information  接收人信息
+     * @return true send success | false send fail
+     */
+    boolean sendTestMsg(NoticeReceiver noticeReceiver);
 }
diff --git a/manager/src/main/java/com/usthe/manager/service/impl/MailServiceImpl.java b/manager/src/main/java/com/usthe/manager/service/impl/MailServiceImpl.java
index 5cbaad5a5e8..c101de51ef6 100644
--- a/manager/src/main/java/com/usthe/manager/service/impl/MailServiceImpl.java
+++ b/manager/src/main/java/com/usthe/manager/service/impl/MailServiceImpl.java
@@ -31,8 +31,12 @@ public class MailServiceImpl implements MailService {
 
     @Override
     public String buildAlertHtmlTemplate(final Alert alert) {
-        String monitorId = alert.getTags().get(CommonConstants.TAG_MONITOR_ID);
-        String monitorName = alert.getTags().get(CommonConstants.TAG_MONITOR_NAME);
+        String monitorId = null;
+        String monitorName = null;
+        if (alert.getTags() != null) {
+            monitorId = alert.getTags().get(CommonConstants.TAG_MONITOR_ID);
+            monitorName = alert.getTags().get(CommonConstants.TAG_MONITOR_NAME);
+        }
         monitorId = monitorId == null? "External alarm, no ID" : monitorId;
         monitorName = monitorName == null? "External alarm, no Name" : monitorName;
         // Introduce thymeleaf context parameters to render pages
diff --git a/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java b/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java
index 604f15ea877..491fca8082d 100644
--- a/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java
+++ b/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java
@@ -3,6 +3,8 @@
 import com.google.common.collect.MapDifference;
 import com.google.common.collect.Maps;
 import com.usthe.common.entity.alerter.Alert;
+import com.usthe.common.util.CommonConstants;
+import com.usthe.manager.component.alerter.DispatcherAlarm;
 import com.usthe.manager.dao.NoticeReceiverDao;
 import com.usthe.manager.dao.NoticeRuleDao;
 import com.usthe.common.entity.manager.NoticeReceiver;
@@ -10,6 +12,7 @@
 import com.usthe.manager.service.NoticeConfigService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -30,12 +33,20 @@
 @Slf4j
 public class NoticeConfigServiceImpl implements NoticeConfigService {
 
+    private static final String ALERT_TEST_TARGET = "Test Target";
+
+    private static final String ALERT_TEST_CONTENT = "test send msg! \n This is the test data. It is proved that it can be received successfully";
+
     @Autowired
     private NoticeReceiverDao noticeReceiverDao;
 
     @Autowired
     private NoticeRuleDao noticeRuleDao;
 
+    @Autowired
+    @Lazy
+    private DispatcherAlarm dispatcherAlarm;
+
     @Override
     public List<NoticeReceiver> getNoticeReceivers(Specification<NoticeReceiver> specification) {
         return noticeReceiverDao.findAll(specification);
@@ -50,6 +61,14 @@ public List<NoticeRule> getNoticeRules(Specification<NoticeRule> specification)
     public void addReceiver(NoticeReceiver noticeReceiver) {
         noticeReceiverDao.save(noticeReceiver);
     }
+    @Override
+    public boolean sendTestMsg(NoticeReceiver noticeReceiver) {
+        Alert alert = new Alert();
+        alert.setContent(CommonConstants.TEST_SEND_MSG);
+        alert.setId(0L);
+        return dispatcherAlarm.sendNoticeMsg(noticeReceiver, alert);
+    }
+
 
     @Override
     public void editReceiver(NoticeReceiver noticeReceiver) {
@@ -115,4 +134,13 @@ public NoticeReceiver getReceiverById(Long receiverId) {
     public NoticeRule getNoticeRulesById(Long ruleId) {
         return noticeRuleDao.getOne(ruleId);
     }
+
+    @Override
+    public boolean sendTestMsg(NoticeReceiver noticeReceiver) {
+        Alert alert = new Alert();
+        alert.setTarget(ALERT_TEST_TARGET);
+        alert.setContent(ALERT_TEST_CONTENT);
+        alert.setPriority(CommonConstants.ALERT_PRIORITY_CODE_CRITICAL);
+        return dispatcherAlarm.sendNoticeMsg(noticeReceiver, alert);
+    }
 }
diff --git a/manager/src/main/java/com/usthe/manager/support/GlobalExceptionHandler.java b/manager/src/main/java/com/usthe/manager/support/GlobalExceptionHandler.java
index db23f1bb727..1442c8950f5 100644
--- a/manager/src/main/java/com/usthe/manager/support/GlobalExceptionHandler.java
+++ b/manager/src/main/java/com/usthe/manager/support/GlobalExceptionHandler.java
@@ -1,6 +1,7 @@
 package com.usthe.manager.support;
 
 import com.usthe.common.entity.dto.Message;
+import com.usthe.manager.support.exception.AlertNoticeException;
 import com.usthe.manager.support.exception.MonitorDatabaseException;
 import com.usthe.manager.support.exception.MonitorDetectException;
 import lombok.extern.slf4j.Slf4j;
@@ -18,9 +19,7 @@
 
 import java.lang.reflect.Field;
 
-import static com.usthe.common.util.CommonConstants.DETECT_FAILED_CODE;
-import static com.usthe.common.util.CommonConstants.MONITOR_CONFLICT_CODE;
-import static com.usthe.common.util.CommonConstants.PARAM_INVALID_CODE;
+import static com.usthe.common.util.CommonConstants.*;
 
 /**
  * controller exception handler
@@ -82,6 +81,13 @@ ResponseEntity<Message<Void>> handleIllegalArgumentException(IllegalArgumentExce
         return ResponseEntity.ok(message);
     }
 
+    @ExceptionHandler(AlertNoticeException.class)
+    @ResponseBody
+    ResponseEntity<Message<Void>> handleAlertNoticeException(AlertNoticeException noticeException) {
+        Message<Void> message = Message.<Void>builder().msg(noticeException.getMessage()).code(FAIL_CODE).build();
+        return ResponseEntity.ok(message);
+    }
+
     /**
      * 处理请求参数错误的失败, 请求参数json映射body时出错
      * @param exception 参数映射body异常
diff --git a/manager/src/main/java/com/usthe/manager/support/exception/AlertNoticeException.java b/manager/src/main/java/com/usthe/manager/support/exception/AlertNoticeException.java
new file mode 100644
index 00000000000..b083fee31bd
--- /dev/null
+++ b/manager/src/main/java/com/usthe/manager/support/exception/AlertNoticeException.java
@@ -0,0 +1,13 @@
+package com.usthe.manager.support.exception;
+
+/**
+ * alert notice send failed
+ * 告警通知发送异常
+ * @author tom
+ * @date 2022/5/8 17:59
+ */
+public class AlertNoticeException extends RuntimeException {
+    public AlertNoticeException(String message) {
+        super(message);
+    }
+}
diff --git a/web-app/src/app/routes/alert/alert-notice/alert-notice.component.html b/web-app/src/app/routes/alert/alert-notice/alert-notice.component.html
index 20580b8c8c8..c8d0568cd1a 100644
--- a/web-app/src/app/routes/alert/alert-notice/alert-notice.component.html
+++ b/web-app/src/app/routes/alert/alert-notice/alert-notice.component.html
@@ -285,6 +285,14 @@
           <input [(ngModel)]="receiver.wechatId" nz-input [required]="receiver.type === 6" name="wechatId" type="text" />
         </nz-form-control>
       </nz-form-item>
+      <nz-form-item>
+        <nz-form-control [nzOffset]="7" [nzSpan]="12">
+          <button nz-button nzDanger nzType="primary" [nzLoading]="isSendTestButtonLoading" (click)="onSendAlertTestMsg()">
+            <i nz-icon nzType="send" nzTheme="outline"></i>
+            {{ 'alert.notice.send-test' | i18n }}
+          </button>
+        </nz-form-control>
+      </nz-form-item>
     </form>
   </div>
 </nz-modal>
diff --git a/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts b/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts
index cf6d6c5c6d7..5448695e47c 100644
--- a/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts
+++ b/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts
@@ -10,7 +10,6 @@ import { NoticeRule } from '../../../pojo/NoticeRule';
 import { NoticeReceiverService } from '../../../service/notice-receiver.service';
 import { NoticeRuleService } from '../../../service/notice-rule.service';
 import { TagService } from '../../../service/tag.service';
-import { Tag } from '../../../pojo/Tag';
 
 @Component({
   selector: 'app-alert-notice',
@@ -154,6 +153,7 @@ export class AlertNoticeComponent implements OnInit {
   isManageReceiverModalVisible: boolean = false;
   isManageReceiverModalAdd: boolean = true;
   isManageReceiverModalOkLoading: boolean = false;
+  isSendTestButtonLoading: boolean = false;
   receiver!: NoticeReceiver;
 
   onNewNoticeReceiver() {
@@ -167,6 +167,32 @@ export class AlertNoticeComponent implements OnInit {
     this.isManageReceiverModalAdd = false;
   }
 
+  onSendAlertTestMsg() {
+    this.isSendTestButtonLoading = true;
+    const sendReq$ = this.noticeReceiverSvc
+      .sendAlertMsgToReceiver(this.receiver)
+      .pipe(
+        finalize(() => {
+          sendReq$.unsubscribe();
+          this.isSendTestButtonLoading = false;
+        })
+      )
+      .subscribe(
+        message => {
+          if (message.code === 0) {
+            this.isSendTestButtonLoading = false;
+            this.notifySvc.success(this.i18nSvc.fanyi('alert.notice.send-test.notify.success'), '');
+          } else {
+            this.notifySvc.error(this.i18nSvc.fanyi('alert.notice.send-test.notify.failed'), message.msg);
+          }
+        },
+        error => {
+          this.isSendTestButtonLoading = false;
+          this.notifySvc.error(this.i18nSvc.fanyi('alert.notice.send-test.notify.failed'), error.msg);
+        }
+      );
+  }
+
   onManageReceiverModalCancel() {
     this.isManageReceiverModalVisible = false;
   }
@@ -192,6 +218,7 @@ export class AlertNoticeComponent implements OnInit {
             }
           },
           error => {
+            this.isManageReceiverModalVisible = false;
             this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), error.msg);
           }
         );
@@ -215,6 +242,7 @@ export class AlertNoticeComponent implements OnInit {
             }
           },
           error => {
+            this.isManageReceiverModalVisible = false;
             this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), error.msg);
           }
         );
diff --git a/web-app/src/app/service/notice-receiver.service.ts b/web-app/src/app/service/notice-receiver.service.ts
index be928997499..9dbb8d353e6 100644
--- a/web-app/src/app/service/notice-receiver.service.ts
+++ b/web-app/src/app/service/notice-receiver.service.ts
@@ -7,6 +7,7 @@ import { NoticeReceiver } from '../pojo/NoticeReceiver';
 
 const notice_receiver_uri = '/notice/receiver';
 const notice_receivers_uri = '/notice/receivers';
+const notice_receiver_send_test_msg_uri = '/notice/receiver/send-test-msg';
 
 @Injectable({
   providedIn: 'root'
@@ -21,6 +22,7 @@ export class NoticeReceiverService {
   public editReceiver(body: NoticeReceiver): Observable<Message<any>> {
     return this.http.put<Message<any>>(notice_receiver_uri, body);
   }
+
   public deleteReceiver(receiverId: number): Observable<Message<any>> {
     return this.http.delete<Message<any>>(`${notice_receiver_uri}/${receiverId}`);
   }
@@ -28,4 +30,8 @@ export class NoticeReceiverService {
   public getReceivers(): Observable<Message<NoticeReceiver[]>> {
     return this.http.get<Message<NoticeReceiver[]>>(notice_receivers_uri);
   }
+
+  public sendAlertMsgToReceiver(body: NoticeReceiver): Observable<Message<any>> {
+    return this.http.post<Message<any>>(notice_receiver_send_test_msg_uri, body);
+  }
 }
diff --git a/web-app/src/assets/i18n/en-US.json b/web-app/src/assets/i18n/en-US.json
index b3ae69fb433..303e98c92bc 100644
--- a/web-app/src/assets/i18n/en-US.json
+++ b/web-app/src/assets/i18n/en-US.json
@@ -176,6 +176,9 @@
   "alert.notice.rule.enable": "Enable",
   "alert.notice.rule.tag": "Tag Filter",
   "alert.notice.rule.priority": "Priority Filter",
+  "alert.notice.send-test": "Send Alert Test Msg",
+  "alert.notice.send-test.notify.success": "Send Alert Test Success!",
+  "alert.notice.send-test.notify.failed": "Send Alert Test Failed!",
   "dashboard.alerts.title": "Recently Alerts List",
   "dashboard.alerts.title-no": "Recently Pending Alerts",
   "dashboard.alerts.no": "No Pending Alerts",
diff --git a/web-app/src/assets/i18n/zh-CN.json b/web-app/src/assets/i18n/zh-CN.json
index 52c797abfcc..e5ede63bdac 100644
--- a/web-app/src/assets/i18n/zh-CN.json
+++ b/web-app/src/assets/i18n/zh-CN.json
@@ -176,6 +176,9 @@
   "alert.notice.rule.enable": "是否启用",
   "alert.notice.rule.tag": "标签过滤",
   "alert.notice.rule.priority": "级别过滤",
+  "alert.notice.send-test": "发送告警测试",
+  "alert.notice.send-test.notify.success": "触发告警测试成功!",
+  "alert.notice.send-test.notify.failed": "触发告警测试失败!",
   "dashboard.alerts.title": "最近告警列表",
   "dashboard.alerts.title-no": "最近未处理告警",
   "dashboard.alerts.no": "暂无未处理告警",
diff --git a/web-app/src/assets/i18n/zh-TW.json b/web-app/src/assets/i18n/zh-TW.json
index 80a627aa03e..3eccf5eb0e2 100644
--- a/web-app/src/assets/i18n/zh-TW.json
+++ b/web-app/src/assets/i18n/zh-TW.json
@@ -176,6 +176,9 @@
   "alert.notice.rule.enable": "是否啓用",
   "alert.notice.rule.tag": "標簽過濾",
   "alert.notice.rule.priority": "級別過濾",
+  "alert.notice.send-test": "發送告警測試",
+  "alert.notice.send-test.notify.success": "觸發告警測試成功!",
+  "alert.notice.send-test.notify.failed": "觸發告警測試失敗!",
   "dashboard.alerts.title": "最近告警列表",
   "dashboard.alerts.title-no": "最近未處理告警",
   "dashboard.alerts.no": "暫無未處理告警",