Рубрики
Без рубрики

Весеннее облако: Обнаружение сервисов с помощью Эврики

Автор оригинала: Dhananjay Singh.

Обзор

В этой статье мы познакомимся с обнаружением служб на стороне клиента и балансировкой нагрузки с помощью Spring Cloud Netflix Eureka .

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

Проблема в архитектуре такого типа заключается в том, как клиентская служба находит все свои конечные службы. Мы могли бы жестко закодировать имя хоста/порт в каком-либо файле свойств, но это не всегда практично или выполнимо в облачной среде. Микросервисов может быть любое количество, и жесткий код требует много времени и ресурсов, когда их количество неизвестно и когда их местоположение может измениться.

Чтобы еще больше усложнить, службы могут иметь несколько собственных экземпляров (в зависимости от нагрузки). Какой экземпляр на самом деле будет обслуживать ответ, может быть сложным, поскольку мы хотим иметь равное распределение нагрузки.

Netflix Эврика

Netflix Eureka – это сервер поиска (также называемый реестром). Все микросервисы в кластере регистрируются на этом сервере.

При выполнении вызова REST другой службе вместо указания имени хоста и порта они просто указывают имя службы.

Фактическая маршрутизация выполняется во время выполнения вместе с равным распределением нагрузки между конечными службами. Существуют и другие клиенты обнаружения служб, такие как Консул , Зооконтролер и т.д., Но в этой статье мы будем использовать Эврику.

Чтобы понять эту концепцию, мы построим три сервиса в нашем примере:

  • Сервер Эврика : действует как реестр служб.
  • Сервис просмотра фильмов : простая служба отдыха, предоставляющая информацию о фильмах.
  • Служба рекомендаций : простая служба отдыха, но она внутренне вызывает службу фильмов для выполнения своих запросов.

Настройка сервера Эврика

Лучший способ начать со скелетного проекта-использовать Spring Initializr . Выберите предпочитаемую версию Spring Boot, добавьте зависимость “Сервер Эврика” и создайте как проект Maven:

Чтобы создать сервер Eureka, все, что нам нужно сделать, это добавить аннотацию @EnableEurekaServer в наш основной класс:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

Мы будем запускать сервер на порту 8761 , который является рекомендуемым портом командой Spring. Поэтому в application.properties мы добавим:

server.port = 8761

Чтобы проверить эту конечную точку, перейдите в свой браузер по адресу http://localhost:8761/ :

Настройка конечной службы (Видеосервис)

Опять же, мы используем Spring Initializr для создания нашего проекта. Выберите предпочитаемую версию Spring Boot, добавьте зависимости “Web” и “Eureka Discovery” и создайте как проект Maven:

Чтобы сделать это клиентом, все, что нам нужно сделать, это добавить аннотацию @EnableEurekaClient на уровне класса:

@SpringBootApplication
@EnableEurekaClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

В качестве альтернативы мы могли бы использовать аннотацию @EnableDiscoveryClient , которая взята из spring-cloud-commons . Он выбирает реализацию (Консул, Смотритель зоопарка, Эврика) в соответствии с путем к классу. В нашем случае он автоматически выбрал бы Эврику.

С этим покончено, мы можем определить нашу модель фильма :

public class Movie {
    private Integer id;

    private String name;

    private String synopsis;

    // getters and setters
}

Git Essentials

Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!

И, наконец, мы можем определить контроллер:

@RestController
public class MovieController {

    private static List movieList = new ArrayList<>();
    static {
        movieList.add(new Movie(1, "movie-1", "summary-1"));
        movieList.add(new Movie(2, "movie-2", "summary-2"));
        movieList.add(new Movie(3, "movie-3", "summary-3"));
    }

    @GetMapping("/movies")
    public ResponseEntity getMovies() {
        return ResponseEntity.ok(movieList);
    }
}

Выше мы создали простую конечную точку, которая возвращает список объектов Movie , имитируя вызов базы данных.

В этом проекте у нас есть Eureka Discovery клиентская банка. Увидев это в пути к классу, Spring попытается найти работающий сервер Spring Eureka. Нам нужно указать это в application.properties :

server.port = 8060
spring.application.name = movie-service
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/

Наряду с указанием URL-адреса сервера, нам также необходимо указать имя приложения. Именно это имя будет использоваться другими службами для совершения вызовов REST.

После этого мы зарегистрировали нашу службу на сервере, и любая другая зарегистрированная служба может вызвать ее с помощью spring.application.имя .

Давайте обновим нашу конечную точку сервера Eureka:

Наряду с регистрацией на сервере Eureka, клиентская банка Eureka также периодически отправляет сердцебиения на сервер Eureka, чтобы сообщить ему, что он все еще доступен.

Настройка Клиентской службы (Служба Рекомендаций)

Теперь давайте создадим наш клиентский сервис, который будет вызывать movie-сервис . Еще раз давайте создадим новый проект с Spring Initializr с теми же зависимостями, что и ранее:

В его application.properties мы снова должны указать имя приложения и данные Эврики:

server.port = 8050
spring.application.name = recommendation-service
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/

Затем мы аннотируем основной класс с помощью @EnableEurekaClient :

@SpringBootApplication
@EnableEurekaClient
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

Нам также нужно создать RestTemplate компонент и пометить его как @LoadBalanced . Это говорит Spring о том, что мы хотим воспользоваться преимуществами балансировки нагрузки на стороне клиента, что в данном случае выполняется с помощью Ленты .

Балансировка нагрузки на стороне клиента решает, какой экземпляр (в случае, если в кластере запущено несколько конечных служб, которые может вызвать клиент) следует вызвать.

Лента была разработана Netflix и позже с открытым исходным кодом. Эта зависимость автоматически поставляется с зависимостью обнаружения Эврики. Он автоматически интегрируется с Spring и распределяет нагрузки в зависимости от работоспособности сервера, производительности, региона и т.д.

Нам не потребуется использовать Ленту напрямую, так как она автоматически интегрирует RestTemplate , Zuul , Притворство и т. Д. Используя @LoadBalanced мы сделали RestTemplate ленту осведомленной.

Давайте напишем Контроллер рекомендаций класс, который внутренне вызывает наш видеосервис:

@RestController
public class RecommendationController {
    @Autowired
    RestTemplate restTemplate;

    @RequestMapping(value = "/recommendations", method = RequestMethod.GET)
    @ResponseBody
    public Movie[] recommendations() {
        Movie[] result = restTemplate.getForObject("http://movie-service/movies", Movie[].class);
        return result;
    }
}

Выше мы @Autowired включили ленту RestTemplate и используем ее для вызова видеосервиса . Обратите внимание, что нам нигде не нужно указывать имя хоста или порт.

Что Spring внутренне делает здесь, так это потому, что он зарегистрирован на сервере Eureka, он хранит список всех служб и их запущенных экземпляров локально. Когда мы сделали вызов REST в movie-сервис , подобный этому (вместо указания имени хоста и порта), он заменяет фактические URL-адреса конечных точек из ранее сохраненного списка, а затем выполняет вызов REST.

Конечно, сохраненный список службы вместе с ее запущенными экземплярами периодически обновляется. Самое приятное во всем этом то, что нам вообще не нужно об этом заботиться, и все эти вещи решаются Spring внутренне.

Давайте протестируем конечную точку рекомендации, перейдите в свой браузер (или используйте curl, postman и т. Д.), Чтобы http://localhost:8050/recommendations , вы увидите ответ, который выглядит примерно так:

Вывод

В этой статье мы рассмотрели, как использовать Spring Cloud Eureka для обнаружения служб в среде микросервисов/облаков. Мы создали две простые службы REST, которые взаимодействуют друг с другом без жесткого кодирования имени хоста/порта при выполнении вызовов REST.

Как всегда, код для примеров, используемых в этой статье, можно найти на Github .