Spring Boot 应用程序无法在 Kubernetes 集群上运行

meh*_*met 1 java spring-boot jhipster kubernetes microservices

我正在使用 jhipster 开发具有微服务架构的应用程序。即使我收到此警告,我也可以在开发模式下运行我的服务,但是当我收到此警告后在 kubernetes 集群上运行它时,pod 会在循环中一遍又一遍地重新启动。我有 4 个微服务和一个网关。全部都一样。先感谢您。

这是警告:

2020-05-06 06:06:51.415 WARN 1 --- [scoveryClient-1] c.netflix.discovery.TimedSupervisorTask : task supervisor timed out 
java.util.concurrent.TimeoutException: null 
at java.base/java.util.concurrent.FutureTask.get(Unknown Source) 
at com.netflix.discovery.TimedSupervisorTask.run(TimedSupervisorTask.java:68) 
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) 
at java.base/java.util.concurrent.FutureTask.run(Unknown Source) 
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) 
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.base/java.lang.Thread.run(Unknown Source)
Run Code Online (Sandbox Code Playgroud)

application.yml 文件:

# ===================================================================
# Spring Boot configuration.
#
# This configuration will be overridden by the Spring profile you use,
# for example application-dev.yml if you use the "dev" profile.
#
# More information on profiles: https://www.jhipster.tech/profiles/
# More information on configuration properties: https://www.jhipster.tech/common-application-properties/
# ===================================================================

# ===================================================================
# Standard Spring Boot properties.
# Full reference is available at:
# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
# ===================================================================

eureka:
  client:
    enabled: true
    healthcheck:
      enabled: true
    fetch-registry: true
    register-with-eureka: true
    instance-info-replication-interval-seconds: 10
    registry-fetch-interval-seconds: 10
  instance:
    appname: derinconfiguration
    instanceId: derinconfiguration:${spring.application.instance-id:${random.value}}
    lease-renewal-interval-in-seconds: 5
    lease-expiration-duration-in-seconds: 10
    status-page-url-path: ${management.endpoints.web.base-path}/info
    health-check-url-path: ${management.endpoints.web.base-path}/health
    metadata-map:
      zone: primary # This is needed for the load balancer
      profile: ${spring.profiles.active}
      version: #project.version#
      git-version: ${git.commit.id.describe:}
      git-commit: ${git.commit.id.abbrev:}
      git-branch: ${git.branch:}


# See https://github.com/Netflix/Hystrix/wiki/Configuration
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 30000
ribbon:
  ReadTimeout: 60000
  connection-timeout: 3000
  eureka:
    enabled: true
zuul:
  ignoredServices: '*'
  host:
    time-to-live: -1
    connect-timeout-millis: 5000
    max-per-route-connections: 10000
    max-total-connections: 5000
    socket-timeout-millis: 60000
  semaphore:
    max-semaphores: 500

management:
  endpoints:
    web:
      base-path: /management
      exposure:
        include: ['configprops', 'env', 'health', 'info', 'jhimetrics', 'logfile', 'loggers', 'prometheus', 'threaddump']
  endpoint:
    health:
      show-details: when_authorized
      roles: 'ROLE_ADMIN'
    jhimetrics:
      enabled: true
  info:
    git:
      mode: full
  health:
    mail:
      enabled: false # When using the MailService, configure an SMTP server and set this to true
  metrics:
    export:
      # Prometheus is the default metrics backend
      prometheus:
        enabled: true
        step: 60
    enable:
      http: true
      jvm: true
      logback: true
      process: true
      system: true
    distribution:
      percentiles-histogram:
        all: true
      percentiles:
        all: 0, 0.5, 0.75, 0.95, 0.99, 1.0
    tags:
      application: ${spring.application.name}
    web:
      server:
        request:
          autotime:
            enabled: true

spring:
  autoconfigure:
    exclude: org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration
  application:
    name: derinconfiguration
  jmx:
    enabled: false
  data:
    jpa:
      repositories:
        bootstrap-mode: deferred
  jpa:
    open-in-view: false
    properties:
      hibernate.jdbc.time_zone: UTC
      hibernate.id.new_generator_mappings: true
      hibernate.connection.provider_disables_autocommit: true
      hibernate.cache.use_second_level_cache: true
      hibernate.cache.use_query_cache: false
      hibernate.generate_statistics: false
      # modify batch size as necessary
      hibernate.jdbc.batch_size: 25
      hibernate.order_inserts: true
      hibernate.order_updates: true
      hibernate.query.fail_on_pagination_over_collection_fetch: true
      hibernate.query.in_clause_parameter_padding: true
      hibernate.cache.region.factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
      hibernate.cache.use_minimal_puts: true
      hibernate.cache.hazelcast.instance_name: derinconfiguration
      hibernate.cache.hazelcast.use_lite_member: true
    hibernate:
      ddl-auto: none
      naming:
        physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
        implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
  messages:
    basename: i18n/messages
  main:
    allow-bean-definition-overriding: true
  mvc:
    favicon:
      enabled: false
  task:
    execution:
      thread-name-prefix: derinconfiguration-task-
      pool:
        core-size: 2
        max-size: 50
        queue-capacity: 10000
    scheduling:
      thread-name-prefix: derinconfiguration-scheduling-
      pool:
        size: 2
  thymeleaf:
    mode: HTML
  output:
    ansi:
      console-available: true
security:
  oauth2:
    client:
      access-token-uri: http://localhost:9080/auth/realms/jhipster/protocol/openid-connect/token
      user-authorization-uri: http://localhost:9080/auth/realms/jhipster/protocol/openid-connect/auth
      client-id: web_app
      client-secret: web_app
      scope: openid profile email
    resource:
      filter-order: 3
      user-info-uri: http://localhost:9080/auth/realms/jhipster/protocol/openid-connect/userinfo

server:
  servlet:
    session:
      cookie:
        http-only: true

# Properties to be exposed on the /info management endpoint
info:
  # Comma separated list of profiles that will trigger the ribbon to show
  display-ribbon-on-profiles: 'dev'

# ===================================================================
# JHipster specific properties
#
# Full reference is available at: https://www.jhipster.tech/common-application-properties/
# ===================================================================

jhipster:
  clientApp:
    name: 'derinconfigurationApp'
  # By default CORS is disabled. Uncomment to enable.
  # cors:
  #     allowed-origins: "*"
  #     allowed-methods: "*"
  #     allowed-headers: "*"
  #     exposed-headers: "Authorization,Link,X-Total-Count"
  #     allow-credentials: true
  #     max-age: 1800
  mail:
    from: derinconfiguration@localhost
  swagger:
    default-include-pattern: /api/.*
    title: derinconfiguration API
    description: derinconfiguration API documentation
    version: 0.0.1
    terms-of-service-url:
    contact-name:
    contact-url:
    contact-email:
    license:
    license-url:
kafka:
  bootstrap-servers: localhost:9092
  consumer:
    key.deserializer: org.apache.kafka.common.serialization.StringDeserializer
    value.deserializer: org.apache.kafka.common.serialization.StringDeserializer
    group.id: derinconfiguration
    auto.offset.reset: earliest
  producer:
    key.serializer: org.apache.kafka.common.serialization.StringSerializer
    value.serializer: org.apache.kafka.common.serialization.StringSerializer
# ===================================================================
# Application specific properties
# Add your own application properties here, see the ApplicationProperties class
# to have type-safe configuration, like in the JHipsterProperties above
#
# More documentation is available at:
# https://www.jhipster.tech/common-application-properties/
# ===================================================================

# application:
Run Code Online (Sandbox Code Playgroud)

库伯内特斯配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: derinconfiguration
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: derinconfiguration
      version: 'v1'
  template:
    metadata:
      labels:
        app: derinconfiguration
        version: 'v1'
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - podAffinityTerm:
                labelSelector:
                  matchExpressions:
                    - key: app
                      operator: In
                      values:
                        - derinconfiguration
                topologyKey: kubernetes.io/hostname
              weight: 100
      initContainers:
        - name: init-ds
          image: busybox:latest
          command:
            - '/bin/sh'
            - '-c'
            - |
              while true
              do
                rt=$(nc -z -w 1 192.168.1.156 5432)
                if [ $? -eq 0 ]; then
                  echo "DB is UP"
                  break
                fi
                echo "DB is not yet reachable;sleep for 10s before retry"
                sleep 10
              done
      containers:
        - name: derinconfiguration-app
          image: 192.168.1.150:5000/derin/derinconfiguration
          env:
            - name: SPRING_PROFILES_ACTIVE
              value: prod
            - name: SPRING_CLOUD_CONFIG_URI
              value: http://admin:${jhipster.registry.password}@jhipster-registry.default.svc.cluster.local:8761/config
            - name: JHIPSTER_REGISTRY_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: registry-secret
                  key: registry-admin-password
            - name: EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE
              value: http://admin:${jhipster.registry.password}@jhipster-registry.default.svc.cluster.local:8761/eureka/
            - name: SPRING_DATASOURCE_URL
              value: jdbc:postgresql://192.168.1.156:5432/derinfw
            - name: SPRING_DATASOURCE_USERNAME
              value: admin
            - name: SPRING_DATASOURCE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgresql-secret
                  key: postgresql-admin-password
            - name: KAFKA_CONSUMER_KEY_DESERIALIZER
              value: 'org.apache.kafka.common.serialization.StringDeserializer'
            - name: KAFKA_CONSUMER_VALUE_DESERIALIZER
              value: 'org.apache.kafka.common.serialization.StringDeserializer'
            - name: KAFKA_CONSUMER_BOOTSTRAP_SERVERS
              value: 'jhipster-kafka.default.svc.cluster.local:9092'
            - name: KAFKA_CONSUMER_GROUP_ID
              value: 'derinconfiguration'
            - name: KAFKA_CONSUMER_AUTO_OFFSET_RESET
              value: 'earliest'
            - name: KAFKA_PRODUCER_BOOTSTRAP_SERVERS
              value: 'jhipster-kafka.default.svc.cluster.local:9092'
            - name: KAFKA_PRODUCER_KEY_DESERIALIZER
              value: 'org.apache.kafka.common.serialization.StringDeserializer'
            - name: KAFKA_PRODUCER_VALUE_DESERIALIZER
              value: 'org.apache.kafka.common.serialization.StringDeserializer'
            - name: JHIPSTER_METRICS_LOGS_ENABLED
              value: 'true'
            - name: JHIPSTER_LOGGING_LOGSTASH_ENABLED
              value: 'true'
            - name: JHIPSTER_LOGGING_LOGSTASH_HOST
              value: jhipster-logstash
            - name: SPRING_ZIPKIN_ENABLED
              value: 'true'
            - name: SPRING_ZIPKIN_BASE_URL
              value: http://jhipster-zipkin
            - name: SPRING_SLEUTH_PROPAGATION_KEYS
              value: 'x-request-id,x-ot-span-context'
            - name: JAVA_OPTS
              value: ' -Xmx256m -Xms256m'
          resources:
            requests:
              memory: '512Mi'
              cpu: '500m'
            limits:
              memory: '1Gi'
              cpu: '1'
          ports:
            - name: http
              containerPort: 8084
          readinessProbe:
            httpGet:
              path: /management/health
              port: http
            initialDelaySeconds: 20
            periodSeconds: 15
            failureThreshold: 6
          livenessProbe:
            httpGet:
              path: /management/health
              port: http
            initialDelaySeconds: 120
Run Code Online (Sandbox Code Playgroud)

Nic*_*ick 5

\n

您是否尝试过禁用就绪性和活性探测器?\xe2\x80\x93 尼克

\n

在我删除就绪性和活性探测器后,它现在可以工作了。看来需要额外的时间来运行。\xe2\x80\x93 穆罕默德

\n
\n

当由于某种原因探测器需要很长时间才能返回结果时,这是很常见的情况。

\n

有时,您必须处理旧应用程序,这些应用程序在首次初始化时可能需要额外的启动时间。在这种情况下,在不影响对引发此类探测的死锁的快速响应的情况下设置活性探测参数可能会很棘手。

\n

诀窍是使用相同的命令、HTTP 或 TCP 检查来设置启动探测器,并具有failureThreshold * periodSeconds足够长的时间来覆盖最坏情况下的启动时间。

\n
livenessProbe:\n  httpGet:\n    path: /healthz\n    port: liveness-port\n  failureThreshold: 1\n  periodSeconds: 10\n
Run Code Online (Sandbox Code Playgroud)\n

Probes有许多字段可用于更精确地控制活动性和就绪性检查的行为:

\n

initialDelaySeconds:容器启动后启动活动或就绪探测之前的秒数。默认为 0 秒。最小值为 0。

\n

periodSeconds:执行探测的频率(以秒为单位)。默认为 10 秒。最小值为 1。

\n

readiness probe查看您的 YAML 文件,我首先从更改开始

\n
readinessProbe:\n httpGet:\n   path: /management/health\n initialDelaySeconds: 20\n periodSeconds: 15\n failureThreshold: 6\n\nlivenessProbe:\n httpGet:\n   path: /management/health\n initialDelaySeconds: 120\n
Run Code Online (Sandbox Code Playgroud)\n

这意味着 20+(6*15)=110 秒后就绪探测将失败。同时liveness探头延迟设置为 120 秒。我会将探测延迟增加到readiness与延迟相同的值livenes,以防止出现流量发送到未完全启动并运行的 Pod 的情况。

\n

以下是Kubernetes 官方文档中有关探针的一些信息:

\n

活性探针

\n

许多长时间运行的应用程序最终会转变为损坏状态,并且除非重新启动否则无法恢复。Kubernetes 提供了活性探针来检测和修复此类情况。

\n

就绪探针

\n

有时,应用程序暂时无法提供流量。例如,应用程序可能需要在启动时加载大量数据或配置文件,或者在启动后依赖外部服务。在这种情况下,您不想终止该应用程序,但也不想向其发送请求。Kubernetes 提供就绪探针来检测和缓解这些情况。包含报告未准备就绪的容器的 Pod 不会通过 Kubernetes 服务接收流量。

\n
\n

注意:就绪探针在容器的整个生命周期中在容器上运行。

\n
\n

就绪探针的配置与活性探针类似。唯一的区别是您使用的是readinessProbe字段而不是字段livenessProbe

\n
readinessProbe:\n  exec:\n    command:\n    - cat\n    - /tmp/healthy\n  initialDelaySeconds: 5\n  periodSeconds: 5\n
Run Code Online (Sandbox Code Playgroud)\n

希望有帮助。

\n