被交叉的日誌很有規律,都是單條日誌過長被截斷的,建議優化下 /*/ruleanalysis.php:68 此處寫入日誌的字串長度為:int(25909)
指令碼服務寫入日誌**如下:
if ($this->iscli == true)
檢視file_put_contents 的原始碼實現,最終寫檔案會執行到_php_stream_write_buffer 函式,裡面有這樣一處**:
明確幾個變數的含義:
count:需寫入檔案的字串長度
stream->chunk_size:預設為8192 (8k)
從上面**可以看出,當寫入的字串長度 大於8192時,則拆為多次<=8192的字串,然後呼叫php_stdiop_write函式寫入檔案,php_stdiop_write函式實現如下:
static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count)
bytes_written = _write(data->fd, buf, (unsigned int)count);
#else
int bytes_written = write(data->fd, buf, count);
#endif
if (bytes_written < 0) return 0;
return (size_t) bytes_written;
} else
data->last_op = 'w';
#endif
return fwrite(buf, 1, count, data->file);}}
php_stdiop_write 則呼叫的 write函式 寫入檔案;write函式是能保證一次寫入的完整的。
所以日誌寫串的原因也就能分析出來了,呼叫鏈結為:file_put_contents ->_php_stream_write_buffer ->php_stdiop_write(多次呼叫,每次最多寫入8192位元組) ->write(),是在 多次呼叫php_stdiop_write 函式時出的問題;第一次寫完,緊接著在高併發的情況下,被其他程序的 write 函式追著寫,此時就出現寫串,也就是前面示例中日誌;
為了證實此觀點,我對報錯的** /**/ruleanalysis.php:68 寫了如下偽**:
public function run()
vim ~/*****/logger.php
if ($this->iscli == true)
執行**看打串日誌的地方是否為8192倍數的位置,結果如下:
截斷的位置非常接近8192的倍數值;但因為定位時間不是當時的時間點,期間資料庫存在部分改動,所以出現偏移,那麼也能驗證我們之前的猜想,正是file_put_contents 多次呼叫write函式的時候出現交叉列印。
1、修改打日誌處**,這麼巨大的日誌寫入檔案是否合理?
2、需要寫入巨大日誌又不希望不被交叉列印,加上lock_ex 標識;
呼叫 open函式 ,fd = open(realpath, open_flags, 0666);
通過 c底層函式保證,寫入預設追加寫;
file_put_contents在呼叫_php_stream_write_buffer 前加乙個鎖 php_stream_supports_lock(stream) ->flock()
得到檔案鎖定後 呼叫_php_stream_write_buffer->多次 write();
寫完後釋放檔案鎖
php_stream_close(stream)->close(data->fd); //直接關閉
總結:lock_ex 保證了乙個巨大字串的完整,不會被寫串;
還是寫在檔案尾部,參考文章:
write函式**如下:
+static inline loff_t file_pos_read_lock(struct file *file)
+static inline void file_pos_write_unlock(struct file *file, loff_t pos)
修改sys_write系統呼叫:
file = fget_light(fd, &fput_needed);
if (file)
每次都會執行 open和clo 微服務中定位線上問題
微服務架構下的程式一般有多個節點提供服務,使用者請求不一定落在哪乙個節點,如果節點 存在問題,一般利用日誌監控系統來確認問題。日誌監控系統提供實時日誌,以及全文檢索日誌,並且日誌實時查詢以及全文檢索查詢都要 以倒敘查詢。中介軟體系統或業務系統對於日誌生成的級別,debug info error等級別...
使用Spring AOP快速定位線上專案效能問題
前提 這篇文章以spring aop為例,介紹如何快速定位執行效率較低的方法,從而解決服務執行較慢的問題。如果不是很了解spring aop的小夥伴,可以先看一下我的這篇文章 spring學習之aop,然後再回來繼續看這篇文章。背景最近線上專案總是收到客戶發來的郵件,吐槽有一些動作要等好幾十秒才能有...
線上服務記憶體OOM問題定位
某乙個物件被頻繁申請,卻沒有釋放,記憶體不斷洩漏,導致記憶體耗盡 某乙個資源被頻繁申請,系統資源耗盡,例如 不斷建立執行緒,不斷發起網路連線 jmap heap 10765 jmap histo live 10765 more 所佔記憶體大小 類名消費者消費速度慢 或停止消費了 而生產者不斷往佇列中...