从具有多个线程的SQS队列中读取

时间:2016-08-03 20:00:16

标签: java multithreading amazon-web-services amazon-sqs

注意:这是来自here的帖子的重新发布。

大家好, 我有一个处理单个SQS队列中的消息的进程。队列中可以包含许多消息,每条消息都会导致数据库命中。因此,我想对这个队列的读者进行线程化。

每个帖子的基本代码是:

public void run() {
    while(true) {
        ReceiveMessageRequest rmr = new ReceiveMessageRequest(queueUrl)
               .withMaxNumberOfMessages(10)
               .withWaitTimeSeconds(3);
        List<Message> messages = sqsClient.receiveMessage(rmr).getMessages();
        // process messages
        // delete messages
    }
}

我所看到的是线程之间有大量重复的消息。我知道我应该期待这里和那里的一些重复,但似乎每个线程获得相同的消息集,并且实际上,只有一个线程做了很多工作。

我是否误解了如何使用API​​或我做错了什么? Javadocs表明AmazonSQS类是线程安全的,实际上甚至为每个线程创建一个新的AmazonSQS类都没有改变。

任何指针都会非常感激。我目前对修复的想法是从SQS队列中读取一个线程,将每条消息放入类似LinkedBlockingDeque的内容,然后让工作人员读取它。但我觉得这个实现不会像我想的那样快地耗尽队列。

2 个答案:

答案 0 :(得分:1)

由于每条消息都有数据库命中,因此处理每条消息似乎需要时间。您应该增加队列的可见性超时。

来自AWS SQS文档:

  

收到消息后,它立即保留在队列中。至   防止其他消费者再次处理消息,Amazon SQS   设置可见性超时,即Amazon SQS的一段时间   防止其他消费组件接收和处理   消息。

http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html

答案 1 :(得分:0)

这将确保重复的消息,您可以使用此代码跳过重复的消息

 @Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
    // create a new view
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_view, parent, false);

    //get device screen width
    int width  = Resources.getSystem().getDisplayMetrics().widthPixels;
    //set your item view width
    v.getLayoutParams().width = width / getItemCount() ;

    MyViewHolder vh = new MyViewHolder(v);
    return vh;
}