2016-12-08 21 views
14

Trong môi trường của chúng tôi, chúng tôi sử dụng RabbitMQ và Celery trên AWS để chạy các tác vụ song song trên nhiều nút.Thả kết nối cần tây với AWS ELB và RabbitMQ

Gần đây, chúng tôi đã biến RabbitMQ thành một cụm gồm 3 nút, cấu hình chính sách ha và thêm bộ cân bằng tải đàn hồi AWS (ELB) cho cổng 5672 cho tất cả 3 nút. Tất cả nhân viên Celery và mã khách hàng đều sử dụng DNS ELB làm URL của nhà môi giới.

Chúng tôi đã nhận thấy kể từ khi thay đổi đó, chờ đợi cho các tác vụ không đồng bộ để hoàn thành sẽ ném một ngoại lệ IOError: Socket closed.

ELB sẽ tắt tất cả các kết nối không hoạt động sau 60 giây. Chúng tôi có các nhiệm vụ mất vài giờ để hoàn thành.

Đặt BROKER_HEARTBEAT thành giá trị thấp hơn 60 kết nối được giải quyết giảm trên đầu người lao động. Nhưng chúng tôi dường như không thể tìm thấy bất kỳ cài đặt nào sẽ giữ kết nối khách hàng còn sống.

Đây có phải là cách tiếp cận chính xác để chờ các nhiệm vụ chạy dài với Celery không?

Một cách giải quyết khác mà chúng tôi chưa thử nghiệm, là nhớ lại phương thức AsyncResult.wait() cho đến khi kết thúc thành công. Vì vậy, ví dụ:

async_result = task.delay(params) 

while True: 
    try: 
     async_result.wait() 
     break 
    except IOError: 
     pass 

Chúng tôi sử dụng:

  1. RabbitMQ 3.6.5
  2. Cần tây 3.1.20
  3. Cần tây backend là pyamqp
  4. kết quả Cần tây backend là rpc
+1

Tôi sẽ đi ra ngoài trên một chi ở đây, nhưng tôi muốn nói rằng bạn đã có cho mình một vấn đề XY cổ điển. Ngay lập tức dơi có mùi đáng kể liên quan đến việc đình chỉ một sợi cho giờ chờ đợi trên công việc async. Thứ hai và trong trường hợp chung ELB/Tuyến 53 được thiết kế để phục vụ hàng triệu và hàng triệu yêu cầu. Với điều này xem xét trong tâm trí nếu họ giữ ổ cắm của bạn mở cửa cho giờ kết thúc họ sẽ bị choáng ngợp khá nhanh chóng. Tôi nghĩ rằng bạn sẽ tìm thấy bạn đang lau sàn với một con bạch tuộc ở đây, bạn phải bỏ cuộc và đi mua một cây lau. – nsfyn55

Trả lời

3

Tôi tin rằng những gì bạn cần làm là kéo dài thời gian chờ trên AWS E LB. Điều đang xảy ra là kết nối đang bị đóng trước khi nhiệm vụ hoàn tất. Bạn có thể thực hiện việc này bằng cách phát hành lệnh sau

elb-modify-lb-attributes myTestELB --connection-settings "idletimeout=3600" --headers 

Điều này sẽ cung cấp cho bạn một giờ để hoàn thành tác vụ. Xem https://aws.amazon.com/blogs/aws/elb-idle-timeout-control/ để biết thêm thông tin về điều này.

Nếu một giờ không đủ thì bạn sẽ phải vô hiệu hóa kết nối tổng hợp. Thêm hai cài đặt này vào cấu hình cần tây của bạn

BROKER_POOL_LIMIT = None 
BROKER_TRANSPORT_OPTIONS = {'confirm_publish': True} 

Thứ hai sẽ có hiệu suất vì nó tăng thêm một số chi phí. Vì bạn có nhiệm vụ chạy dài nên đây có thể không phải là vấn đề. Các thiết lập thứ hai có thể không cần thiết nhưng tôi khuyên bạn nên nó cho rằng bạn đang đứng sau một cân bằng tải. Cài đặt này sẽ đảm bảo nhận được tin nhắn và không bị mất trong quá trình này.

Một tùy chọn khác là chia công việc dài của bạn thành các tác vụ nhỏ hơn! Điều này có thể có nghĩa là mã nhiều hơn nhưng nó có thể có giá trị trong thời gian dài.

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