Как вызвать один микросервис из другого микросервиса с помощью образов докеров

У меня два микросервиса SpringBoot: M1 (порт 2002) и M2 (порт 2004)

M1 и M2 успешно обмениваются данными, если я запускаю их с помощью eclipse (запускается как Java Project или SpringBoot Project).

Однако я хочу общаться с ними с помощью Docker container.

Поэтому я создаю образы для Microservices (M1 и M2), используя команду:

docker build -f Dockerfile -t image_name .

И запустите изображения, используя:

docker run -p 2004:2004 image_name

Примечание: я выставляю тот же порт из докера, как определено выше.

Но M1 и M2 не могут обмениваться данными. Я использую RestTemplate

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Boolean> isUp = restTemplate.getForEntity("http://localhost:2002/apis/test",Boolean.class);

Я получаю исключение ниже:

I/O error on GET request for \"http://localhost:2002/apis/test\": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)

Однако, если я вызываю другой микросервис, используя свой IP машины, он успешно обменивается данными.

ResponseEntity<Boolean> isUp = restTemplate.getForEntity("http://XX.XX.XX.XXX:2002/apis/test",Boolean.class);

Может ли кто-нибудь сказать, пишу ли я (используя IP-адрес) или есть еще один хороший подход для вызова одного микросервиса из другого с помощью Docker?

Вы пробовали использовать --net=host (параметр для запуска докера)? Это должно решить проблему, заключающуюся в том, что localhost ссылается на внутренний IP-адрес контейнера, а не на IP-адрес машины.

Ben 19.07.2018 09:18

@ Бен нет, не могли бы вы добавить это в качестве ответа. А чем я заменяю host?

Mehraj Malik 19.07.2018 09:19

Поскольку это скорее предложение, а не прямой ответ, комментарий здесь просто прекрасен. И вы уверены, что это не поможет? Потому что в этот момент localhost должен на 100% ссылаться на хост-машину. Ссылка на вопрос это, в принятом ответе очень подробно объясняются вещи.

Ben 19.07.2018 09:20

Хотя ответ Бена, вероятно, сработает, это может быть не лучший вариант. Вы должны сначала прочитать документ docs.docker.com/network

StephaneM 19.07.2018 09:23
javaonfly.blogspot.com/2017/07/…, попробуйте это
Jinna Balu 19.07.2018 09:30

@JinnaBalu Вопрос в том, как работать с Using docker, я знаю, что могу использовать Feign, заменяя RestTemplate. Но это не решает проблему с использованием Docker container.

Mehraj Malik 19.07.2018 09:32

Эти контейнеры находятся в одной сети? В таком случае они будут общаться с Feign Rest Client. Evn, если они не находятся в одной сети, если IP-адреса и порты открыты между сетью, это будет работать.

Jinna Balu 19.07.2018 09:36

Вас также может заинтересовать Docker Compose: docs.docker.com/compose

Arnaud 19.07.2018 10:36
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
5
8
8 418
2

Ответы 2

Попытка связаться с другим контейнером не будет работать с localhost.

Вы должны создать настраиваемую мостовую сеть, которая позволит вам обращаться к контейнерам по имени. И нет необходимости публиковать порты, если вы разговариваете только внутренне.

# create network
docker network create -d bridge mynet
# container 1
docker container run --network mynet --name container1 -d image_name
# container 2
docker container run --network mynet --name container2 -d some_other_image_name

Затем IP-адрес в фрагменте кода можно заменить именем другого контейнера.

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Boolean> isUp = restTemplate.getForEntity("http://container2:2002/apis/test",Boolean.class)

Кроме того, вы также можете связать два контейнера вместе с помощью --link. Предполагая, что вы хотите, чтобы container1 был клиентом для container2, вы можете использовать ниже:

sudo docker run --link container2 --name=container1 -d image_name

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