没有http的微服务的活性探测
liveness probe for microservice without http
我有一个不是网络服务的微服务。
它是一个 Spring Boot (1.5) CommandLineRunner 应用程序,不需要公开 API 或使用 http 做任何事情。
但是,我需要给它一个 Kubernetes 的活性探测。
是否可以在不将其重构为网络服务应用程序的情况下实现这一目标?
我添加了此配置以启用 Spring 的信息端点
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
我实施了这个健康检查class
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");
}
}
}
这个想法可行吗?或者我是否必须重构它来处理网络请求?
感谢您提供任何线索
您可以公开执行器端点详细信息,包括使用 JMX 的健康检查。
示例application.yml
management:
endpoints:
jmx:
exposure:
include: health,info,metrics,mappings
然后将活性探测定义为 运行 脚本(或 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
正在尝试 stringy05 的想法...
启用的 jmx 端点:
management:
endpoints:
jmx:
exposure:
include: "*"
exclude:
endpoint:
health:
enabled: true
info:
enabled: true
使用这个答案:
Calling JMX MBean method from a shell script
我试过这个:
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 class
@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 脚本中。
谢谢!
我有一个不是网络服务的微服务。
它是一个 Spring Boot (1.5) CommandLineRunner 应用程序,不需要公开 API 或使用 http 做任何事情。
但是,我需要给它一个 Kubernetes 的活性探测。
是否可以在不将其重构为网络服务应用程序的情况下实现这一目标?
我添加了此配置以启用 Spring 的信息端点
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
我实施了这个健康检查class
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");
}
}
}
这个想法可行吗?或者我是否必须重构它来处理网络请求?
感谢您提供任何线索
您可以公开执行器端点详细信息,包括使用 JMX 的健康检查。
示例application.yml
management:
endpoints:
jmx:
exposure:
include: health,info,metrics,mappings
然后将活性探测定义为 运行 脚本(或 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
正在尝试 stringy05 的想法...
启用的 jmx 端点:
management:
endpoints:
jmx:
exposure:
include: "*"
exclude:
endpoint:
health:
enabled: true
info:
enabled: true
使用这个答案:
Calling JMX MBean method from a shell script
我试过这个:
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 class
@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 脚本中。
谢谢!