Статьи

Bootiful GCP: Spring Cloud Stream с Google Cloud Pub / Sub

Я недавно прочитал серию Джоша Лонга « Bootiful GCP» в инженерном блоге Sprint Central, и мне особенно понравилась 4-я часть об использовании Pub / Sub Google Cloud. Я был вдохновлен серией, а также оцениваю Spring Cloud Stream для моего нового проекта. Я думал, что я бы расширил эту статью, где остановился Джош. В этой статье описывается, как использовать Spring Cloud Stream с Google Cloud Pub / Sub для реализации простого производителя и потребительского приложения.

Вступление

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

Что такое Google Cloud Pub / Sub?

Google определяет Pub / Sub следующим образом.

Cloud Pub / Sub обеспечивает масштабируемость, гибкость и надежность корпоративного промежуточного программного обеспечения, ориентированного на сообщения, в облако. Предоставляя асинхронный обмен сообщениями «многие ко многим», который разъединяет отправителей и получателей, он обеспечивает безопасную и высокодоступную связь между независимо написанными приложениями.

https://cloud.google.com/pubsub/docs/overview

Проще говоря, Pub / Sub — это решение Google для поддержки разработчиков, связывающих компоненты приложения с брокером сообщений в масштабе Google. Как следует из названия, это решение реализует механизм публикации / подписки с теми же концепциями, которые вы ожидаете. Сообщения могут быть отправлены по темам, и все подписчики определенной темы получают опубликованное сообщение.

Google Cloud Pub / Sub

Здесь важно подчеркнуть, что Pub / Sub предлагает по крайней мере один раз доставку для каждого отправленного сообщения. Если вы хотите, чтобы сообщение доставлялось только один раз, вам придется позаботиться об этом самостоятельно.

Что такое весенняя интеграция?

Spring Integration — это проект Spring в их портфолио. На ней может быть написана целая статья или даже целая книга, так как она сама по себе обширная структура. Таким образом, Spring Integration — это инфраструктура, которая помогает вам разрабатывать и интегрировать приложения с использованием шаблонов EIP . Два самых основных примитива Spring Integration — это Message<T> и MessageChannel . В связи с этим разработчики могут разъединять и изолировать компоненты друг от друга. Вы можете думать об этом механизме, как будто Spring Integration продвинет идею внедрения зависимостей еще дальше, так что компоненты даже не должны знать друг о друге, но вместо этого они обмениваются сообщениями.

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

Google Cloud Pub / Sub

Spring Integration предоставляет множество адаптеров, которые помогают разработчикам подключаться к базам данных, брокерам сообщений и многим другим внешним системам. В этом случае адаптеры используются для отправки и получения сообщений в / из Google Cloud Pub / Sub. Проект Spring Cloud GCP предоставляет входящие и исходящие адаптеры для Pub / Sub, что делает обмен сообщениями прозрачным с точки зрения потока сообщений Spring Integration.

Если вы читаете статью Джоша, он делает то, что он представляет Spring Integration для чистого и последовательного использования Pub / Sub. Это означает, что прямые ссылки на PubSubTemplate удаляются, и, как следствие, если вы хотите адаптировать примеры в этой статье, например, к RabbitMQ, все, что вам нужно сделать, это просто заменить соответствующие адаптеры канала.

Что такое Spring Cloud Stream?

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

Однако при разработке современных приложений мы не обязательно хотим интегрироваться с унаследованными системами, мы бы лучше интегрировались с современными брокерами сообщений, такими как RabbitMQ , Apache Kafka или с GCP Pub / Sub в этом случае. При этом нам не нужен полный репертуар Spring Integration с точки зрения возможности интеграции с широким спектром внешних систем. Эта дополнительная гибкость потребует от нас настройки адаптеров, которые нам не нужны. Если мы просто используем GCP Pub / Sub или любой другой современный брокер сообщений, упомянутый ранее, становится утомительно определять и настраивать адаптеры для каждого отдельного компонента.

Google Cloud Pub / Sub

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

Использование Spring Cloud Stream с Google Cloud Pub / Sub

Я думаю, что достаточно рассказал о фонде Spring Cloud Stream, Spring Integration и Google Cloud Pub / Sub. Пришло время увидеть код. Есть два очень простых приложения Spring Boot, которые обмениваются простой строкой в ​​качестве полезной нагрузки сообщений. Начнем с издателя .

издатель

По сути, это простой контроллер, который отправляет простую строку в качестве полезной нагрузки сообщения. Если вы работали с Spring Integration раньше, в отправляющей части нет ничего особенного.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@RestController
public class PublisherController {
 
  private final MessageChannel outgoing;
 
  public PublisherController(Channels channels) {
    outgoing = channels.outgoing();
  }
 
  @PostMapping("/publish/{name}")
  public void publish(@PathVariable String name) {
    outgoing.send(MessageBuilder.withPayload("Hello " + name + "!").build());
  }
 
}

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

1
2
3
4
5
6
7
8
9
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
 
public interface Channels {
 
  @Output
  MessageChannel outgoing();
 
}

Channels в свою очередь, — это просто интерфейс, в котором можно определить произвольное количество каналов сообщений и пометить либо @Input либо @Output . Spring Cloud Stream заботится о создании объекта-посредника, который отвечает за возврат ссылок на объекты MessageChannel .

1
2
3
4
5
6
7
8
9
@EnableBinding(Channels.class)
@SpringBootApplication
public class PubsubPublisherApplication {
 
  public static void main(String[] args) {
    SpringApplication.run(PubsubPublisherApplication.class, args);
  }
 
}

Spring Cloud Stream использует Spring Boot и Spring Integration. Аннотация @EnableBinding помечает Channels как привязываемый интерфейс и связывает логическое имя привязки ( outgoing ) с адресатом. Что означает назначение, которое варьируется в зависимости от подшивок, для Pub / Sub это означает тему для производителя сообщений и подписку для потребителя сообщений. Эти привязки могут быть определены в application.yml .

1
2
3
4
5
6
spring:
  cloud:
    stream:
      bindings:
        outgoing:
          destination: reservations

подписчик

Подписчик даже проще, чем издатель, это всего лишь один класс.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.messaging.Message;
 
@Slf4j
@EnableBinding(Sink.class)
@SpringBootApplication
public class PubsubSubscriberApplication {
 
  public static void main(String[] args) {
    SpringApplication.run(PubsubSubscriberApplication.class, args);
  }
 
  @StreamListener(Sink.INPUT)
  public void handleMessage(Message<String> message) {
    log.info("Received: {}.", message.getPayload());
  }
 
}

Здесь стоит упомянуть, что такое Sink? Как мы только что видели, @EnableBinding может принимать интерфейсы, а затем инфраструктура скрывает сложность подключения адаптеров @EnableBinding и исходящих сообщений к каналам сообщений, а также настраивает соответствующую инфраструктуру. Большинство приложений просто отправляют или получают сообщения в / из одного канала. Вот почему Spring Cloud Stream предоставляет интерфейсы Source , Sink и Processor , чтобы помочь вам сократить код. Тем не менее, мы могли бы также использовать Source для издателя вместо определения Channels , но я хотел показать, на что способен фреймворк.

Запуск демо

Чтобы запустить примеры, вам необходимо выполнить следующие шаги.

    1. Создать проект GCP

      Если у вас уже есть, вы можете пропустить этот шаг.

    2. Запустите Google Cloud Shell

      Я думаю, проще, если вам не нужно ничего устанавливать. Google Cloud Shell поставляется с Google Cloud SDK , Git, Maven и Java, предварительно установленными по умолчанию.

    3. Включить API Pub / Sub

      Поскольку Spring Cloud Stream является самоуверенным фреймворком, приложения, созданные на его основе, будут создавать темы и подписки самостоятельно. При этом создание темы и подписки вручную здесь необязательно. Вы должны будете включить API Pub / Sub, хотя.

      1
      2
      3
      % gcloud services enable pubsub.googleapis.com
      % gcloud pubsub topics create reservations
      % gcloud pubsub subscriptions create reservations --topic=reservations
    4. Клон Springoi-примеры репо

      1
      % git clone https://github.com/springuni/springuni-examples.git
    5. Начать издателя

      1
      2
      % cd ~/springuni-examples/spring-cloud/spring-cloud-stream-pubsub-publisher
      % mvn spring-boot:run
    6. Запустить подписчика

      Google Cloud Shell поставляется с поддержкой tmux, а это также означает, что он запускает сеанс tmux по умолчанию. Это может быть отключено, конечно. Важным моментом является то, что вам не нужно открывать новую оболочку, вам просто нужно открыть новое окно, нажав Ctrl-B и C. Обратитесь к связыванию клавиш Tmux для получения дополнительной информации.

      1
      2
      % cd ~/springuni-examples/spring-cloud/spring-cloud-stream-pubsub-subscriber
      % mvn spring-boot:run
    7. Послать сообщение

      Снова откройте новое окно, как и раньше, и отправьте сообщение.

      1
      % curl -XPOST http://localhost:8080/publish/test

      Вы должны увидеть подписчика, получающего его.

Вопросы

  • Как вы думаете, что произойдет, если вы начнете больше подписчиков?
  • Получат ли все они одно и то же сообщение или только одно из них?
  • И конечно почему?

Оставьте комментарий ниже и дайте мне знать, что вы думаете!

Вывод

Мы увидели, что такое Google Cloud Pub / Sub, что такое Spring Integration и почему Spring Cloud Stream основан на Spring Integration, чтобы помочь разработчикам быстрее создавать управляемые сообщениями микросервисы. С примерами кода, приведенными выше, я продолжил пример Джоша и использовал Spring Cloud Stream, заменяя Spring Integration, и в конечном итоге сократил код еще больше.

См. Оригинальную статью здесь: Bootiful GCP: Spring Cloud Stream с Google Cloud Pub / Sub

Мнения, высказанные участниками Java Code Geeks, являются их собственными.