簡體   English   中英

Spring Boot將我自己的端點添加為端點管理

[英]Spring Boot add my own endpoint as endpoint management

我對彈簧框架和所有彈簧都很陌生 - 我開始潛入彈簧靴並評估它作為圍繞REST服務構建新產品的候選者。

目前我對通過“ 執行器 ”模塊暴露的內容感興趣,開箱即用我知道我可以收集信息(/ info)監控掛鈎(/ health)甚至關閉端點,所有這些都與主要解耦服務器通過提供配置選項將端點置於特定端口和“命名空間”下

management.port=9000
management.contextPath=/admin

我正在尋找一個提示,將我自己的端點添加到已定義的端點(注意,我不想像HealthIndicator所提議的那樣豐富現有端點,但我真的想添加一個像'/ admin / get_me_out_of_load_balancers這樣的新端點“)

我可以看到所有現有端點都擴展了AbstractEndpoint,但沒有設法在管理contextPath下獲取我的端點...

Endpoint類的實例公開為bean; Spring Boot的執行器自動配置自動發現它 例如:

package demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

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

    @Bean
    public static Endpoint exampleEndpoint() {
        return new Endpoint<String>() {
            @Override
            public String getId() {
                return "example";
            }

            @Override
            public boolean isEnabled() {
                return true;
            }

            @Override
            public boolean isSensitive() {
                return false;
            }

            @Override
            public String invoke() {
                return "example";
            }
        };
    }
}

您可以使用AbstractMvcEndpoint在單獨的類中輕松實現它,並使用@RequestMapping簡化或添加params到端點,以便您可以查找其他服務信息:

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.endpoint.mvc.AbstractMvcEndpoint;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.LoadBalancerStats;
import com.netflix.loadbalancer.Server;
import lombok.Builder;

@Configuration
public class BalancingEndpoint extends AbstractMvcEndpoint {

    @Value("${spring.application.name}")
    private String localServiceName;

    @Autowired
    private SpringClientFactory springClientFactory;

    @Autowired
    private DiscoveryClient discoveryClient;

    public BalancingEndpoint() {
        super("/balancing", false);
    }

    @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public BalancingResponse get() {
        return getEndpointContent(localServiceName);
    }

    @RequestMapping(value = "/{serviceName}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public BalancingResponse get(@PathVariable("serviceName") String serviceName) {
        return getEndpointContent(serviceName);
    }

    private BalancingResponse getEndpointContent(String serviceName) {

        DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) springClientFactory.getLoadBalancer(serviceName);

        return BalancingResponse.builder()
            .discovery(discoveryClient.getLocalServiceInstance())
            .loadBalancerStats(loadBalancer.getLoadBalancerStats())
            .loadBalancerAllServers(loadBalancer.getAllServers())
            .build();
    }

    @Builder
    @JsonPropertyOrder({"discovery", "loadBalancerStats", "loadBalancerAllServers"})
    public static class BalancingResponse {

        @JsonProperty
        ServiceInstance discovery;

        @JsonProperty
        private LoadBalancerStats loadBalancerStats;

        @JsonProperty
        private List<Server> loadBalancerAllServers;
    }
}

此外,考慮這個( +信息 )很有意思:

如果您正在將此作為庫功能,請考慮在org.springframework.boot.actuate.autoconfigure.ManagementContextConfiguration鍵下將@ManagementContextConfiguration注釋的配置類添加到/META-INF/spring.factories。 如果您這樣做,那么如果您的用戶要求單獨的管理端口或地址,則端點將移動到具有所有其他MVC端點的子上下文。 如果想要將靜態資源(例如)添加到管理端點,則以這種方式聲明的配置可以是WebConfigurerAdapter。

對於Spring Boot 2,請看一下示例: Spring Boot Actuator:5.2。 自定義端點

@Component
@Endpoint(id = "custom-endpoint")
public class CustomEndpoint{

  @ReadOperation
  public String custom() {
    return "custom-end-point";
  }

  @ReadOperation
  public String customEndPointByName(@Selector String name) {
    return "custom-end-point";
  }

  @WriteOperation
  public void writeOperation(@Selector String name) {
    //perform write operation
  }

  @DeleteOperation
  public void deleteOperation(@Selector String name){
    //delete operation
  }
}

另請參閱Spring Boot 2.0中的Actuator Endpoints簡介

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM