Spring Shared Queue as a Service

时间:2016-08-28 12:57:36

标签: java spring queue

我想实现一个存储来自另一个队列(SQS)的数据的服务。 首先我定义了Listener

@Component
public class MyListener implements MessageListener{


    @Override
    @JmsListener(destination = "my-queue")
    public void onMessage(Message message) {
        try{
            System.out.println(((TextMessage) message).getText());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

仅用于测试该方法仅打印消息的有效负载

现在我想基于LinkedBlockingQueue将某种内存中队列定义为service

public interface IStoreService {
    void save(Order order);
    String get();
}

这个想法是其他服务可以使用get()方法获取第一条消息并使用它。我认为这个解决方案可以通过创建一个服务可以获取某些信息或等待通知的单个端点来减少延迟。这也只是我的假设,我可能会误解一些东西。

最后一个问题:我应该如何为一个生产者和多个消费者正确地共享这个队列?

UPD1 (有关该应用程序的更多信息)。

它是从Simple Queue Service(亚马逊)获取信息(比如说JSON对象)的独立应用程序。该逻辑在MyListener组件中实现。我还有另一个队列Orders,队列基于ActiveMQ(是的,应用程序的架构令人作呕)。

这是工作流程: ActiveMQListener从ActiveMQ队列逐个获取订单,我希望ActiveMQListener从我的Storage抓取第一条消息,让我们说合并这两个对象。

唯一的问题是如何在从SQS获取数据并将其推送到存储的MyListener和从ActiveMQ获取数据的ActiveMQListener之间共享此存储。

还有StoreService的演示代码。

public class StoreService implements IStoreService {

    private final Queue<Order> queue = new LinkedBlockingQueue<>();
    @Override
    public void save(Order order) {
        this.queue.add(order);
    }

    @Override
    public String get() {
        Order order = queue.poll();
        return order.getId();
    }
}

UPD2 我在尝试解决问题时遇到了问题。正如我上面提到的,有三个队列:

+--------------+-----------------------------------------+
|request.queue | - get information from ActiveMQ         |
|response.queue| - pass data to another ActiveMQ queue   |
|sqs.queue     | - queue based on Amazon SQS             |
+--------------+-----------------------------------------+

我也有StoreService

@Service
public class StoreService implements IStoreService {

    private final BlockingQueue<Order> queue = new LinkedBlockingQueue<>();
    @Override
    public void save(Order order) {
        this.queue.add(order);
    }

    @Override
    public String get() {
        Order order = null;
        try {
            order = queue.take();
            return order.getId();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return null;
    }
}

ActiveMQListener,方法为receiveRequest

    @JmsListener(destination = "request.queue")
    @SendTo("response.queue")
    public String receiveRequest(Order order){

        System.out.println("[INFO] REQUEST:" + order.getId());
        try{
            String test = storeService.get();
            System.out.println("[INFO] SQS:" + test);

        }catch (Exception e){
            e.printStackTrace();
        }

        return order.getId();
    }

对不起System.out.prinln,我已禁用记录器 正如您所看到的,此方法从名为request.queue的队列中获取信息,并尝试从storeSerivce获取数据

行:String test = storeService.get()

但问题是我不知道如何将storeService传递给它。我做了类似的事情

    private StoreService storeService;
    @Autowired
    public ActiveMQListener Listener(StoreService storeService){
        this.storeService = storeService;
    }

storeService为空,因为它只是storeService的新实例。

有什么想法吗?

UPD3 我还将它上传到github repository。这有点乱,但我认为理解这个概念是可以的。

1 个答案:

答案 0 :(得分:0)

Spring可以使用依赖注入注入StoreService,如下所示:

@Autowired
private StoreService storeService;

必须在服务用于获取由Spring管理的唯一实例的任何地方执行此操作。