亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 Spring Boot 中分析復雜的 http 請求處理?

如何在 Spring Boot 中分析復雜的 http 請求處理?

蠱毒傳說 2022-06-15 17:23:53
我有復雜的@RestController 方法,如下所示:@PostMapping("{id}")@PreAuthorize("hasRole('ADMIN')")@Transactionalpublic Response handleRequest(@PathVariable("id") long id, @RequestBody @Valid Request request) {    return service.handleRequest(id, request);}我們的請求處理非常慢,因此我們想檢查在特定請求處理任務上花費了多少時間。不幸的是,很多事情都是在我的方法之外完成的,比如:反序列化請求證實權限檢查開始和結束交易序列化響應有沒有辦法簡單地測量所有這些部分?也許是一組接收跟蹤消息的記錄器,以便我可以在每個步驟結束時提取時間戳?我現在看到的唯一方法是更改該方法以接受 HttpServletRequest 和 HttpServletResponse 并在方法主體內執行這些部分。但是那樣我會失去很多 Spring Boot 的好處。
查看完整描述

3 回答

?
守著一只汪

TA貢獻1872條經驗 獲得超4個贊

您還可以檢查 tuto 為執行器添加自定義指標,但這似乎有點復雜(但是您必須編寫自己的指標 bean 并將其注入代碼中,覆蓋 objectMapper 以進行映射等... )

或者可能激活 jackson、spring-security、javax.validation 上的日志信息,以檢查每個操作的日志時間,但不是很精確


查看完整回答
反對 回復 2022-06-15
?
嗶嗶one

TA貢獻1854條經驗 獲得超8個贊

你真正需要的是 Java Thread Profiler,它會告訴你到底出了什么問題,你可以使用任何 APM 工具,我最喜歡的是 GLOWROOT 。我在類似的場景中使用它來測量 API 的性能并識別慢跟蹤將清楚地告訴您哪個方法正在花費時間,您可以看到從方法調用開始到內部調用的所有方法的整個跟蹤,甚至可以識別慢查詢(如果有的話)。希望這可以幫助

該網站:https ://glowroot.org/

示例跟蹤:

https://demo.glowroot.org/transaction/thread-profile?transaction-type=Web&transaction-name=%2Fhot-sauces


查看完整回答
反對 回復 2022-06-15
?
九州編程

TA貢獻1785條經驗 獲得超4個贊

無需更改方法即可期待 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

}


查看完整回答
反對 回復 2022-06-15
  • 3 回答
  • 0 關注
  • 174 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號