Spring Boot java.net.ConnectException:在Sping Boot 和Keycloak中使用docker-compose时连接被拒绝

dkqlctbz  于 5个月前  发布在  Spring
关注(0)|答案(1)|浏览(48)

我确实有几个Sping Boot 服务作为docker-compose文件的一部分。

Caused by: java.lang.IllegalArgumentException: Unable to resolve Configuration with the provided Issuer of "http://iam-service:8080/realms/OptionAdvisor"
        at org.springframework.security.oauth2.client.registration.ClientRegistrations.getBuilder(ClientRegistrations.java:228) ~[spring-security-oauth2-client-6.0.2.jar:6.0.2]
        at org.springframework.security.oauth2.client.registration.ClientRegistrations.fromIssuerLocation(ClientRegistrations.java:152) ~[spring-security-oauth2-client-6.0.2.jar:6.0.2]
        at org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesRegistrationAdapter.getBuilderFromIssuerIfPossible(OAuth2ClientPropertiesRegistrationAdapter.java:86) ~[spring-boot-autoconfigure-3.0.4.jar:3.0.4]
        at org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesRegistrationAdapter.getClientRegistration(OAuth2ClientPropertiesRegistrationAdapter.java:60) ~[spring-boot-autoconfigure-3.0.4.jar:3.0.4]
        at org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesRegistrationAdapter.lambda$getClientRegistrations$0(OAuth2ClientPropertiesRegistrationAdapter.java:54) ~[spring-boot-autoconfigure-3.0.4.jar:3.0.4]
        at java.base/java.util.HashMap.forEach(HashMap.java:1425) ~[na:na]
        at org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesRegistrationAdapter.getClientRegistrations(OAuth2ClientPropertiesRegistrationAdapter.java:53) ~[spring-boot-autoconfigure-3.0.4.jar:3.0.4]
        at org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientRegistrationRepositoryConfiguration.clientRegistrationRepository(OAuth2ClientRegistrationRepositoryConfiguration.java:49) ~[spring-boot-autoconfigure-3.0.4.jar:3.0.4]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139) ~[spring-beans-6.0.6.jar:6.0.6]
        ... 81 common frames omitted
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://iam-service:8080/realms/OptionAdvisor/.well-known/openid-configuration": Connection refused
        at org.springframework.web.client.RestTemplate.createResourceAccessException(RestTemplate.java:888) ~[spring-web-6.0.6.jar:6.0.6]
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:868) ~[spring-web-6.0.6.jar:6.0.6]
        at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:714) ~[spring-web-6.0.6.jar:6.0.6]
        at org.springframework.security.oauth2.client.registration.ClientRegistrations.lambda$oidc$0(ClientRegistrations.java:163) ~[spring-security-oauth2-client-6.0.2.jar:6.0.2]
        at org.springframework.security.oauth2.client.registration.ClientRegistrations.getBuilder(ClientRegistrations.java:216) ~[spring-security-oauth2-client-6.0.2.jar:6.0.2]
        ... 93 common frames omitted
Caused by: java.net.ConnectException: Connection refused
        at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
        at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:669) ~[na:na]
        at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) ~[na:na]
        at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597) ~[na:na]
        at java.base/java.net.Socket.connect(Socket.java:630) ~[na:na]
        at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:177) ~[na:na]
        at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:497) ~[na:na]
        at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:600) ~[na:na]
        at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:246) ~[na:na]
        at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:351) ~[na:na]
        at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:372) ~[na:na]
        at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1299) ~[na:na]
        at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1232) ~[na:na]
        at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1120) ~[na:na]
        at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1051) ~[na:na]
        at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:75) ~[spring-web-6.0.6.jar:6.0.6]
        at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-6.0.6.jar:6.0.6]
        at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66) ~[spring-web-6.0.6.jar:6.0.6]
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:862) ~[spring-web-6.0.6.jar:6.0.6]
        ... 96 common frames omitted

字符串
我不知道为什么我会看到http://iam-service:8080/realms/OptionAdvisor/.well-known/openid-configuration": Connection refused。当我从另一个容器执行wget http://iam-service:8080/realms/OptionAdvisor/.well-known/openid-configuration时,我得到了预期的响应。当我在主机的浏览器中访问http://localhost:8080/realms/OptionAdvisor/.well-known/openid-configuration时,我也得到了预期的响应。
你有什么提示给我什么可能导致这个?下一步你会做什么来调试这个?
这是我的docker-compose.yml文件的样子(ranking-service,decision-service和compare-decision-service受到此问题的影响):

version: '3.8'
services:
  db-service:
    image: postgres:15.2
    environment:
      - POSTGRES_USER=${POSTGRESDB_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_MULTIPLE_DATABASES=${KC_DB_NAME},${RANKING_STRATEGY_SERVICE_DB_NAME},${COMPARE_DECISION_SERVICE_DB_NAME},${SECRET_SERVICE_DB_NAME},${RANKING_SERVICE_DB_NAME},${DECISION_SERVICE_DB_NAME}
    ports:
      - ${POSTGRESDB_LOCAL_PORT}:${POSTGRESDB_DOCKER_PORT}
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./postgresinit/:/docker-entrypoint-initdb.d
  iam-service:
    image: quay.io/keycloak/keycloak:23.0.0
    volumes:
      - ./imports/OptionAdvisorRealm.json:/opt/keycloak/data/import/OptionAdvisorRealm.json
    environment:     
      - KEYCLOAK_ADMIN=${KC_ADMIN}
      - KEYCLOAK_ADMIN_PASSWORD=${KC_ADMIN_PASSWORD}
      - KC_DB=${KC_DB}
      - KC_DB_USERNAME=${POSTGRESDB_USER}
      - KC_DB_PASSWORD=${POSTGRES_PASSWORD}
      - KC_DB_URL=${KC_DB_URL}
    ports:
      - ${KC_LOCAL_PORT}:${KC_DOCKER_PORT}
    entrypoint: "/opt/keycloak/bin/kc.sh start-dev --import-realm"
    depends_on:
      - db-service
  ranking-strategy-service:
    build:
      context: ../ranking-strategy-service
      dockerfile: Dockerfile
    ports:
      - ${RANKING_STRATEGY_SERVICE_LOCAL_PORT}:${RANKING_STRATEGY_SERVICE_DOCKER_PORT}
    depends_on:
      - iam-service
      - db-service
    environment:
      - SPRING_DATASOURCE_URL=${RANKING_STRATEGY_SERVICE_DATASOURCE_URL}
      - SPRING_DATASOURCE_USERNAME=${POSTGRESDB_USER}
      - SPRING_DATASOURCE_PASSWORD=${POSTGRES_PASSWORD}
      - IAM_SERVICE.BASE_URL=${KC_BASE_URL}
      - SPRING_PROFILES_ACTIVE=dev
  secret-service:
    build:
      context: ../secret-service
      dockerfile: Dockerfile
    ports:
      - ${SECRET_SERVICE_LOCAL_PORT}:${SECRET_SERVICE_DOCKER_PORT}
    depends_on:
      - iam-service
      - db-service
    environment:
      - SPRING_DATASOURCE_URL=${SECRET_SERVICE_DATASOURCE_URL}
      - SPRING_DATASOURCE_USERNAME=${POSTGRESDB_USER}
      - SPRING_DATASOURCE_PASSWORD=${POSTGRES_PASSWORD}
      - IAM_SERVICE.BASE_URL=${KC_BASE_URL}
      - SPRING_PROFILES_ACTIVE=dev
  compare-decision-service:
    build:
      context: ../compare-decision-service
      dockerfile: Dockerfile
    ports:
      - ${COMPARE_DECISION_SERVICE_LOCAL_PORT}:${COMPARE_DECISION_SERVICE_DOCKER_PORT}
    depends_on:
      - iam-service
      - ranking-strategy-service
      - db-service
      - secret-service
    environment:
      - SPRING_DATASOURCE_URL=${COMPARE_DECISION_SERVICE_DATASOURCE_URL}
      - SPRING_DATASOURCE_USERNAME=${POSTGRESDB_USER}
      - SPRING_DATASOURCE_PASSWORD=${POSTGRES_PASSWORD}
      - IAM_SERVICE.BASE_URL=${KC_BASE_URL}
      - SECRET_SERVICE.BASE_URL=${SECRET_SERVICE_BASE_URL}
      - RANKING_STRATEGY_SERVICE.BASE_URL=${RANKING_STRATEGY_SERVICE_BASE_URL}
      - DECISION_SERVICE.BASE_URL=${DECISION_SERVICE_BASE_URL}
      - RANKING_SERVICE.BASE_URL=${RANKING_SERVICE_BASE_URL}
      - SPRING_PROFILES_ACTIVE=dev      
  ranking-service:
    build:
      context: ../ranking-service
      dockerfile: Dockerfile
    ports:
      - ${RANKING_SERVICE_LOCAL_PORT}:${RANKING_SERVICE_DOCKER_PORT}
    depends_on:
      - iam-service
      - db-service
      - secret-service
    environment:
      - SPRING_DATASOURCE_URL=${RANKING_SERVICE_DATASOURCE_URL}
      - SPRING_DATASOURCE_USERNAME=${POSTGRESDB_USER}
      - SPRING_DATASOURCE_PASSWORD=${POSTGRES_PASSWORD}
      - IAM_SERVICE.BASE_URL=${KC_BASE_URL}
      - SECRET_SERVICE.BASE_URL=${SECRET_SERVICE_BASE_URL}
      - SPRING_PROFILES_ACTIVE=dev
  decision-service:
    build:
      context: ../decision-service
      dockerfile: Dockerfile
    ports:
      - ${DECISION_SERVICE_LOCAL_PORT}:${DECISION_SERVICE_DOCKER_PORT}
    depends_on:
      - iam-service
      - db-service
      - secret-service
      - ranking-service
      - ranking-strategy-service
    environment:
      - SPRING_DATASOURCE_URL=${DECISION_SERVICE_DATASOURCE_URL}
      - SPRING_DATASOURCE_USERNAME=${POSTGRESDB_USER}
      - SPRING_DATASOURCE_PASSWORD=${POSTGRES_PASSWORD}
      - IAM_SERVICE.BASE_URL=${KC_BASE_URL}
      - SECRET_SERVICE.BASE_URL=${SECRET_SERVICE_BASE_URL}
      - RANKING_SERVICE.BASE_URL=${RANKING_SERVICE_BASE_URL}
      - SPRING_PROFILES_ACTIVE=dev
volumes:
  pgdata:


这就是我的.env文件的样子

POSTGRESDB_USER=admin
POSTGRES_PASSWORD=password
POSTGRESDB_LOCAL_PORT=5432
POSTGRESDB_DOCKER_PORT=5432
POSTGRESDB_BASE_URL=postgresql://db-service:${POSTGRESDB_DOCKER_PORT}

KC_ADMIN=admin
KC_ADMIN_PASSWORD=password
KC_DB=postgres
KC_DB_NAME=iam_service_db
KC_DB_URL=jdbc:${POSTGRESDB_BASE_URL}/${KC_DB_NAME}
KC_LOCAL_PORT=8080
KC_DOCKER_PORT=8080
KC_BASE_URL=http://iam-service:${KC_DOCKER_PORT}

RANKING_STRATEGY_SERVICE_LOCAL_PORT=8083
RANKING_STRATEGY_SERVICE_DOCKER_PORT=8083
RANKING_STRATEGY_SERVICE_DB_NAME=ranking_strategy_service_db
RANKING_STRATEGY_SERVICE_DATASOURCE_URL=jdbc:${POSTGRESDB_BASE_URL}/${RANKING_STRATEGY_SERVICE_DB_NAME}
RANKING_STRATEGY_SERVICE_BASE_URL=http://ranking-strategy-service:${RANKING_STRATEGY_SERVICE_DOCKER_PORT}

SECRET_SERVICE_LOCAL_PORT=8082
SECRET_SERVICE_DOCKER_PORT=8082
SECRET_SERVICE_DB_NAME=secret_service_db
SECRET_SERVICE_DATASOURCE_URL=jdbc:${POSTGRESDB_BASE_URL}/${SECRET_SERVICE_DB_NAME}
SECRET_SERVICE_BASE_URL=http://secret-service:${SECRET_SERVICE_DOCKER_PORT}

COMPARE_DECISION_SERVICE_LOCAL_PORT=8084
COMPARE_DECISION_SERVICE_DOCKER_PORT=8084
COMPARE_DECISION_SERVICE_DB_NAME=compare_decision_service_db
COMPARE_DECISION_SERVICE_DATASOURCE_URL=jdbc:${POSTGRESDB_BASE_URL}/${COMPARE_DECISION_SERVICE_DB_NAME}

RANKING_SERVICE_LOCAL_PORT=8085
RANKING_SERVICE_DOCKER_PORT=8085
RANKING_SERVICE_DB_NAME=ranking_service_db
RANKING_SERVICE_DATASOURCE_URL=jdbc:${POSTGRESDB_BASE_URL}/${RANKING_SERVICE_DB_NAME}
RANKING_SERVICE_BASE_URL=http://ranking-service:${RANKING_SERVICE_DOCKER_PORT}

DECISION_SERVICE_LOCAL_PORT=8081
DECISION_SERVICE_DOCKER_PORT=8081
DECISION_SERVICE_DB_NAME=decision_service_db
DECISION_SERVICE_DATASOURCE_URL=jdbc:${POSTGRESDB_BASE_URL}/${DECISION_SERVICE_DB_NAME}
DECISION_SERVICE_BASE_URL=http://decisiony-service:${DECISION_SERVICE_DOCKER_PORT}


这就是我的排名服务的application.yml文件的样子

iam-service:
  base-url: http://localhost:8080
secret-service:
  base-url: http://localhost:8082
spring:
  datasource:
    url: "jdbc:postgresql://localhost:5432/decision-service"
    username: postgres
  application:
    name: ranking-service
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: ${iam-service.base-url}/realms/OptionAdvisor
          jwk-set-uri: ${iam-service.base-url}/realms/OptionAdvisor/protocol/openid-connect/certs
      client:
        registration:
          ranking-service:
            client-id: ${spring.application.name}
            client-secret: ranking-service-secret
            authorization-grant-type: client_credentials
        provider:
          ranking-service:
            issuer-uri: ${iam-service.base-url}/realms/OptionAdvisor
            token-uri: ${iam-service.base-url}/realms/OptionAdvisor/protocol/openid-connect/token
            user-name-attribute: preferred_username
server:
  servlet:
    context-path: /ranking_service/api
  port: 8085


这就是我的ranking-service的application-dev.yml文件的样子

logging:
  level:
    org:
      hibernate:
        SQL: TRACE
      x:
        optionadvisor:
          rankingservice: DEBUG
spring:
  jpa:
    hibernate:
      ddl-auto: create-drop

fkaflof6

fkaflof61#

问题是docker-compose depends on并不像我最初想象的那样工作。我以为容器的启动会等待所有依赖容器的完全启动。但似乎需要通过healthchecks添加:
https://docs.docker.com/compose/startup-order/

相关问题