
我正在編寫一個目前在 2.2.22 上運行的 Apache 模組。該模組運行用新的程式語言編寫的腳本,並且為了最佳化,它會快取解析結果以供後續使用。
由於修改文件時應刪除快取的解析,因此我儲存修改時間並在每次運行時根據檔案系統進行檢查。
這是一些帶有調試訊息的程式碼:
if (file->is_modified (mtime)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"P* removing cached file");
files.erase(it);
}
我在測試時發現(獲取頁面,修改文件,再次獲取),這個區塊永遠不會到達。文件更改後會再次解析,但不是因為此檢查。在我看來,Apache 本身正在檢查修改時間並釋放模組中的所有記憶體。
當未修改時,已解析的檔案將被正確地重新使用。
這是 Apache 伺服器的預期行為嗎?
檢查快取程式的函數的完整程式碼
shared_ptr<pstar_file> pstar_pool::get_file_handle (
request_rec *r,
wpl_io &io,
const char *filename,
int mtime
)
{
pstar_map_t::iterator it;
apr_proc_mutex_lock (mutex);
// Check if a cached program exists
it = files.find(filename);
if (it != files.end()) {
if (it->second->is_modified (mtime)) {
files.erase(it);
}
else {
apr_proc_mutex_unlock (mutex);
return it->second;
}
}
apr_proc_mutex_unlock (mutex);
shared_ptr<pstar_file> file_ptr(new pstar_file(io, filename, mtime));
apr_proc_mutex_lock (mutex);
files.insert(std::pair<string,shared_ptr<pstar_file>>(filename, file_ptr));
apr_proc_mutex_unlock (mutex);
return file_ptr;
}
Github 上整個模組的完整程式碼(多個檔案):https://github.com/atlesn/P-star/blob/master/src/apache2/pstar_pool.cpp
答案1
這裡缺少相當多的上下文。然而,我認為答案可能很簡單。
實例化工作進程時會載入模組。載入模組時,通常會將其複製到記憶體中的進程映像中,磁碟上的變更不會影響它。這是否相關取決於您在自訂模組中所做的事情。
當然,當使用和更改模組存取的檔案時,apache 不會表現出奇怪或未定義的行為。如果您的模組打開一個文件,稍後對該文件進行修改以執行您所說的操作會很奇怪,儘管我感覺可能有一個不清楚的原因。
還要檢查底層檔案系統是否確實按照您期望的方式儲存和更新 mtime。並不總是如此。您的即時檢查(您沒有包括在內)也可能是錯誤的。
既然您說檔案正在透過某種未知方式重新加載,那麼很可能會為每個請求實例化一個新的工作進程,或者每次嘗試時都會得到不同的工作進程。
考慮在即時檢查中進行調試列印,以幫助隔離此問題。