功能编程模型bean定义和spring-cloud-function + spring-cloud-stream集成

时间:2019-06-09 18:40:21

标签: spring-webflux spring-cloud-stream spring-cloud-function

大家好,还有一支特别的春季队!

如何使用功能Bean编程模型样式的spring-cloud-stream和spring-cloud-stream传递管道?

例如,我有两个依赖项的pom.xml:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-stream-reactive</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-function-webflux</artifactId>
</dependency>

让我们说下一步:

  1. 通过spring-cloud-function(webflux)通过http有效负载字符串发送
  2. 使用我的toUpperCase函数对其进行大写
  3. 最后发送到我的管道中,以安装粘合剂(kafka / rabbit / test-binder)

所以我希望像这样实现它:

@Log4j2
@SpringBootApplication
public class SpringCloudFunctionStreamApplication {

  /**
   * can I sent result of that function to my broker without any
   * explicitly defined output.send(...) execution?
   */
  @Bean
  public Function<String, String> toUpperCase() {
    return arg -> {
      var res = arg.toUpperCase();
      log.info("toUpperCase: {}", res);
      return res;
    };
  }

  public static void main(String[] args) {
    SpringApplication.run(
      SpringCloudFunctionStreamApplication.class,
      "--spring.cloud.function.definition=toUpperCase",
      "--spring.cloud.stream.function.definition=toUpperCase"
    );
  }
}

所以当我使用HTTPie发送有效负载时,就像这样:

echo 'hello' | http :8080/toUpperCase

spring-cloud-function似乎工作正常,我可以看到预期的日志:

2019-06-09 21:20:36.978 ...SpringCloudFunctionStreamApplication : toUpperCase: hello

同样认为如果我通过Rabbitmq管理Web ui发布消息,但是如何从一个管道流向另一个管道

所以我的问题与类型为{Function},“ Consumer”和“ Supplier”的@Beans的according to spring documentation which says that I can use spring-cloud-stream as well:包装有关,它们作为HTTP端点和/或RabbitMQ,Kafka等消息流侦听器/发布器暴露给外界,但是我不明白怎么办?

不幸的是,目前,我只能使用Source see example here手动将消息发布到spring-cloud-stream绑定器,但是我当然想知道是否有可能魔术地避免使用spring。

可以请任何人告诉我(也许加里·罗素,戴夫·索耶,阿特姆·比兰,奥列格·朱拉库斯基或任何其他知道的人):我错过了什么,我应该如何配置我的应用程序,或者应该在我的application.properties中添加哪些道具。等等?

谢谢!


关于, 马克西姆

3 个答案:

答案 0 :(得分:0)

马克西姆

这不是理想的选择,但是鉴于我们在现有绑定程序的范围内实现了初始功能支持,因此存在一些限制。我会解释,但首先这里是功能齐全的代码:

@SpringBootApplication
public class SimpleFunctionRabbitDemoApplication  {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SimpleFunctionRabbitDemoApplication.class,
            "--spring.cloud.stream.function.definition=uppercase");
    }

    @Autowired
    private Processor processor;

    @Bean
    public Consumer<String> consume() {
        return v -> processor.input().send(MessageBuilder.withPayload(v).build());
    }

    @Bean
    public Function<String, String> uppercase() {
        return value -> value.toUpperCase();
    }
}

基本上有些不匹配。在流方面,我们有活页夹,在功能方面,我们有适配器。您实际上(根据您的要求)试图将两者桥接到一个管道中。所以。 。 。

让我们先看看活页夹。

大写功能绑定到消息通道绑定程序(兔子或kafka)提供的inputoutput通道,有效地创建了内部管道input -> uppercase -> output。它也通过s-c函数作为REST端点公开,但是,s-c-函数无法访问上述管道。实际上,它实际上具有自己的管道request -> uppercase -> reply。 因此,我们需要做的是将两个概念联系在一起,而这实际上就是我所做的。

  • 您为应用程序注入了Processor绑定,其中包含对绑定到渠道uppercase的引用。

  • 您通过REST consume()调用http://localhost:8080/consume/blah

  • 您将消息发送到uppercase函数的输入通道

在将来为简化此操作,我们只需要创建类似绑定程序的Web适配器版本,因此请随时提出功能要求。但是您可以看到,当前的解决方法并没有全部解决。

答案 1 :(得分:0)

这对Oleg Zhurakousky来说是个问题。如果回答会很高兴

如果我使用@Bean Supplier<Pojo>...来绑定输出目的地,则每次发送新的@Service时如何从@Controller类或Pojo类调用它。卡夫卡/兔子。

Supplier仅公开get()方法。

我只写生产者,它将为Kafka写一个自定义Pojo,而另一个应用程序是消费者。对于Consumer<Pojo>...而言,功能方法更为清晰,只需从Kafka和过程中读取即可。生产者的Supplier<Pojo>...部分不清楚。

https://www.youtube.com/watch?v=nui3hXzcbK0&t=3478s

答案 2 :(得分:0)

@Abhishek

您可以按照here所述使用EmitterProcessor。所提供的示例使用rest终结点作为实际数据源,但是您可以看到它没有计数,因为您所需要做的只是调用onNext的{​​{1}}操作,以便从Service传递事件。