Thứ tư, 26/02/2014 | 00:00 GMT+7

Cách gửi tin nhắn dựa trên các phím định tuyến bằng thư viện RabbitMQ và Puka Python

Văn bản này là phần tiếp theo của Cách sử dụng RabbitMQ và Python của Puka để gửi thông điệp đến nhiều người tiêu dùng và yêu cầu cùng một gói phần mềm được cài đặt và chạy đúng cách. Ngoài ra, các định nghĩa tương tự cũng được sử dụng trong toàn bộ bài báo và ta giả định người đọc đã quen với các chủ đề từ văn bản cũ.

Bắt đầu


Yêu cầu


Sở giao dịch


Ta đã mô tả về trao đổi fanout , cung cấp thông điệp đến mọi hàng đợi ràng buộc với trao đổi đó mà không có luật bổ sung nào được áp dụng. Đó là một cơ chế rất hữu ích, nhưng thiếu tính linh hoạt. Thường không mong muốn nhận được mọi thứ mà một nhà production phát ra cho sàn giao dịch. RabbitMQ cung cấp hai loại trao đổi khác nhau được dùng để thực hiện các kịch bản phức tạp hơn. Một trong số đó là trao đổi direct .

Trao đổi trực tiếp



Trao đổi trực tiếp cung cấp một cơ chế định tuyến dựa trên khóa đơn giản trong RabbitMQ . Nó tương tự như trao đổi không tên được sử dụng trong ví dụ đầu tiên, trong đó một thông điệp được gửi đến hàng đợi có tên bằng với khóa định tuyến của thông báo. Tuy nhiên, trong khi với trao đổi không tên, không cần xác định ràng buộc hàng đợi rõ ràng, trong trao đổi trực tiếp, ràng buộc là quan trọng và bắt buộc.

Khi sử dụng trao đổi trực tiếp, mỗi thông báo được tạo cho trao đổi đó phải có một khóa định tuyến được chỉ định, đó là một chuỗi tên tùy ý, ví dụ: Texas . Sau đó, thông báo sẽ được gửi đến tất cả các hàng đợi đã được liên kết với trao đổi này với cùng một khóa định tuyến (tất cả các hàng đợi đã được khai báo rõ ràng là quan tâm đến các thông báo có khóa định tuyến Texas ).

Sự khác biệt lớn nhất giữa trao đổi không tên cơ bản và trao đổi direct là trao đổi sau cần các ràng buộc và không có hàng đợi nào lắng nghe thông báo trên trao đổi đó trước đó. Điều đó lần lượt dẫn đến ba lợi thế lớn.

  1. Một hàng đợi có thể được ràng buộc để nghe nhiều khóa định tuyến khác nhau trên cùng một trao đổi

  2. Một hàng đợi có thể bị ràng buộc để nghe trên nhiều sàn giao dịch khác nhau cùng một lúc

  3. Nhiều hàng đợi có thể bị ràng buộc để nghe cùng một khóa định tuyến trên một sàn giao dịch

Hãy tưởng tượng một trung tâm city lớn: một ga xe lửa và xe buýt, với nhiều điểm đến có thể đến được bằng cả hai phương tiện giao thông. Và hãy tưởng tượng rằng nhà ga muốn gửi thông báo khởi hành bằng RabbitMQ . Nhiệm vụ là thông báo cho mọi người quan tâm rằng xe buýt hoặc xe lửa đến Seattle , Tooele hoặc Boston sẽ sớm khởi hành.

Một chương trình như vậy sẽ xác định một trao đổi departures trực tiếp mà tất cả khách hàng quan tâm có thể đăng ký xếp hàng của họ. Sau đó, các thông báo có chứa thời gian khởi hành sẽ được gửi tới trao đổi đó với khóa định tuyến chứa điểm đến. Ví dụ:

  1. Thông báo departures trao đổi với khóa định tuyến Tooele và nội dung 2014-01-03 15:23

  2. Thông báo departures trao đổi với khóa định tuyến Boston và nội dung 2014-01-03 15:41

  3. Thông báo departures trao đổi với khóa định tuyến Seattle và nội dung 2014-01-03 15:55

Vì một hàng đợi có thể được liên kết với nhiều khóa định tuyến cùng một lúc và nhiều hàng đợi có thể được liên kết với cùng một khóa, ta có thể dễ dàng có:

  1. Một khách hàng chỉ quan tâm đến Tooele

  2. Một khách hàng chỉ quan tâm đến Boston

  3. Một khách hàng khác quan tâm đến TooeleBoston cùng lúc

Tất cả chờ đợi thông tin cùng một lúc.Họ sẽ nhận được tin nhắn thích hợp bằng cách sử dụng trao đổi trực tiếp của ta .

Người production


Để đơn giản hóa nhiệm vụ một chút cho ví dụ, hãy viết một trình điều phối thông báo cơ bản sẽ chấp nhận một tham số dòng lệnh. Nó sẽ chỉ định điểm đến và ứng dụng sẽ gửi thời gian hiện tại cho tất cả người tiêu dùng quan tâm.

Tạo một tập lệnh python mẫu có tên direct_notify.py

vim direct_notify.py 

và dán nội dung tập lệnh:

import puka import datetime import time import sys  # declare and connect a producer producer = puka.Client("amqp://localhost/") connect_promise = producer.connect() producer.wait(connect_promise)  # create a direct exchange named departures exchange_promise = producer.exchange_declare(exchange='departures', type='direct') producer.wait(exchange_promise)  # send current time to destination specified with command line argument message = "%s" % datetime.datetime.now()  message_promise = producer.basic_publish(exchange='departures', routing_key=sys.argv[1], body=message) producer.wait(message_promise)  print "Departure to %s at %s" % (sys.argv[1], message)  producer.close() 

Nhấn : wq để lưu file và thoát.

Chạy tập lệnh với một tham số sẽ in ra thời gian hiện tại và điểm đến đã sử dụng. Đầu ra sẽ giống như sau:

root@rabbitmq:~# python direct_notify.py Tooele Departure to Tooele at 2014-02-18 15:57:29.035000 root@rabbitmq:~# 

Hãy xem qua kịch bản từng bước:

  1. Máy khách Producer được tạo và kết nối với version RabbitMQ local . Từ bây giờ nó có thể giao tiếp với RabbitMQ một cách tự do.

  2. Một trao đổi trực tiếp departures được đặt tên được tạo ra. Nó không cần khóa định tuyến được chỉ định khi tạo, vì bất kỳ thông báo nào được xuất bản tới trao đổi đó đều có thể được gán khóa khác cho nó. Sau bước đó, trao đổi tồn tại trên server RabbitMQ và được dùng để liên kết hàng đợi với nó và gửi tin nhắn qua nó.

  3. Một thông báo chứa thời gian hiện tại được xuất bản lên sàn giao dịch đó, sử dụng tham số dòng lệnh làm khóa định tuyến. Trong lần chạy mẫu, Tooele được sử dụng làm tham số và do đó làm khóa định tuyến - đích khởi hành.

Lưu ý: để đơn giản, tập lệnh không kiểm tra xem đối số dòng lệnh bắt buộc có được cung cấp hay không! Nó sẽ không hoạt động bình thường nếu được thực thi mà không có tham số.

Khách hàng


Ứng dụng tiêu dùng ví dụ này sẽ hoạt động như một khách hàng vận tải công cộng quan tâm đến một hoặc nhiều điểm đến có thể đến được từ nhà ga.

Tạo một tập lệnh python mẫu có tên direct_watch.py

vim direct_watch.py 

và dán nội dung tập lệnh:

import puka import sys  # declare and connect a consumer consumer = puka.Client("amqp://localhost/") connect_promise = consumer.connect() consumer.wait(connect_promise)  # create temporary queue queue_promise = consumer.queue_declare(exclusive=True) queue = consumer.wait(queue_promise)['queue']  # bind the queue to all routing keys specified by command line arguments for destination in sys.argv[1:]:     print "Watching departure times for %s" % destination     bind_promise = consumer.queue_bind(exchange='departures', queue=queue, routing_key=destination)     consumer.wait(bind_promise)  # start waiting for messages on the queue created beforehand and print them out message_promise = consumer.basic_consume(queue=queue, no_ack=True)  while True:     message = consumer.wait(message_promise)     print "Departure for %s at %s" % (message['routing_key'], message['body'])  consumer.close() 

Nhấn : wq để lưu file và thoát.

Chạy tập lệnh với một tham số Tooele sẽ thông báo rằng tập lệnh xem thời gian khởi hành cho Tooele , trong khi chạy tập lệnh với nhiều tham số sẽ thông báo xem thời gian khởi hành cho nhiều điểm đến.

root@rabbitmq:~# python direct_watch.py Tooele Watching departure times for Tooele (...) root@rabbitmq:~# python direct_watch.py Tooele Boston Watching departure times for Tooele Watching departure times for Boston (...) root@rabbitmq:~# 

Hãy xem từng bước script để giải thích những gì nó làm:

  1. Khách hàng tiêu dùng được tạo và kết nối với version RabbitMQ local . Từ bây giờ nó có thể giao tiếp với RabbitMQ một cách tự do.

  2. Hàng đợi tạm thời cho người tiêu dùng cụ thể này được tạo, với tên do RabbitMQ tạo tự động. Hàng đợi sẽ bị hủy sau khi tập lệnh kết thúc.

  3. Hàng đợi được ràng buộc với tất cả các departures trao đổi trên tất cả các phím định tuyến (điểm đến) được chỉ định bằng cách sử dụng các tham số dòng lệnh, in thông tin trên màn hình mỗi điểm đến.

  4. Tập lệnh bắt đầu chờ tin nhắn trên hàng đợi. Nó sẽ nhận được tất cả các thông báo trùng với các khóa định tuyến bị ràng buộc. Khi chạy với Tooele dưới dạng một tham số duy nhất - chỉ những tham số này, khi chạy với cả TooeleBoston - trên cả hai. Mỗi thời gian khởi hành sẽ được in trên màn hình.

Thử nghiệm


Để kiểm tra xem cả hai tập lệnh có hoạt động như mong đợi hay không, hãy mở ba cửa sổ terminal vào server . Một sẽ được sử dụng như một trạm giao thông công cộng để gửi thông báo. Hai người khác sẽ phục vụ như khách hàng chờ khởi hành.

Trong terminal đầu tiên, hãy chạy tập lệnh direct_notify.py một lần với bất kỳ tham số nào:

root@rabbitmq:~# python direct_notify.py Tooele Departure to Tooele at 2014-02-18 15:57:29.035000 root@rabbitmq:~# 

Quan trọng: tập lệnh direct_notify.py phải được thực thi ít nhất một lần trước bất kỳ người tiêu dùng nào, vì trao đổi phải được tạo trước khi ràng buộc hàng đợi với nó. Sau khi thực hiện, trao đổi vẫn ở trên server RabbitMQ và được dùng tự do.

Trong terminal thứ hai, chạy tập lệnh direct_watch.py với một tham số - Tooele :

root@rabbitmq:~# python direct_watch.py Tooele Watching departure times for Tooele (...) root@rabbitmq:~# 

Trong terminal thứ ba, chạy tập lệnh direct_watch.py với hai tham số - TooeleBoston :

root@rabbitmq:~# python direct_watch.py Tooele Boston Watching departure times for Tooele Watching departure times for Boston (...) root@rabbitmq:~# 

Sau đó, quay lại nhà ga đầu tiên, gửi ba thông báo khởi hành. Một đến Tooele , một đến Boston và một đến Chicago :

root@rabbitmq:~# python direct_notify.py Tooele Departure to Tooele at 2014-02-18 15:57:29.035000 root@rabbitmq:~# python direct_notify.py Boston Departure to Tooele at 2014-02-18 15:57:31.035000 root@rabbitmq:~# python direct_notify.py Chicago Departure to Tooele at 2014-02-18 15:57:35.035000 root@rabbitmq:~# 

Thông báo đầu tiên chỉ được nhận bởi cả những người tiêu dùng đang chờ chuyến khởi hành đến Tooele. Chiếc thứ hai chỉ đến tay khách hàng đang chờ khởi hành đến Boston. Người thứ ba không nên nhận bởi bất kỳ người tiêu dùng nào trong số này, vì không ai trong số họ chờ khởi hành đến Chicago.

Đây là hành vi được mong đợi. Những ví dụ đơn giản đó minh họa cách gửi thông báo mà chỉ một số người tiêu dùng nhất định được chỉ định bởi khóa định tuyến mới nhận được.

đọc thêm


Định tuyến trực tiếp không cung cấp khả năng kiểm soát hoàn toàn nơi các tin nhắn sẽ được gửi, nhưng là một bước tiến lớn so với trao đổi fanout được sử dụng trong các sàn giao dịch trước đó, vốn đưa tin nhắn đến mọi nơi một cách mù quáng. Với trao đổi direct nhiều kịch bản nhắn tin trong thế giới thực có thể được phục vụ và quá trình này không quá khó khăn.

Mục tiêu chính của văn bản này là giới thiệu định tuyến trực tiếp cơ bản sử dụng một tình huống thực tế, đơn giản. Nhiều cách sử dụng khác được đề cập chi tiết trong tài liệu chính thức của RabbitMQ , đây là một tài nguyên tuyệt vời cho user và administrator RabbitMQ.

<div class = “author”> Bài viết được gửi bởi: <a href=p>http://maticomp.net[> Mateusz Papiernik </a> </div>


Tags:

Các tin liên quan

Cách đóng gói và phân phối các ứng dụng Python
2014-01-14
Cách triển khai ứng dụng web WSGI Python dựa trên kim tự tháp
2013-12-30
Cách triển khai ứng dụng WSGI Python bằng server Gunicorn HTTP đằng sau Nginx
2013-12-12
Cách triển khai ứng dụng WSGI Python bằng web server uWSGI với Nginx
2013-12-11
Cách triển khai ứng dụng WSGI Python bằng web server CherryPy đằng sau Nginx
2013-12-10
Cách sử dụng khung kim tự tháp để xây dựng ứng dụng web Python của bạn trên Ubuntu
2013-12-10
Cách thiết lập Python 2.7.6 và 3.3.3 trên CentOS 6.4
2013-12-04
Các công cụ Python phổ biến: Sử dụng virtualenv, Cài đặt bằng Pip và Quản lý Gói
2013-12-03
Cách tạo plugin Nagios bằng Python trên Ubuntu 12.10
2013-04-29
Cách tạo plugin Nagios bằng Python trên CentOS 6
2013-04-29