樓主今天興高采烈的在部署環境,下載 JDK,打包項目,上傳至服務器。java
配置 JDK ,打包上傳項目樓主就不在這裏重複了,讀者自行解決哈!程序員
1. 啓動項目數據庫
java -jar xxxx.jar vim
令樓主沒有想到的是:程序卡主了,卡在了數據庫創建鏈接的位置。(查看方法方式: jstack <pid> 便可)bash
2. 堆棧信息服務器
因爲是項目剛一啓動,初始化數據庫鏈接池,並無太多的線程堆棧。這裏我貼一下我遇到的主要問題的堆棧信息:oracle
"restartedMain" #11 prio=5 os_prio=0 tid=0x00007f4430002800 nid=0x65b0 runnable [0x00007f447837a000] java.lang.Thread.State: RUNNABLE at java.io.FileInputStream.readBytes(Native Method) at java.io.FileInputStream.read(FileInputStream.java:255) at sun.security.provider.SeedGenerator$URLSeedGenerator.getSeedBytes(SeedGenerator.java:539) at sun.security.provider.SeedGenerator.generateSeed(SeedGenerator.java:144) at sun.security.provider.SecureRandom$SeederHolder.<clinit>(SecureRandom.java:203) at sun.security.provider.SecureRandom.engineNextBytes(SecureRandom.java:221) - locked <0x00000000d6eb8930> (a sun.security.provider.SecureRandom) at java.security.SecureRandom.nextBytes(SecureRandom.java:468) at oracle.security.o5logon.O5Logon.a(Unknown Source) at oracle.security.o5logon.O5Logon.<clinit>(Unknown Source) at oracle.jdbc.driver.T4CTTIoauthenticate.<init>(T4CTTIoauthenticate.java:566) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:370) at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546) at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236) at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
或許你會問我,爲何你要定位到這個線程?主要是由於道友通過好幾回 jstack 操做,發現該線程一直都停留在該位置,這就足以說明這個線程是當前線程!dom
3. 分析堆棧信息jvm
從上面的堆棧信息中,咱們能夠得知那些信息?ide
經過分析堆棧,想必讀取文件不會有什麼問題,咱們往線程堆棧的上層追蹤。目標點落在
at sun.security.provider.SeedGenerator$URLSeedGenerator.getSeedBytes(SeedGenerator.java:539)
很明顯,這裏是 JDK 源碼的調用,接下來打卡 jdk 源碼進行查看!
4. 源碼分析
咱們經過堆棧信息一步步跟進源碼查看,
從方法 nextBytes 上來看,他調用這個是爲了:生成用戶指定的隨機字節數。好吧,那就是它在生成的時候,須要讀取某個文件來生成隨機數。
5. 寫個測試驗證想法
[ryan@ryanmacbook ~]$ vim HelloWorld.java import java.security.SecureRandom; class HelloWorld { public static void main(String args[]) throws Exception { byte[] bytes = new byte[32]; SecureRandom.getInstance("SHA1PRNG").nextBytes(bytes); System.out.println("SourceRandom nextBytes : " + new String(bytes)); } }
緊接着執行
javac HelloWorld.java
這個要是讀者你不會,那你就放棄java吧,java 界可能不適合你。
接下來執行
java HelloWorld
執行後,,的結果是
[ryan@ryanmacbook ~]$ java HelloWorld ^C [ryan@ryanmacbook ~]$
卡住了,樓主強制 kill 了。
說明咱們的問題點就是這裏。
接下來,解決辦法是啥?你要問樓主樓主也不知道,咋辦?上百度唄,百度都不會用的程序員不是好程序員:
6. 解決辦法
最後的解決辦法就是 ,在項目啓動的時候,修改 java.security.egd,經過以下方式,專業術語叫作 熵池策略 :
java -Djava.security.egd=file:/dev/urandom HelloWorld
問題的本質仍是 Oracle 驅動類中調用了 SecureRandom.nextBytes() 。樓主還沒來得及看其餘驅動程序是否也有這個問題,固然也不排除與操做系統有關係。待驗證其餘操做系統後,再補充!
果斷成功!
道友查了下,說是 JVM 的 bug , 在收集噪點的時候沒有收集全致使的。若是你的也有遇到這樣的問題,時而可用,時而不可用,那就是噪點收集的問題。