最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java項(xiàng)目啟動(dòng)成功、失敗信息實(shí)時(shí)反饋提醒問題(郵件或者短信)

 更新時(shí)間:2024年06月12日 09:47:12   作者:程序猿楊鮑  
這篇文章主要介紹了Java項(xiàng)目啟動(dòng)成功、失敗信息實(shí)時(shí)反饋提醒問題(郵件或者短信),具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

在開發(fā)的流程中必須涉及的項(xiàng)目的部署發(fā)布,這個(gè)過程也肯定會有成功失敗,在不同的公司里采用的提醒方式不同。

在說明下面的方案前,需要首先說明一下基本應(yīng)用的場景。

場景說明

1、純后臺應(yīng)用,現(xiàn)在項(xiàng)目基本都是前后端分離,因?yàn)橐粋€(gè)前端服務(wù)可能會對應(yīng)多個(gè)后端服務(wù)的支持,隨著整個(gè)開發(fā)大環(huán)境的完善和技術(shù)的成熟,之前那種前后端耦合的應(yīng)用很少,這里不在做具體的考慮。

2、項(xiàng)目的基本架構(gòu)是Spring+Spring MVC+Mybatis,其實(shí)主要是Spring+Spring MVC,因?yàn)橄旅娴膶?shí)現(xiàn)方式在這種模式下模擬,其他環(huán)境可以根據(jù)這個(gè)模式仿照,但是照搬可能存在問題,因?yàn)楝F(xiàn)在很多公司都開始使用SpringBoot相關(guān)的前沿技術(shù)。

3、環(huán)境說明

  • 本地測試環(huán)境,就是IDEA的啟動(dòng)測試,不多說;
  • 開發(fā)測試環(huán)境,這個(gè)環(huán)境基本用來聯(lián)調(diào),開發(fā)人員發(fā)布項(xiàng)目使用的;
  • 測試環(huán)境,這個(gè)是測試人員來用,將開發(fā)的代碼拉到測試環(huán)境,進(jìn)行各種姿勢的測試;
  • 演示環(huán)境,這個(gè)環(huán)境看各個(gè)公司的定義可能不同,也就是上線前的最后一個(gè)環(huán)境,基本模擬線上環(huán)境,最終驗(yàn)證項(xiàng)目的完整性,有時(shí)候所說的灰度、冒煙測試都會在這個(gè)環(huán)境執(zhí)行;
  • 線上環(huán)境,不解釋。

4、下面的內(nèi)容數(shù)據(jù)自己歪歪,如果存在問題,歡迎提建議。

簡單實(shí)現(xiàn)的幾種方式

在項(xiàng)目中添加一個(gè)主頁,當(dāng)發(fā)布完成后,訪問該頁面是OK就表示發(fā)布成功,反之就是失敗,但是這樣存在很多問題,比如在線上環(huán)境,這個(gè)頁面可能就訪問不到(純后臺應(yīng)用可能不會提供這個(gè)訪問功能)。在本地測試和開發(fā)環(huán)境可以湊合使用。

定時(shí)任務(wù)請求項(xiàng)目,這個(gè)不僅能監(jiān)控到項(xiàng)目啟動(dòng)是否成功,也可以監(jiān)控服務(wù)器宕機(jī)問題,但是也存在問題,那就是要重新開一個(gè)項(xiàng)目,用于發(fā)送請求,另外當(dāng)項(xiàng)目啟動(dòng)的時(shí)候,剛好定時(shí)任務(wù)發(fā)起,此時(shí)是請求不通的,系統(tǒng)會誤報(bào)啟動(dòng)失敗或者宕機(jī),其實(shí)不是這樣。

日志掃描,通過對日志的分析查看日志中的異常,并做分析,給予開發(fā)或者維護(hù)人員一個(gè)通知,可以通過Python腳本等方式執(zhí)行,設(shè)計(jì)到整體項(xiàng)目架構(gòu)的問題,不做太多的討論,也不是這個(gè)博客的主要討論范疇,不做太多贅述。

項(xiàng)目中添加邏輯代碼,用于捕獲項(xiàng)目啟動(dòng)加載是否正常,從而判斷項(xiàng)目是否啟動(dòng)成功。(主要討論)

項(xiàng)目啟動(dòng)反饋提醒實(shí)現(xiàn)

web.xml文件中的配置

<servlet>
    <servlet-name>spring-dispatcher</servlet-name>
    <servlet-class>com.minuor.service.notice.LocalDispatcherServletDemo</servlet-class>
    <!-- 配置SpringMVC需要加載的配置文件 spring-xxx.xml -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-web.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>spring-dispatcher</servlet-name>
	<!--默認(rèn)匹配所有的請求 -->
	<url-pattern>/</url-pattern>
</servlet-mapping>

正常應(yīng)該配置spring默認(rèn)的DispatcherServlet,這里需要改為加載重新后的LocalDispatcherServletDemo。

LocalDispatcherServletDemo類代碼

package com.minuor.service.notice;

import com.minuor.common.utils.JavaMailSendUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.i18n.LocaleContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * @Author: Joker
 * @Date: 2018/3/19
 * @Desc: 重寫DispatcherServlet,做系統(tǒng)啟動(dòng)成功失敗監(jiān)控并通知
 */
@Slf4j
public class LocalDispatcherServletDemo extends DispatcherServlet {

    public LocalDispatcherServletDemo() {
        super();
    }

    public LocalDispatcherServletDemo(WebApplicationContext webApplicationContext) {
        super(webApplicationContext);
    }

    @Override
    protected WebApplicationContext initWebApplicationContext() {
        WebApplicationContext webApplicationContext;
        try {
            webApplicationContext = super.initWebApplicationContext();
            sendMsg(Boolean.TRUE);
            log.info(">>>>>>>webApplicationContext初始化成功~");
        } catch (Exception e) {
            sendMsg(Boolean.FALSE);
            webApplicationContext = new XmlWebApplicationContext();//設(shè)置臨時(shí)值,避免重復(fù)初始化
            log.info(">>>>>>>webApplicationContext初始化失敗~");
        }
        return webApplicationContext;
    }

    /**
     * 發(fā)送郵件
     *
     * @param flag
     */
    private void sendMsg(boolean flag) {
        try {
            JavaMailSendUtil sender = new JavaMailSendUtil();
            //成功失敗信息
            String result = "FAIL";
            if (flag) result = "SUCCESS";
            //模塊名
            String ip = InetAddress.getLocalHost().getHostAddress();
            String userDir = System.getProperty("user.dir");
            String tempStr = userDir.substring(0, userDir.indexOf(File.separator + "bin"));
            String userDirModel = tempStr.substring(tempStr.lastIndexOf(File.separator) + 1);
            //組裝并推送信息
            String mailTest = "發(fā)布系統(tǒng):" + "Minuor個(gè)人博客系統(tǒng)" + "<br/>" +
                    "發(fā)布環(huán)境:" + ip + "<br/>" +
                    "模塊名稱:" + userDirModel + "<br/>" +
                    "發(fā)布時(shí)間:" + new SimpleDateFormat("yyyyMMdd HH:mm:ss").format(new Date()) + "<br/>" +
                    "發(fā)布結(jié)果:" + result + "<br/>" +
                    "溫馨提示:" + "此郵件僅為系統(tǒng)發(fā)布通知郵件,請勿回復(fù)!";
            sender.sendEmail("個(gè)人博客系統(tǒng)發(fā)布結(jié)果提醒", mailTest, "xxxx@163.com");
        } catch (Exception e) {
            log.info(">>>>>個(gè)人博客系統(tǒng)發(fā)布結(jié)果預(yù)警郵件推送失??!異常信息:{}", e);
        }
    }

    @Override
    public void setDetectAllHandlerMappings(boolean detectAllHandlerMappings) {
        super.setDetectAllHandlerMappings(detectAllHandlerMappings);
    }

    @Override
    protected void initFrameworkServlet() throws ServletException {
        super.initFrameworkServlet();
    }

    @Override
    public void setDetectAllHandlerAdapters(boolean detectAllHandlerAdapters) {
        super.setDetectAllHandlerAdapters(detectAllHandlerAdapters);
    }

    @Override
    public void setDetectAllHandlerExceptionResolvers(boolean detectAllHandlerExceptionResolvers) {
        super.setDetectAllHandlerExceptionResolvers(detectAllHandlerExceptionResolvers);
    }

    @Override
    public void setDetectAllViewResolvers(boolean detectAllViewResolvers) {
        super.setDetectAllViewResolvers(detectAllViewResolvers);
    }

    @Override
    public void setThrowExceptionIfNoHandlerFound(boolean throwExceptionIfNoHandlerFound) {
        super.setThrowExceptionIfNoHandlerFound(throwExceptionIfNoHandlerFound);
    }

    @Override
    public void setCleanupAfterInclude(boolean cleanupAfterInclude) {
        super.setCleanupAfterInclude(cleanupAfterInclude);
    }

    @Override
    protected void onRefresh(ApplicationContext context) {
        super.onRefresh(context);
    }

    @Override
    protected void initStrategies(ApplicationContext context) {
        super.initStrategies(context);
    }

    @Override
    protected <T> T getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface) {
        return super.getDefaultStrategy(context, strategyInterface);
    }

    @Override
    protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
        return super.getDefaultStrategies(context, strategyInterface);
    }

    @Override
    protected Object createDefaultStrategy(ApplicationContext context, Class<?> clazz) {
        return super.createDefaultStrategy(context, clazz);
    }

    @Override
    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        super.doService(request, response);
    }

    @Override
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        super.doDispatch(request, response);
    }

    @Override
    protected LocaleContext buildLocaleContext(HttpServletRequest request) {
        return super.buildLocaleContext(request);
    }

    @Override
    protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
        return super.checkMultipart(request);
    }

    @Override
    protected void cleanupMultipart(HttpServletRequest request) {
        super.cleanupMultipart(request);
    }

    @Override
    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        return super.getHandler(request);
    }

    @Override
    protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception {
        super.noHandlerFound(request, response);
    }

    @Override
    protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
        return super.getHandlerAdapter(handler);
    }

    @Override
    protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        return super.processHandlerException(request, response, handler, ex);
    }

    @Override
    protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
        super.render(mv, request, response);
    }

    @Override
    protected String getDefaultViewName(HttpServletRequest request) throws Exception {
        return super.getDefaultViewName(request);
    }

    @Override
    protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale, HttpServletRequest request) throws Exception {
        return super.resolveViewName(viewName, model, locale, request);
    }
}

重新所有的方法,直接調(diào)用父類DispatcherServlet內(nèi)的邏輯,實(shí)際LocalDispatcherServletDemo中沒有具體的邏輯,只有構(gòu)造方法、initWebApplicationContext、sendMsg短信發(fā)送邏輯的修改和創(chuàng)建。

JavaMailSendUtil郵件發(fā)送邏輯代碼

package com.minuor.common.mail;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

/**
 * @Author: Joker
 * @Date: 2018/3/19
 * @Desc: 發(fā)送郵件服務(wù)
 */
@Slf4j
public class JavaMailSendUtil {
    /**
     * 發(fā)送郵件
     */
    public void sendEmail(String subject, String mailText, String rStr) {
        try {
            // 1.創(chuàng)建一個(gè)程序與郵件服務(wù)器會話對象 Session
            Properties props = new Properties();
            props.setProperty("mail.smtp.host", "smtp.163.com");
            props.setProperty("mail.smtp.port", "25");
            // 指定驗(yàn)證為true
            props.setProperty("mail.smtp.auth", "true");
            // 驗(yàn)證賬號及密碼,密碼需要是第三方授權(quán)碼
            Authenticator auth = new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(
                            "xxxx@163.com", "123456");
                }
            };
            Session session = Session.getInstance(props, auth);

            // 2.創(chuàng)建一個(gè)Message,它相當(dāng)于是郵件內(nèi)容
            Message message = new MimeMessage(session);
            // 設(shè)置發(fā)送者
            message.setFrom(new InternetAddress("xxxxx@163.com"));
            // 設(shè)置發(fā)送方式與接收者
            if (StringUtils.isBlank(rStr)) return;
            String[] rStrs = rStr.split(",");
            InternetAddress[] address = new InternetAddress[rStrs.length];
            int index = 0;
            for (String str : rStrs) {
                address[index] = new InternetAddress(str);
                index++;
            }
            message.setRecipients(MimeMessage.RecipientType.TO, address);
            // 設(shè)置主題
            message.setSubject(subject);
            // 設(shè)置內(nèi)容
            message.setContent(mailText, "text/html;charset=utf-8");
            // 3.創(chuàng)建 Transport用于將郵件發(fā)送
            Transport.send(message);
            log.info(">>>>>>>發(fā)送郵件成功<<<<<<<");
        } catch (Exception e) {
            log.error(">>>>>>>發(fā)送郵件異常:{}", e);
        }
    }
}

封裝的最簡單的發(fā)送方式,只為實(shí)現(xiàn)簡單的郵件推送功能。

具體說明

在重新initWebApplicationContext內(nèi),對調(diào)用父類的initWebApplicationContext方法加了異常捕捉,在catch捕捉中添加了郵件處理邏輯,也將異常吃點(diǎn)不再打印出來;

郵件推送分為兩個(gè)部分,一個(gè)是項(xiàng)目啟動(dòng)成功,一個(gè)是項(xiàng)目啟動(dòng)失敗,兩個(gè)部分都會給開發(fā)或者維護(hù)人員提供相應(yīng)的郵件提醒;

最主要的一點(diǎn),這里涉及到的郵件發(fā)送工具類,重寫類LocalDispatcherServletDemo都不能交給spring管理,因?yàn)樵趕pring加載失敗的時(shí)候,這些類對應(yīng)的bean是不能創(chuàng)建成功的,更不用說對象的注入以及具體邏輯的實(shí)現(xiàn)。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • idea2023.3安裝及配置詳細(xì)圖文教程

    idea2023.3安裝及配置詳細(xì)圖文教程

    IDEA全稱IntelliJ?IDEA,是Java語言對的集成開發(fā)環(huán)境,IDEA在業(yè)界被認(rèn)為是公認(rèn)最好的Java開發(fā)工具,這篇文章主要給大家介紹了關(guān)于idea2023.3安裝及配置的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • java并發(fā)編程專題(一)----線程基礎(chǔ)知識

    java并發(fā)編程專題(一)----線程基礎(chǔ)知識

    這篇文章主要介紹了java并發(fā)編程線程的基礎(chǔ)知識,文中講解非常詳細(xì),幫助大家更好的學(xué)習(xí)JAVA并發(fā)編程,感興趣想學(xué)習(xí)JAVA的可以了解下
    2020-06-06
  • Java線程池的拒絕策略實(shí)現(xiàn)詳解

    Java線程池的拒絕策略實(shí)現(xiàn)詳解

    這篇文章主要介紹了Java線程池的拒絕策略實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • 詳解Vue響應(yīng)式的部分實(shí)現(xiàn)

    詳解Vue響應(yīng)式的部分實(shí)現(xiàn)

    響應(yīng)式,簡單來說當(dāng)數(shù)據(jù)發(fā)生變化時(shí),對數(shù)據(jù)有依賴的代碼會重新執(zhí)行。這篇文章主要為大家介紹了Vue中響應(yīng)式的部分實(shí)現(xiàn),感興趣的可以了解一下
    2022-12-12
  • 如何使用SpEL表達(dá)式實(shí)現(xiàn)動(dòng)態(tài)分表查詢

    如何使用SpEL表達(dá)式實(shí)現(xiàn)動(dòng)態(tài)分表查詢

    這篇文章主要介紹了如何使用SpEL表達(dá)式實(shí)現(xiàn)動(dòng)態(tài)分表查詢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java Iterator接口遍歷單列集合迭代器原理詳解

    Java Iterator接口遍歷單列集合迭代器原理詳解

    這篇文章主要介紹了Java Iterator接口遍歷單列集合迭代器原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Spring注解之@Conditional使用解析

    Spring注解之@Conditional使用解析

    這篇文章主要介紹了Spring注解之@Conditional使用解析,@Conditional注解可以說是SpringBoot的條件注解,表示組件只有在所有指定條件都匹配時(shí)才有資格注冊,條件是可以在 bean 定義注冊之前??以編程方式確定的任何狀態(tài),需要的朋友可以參考下
    2024-01-01
  • Spring Boot 注解體系與工程實(shí)踐示例指南

    Spring Boot 注解體系與工程實(shí)踐示例指南

    本文詳細(xì)介紹了SpringBoot核心注解的語法、語義、適用場景及組合方式,涵蓋了自動(dòng)配置、條件化注入、AOP與事務(wù)等關(guān)鍵領(lǐng)域,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • Spring?JDBC配置與使用的實(shí)現(xiàn)

    Spring?JDBC配置與使用的實(shí)現(xiàn)

    本文主要介紹了Spring?JDBC配置與使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-06-06
  • 詳解Spring?MVC優(yōu)雅處理異常的6種方式

    詳解Spring?MVC優(yōu)雅處理異常的6種方式

    在Spring中提供了多種機(jī)制來處理控制器拋出的異常,確保應(yīng)用程序在面對各種錯(cuò)誤情況時(shí)能夠優(yōu)雅地響應(yīng),本文我們來詳細(xì)分析Spring?MVC中6種優(yōu)雅處理異常的方式,需要的可以參考下
    2024-12-12

最新評論

竹北市| 新津县| 闻喜县| 汕尾市| 通海县| 蓝田县| 铁岭市| 疏勒县| 晋宁县| 资阳市| 鸡西市| 罗山县| 曲麻莱县| 桃源县| 福州市| 凤阳县| 黄浦区| 仪陇县| 隆子县| 同德县| 六安市| 郧西县| 雷山县| 天水市| 平乡县| 大悟县| 新津县| 大悟县| 奉化市| 棋牌| 德清县| 望城县| 商水县| 阿拉善盟| 涿鹿县| 叶城县| 余干县| 曲周县| 白河县| 资兴市| 焦作市|