Push Subscriptions — HTTP Endpoint & Retry Mechanics
Push subscription đảo ngược vai trò: thay vì subscriber chủ động pull message, Pub/Sub đóng vai trò HTTP client và gọi vào endpoint của bạn. Mô hình này đơn giản cho các use case nhỏ — không cần duy trì long-running process, chỉ cần expose một HTTP endpoint. Nhưng ẩn bên dưới là các cơ chế kiểm soát lưu lượng phức tạp mà nếu không hiểu, bạn có thể gặp overload endpoint hoặc message tích tụ mà không xử lý được.
Cơ chế delivery: Pub/Sub như HTTP client
Message delivery flow
Khi push subscription nhận được messages mới từ topic, Pub/Sub gọi HTTP POST tới endpoint đã cấu hình:
Pub/Sub → POST /your-endpoint HTTP/1.1
Content-Type: application/json
{
"message": {
"data": "<base64-encoded payload>",
"messageId": "12345",
"publishTime": "2025-01-15T10:00:00Z",
"attributes": {
"key": "value"
}
},
"subscription": "projects/my-project/subscriptions/my-subscription"
}Một request = một message. Push subscriptions gửi một message per HTTP request, không batch. Đây là khác biệt lớn so với pull (có thể nhận nhiều messages cùng lúc).
Acknowledgment qua HTTP status code
Endpoint phải trả về HTTP status code để ack hoặc nack:
Ack (thành công):
102,200,201,202,204— bất kỳ code nào trong danh sách này
Nack (thất bại, redeliver):
- Bất kỳ status code nào khác (4xx, 5xx, timeout)
- Không trả về response trong
ackDeadlineSeconds
Lưu ý: HTTP 4xx cũng trigger redeliver, không phải "không retry" như trong nhiều HTTP semantics thông thường. Pub/Sub không phân biệt 400 Bad Request với 500 Internal Server Error — cả hai đều là "nack, redeliver". Nếu message thực sự invalid và endpoint luôn trả 400, nó sẽ bị redeliver mãi cho đến khi Dead Letter Topic trigger.
HTTPS requirement
Push subscription bắt buộc HTTPS với certificate hợp lệ (không phải self-signed). Pub/Sub verify TLS certificate của endpoint. Endpoint phải:
- Publicly reachable (hoặc qua VPC private)
- TLS certificate valid (CA-signed, chưa expired)
- Không dùng self-signed certificate
Với Cloud Run, Cloud Functions, App Engine — endpoint tự động đáp ứng điều kiện này. Với custom server, phải cấu hình TLS đúng cách.
Push window — slow-start algorithm và rate control
Đây là phần ít được biết nhất nhưng quan trọng nhất để hiểu behavior của push subscriptions.
Push window là gì
Pub/Sub sử dụng khái niệm push window — số lượng concurrent outstanding HTTP requests tới endpoint tại bất kỳ thời điểm nào. Pub/Sub không gửi message mới cho đến khi có "slot" trong push window trống (tức là một request đang chờ response được resolve).
Slow-start mechanism: Push window không cố định — nó tăng dần dựa trên success rate:
- Mỗi successful delivery (HTTP 2xx): window size tăng lên
- Mỗi failed delivery hoặc timeout: window size giảm xuống
- Sau một số lần failure liên tiếp: Pub/Sub enter push backoff mode
Push window ceiling
Pub/Sub không publish chính xác giới hạn trên của push window, nhưng docs đề cập 3,000 outstanding messages per region là điểm mà growth trở thành linear thay vì exponential. Trong thực tế, push throughput bị giới hạn bởi:
- Response time của endpoint: Nếu endpoint mất 100ms/request và window = 100, throughput = 1,000 msg/s
- Window ceiling: Sau 3,000 outstanding, growth chậm lại
- Endpoint capacity: Pub/Sub sẽ không gửi nhanh hơn khả năng xử lý của endpoint
Với low-latency endpoint (< 10ms), push throughput có thể đạt cao. Với high-latency endpoint (> 1s), push window cần lớn hơn để đạt cùng throughput.
Retry mechanics và exponential backoff
Khi nào retry xảy ra
Pub/Sub retry push delivery khi:
- Endpoint trả về HTTP status khác 2xx
- Endpoint không trả response trong
ackDeadlineSeconds - Network error khi kết nối tới endpoint
Push backoff — cơ chế thực tế
Khi endpoint thất bại nhiều lần liên tiếp, Pub/Sub không retry ngay lập tức — nó apply exponential backoff:
Delay range: 100ms đến 60s (theo documentation)
Sau mỗi failure: delay tăng exponentially
Sau thành công: delay reset về minimumQuan trọng: Push backoff áp dụng globally cho toàn subscription, không per-message. Nếu endpoint đang bị quá tải và trả về 503, Pub/Sub sẽ giảm tốc độ gửi cho tất cả messages của subscription đó — kể cả messages "khỏe mạnh" có thể xử lý được.
Theo docs: "Push backoff can't be turned on or off. You also can't modify the values used to calculate the delay."
Đây là một trong các lý do push subscription ít linh hoạt hơn pull subscription trong scenarios cần fine-grained control.
Retry không có DLQ tự động (nếu không cấu hình Dead Letter Topic)
Mặc định, nếu endpoint liên tục fail, message sẽ bị redeliver mãi cho đến khi retention period hết (default 7 ngày). Message không tự động bị drop hay gửi sang DLT trừ khi bạn cấu hình Dead Letter Topic với max delivery attempts.
Authentication — JWT signing
Cơ chế
Khi cấu hình authentication cho push subscription, Pub/Sub tạo một JWT và include trong Authorization header của mỗi HTTP request:
POST /your-endpoint HTTP/1.1
Authorization: Bearer <signed-JWT>
Content-Type: application/json
...JWT được ký bởi service account của Pub/Sub. Endpoint có thể verify JWT bằng cách:
- Fetch public key từ Google's public key endpoint
- Verify JWT signature
- Verify claims:
iss(issuer),aud(audience phải match endpoint URL),exp(chưa expired)
Service account trong JWT: JWT email claim chứa service account được cấu hình cho push subscription. Endpoint có thể dùng claim này để verify identity và authorize.
Khi không dùng authentication
Nếu endpoint không verify JWT, bất kỳ ai biết URL đều có thể gửi fake messages. Với public endpoints, luôn enable và verify authentication. Với Cloud Run và Cloud Functions, có thể dùng GCP-native authentication thay vì manual JWT verification.
Ordering với push subscriptions
Push subscription có một ràng buộc quan trọng khi dùng ordering keys: chỉ có một outstanding message per ordering key tại bất kỳ thời điểm nào.
Điều này có nghĩa: nếu ordering key "customer-123" đang có một message được gửi tới endpoint nhưng chưa nhận ack, Pub/Sub sẽ không gửi message tiếp theo có cùng ordering key cho đến khi nhận được ack.
Throughput implication: Với nhiều ordering keys, throughput tổng vẫn cao. Nhưng với một ordering key hot (nhiều messages cho cùng key), throughput của key đó bị giới hạn bởi response time của endpoint. Nếu endpoint mất 100ms/request, throughput cho key đó là tối đa 10 msgs/s — dù endpoint nhanh đến đâu với requests của keys khác.
So sánh Push vs Pull
| Đặc điểm | Push | Pull |
|---|---|---|
| Ai initiate kết nối | Pub/Sub | Subscriber |
| Throughput control | Pub/Sub (push window) | Subscriber (flow control) |
| Endpoint requirement | Public HTTPS | Không cần |
| Latency | Thấp (server push) | Thấp (StreamingPull) |
| Exactly-once | Không hỗ trợ | Hỗ trợ |
| Messages per request | 1 | Nhiều (batch) |
| Backpressure mechanism | Push backoff (auto) | maxOutstandingMessages |
| Ordering support | Có (1 outstanding per key) | Có |
| Use case tốt | Serverless, event-driven | High-throughput, stateful processing |
Khi nào chọn push vs pull
Chọn Push khi:
- Endpoint là serverless (Cloud Functions, Cloud Run): không cần long-running process
- Simple event processing: nhận event → xử lý → done
- Scale-to-zero là yêu cầu quan trọng
- Message rate không quá cao (< 10,000 msgs/s)
Chọn Pull khi:
- Cần exactly-once delivery (push không hỗ trợ)
- Cần fine-grained flow control (maxOutstandingMessages)
- High-throughput (> 10,000 msgs/s): Pull batch nhiều messages hiệu quả hơn
- Endpoint không publicly accessible
- Cần batch processing: pull N messages, xử lý batch, ack batch
- Cần concurrent processing: một subscription với nhiều subscriber instances
Anti-pattern phổ biến với push: Dùng push cho high-throughput workload với heavy processing. Một message per request overhead trở nên đáng kể ở scale cao. Push phù hợp với "nhẹ, nhanh, stateless" — nếu processing phức tạp, pull cho phép kiểm soát tốt hơn.