2

我们目前正在使用 Spring Boot Admin 来监控 OpenShift 集群内的微服务。Spring Boot Admin 应用程序使用spring-cloud-starter-kubernetes依赖 项
从 Openshift 的服务发现中获取有关服务的信息。

在我们使用自定义server.servlet.context-path部署应用程序之前,一切都很好。

例如,我们的微服务有server.servlet.context-path=/dictionary。但是,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"

我们如何自定义managementUrlhealthUrl以便我们的 Spring Boot 管理服务器可以使用正确的 URL 来监视此服务?

4

2 回答 2

2

我遇到了同样的问题。但用其他解决方案解决:

  1. 我更改了 Spring Boot 应用程序的管理端口
management.server.port=8090
server.port=8080

现在管理端点(/actuator、/actuator/health)不受“server.servlet.context-path”的影响。

  1. 我在我的 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
  1. 我在我的 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
  1. 我对 Spring Boot Admin 说要使用的女巫端口名称
spring.cloud.kubernetes.discovery.primary-port-name=management
于 2020-06-24T09:28:43.600 回答
1

好的,所以我终于解决了。也许它会对某人有所帮助。

问题中的“注册”对象是在 Spring Boot Admin 本身中生成的。这是ServiceInstanceConverter接口的可靠性。默认情况下,使用DefaultServiceInstanceConverter实现(您可以在此处阅读有关此内容的更多信息)。

有几个元数据键可用于修改managementUrlhealthUrl(默认情况下,分别使用“/actuator”“/actuator/health”)。

首先,我认为我们可以使用management.context-path元数据键来附加我们的server.servlet.context-path,但不幸的是,您不能在元数据标签值中使用“/”字符(“dictionary/actuator”无效) ,所以在我的情况下还不够。

相反,我们决定扩展DefaultServiceInstanceConverter并覆盖convertgetManagementPath方法:

@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作为元数据management.prefix键包含在服务模板中:

kind: Template
apiVersion: v1
metadata:
  name: dictionary-service
annotations:
  description: Template for Dictionary Service 1.0.0
labels:
  app: dictionary-service
  management.prefix: dictionary
...

现在它就像一个魅力。

于 2020-03-19T14:09:58.223 回答