Spring?Boot?如何通過ServletRequestHandledEvent事件實(shí)現(xiàn)接口請(qǐng)求的性能監(jiān)控

概述
在Spring框架中,監(jiān)控接口請(qǐng)求的性能可以通過ServletRequestHandledEvent事件實(shí)現(xiàn)。這種方法簡(jiǎn)單有效,能夠幫助開發(fā)者實(shí)時(shí)跟蹤和分析請(qǐng)求的性能。
1. ServletRequestHandledEvent事件
ServletRequestHandledEvent是Spring中的一個(gè)事件類,它在請(qǐng)求處理完成后發(fā)布,包含了請(qǐng)求的詳細(xì)信息,如客戶端地址、請(qǐng)求URL、請(qǐng)求方法和處理時(shí)間。使用這個(gè)事件可以輕松地監(jiān)控和記錄每個(gè)請(qǐng)求的性能數(shù)據(jù)。
2. 實(shí)現(xiàn)步驟
下面是如何通過TimeCountListener實(shí)現(xiàn)接口請(qǐng)求性能監(jiān)控的步驟:
創(chuàng)建監(jiān)聽器類
實(shí)現(xiàn)ApplicationListener<ServletRequestHandledEvent>接口并覆蓋onApplicationEvent方法:
@Component
public class TimeCountListener implements ApplicationListener<ServletRequestHandledEvent> {
@Override
public void onApplicationEvent(ServletRequestHandledEvent event) {
Throwable failureCause = event.getFailureCause();
if (failureCause != null) {
System.err.printf("錯(cuò)誤原因: %s%n", failureCause.getMessage());
}
System.err.println("========================================");
System.err.printf("請(qǐng)求客戶端地址:%s\n請(qǐng)求URL: %s\n請(qǐng)求Method: %s\n請(qǐng)求耗時(shí): %d毫秒%n",
event.getClientAddress(),
event.getRequestUrl(),
event.getMethod(),
event.getProcessingTimeMillis());
System.err.println("========================================");
}
}注冊(cè)監(jiān)聽器
使用@Component注解標(biāo)記TimeCountListener,Spring會(huì)自動(dòng)將其注冊(cè)為應(yīng)用程序的事件監(jiān)聽器。
3. 優(yōu)缺點(diǎn)分析
優(yōu)點(diǎn):
- 簡(jiǎn)單易用:無需對(duì)業(yè)務(wù)代碼進(jìn)行侵入式修改,只需創(chuàng)建監(jiān)聽器類。
- 準(zhǔn)確性高:Spring會(huì)在請(qǐng)求處理完成后發(fā)布事件,記錄的時(shí)間較為準(zhǔn)確。
- 低侵入性:與業(yè)務(wù)邏輯代碼解耦,易于維護(hù)和擴(kuò)展。
缺點(diǎn):
- 性能開銷:盡管開銷較小,但記錄和處理事件仍然會(huì)增加系統(tǒng)的負(fù)擔(dān)。
- 事件丟失:在高并發(fā)或系統(tǒng)異常情況下,事件可能會(huì)丟失或記錄不全。
4. 測(cè)試與驗(yàn)證

要測(cè)試TimeCountListener的有效性,可以創(chuàng)建一個(gè)測(cè)試接口,并在其上執(zhí)行不同的請(qǐng)求。以下是一個(gè)簡(jiǎn)單的測(cè)試示例:
package com.artisan.controller;
import com.artisan.domain.Artisan;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
/**
* @author 小工匠
* @version 1.0
* @description: TODO
* @date 2021/1/9 22:39
* @mark: show me the code , change the world
*/
@RestController
public class ArtisanController {
@RequestMapping("/hi")
public String test() {
return "小工匠 每日一博";
}
@RequestMapping("/hi2")
public Object test2() {
Artisan artisan = new Artisan();
artisan.setName("小工匠");
artisan.setAge(18);
artisan.setHobbies(Arrays.asList("code", "sleep", "study"));
return artisan;
}
/**
* 處理GET請(qǐng)求,返回自定義的響應(yīng)
* 該方法通過@RequestParam接收id和kw作為查詢參數(shù),然后構(gòu)建一個(gè)自定義的響應(yīng)返回給調(diào)用者
* 主要用于演示如何在Spring MVC中返回自定義的響應(yīng)體和響應(yīng)頭
*
* @param id 需要查詢的ID
* @return 自定義的響應(yīng)對(duì)象,包含響應(yīng)體、響應(yīng)頭和HTTP狀態(tài)碼
*/
@GetMapping("/hi3")
public Object index(Long id) {
// 創(chuàng)建HttpHeaders對(duì)象,用于自定義響應(yīng)頭
HttpHeaders headers = new HttpHeaders();
// 向響應(yīng)頭中添加自定義的版本信息
headers.add("x-version", "v1");
// 創(chuàng)建響應(yīng)對(duì)象,設(shè)置響應(yīng)體、響應(yīng)頭和HTTP狀態(tài)碼
ResponseEntity<Object> response = new ResponseEntity<>(
// 構(gòu)建響應(yīng)體內(nèi)容,格式化輸出id和kw
String.format("id = %d", id),
headers,
HttpStatus.valueOf(200)
);
// 返回自定義的響應(yīng)對(duì)象
return response;
}
}訪問 http://localhost:7777/hi3?id=1

小結(jié)
使用Spring的ServletRequestHandledEvent進(jìn)行接口請(qǐng)求性能監(jiān)控是一種簡(jiǎn)單且有效的方法。通過創(chuàng)建一個(gè)監(jiān)聽器,可以輕松地獲取請(qǐng)求的詳細(xì)性能信息,而無需對(duì)現(xiàn)有代碼進(jìn)行重大修改。然而,這種方法也有其局限性,如輕微的性能開銷和潛在的事件丟失問題。
其他方案
1. 自定義攔截器
概述:自定義攔截器可以用來在請(qǐng)求處理的不同階段(如請(qǐng)求前、請(qǐng)求后、請(qǐng)求完成后)添加額外的邏輯。
實(shí)現(xiàn)步驟:
- 實(shí)現(xiàn)
HandlerInterceptor接口,覆蓋其中的方法,如preHandle、postHandle、和afterCompletion。 - 在這些方法中記錄請(qǐng)求開始時(shí)間、結(jié)束時(shí)間,計(jì)算處理時(shí)間。
- 將攔截器注冊(cè)到Spring MVC配置中。
示例代碼:
public class PerformanceInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(PerformanceInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
request.setAttribute("startTime", System.currentTimeMillis());
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
long startTime = (Long) request.getAttribute("startTime");
long endTime = System.currentTimeMillis();
long executeTime = endTime - startTime;
logger.info("請(qǐng)求URL: {},耗時(shí): {} ms", request.getRequestURI(), executeTime);
}
}優(yōu)點(diǎn):能夠靈活控制每個(gè)請(qǐng)求的處理過程,精確測(cè)量請(qǐng)求耗時(shí)。
2. 性能監(jiān)控平臺(tái)
概述:使用專用的性能監(jiān)控平臺(tái)可以提供豐富的可視化和分析功能,幫助識(shí)別性能瓶頸。
常用工具:
- Prometheus和Grafana:Prometheus用于數(shù)據(jù)收集和監(jiān)控,Grafana用于數(shù)據(jù)可視化和告警設(shè)置。
- New Relic:提供全面的應(yīng)用性能監(jiān)控,支持多種編程語言和框架。
- AppDynamics:實(shí)時(shí)監(jiān)控應(yīng)用性能,幫助快速定位問題。
集成步驟:
在應(yīng)用中集成相應(yīng)的監(jiān)控客戶端庫。配置監(jiān)控指標(biāo)和數(shù)據(jù)收集策略。在監(jiān)控平臺(tái)上設(shè)置儀表板,實(shí)時(shí)觀察應(yīng)用性能數(shù)據(jù)。
優(yōu)點(diǎn):提供全面的性能數(shù)據(jù)分析和可視化,支持告警和歷史數(shù)據(jù)回溯。
3. 使用Spring Boot Actuator
概述:Spring Boot Actuator提供了一組生產(chǎn)級(jí)的監(jiān)控功能,包括指標(biāo)、健康檢查、審計(jì)等。
集成步驟:
- 在Spring Boot項(xiàng)目中引入
spring-boot-starter-actuator依賴。 - 配置
application.properties啟用所需的監(jiān)控端點(diǎn)。 - 使用內(nèi)置的HTTP端點(diǎn)或JMX監(jiān)控應(yīng)用的健康狀況和性能指標(biāo)。
示例配置:
management.endpoints.web.exposure.include=*
優(yōu)點(diǎn):集成簡(jiǎn)單,提供豐富的監(jiān)控端點(diǎn),適合Spring Boot應(yīng)用。
4. APM工具
概述:應(yīng)用性能管理(APM)工具可以幫助全面監(jiān)控和分析應(yīng)用性能,識(shí)別瓶頸并優(yōu)化性能。
常用工具:
- Elastic APM:與Elastic Stack整合,提供應(yīng)用性能監(jiān)控和日志管理。
- Datadog:支持云原生應(yīng)用監(jiān)控,提供全面的性能數(shù)據(jù)。
- Skywalking:支持云原生應(yīng)用監(jiān)控,提供全面的性能數(shù)據(jù)。
優(yōu)點(diǎn):提供詳細(xì)的性能分析報(bào)告和可視化,易于識(shí)別和解決性能問題。
到此這篇關(guān)于Spring Boot 如何通過ServletRequestHandledEvent事件實(shí)現(xiàn)接口請(qǐng)求的性能監(jiān)控的文章就介紹到這了,更多相關(guān)Spring Boot接口請(qǐng)求的性能監(jiān)控內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
maven中自定義MavenArchetype的實(shí)現(xiàn)
Maven自身提供了許多Archetype來方便用戶創(chuàng)建Project,為了避免在創(chuàng)建project時(shí)重復(fù)的拷貝和修改,我們通過自定義Archetype來規(guī)范顯得還蠻有必要,下面就來介紹一下,感興趣的可以了解一下2025-01-01
SpringCloud引入feign失敗或找不到@EnableFeignClients注解問題
這篇文章主要介紹了SpringCloud引入feign失敗或找不到@EnableFeignClients注解問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Elasticsearch 映射參數(shù)詳解 fields
這篇文章主要介紹了fields Elasticsearch 映射參數(shù)fields,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Intellij idea遠(yuǎn)程debug連接tomcat實(shí)現(xiàn)單步調(diào)試
這篇文章主要介紹了Intellij idea遠(yuǎn)程debug連接tomcat實(shí)現(xiàn)單步調(diào)試,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05
SpringBoot?docker項(xiàng)目部署實(shí)戰(zhàn)
本文主要介紹了SpringBoot?docker項(xiàng)目部署實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08
SpringBoot工程搭建打包、啟動(dòng)jar包和war包的教程圖文詳解
這篇文章主要介紹了SpringBoot工程搭建打包、啟動(dòng)jar包和war包的教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09

