最近 Funliday-旅遊規劃 常發一些精選旅遊回憶的 App 通知給使用者,在去年十一二月的時候發通知 Server 還能撐的了瞬時大流量的 request。
但今年開始發這類通知,總共發了三次,三次都造成 Server 被打掛,而且重開 AP 還緩解不了,瞬間手足無措。大概都要等過了十分鐘左右,Server 才將這些 request 消化完。
這裡就來簡單整理一下時間軸,順便分享一下 Funliday 是如何解決這個問題。
---
* 1/6 1900:系統排程發送精選旅遊回憶的 App 通知
* 1/6 1900+10s 開始:Server 收到極大量的 request
* 1/6 1900+20s:Nginx 出現錯誤訊息 1024 worker not enough,並回傳 http status code 503
* 1/6 1900+25s:PostgreSQL 出現錯誤訊息 could not fork new process for connection (cannot allocate memory)
* 1/6 1900+38s:Node.js 收到 PostgreSQL 的 exception。There was an error establishing an SSL connection error
* 1/6 1900+69s:PostgreSQL 出現錯誤訊息 database system is shut down
* 1/6 1900+546s:PostgreSQL 出現錯誤訊息 the database system is starting up
---
看了時間軸就覺得奇怪,先不論 10s 的時候發了極大量 request,造成 20s 在 Nginx 出現 worker not enough 的錯誤訊息。而是要關注 25s 時的 PostgreSQL 出現 could not fork new process for connection 的錯誤訊息。
Funliday 用了同時可承載 n 個 connection 的資料庫,而且程式碼又有加上 connection pool,理論上根本不該出現這個錯誤訊息。但整個時間軸看下來感覺就是 PostgreSQL 的 capacity 問題,造成系統無法運作。
因為就算將 Nginx 的 worker connection size 再加大 10 倍,只是造成 PostgreSQL 要接受的 request 也跟著被加大 10 倍,但 PostgreSQL 那裡因為 request 變多,原本在 69s 直接關機的時間點只會提早,而無法真正緩解這個狀況。
基於以上狀況,小編就開始回去看自己的程式碼是不是哪裡寫錯了。會這樣想也是覺得 PostgreSQL 應該沒這麼弱,一下就被打掛,一定是自己程式碼的問題 Orz
---
這邊來分享一下自己程式碼的寫法,圖一是原始寫法,在每個 API 都 create 一個 db client instance 來處理該 API 層的所有 db request。這是蠻單純的做法,也是 day 1 開始的處理方式。但有個小問題,就是每個 API 層都要自己 create instance,不好管理,且浪費資源。
後來因為想要做 graceful shutdown 的關係,所以調整了一下 db client instance 的建立方式,用 inject 將 instance 綁在 request 上面,如圖二。這樣只要在 middleware 建立 db client instance 就好,好管理,而且只要有 req 就可以取得 instance,非常方便。而這也是 1/6 時的程式碼,就從這裡開始研究吧。
---
直接切入 node-postgres 的文件,認真讀了一下 pool 有下面兩種使用方式:
1. pool.connect, pool.release:文件寫著 checkout, use, and return,光看描述就應該用這個沒錯。
2. pool.query:適用於不需要 pool 的連線方式,文件上也清楚寫著內部實作是直接 call client.query,所以用了這個方式是完全跟 pool 扯不上邊。
但偏偏小編從 day 1 用的就是第 2 種方式 Orz,雖然看起來應該是寫錯,但也是要修改後實測,才知道是不是真的可以解決問題。
---
如圖三,這是修改後的程式碼。想了一下子,覺得目前在 API 層使用 req.pool.query 還不錯,不想用官方的建議做法:先 create client,然後 query 之後,再使用 release。
如果照官方建議做法,API 層的程式碼會多一堆與商業邏輯無關的程式碼,也不好維護。所以在不想動到 API 層的程式碼,只能使用 monkey patch 的方式來達到這個需求。
monkey patch 可以將原方法利用類似 override 的方式,將整個方法改掉,而不改變 caller 的程式碼,這也是 JavaScript, Ruby, Python 這類動態語言的特性之一,但真的要慎用,一不小心就會把原方法改成完全不同意義的方法了。
所以原本應該要在 API 層實作 connect, query, release 一大堆程式碼,可以用 monkey patch 完美解決這一大堆程式碼。
---
在 dev 壓測後至少 capacity 可以達到原本的 4 倍以上,隔天實際上 production 之後也確實如壓測般的數據,可以承載目前的流量。
其實這篇分享的重點只有一點,文件看仔細才是最重要的事啦!如果沒把文件看仔細,然後開發經驗也不足的話,什麼 RCA、monkey patch 都幫不上忙啦!
---
後記:有夠丟臉,其實完全用不到圖三,只要把圖二的 pool creation 放到最外層就好了,因為 pool.query 的內部實作已經有做 connect, query, release 了。
感謝下面的 Mark T. W. Lin 及 Rui An Huang 的幫忙,實在是太搞笑了 Orz
* Pool 的文件:https://node-postgres.com/features/pooling
* 官方建議寫法:https://node-postgres.com/guides/project-structure
* pool.query 的內部實作:https://github.com/brianc/node-postgres/blob/master/packages/pg-pool/index.js#L332
#expressjs #nodejs #javascript #postgresql
db 1 無法 關機 在 毛毛遊戲城堡 Facebook 的精選貼文
這次開團的是AIRMATE艾美特2019最新機型
-\-\符合新制一級能效的
👉🏻負離子智能清淨除濕機 #同步有乾衣功能
🔺下單網址→ https://reurl.cc/gGqxQ
原價$15800、市場售價$12800
限時 75 折,活動價$9,580
再贈「USB 風扇手持迷你靜音小風扇」(市價$699)
-
選購除濕機要注意哪些細節呢?
莫莉媽來做個重點整理!!
✅圖文分享→ https://reurl.cc/NQdEk
❤️重點1:到底要選擇幾公升的除濕機?
最簡單的算法是一坪約等於一公升
(市售定價1L約=$1000)
大部份的人是一台除濕機用在不同空間
所以建議選大不選小 除濕效率才會好
艾美特這台是16L超大坪數適用
能有效率的針對15坪空間除濕
而且人家都說越大坪數越耗電
但這台超難得!!
符合經濟部的新制一級效能
每年耗電量僅135度 電費約$486
每天電費不到 1.5 元 超級省電啊!!!
❤️重點2:能自動偵測濕度才好用
許多簡易機型僅有自動除濕功能
無法設定濕度 自動除濕通常會預設60%
但有時候天氣潮溼,60%不見得舒服
這時候就需要有「連續除濕」模式
或者能指定濕度的機種
艾美特這台濕度設定可自由選擇 40/50/60/70%
也可設定連續除濕 自動偵測濕度哦!
❤️重點3:有沒有乾衣功能的除濕機差在哪?
天氣濕答答 衣服總是乾不了
每年到了梅雨季 就是主婦超頭痛的時候
晾太久沒乾 衣服產生異味 真的好阿雜!
具備乾衣模式的機型 出風口會朝上
可以直接對著衣物吹
達到最佳的除濕效果
艾美特這台具有強檔乾衣功能
風口不只朝上 還可以搭配擺葉吹風
讓空氣對流 衣物快快乾 而且無異味
❤️重點4:除了除濕力,還需要注意哪些選購細節?
→ 機身與水箱要易於移動
這是選購時常常被忽略的重點
常常買回去才意識到機器很難移動
(除濕機+儲水重) 之後就懶得移位了
也有人礙於好移動選擇小容量的機種
事後發現除濕力根本不足
艾美特這台 即使是大容量
而且是除濕力極高的機種
但是它貼心的在底座加裝萬向移動輪
機身也有把手,可以輕鬆在家中移動哦!
-
除了這些達人特別提出來的選購重點
艾美特還有這多貼心之處
比如水箱有4L 大容量
可以長時間除濕 不用頻繁倒水
有 1、2、4、8 小時定時關機功能
在機體內部費盡心思
滴水管處增加小滑梯
達到無聲滴水效果👍🏻
使用環保冷媒,有效減少振動噪音
擁有15重安全裝置
具有自動除霜保護、滿水自動停止運轉、壓縮機保護功能與高低溫保護等 15 重安全裝置,不擔心因為無停歇的過度運轉而造成危險
它是屬於壓縮機式的除濕機
所以售價基本上不會太低
壓縮機式的除濕機有2個很大的好處
就是 較省電、且較不發熱
如果買到壓縮機品質不好的機種音量就會很大
但這台是迴轉式安靜除溼
同時搭配R-134a環保冷媒有效減少震動噪音
除濕時的分貝量低於46 Db
-
✅產品細節
尺寸:W34.6xD24.2xH59cm(電源線長度 2m)
重量:14.7kg
電壓:110V/60Hz
功率:250W
除濕量:16.0 L/d(標準試驗環境 27°C 60% RH)
能源因數:2.66(1 級能效)
水箱容量:4L
材質:ABS 塑料
產地:台灣品牌,台灣製造
-
艾美特負離子除濕機台灣原廠公司貨
享全機 1 年保固,壓縮機 3 年保固,到府收送維修 1 年
3/22~3/28艾美特負離子智能清淨除濕機
原價$12,800,限時 75 折,活動價$9,580
再贈「USB 風扇手持迷你靜音小風扇」(市價$699)
🔺下單網址→ https://reurl.cc/gGqxQ
✅圖文分享→ https://reurl.cc/NQdEk