5

我有一个不是 Web 服务的微服务。

它是一个 Spring Boot (1.5) CommandLineRunner 应用程序,不需要公开 API 或对 http 执行任何操作。

但是,我需要给它一个 Kubernetes 的活性探测。

这可以在不将其重构为 Web 服务应用程序的情况下完成吗?

我添加了这个配置来启用 Spring 的 info 端点

management:
  endpoint:
    health:
      enabled: true
    info:
      enabled: true

# https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready-endpoints
info:
  app:
    name: foo-parser
    description: parses binary files from S3 and updates the database

我实现了这个健康检查类

import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health.Builder;

@Component
public class HealthCheck extends AbstractHealthIndicator {

  Logger log = LoggerFactory.getLogger("jsonLogger");

  private final MySQLAccessor mySQLAccessor;
  private static final String FOO_TABLE = "foo";

  @Autowired
  public HealthCheck(final MySQLAccessor mySQLAccessor) {
    this.mySQLAccessor = mySQLAccessor;
  }

  @Override
  protected void doHealthCheck(Builder builder) throws Exception {
    boolean result = mySQLAccessor.healthCheck(FOO_TABLE);
    if (result) {
      log.info("HELLO! the health check is good!");
      builder.up().withDetail("test", "good");
    }
    else {
      log.info("HELLO! OH NOES the health check is ungood!");
      builder.down().withDetail("test", "bad");
    }
  }
}


这个想法可行吗?还是我必须重构它以服务 Web 请求?

谢谢你的任何线索

4

2 回答 2

2

您可以使用 JMX 公开执行器端点详细信息,包括运行状况检查。

例子application.yml

management:
  endpoints:
    jmx:
      exposure:
        include: health,info,metrics,mappings

然后定义 liveness 探针以运行脚本(或 java 程序)来调用 JMX 端点并回答运行状况检查:

示例 k8s 配置

apiVersion: v1
kind: Pod
spec:
  containers:
  - name: liveness
    image: my-app 
    livenessProbe:
      exec:
        command:
        - /bin/sh
        - test_app_with_jmx.sh 
      initialDelaySeconds: 5
      periodSeconds: 5
于 2020-06-04T03:35:54.377 回答
1

尝试 stringy05 的想法...

启用 jmx 端点:

management:
  endpoints:
    jmx:
      exposure:
        include: "*"
        exclude:
  endpoint:
    health:
      enabled: true
    info:
      enabled: true

使用这个答案:

从 shell 脚本调用 JMX MBean 方法

我试过这个:

import javax.management.*;
import javax.management.remote.*;

public class JMXInvoker {

  public static void main(String... args) throws Exception {
    Object result = JMXConnectorFactory.connect(new JMXServiceURL(args[0]))
        .getMBeanServerConnection().invoke(new ObjectName(args[1]), args[2], new Object[]{}, new String[]{});
    String status = "" + result;
    String state = status.substring(8,10);
    Boolean ok = state.compareTo("UP") == 0;
    if (!ok)
      System.exit(1);
  }
}

在主应用程序类中添加了一些与 JMX 相关的 bean

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class FooParserApplication implements CommandLineRunner {

  Logger log = LoggerFactory.getLogger("jsonLogger");
  @Autowired
  private FooStuff fooStuff;

  @Bean
  public RmiRegistryFactoryBean rmi() {
    RmiRegistryFactoryBean rmi = new RmiRegistryFactoryBean();
    rmi.setPort(5555);
    return rmi;
  }

  @Bean
  public ConnectorServerFactoryBean server() throws Exception {
    ConnectorServerFactoryBean fb = new ConnectorServerFactoryBean();
    fb.setObjectName("connector:name=rmi");
    fb.setServiceUrl("service:jmx:rmi://localhost/jndi/rmi://localhost:5555/myconnector");
    return fb;
  }

  public static void main(final String[] args) {
    final SpringApplication springApplication = new SpringApplication(ECHParserApplication.class);
    springApplication.run(args);
  }

  @Override
  public void run(final String... args) {
     fooStuff.doIt()
  }
}

从 bash 调用它:

java -cp foo-parser.jar -Dloader.main=com.foo.JMXInvoker org.springframework.boot.loader.PropertiesLauncher service:jmx:rmi://localhost/jndi/rmi://localhost:5555/myconnector org.springframework.boot:type=Endpoint,name=Health health

现在我只需要将它放入 Kubernetes 的 bash 脚本中。

谢谢!

于 2020-06-04T21:37:41.460 回答