2011-02-08 70 views
17

Có cách nào để chặn các thư trùng lặp trên hàng đợi được xác định trên máy chủ ActiveMQ?Tránh các thư trùng lặp trên JMS/ActiveMQ

Tôi đã cố định nghĩa JMSMessageID theo cách thủ công, (message.setJMSMessageID ("uniqueid")), nhưng máy chủ bỏ qua sửa đổi này và gửi thông báo với JMSMessageID được tạo sẵn.

Theo đặc điểm kỹ thuật, tôi không tìm thấy tham chiếu về cách loại bỏ các thư trùng lặp.

Trong HornetQ, để giải quyết vấn đề này, chúng ta cần khai báo đặc tính HQ cụ thể org.hornetq.core.message.impl.HDR_DUPLICATE_DETECTION_ID trên định nghĩa thư.

tức là .:

Message jmsMessage = session.createMessage(); 
String myUniqueID = "This is my unique id"; // Could use a UUID for this 
message.setStringProperty(HDR_DUPLICATE_DETECTION_ID.toString(), myUniqueID); 

Ai biết nếu có một giải pháp tương tự cho ActiveMQ?

Trả lời

7

Bạn nên nhìn vào Apache Camel, nó cung cấp một bộ phận người tiêu dùng idempotent rằng sẽ làm việc với bất kỳ nhà cung cấp JMS, xem: http://camel.apache.org/idempotent-consumer.html

Sử dụng mà kết hợp với ActiveMQ Component được thiết kế sử dụng JMS khá đơn giản, xem: http://camel.apache.org/activemq.html

+1

Tôi nghi ngờ nếu phương pháp này sẽ giải quyết được vấn đề của tôi. Tôi cần phải giữ chỉ là một ví dụ của tin nhắn với cùng một JMSMessageID chỉ trong trường hợp này là trong hàng đợi. Tôi cần nó làm việc như một Set. Tôi muốn có thể đặt tin nhắn khác với cùng một JMSMessageID sau khi các yếu tố idem mới nhất đã được gỡ bỏ từ hàng đợi. Tôi cần phải thực hiện nó và kiểm tra. Nhưng, dựa trên Idempotent được mô tả trên cuốn sách EAI, tôi nghĩ rằng khái niệm này không phù hợp với sự cần thiết của tôi. BUT, giải pháp được đề xuất là tốt. Tôi sẽ nghiên cứu thêm về nó và bình luận ở đây kết quả của tôi. Cảm ơn – apast

4

Tôi nghi ngờ nếu ActiveMQ hỗ trợ nó một cách tự nhiên, nhưng sẽ dễ dàng để thực hiện một người tiêu dùng không cần thiết. Một cách để làm điều này là thêm một mã định danh duy nhất vào mỗi thư ở cuối nhà sản xuất, bây giờ ở cuối người tiêu dùng bằng một cửa hàng (db, cache, vv), có thể kiểm tra xem thư đã được nhận trước chưa và tiếp tục xử lý dựa trên kiểm tra đó.

Tôi thấy câu hỏi về lưu lượng truy cập chồng trước đó dọc theo cùng một dòng - Apache ActiveMQ 5.3 - How to configure a queue to reject duplicate messages?, điều đó cũng có thể hữu ích.

3

Có một cách để làm cho ActiveMQ lọc các bản sao dựa trên thuộc tính JMS. nó liên quan đến việc viết một Activemq Plugin. Bộ lọc môi giới cơ bản gửi thư trùng lặp tới hàng đợi bản tin sẽ như thế này

import java.util.List; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

import org.apache.activemq.broker.Broker; 
import org.apache.activemq.command.Message; 
import org.apache.activemq.command.ActiveMQMessage; 
import org.apache.activemq.broker.BrokerFilter; 
import org.apache.activemq.broker.ConnectionContext; 
import org.apache.activemq.command.ConnectionInfo; 
import org.apache.activemq.broker.ProducerBrokerExchange; 

public class DuplicateFilterBroker extends BrokerFilter { 
    String messagePropertyName; 
    boolean switchValue; 

    public DuplicateFilterBroker(Broker next, String messagePropertyName) { 
     super(next); 
     this.messagePropertyName = messagePropertyName; 
    } 

    public boolean hasDuplicate(String propertyValue){ 
     switchValue = propertyValue; 
     return switchValue; 
    } 

    public void send(ProducerBrokerExchange producerExchange, Message msg) throws Exception { 
     ActiveMQMessage amqmsg = (ActiveMQMessage)msg; 
     Object msgObj = msg.getMessage(); 
     if (msgObj instanceof javax.jms.Message) { 
      javax.jms.Message jmsMsg = (javax.jms.Message) msgObj; 
      if (!hasDuplicate(jmsMsg.getStringProperty(messagePropertyName))) { 
       super.send(producerExchange, msg); 
      } 
      else { 
       sendToDeadLetterQueue(producerExchange.getConnectionContext(), msg); 
      } 
     } 
    } 
} 
+0

chắc chắn là một cách rất rất tốt đẹp để giải quyết vấn đề này. – user1052080

3

Hiện tại, hỗ trợ xóa thư trùng lặp được đưa vào ActiveMQ. Xem các giá trị cấu hình auditDepthauditMaximumProducerNumber trong Connection Configuration Guide.

+3

làm thế nào để bạn thực sự cấu hình các tham số để tránh trùng lặp? – Thomas

+0

@Thomas Tôi không chắc chắn những gì bạn đang yêu cầu. Nói chung, làm thế nào để áp dụng cấu hình trong ActiveMQ? Hoặc những giá trị nào để sử dụng cho các trường cụ thể này? –

+0

Nó chỉ là từ các mô tả của các tham số nó không âm thanh quá rõ ràng với tôi. Ví dụ 'auditDepth', giá trị có nghĩa là Nb của các thông điệp hoặc số byte của byte sẽ được kiểm tra ngược lại để sao chép không? Về 'auditMaximumProducerNumber', điều đó có nghĩa là có một số lượng hạn chế các nhà sản xuất sẽ được sàng lọc? Btw, nếu một thông điệp có cùng nội dung được xuất bản bởi 2 người đăng ký khác nhau, thì thông điệp đó có được coi là trùng lặp không? – Thomas

0

Dường như cách được đề xuất trong câu hỏi, cũng hoạt động cho ActiveMQ (2016/12). Xem hướng dẫn activemq-artemis. Điều này yêu cầu nhà sản xuất thiết lập một thuộc tính cụ thể vào tin nhắn.

Message jmsMessage = session.createMessage(); 
String myUniqueID = "This is my unique id"; // Could use a UUID for this 
message.setStringProperty(HDR_DUPLICATE_DETECTION_ID.toString(), myUniqueID); 

Tuy nhiên lớp chứa tài sản là khác nhau: org.apache.activemq.artemis.core.message.impl.HDR_DUPLICATE_DETECTION_ID và giá trị tài sản là _AMQ_DUPL_ID.

Các vấn đề liên quan