2011-10-19 3 views
36

Từ hướng dẫn sử dụng PHP, trạng thái session.gc_probability và session.gc_divisor rằng gc sẽ xảy ra dựa trên xác suất này. Tôi hiểu rồi.Thu hồi bộ sưu tập rác PHP

Điều tôi không rõ ràng là liệu xác suất này có trên phiên theo phiên hoặc tổng thể hay không. Vì vậy, nếu xác suất của tôi là 1% (1/100) GC sẽ xảy ra, điều đó có nghĩa là nếu một phiên tiếp tục được gia hạn, mỗi lần có thay đổi 1% mà phiên cụ thể đó sẽ được dọn sạch? Hoặc điều này có nghĩa là 1% của tất cả các phiên hiện có (cũng như các phiên mới) sẽ kích hoạt GC cho tất cả các phiên hiện có khác?

Tôi chắc chắn đó là thứ hai, tôi chỉ muốn đảm bảo.

Mục đích của câu hỏi này là trên trang web của chúng tôi, tôi muốn người dùng có các phiên dài hạn (6 tháng). Nếu 1% tất cả các phiên kích hoạt GC, thì điều đó có hiệu quả loại bỏ mục đích có phiên dài hạn đó, vì GC sẽ kết thúc sau mỗi hoặc hai giờ.

+2

câu hỏi rất thú vị! +1 –

+0

liên quan http://stackoverflow.com/questions/3865303/debian-based-systems-session-killed-at-30-minutes-in-special-cron-how-to-overri –

+0

Đối với bất kỳ ai khác đang đọc nỗ lực này ở trên, với 6 tháng của tập tin phiên nó có thể gây ra vấn đề hiệu suất nghiêm trọng (như đã nêu dưới đây). Tuy nhiên, bạn có thể sử dụng session_set_save_handler() để viết một trình xử lý phiên tùy chỉnh sẽ sử dụng DB thay vì FS, phủ nhận nhiều hình phạt hiệu suất. – Meep3D

Trả lời

10

Mỗi lần một tập lệnh PHP được thực thi và bắt đầu phiên có khả năng là nó sẽ quét qua thư mục phiên giết chết phiên cũ.

Dọn dẹp sẽ chỉ xóa các phiên không được truy cập trong một thời gian nhất định. Tuy nhiên PHP không đảm bảo rằng phiên sẽ bị hủy trong thời gian đó.

chiến lược phiên lâu dài của bạn nên chỉ làm việc tốt, nhưng bạn có thể muốn giảm 1% xuống còn một cái gì đó giống như 0,1%

Một điều để tìm cho ra là hệ điều hành có thể dọn dẹp thư mục/tmp bạn trong thời gian khởi động lại ngay cả khi PHP không làm điều đó.

+0

Tôi đã giảm xác suất từ ​​1/100 xuống 1/1000000 (0,000001%). Tôi hy vọng rằng sửa chữa vấn đề. Ngoài ra, đây là một trang Magento, vì vậy các phiên được lưu trữ trong/var/session. Thư mục này, theo như tôi biết, không được máy chủ chạm vào (nhưng tôi đoán nó sẽ bị xóa nếu "bộ nhớ cache Flush" được chọn từ quản trị viên Magento). – pspahn

+0

Ồ, cho phép hy vọng Magento không thực hiện các phiên thay thế mà sẽ bỏ qua cài đặt gc_ *. – romaninsh

+5

và tác dụng phụ của việc giảm xác suất là bạn sẽ lấp đầy ổ cứng của mình với các phiên cũ. và các phiên sẽ mất nhiều thời gian hơn và lâu hơn để tìm và tải, và vào cuối ngày vẫn có một cơ hội tối thiểu bạn sẽ xóa các phiên anyway (mặc dù nó là từ xa nhỏ). Bạn có thể xem xét các tùy chọn thay thế như viết trình xử lý phiên của riêng bạn và kiểm soát chính xác phiên nào bạn muốn xóa và khi nào. điều đó không khó đến vậy đâu. http://www.php.net/manual/en/function.session-set-save-handler.php – bumperbox

2

Tôi không phải là chuyên gia về điều này, nhưng từ việc đọc hướng dẫn, tôi sẽ thu hút sự chú ý của bạn đến một cài đặt khác, session.gc_maxlifetime. Từ các tài liệu:

session.gc_maxlifetime định số giây sau đó dữ liệu sẽ được xem như 'rác' và có khả năng dọn dẹp. Thu gom rác có thể xảy ra trong khi bắt đầu phiên (tùy thuộc vào session.gc_probabilitysession.gc_divisor).

Vì vậy, nếu bạn thiết lập cài đặt này để một giá trị thích hợp (60 * 60 * 24 * 365/2 cho nửa năm, vì vậy 15768000), sau đó các dữ liệu thích hợp sẽ không đủ điều kiện cho thu gom rác thải, không có vấn đề gì các thiết lập khác.

+1

Tôi đã đặt gc_maxlifetime thành 15552000 (180 ngày) - Mọi thứ dường như hoạt động bình thường trên trang web dev, nhưng một khi tôi đã phát trực tiếp, nó đã hoạt động được một thời gian trước khi bắt đầu đưa người dùng trở lại trang đăng nhập. – pspahn

+7

giá trị này có nghĩa là "giây sau khi tạo phiên" hay "giây sau lần sửa đổi lần cuối" không? –

+0

Nó sẽ cần phải là sự kết hợp của việc bỏ bộ thu gom rác để dữ liệu phiên của bạn sẽ có trong từ điển mà còn mở rộng tuổi thọ cookie của bạn để nó lưu id phiên duy nhất cho hàng dữ liệu phiên đó nếu tôi hiểu chính xác. – vikingben

7

lần cuối cùng tôi xem nguồn mỗi cuộc gọi đến session_start() "đã cuộn xúc xắc" để nói, sử dụng ước số và xác suất. Nếu bạn nhấn, nó sẽ xóa tất cả các tệp khỏi thư mục session.save_path cũ hơn session.gc_maxlifetime. Tôi quên nếu nó sử dụng sửa đổi hoặc truy cập thời gian của tập tin, mặc dù nó không quan trọng trong curcumstances bình thường vì php ghi đè lên tập tin phiên theo mặc định ở phần cuối của thực thi kịch bản, do đó, mod và thời gian truy cập nên hầu như luôn luôn phù hợp rất chặt chẽ.

// Rough psuedo code of how php's session_start() function works regarding garbage collection. 
function session_start() { 
    $percentChanceToGC = 100 * ini_get('session.gc_probability')/ini_get('session.session.gc_divisor'); 
    $shouldDoGarbageCollection = rand(1, 100) < $percentChanceToGC; 
    if ($shouldDoGarbageCollection) { 
     $expiredCutoffTime = time() - ini_get('session.gc_maxlifetime'); 
     foreach (scandir(ini_get('session.save_path')) as $sessionFile) { 
      if (filemtime($sessionFile) < $expiredCutoffTime) { 
       unlink($sessionFile); 
      } 
     } 
    } 

    // ... rest of code .... 
} 

Tôi không biết có bao nhiêu tệp phiên bạn sắp kết thúc có treo xung quanh nếu bạn muốn chúng sống ít nhất 6 tháng. Xem xét nó có thể mất một chút thời gian cho php để stat nhiều ngàn tập tin để xác định tuổi của họ. Có thể xem xét các tùy chọn khác để lưu trữ lâu bền dữ liệu này. Hoặc bạn có thể tắt php gc và chỉ cần chạy một công việc cron để xóa các tập tin phiên cũ.Nếu không, 1% yêu cầu sẽ kích hoạt gc và phải đợi php; nói cách khác nó có thể có thể tụt lại.