我们目前正在使用Spring Boot Admin来监控OpenShift集群中的微服务
Spring Boot Admin应用程序使用Spring cloud starter kubernetes依赖项从Openshift的服务发现中获取有关服务的信息。
在我们使用自定义server.servlet.context路径.部署应用程序之前,一切都很好
例如,我们的微服务有server.servlet.context path=/didictionary。然而,Spring Boot Admin从OpenShift的发现中获得以下信息:
{
"registration": {
"name": "dictionary-service",
"managementUrl": "http://10.130.1.169:8080/actuator",
"healthUrl": "http://10.130.1.169:8080/actuator/health",
"serviceUrl": "http://10.130.1.169:8080/",
"source": "discovery",
"metadata": {
"app": "dictionary-service",
...
}
}
}
因此,Spring Boot Admin期望执行器在"http://10.130.1.169:8080/actuator"
上工作,但实际上它在"http://10.130.1.169:8080/dictionary/actuator"
上工作
我们如何自定义managementUrl和healthUrl,以便我们的Spring Boot管理服务器可以使用正确的URL来监控此服务?
我遇到了同样的问题。但用另一种解决方案解决了问题:
- 我更改了Spring Boot应用程序上的管理端口
management.server.port=8090
server.port=8080
现在管理端点(/致动器、/致动器/健康(不受";server.servlet.context路径";。
- 我打开了k8s部署上的端口
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 1
template:
spec:
containers:
- name: app
image: ${docker_image}
ports:
- containerPort: 8080
- containerPort: 8090
- 我在k8s服务上用名称声明了端口
kind: Service
apiVersion: v1
metadata:
name: app-service
spec:
selector:
app: app
ports:
- protocol: TCP
port: 8080
targetPort: 8080
name: api
- protocol: TCP
port: 8090
targetPort: 8090
name: management
- 我对Spring Boot Admin交换机说要使用的端口名
spring.cloud.kubernetes.discovery.primary-port-name=management
好的,所以我终于解决了它。也许它会对某人有所帮助。
问题中的"registration">对象在Spring Boot Admin中生成。这是ServiceInstanceConverter接口的可靠性。默认情况下,使用DefaultServiceInstanceConverter实现(您可以在此处阅读更多信息(。
有几个元数据键可用于修改管理URL和健康URL/actuator">"/ectuator/health">
首先,我认为我们可以使用management.context path元数据键来附加我们的server.servlet.context path,但不幸的是,您不能在元数据标签值中使用"/"字符("dictionary/activator"无效(,所以在我的情况下这还不够。
相反,我们决定扩展DefaultServiceInstanceConverter并覆盖convert和getManagementPath方法:
@Component
public class OpenShiftServiceInstanceConverter extends DefaultServiceInstanceConverter {
private static final String MANAGEMENT_CONTEXT_PATH = "/actuator";
private static final String MANAGEMENT_PREFIX = "management.prefix";
@Override
public Registration convert(ServiceInstance instance) {
return Registration.create(instance.getServiceId(), getHealthUrl(instance).toString())
.managementUrl(getManagementUrl(instance).toString()).serviceUrl(getServiceUrl(instance).toString())
.metadata(getMetadata(instance)).build();
}
@Override
protected String getManagementPath(ServiceInstance instance) {
String managementPath = instance.getMetadata().get(MANAGEMENT_PREFIX);
if (!isEmpty(managementPath)) {
return managementPath + MANAGEMENT_CONTEXT_PATH;
}
return MANAGEMENT_CONTEXT_PATH;
}
}
通过这种方式,我们可以在服务模板中包含server.servlet.context path作为元数据managementprefix密钥
kind: Template
apiVersion: v1
metadata:
name: dictionary-service
annotations:
description: Template for Dictionary Service 1.0.0
labels:
app: dictionary-service
management.prefix: dictionary
...
现在它就像一个符咒。
如果添加一个"management.context path";服务元数据的注释,例如:
apiVersion: v1
kind: Service
metadata:
name: carts
annotations:
management.context-path: /carts/actuator
Spring Boot Admin DefaultServiceInstanceConverter将自动从Spring Cloud Discovery元数据中读取并查找该元数据以设置正确的管理&健康路径。要使其工作,您需要将属性spring.cloud.kubernetes.discovery.metadata.add-annotations
设置为true(无论如何,这是默认值(
附言:我没有一个OpenShift集群可以测试,但它在本地的minikube和Amazon EKS集群上对我有效。