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

Весеннее облако – Загрузка

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

Автор оригинала: Tim Schimandle.

1. Обзор

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

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

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

  • Экстернализация конфигурации таким образом, чтобы она была гибкой и не требовала перестройки службы при изменении
  • Обнаружение служб
  • Скрытие сложности служб, развернутых на разных хостах

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

2. Сервер конфигурации

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

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

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

2.1. Настройка

Перейдите к https://start.spring.io и выберите Maven и Spring Boot 2.2.x.

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

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

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


    org.springframework.boot
    spring-boot-starter-parent
    2.4.0
    



    
        org.springframework.boot
        spring-boot-starter-test
        test
    
 


    
        
            org.springframework.cloud
            spring-cloud-dependencies
            Hoxton.SR4
            pom
            import
        
    



    
        
            org.springframework.boot
            spring-boot-maven-plugin
        
    

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


    org.springframework.cloud
    spring-cloud-config-server

Для справки, мы можем найти последнюю версию на Maven Central ( spring-cloud-dependencies , test , config-server ).

2.2. Конфигурация пружины

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

@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\{имя пользователя}\ в Windows или /Пользователи/{имя пользователя}/|/на *nix. Это свойство указывает на репозиторий Git, в котором хранятся файлы свойств для всех других приложений. При необходимости для него можно установить абсолютный путь к файлу.

Совет : На компьютере с Windows введите значение “file:///”, на *nix затем используйте “file://”.

2.4. Репозиторий Git

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

2.5. Запуск

Давайте запустим сервер конфигурации и убедимся, что он работает. Из командной строки введите mvn spring-boot:run . Это запустит сервер.

Мы должны увидеть этот вывод, указывающий на то, что сервер запущен:

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

2.6. Конфигурация начальной загрузки

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

Это процесс начальной загрузки, и каждое из этих приложений будет иметь файл с именем bootstrap.properties . Он будет содержать свойства, такие же, как application.properties , но с изюминкой:

Родительская пружина ApplicationContext сначала загружает bootstrap.properties . Это очень важно, чтобы сервер конфигурации мог начать управлять свойствами в application.properties . Именно этот специальный ApplicationContext также расшифрует любые зашифрованные свойства приложения.

Разумно, чтобы эти файлы свойств отличались друг от друга. bootstrap.properties предназначен для подготовки сервера конфигурации, а application.properties – для свойств, специфичных для нашего приложения. Технически, однако, можно поместить свойства приложения в bootstrap.properties .

Наконец, поскольку сервер конфигурации управляет свойствами нашего приложения, можно задаться вопросом, зачем вообще иметь application.properties ? Ответ заключается в том, что они по-прежнему пригодятся в качестве значений по умолчанию, которых, возможно, нет на сервере конфигурации.

3. Открытие

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

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

Чтобы узнать больше подробностей и увидеть более сложную реализацию обнаружения, ознакомьтесь со статьей Spring Cloud Eureka .

3.1. Настройка

Снова мы перейдем к start.spring.io . Установите для артефакта значение “обнаружение”. Найдите “сервер эврика” и добавьте эту зависимость. Найдите “клиент конфигурации” и добавьте эту зависимость. Наконец, создайте проект.

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


    org.springframework.cloud
    spring-cloud-starter-config


    org.springframework.cloud
    spring-cloud-starter-eureka-server

Для справки мы найдем пакеты на Maven Central ( config-client , eureka-server ).

3.2. Конфигурация пружины

Давайте добавим Java config в основной класс:

@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.имя свойство.

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

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

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

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

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


    org.springframework.cloud
    spring-cloud-starter-eureka

Для справки, мы можем найти пакет на Maven Central ( eureka-client ).

Добавьте эти свойства в файл 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 . Вывод из командной строки должен включать:

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

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

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, чтобы разрешить перекрестные запросы на клиентах. Мы можем решить эту проблему, создав сервер шлюза. Это будет действовать как обратный прокси-сервер, отправляющий запросы от клиентов на наши внутренние серверы.

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

4.1. Настройка

Теперь мы знаем, как это делается. Перейдите к https://start.spring.io . Установите для артефакта значение “шлюз”. Найдите “zuul” и добавьте эту зависимость. Найдите “клиент конфигурации” и добавьте эту зависимость. Найдите “открытие эврики” и добавьте эту зависимость. Наконец, создайте этот проект.

В качестве альтернативы мы могли бы создать приложение Spring Boot с этими зависимостями:


    org.springframework.cloud
    spring-cloud-starter-config


    org.springframework.cloud
    spring-cloud-starter-eureka


    org.springframework.cloud
    spring-cloud-starter-zuul

Для справки, мы можем найти пакет на Maven Central ( config-client , eureka-client , zuul ).

4.2. Конфигурация пружины

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

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class GatewayApplication {...}

4.3. Свойства

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

bootstrap.properties in src/main/resources :

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 позволяет нам определить приложение для маршрутизации определенных запросов на основе муравьиного UrlMatcher. Наше свойство говорит Zuul направлять любой запрос, поступающий в /book-service/** , в приложение с помощью spring.application.название |/книжной службы . Затем 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)

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

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

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

5. Книжное Обслуживание

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

5.1. Настройка

Ещё раз. Перейдите к https://start.spring.io . Установите артефакт в положение “книга-сервис”. Найдите “веб” и добавьте эту зависимость. Найдите “клиент конфигурации” и добавьте эту зависимость. Найдите “открытие эврики” и добавьте эту зависимость. Создайте этот проект.

Кроме того, добавьте эти зависимости в проект:


    org.springframework.cloud
    spring-cloud-starter-config


    org.springframework.cloud
    spring-cloud-starter-eureka


    org.springframework.boot
    spring-boot-starter-web

Для справки, мы можем найти пакет на Maven Central ( config-client , eureka-client , web ).

5.2. Конфигурация пружины

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

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

    private List 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 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 in 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:

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 с двумя книгами, которые мы добавили в контроллер out. Обратите внимание, что мы не обращаемся к службе книг непосредственно через порт 8083, а проходим через сервер шлюза.

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

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

6.1. Настройка

Ещё раз. Перейдите к https://start.spring.io . Установите для артефакта значение “рейтинг-сервис”. Найдите “веб” и добавьте эту зависимость. Найдите “клиент конфигурации” и добавьте эту зависимость. Найдите eureka discovery и добавьте эту зависимость. Затем создайте этот проект.

Кроме того, добавьте эти зависимости в проект:


    org.springframework.cloud
    spring-cloud-starter-config


    org.springframework.cloud
    spring-cloud-starter-eureka


    org.springframework.boot
    spring-boot-starter-web

Для справки, мы можем найти пакет на Maven Central ( config-client , eureka-client , web ).

6.2. Конфигурация пружины

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

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

    private List 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 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 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 in 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/

рейтинг-сервис.свойства в нашем репозитории Git:

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/ratings/all и мы получаем обратно JSON, содержащий все наши рейтинги. Обратите внимание, что мы не обращаемся к службе оценки непосредственно через порт 8084, а проходим через сервер шлюза.

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

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

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