Исключение в потоке монитора при подключении к серверу

Я создал среду докера, которая работает

  1. mongo — запускает mongodb
  2. mongoimport — вводит фиктивные данные
  3. ordersearchservice — микросервисное приложение с пружинной загрузкой
  4. Productinfoservice — микросервисное приложение Spring-Boot
  5. userinfoservice — приложение микросервиса с пружинной загрузкой

userinfoservice — единственный, которому на данный момент необходимо подключиться к mongodb. Предполагается получить данные пользователя из документа mongodb. Все работает нормально, если я запускаю его вне контейнера докеров, но если я запускаю контейнер, соединение mongodb работает неправильно. Есть две ошибки.

  1. Ошибка при запуске userinfoservice
Exception in monitor thread while connecting to server localhost:27017
userinfoservice-1     |
userinfoservice-1     | com.mongodb.MongoSocketOpenException: Exception opening socket
userinfoservice-1     |         at 
  1. Ошибка при обращении к контроллеру из почтальона (или даже напрямую из браузера)
userinfoservice-1     | org.springframework.dao.DataAccessResourceFailureException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception = {com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/[0:0:0:0:0:0:0:1]:27017}, caused by {java.net.ConnectException: Connection refused}}]
userinfoservice-1     |         at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:88) ~[spring-data-mongodb-4.2.5.jar!/:4.2.5]

Вот файлы, которые я использую

  1. docker-compose.yml
version: "3"

services:
  mongo:
    image: mongo
    container_name: mongodb
    ports:
      - "27017:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: pwd
      MONGO_INITDB_DATABASE: admin

  mongoimport:
    image: mongo
    volumes:
      - ./mongo/data/users.json:/src/data/users.json
    command: mongoimport --host mongo --username root --password pwd --db admin --collection users --file /src/data/users.json --jsonArray
    depends_on:
      - mongo

  ordersearchservice:
    build:
      context: ./order-search-service
      dockerfile: Dockerfile
    image: order-search-service
    ports:
      - "8081:8081"
    depends_on:
      - mongoimport
    environment:
      SPRING_DATA_MONGODB_URI: mongodb://root:pwd@localhost:27017/admin

  productinfoservice:
    build:
      context: ./product-info-service
      dockerfile: Dockerfile
    image: product-info-service
    ports:
      - "8082:8082"
    depends_on:
      - ordersearchservice
    environment:
      SPRING_DATA_MONGODB_URI: mongodb://root:pwd@localhost:27017/admin

  userinfoservice:
    build:
      context: ./user-info-service
      dockerfile: Dockerfile
    image: user-info-service
    ports:
      - "8083:8083"
    depends_on:
      - productinfoservice
    environment:
      SPRING_DATA_MONGODB_URI: mongodb://root:pwd@localhost:27017/admin

  1. userinfoservice/pom.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.shaan</groupId>
    <artifactId>user-info-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-info-service</name>
    <description>User Info service</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver-reactivestreams</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-core</artifactId>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

  1. userinfoservice/Dockerfile
FROM maven:3.8.4-openjdk-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn package -DskipTests

FROM openjdk:17-oracle
WORKDIR /app
COPY --from=build /app/target/user-info-service-0.0.1-SNAPSHOT.jar .
ENTRYPOINT  java -jar user-info-service-0.0.1-SNAPSHOT.jar

  1. userinfoservice/src/main/resources/application.properties
spring.application.name=user-info-service
spring.data.mongodb.uri=mongodb://root:pwd@localhost:27017/admin

searchOrderByPhoneUrl=http://localhost:8081/orderSearchService/order/phone
searchProductByProductCode=http://localhost:8082/productInfoService/product/names

server.port=8083

Я уже пробовал следующие вещи:

  1. Я думал, что mongodb еще не запущен, когда запускается userinfoservice, поэтому я сделал его зависимым от mongodb.
  2. Я дважды проверил наличие проблем с подключением к базе данных, но докер прекрасно запускает mongodb.
  3. Я проверил реактивный драйвер базы данных в pom.xml, и он тоже выглядит на месте (не требуется, поскольку приложение работает нормально вне докера)
  4. Я проверил брандмауэр. Ничего нет.

Но я все равно не могу получить данные, когда служба работает в докере. Пожалуйста, дайте мне знать, если я что-то упускаю. Спасибо за помощь.

Можете ли вы изменить URI подключения к mongoDB на: Spring.data.mongodb.uri=mongodb://root:pwd@mongo:27017/admin Изнутри контейнера localhost 27017 ничего не значит.

antoine.lange 27.04.2024 16:53

Удивительно, это сработало!! Не могли бы вы объяснить один раз или поделиться каким-либо справочным документом?

Anubhav Sharma 27.04.2024 17:51

Приятно слышать, объясню в ответе

antoine.lange 27.04.2024 17:52
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
1
3
110
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При запуске приложений внутри контейнеров каждый контейнер обычно имеет собственное изолированное сетевое пространство имен. Это означает, что «localhost» внутри контейнера относится к самому контейнеру, а не к хост-компьютеру или другим контейнерам. Итак, приложение userinfoservice не может просматривать mongo сервис, потому что 27017 порт открыт для вашего локального компьютера и виден с вашего локального хоста, но не из контейнера.

По умолчанию Docker Compose вы используете настройку единой сети для вашего приложения. Каждый контейнер службы присоединяется к сети по умолчанию и доступен другим контейнерам в этой сети, а также доступен для обнаружения по имени службы. (https://docs.docker.com/compose/networking/)

Другие вопросы по теме