2016-08-03 18 views
7

Tôi có một dự án Azure WebJob, mà tôi đang chạy cục bộ trên máy tính dev của tôi. Nó đang nghe một hàng đợi tin nhắn dịch vụ Azure. Không có gì diễn ra như Chủ đề, chỉ là hàng đợi thông điệp cơ bản nhất.Cách ngăn Azure webjob xử lý cùng một thư nhiều lần đồng thời

Nó đang nhận/xử lý cùng một thông báo nhiều lần, khởi chạy hai lần ngay lập tức khi nhận được tin nhắn, sau đó liên tục trong khi tin nhắn đang được xử lý.

Câu hỏi:

  • Tại sao tôi nhận được cùng một thông điệp nhiều lần ngay lập tức? Có vẻ như nó đang tìm nạp lại trước khi một PeekLock được áp dụng?
  • Thông báo đang được nhận lại như thế nào ngay cả khi tin nhắn vẫn đang được xử lý? Tôi có thể đặt thời lượng PeekLock hay bằng cách nào đó khóa tin nhắn để chỉ được xử lý một lần
  • Làm cách nào để đảm bảo rằng mỗi thư trên hàng đợi chỉ được xử lý một lần?
  • Tôi muốn có thể xử lý nhiều thư cùng một lúc, không phải cùng một thông báo nhiều lần, vì vậy, hãy đặt MaxConcurrentCalls thành 1 có vẻ không phải là câu trả lời của tôi hoặc tôi có hiểu nhầm thuộc tính đó không?

Tôi đang sử dụng một chức năng async, phun đơn giản và một JobActivator tùy chỉnh, vì vậy thay vì một khoảng trống phương pháp tĩnh, chữ ký Chức năng của tôi là:

public async Task ProcessQueueMessage([ServiceBusTrigger("AnyQueue")] MediaEncoderQueueItem message, TextWriter log) {...} 

Bên trong công việc, nó được di chuyển một số tập tin xung quanh trên một dịch vụ blob, và gọi (và chờ đợi) một bộ mã hóa phương tiện từ các dịch vụ truyền thông. Vì vậy, trong khi công việc web chính nó không phải là làm rất nhiều chế biến, phải mất khá nhiều thời gian (15 phút, đối với một số tập tin).

Ứng dụng sẽ khởi chạy và khi tôi đăng thông báo lên hàng đợi, nó sẽ phản hồi. Tuy nhiên, nó nhận được tin nhắn nhiều lần ngay sau khi nhận được tin nhắn:

Executing: 'Functions.ProcessQueueMessage' - Reason: 'New ServiceBus message detected on 'MyQueue'.' 
Executing: 'Functions.ProcessQueueMessage' - Reason: 'New ServiceBus message detected on 'MyQueue'.' 

Thêm vào đó, trong khi nhiệm vụ đang chạy (và tôi thấy đầu ra từ các chức năng dịch vụ Media), nó sẽ nhận được một "bản sao" từ hàng đợi.

cuối cùng sau khi tác vụ đã hoàn thành, nó vẫn không liên tục xử lý cùng một thông báo.

+1

DeliveryCount và LockDuration được chỉ định trên hàng đợi là gì? –

+0

Tôi cần xem xét nó. Điều kỳ lạ về LockDuration là nó dường như nhặt tin nhắn hai lần gần như ngay lập tức, như thể nó không khóa nó chút nào. Tôi tự hỏi nếu nó thực sự là một vấn đề với cách tôi đã thiết lập xử lý không đồng bộ? – AndrewP

+0

Tắt âm thanh một chút. Các nhà môi giới sẽ không bao giờ cung cấp cho cùng một thông điệp nhiều hơn một người tiêu dùng cạnh tranh nếu LockDuration đã không hết hạn. Tôi nghi ngờ điều gì đó khác đang xảy ra. Bất kỳ cơ hội nào bạn có thể chia sẻ một repro trên GitHub hoặc BitBucket? –

Trả lời

7

Tôi nghi ngờ điều gì đang xảy ra như sau: Tối đa DurationLock có thể là 5 phút. Nếu quá trình xử lý tin nhắn được thực hiện dưới 5 phút, tin nhắn được đánh dấu là đã hoàn thành và bị xóa khỏi nhà môi giới. Nếu không, thông báo sẽ xuất hiện lại nếu quá trình xử lý mất hơn 5 phút (chúng tôi đã mất khóa trên tin nhắn) và sẽ bị tiêu thụ lại. Bạn có thể xác minh điều đó bằng cách xem DeliveryCount thư của bạn.

Để giải quyết điều đó, bạn có thể gia hạn khóa tin nhắn ngay trước khi nó sắp hết hạn sử dụng BrokeredMessage.RenewLockAsync().

+0

Tôi sẽ kiểm tra phương thức đó và sẽ xem xét số lượng phân phối và thời lượng khóa. Điều kỳ lạ là nó không xảy ra mọi lúc, và dường như không có nhiều sự nhất quán về khi nó đang xảy ra, và cũng có vẻ như nó đang xử lý cùng một thông điệp hai lần ngay lập tức. Nhưng cảm ơn vì đã chỉ ra chức năng đó! – AndrewP

+0

@AndrewP Nó cũng có thể là trường hợp tự động thử lại nếu công việc của bạn là ném một ngoại lệ chưa được giải quyết, và bạn có tự động hoàn thành đúng trong cấu hình bus dịch vụ. Bạn có thể kiểm tra điều này bằng cách chỉ cần ném một ví dụ trong hàm kích hoạt của bạn, sau đó đăng một thông điệp lên chủ đề - bạn sẽ thấy một thông báo phát hiện cho đến khi số lần thử lại tối đa. – JoeBrockhaus

+0

Không phải khóa tự động được gia hạn theo mặc định? Vì vậy, sau 5 phút, khóa sẽ tự động được gia hạn nếu quá trình xử lý vẫn đang diễn ra. Hay tôi đang thiếu một cái gì đó? – GETah

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