厉害!某生鲜电商平台竟然是这样设计监控模块的(已开源)~
我们谈到监控,一般设计到两个方面的内容:
服务器本身的监控。(比如:linux服务器的CPU,内存,磁盘IO等监控) 业务系统的监控. (比如:业务系统性能的监控,SQL语句的监控,请求超时 的监控,用户输入的监控,整个请求过程时间的监控,优化等等)
服务器本身的监控
说明:由于Java开源生鲜电商平台采用的是阿里云的linux CentOS服务器,由于阿里云本身是有监控预警的,但是我们不可能时刻去看,最好有集成自己的系统监控,最终在各种系统对比的过程中,选择了netdata这个工具,当然有一些软件比如:zabbix,negios等等都是可以的,但是我们服务器压力不算大,最终采用了更加轻量级的解决方案。 相关的安装与使用,大家自行百度处理,我这边就不列举出来了。 以下是相关的实际运营截图:
业务监控
说明:任何一个业务系统都需要采用业务监控,抛异常,有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的执行时间
*/
public class LogAspect {
private static final Logger logger=LoggerFactory.getLogger(LogAspect.class);
/**
* 切入点:表示在哪个类的哪个方法进行切入。配置有切入点表达式
*/
public void pointcutExpression() {
logger.debug("配置切入点");
}
/**
* 1 前置通知
* @param joinPoint
*/
public void beforeMethod(JoinPoint joinPoint) {
logger.debug("前置通知执行了");
}
/**
* 2 后置通知
* 在方法执行之后执行的代码. 无论该方法是否出现异常
*/
public void afterMethod(JoinPoint joinPoint) {
logger.debug("后置通知执行了,有异常也会执行");
}
/**
* 3 返回通知
* 在方法法正常结束受执行的代码
* 返回通知是可以访问到方法的返回值的!
* @param joinPoint
* @param returnValue
*/
public void afterRunningMethod(JoinPoint joinPoint, Object returnValue) {
logger.debug("返回通知执行,执行结果:" + returnValue);
}
/**
* 4 异常通知
* 在目标方法出现异常时会执行的代码.
* 可以访问到异常对象; 且可以指定在出现特定异常时在执行通知代码
* @param joinPoint
* @param e
*/
public void afterThrowingMethod(JoinPoint joinPoint, Exception e)
{
logger.debug("异常通知, 出现异常 " + e);
}
/**
* 环绕通知需要携带 ProceedingJoinPoint 类型的参数.
* 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法.
* 且环绕通知必须有返回值, 返回值即为目标方法的返回值
*/
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;
}
}
javamelody
对于整个业务线的监控,我们采用了另外一种开源的监控:javamelody。
相关的配置与处理如下:
POM文件中设置:
<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>
最终运营效果如下:
总结
最终可以形成一套基于自己的监控系统,当然还有类似的更加强大的监控系统,比如:连接池方面druid,系统方面zabbix,业务方面可以用cat等等,甚至开发采用自己的监控系统也是可以的。也是支持二次开发的。
来源:https://www.cnblogs.com/jurendage/p/9070442.html
大家一起在评论区聊聊呗~
评论