最近碰到了個很有意思的問題,springboot加載多數據源,遇到了在啟動時數據庫連接報錯的問題。
報錯信息:
The error occurred while executing a query
然后找到了一篇文章,linux熵池耗盡
在jvm啟動參數里加上
-Djava.security.egd=file:/dev/./urandom
就ok了。
可是這是為什么呢?
因為相同環境的多台機器,有些機器有問題,有些機器沒問題,排查這個問題耗費了很長時間。
是虛擬機導致的嗎?
可以看到,上面那篇博文里是怎么說的:
在無頭服務器中,用於(java)應用程序連接的11g JDBC驅動程序可能會造成麻煩。
原因是JDBC 11g需要大約40個字節的安全隨機數,從/ dev / random收集,以加密其連接字符串。
為什么這個神秘的“熵池”耗盡了隨機數?
我們先去看看。
首先是正常的服務器,執行如下命令:
cat /proc/sys/kernel/random/entropy_avail
cat /proc/sys/kernel/random/poolsize
接着是報錯的那台機器:
為什么entropy_avail就只有189呢?是這個原因嗎?
為什么只有189就不能用了呢?
再來看看這篇文章
https://jarfield.iteye.com/blog/1739834
再回來看看oracleJDBC,原來默認情況下,Oracle JDBC 11g似乎會使用/ dev / random。而使用/dev/random生成隨機數時,依賴熵池。如果熵池空了或不夠用,對/dev/random的讀取就會堵塞,直到熵池夠用為止。
但是上面這篇文章中說,有得必有失,urandom的隨機性弱於random。
這點我也找到了一篇文章,來反駁這種說法,大家可自行圍觀。
那怎么讓熵池增加呢?熵池小會有什么其他后果嗎?
jarfield老兄上面那篇文章中說到
熵池本質上是若干字節。/proc/sys/kernel/random/entropy_avail中存儲了熵池現在的大小,/proc/sys/kernel/random/poolsize是熵池的最大容量,單位都是bit。如果entropy_avail的值小於要產生的隨機數bit數,那么/dev/random就會堵塞。
熵斥怎么增加?
只有少數驅動程序會填充熵池,首先是鍵盤和鼠標。
實際上是從各種noice source中獲取數據,noice source可能是 鍵盤事件、鼠標事件、設備時鍾中等。
linux內核從2.4升級到2.6時,處於安全性的考慮,廢棄了一些source。source減少了,熵池補給的速度當然也變慢,進而不夠用。
熵斥堵塞會有什么后果?
其實,通過消耗熵池,可以構造DOS攻擊。原理很簡單,熵池空了,依賴隨機數的業務(SSL,加密等)就不能正常進行。
怎么補充熵池?
Linux服務器在運行時,既沒有鍵盤事件,也沒有鼠標事件,如何快速積累熵池呢?
在上面那篇文章中有說到:
例如rngd或rng-tools。
先觀察rngd啟動前的熵池大小:
watch cat /proc/sys/kernel/random/entropy_avail
只有100多。
安裝rng-tools,參考文章 https://blog.csdn.net/tiantao2012/article/details/78792046。
yum install rng-tools -y
啟動rngd服務
service rngd start
再看下熵池
飆升到3000多。
哈哈,搞定收工。
最后,是我的星球,哈哈。