Yêu cầu trang quản trị chạy dài Chặn các yêu cầu khác


17

Nếu tôi đăng nhập vào phần phụ trợ của Magento và thực hiện một số tác vụ mất nhiều thời gian (tìm kiếm toàn cầu trên các danh mục lớn, dataflow chạy dài, v.v.), trình duyệt web của tôi sẽ từ chối chỉ tải các trang quản trị khác trong trình duyệt đó . Tại sao điều này xảy ra, và có bất kỳ khoa học được biết đến cho cách giải quyết?

Đó là, nếu tôi

  1. Đăng nhập vào trang bảng điều khiển của Magento

  2. Mở tab thứ hai với bất kỳ trang quản trị Magento nào

  3. Thực hiện tìm kiếm toàn cầu chạy dài (mô phỏng với một cuộc gọi đến sleep(30)khi bắt đầu globalSearchAction) trong tab đầu tiên

  4. Cố gắng tải lại tab thứ hai

Hành vi dự kiến: Tab thứ hai tải với nội dung trang ngay lập tức

Hành vi thực tế: Tab thứ hai chỉ tải khi tìm kiếm toàn cầu chạy dài hoàn thành

Có ai biết, cụ thể, tại sao điều này xảy ra? (Tôi đoán là bảng điều khiển quản trị Magento yêu cầu khóa một số tài nguyên mà Magento cần để bootstrap, nhưng tôi không biết đó là gì)

Có ai biết về một sửa chữa / giải pháp?


1
Bạn, thưa ngài, vừa gửi cho tôi một thách thức! :)
davidalger

Câu trả lời:


21

Vấn đề được gây ra bởi một khóa được đặt bởi trình xử lý phiên PHP. Vì vậy, Magento không rõ ràng khóa một cái gì đó và cố gắng chặn các yêu cầu của quản trị viên, mà gần như là một tác dụng phụ cho mỗi lần lưu trữ phiên dựa trên tệp.

Một khóa ghi đang được đặt trên tệp dữ liệu phiên khi nó được mở bởi yêu cầu ban đầu (chạy dài), khiến yêu cầu thứ hai bị chặn cho đến khi khóa được giải phóng khi nó gọi session_startvàoMage_Core_Model_Session_Abstract_Varien::start

Đây là 100% tái sản xuất. Tôi đã sử dụng cùng một phương pháp bạn đã làm, thêm một sleep(30)vào đầuMage_Adminhtml_IndexController::globalSearchAction

Đáng lưu ý là điều này không thể được sao chép nếu bạn đang sử dụng bộ lưu trữ phiên db. Sau khi tôi tìm thấy nguyên nhân gốc, tôi đặt hộp cát thành bộ lưu trữ phiên db và không thể tái tạo vấn đề nữa. Vì vậy, trình xử lý phiên db Magento dường như không sử dụng khóa cấp hàng để khóa ghi phiên. Tôi thấy điều này thú vị, bởi vì nó có khả năng mất dữ liệu phiên vì ứng dụng rõ ràng không chiếm nhiều luồng cho cùng một phiên. Lưu ý cho người đọc: Tôi sẽ không bao giờ sử dụng lưu trữ phiên db trong sản xuất để thử và giải quyết vấn đề này, nó chỉ tốt cho việc quá tải cơ sở dữ liệu MySql của bạn.

Tôi đã không thử tái tạo hành vi bằng các hệ thống lưu trữ phiên dựa trên bộ nhớ như Redis, nhưng tôi đoán là việc khóa các bản ghi trong kho lưu trữ phiên cũng có thể bị bỏ qua.

Có những kỹ thuật có thể được sử dụng để tránh điều này như sử dụng session_write_closeđể giải phóng khóa trước khi bạn bắt đầu một công việc dài hạn. Nhưng điều này cũng sẽ ngăn bạn viết vào phiên vì bạn vừa đóng nó. Vì vậy, nó không có khả năng được triển khai dễ dàng trên bảng trong Magento, nhưng có khả năng có thể được triển khai trên các tuyến / bộ điều khiển cụ thể.

Kỹ thuật của tôi để xác định điều này là nguyên nhân gốc là để kích hoạt trình tạo hồ sơ Xdebug và kiểm tra tệp "cacheegrind". Khi yêu cầu thứ hai hoàn thành, tôi đã tải tệp đầu ra (~ 25 MB log) vào MacCallGrind và đi sâu vào dấu vết theo đường dẫn của các cuộc gọi trong đó thời gian bao gồm là 28 giây hoặc lớn hơn. Điều này cuối cùng đã dẫn tôi đến session_startcuộc gọi mất ~ 28 giây để chạy, cho tôi một điểm tuyệt vời để nghiên cứu.

EDIT: Đối với những người quan tâm, tôi đã đăng một ảnh chụp màn hình của tệp "cacheegrind" được xem trong MacCallGrind trên Twitter.


Mô-đun uRapidFlow của Unirgy đóng phiên để tránh sự cố này, đây là một cách hay, nhưng điều đó gây khó chịu vì nó gây khó khăn cho việc cung cấp phản hồi cho người dùng sau đó.
Peter O'Callaghan

@davidalger - Bạn thường triển khai bộ lưu trữ phiên nào cho các trang web của khách hàng?
Alan Storm

3
Re: khóa tệp phiên PHP, điều này ít hơn đối với tính toàn vẹn dữ liệu so với tính toàn vẹn của chính tệp trên đĩa. Có nhiều quá trình mở và ghi vào bit trên đĩa (đó là những gì một tệp) sẽ nhanh chóng dẫn đến hỏng dữ liệu. MySQL, redis và hầu hết các cơ sở dữ liệu được thiết kế đặc biệt để duy trì sự nhất quán, ngay cả khi có nhiều lần ghi gần như cùng một lúc. tức là không phải khóa đã bị bỏ qua, nó không cần thiết lắm.
Alan Storm

@AlanStorm - Một phiên bản Memcached dành riêng cho cài đặt cân bằng tải, hệ thống tệp cho các cụm nút ứng dụng đơn. Hệ thống tệp hoạt động tốt nhất khi bạn không có nhiều nút vì bạn không có độ trễ IP.
davidalger

Chính xác, khóa các tập tin là tất cả về ngăn chặn tham nhũng dữ liệu. Tuy nhiên, giữ khóa cho đến khi phiên đóng cửa là về việc ngăn ngừa mất dữ liệu. Nếu hai quá trình tải dữ liệu phiên, sửa đổi nó và sau đó viết nó ra, một trong số chúng sẽ có các sửa đổi được ghi đè. Nói chung sẽ không gây ra vấn đề nghiêm trọng, nhưng có thể gây mất dữ liệu và / hoặc khó khăn để gỡ lỗi.
davidalger
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.