<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          厲害!某生鮮電商平臺(tái)竟然是這樣設(shè)計(jì)監(jiān)控模塊的(已開(kāi)源)~

          共 4787字,需瀏覽 10分鐘

           ·

          2021-01-28 18:20

          我們談到監(jiān)控,一般設(shè)計(jì)到兩個(gè)方面的內(nèi)容:
          1. 服務(wù)器本身的監(jiān)控。(比如:linux服務(wù)器的CPU,內(nèi)存,磁盤(pán)IO等監(jiān)控)
          2. 業(yè)務(wù)系統(tǒng)的監(jiān)控. ?(比如:業(yè)務(wù)系統(tǒng)性能的監(jiān)控,SQL語(yǔ)句的監(jiān)控,請(qǐng)求超時(shí) 的監(jiān)控,用戶輸入的監(jiān)控,整個(gè)請(qǐng)求過(guò)程時(shí)間的監(jiān)控,優(yōu)化等等)

          ?

          服務(wù)器本身的監(jiān)控


          說(shuō)明:由于Java開(kāi)源生鮮電商平臺(tái)采用的是阿里云的linux CentOS服務(wù)器,由于阿里云本身是有監(jiān)控預(yù)警的,但是我們不可能時(shí)刻去看,最好有集成自己的系統(tǒng)監(jiān)控,最終在各種系統(tǒng)對(duì)比的過(guò)程中,選擇了netdata這個(gè)工具,當(dāng)然有一些軟件比如:zabbix,negios等等都是可以的,但是我們服務(wù)器壓力不算大,最終采用了更加輕量級(jí)的解決方案。

          相關(guān)的安裝與使用,大家自行百度處理,我這邊就不列舉出來(lái)了。

          以下是相關(guān)的實(shí)際運(yùn)營(yíng)截圖:

          ?


          ?

          ?

          業(yè)務(wù)監(jiān)控


          說(shuō)明:任何一個(gè)業(yè)務(wù)系統(tǒng)都需要采用業(yè)務(wù)監(jiān)控,拋異常,有error日志,短信預(yù)警,推送等等


          • Java內(nèi)存

          • JavaCPU使用情況

          • ?用戶Session數(shù)量

          • JDBC連接數(shù)

          • http請(qǐng)求、sql請(qǐng)求、jsp頁(yè)面與業(yè)務(wù)接口方法(EJB3、Spring、 Guice)的執(zhí)行數(shù)量,平均執(zhí)行時(shí)間,錯(cuò)誤百分比等

          ?

          最終,業(yè)務(wù)代碼中采用了Spring AOP進(jìn)行日志攔截,把請(qǐng)求方法超過(guò)了1500秒的方法進(jìn)行了error日志的輸出:

          ?

          業(yè)務(wù)代碼如下:

          import org.apache.commons.lang.time.StopWatch;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;
          import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;/** * 聲明一個(gè)切面,記錄每個(gè)Action的執(zhí)行時(shí)間 */@Aspect@Componentpublic class LogAspect {
          private static final Logger logger=LoggerFactory.getLogger(LogAspect.class);
          /** * 切入點(diǎn):表示在哪個(gè)類的哪個(gè)方法進(jìn)行切入。配置有切入點(diǎn)表達(dá)式 */ @Pointcut("execution(* com.netcai.admin.controller.*.*.*(..))") public void pointcutExpression() { logger.debug("配置切入點(diǎn)"); }
          /** * 1 前置通知 * @param joinPoint */ @Before("pointcutExpression()") public void beforeMethod(JoinPoint joinPoint) { logger.debug("前置通知執(zhí)行了"); }
          /** * 2 后置通知 * 在方法執(zhí)行之后執(zhí)行的代碼. 無(wú)論該方法是否出現(xiàn)異常 */ @After("pointcutExpression()") public void afterMethod(JoinPoint joinPoint) { logger.debug("后置通知執(zhí)行了,有異常也會(huì)執(zhí)行"); }
          /** * 3 返回通知 * 在方法法正常結(jié)束受執(zhí)行的代碼 * 返回通知是可以訪問(wèn)到方法的返回值的! * @param joinPoint * @param returnValue */ @AfterReturning(value = "pointcutExpression()", returning = "returnValue") public void afterRunningMethod(JoinPoint joinPoint, Object returnValue) { logger.debug("返回通知執(zhí)行,執(zhí)行結(jié)果:" + returnValue); } /** * 4 異常通知 * 在目標(biāo)方法出現(xiàn)異常時(shí)會(huì)執(zhí)行的代碼. * 可以訪問(wèn)到異常對(duì)象; 且可以指定在出現(xiàn)特定異常時(shí)在執(zhí)行通知代碼 * @param joinPoint * @param e */ @AfterThrowing(value = "pointcutExpression()", throwing = "e") public void afterThrowingMethod(JoinPoint joinPoint, Exception e) { logger.debug("異常通知, 出現(xiàn)異常 " + e); }
          /** * 環(huán)繞通知需要攜帶 ProceedingJoinPoint 類型的參數(shù). * 環(huán)繞通知類似于動(dòng)態(tài)代理的全過(guò)程: ProceedingJoinPoint 類型的參數(shù)可以決定是否執(zhí)行目標(biāo)方法. * 且環(huán)繞通知必須有返回值, 返回值即為目標(biāo)方法的返回值 */ @Around("pointcutExpression()") public Object aroundMethod(ProceedingJoinPoint pjd) { StopWatch clock = new StopWatch(); //返回的結(jié)果 Object result = null; //方法名稱 String className=pjd.getTarget().getClass().getName();
          String methodName = pjd.getSignature().getName();
          try { // 計(jì)時(shí)開(kāi)始 clock.start(); //前置通知 //執(zhí)行目標(biāo)方法 result = pjd.proceed(); //返回通知 clock.stop(); } catch (Throwable e) { //異常通知 e.printStackTrace(); } //后置通知 if(!methodName.equalsIgnoreCase("initBinder")) { long constTime=clock.getTime();
          logger.info("["+className+"]"+"-" +"["+methodName+"]"+" 花費(fèi)時(shí)間:" +constTime+"ms");
          if(constTime>500) { logger.error("["+className+"]"+"-" +"["+methodName+"]"+" 花費(fèi)時(shí)間過(guò)長(zhǎng),請(qǐng)檢查: " +constTime+"ms"); } } return result; }}


          補(bǔ)充說(shuō)明:這個(gè)方法記錄那個(gè)類,那個(gè)方法執(zhí)行的時(shí)間多少,超過(guò)設(shè)置的閥值,那么就打印error日志,需要我們每天進(jìn)行查看與針對(duì)性的優(yōu)化。

          ?

          javamelody


          對(duì)于整個(gè)業(yè)務(wù)線的監(jiān)控,我們采用了另外一種開(kāi)源的監(jiān)控:javamelody。


          相關(guān)的配置與處理如下:


          POM文件中設(shè)置:


                  <dependency>            <groupId>net.bull.javamelodygroupId>            <artifactId>javamelody-coreartifactId>            <version>1.68.1version>        dependency>

          <dependency> <groupId>org.jrobingroupId> <artifactId>jrobinartifactId> <version>1.5.9version> dependency>

          ?

          web.xml文件中處理


              <context-param>        <param-name>contextConfigLocationparam-name>        <param-value>            classpath*:config/applicationContext.xml            classpath*:net/bull/javamelody/monitoring-spring.xml            classpath*:net/bull/javamelody/monitoring-spring-datasource.xml            classpath*:net/bull/javamelody/monitoring-spring-aspectj.xml        param-value>    context-param>


                  <filter>        <filter-name>monitoringfilter-name>        <filter-class>net.bull.javamelody.MonitoringFilterfilter-class>        <async-supported>trueasync-supported>        <init-param>            <param-name>logEnabledparam-name>            <param-value>trueparam-value>        init-param>    filter>

          <filter-mapping> <filter-name>monitoringfilter-name> <url-pattern>/*url-pattern> filter-mapping>

          <listener> <listener-class>net.bull.javamelody.SessionListenerlistener-class> listener>

          ?

          最終運(yùn)營(yíng)效果如下:


          ?

          ?


          ?

          總結(jié)


          最終可以形成一套基于自己的監(jiān)控系統(tǒng),當(dāng)然還有類似的更加強(qiáng)大的監(jiān)控系統(tǒng),比如:連接池方面druid,系統(tǒng)方面zabbix,業(yè)務(wù)方面可以用cat等等,甚至開(kāi)發(fā)采用自己的監(jiān)控系統(tǒng)也是可以的。也是支持二次開(kāi)發(fā)的。

          來(lái)源:https://www.cnblogs.com/jurendage/p/9070442.html
          PS:如果覺(jué)得我的分享不錯(cuò),歡迎大家隨手點(diǎn)贊、在看。

          大家一起在評(píng)論區(qū)聊聊唄~


          瀏覽 54
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91人妻人人澡人人 | 99在线视频免费 | 一区二区三区性爱视频 | 黄色色情网站免费观看 | 青娱乐亚洲成人在线视频 |