Một sự hiểu biết khái niệm tốt về những gì giao thức AMQP thực hiện "dưới mui xe" là hữu ích ở đây. Tôi sẽ cung cấp rằng tài liệu và API mà AMQP 0.9.1 đã chọn để triển khai làm cho điều này đặc biệt khó hiểu, vì vậy câu hỏi này là một câu hỏi mà nhiều người phải vật lộn với.
TL; DR
Một kết nối là ổ cắm TCP được thương lượng vật lý với máy chủ AMQP. Các máy khách được triển khai đúng cách sẽ có một trong số các ứng dụng này, an toàn theo luồng, có thể chia sẻ giữa các luồng.
Một kênh là một phiên ứng dụng duy nhất trên kết nối. Một chủ đề sẽ có một hoặc nhiều trong số các phiên này. Kiến trúc AMQP 0.9.1 là những thứ này không được chia sẻ giữa các luồng và nên được đóng / hủy khi luồng tạo ra nó kết thúc với nó. Chúng cũng bị đóng bởi máy chủ khi xảy ra các vi phạm giao thức khác nhau.
Khách hàng là một cấu trúc ảo đại diện cho sự hiện diện của "hộp thư" trên một kênh cụ thể. Việc sử dụng của người tiêu dùng nói với người môi giới để đẩy các thông điệp từ một hàng đợi cụ thể đến điểm cuối kênh đó.
Sự kiện kết nối
Đầu tiên, như những người khác đã chỉ ra một cách chính xác, một kết nối là đối tượng đại diện cho kết nối TCP thực sự đến máy chủ. Các kết nối được chỉ định ở cấp giao thức trong AMQP và tất cả giao tiếp với nhà môi giới xảy ra qua một hoặc nhiều kết nối.
- Vì là kết nối TCP thực tế, nó có Địa chỉ IP và Cổng #.
- Các tham số giao thức được đàm phán trên cơ sở mỗi khách hàng như là một phần của việc thiết lập kết nối (một quá trình được gọi là bắt tay .
- Nó được thiết kế để tồn tại lâu dài ; có vài trường hợp đóng kết nối là một phần của thiết kế giao thức.
- Từ góc độ OSI, nó có thể nằm ở đâu đó xung quanh Lớp 6
- Nhịp tim có thể được thiết lập để theo dõi trạng thái kết nối, vì TCP không chứa bất cứ thứ gì trong chính nó để làm điều này.
- Tốt nhất là có một luồng quản lý chuyên dụng đọc và ghi vào ổ cắm TCP bên dưới. Hầu hết, nếu không phải tất cả, khách hàng của RabbitMQ làm điều này. Về vấn đề đó, chúng thường an toàn cho chủ đề.
- Nói một cách tương đối, các kết nối là "tốn kém" để tạo ra (do bắt tay), nhưng thực tế mà nói, điều này thực sự không quan trọng. Hầu hết các quá trình thực sự sẽ chỉ cần một đối tượng kết nối. Nhưng, bạn có thể duy trì các kết nối trong một nhóm, nếu bạn thấy bạn cần nhiều thông lượng hơn một luồng / ổ cắm duy nhất có thể cung cấp (không thể với công nghệ điện toán hiện tại).
Sự kiện kênh
Một kênh là phiên ứng dụng được mở ra cho mỗi phần của ứng dụng của bạn để liên lạc với người môi giới RabbitMQ. Nó hoạt động trên một kết nối duy nhất và đại diện cho một phiên với nhà môi giới.
- Vì nó đại diện cho một phần logic của logic ứng dụng, mỗi kênh thường tồn tại trên luồng riêng của nó.
- Thông thường, tất cả các kênh được mở bởi ứng dụng của bạn sẽ chia sẻ một kết nối (chúng là các phiên nhẹ hoạt động trên đầu kết nối). Các kết nối là an toàn chủ đề, vì vậy điều này là OK.
- Hầu hết các hoạt động AMQP diễn ra trên các kênh.
- Từ phối cảnh Lớp OSI, các kênh có thể nằm xung quanh Lớp 7 .
- Các kênh được thiết kế tạm thời ; một phần của thiết kế AMQP là kênh thường bị đóng để phản hồi lỗi (ví dụ: khai báo lại một hàng đợi với các tham số khác nhau trước khi xóa hàng đợi hiện có).
- Vì chúng là nhất thời, các kênh không nên được tổng hợp bởi ứng dụng của bạn.
- Máy chủ sử dụng một số nguyên để xác định một kênh. Khi luồng quản lý kết nối nhận được một gói cho một kênh cụ thể, nó sử dụng số này để báo cho người môi giới biết gói / phiên thuộc về kênh nào.
- Các kênh nói chung không an toàn cho luồng vì sẽ không có ý nghĩa khi chia sẻ chúng giữa các luồng. Nếu bạn có một chủ đề khác cần sử dụng nhà môi giới, một kênh mới là cần thiết.
Thông tin người tiêu dùng
Một người tiêu dùng là một đối tượng được xác định bởi giao thức AMQP. Nó không phải là kênh cũng không phải là kết nối, thay vào đó là thứ mà ứng dụng cụ thể của bạn sử dụng làm "hộp thư" sắp xếp để gửi tin nhắn.
- "Tạo người tiêu dùng" có nghĩa là bạn thông báo cho nhà môi giới (sử dụng kênh thông qua kết nối ) rằng bạn muốn tin nhắn được gửi đến bạn qua kênh đó. Đáp lại, nhà môi giới sẽ đăng ký rằng bạn có một người tiêu dùng trên kênh và bắt đầu đẩy tin nhắn cho bạn.
- Mỗi thông báo được đẩy qua kết nối sẽ tham chiếu cả số kênh và số người tiêu dùng . Theo cách đó, luồng quản lý kết nối (trong trường hợp này, trong API Java) biết phải làm gì với thông báo; sau đó, luồng xử lý kênh cũng biết phải làm gì với thông báo.
- Việc triển khai của người tiêu dùng có số lượng biến thể lớn nhất, bởi vì nó thực sự là ứng dụng cụ thể. Trong quá trình thực hiện, tôi đã chọn loại bỏ một nhiệm vụ mỗi khi có tin nhắn đến người tiêu dùng; do đó, tôi có một luồng quản lý kết nối, một luồng quản lý kênh (và theo phần mở rộng, người tiêu dùng) và một hoặc nhiều luồng tác vụ cho mỗi thông báo được gửi qua người tiêu dùng.
- Đóng kết nối sẽ đóng tất cả các kênh trên kết nối. Đóng một kênh sẽ đóng tất cả người tiêu dùng trên kênh. Cũng có thể hủy một người tiêu dùng (mà không đóng kênh). Có nhiều trường hợp khác nhau khi thực hiện bất kỳ điều gì trong ba điều này.
- Thông thường, việc triển khai người tiêu dùng trong ứng dụng khách AMQP sẽ phân bổ một kênh dành riêng cho người tiêu dùng để tránh xung đột với các hoạt động của các luồng hoặc mã khác (bao gồm xuất bản).
Xét về ý nghĩa của nhóm chủ đề người tiêu dùng, tôi nghi ngờ rằng máy khách Java đang làm một cái gì đó tương tự như những gì tôi đã lập trình cho máy khách của mình (tôi đã dựa trên máy khách .Net, nhưng đã được sửa đổi rất nhiều).