springboot+RabbitMQ+InfluxDB+Grafara 모니터링 실천

본 고 는 spring boot 또는 spring cloud 관련 마이크로 서비스 프레임 워 크 에 대한 기반 이 필요 합 니 다.관련 기반 을 갖 추 면 다음 과정 을 쉽게 실현 할 수 있 습 니 다!!!!!!!!바라다
본문 에서 말 한 것 은 필요 한 당신 에 게 도움 이 됩 니 다.
여기 서부 터 우 리 는 잡담 단계 에 들어간다.
spring boot 는 많은 제3자 프레임 워 크 를 통합 시 켰 다 는 것 을 잘 알 고 있 습 니 다.우 리 는 성능 모니터링 과 JVM 모니터링 과 관련 된 것 을 간단하게 토론 하고 사용 합 니 다.다른 본 고 는 토론 하지 않 습 니 다.비록 관련 이 있 지만 처음에 spring boot 프레임 워 크 기반 이 필요 하 다 고 말 했 습 니 다.이렇게 많은 쓸데없는 말 을 했 습 니 다.다음은 진정 으로 주제 에 들 어 갑 니 다.
여기 서 먼저 전체적인 데이터 흐름 도 를 보 여 드 리 겠 습 니 다.그 중에서 두 개의 메 인 라인 중 하 나 는 인터페이스 나 방법 성능 모니터링 데이터 수집 이 고 다른 하 나 는 spring boot 마이크로 서비스 JVM 관련 기준 데이터 수집 입 니 다.마지막 으로 모두 InfluxDB 순차 데이터 베이스 에 모여 데이터 전시 도구 인 Grafara 로 데이터 전시 나 경 고 를 합 니 다.

기초 서비스
기초 서비스 가 비교적 많은 데 그 중에서 RabbitMQ,Eureka 등록 센터,influxDB,Grafara(이런 것들 을 모 르 면 바 이 두 나 구 글 에서 관련 지식 을 알 아 보 세 요)를 포함한다.다음은 각 기초 서비스의 기능 을 간단하게 설명 한다.
RabbitMQ 는 매우 유행 하 는 메시지 미들웨어 로 주로 spring boot 응용 모니터링 성능 에 관 한 정 보 를 수집 합 니 다.왜 RabbitMQ 가 다른 kafka 가 아 닌 지 등 테스트 편의 성 이 충분 하기 때문에 spring boot 는 완벽 하 게 통합 되 었 습 니 다.
유레카 등록 센터,일반적으로 spring cloud 관련 프레임 워 크 를 보 거나 사용 한 적 이 있 는 사람들 은 spring cloud 등록 센터 에서 주로 유레카 를 추천 합 니 다!왜 지나치게 많은 토론 을 하지 않 는 지 에 대해 서 는 본문의 주요 토론 의 관심 사가 아니다.본 고 는 주로 등록 센터 에 등 록 된 응용 에 관 한 정 보 를 동기 화하 고 얻 는 데 사용 된다.
InfluxDB 와 Grafara 는 왜 이 두 가 지 를 선 택 했 습 니까? ElasticSearch 、Logstash 、Kibana,ELK 의 조합 등!이 유 는 분명히 influxDB 가 순차 데이터베이스 데이터 의 압축 비율 이 다른 것 보다 높다(ElasticSearch )좋 습 니 다.또한 InfluxDB 는 SQL 과 매우 유사 한 my sql 등 관계 형 데이터 베 이 스 를 사용 하여 입문 이 편리 하고 Grafara 도 구 는 미리 경고 할 수 있 습 니 다.잠깐 만!!!!!!!!!!!
도 구 는 여기까지 간단하게 소개 합 니 다.이런 도 구 를 어떻게 배치 하고 구축 하 는 지 에 대해 먼저 자 료 를 찾 아 공부 하 십시오.아니면 본 고 에서 중점적으로 소개 한 내용 이 아니 기 때문에 깊이 토론 하지 않 습 니 다.docker 와 관련 된 기본 적 인 어린이 신발 이 있 으 면 미 러 를 직접 다운로드 하여 시작 하여 테스트 를 할 수 있 습 니 다.(본인 은 docker 로 시작 하 는 위 에 있 는 기본 애플 리 케 이 션(Eureka 제외)
1.감 시 된 응용
모니터링 애플 리 케 이 션 이 spring boot 프로젝트 라 고 는 많이 말 하지 않 지만 관련 패키지 와 관련 주 해 를 참조 하고 관련 프로필 을 수정 해 야 합 니 다.
가방 참조,이 가방 들 은 반드시 인용 해 야 합 니 다.

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
     <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>
간단하게 말하자면 관련 패키지 의 기능 인 spring-cloud-starter-netflix-eureka-client 는 등록 센터 에서 사용 하 는 패키지 입 니 다.spring-cloud-starter-stream-rabbit 는 RabbitMQ 관련 패 키 지 를 보 내 고 spring-boot-starter-actuator 는 모니터링 관련 rest 인터페이스 패 키 지 를 발표 합 니 다.
spring-cloud-starter-hystrix 용 단 성능 모니터링 패키지.
관련 주해

@EnableHystrix//      
@RefreshScope//            
@EnableAutoConfiguration
@EnableFeignClients//RPC       
@RestController
@SpringBootApplication
public class ServerTestApplication {
  protected final static Logger logger = LoggerFactory.getLogger(ServerTestApplication.class);

  public static void main(String[] args) {
    SpringApplication.run(ServerTestApplication.class, args);
  }
}
프로필 관련

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
hystrix.threadpool.default.coreSize: 100
spring:
 application:
  name: spring-cloud-server2-test
 rabbitmq:
  host: 10.10.12.21
  port: 5672
  username: user
  password: password

encrypt:
 failOnError: false
server:
 port: 8081
eureka:
 instance:
  appname: spring-cloud-server2-test
  prefer-ip-address: true
 client: 
  serviceUrl:
   defaultZone: http://IP:PORT/eureka/#      
  eureka-server-total-connections-per-host: 500
endpoints:
 refresh:
  sensitive: false
 metrics:
  sensitive: false
 dump:
  sensitive: false
 auditevents:
  sensitive: false
 features:
  sensitive: false
 mappings:
  sensitive: false
 trace:
  sensitive: false
 autoconfig:
  sensitive: false
 loggers:
  sensitive: false
endpoints 아래 의 관련 설정 을 간단하게 설명 합 니 다.주로 이러한 경 로 는 권한 을 부여 하여 방문 해 야 합 니 다.이러한 경로 인 터 페 이 스 를 설정 함으로써 더 이상 민감 한 권한 을 부여 해 야 하 는 인터페이스 가 아니 라 등록 센터 에 등 록 된 모든 서비스의 응답 인 터 페 이 스 를 쉽게 방문 할 수 있 습 니 다.여기에 인터페이스 성능 을 삽입 하려 면 방법 에 다음 과 같은 유사 한 주 해 를 더 해 야 관련 성능 데이터 출력 이 가능 합 니 다.

@Value("${name}")
  private String name;
  
  @HystrixCommand(commandProperties = {
      @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "20000") }, threadPoolProperties = {
          @HystrixProperty(name = "coreSize", value = "64") }, threadPoolKey = "test1")
  @GetMapping("/testpro1")
  public String getStringtest1(){
    
    return name;
  }
자,여기까지.방문 하 셔 도 됩 니 다.

위의 인터페이스 라면 기본 OK 를 사용 합 니 다.왜 기본적으로 성능 정 보 를 캡 처 하지 않 고 RabbitMQ 에 관 한 정 보 를 보 냈 기 때 문 입 니까?이것 은 일 지 를 봐 야 합 니 다.가입 에 실 패 했 습 니 다.논평 구역 에서 토론 하고 있 습 니 다.일단 메 인 에 주목 하 겠 습 니 다.
좋 습 니 다.spring boot 애플 리 케 이 션 은 여기까지 하 겠 습 니 다.다음 주 제 를 시작 하 겠 습 니 다.
2.성능 지표 데이터 수집
방금 방문http://IP:port/hystrix.stream이 표 시 된 정 보 는 핑계 나 방법 성능 에 관 한 정 보 를 출력 하 는 것 입 니 다.위 에 문제 가 없다 면 데 이 터 는 RabbitMQ 에 보 내야 합 니 다.저 희 는 RabbitMQ 에 직접 가서 관련 데 이 터 를 받 으 면 됩 니 다.
성능 지표 데이터 수집 서 비 스 는 주로 다음 과 같은 패 키 지 를 사용 합 니 다.

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.github.miwurster/spring-data-influxdb -->
    <dependency>
      <groupId>org.influxdb</groupId>
      <artifactId>influxdb-java</artifactId>
      <version>2.8</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure</artifactId>
    </dependency>
직접 코드 붙 이기

package application;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 
 * @author zyg
 *
 */
@SpringBootApplication
public class RabbitMQApplication {

  public static void main(String[] args) {
    SpringApplication.run(RabbitMQApplication.class, args);
  }

}

package application;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;  

/**
 * 
 * @author zyg
 *
 */
@Configuration
public class RabbitMQConfig {
  public final static String QUEUE_NAME = "spring-boot-queue";
  public final static String EXCHANGE_NAME = "springCloudHystrixStream";
  public final static String ROUTING_KEY = "#";

  //     
  @Bean
  public Queue queue() {
    return new Queue(QUEUE_NAME);
  }

  //      topic       
  @Bean
  public TopicExchange exchange() {
    return new TopicExchange(EXCHANGE_NAME);
  }

  //      (routingKey)   (Queue)      (Exchange)
  @Bean
  public Binding binding(Queue queue, TopicExchange exchange) {
    return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY);
  }

  @Bean
  public ConnectionFactory connectionFactory() {
    //rabbitmq IP    
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory("IP", 5672);
    connectionFactory.setUsername("user");
    connectionFactory.setPassword("password");
    return connectionFactory;
  }

  @Bean
  public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
    return new RabbitTemplate(connectionFactory);
  }
}

package application;

import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBFactory;
import org.influxdb.dto.Point;
import org.influxdb.dto.Point.Builder;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;

/**
 * 
 * @author zyg
 *
 */
public class InfluxDBConnect {
  private String username;//    
  private String password;//   
  private String openurl;//     
  private String database;//    

  private InfluxDB influxDB;

  public InfluxDBConnect(String username, String password, String openurl, String database) {
    this.username = username;
    this.password = password;
    this.openurl = openurl;
    this.database = database;
  }

  /**        ;  InfluxDB **/
  public InfluxDB influxDbBuild() {
    if (influxDB == null) {
      influxDB = InfluxDBFactory.connect(openurl, username, password);
      influxDB.createDatabase(database);

    }
    return influxDB;
  }

  /**
   *          defalut     /database     / 30d       30 / 1      1/   DEFAULT
   *           
   */
  public void createRetentionPolicy() {
    String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT",
        "defalut", database, "30d", 1);
    this.query(command);
  }

  /**
   *   
   * 
   * @param command
   *          
   * @return
   */
  public QueryResult query(String command) {
    return influxDB.query(new Query(command, database));
  }

  /**
   *   
   * 
   * @param measurement
   *       
   * @param tags
   *        
   * @param fields
   *        
   */
  public void insert(String measurement, Map<String, String> tags, Map<String, Object> fields) {
    Builder builder = Point.measurement(measurement);
    builder.time(((long)fields.get("currentTime"))*1000000, TimeUnit.NANOSECONDS);
    builder.tag(tags);
    builder.fields(fields);
    //
    influxDB.write(database, "", builder.build());
  }

  /**
   *   
   * 
   * @param command
   *          
   * @return       
   */
  public String deleteMeasurementData(String command) {
    QueryResult result = influxDB.query(new Query(command, database));
    return result.getError();
  }

  /**
   *      
   * 
   * @param dbName
   */
  public void createDB(String dbName) {
    influxDB.createDatabase(dbName);
  }

  /**
   *      
   * 
   * @param dbName
   */
  public void deleteDB(String dbName) {
    influxDB.deleteDatabase(dbName);
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getOpenurl() {
    return openurl;
  }

  public void setOpenurl(String openurl) {
    this.openurl = openurl;
  }

  public void setDatabase(String database) {
    this.database = database;
  }
}

package application;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 
 * @author zyg
 *
 */
@Configuration
public class InfluxDBConfiguration {
  
  private String username = "admin";//   
  private String password = "admin";//  
  private String openurl = "http://IP:8086";//InfluxDB    
  private String database = "test_db";//   
  
  @Bean
  public InfluxDBConnect getInfluxDBConnect(){
    InfluxDBConnect influxDB = new InfluxDBConnect(username, password, openurl, database);
    
    influxDB.influxDbBuild();
    
    influxDB.createRetentionPolicy();
    return influxDB;
  }
}

package application;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 
 * @author zyg
 *
 */
@Component
public class Consumer {
  protected final static Logger logger = LoggerFactory.getLogger(Consumer.class);

  private ObjectMapper objectMapper = new ObjectMapper();

  @Autowired
  private InfluxDBConnect influxDB;

  @RabbitListener(queues = RabbitMQConfig.QUEUE_NAME)
  public void sendToSubject(org.springframework.amqp.core.Message message) {

    String payload = new String(message.getBody());
    logger.info(payload);

    if (payload.startsWith("\"")) {
      // Legacy payload from an Angel client
      payload = payload.substring(1, payload.length() - 1);
      payload = payload.replace("\\\"", "\"");
    }
    try {
      if (payload.startsWith("[")) {
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> list = this.objectMapper.readValue(payload, List.class);
        for (Map<String, Object> map : list) {
          sendMap(map);
        }
      } else {
        @SuppressWarnings("unchecked")
        Map<String, Object> map = this.objectMapper.readValue(payload, Map.class);
        sendMap(map);
      }
    } catch (IOException ex) {
      logger.error("Error receiving hystrix stream payload: " + payload, ex);
    }
  }

  private void sendMap(Map<String, Object> map) {
    Map<String, Object> data = getPayloadData(map);
    data.remove("latencyExecute");
    data.remove("latencyTotal");
    Map<String, String> tags = new HashMap<String, String>();
    
    tags.put("type", data.get("type").toString());
    tags.put("name", data.get("name").toString());
    tags.put("instanceId", data.get("instanceId").toString());
    //tags.put("group", data.get("group").toString());
    
    
    influxDB.insert("testaaa", tags, data);

    // for (String key : data.keySet()) {
    // logger.info("{}:{}",key,data.get(key));
    // }


  }

  public static Map<String, Object> getPayloadData(Map<String, Object> jsonMap) {
    @SuppressWarnings("unchecked")
    Map<String, Object> origin = (Map<String, Object>) jsonMap.get("origin");
    String instanceId = null;
    if (origin.containsKey("id")) {
      instanceId = origin.get("host") + ":" + origin.get("id").toString();
    }
    if (!StringUtils.hasText(instanceId)) {
      // TODO: instanceid template
      instanceId = origin.get("serviceId") + ":" + origin.get("host") + ":" + origin.get("port");
    }
    @SuppressWarnings("unchecked")
    Map<String, Object> data = (Map<String, Object>) jsonMap.get("data");
    data.put("instanceId", instanceId);
    return data;
  }

}
여 기 는 말 할 것 도 없 이 RabbitMQ 정 보 를 받 아 InfluxDB 데이터베이스 에 저장 하 는 것 이다.
3.JVM 관련 데이터 수집
JVM 관련 데이터 수집 은 매우 간단 하 다.
서비스 가 인용 한 가방 은 많 지 않 습 니 다.이 서 비 스 는 등록 센터 Eureka 에 등록 해 야 합 니 다.모든 서비스의 모니터링 정 보 를 받 아야 하기 때 문 입 니 다.
InfluxDB 코드 를 삽입 하 는 것 은 위 와 거의 유사 합 니 다.일괄 삽입 방법 이 하나 더 있 을 뿐 입 니 다.

package com.zjs.collection;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * 
 * @author zyg
 *
 */
@EnableEurekaClient
@SpringBootApplication
public class ApplictionCollection 
{
  public static void main(String[] args) {
    SpringApplication.run(ApplictionCollection.class, args);
  }
}

/**
   *     
   * 
   * @param measurement
   *       
   * @param tags
   *        
   * @param fields
   *        
   */
  public void batchinsert(String measurement, Map<String, String> tags, List<Map<String, Object>> fieldslist) {
    org.influxdb.dto.BatchPoints.Builder batchbuilder=BatchPoints.database(database);

    for (Map<String, Object> map : fieldslist) {
      Builder builder = Point.measurement(measurement);
      tags.put("instanceId", map.get("instanceId").toString());
      builder.time((long)map.get("currentTime"), TimeUnit.NANOSECONDS);
      builder.tag(tags);
      builder.fields(map);
      batchbuilder.point(builder.build());
    }
    
    System.out.println(batchbuilder.build().toString());
    
    influxDB.write(batchbuilder.build());
  }

package com.zjs.collection;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
 *        
 * 
 * @author zyg
 *
 */
@Component
@SpringBootApplication
@EnableScheduling
public class MicServerInstanceInfoHandle {

  protected final static Logger logger = LoggerFactory.getLogger(MicServerInstanceInfoHandle.class);

  final String pathtail = "/metrics/mem.*|heap.*|threads.*|gc.*|nonheap.*|classes.*";

  Map<String, String> tags;

  ThreadPoolExecutor threadpool;

  @Autowired
  DiscoveryClient dc;

  @Autowired
  RestTemplate restTemplate;

  final static LinkedBlockingQueue<Map<String, Object>> jsonMetrics = new LinkedBlockingQueue<>(1000);

  /**
   *                     
   */
  public MicServerInstanceInfoHandle() {
    
    tags = new HashMap<String, String>();
    threadpool = new ThreadPoolExecutor(4, 20, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100));

  }

  @Autowired
  private InfluxDBConnect influxDB;

  /**
   * metrics    
   */
  @Scheduled(fixedDelay = 2000)
  public void metricsDataObtain() {
    logger.info("    metrics  ");
    List<String> servicelist = dc.getServices();
    for (String str : servicelist) {

      List<ServiceInstance> silist = dc.getInstances(str);

      for (ServiceInstance serviceInstance : silist) {
        threadpool.execute(new MetricsHandle(serviceInstance));
      }
    }
  }

  /**
   *       influxdb   
   */
  @Scheduled(fixedDelay = 5000)
  public void metricsDataToInfluxDB() {
    logger.info("     metrics  insert-influxdb");
    ArrayList<Map<String, Object>> metricslist = new ArrayList<>();
    MicServerInstanceInfoHandle.jsonMetrics.drainTo(metricslist);

    if (!metricslist.isEmpty()) {
      logger.info("      :{}", metricslist.size());
      influxDB.batchinsert("metrics", tags, metricslist);
    }

    logger.info("    metrics  insert");
  }

  @Bean
  public RestTemplate getRestTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    SimpleClientHttpRequestFactory achrf = new SimpleClientHttpRequestFactory();
    achrf.setConnectTimeout(10000);
    achrf.setReadTimeout(10000);
    restTemplate.setRequestFactory(achrf);
    return restTemplate;

  }

  class MetricsHandle extends Thread {
    
    private ServiceInstance serviceInstanc;
    
    public MetricsHandle(ServiceInstance serviceInstance){
      serviceInstanc=serviceInstance;
    }
    
    @Override
    public void run() {

      try {
        
        logger.info("   {}:{}:{}   metrics  ",serviceInstanc.getServiceId(),serviceInstanc.getHost(),serviceInstanc.getPort());
        
        @SuppressWarnings("unchecked")
        Map<String, Object> mapdata = restTemplate
            .getForObject(serviceInstanc.getUri().toString() + pathtail, Map.class);
        mapdata.put("instanceId", serviceInstanc.getServiceId() + ":" + serviceInstanc.getHost() + ":"
            + serviceInstanc.getPort());
        mapdata.put("type", "metrics");
        mapdata.put("currentTime", System.currentTimeMillis() * 1000000);
        MicServerInstanceInfoHandle.jsonMetrics.add(mapdata);

      } catch (Exception e) {
        logger.error("instanceId:{},host:{},port:{},path:{},exception:{}", serviceInstanc.getServiceId(),
            serviceInstanc.getHost(), serviceInstanc.getPort(), serviceInstanc.getUri(),
            e.getMessage());
      }
    }
  }

}
여기 서 이 코드 를 간단하게 설명 하 겠 습 니 다 final String pathtail = "/metrics/mem.*|heap.*|threads.*|gc.*|nonheap.*|classes.*"; ,metrics 라 는 경로 에서 정보 가 많 지만 우 리 는 모두 필요 하지 않 기 때문에 우 리 는 선택 적 으로 데이터 와 시간 을 절약 해 야 합 니 다.위의 관건 적 인 클래스 인 MicServer InstanceInfoHandle 은 다 중 스 레 드 접근 을 했 습 니 다.주로 등록 센터 에 수백 수천 개의 서비스 가 있 을 때 단일 스 레 드 가 순서 가 맞지 않 을 수 있 습 니 다.동시에 하나의 대기 열 버퍼 를 만들어 InfluxDB 에 대량으로 삽입 되 었 습 니 다.
결과 전시

데이터 수집 에 성공 하면 위의 그림 을 그 릴 수 있 습 니 다.아래 는 해당 하 는 sql 입 니 다.

SELECT mean("rollingCountFallbackSuccess"), mean("rollingCountSuccess") FROM "testaaa" WHERE ("instanceId" = 'IP:spring-cloud-server1-test:8082' AND "type" = 'HystrixCommand') AND $timeFilter GROUP BY time($__interval) fill(null)

SELECT mean("currentPoolSize") FROM "testaaa" WHERE ("type" = 'HystrixThreadPool' AND "instanceId" = '10.10.12.51:spring-cloud-server1-test:8082') AND $timeFilter GROUP BY time($__interval) fill(null)

SELECT "heap", "heap.committed", "heap.used", "mem", "mem.free", "nonheap", "nonheap.committed", "nonheap.used" FROM "metrics" WHERE ("instanceId" = 'SPRING-CLOUD-SERVER1-TEST:10.10.12.51:8082') AND $timeFilter
자,이제 거의 끝 났 습 니 다.
5.최적화 및 구상
위의 기초 서 비 스 는 모두 높 은 사용 이 필요 할 것 이 니 모두 배 워 야 한 다 는 것 은 의심 할 여지 가 없다.시간 이 있 으 면 저도 여러분 께 일일이 소개 하 겠 습 니 다.여러분 도 관련 자 료 를 검색 해서 보 실 수 있 습 니 다!
텔 레 그 라 프 라 는 작은 플러그 인 이 관련 데 이 터 를 직접 수집 하여 취 합 결 과 를 모니터링 할 수 있다 고 물 었 을 수도 있 습 니 다.
사실 저도 예전 에 텔 레 그 라 프 라 는 작은 도 구 를 사 용 했 는데 문 제 를 발 견 했 습 니 다.
모니터링 되 는 애플 리 케 이 션 이 재 부팅 될 때마다 관련 필드 이름 이 바 뀌 는 것 입 니 다.
그 가 수집 한 것 은 인 스 턴 스 의 이름 을 필드 이름 으로 사용 하기 때문에 우 리 는 매우 불편 할 것 입 니 다.프로그램 을 다시 시작 할 때마다 sql 문 구 를 다시 설정 하 는 것 은 매우 우호 적 이지 않 습 니 다.
데이터 수집 이 어렵 지 않 을 것 같 아서 데 이 터 를 수집 하 는 코드 를 썼 습 니 다!텔 레 그 라 프 에 대해 잘 아 시 는 분 이 있다 면 제 가 말씀 드 린 문 제 를 해결 할 수 있 습 니 다.메 시 지 를 남 겨 주세요!여기 서 먼저 감사합니다!
어떤 부분 은 최적화 가 필요 하 다.예 를 들 어 일부 IP 포트 같은 것 은 모두 설정 파일 에 넣 을 수 있다.
총화
spring boot 부터 지금까지 짧 은 2,3 년 동안 빠르게 뜨 거 워 졌 고 지식 체계 도 완선 되 었 으 며 개발 원가 가 점점 낮 아 졌 다.
그래서 보급 수준 이 점점 높 아 지고 마이크로 서 비 스 는 좋 지만 우 리 는 잘 활용 해 야 한다.감 시 는 중요 한 일환 이다.
당신 의 기관실 에서 수천 명의 서 비 스 를 운행 하고 있 으 며,안정 적 인 운행 과 문제 가 있 는 서 비 스 를 제때에 발견 하 는 것 이 얼마나 중요 한 일 인지 생각해 보 세 요!
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기