一、需解决的问题
部分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性能方面影响可忽略
相关推荐
在实际开发过程中,可以选择多种方式来实现日志记录功能。例如,在Python语言中,可以通过内置的`logging`模块轻松配置日志记录。下面是一个简单的日志记录示例: ```python import logging # 配置日志 logging....
* 监控平台架构图:日志监控系统应用异常监控(method 调用异常)、应用性能监控、中间件监控(zk、es、kafka)、中间价系统资源监控、服务器监控、告警系统 三、日志监控方案 日志监控方案包括丰富的采集数据源...
- **V1.4**:引入调用链路跟踪,实现跨系统的全链路性能监控。 #### 架构图与关键组件 - **中间件告警系统**:对监控数据进行异常检测和告警,支持邮件、短信等多种通知方式。 - **云化监控平台**:考虑到企业私有...
本资源“带日志记录的Delphi功能实现”显然聚焦于如何在Delphi程序中实现日志记录功能,这对于调试、问题排查以及系统监控至关重要。下面将详细介绍这个主题,并围绕相关知识点展开讨论。 日志记录是软件开发中的一...
### 物联网设备监控:实现访问日志记录的全面指南 物联网(IoT)设备的广泛应用正在改变我们的生活和工作方式。从智能家居设备到工业自动化系统,这些智能设备正在不断生成大量的数据。为了确保这些设备的安全性和...
日志记录在软件开发中扮演着至关重要的角色,它能帮助开发者追踪程序运行状态,定位错误源,以及进行性能分析。ZHN.LogLib是一个优秀的、免费的日志记录库,它的出现为开发者提供了更加便捷的解决方案,尤其对于那些...
这在性能监控、日志记录、事务管理等方面尤为有用。本篇文章将深入探讨如何使用Spring AOP实现性能监控器,并通过源码分析来理解其工作原理。 首先,我们要了解AOP的核心概念——切面(Aspect)、通知(Advice)、...
日志记录和监控不仅可以帮助开发者追踪应用程序运行时的状态,还能在出现错误或性能瓶颈时迅速定位问题。在本文中,我们将探讨Node.js环境下的日志监控方案和实践。 Node.js是一种基于Chrome V8引擎的JavaScript...
【标题】:“Docker容器的性能监控和日志服务的设计与实现1” 【描述】:这篇硕士论文主要探讨了在Docker容器环境下如何设计和实现性能监控和日志服务,以提升分布式应用的管理和优化能力。 【部分内容】:这篇...
这篇12页的PDF文档,"c#实现服务器性能监控并发送邮件保存日志",显然详细介绍了如何使用C#来构建一个这样的系统。 首先,服务器性能监控通常涉及以下几个方面: 1. **CPU使用率**:通过调用`System.Diagnostics....
总的来说,ElasticSearch+FileBeats+Kibana的组合提供了一种轻量级但功能强大的日志监控解决方案,特别适用于JMeter分布式压测中的性能监控。它不仅能够实时收集和分析大量的日志数据,还能够帮助我们快速定位和解决...
本实验“网络实验之设备性能监控”聚焦于通过代码实现对网络设备的监控,以提供可运行的解决方案。 在进行设备性能监控时,通常涉及以下几个核心知识点: 1. **数据采集**:这是监控的第一步,需要从网络设备(如...
在VB(Visual Basic)编程中,利用日志记录钩子实现键盘监控是一种常见的系统监控技术。日志记录钩子(WH_JOURNALRECORD)是Windows操作系统提供的一种钩子类型,它可以记录并处理发送到系统消息队列的所有消息,包括...
监控过程中,管理员可以通过各种工具来实施,比如vCenter自带的监控工具、第三方监控软件以及开源的性能监控工具vimtop。 使用vimtop进行性能监控是一种比较常见的方法。vimtop是一个开源工具,类似于Linux系统中的...
在IT行业中,性能监控是确保系统稳定性和效率的关键环节,特别是在大规模应用如美团点评这样的平台上。本资源"cat性能监控demo资源"旨在提供一个关于如何使用Cat(Coding Analysis and Testing,编码分析与测试)...
"监控系统运行情况记录表"是一个文档,用于详细记录监控系统的各项关键数据和事件,以便进行故障排查、性能优化以及维护历史追踪。 在监控系统运行情况记录表中,以下几个部分构成了核心的记录内容: 1. **日期**...
为了防止日志记录影响系统性能,可以考虑异步写入日志、批量处理或者使用日志聚合服务。 10. **代码示例** 假设我们有一个名为`OperationLogger`的类,其中包含`Log`方法来记录日志。在自定义的`ActionFilter`中...
日志记录(log recording)是软件开发中的一个重要环节,它有助于调试、监控和故障排查。本篇文章将深入探讨如何在VC++、C++和MFC环境下实现日志功能。 1. **日志的基本概念** - 日志是记录程序运行过程中的事件、...
2. 实现方式:可以通过SQL查询、Oracle Enterprise Manager (OEM)、脚本化工具如DBMS_METADATA、DBMS_SERVER_ALERT等进行监控。 3. 自动化监控:描述中提到的"DG监控程序"可能包含了自定义的PL/SQL脚本,用于定时...