Spring Cloud - Самозагрузка

1. Обзор

Spring Cloud - это платформа для создания надежных облачных приложений. Эта среда облегчает разработку приложений, предоставляя решения для многих распространенных проблем, возникающих при переходе в распределенную среду.

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

Улучшения могут быть внесены без влияния на другие части системы.

С другой стороны, возникают разные проблемы, когда мы применяем микросервисный подход:

  • Внешняя конфигурация, так что она гибкая и не требует

перестроить сервис на смену ** Обнаружение службы

  • Сокрытие сложности служб, развернутых на разных хостах

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

2. Конфиг-сервер

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

Чтобы решить эту проблему, мы объединим всю нашу конфигурацию в один репозиторий Git и соединим ее с одним приложением, которое управляет конфигурацией для всех наших приложений. Мы собираемся создать очень простую реализацию.

Чтобы узнать больше деталей и увидеть более сложный пример, взгляните на ссылку:/spring-cloud-configuration[Spring Cloud Configuration]статья.

2.1. Настроить

Перейдите на start.spring.io и выберите Maven и Spring Boot 1.4.x.

Установите для артефакта « config» . В разделе зависимостей найдите « config server» и добавьте этот модуль. Затем нажмите кнопку generate , и вы сможете скачать zip-файл с предварительно сконфигурированным проектом и готовым к работе.

Кроме того, мы можем сгенерировать проект Spring Boot и добавить некоторые зависимости в файл POM вручную.

Эти зависимости будут распределены между всеми проектами:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Brixton.SR5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Давайте добавим зависимость для сервера конфигурации:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

Для справки: вы можете найти последнюю версию на Maven Central ( https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A% 22spring-cloud-dependencies% 22[spring-cloud-dependencies], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20AND%20a% 3A% 22spring-boot-starter-test% 22[test], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a% 3A% 22spring-облако-конфигурация-сервер 22%[конфигурация-сервер]).

2.2. Spring Config

Чтобы включить сервер конфигурации, мы должны добавить некоторые аннотации к основному классу приложения:

@SpringBootApplication
@EnableConfigServer
public class ConfigApplication {...}

@ EnableConfigServer превратит наше приложение в сервер конфигурации.

2.3. Свойства

Давайте добавим application.properties в src/main/resources:

server.port=8081
spring.application.name=config

spring.cloud.config.server.git.uri=file://${user.home}/application-config

Наиболее значимым параметром для сервера конфигурации является параметр git.uri . В настоящее время для него задан относительный путь к файлу, который обычно разрешается в c: \ Users \\ {username} \ в Windows или /Users/\ {username}/ в ** nix. Это свойство указывает на Git-репозиторий, где хранятся файлы свойств для всех других приложений. При необходимости можно указать абсолютный путь к файлу.

  • Совет : На компьютере с Windows предваряйте значение с помощью «file:///», на nix затем используйте «file://».

2.4. Git Repository

Перейдите в папку, определенную spring.cloud.config.server.git.uri , и добавьте папку «application-config». CD в ​​эту папку и введите git init . Это инициализирует Git-репозиторий, где мы можем хранить файлы и отслеживать их изменения.

2.5. Бежать

Давайте запустим конфигурационный сервер и убедимся, что он работает. В командной строке введите mvn spring-boot: run . Это запустит сервер. Вы должны увидеть эти выходные данные, указывающие, что сервер работает:

Tomcat started on port(s): 8081 (http)

3. Discovery

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

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

Таким образом, другие приложения могут использовать эту информацию при выполнении запросов.

Чтобы узнать больше деталей и увидеть более сложную реализацию обнаружения, взгляните на ссылку:/spring-cloud-netflix-eureka[Статья Spring Cloud Eureka].

3.1. Настроить

Мы снова перейдем к start.spring.io . Установите для артефакта «обнаружение». Найдите « eureka server » и добавьте эту зависимость. Найдите « config client » и добавьте эту зависимость.

Генерация проекта.

Кроме того, мы можем создать проект Spring Boot , скопировать содержимое POM с сервера конфигурации и поменять местами следующие зависимости:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

Для справки: вы можете найти пакеты на Maven Central ( https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A%22spring -cloud-starter-config% 22[config-client], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A % 22spring-облако-стартер-Eureka-сервер 22%[Eureka-сервер]).

3.2. Spring Config

Давайте добавим конфигурацию Java в основной класс:

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryApplication {...}

@ EnableEurekaServer настроит этот сервер в качестве сервера обнаружения с помощью Netflix Eureka . Spring Boot автоматически обнаружит зависимость конфигурации от пути к классам и выполнит поиск конфигурации с сервера конфигурации.

3.3. Свойства

Теперь мы добавим два файла свойств:

bootstrap.properties в src/main/resources

spring.cloud.config.name=discovery
spring.cloud.config.uri=http://localhost:8081

Эти свойства позволят серверу обнаружения запрашивать сервер конфигурации при запуске.

discovery.properties в нашем Git-репозитории

spring.application.name=discovery
server.port=8082

eureka.instance.hostname=localhost

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

Имя файла должно соответствовать свойству spring.application.name .

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

В производственной среде у вас будет более одного из них для обеспечения избыточности в случае сбоя, и этот параметр будет верным.

Давайте передадим файл в репозиторий Git. В противном случае файл не будет обнаружен.

3.4. Добавить зависимость к серверу конфигурации

Добавьте эту зависимость в файл POM сервера конфигурации:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

Для справки : вы найдете пакет на Maven Central ( https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a % 3A% 22spring-облако стартер-Eureka% 22[Eureka-клиент]).

Добавьте эти свойства в файл application.properties в src/main/resources сервера конфигурации:

eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5
eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

====  **  3.5. Бежать**

Запустите сервер обнаружения с помощью той же команды __mvn spring-boot: run__. Вывод из командной строки должен включать:

[source,text,gutter:,true]

Fetching config from server at: http://localhost:8081 …​ Tomcat started on port(s): 8082 (http)

Остановите и перезапустите службу конфигурации. Если все хорошо, результат должен выглядеть следующим образом:

[source,text,gutter:,true]

DiscoveryClient CONFIG/10.1.10.235:config:8081: registering service…​ Tomcat started on port(s): 8081 (http) DiscoveryClient CONFIG/10.1.10.235:config:8081 - registration status: 204

===  **  4. Шлюз **

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

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

Мы можем решить эту проблему, создав сервер __Gateway__. Это будет действовать как обратный запрос прокси от клиентов к нашим внутренним серверам.

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

Это устранит необходимость в CORS и даст нам удобное место для решения распространенных проблем, таких как аутентификация.

====  **  4.1. Настроить**

К настоящему времени мы знаем тренировку. Перейдите по адресу http://start.spring.io/[start.spring.io]. Установите для артефакта ‘__gateway__‘. Найдите «zuul» и добавьте эту зависимость. Найдите «__config client» __ и добавьте эту зависимость. Найдите «__eureka discovery» __ и добавьте эту зависимость. Создайте этот проект.

В качестве альтернативы мы могли бы создать приложение __Spring Boot__ со следующими зависимостями:

[source,xml,gutter:,true]

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency>

Для справки: вы найдете пакет на __Maven Central__ (https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A%22spring -cloud-starter-config% 22[config-client], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A % 22spring-cloud-starter-eureka% 22[клиент-эврика], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a % 3A% 22spring-облако стартер-Zuul% 22[Zuul]).

====  **  4.2. Spring Config **

Давайте добавим конфигурацию в основной класс:

[source,java,gutter:,true]

@SpringBootApplication @EnableZuulProxy @EnableEurekaClient public class GatewayApplication {…​}

====  **  4.3. Свойства **

Теперь мы добавим два файла свойств:

__bootstrap.properties__ в src/main/resources

[source,text,gutter:,true]

spring.cloud.config.name=gateway spring.cloud.config.discovery.service-id=config spring.cloud.config.discovery.enabled=true

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

gateway.properties в нашем Git-репозитории

spring.application.name=gateway
server.port=8080

eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5

zuul.routes.book-service.path=/book-service/** **
zuul.routes.book-service.sensitive-headers=Set-Cookie,Authorization
hystrix.command.book-service.execution.isolation.thread.timeoutInMilliseconds=600000

zuul.routes.rating-service.path=/rating-service/** **
zuul.routes.rating-service.sensitive-headers=Set-Cookie,Authorization
hystrix.command.rating-service.execution.isolation.thread.timeoutInMilliseconds=600000

zuul.routes.discovery.path=/discovery/** **
zuul.routes.discovery.sensitive-headers=Set-Cookie,Authorization
zuul.routes.discovery.url=http://localhost:8082
hystrix.command.discovery.execution.isolation.thread.timeoutInMilliseconds=600000

Свойство zuul.routes позволяет нам определять приложение для маршрутизации определенных запросов на основе муравьиного URL-сопоставления. Наше свойство сообщает Zuul направлять любой запрос, поступающий в «/book-service/ », к приложению с spring.application.name из «book-service». Затем Zuul выполнит поиск хоста с сервера обнаружения, используя имя приложения, и перенаправит запрос на этот сервер.

Не забудьте зафиксировать изменения в хранилище!

4.4. Бежать

Запустите приложения конфигурации и обнаружения и подождите, пока приложение конфигурации не зарегистрируется на сервере обнаружения. Если они уже запущены, вам не нужно их перезапускать. Как только это будет завершено, запустите сервер шлюза. Сервер шлюза должен запускаться через порт 8080 и регистрироваться на сервере обнаружения. Вывод из консоли должен содержать:

Fetching config from server at: http://10.1.10.235:8081/...
DiscoveryClient__GATEWAY/10.1.10.235:gateway:8080: registering service...
DiscoveryClient__GATEWAY/10.1.10.235:gateway:8080 - registration status: 204
Tomcat started on port(s): 8080 (http)

Одной из ошибок, которую легко сделать, является запуск сервера до того, как сервер конфигурации будет зарегистрирован в Eureka . В этом случае вы увидите журнал с таким выводом:

Fetching config from server at: http://localhost:8888

Это URL-адрес и порт по умолчанию для сервера конфигурации, и он указывает, что у нашей службы обнаружения не было адреса при выполнении запроса конфигурации. Просто подождите несколько секунд и повторите попытку, как только сервер конфигурации будет зарегистрирован в Eureka, проблема решится.

5. Забронировать Сервис

В микросервисной архитектуре мы можем создавать как можно больше приложений для бизнес-целей. Часто инженеры делят свои услуги по доменам. Мы будем следовать этому шаблону и создадим сервис книг для обработки всех операций с книгами в нашем приложении.

5.1. Настроить

Еще раз. Перейдите по адресу start.spring.io . Установите для артефакта «книжный сервис». Найдите « web » и добавьте эту зависимость. Найдите « config client » и добавьте эту зависимость. Найдите «eureka discovery» и добавьте эту зависимость. Создайте этот проект.

Или добавьте эти зависимости в проект:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Для справки: вы найдете пакет на Maven Central ( https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A%22spring -cloud-starter-config% 22[config-client], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A % 22spring-cloud-starter-eureka% 22[eureka-client], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20AND%20a % 3A% 22spring-загрузка стартер веб-% 22[веб]).

5.2. Spring Config

Давайте изменим наш основной класс:

@SpringBootApplication
@EnableEurekaClient
@RestController
@RequestMapping("/books")
public class BookServiceApplication {
    public static void main(String[]args) {
        SpringApplication.run(BookServiceApplication.class, args);
    }

    private List<Book> bookList = Arrays.asList(
        new Book(1L, "Baeldung goes to the market", "Tim Schimandle"),
        new Book(2L, "Baeldung goes to the park", "Slavisa")
    );

    @GetMapping("")
    public List<Book> findAllBooks() {
        return bookList;
    }

    @GetMapping("/{bookId}")
    public Book findBook(@PathVariable Long bookId) {
        return bookList.stream().filter(b -> b.getId().equals(bookId)).findFirst().orElse(null);
    }
}

Мы также добавили контроллер REST и поле, установленное нашим файлом свойств, чтобы вернуть значение, которое мы установим во время настройки.

Давайте теперь добавим книгу POJO:

public class Book {
    private Long id;
    private String author;
    private String title;

   //standard getters and setters
}

5.3. Свойства

Теперь нам просто нужно добавить два файла свойств:

bootstrap.properties в src/main/resources:

spring.cloud.config.name=book-service
spring.cloud.config.discovery.service-id=config
spring.cloud.config.discovery.enabled=true

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

book-service.properties в вашем Git-репозитории:

[source,text,gutter:,true]

spring.application.name=book-service server.port=8083

eureka.client.region = default eureka.client.registryFetchIntervalSeconds = 5 eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

Давайте внесем изменения в хранилище.

5.4. Бежать

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

DiscoveryClient__BOOK-SERVICE/10.1.10.235:book-service:8083: registering service...
DiscoveryClient__BOOK-SERVICE/10.1.10.235:book-service:8083 - registration status: 204
Tomcat started on port(s): 8083 (http)

Как только он будет запущен, мы можем использовать наш браузер для доступа к конечной точке, которую мы только что создали. Перейдите по адресу http://localhost : 8080/book-service/books, и мы получим объект JSON с двумя книгами, которые мы добавили в наш контроллер. Обратите внимание, что мы не обращаемся к службе книг напрямую через порт 8083, но мы проходим через сервер шлюза.

6. Рейтинговая служба

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

6.1. Настроить

Еще раз. Перейдите по адресу start.spring.io . Установите для артефакта «рейтинг-сервис». Найдите « web » и добавьте эту зависимость. Найдите « config client » и добавьте эту зависимость. Найдите «eureka discovery» и добавьте эту зависимость. Создайте этот проект.

Или добавьте эти зависимости в проект:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Для справки: вы найдете пакет на Maven Central ( https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A%22spring -cloud-starter-config% 22[config-client], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.cloud%22%20AND%20a%3A % 22spring-cloud-starter-eureka% 22[eureka-client], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.springframework.boot%22%20AND%20a % 3A% 22spring-загрузка стартер веб-% 22[веб]).

6.2. Spring Config

Давайте изменим наш основной класс:

@SpringBootApplication
@EnableEurekaClient
@RestController
@RequestMapping("/ratings")
public class RatingServiceApplication {
    public static void main(String[]args) {
        SpringApplication.run(RatingServiceApplication.class, args);
    }

    private List<Rating> ratingList = Arrays.asList(
        new Rating(1L, 1L, 2),
        new Rating(2L, 1L, 3),
        new Rating(3L, 2L, 4),
        new Rating(4L, 2L, 5)
    );

    @GetMapping("")
    public List<Rating> findRatingsByBookId(@RequestParam Long bookId) {
        return bookId == null || bookId.equals(0L) ? Collections.EMPTY__LIST : ratingList.stream().filter(r -> r.getBookId().equals(bookId)).collect(Collectors.toList());
    }

    @GetMapping("/all")
    public List<Rating> findAllRatings() {
        return ratingList;
    }
}

Мы также добавили контроллер REST и поле, установленное нашим файлом свойств, чтобы вернуть значение, которое мы установим во время настройки.

Добавим рейтинг POJO:

public class Rating {
    private Long id;
    private Long bookId;
    private int stars;

   //standard getters and setters
}

6.3. Свойства

Теперь нам просто нужно добавить два файла свойств:

bootstrap.properties в src/main/resources:

spring.cloud.config.name=rating-service
spring.cloud.config.discovery.service-id=config
spring.cloud.config.discovery.enabled=true

eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

rating-service.properties в вашем Git-репозитории:

[source,text,gutter:,true]

spring.application.name=rating-service server.port=8084

eureka.client.region = default eureka.client.registryFetchIntervalSeconds = 5 eureka.client.serviceUrl.defaultZone=http://localhost:8082/eureka/----

Давайте внесем изменения в хранилище.

6.4. Бежать

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

DiscoveryClient__RATING-SERVICE/10.1.10.235:rating-service:8083: registering service...
DiscoveryClient__RATING-SERVICE/10.1.10.235:rating-service:8083 - registration status: 204
Tomcat started on port(s): 8084 (http)

Как только он будет запущен, мы можем использовать наш браузер для доступа к конечной точке, которую мы только что создали. Перейдите по адресу http://localhost : 8080/rating-service/rating/all, и мы вернемся в JSON, содержащий все наши рейтинги. Обратите внимание, что мы не обращаемся к службе оценки напрямую через порт 8084, но мы проходим через сервер шлюза.

7. Заключение

Теперь мы можем соединить различные части Spring Cloud в работающее микросервисное приложение. Это формирует базу, которую мы можем использовать, чтобы начать создавать более сложные приложения.

Как всегда, вы можете найти этот исходный код на Github .