Java生鮮電商平台-監控模塊的設計與架構
說明:Java開源生鮮電商平台-監控模塊的設計與架構,我們談到監控,一般設計到兩個方面的內容:
1. 服務器本身的監控。(比如:linux服務器的CPU,內存,磁盤IO等監控)
2. 業務系統的監控. (比如:業務系統性能的監控,SQL語句的監控,請求超時的監控,用戶輸入的監控,整個請求過程時間的監控,優化等等)
1. 服務器本身的監控
說明:由於Java開源生鮮電商平台采用的是阿里雲的linux CentOS服務器,由於阿里雲本身是有監控預警的,但是我們不可能時刻去看,最好有集成自己的系統監控,
最終在各種系統對比的過程中,選擇了netdata這個工具,當然有一些軟件比如:zabbix,negios等等都是可以的,但是我們服務器壓力不算大,最終采用了更加輕量級的解決方案。
相關的安裝與使用,大家自行百度處理,我這邊就不列舉出來了。
以下是相關的實際運營截圖:



2. 業務監控
說明:任何一個業務系統都需要采用業務監控,拋異常,有error日志,短信預警,推送等等
- Java內存
- JavaCPU使用情況
- 用戶Session數量
- JDBC連接數
- http請求、sql請求、jsp頁面與業務接口方法(EJB3、Spring、 Guice)的執行數量,平均執行時間,錯誤百分比等
最終,業務代碼中采用了Spring AOP進行日志攔截,把請求方法超過了1500秒的方法進行了error日志的輸出:
業務代碼如下:
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;
/**
* 聲明一個切面,記錄每個Action的執行時間
*/
@Aspect
@Component
public class LogAspect {
private static final Logger logger=LoggerFactory.getLogger(LogAspect.class);
/**
* 切入點:表示在哪個類的哪個方法進行切入。配置有切入點表達式
*/
@Pointcut("execution(* com.netcai.admin.controller.*.*.*(..))")
public void pointcutExpression() {
logger.debug("配置切入點");
}
/**
* 1 前置通知
* @param joinPoint
*/
@Before("pointcutExpression()")
public void beforeMethod(JoinPoint joinPoint) {
logger.debug("前置通知執行了");
}
/**
* 2 后置通知
* 在方法執行之后執行的代碼. 無論該方法是否出現異常
*/
@After("pointcutExpression()")
public void afterMethod(JoinPoint joinPoint) {
logger.debug("后置通知執行了,有異常也會執行");
}
/**
* 3 返回通知
* 在方法法正常結束受執行的代碼
* 返回通知是可以訪問到方法的返回值的!
* @param joinPoint
* @param returnValue
*/
@AfterReturning(value = "pointcutExpression()", returning = "returnValue")
public void afterRunningMethod(JoinPoint joinPoint, Object returnValue) {
logger.debug("返回通知執行,執行結果:" + returnValue);
}
/**
* 4 異常通知
* 在目標方法出現異常時會執行的代碼.
* 可以訪問到異常對象; 且可以指定在出現特定異常時在執行通知代碼
* @param joinPoint
* @param e
*/
@AfterThrowing(value = "pointcutExpression()", throwing = "e")
public void afterThrowingMethod(JoinPoint joinPoint, Exception e)
{
logger.debug("異常通知, 出現異常 " + e);
}
/**
* 環繞通知需要攜帶 ProceedingJoinPoint 類型的參數.
* 環繞通知類似於動態代理的全過程: ProceedingJoinPoint 類型的參數可以決定是否執行目標方法.
* 且環繞通知必須有返回值, 返回值即為目標方法的返回值
*/
@Around("pointcutExpression()")
public Object aroundMethod(ProceedingJoinPoint pjd)
{
StopWatch clock = new StopWatch();
//返回的結果
Object result = null;
//方法名稱
String className=pjd.getTarget().getClass().getName();
String methodName = pjd.getSignature().getName();
try
{
// 計時開始
clock.start();
//前置通知
//執行目標方法
result = pjd.proceed();
//返回通知
clock.stop();
} catch (Throwable e)
{
//異常通知
e.printStackTrace();
}
//后置通知
if(!methodName.equalsIgnoreCase("initBinder"))
{
long constTime=clock.getTime();
logger.info("["+className+"]"+"-" +"["+methodName+"]"+" 花費時間: " +constTime+"ms");
if(constTime>500)
{
logger.error("["+className+"]"+"-" +"["+methodName+"]"+" 花費時間過長,請檢查: " +constTime+"ms");
}
}
return result;
}
}
補充說明:這個方法記錄那個類,那個方法執行的時間多少,超過設置的閥值,那么就打印error日志,需要我們每天進行查看與針對性的優化。
3. 對於整個業務線的監控,我們采用了另外一種開源的監控:javamelody
相關的配置與處理如下:
POM文件中設置:
<!-- 系統監控 -->
<dependency>
<groupId>net.bull.javamelody</groupId>
<artifactId>javamelody-core</artifactId>
<version>1.68.1</version>
</dependency>
<dependency>
<groupId>org.jrobin</groupId>
<artifactId>jrobin</artifactId>
<version>1.5.9</version>
</dependency>
web.xml文件中處理
<context-param>
<param-name>contextConfigLocation</param-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>
<!--javamelody -->
<filter>
<filter-name>monitoring</filter-name>
<filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>logEnabled</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>monitoring</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>net.bull.javamelody.SessionListener</listener-class>
</listener>
最終運營效果如下:




總結:最終可以形成一套基於自己的監控系統,當然還有類似的更加強大的監控系統,比如:連接池方面druid,系統方面zabbix,業務方面可以用cat等等,甚至開發采用自己的監控系統也是可以的。也是支持二次開發的。
