我有复杂的@RestController方法,如下所示:
@PostMapping("{id}")
@PreAuthorize("hasRole('ADMIN')")
@Transactional
public Response handleRequest(@PathVariable("id") long id, @RequestBody @Valid Request request) {
return service.handleRequest(id, request);
}
我们的请求处理非常慢,因此我们想检查在特定请求处理任务上花费了多少时间。不幸的是,很多事情都是在我的方法之外完成的,例如:
有没有办法简单地测量所有这些部件?也许是一组接收跟踪消息的记录器,以便我可以在每个步骤结束时提取时间戳?
我现在看到的唯一方法是更改该方法以接受HttpServletRequest和HttpServletResponse,并在方法主体中执行这些部分。但这样我就会失去很多Spring Boot的好处。
无需更改期望 HttpServletRequest 的方法。您可以使用AspectJ
使用它,您可以收集在每种方法上花费的时间并分析其中的数据。
创建方法计时注释
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodTiming {
}
在您的请求中,创建一个映射,该映射将保留所有方法及其所花费的时间:
public class Request {
private Map<String, Long> methodTimings = new TreeMap<String, Long>();
public void addMethodTiming(String classAndMethodName, long executionTimeMillis) {
Long value = methodTimings.get(classAndMethodName);
if (value != null) {
executionTimeMillis += value;
}
methodTimings.put(classAndMethodName, executionTimeMillis);
}
}
比,创建将处理它的 Aspect 类:
@Aspect
@Component
public class MethodTimingAspect {
private static final String DOT = ".";
@Around("@annotation(MethodTiming)")
public Object timeAround(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = null;
StopWatch watch = new StopWatch();
try {
watch.start();
result = joinPoint.proceed();
} finally {
watch.stop();
long executionTime = watch.getLastTaskTimeMillis();
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = joinPoint.getSignature().getName();
String classAndMethodName = className + DOT + methodName;
Object[] methodArgs = joinPoint.getArgs();
if (methodArgs != null) {
for (Object arg : methodArgs) {
if (arg instanceof Request) {
// inject time back into Request
Request request = (Request) arg;
request.addMethodTiming(classAndMethodName, executionTime);
break;
}
}
}
}
return result;
}
最后,只需在您希望测量的方法上添加@MethodTiming:
@MethodTiming
public Request handleRequest(Request request) {
// handle the Request
return request
}
您的请求对象将在处理后具有类似
"methodTimings": {
"RequestService.handleRequest": 2610,
"AnotherRequestService.anotherMethod": 1351
}
您真正需要的是Java线程分析器,它将告诉您到底出了什么问题,为此您可以使用任何APM工具,我最喜欢的是GLOWROOT,我在类似场景中使用它来测量API的性能并识别慢速跟踪,这将清楚地告诉您哪种方法需要时间,您可以看到从方法调用到所有方法的整个跟踪在内部调用,甚至可以识别慢查询(如果有)。希望这有帮助
网站: https://glowroot.org/
示例跟踪:
https://demo.glowroot.org/transaction/thread-profile?transaction-type=Web
您还可以检查 tuto 以添加执行器的自定义指标,但这似乎有点复杂(但您必须编写自己的指标 bean 并将其注入到您的代码中,覆盖 objectMapper 进行映射等......
或者可以激活Jackson,Spring-Security,javax.validation上的日志记录信息,以检查每个操作的日志中的时间,但不是很精确
问题内容: 看来我应该这样做: 通过将其设置为来配置dispatcherServlet 但是,考虑到我没有XML配置,或者代码中没有任何各种初始化程序类(此答案提到),该怎么做? 在一个类中,我有一个像这样的方法,当前不会被调用。 Spring Boot 1.2.7.RELEASE; 一个简单的设置与Spring REST指南并没有太大区别 。 问题答案: 选项1:Spring Boot属性(仅适
我是web服务新手,正在阅读Martin Kalin的《Java Webservices》一书。我已经了解了它最初的基本概念,有一个问题: 假设将HTTP请求(包含SOAP消息信封)发送到JavaWeb服务()。该请求是否由Servlet内部处理,Servlet提取SOAP消息并将其转换为相应Java域对象,然后调用服务实现bean? 无论Metro和Axis等现成框架如何,这个问题都是通用的。只
首先,我阅读了“如何使用Spring MVC处理HTTP选项?”但答案似乎并不直接适用于Spring Boot。 看起来我应该这么做: 通过将dispatcherServlet的设置为 但是,考虑到我的代码中没有XML配置,也没有任何种类的初始化器类(在这个答案中提到),如何做到这一点呢? 在一个类中,我有一个这样的方法,它目前没有被调用。 Spring靴1.2.7。释放一个简单的设置与Sprin
我正在运行,刚刚检查了服务器日志,并出现了几个类似的错误。我不明白是什么导致了它,因为错误每天都在12/24小时后出现。
我正在使用Amazon SNS在我的HTTP/HTTPSendpoint上接收推送消息。endpoint应用程序是用Django编写的。要在endpoint(web app)上接收通知,HTTP/HTTPSendpoint需要订阅一个主题。 我的问题是当Amzaon SNS发送订阅确认时,它如何在POST请求中发送CSRF令牌,以便我处理请求并检索所需信息? 文档:http://docs.aws.
问题内容: 我在我的应用程序中使用JSF框架。我需要在“阶段侦听器”类中的渲染响应阶段之前运行特定的脚本。 运行此脚本的条件是,如果触发的请求是Ajax请求,则需要运行该脚本;如果触发的请求是Http请求,则不应运行该脚本。 谁能帮我区分收到的请求吗? 问题答案: Ajax请求通常具有一个请求标头。在JSF中,您可以通过获得请求标头。
当我试图从spring boot应用程序访问OAuth HTTPSendpoint时,我得到了以下错误,但HTTPendpoint工作得非常好 错误: 安全java配置 POM文件
通常用于HTTP/HTTPS请求失败/成功等处理. 进程: 主进程 IncomingMessage是由 EventEmitter响应可读流接口 实例事件 事件: 'data' 用途:响应或回调传送到应用的数据 chunk Buffer - 响应正文的数据块. 事件: 'end' 触发:响应正文已结束时 事件: 'aborted' 触发:正在进行的HTTP事务期间请求已取消时 事件: 'error