Amazon SQS 处理监听器的更好方式
Amazon SQS better way of handling listeners
我有一个 SQS 队列,其中有很多消息(通常有数千条)。目前,我有多个侦听器(由从同一源创建的线程创建),每个侦听器都侦听队列并接收消息。一旦侦听器从队列中收到消息,该侦听器就会从队列中删除该消息。只有从队列中删除消息后,消息才会被处理。我的可见性超时为 30 秒。
我没有使用任何锁或任何东西来处理重复项,因为我会在收到消息后立即从队列中删除消息。直到现在我还没有看到口是心非的案例,但我只是担心它可能会出现。
现在的问题是,以这种方式拥有多个侦听器还是在单个线程中侦听队列,然后启动新线程来处理您收到的每条消息,哪种方法更好?
首先,值得理解消息隐身超时的概念。
当从 Amazon SQS 队列中检索消息时(例如,通过您的线程),该消息在 Amazon SQS 中被标记为 不可见。最佳做法是让您的线程处理消息,然后 在完成消息处理后删除消息 。这样,如果线程失败,消息将自动再次在队列中可见,另一个线程可以处理它。
根据您当前的应用程序设计,如果线程失败,则消息将丢失并且不会重试。您应该考虑更改您的代码,以便仅在 处理邮件后删除邮件。
建议使用多线程处理消息,因为它会通过并行处理消息提高消息吞吐量。这也是一个更简单的设计,简单总是最好的。让一个进程检索消息然后触发线程来处理消息的替代想法更加复杂,并且没有任何好处。
Amazon SQS 队列 偶尔会 return 同一消息多次 。这种情况很少见,但可能会发生。多线程设计可能会导致它比单线程设计发生得更多,因为多个线程可能同时检索相同的消息。但是,它仍然可能在单线程模型中发生。
如果担心处理同一条消息两次,请考虑使用 FIFO queue(目前并非在每个 AWS 区域都可用)。这将保证每条消息只被接收一次。或者,您的代码需要检查特定消息是否已被处理(例如,通过检查数据库)。
多线程设计还允许您通过让多个系统(甚至跨多个可用区)处理消息来水平扩展,而您的单线程设计只有一个故障点并且可扩展性较差。
我有一个 SQS 队列,其中有很多消息(通常有数千条)。目前,我有多个侦听器(由从同一源创建的线程创建),每个侦听器都侦听队列并接收消息。一旦侦听器从队列中收到消息,该侦听器就会从队列中删除该消息。只有从队列中删除消息后,消息才会被处理。我的可见性超时为 30 秒。
我没有使用任何锁或任何东西来处理重复项,因为我会在收到消息后立即从队列中删除消息。直到现在我还没有看到口是心非的案例,但我只是担心它可能会出现。
现在的问题是,以这种方式拥有多个侦听器还是在单个线程中侦听队列,然后启动新线程来处理您收到的每条消息,哪种方法更好?
首先,值得理解消息隐身超时的概念。
当从 Amazon SQS 队列中检索消息时(例如,通过您的线程),该消息在 Amazon SQS 中被标记为 不可见。最佳做法是让您的线程处理消息,然后 在完成消息处理后删除消息 。这样,如果线程失败,消息将自动再次在队列中可见,另一个线程可以处理它。
根据您当前的应用程序设计,如果线程失败,则消息将丢失并且不会重试。您应该考虑更改您的代码,以便仅在 处理邮件后删除邮件。
建议使用多线程处理消息,因为它会通过并行处理消息提高消息吞吐量。这也是一个更简单的设计,简单总是最好的。让一个进程检索消息然后触发线程来处理消息的替代想法更加复杂,并且没有任何好处。
Amazon SQS 队列 偶尔会 return 同一消息多次 。这种情况很少见,但可能会发生。多线程设计可能会导致它比单线程设计发生得更多,因为多个线程可能同时检索相同的消息。但是,它仍然可能在单线程模型中发生。
如果担心处理同一条消息两次,请考虑使用 FIFO queue(目前并非在每个 AWS 区域都可用)。这将保证每条消息只被接收一次。或者,您的代码需要检查特定消息是否已被处理(例如,通过检查数据库)。
多线程设计还允许您通过让多个系统(甚至跨多个可用区)处理消息来水平扩展,而您的单线程设计只有一个故障点并且可扩展性较差。