Microservice topic 13-Spring Cloud Stream (on)

Preface

In the previous chapter, we talked about Spring Cloud Gateway

In this section, continue to share the content of the microservice topic, a total of 16 sections, namely:

The key points of this section are:

  • RabbitMQ
  • Spring RabbitMQ
  • Spring Boot RabbitMQ

Spring Cloud Stream related technologies

Spring Cloud Stream is a framework for building message-driven capabilities for microservice applications. It can be based on Spring Boot to create independent, production-ready Spring applications. Spring Cloud Stream provides personalized automated configuration implementations for some vendors' message middleware products, and introduces three core concepts: publish-subscribe, consumer group, and partition. By using Spring Cloud Stream, developers can effectively simplify the complexity of using message middleware, allowing system developers to focus more on the processing of core business logic.Insert picture description here

Take Java8 Stream as an example:

        Stream
                .of(1, 2, 3, 4, 5)                         // 生产
                .map(String::valueOf)               // 处理
                .forEach(System.out::println);  // 消费

There are three identities:

  • Publisher: Producer

  • Subscriber: Processor

  • Processor:consumer

[External link image transfer failed. The origin site may have an anti-leech link mechanism. It is recommended to save the image and upload it directly (img-qFl8tsgR-1597760291411)(assets/1534339046352.png)]

Metaprogramming: programming based on programming, such as reflection, functional programming Function, Lambda expression, expression language${user.age}

Spring Cloud Data Flow

Different from the steam stream processing mentioned above, Spring Cloud Data Flow implements the three processes of production, processing, and consumption based on the application!

Insert picture description here

There should be a different process end number between each process. Use System.exit(N), where N is a variable integer to distinguish different processes.

Spring Cloud Stream 整合 RabbitMQ

Here we use the projects that have been built before in this topic:

  • spring-cloud-client-application
  • spring-cloud-server-application

Technical implementation of RabbitMQ on this basis:
Insert picture description here

1. Pom depends on configuration.

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>

2. Configuration items.

We refer to the source code: it org.springframework.cloud.stream.binder.rabbit.properties.RabbitBindingPropertiesis not difficult to find that the two-way binding of SpringCloud and rabbitmq is achieved through the following configuration:

## IP、端口、用户名、密码、虚拟主机
## 默认使用 / 的vhost,如果修改vhost,加在端口后即可,如 /testhost
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

# Spring Cloud Stream 配置
## 驱动的名字是 test2020
## spring.cloud.stream.bindings.${channel-name}.destination
## destination = topic
spring.cloud.stream.bindings.test2020.binder = rabbit
spring.cloud.stream.bindings.test2020.destination = test2020

Tips, to learn the language, to master the Belden truth, the source code designer also constantly improves the model based on the experience of the predecessors, such as the xxxOperations implemented by various xxxTemplate in Spring:

  • JdbcTemplate: Spring operates jdbc to connect to the database.
  • RedisTemplate: Spring operates redis to connect to the cache database.
  • RabbitTemplate : Spring operates rabbit connection message middleware.
  • KafkaTemplate: Spring operates Kafka connection message middleware.
  • RestTemplate: Spring encapsulates http requests for remote calls.

3. The client and the server implement rabbitmq message communication.

Client configuration

Use MessageChannel to encapsulate the request

public interface SimpleMessageService {
    
    

    @Output("test2020") // Channel name
    MessageChannel test(); //  destination = test2020
}

Write the client api:

@RestController
public class MessageController {
    
    

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private SimpleMessageService simpleMessageService;

    @GetMapping("/stream/send")
    public boolean streamSend(@RequestParam String message) {
    
    
        // 获取 MessageChannel
        MessageChannel messageChannel = simpleMessageService.test();
        Map<String, Object> headers = new HashMap<>();
        headers.put("charset-encoding", "UTF-8");
        headers.put("content-type", MediaType.TEXT_PLAIN_VALUE);
        return messageChannel.send(new GenericMessage(message, headers));
    }
}

Then, the startup item activates and introduces SimpleMessageService:

@EnableBinding(SimpleMessageService.class) // 激活并引入 SimpleMessageService

Server configuration

Similarly, use SubscribableChannel to encapsulate the receiving class:

public interface SimpleMessageReceiver {
    
    

    @Input("test2020")
    SubscribableChannel test();
}

Then, start class activation and introduce SimpleMessageReceiver:

@EnableBinding(SimpleMessageReceiver.class) // 激活并引入 SimpleMessageReceiver

Then, be sure to do idempotence in message processing:

    @Autowired
    private SimpleMessageReceiver simpleMessageReceiver;

	@PostConstruct
    public void init() {
    
      // 接口编程
        // 获取 SubscribableChannel
        SubscribableChannel subscribableChannel = simpleMessageReceiver.gupao();
        subscribableChannel.subscribe(message -> {
    
    
            MessageHeaders headers = message.getHeaders();
            String encoding = (String) headers.get("charset-encoding");
            String text = (String) headers.get("content-type");
            byte[] content = (byte[]) message.getPayload();
            try {
    
    
                System.out.println("接受到消息:" + new String(content, encoding));
            } catch (UnsupportedEncodingException e) {
    
    
                e.printStackTrace();
            }
        });
    }

    @StreamListener("test2020")  // Spring Cloud Stream 注解驱动
    public void onMessage(byte[] data) {
    
    
        System.out.println("onMessage(byte[]): " + new String(data));
    }

    @StreamListener("test2020")  // Spring Cloud Stream 注解驱动
    public void onMessage(String data) {
    
    
        System.out.println("onMessage(String) : " + data);
    }

    @StreamListener("test2020") // Spring Cloud Stream 注解驱动
    public void onMessage2(String data2) {
    
    
        System.out.println("onMessage2(String) : " + data2);
    }

    @ServiceActivator(inputChannel = "test2020") // Spring Integration 注解驱动
    public void onServiceActivator(String data) {
    
    
        System.out.println("onServiceActivator(String) : " + data);
    }

Note: The same programming model is executed repeatedly, for example @StreamListener, different programming models are executed in turn

5. Start and test

Start separately, spring-cloud-client-application project, spring-cloud-server-application project, zookeeper service and rabbitmq service. For rabbitmq service construction, please refer to my previous rabbitmq blog .

Now we visit:
http://localhost:8888/stream/send?message=test to
Insert picture description here
visit RabbitMQ management page:
Insert picture description here

postscript

Code address of this section: Spring Cloud Steam

For more architectural knowledge, please pay attention to this series of articles on Java : The Road to Growth of Java Architects

Guess you like

Origin blog.csdn.net/qq_34361283/article/details/108089180