【问题标题】:Spring Boot add my own endpoint as endpoint managementSpring Boot 添加我自己的端点作为端点管理
【发布时间】:2014-07-30 15:51:34
【问题描述】:

我对 spring 框架和所有 spring-* 都很陌生,我开始深入研究 spring boot 并将其评估为围绕 REST 服务构建的新产品的候选者。

目前我对通过“actuator”模块公开的内容感兴趣,开箱即用我知道我可以收集信息(/info)监控钩子(/health)和甚至是关闭端点,通过提供配置选项将这些端点置于特定端口和“命名空间”下,所有这些都与主服务器解耦

management.port=9000
management.contextPath=/admin

我正在寻找将我自己的端点添加到已经定义的端点的提示(注意,我不想像 HealthIndicator 提议的那样丰富现有端点,但我真的想添加一个新端点,比如说'/ admin/get_me_out_of_load_balancers')

我可以看到所有现有端点都扩展了 AbstractEndpoint 但没有设法让我的端点在管理 contextPath 下可用...

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    Endpoint 类的实例公开为 bean; Spring Boot 的执行器自动配置will discover it。例如:

    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";
                }
            };
        }
    }
    

    【讨论】:

    • 只是说,你可以通过curl 127.0.0.1:&lt;port&gt;/example调用它
    【解决方案2】:

    对于 Spring Boot 2,请查看示例: Spring Boot Actuator: 5.2. Custom Endpoint

    @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
      }
    }
    

    另见Introducing Actuator Endpoints in Spring Boot 2.0

    【讨论】:

      【解决方案3】:

      您可以使用AbstractMvcEndpoint 在单独的类中轻松实现它,并使用@RequestMapping 简化或将参数添加到端点,以便查找其他服务信息:

      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;
          }
      }
      

      另外,考虑一下这个很有趣(+info):

      如果您将此作为库功能,请考虑添加 使用 @ManagementContextConfiguration 注解的配置类 /META-INF/spring.factories 下的键 org.springframework.boot.actuate.autoconfigure.ManagementContextConfiguration。 如果你这样做,那么端点将移动到所有的子上下文 如果您的用户要求单独管理,则其他 MVC 端点 端口或地址。以这种方式声明的配置可以是 WebConfigurerAdapter 如果要添加静态资源(对于 实例)到管理端点。

      【讨论】:

        猜你喜欢
        • 2018-01-08
        • 1970-01-01
        • 2020-11-13
        • 2020-06-01
        • 2021-04-24
        • 1970-01-01
        • 1970-01-01
        • 2014-06-18
        • 2019-03-10
        相关资源
        最近更新 更多