spring cloud stream使用指南

来源:互联网 发布:重启还原软件 编辑:程序博客网 时间:2024/05/03 18:27

最近在工作中会使用到spring cloud stream,网上中文资料几乎没有,阅读官网配置,好不容易搞定,在这里分享一下使用过程,也是自己做一个记录。

主页君自己使用场景是实现两个app之间的通信,第一个app输出数据,第二个app输入数据。这里的app也就是指一个service。

1.配置文件中进行绑定

app1中,配置输出通道相关信息。

application.yml 或者 application.properties或者配置文件中,配置

spring:  cloud:    stream:      bindings:        output_channel:       #channelName          destination: mydest #destination,或者可以认为是发布-订阅模型里面的topic          binder: rabbit1      binders:        rabbit1:          type: rabbit          environment:            spring:              rabbitmq:                host: 192.168.1.1   #rabbitMQ服务器地址                port: 5672          #rabbitMQ服务器端口                username: username                password: pwd                virtual-host: /hostName
app2中,配置输入通道相关信息。

spring:  cloud:    stream:      bindings:        input_channel:        #<span style="font-family: Arial, Helvetica, sans-serif;">position1。</span><span style="font-family: Arial, Helvetica, sans-serif;">channelName.</span>          destination: modest #position2。destination,或者可以认为是发布-订阅模型里面的topic,这里应该与输出app中发布的topic一致,表示订阅该主题          binder: rabbit1      binders:        rabbit1:          type: rabbit     #可以是其它,比如kafka          environment:            spring:              rabbitmq:                host: 192.168.1.1   #rabbitMQ服务器地址                port: 5672          #rabbitMQ服务器端口                username: username                password: pwd                virtual-host: /hostName

2.定义接口,进行channel绑定:

官网的例子中,使用的是sink和source接口,如果每个app里面只有一个通道,可以直接使用stream自带的接口,但是如果要实现多个接口,就需要自己进行接口定义了。下面是我自己定义的接口例子,具体用法会在注释中详细说明。

import org.springframework.cloud.stream.annotation.Input;import org.springframework.cloud.stream.annotation.Output;import org.springframework.messaging.MessageChannel;import org.springframework.messaging.SubscribableChannel;public interface Barista {    String INPUT_CHANNEL = "input_channel";  #position3    String OUTPUT<span style="font-family: Arial, Helvetica, sans-serif;">_CHANNEL</span> = "output_channel";    String INPUT1 = "input1";    String OUTPUT1 = "output1";    #注解@Input声明了它是一个输入类型的通道,名字是<span style="font-family: Arial, Helvetica, sans-serif;">Barista</span><span style="font-family: Arial, Helvetica, sans-serif;">.INPUT_CHANNEL,也就是position3的input_channel。这一名字与上述配置app2的配置文件中position1应该一致,表明注入了一个名字叫做input_channel的通道,它的类型是input,订阅的主题是position2处声明的mydest这个主题</span>    @Input(<span style="font-family: Arial, Helvetica, sans-serif;">Barista</span><span style="font-family: Arial, Helvetica, sans-serif;">.INPUT_CHANNEL</span><span style="font-family: Arial, Helvetica, sans-serif;">)</span>    SubscribableChannel logInput();    #注解@Output声明了它是一个输出类型的通道,名字是<span style="font-family: Arial, Helvetica, sans-serif;">output_channel。这一名字与app1中通道名一致,表明注入了一个名字为output_channel的通道,类型是output,发布的主题名为mydest。</span>    @Output(Barista.<span style="font-family: Arial, Helvetica, sans-serif;">OUTPUT</span><span style="font-family: Arial, Helvetica, sans-serif;">_CHANNEL</span><span style="font-family: Arial, Helvetica, sans-serif;">)</span>    MessageChannel logOutPut();    @Input(Barista.INPUT1)    SubscribableChannel input1();    @Output(Barista.OUTPUT1)    MessageChannel output1();    }

这里的Barista接口是定义来作为后面类的参数,这一接口定义来通道类型和通道名称。

通道名称是作为配置用,通道类型则决定了app会使用这一通道进行发送消息还是从中接收消息。

3.在输出应用的Application.java类中注入上述Barista接口

import Barista;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.feign.EnableFeignClients;import org.springframework.cloud.stream.annotation.EnableBinding;import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;/** *  */@SpringBootApplication@EnableDiscoveryClient@EnableFeignClients@EnableRedisHttpSession@EnableBinding(Barista.class)public class OutputServiceApplication {    public static void main(String[] args) {        SpringApplication.run(<span style="font-family: Arial, Helvetica, sans-serif;">OutputServiceApplication</span><span style="font-family: Arial, Helvetica, sans-serif;">.class, args);</span>    }}
这里需要在Application类中注入接口,否则在引用接口的时候,会提示找不到bean。原因是stream只有找到@EnableBinding注解,才会自动给其中的参数Barista.class创建实例。这是spring cloud stream自带的操作,需要遵守。

4.发送消息:

import Barista;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.messaging.support.MessageBuilder;import org.springframework.stereotype.Component;import org.springframework.stereotype.Service;@Service@Componentpublic class RabbitSender {    @Autowired    private Barista source;    // 发送消息    public String sendMessage(){        try{    Obj obj = new Obj();            source.logOutPut().send(MessageBuilder.withPayload(obj).build());            logger.info("发送");        }catch (Exception e){            e.printStackTrace();        }        return null;    }}

source是一个实例化的Barista对象,调用其中的logOutPut()方法实际上是调用了一个MessageChannel,并使用它将消息发送出去。

5.接收消息:

在输入应用中注入接口,并声明监听

import Barista;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cloud.stream.annotation.EnableBinding;import org.springframework.cloud.stream.annotation.StreamListener;import org.springframework.messaging.Message;@EnableBinding(Barista.class)public class RabbitReceiver {    private static final Log logger = LogFactory.getLog(RabbitReceiver.class);    @StreamListener(Barista.LOG_INPUT)    public void receiver(Message<Obj> message){        Obj obj = message.getPayload();        logger.info("接受对象:"+<span style="font-family: Arial, Helvetica, sans-serif;">obj</span><span style="font-family: Arial, Helvetica, sans-serif;">+"\n");</span>    }}
先,在类上添加注解@EnableBinding(Barista.class),实现与消息代理的连接。在方法receiver()上添加注解@StreamListener,并以通道名称作为参数,可以实现对相应通道的监听。


至此,实现了两个app之间进行消息传递。










0 0