Tôi đang lưu trữ các trang được tạo động (PHP-FPM, NGINX) và có véc ni trước chúng, điều này hoạt động rất tốt.
Tuy nhiên, khi hết thời gian chờ bộ đệm, tôi thấy điều này:
- trang yêu cầu khách hàng mới
- véc ni nhận ra thời gian chờ bộ nhớ cache
- khách hàng chờ đợi
- véc ni lấy trang mới từ phụ trợ
- véc ni cung cấp trang mới cho khách hàng (và cũng được lưu trong bộ nhớ cache cho yêu cầu tiếp theo nhận được ngay lập tức)
Những gì tôi muốn làm là:
- trang yêu cầu khách hàng
- véc ni nhận ra thời gian chờ
- véc ni cung cấp trang cũ cho khách hàng
- véc ni lấy trang mới từ phụ trợ và đặt nó vào bộ đệm
Trong trường hợp của tôi, đó không phải là trang web mà thông tin lỗi thời là một vấn đề lớn như vậy, đặc biệt là khi chúng ta đang nói về thời gian chờ bộ nhớ cache từ vài phút.
Tuy nhiên, tôi không muốn trừng phạt người dùng xếp hàng chờ đợi và thay vào đó cung cấp một cái gì đó ngay lập tức. Điều đó có thể theo một cách nào đó?
Để minh họa, đây là một đầu ra mẫu của cuộc bao vây chạy 5 phút đối với máy chủ của tôi được cấu hình để lưu trữ trong một phút:
HTTP/1.1,200, 1.97, 12710,/,1,2013-06-24 00:21:06
...
HTTP/1.1,200, 1.88, 12710,/,1,2013-06-24 00:21:20
...
HTTP/1.1,200, 1.93, 12710,/,1,2013-06-24 00:22:08
...
HTTP/1.1,200, 1.89, 12710,/,1,2013-06-24 00:22:22
...
HTTP/1.1,200, 1.94, 12710,/,1,2013-06-24 00:23:10
...
HTTP/1.1,200, 1.91, 12709,/,1,2013-06-24 00:23:23
...
HTTP/1.1,200, 1.93, 12710,/,1,2013-06-24 00:24:12
...
Tôi đã bỏ qua hàng trăm yêu cầu đang chạy 0.02
. Nhưng điều đó vẫn khiến tôi lo ngại rằng sẽ có người dùng phải chờ gần 2 giây cho HTML thô của họ.
Chúng ta không thể làm tốt hơn ở đây?
(Tôi đã bắt gặp Varnish gửi trong khi bộ đệm , nghe có vẻ tương tự nhưng không chính xác những gì tôi đang cố gắng làm.)
Giải pháp
Câu trả lời từ Shane Madden có chứa giải pháp nhưng tôi đã không nhận ra ngay lập tức. Có một chi tiết khác tôi không bao gồm trong câu hỏi của mình vì tôi nghĩ nó không liên quan, nhưng thực ra nó là như vậy.
Giải pháp CMS tôi hiện đang sử dụng có trình nghe cơ sở dữ liệu véc ni và do đó có khả năng thông báo véc ni để cấm các trang có nội dung đã thay đổi. Nó đã gửi một PURGE
yêu cầu với một số regex để cấm một số trang.
Tóm lại, có hai trường hợp tôi gặp phải những người dùng không may mắn:
- véc ni bình thường của một trang hết hạn
- người dùng phụ trợ thay đổi nội dung, điều này sẽ gửi một yêu cầu thanh lọc đến véc ni
Trong cả hai trường hợp tôi đều có người dùng "không may mắn". Trong trường hợp thứ hai, nó được giảm bớt bởi thực tế là người dùng phụ trợ thường kiểm tra trang sau khi nó đã được thay đổi; nhưng không nhất thiết
Tuy nhiên, đối với trường hợp thứ hai tôi đã tạo ra một giải pháp (vâng, tôi nhận ra câu hỏi này bắt đầu bằng việc tìm kiếm một câu trả lời cho trường hợp đầu tiên ... câu hỏi được xây dựng kém về phía tôi):
Thay vì gửi yêu cầu thanh lọc, tôi đã sử dụng đề xuất Shanes và điều chỉnh VCL để người nghe cơ sở dữ liệu véc ni của tôi có thể gửi yêu cầu đặc biệt để tìm nạp một trang hash_always_miss
được đặt thành true
.
Với kiến trúc hiện tại, tôi không thực sự có hứng thú khi thực hiện một yêu cầu không đồng bộ thực sự, nhưng với sự trợ giúp của Làm thế nào để tôi thực hiện một yêu cầu GET không đồng bộ trong PHP? Tôi đã có thể tạo một yêu cầu GET để đánh vecni không chờ trang được tải nhưng đủ tốt để kích hoạt véc ni để lấy trang từ phụ trợ và lưu vào bộ đệm.
Hiệu quả thực tế là người nghe cơ sở dữ liệu đã gửi yêu cầu vecni và trong khi tôi đang thăm dò trang cụ thể thì nó không bao giờ làm cho yêu cầu của tôi "không may mắn" nhưng một khi vecni đã tải trang hoàn toàn từ phần phụ trợ (điều này có thể dao động từ 300ms đến 2 giây) Đột nhiên ở đó.
Tôi vẫn chưa tìm ra giải pháp làm thế nào để tránh những vấn đề tương tự khi hết bình thường, nhưng tôi đoán giải pháp này cũng chính xác như Shane gợi ý: sử dụng wget để kích hoạt hash_always_miss
, tôi sẽ phải đủ thông minh để có được danh sách trang tôi phải làm mới.