前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >厉害!某生鲜电商平台竟然是这样设计监控模块的(已开源)~

厉害!某生鲜电商平台竟然是这样设计监控模块的(已开源)~

作者头像
java进阶架构师
发布2020-11-03 10:41:45
6090
发布2020-11-03 10:41:45
举报
文章被收录于专栏:Java进阶架构师Java进阶架构师

★★★建议星标我们★★★

公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为星标”!这样才不会错过每日进阶架构文章呀。

2020年Java原创面试题库连载中

【000期】Java最全面试题库思维导图

【020期】JavaSE系列面试题汇总(共18篇)

【028期】JavaWeb系列面试题汇总(共10篇)

【042期】JavaEE系列面试题汇总(共13篇)

【049期】数据库系列面试题汇总(共6篇)

【053期】中间件系列面试题汇总(共3篇)

【065期】数据结构与算法面试题汇总(共11篇)

【076期】分布式面试题汇总(共10篇)

【077期】综合面试题系列(一)

【078期】综合面试题系列(二)

【079期】综合面试题系列(三)

【080期】综合面试题系列(四)

【081期】综合面试题系列(五)

【082期】综合面试题系列(六)

【083期】综合面试题系列(七)

【084期】综合面试题系列(八)

【085期】综合面试题系列(九)

【086期】综合面试题系列(十)

【087期】综合面试题系列(十一)

【088期】综合面试题系列(十二)

【089期】综合面试题系列(十三)

更多内容,点击上面蓝字查看

我们谈到监控,一般设计到两个方面的内容:

  1. 服务器本身的监控。(比如:linux服务器的CPU,内存,磁盘IO等监控)
  2. 业务系统的监控. (比如:业务系统性能的监控,SQL语句的监控,请求超时 的监控,用户输入的监控,整个请求过程时间的监控,优化等等)

# 服务器本身的监控

说明:由于Java开源生鲜电商平台采用的是阿里云的linux CentOS服务器,由于阿里云本身是有监控预警的,但是我们不可能时刻去看,最好有集成自己的系统监控,最终在各种系统对比的过程中,选择了netdata这个工具,当然有一些软件比如:zabbix,negios等等都是可以的,但是我们服务器压力不算大,最终采用了更加轻量级的解决方案。

相关的安装与使用,大家自行百度处理,我这边就不列举出来了。

以下是相关的实际运营截图:

# 业务监控

说明:任何一个业务系统都需要采用业务监控,抛异常,有error日志,短信预警,推送等等

  • Java内存
  • JavaCPU使用情况
  • 用户Session数量
  • JDBC连接数
  • http请求、sql请求、jsp页面与业务接口方法(EJB3、Spring、 Guice)的执行数量,平均执行时间,错误百分比等

最终,业务代码中采用了Spring AOP进行日志拦截,把请求方法超过了1500秒的方法进行了error日志的输出:

业务代码如下:

代码语言:javascript
复制
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日志,需要我们每天进行查看与针对性的优化。

# javamelody

对于整个业务线的监控,我们采用了另外一种开源的监控:javamelody。

相关的配置与处理如下:

POM文件中设置:

代码语言:javascript
复制
<!-- 系统监控 -->
        <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文件中处理

代码语言:javascript
复制
    <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>
代码语言:javascript
复制
    <!--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等等,甚至开发采用自己的监控系统也是可以的。也是支持二次开发的。

来源:https://urlify.cn/AZVnee

代码语言:javascript
复制
之前,给大家发过三份Java面试宝典,这次新增了一份,目前总共是四份面试宝典,相信在跳槽前一个月按照面试宝典准备准备,基本没大问题。《java面试宝典5.0》(初中级)《350道Java面试题:整理自100+公司》(中高级)《资深java面试宝典-视频版》(资深)《Java[BAT]面试必备》(资深)分别适用于初中级,中高级,资深级工程师的面试复习。内容包含java基础、javaweb、mysql性能优化、JVM、锁、百万并发、消息队列,高性能缓存、反射、Spring全家桶原理、微服务、Zookeeper、数据结构、限流熔断降级等等。获取方式:点“在看”,V信关注上述Java最全面试题库号并回复 【面试】即可领取,更多精彩陆续奉上。
看到这里,证明有所收获必须点个在看支持呀,喵
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-10-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java进阶架构师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
应用性能监控
应用性能监控(Application Performance Management,APM)是一款应用性能管理平台,基于实时多语言应用探针全量采集技术,为您提供分布式性能分析和故障自检能力。APM 协助您在复杂的业务系统里快速定位性能问题,降低 MTTR(平均故障恢复时间),实时了解并追踪应用性能,提升用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档