最近我遇到了一個系統問題,我們一些以 Ruby Rake 任務形式編寫的批次作業最終出現重複調用,這導致資料庫中出現重複記錄或在 Slack 中出現重複警報。這絕對是基礎設施問題,但在從基礎設施修復它之前,我需要從編碼角度找到解決它的方法。嘗試將所有內容重寫為盡可能冪等的並不太現實,增強應用程式級驗證或資料庫唯一性約束也不是一個選擇,因為並非所有作業都可以是冪等的,也並非所有作業都會寫入資料庫,此外問題是由競爭條件引起的,不是來自兩個線程,而是來自兩個進程。經過一些研究和實驗,我決定使用「Redis」作為一個簡單的分散鎖解決方案,它已經在我們的應用程式中可用,不需要任何額外的設置,而且它是一個單一實例,因此不需要考慮複製同步問題。 「Redis」 是單執行緒架構,無論有多少並發客戶端嘗試寫入它,它都能保證結果是順序的和原子的。我發現可以利用這種性質來解決所面臨的問題。
tmux 是一個終端多工器。當我們需要在後台在遠端伺服器上運行長時間運行的任務並稍後檢查結果時,它非常有用,而不需要保持持續的 ssh 連線並擔心網路故障導致任務意外退出。以下是滿足大多數用例的最少指令清單。
從 JDK 11 開始,Java 支援直接執行原始文件,而無需先編譯為類別文件,這使得用 Java 編寫腳本成為可能,就像通常使用 python、ruby 或 nodejs 等動態程式語言一樣。這篇文章既可以作為範例,又可以作為如何實現它的快速參考。
在許多情況下,例如處理 JSON 格式的 API 回應、處理網站上嵌入的 JavaScript 資源等時,我們會頻繁看到 13 位長數字,並且我們可能知道它是源自new Date().getTime()
等程式碼的紀元時間戳,但是,作為人類,我們無法快速分辨出它代表的日期和時間。有一個名為 Epoch Converter 的便捷網站,可以輕鬆地將其轉換為人類可讀的格式,但對於開發人員來說,大多數時候還有比打開網站更快捷的方法,即使用許多程式語言自帶的「互動式 shell」。
Ruby 3.0 帶來了一些重大變化,這會為使用大量 gem 的典型 rails 應用程式帶來很多麻煩,尤其是關鍵字參數行為的重大變化和 URI.escape
方法的刪除。
傳統上,有幾種方法可以靜態添加css到頁面,也可以透過JavaScript動態添加,方法是創建一個帶有rel="stylesheet"
和href
的link
元素設定為css檔案位置,或者創建一個以css定義作為其內容的style
元素。現在有第三種方法:透過稱為「CSS 模組腳本」的功能,直接從 ESM 腳本標籤內匯入 css,類似於匯入 JavaScript 資源的方式。
在處理大型文字檔案(例如解析日誌檔案)時,出於效率和效能原因,推薦逐行載入/迭代內容,而不是將所有內容讀入記憶體。在 Nodejs 中,這一直很麻煩,因為從日常用戶的角度來看,逐行閱讀的方式看起來很繁瑣且太底層。不過,得益於最近合併到版本 v18.11.0
的PR,情況不再如此,現在有了內建的 FileHandle.prototype.readLines
,使用起來非常方便。
在其他程式語言中,例如 Java、Ruby 和 Python,有 Thread.sleep()
、sleep
和 time.sleep()
方法來暫停當前執行緒的執行並等待指定時間後繼續執行,當與循環一起使用時,它可以幫助解決競爭條件問題。在 node.js 和一般的 JavaScript 中,由於單執行緒、事件驅動和非同步架構的性質,暫停和等待的方式可能看起來不是很明顯,也不常見。不過由於在特定情況下,使用 wait
和 retry
仍然是需要的且有幫助的,所以可以在 nodejs 或 JavaScript 中模擬類似的功能和效果。
如果 ssh 伺服器和用戶端之間沒有在一段時間內發送訊息,那麼 ssh 連線很快就會終止,這有時會很煩人,但有一些方法可以讓它在客戶端或伺服器端長時間或永遠保持活動狀態。
在 Nodejs 中,當處理非文字檔案(例如圖像)的 IO 操作(例如透過網路傳輸或從磁碟讀取)時,有很大的機會以 stream.Readable
的形式接收內容,並且在我們能夠處理內存中的完整資料(例如計算位元組大小或圖像尺寸)之前,我們需要將 stream
保存到 `buffer 中,這裡有幾種方法。