spring REST 消息总线通信

spring REST message bus communication

我正在寻找可以帮助我将 spring REST Web 服务与消息总线 (RabbitMQ) 集成的 spring 模块。 REST Web 服务充当来自客户端的 AMQP 消息的消费者。每当通过总线发送消息时,它都是 AMQP 消息,要使其与 REST 一起工作,必须将其转换为 REST 调用。有人知道现有的解决方案吗?

我个人看不到这其中的价值,即使用同步 REST 接口来使用一些非同步 AMQP 消息,因为您有点失去像 RabbitMQ 这样的非同步消息系统的目的/优势。

AMQP 的伟大之处在于它是一种有线协议,而不是绑定到一种语言(例如,JMS 几乎绑定到 Java)。这意味着你可以使用 Java / Spring / AMQP library, Node.JS / AMQP library, C# / AMQP library etc.这篇文章解释了比我更好的优点http://www.wmrichards.com/amqp.pdf 我的观点是的,如果您正在寻找 REST 在另一种语言/系统等与 RabbitMQ 之间建立桥梁,那么我首先会调查其他语言/系统是否支持 AMQP 库。

但是,如果您必须有一个 REST'ful 接口,您可以使用 SpringMVC 创建一个简单的控制器并使用一些方法注入 private AmqpTemplate amqpTemplate;。这有效地创建了您的 REST 到 AMQP 桥/代理。 spring 配置/Java 控制器如下(注意这已经过测试并且有效):-

/spring/restAmqpContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
                    http://www.springframework.org/schema/mvc     http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
                    http://www.springframework.org/schema/rabbit  http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">

<!-- Location of "config.properties" to override RabbitMQ connection details if required. -->
<context:property-placeholder ignore-resource-not-found="true" 
                              location="classpath:/config.properties,
                                        ${DATA_HOME:}/config.properties"  />

<bean class="com.bobmarks.controller.RestAmqpController">
    <property name="amqpTemplate" ref="amqpTemplate"/>
</bean>

<mvc:default-servlet-handler />
<mvc:annotation-driven/>

<rabbit:connection-factory id="amqpConnectionFactory" 
                           host="${rabbitmq.host:localhost}" 
                           port="${rabbitmq.port:5672}" 
                           username="${rabbitmq.username:guest}" 
                           password="${rabbitmq.password:guest}"
                           publisher-confirms="${rabbitmq.publisher.confirms:true}" 
                           publisher-returns="${rabbitmq.publisher.returns:true}" />

<rabbit:template id="amqpTemplate" connection-factory="amqpConnectionFactory" mandatory="true" />

<rabbit:admin id="rabbitAdmin" connection-factory="amqpConnectionFactory" />

<rabbit:queue name="my_queue" />
<rabbit:direct-exchange name="my_exchange">
    <rabbit:bindings><rabbit:binding queue="my_queue" key="my_binding" /></rabbit:bindings>
</rabbit:direct-exchange>

RestAmqpController.java

package com.bobmarks.controller;

import java.util.Date;

import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * Simple Rest To AMQP Controller.
 */
@Controller
@RequestMapping(value = "/rest2amqp")
public class RestAmqpController {

    private AmqpTemplate amqpTemplate;

    public RestAmqpController() {}

    public void setAmqpTemplate(AmqpTemplate amqpTemplate) {
        this.amqpTemplate = amqpTemplate;
    }

    @RequestMapping(method = RequestMethod.GET)
    public ResponseEntity<String> message(@RequestParam(value = "message") String message) {

        try {
            amqpTemplate.convertAndSend("my_exchange", "my_binding", message);
            return new ResponseEntity<String>("Message sent to AMQP queue at: " + new Date(), HttpStatus.OK);
        }
        catch (AmqpException amqpEx) {
            return new ResponseEntity<String>(amqpEx.getMessage(), HttpStatus.BAD_REQUEST);
        }
    }
}

这些以通常的方式打包(Tomcat / Spring Boot / etc),例如如果项目被称为 data REST发送消息的端点如下:-

http://localhost/data/rest2amqp?message=Hello_World

这可能最好用屏幕截图显示。

提交消息截图(仅使用FireFox)

显示消息到达的 RabbitMQ 管理客户端屏幕截图

实际消息的屏幕截图

注意:这是一个非常基本的例子,只有一个 RabbitMQ 交换/队列,不包含安全性或您可能想要的任何其他基本内容!