`
uule
  • 浏览: 6322778 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

日志记录、性能监控的三种实现方式

 
阅读更多

一、需解决的问题

部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法。

 

第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如:

 

boolean isValid = accountService.validSignature(appid, signature, client_signature);
if (!isValid) return ErrorUtil.buildError(ErrorUtil.ERR_CODE_COM_SING);

 

 

第二种实现方式(Spring Interception):利用spring的拦截器功能,对指定的接口进行拦截,拦截器实现签名校验算法,例如:

 

<mvc:interceptors>
     <mvc:interceptor>
            <mvc:mapping path="/connect/share/**" />
            <mvc:mapping path="/friend/**" />
            <mvc:mapping path="/account/get_bind" />
            <mvc:mapping path="/account/get_associate" />
            <bean class="com.sogou.upd.passport.web.inteceptor.IdentityAndSecureInteceptor" />
     </mvc:interceptor>
 </mvc:interceptors> 

 

 

第三种实现方式(spring AOP):自定义注解,对需要进行签名验证的方法添加注解,例如:

 

@SecureValid
@ResponseBody
@RequestMapping(value = "/share/add", method = RequestMethod.POST)
public Object addShare(HttpServletRequest req, HttpServletResponse res,InfoAPIRequestParams requestParams) {
    ...
}

 

 

2. 日志记录功能,例如:某些接口需要记录请求和响应,执行时间,类名,方法名等日志信息。也可采用以上三种方式实现。

3. 代码性能监控问题,例如方法调用时间、次数、线程和堆栈信息等。这类问题在后一个专题提出解决方案,采用以上三种方式实现缺点太多。

 

以下是三种实现方式比较:

 

实现方式 优点 缺点
Origin

不采用反射机制,性能最佳

逻辑复杂时,代码复用不好

需要在每个接口里写入相同代码(我太懒,就想写几个字母)

Spring Inter

非常适合对所有方法进行拦截,例如调试时打印所有方法执行时间

类似过滤器的功能,如日志处理、编码转换、权限检查

是AOP的子功能

不采用反射机制,性能有所影响

需要在xml文件里配置对哪些接口进行拦截,比较麻烦

Spring AOP

使用方便,增加一个注解

非常灵活,可@Before,@After,@Around等

不采用反射机制,性能有所影响(性能对比后面详细展示)

 

 

 

二、Spring AOP 自定义注解的实现

在Maven中加入以下以依赖:

<!-- Spring AOP + AspectJ by shipengzhi -->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-aop</artifactId>

            <version>3.0.6.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-aspects</artifactId>

            <version>3.0.6.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.aspectj</groupId>

            <artifactId>aspectjrt</artifactId>

            <version>1.6.11</version>

        </dependency>

        <dependency>

            <groupId>org.aspectj</groupId>

            <artifactId>aspectjweaver</artifactId>

            <version>1.6.11</version>

        </dependency>

        <dependency>

            <groupId>cglib</groupId>

            <artifactId>cglib</artifactId>

            <version>2.1_3</version>

        </dependency>

        <!-- end -->

 

在spring-***.xml中加入spring支持,打开aop功能

 

头文件声明 :

<xmlns:aop="http://www.springframework.org/schema/aop" 
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  <!-- 自定义AOP -->
    <aop:aspectj-autoproxy proxy-target-class="true">
        <aop:include name="controllerAspect" />
    </aop:aspectj-autoproxy>
    <bean id="controllerAspect" class="com.sogou.upd.passport.common.aspect.ControllerAspect"></bean>

  <!-- 或: -->
    <aop:aspectj-autoproxy> 

 

 

自定义注解实现在Controller层面

/**
     * 对Controller进行安全和身份校验  
     */
    @Around("within(@org.springframework.stereotype.Controller *) && @annotation(is)")
    public Object validIdentityAndSecure(ProceedingJoinPoint pjp, SecureValid is)
            throws Exception {
        Object[] args = pjp.getArgs();
        //Controller中所有方法的参数,前两个分别为:Request,Response 
        HttpServletRequest request = (HttpServletRequest) args[0];
        
        String appid = request.getParameter("appid");
        int app_id = Integer.valueOf(appid);
        String signature = request.getParameter("signature");
        String clientSignature = request.getParameter("client_signature");
        String uri = request.getRequestURI();

        String provider = request.getParameter("provider");
        if (StringUtils.isEmpty(provider)) {
            provider = "passport";
        }

        // 对appid和signature进行校验
        try {
            appService.validateAppid(app_id);
            boolean isValid = accountService.validSignature(app_id, signature, clientSignature);
            if (!isValid) throw new ProblemException(ErrorUtil.ERR_CODE_COM_SING);
        } catch (Exception e) {
            return handleException(e, provider, uri);
        }
        // 继续执行接下来的代码
        Object retVal = null;
        try {
            retVal = pjp.proceed();
        } catch (Throwable e) {
            if (e instanceof Exception) { return handleException((Exception) e, provider, uri); }
        }
        // 目前的接口走不到这里
        return retVal;
    }

 

 

三、Spring拦截器的实现

在spring-***.xml中加入拦截器的配置

编写拦截器实现类

public class CostTimeInteceptor extends HandlerInterceptorAdapter {

    private static final Logger log = LoggerFactory.getLogger(CostTimeInteceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long startTime = System.currentTimeMillis();
        request.setAttribute("startTime", startTime);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        long startTime = (Long) request.getAttribute("startTime");
        long endTime = System.currentTimeMillis();
        long executeTime = endTime - startTime;
        if (log.isInfoEnabled()) {
            log.info("[" + request.getRequestURI() + "] executeTime : " + executeTime + "ms");
        }
    }
}

 

 

 四、性能对比

 实验环境:对/account/get_associate接口,并发500,压测10分钟

指标 Origin Spring Inter Spring AOP
CPU user%:26.57

sys%:10.97

cpu%:37.541

user%:26.246

sys%:10.805

cpu%:37.051

user%:24.123

sys%:9.938

cpu%:34.062

Load 13.85 13.92  12.21 
QPS 6169 6093.2 5813.27
RT

0.242ms

0.242ms

0.235ms

采用AOP对响应时间无明显影响

采用AOP对Load无明显影响

采用AOP对CPU无明显影响

 

结论:使用AOP性能方面影响可忽略

 

分享到:
评论

相关推荐

    日志记录器

    日志记录在软件开发中扮演着至关重要的角色,它能帮助开发者追踪程序运行状态,定位错误源,以及进行性能分析。ZHN.LogLib是一个优秀的、免费的日志记录库,它的出现为开发者提供了更加便捷的解决方案,尤其对于那些...

    Spring aop 性能监控器

    这在性能监控、日志记录、事务管理等方面尤为有用。本篇文章将深入探讨如何使用Spring AOP实现性能监控器,并通过源码分析来理解其工作原理。 首先,我们要了解AOP的核心概念——切面(Aspect)、通知(Advice)、...

    Docker容器的性能监控和日志服务的设计与实现1

    【标题】:“Docker容器的性能监控和日志服务的设计与实现1” 【描述】:这篇硕士论文主要探讨了在Docker容器环境下如何设计和实现性能监控和日志服务,以提升分布式应用的管理和优化能力。 【部分内容】:这篇...

    统一监控平台方案(日志监控、方法监控、调用链路监控).pdf

    * 监控平台架构图:日志监控系统应用异常监控(method 调用异常)、应用性能监控、中间件监控(zk、es、kafka)、中间价系统资源监控、服务器监控、告警系统 三、日志监控方案 日志监控方案包括丰富的采集数据源...

    带日志记录的Delphi功能实现..rar

    本资源“带日志记录的Delphi功能实现”显然聚焦于如何在Delphi程序中实现日志记录功能,这对于调试、问题排查以及系统监控至关重要。下面将详细介绍这个主题,并围绕相关知识点展开讨论。 日志记录是软件开发中的一...

    性能监控之JMeter分布式压测轻量日志解决方案.docx

    总的来说,ElasticSearch+FileBeats+Kibana的组合提供了一种轻量级但功能强大的日志监控解决方案,特别适用于JMeter分布式压测中的性能监控。它不仅能够实时收集和分析大量的日志数据,还能够帮助我们快速定位和解决...

    网络实验之设备性能监控

    本实验“网络实验之设备性能监控”聚焦于通过代码实现对网络设备的监控,以提供可运行的解决方案。 在进行设备性能监控时,通常涉及以下几个核心知识点: 1. **数据采集**:这是监控的第一步,需要从网络设备(如...

    在MVC中记录操作日志类

    为了防止日志记录影响系统性能,可以考虑异步写入日志、批量处理或者使用日志聚合服务。 10. **代码示例** 假设我们有一个名为`OperationLogger`的类,其中包含`Log`方法来记录日志。在自定义的`ActionFilter`中...

    oracle dg监控程序、归档日志监控程序

    2. 实现方式:可以通过SQL查询、Oracle Enterprise Manager (OEM)、脚本化工具如DBMS_METADATA、DBMS_SERVER_ALERT等进行监控。 3. 自动化监控:描述中提到的"DG监控程序"可能包含了自定义的PL/SQL脚本,用于定时...

    日志记录组件

    日志记录组件是实现这一功能的专业工具,通常提供API接口供程序员调用,以便在代码的各个关键点插入日志输出。 这个名为“日志记录组件”的项目,包含了一些核心文件,我们可以逐一解析它们的作用: 1. **reg.bat*...

    mysql 性能监控脚本

    综上所述,“mysql 性能监控脚本”是MySQL运维中的一种实用工具,通过定期收集和分析性能数据,可以帮助我们及时发现并解决问题,确保数据库系统的高效运行。实际应用时,需要根据具体业务场景和需求,定制合适的...

    加入切面环绕通知实现,日志比较完善的使用方式

    6. **异步日志**:避免日志记录影响主线程的执行效率,可以使用异步方式记录日志。 在实际应用中,我们可能还需要结合具体的需求,如`MDC(Mapped Diagnostic Context)`来跟踪请求上下文,或者使用第三方日志框架...

    日志记录系统

    下面我们将深入探讨日志记录系统的概念、实现方式以及C语言在其中的角色。 首先,日志记录系统的基本功能包括接收和处理来自不同来源的日志消息,按照预定义的格式和级别(如调试、信息、警告、错误等)进行记录。...

    linux性能监控脚本

    在Linux系统管理中,性能监控是一项至关重要的...同时,良好的日志记录和错误处理机制也是必不可少的,以确保在出现问题时能有迹可循。通过熟练掌握和应用这些性能监控脚本,你将能够更有效地管理和维护你的Linux系统。

    vc++ c++ mfc 日志 log 记录

    日志记录(log recording)是软件开发中的一个重要环节,它有助于调试、监控和故障排查。本篇文章将深入探讨如何在VC++、C++和MFC环境下实现日志功能。 1. **日志的基本概念** - 日志是记录程序运行过程中的事件、...

    多线程的日志记录.rar

    本文将深入探讨如何在多线程环境中有效地实现日志记录。 首先,我们需要理解多线程环境下日志记录面临的主要挑战。在单线程应用中,日志通常很简单,但当多个线程同时写入同一个日志文件时,可能会出现线程安全问题...

    ASP.NET(C#)日志记录系统

    日志记录是软件开发中一种常见的调试和监控手段,它能够记录应用程序在运行时的各种信息,如IP地址、登录账户ID、操作时间等。在ASP.NET(C#)中,可以使用内置的`System.Diagnostics.Trace`类或者第三方的日志框架,...

    辅助监控日志文件重启服务

    在IT行业中,辅助监控日志...通过log4net进行日志记录,使用Timer实现定期检查和重启操作,并与PLC和OPC相结合,实现了对自动化系统的高效监控和维护。理解和掌握这些技术,对于提升系统的可靠性和维护效率至关重要。

    网络上的高性能日志类

    高性能日志类可能需要集成性能监控工具,记录系统的性能指标,如CPU使用率、内存占用、网络I/O等。 9. **可扩展性**: 设计时考虑到插件化或者依赖注入,让日志类能够轻松集成第三方日志框架,如Log4Net、NLog或...

    FLEX自定义的日历组件,带有日志记录功能

    在这个特定的案例中,我们讨论的是一个自定义的日历组件,它不仅提供了基本的日历显示功能,还集成了日志记录功能,这对于跟踪用户交互、错误检测和应用性能监控具有重要价值。 日历组件是用户界面设计中的关键部分...

Global site tag (gtag.js) - Google Analytics