Цель: В результате выполнения ДЗ вы интегрируете в ваш проект социальной сети docker и auto discovery сервисов с помощью consul
В данном задании тренируются навыки:
- использование docker;
- использование consul;
- построение auto discovery;
Задачи:
- Обернуть сервис диалогов в docker
- Развернуть consul в вашей системе
- Интегрировать auto discovery в систему диалогов
- Научить монолитное приложение находить и нагружать поднятые узлы сервиса диалогов
- Опционально можно использовать nomad
Используется docker-compose.yml:
# Use root/example as user/password credentials
version: '3.4'
services:
consul:
image: consul:1.1.0
hostname: localhost
networks:
- lan
ports:
- 8500:8500
dialogs_service:
image: avpgenium/dialogs-service:latest
container_name: "dialogs-service"
restart: on-failure
environment:
CONSUL_HOST: consul
CONSUL_PORT: 8500
ports:
- 9090:9090
networks:
- lan
social_backend:
image: avpgenium/social-backend:latest
container_name: "social-backend"
environment:
RABBIT_HOST: rabbitmq
REDIS_HOST: redis
CONSUL_HOST: consul
CONSUL_PORT: 8500
restart: on-failure
ports:
- 8888:8888
- 9292:9292
depends_on:
- rabbitmq
- mysql
- redis
networks:
- lan
...
После старта consul доступен на http://localhost:8500.
Микросервис диалогов необходимо зарегистрировать в consul с помощью POST-запроса (либо, что предпочтительнее, использовать настройку instance-id для автоматической регистрации микросервиса при старте):
curl -s -XPUT -d"{
\"Name\": \"dialogs-service\",
\"ID\": \"dialogs-service\",
\"Tags\": [ \"chats\", \"messages\" ],
\"Address\": \"localhost\",
\"Port\": 9090,
\"Check\": {
\"Name\": \"dialogs-service HTTP on port 9090\",
\"ID\": \"dialogs-service\",
\"Interval\": \"10s\",
\"HTTP\": \"dialogs-service:8080/actuator/health\",
\"Timeout\": \"1s\",
\"Status\": \"passing\"
}
}" localhost:8500/v1/agent/service/register
Для того, чтобы consul мог проверять работоспособность сервиса диалогов, была добавлена зависимость на spring-actuator, который предоставляет endpoint для health-check-а.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
</dependencies>
Настройки монолитного бекенда и микросервиса диалогов для работы с consul:
spring:
cloud:
consul:
host: localhost
port: 8500
discovery:
# указать instance-id, чтобы сервис сам при запуске зарегистрировался в consul
instance-id: ${spring.application.name}:${random.value}
enabled: true
health-check-interval: 10s
Получение информации о сервисе, к которому хотим отправить запрос происходит примено так:
/**
* Находит первый из доступных инстансов сервиса по его имени и возвращет его адрес
* @param serviceName имя сервиса
* @return URI сервиса для доступа к нему по http
*/
@Override
public Optional<URI> serviceUrl(String serviceName) {
return discoveryClient.getInstances(serviceName)
.stream()
.map(ServiceInstance::getUri)
.findFirst();
}
И затем может использоваться для отправки запросов к сервисам. Например:
private final RestTemplate restTemplate = new RestTemplate();
private final DiscoveryService discoveryService;
/**
* Отправить новое сообщение в чат
* @param messageDto новое сообщение в чат
* @throws ServiceUnavailableException микросервис не доступен
*/
public String createMessage(MessageDto messageDto) throws ServiceUnavailableException
{
URI service = discoveryService.serviceUrl(Constants.ServicesNames.DIALOGS_SERVICE)
.map(s -> s.resolve(Constants.API_ENDPOINT + "/messages"))
.orElseThrow(ServiceUnavailableException::new);
RequestEntity<MessageDto> newMessageDto = new RequestEntity<>(messageDto, HttpMethod.POST, service);
return restTemplate.postForEntity(service, newMessageDto, String.class)
.getBody();
}
Скрипты для сборки докер-образов бекенда социальной сети и микросервиса диалогов:
- Dockerfile сервиса диалогов (готовый образ dialogs-service на docker-hub).
- Dockerfile основного бэкэнда (готовый образ social-backend на docker-hub).