c 做asp.net網(wǎng)站西安seo建站
spring maven項(xiàng)目 實(shí)時(shí)接口請(qǐng)求次數(shù)及時(shí)間發(fā)送到grafana監(jiān)控_親測(cè)成功
說明: spring項(xiàng)目使用aop方式拿到請(qǐng)求接口uri,算出從請(qǐng)求到響應(yīng)的耗時(shí), 然后使用statsd包發(fā)送udp數(shù)據(jù)給grafana去展示.
完全不影響代碼性能和穩(wěn)定性,因?yàn)槭褂胾dp協(xié)議發(fā)送,就算grafana那邊掛了,也不影響項(xiàng)目正常運(yùn)行
UDP簡(jiǎn)單介紹
UDP提供不可靠服務(wù)
UDP是一個(gè)非連接的協(xié)議,傳輸數(shù)據(jù)之前源端和終端不建立連接, 當(dāng)它想傳送時(shí)就簡(jiǎn)單地去抓取來自應(yīng)用程序的數(shù)據(jù),并盡可能快地把它扔到網(wǎng)絡(luò)上。 在發(fā)送端,UDP傳送數(shù)據(jù)的速度僅僅是受應(yīng)用程序生成數(shù)據(jù)的速度、 計(jì)算機(jī)的能力和傳輸帶寬的限制; 在接收端,UDP把每個(gè)消息段放在隊(duì)列中,應(yīng)用程序每次從隊(duì)列中讀一個(gè)消息段。
maven項(xiàng)目pom.xml引入依賴包
<dependency><groupId>com.timgroup</groupId><artifactId>java-statsd-client</artifactId><version>3.1.0</version></dependency>
配置監(jiān)控udp地址
statsd:prefix: devhost: 192.168.1.53port: 8125
初始化配置
package com.beyond.app.config;import com.timgroup.statsd.NonBlockingStatsDClient;
import com.timgroup.statsd.StatsDClient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class StatsdConfig {private static final Logger logger = LogManager.getLogger(StatsdConfig.class);@Value("${spring.statsd.prefix}")private String prefix;@Value("${spring.statsd.host}")private String host;@Value("${spring.statsd.port}")private int port;@Bean(name = "statsDClient")public StatsDClient statsDClient() {logger.info("StatsdConfig Configuring Statsd {}-{}:{}", prefix, host, port);return new NonBlockingStatsDClient(prefix, host, port);}}
定義service
package com.beyond.app.service;import com.timgroup.statsd.StatsDClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;/*** Created by liang.*/
@Service
public class StatsdService {@Autowiredprivate StatsDClient statsDClient;@Asyncpublic void statsd (String uri, long time) {statsDClient.time("manage." + uri, time);//dev.manage.uri:10|ms//dev開發(fā)環(huán)境, manage功能, uri接口, 10ms接口耗時(shí)}}
spring aop環(huán)繞通知發(fā)送接口數(shù)據(jù)
package com.beyond.app.aop;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.beyond.app.service.StatsdService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;/*** Created by liang.*/@Component
@Aspect
public class LogAspect {private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);@Autowiredprivate StatsdService statsdService;/*** 定義一個(gè)切入點(diǎn).* 解釋下:** ~ 第一個(gè) * 代表任意修飾符及任意返回值.* ~ 第二個(gè) * 定義在web包或者子包* ~ 第三個(gè) * 任意方法* ~ .. 匹配任意數(shù)量的參數(shù).*/@Pointcut("execution(* com.beyond.app.api..*.*(..))")public void logPointCut(){}@Around("logPointCut()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{long start = System.currentTimeMillis();ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();long end = System.currentTimeMillis();try {Object result = joinPoint.proceed();end = System.currentTimeMillis();logger.info("+++++around " + joinPoint + "\tUse time : " + (end - start) + " ms!");return result;} catch (Throwable e) {end = System.currentTimeMillis();logger.error("+++++around " + joinPoint + "\tUse time : " + (end - start) + " ms with exception : " + e.getMessage());throw e;} finally {statsdService.statsd(request.getRequestURI(), end - start);}}
}