RFC 2920 – SMTP Pipelining RFC 2920 – Đường ống SMTP
Tại Sao RFC Này Tồn Tại
SMTP tiêu chuẩn là một giao thức yêu cầu-phản hồi nghiêm ngặt. Máy khách gửi một lệnh, chờ phản hồi của máy chủ, sau đó gửi lệnh tiếp theo. Mỗi vòng lặp đều tăng độ trễ, đặc biệt là qua các liên kết mạng có độ trễ cao. Đối với một tin nhắn có 50 người nhận, máy khách sẽ cần 50 vòng lặp riêng biệt chỉ để các lệnh RCPT TO.
RFC 2920 định nghĩa phần mở rộng SMTP PIPELINING, cho phép máy khách gửi nhiều lệnh cùng một lúc mà không cần chờ phản hồi từng cái. Máy chủ đệm và xử lý các lệnh theo thứ tự, sau đó gửi lại tất cả phản hồi. Điều này làm giảm đáng kể tổng thời gian cho một phiên SMTP.
Pipelining là một trong những phần mở rộng SMTP được hỗ trợ rộng rãi nhất. Hầu như mọi máy chủ thư hiện đại đều quảng cáo nó, và hầu hết thư viện máy khách SMTP sử dụng nó theo mặc định.
Cách Hoạt Động
- Máy khách gửi
EHLOvà xác nhận máy chủ quảng cáoPIPELININGtrong danh sách khả năng. - Máy khách nhóm các lệnh có thể pipeline một cách an toàn — thường là
MAIL FROM, một hoặc nhiềuRCPT TO, vàDATA. - Máy khách gửi tất cả các lệnh này liên tiếp mà không cần chờ phản hồi riêng lẻ.
- Máy chủ xử lý từng lệnh theo thứ tự và gửi lại một phản hồi cho mỗi lệnh, theo thứ tự.
- Máy khách đọc tất cả các phản hồi và xử lý bất kỳ lỗi nào (ví dụ: một người nhận bị từ chối).
Ví Dụ SMTP
Không có pipelining (5 vòng lặp cho bao thư):
Có pipelining (1 vòng lặp cho toàn bộ bao thư):
Chi Tiết Kỹ Thuật Chính
Lệnh Nào Có Thể Được Pipelined
Không phải tất cả các lệnh SMTP đều an toàn để pipeline. RFC 2920 chia các lệnh thành hai loại:
| An Toàn Để Pipeline | Phải Chờ Phản Hồi |
|---|---|
MAIL FROM |
EHLO / HELO
|
RCPT TO |
STARTTLS |
DATA |
AUTH |
RSET |
QUIT |
NOOP |
DATA content (the dot-stuffed body) |
Các lệnh thay đổi trạng thái kết nối (EHLO, STARTTLS, AUTH) là những điểm đồng bộ hóa — máy khách phải chờ phản hồi trước khi gửi bất cứ thứ gì khác.
Xử Lý Lỗi
Khi pipelining, một số lệnh trong một nhóm có thể thành công trong khi những lệnh khác thất bại. Máy khách phải khớp phản hồi với các lệnh theo thứ tự. Một RCPT TO bị từ chối không làm vô hiệu hóa toàn bộ giao dịch — tin nhắn vẫn được gửi tới các người nhận được chấp nhận. Tuy nhiên, nếu MAIL FROM bị từ chối, các lệnh RCPT TO tiếp theo cũng sẽ thất bại.
Cân Nhắc Đệm TCP
Pipelining dựa vào đệm TCP. Máy khách ghi nhiều lệnh vào socket mà không cần đọc, tin tưởng rằng bộ đệm gửi TCP có thể chứa chúng. Đối với các nhóm RCPT TO rất lớn (hàng trăm hoặc hàng nghìn), máy khách có thể cần phải pipeline theo các nhóm để tránh lấp đầy bộ đệm TCP và bế tắc.
Tương Tác Với STARTTLS
Sau phản hồi EHLO bao gồm STARTTLS, máy khách phải không pipeline STARTTLS với các lệnh khác. Bắt tay TLS thay đổi trạng thái của toàn bộ kết nối, vì vậy nó là một điểm đồng bộ hóa cứng. Sau khi TLS được thiết lập và gửi EHLO mới, pipelining có thể tiếp tục.
Sai Lầm Phổ Biến
- Pipelining EHLO hoặc STARTTLS với các lệnh khác. Đây là những điểm đồng bộ hóa. Pipelining chúng gây ra lỗi giao thức vì phản hồi của máy chủ thay đổi trạng thái phiên mà các lệnh tiếp theo phụ thuộc vào.
- Không đọc tất cả các phản hồi trước khi xử lý lỗi. Nếu bạn pipeline 5 lệnh, bạn phải đọc tất cả 5 phản hồi, ngay cả khi lệnh đầu tiên là lỗi. Từ bỏ luồng phản hồi làm hỏng trạng thái giao thức.
-
Giả định rằng tất cả máy chủ đều hỗ trợ pipelining. Mặc dù gần như phổ quát, pipelining là một phần mở rộng. Luôn kiểm tra phản hồi
EHLOchoPIPELININGtrước khi sử dụng. Quay lại chế độ một-lần-một nếu không có. -
Pipelining sau khi MAIL FROM bị từ chối. Nếu
MAIL FROMbị từ chối và bạn đã pipeline các lệnhRCPT TO, chúng sẽ tất cả thất bại. Đọc phản hồiMAIL FROMtrước khi pipeline các người nhận, hoặc chuẩn bị để xử lý các lỗi liên tầng. -
Gửi nội dung DATA trong pipeline. Lệnh
DATAcó thể được pipeline, nhưng nội dung tin nhắn theo sau không thể. Bạn phải chờ phản hồi354choDATAtrước khi gửi nội dung tin nhắn.
Tác Động Đến Khả Năng Gửi
- Gửi nhanh hơn cho tin nhắn nhiều người nhận. Pipelining giảm tin nhắn N-người nhận từ N+2 vòng lặp xuống khoảng 2 vòng lặp cho giai đoạn bao thư. Trên các kết nối có độ trễ cao, điều này tiết kiệm vài giây trên mỗi tin nhắn.
- Thông lượng cao hơn cho gửi hàng loạt. Khi gửi nhiều tin nhắn qua cùng một kết nối, pipelining cho phép bạn chồng chéo bao thư của tin nhắn tiếp theo với quá trình truyền dữ liệu của tin nhắn hiện tại, tối đa hóa sử dụng kết nối.
- Thời gian kết nối giảm. Các phiên ngắn hơn có nghĩa là ít thời gian giữ mở các kết nối. Điều này rất quan trọng đối với các máy chủ thực thi giới hạn thời gian mỗi kết nối hoặc giới hạn tốc độ dựa trên thời lượng kết nối.
- Hành vi tốt hơn dưới tải. Pipelining giảm số lượng vòng lặp mạng, giảm tải trên cả máy chủ gửi và nhận. Điều này làm cho cơ sở hạ tầng gửi của bạn hiệu quả hơn.
-
Từ chối từng người nhận vẫn hoạt động. Pipelining không giảm khả năng của máy chủ để từ chối các người nhận cá nhân. Mỗi
RCPT TOvẫn nhận mã phản hồi riêng của nó, vì vậy xử lý phản hồi hoạt động chính xác như nhau.