1. 程式人生 > >記一次服務釋出之後,圖形驗證碼亂碼的服務排查

記一次服務釋出之後,圖形驗證碼亂碼的服務排查

由於業務拓展,新買了臺系統為centOS7的伺服器,配置完jdk和nginx之後,將服務釋出到伺服器上並部署啟動,然後重新整理頁面,神奇的事情就出現了:

第一個想到的問題,就是進行本地除錯,發現一切正常;於是在生成驗證碼文字的地方加上了logger輸出,再次釋出程式到伺服器上,確定是否是文字生成時產生的問題,附上程式碼:

  1. public Valicode() throws IOException {  
  2. //        String vcode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  3.         String vcode = "0123456789";  
  4.         codeImg = new
     BufferedImage(7430, BufferedImage.TYPE_3BYTE_BGR);  
  5.         Graphics2D g = codeImg.createGraphics();  
  6.         g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);  
  7.         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);  
  8.         g.setColor(Color.white);  
  9.         g.fillRect(007430);  
  10.         for (int i = 0; i < 100; i++) {  
  11.             int x = (int) Math.round((Math.random() * 74));  
  12.             int y = (int) Math.round((Math.random() * 30));  
  13.             Color color = new Color((float) (Math.random() * 0.7) + 0.3F, (
    float) (Math.random() * 0.7) + 0.3F,  
  14.                 (float) (Math.random() * 0.7) + 0.3F);  
  15.             g.setColor(color);  
  16.             g.drawRect(x, y, 11);  
  17.         }  
  18.         code = "";  
  19.         for (int i = 0; i < 4; i++) {  
  20.             int fontsize = (int) Math.round(Math.random() * 3 + 20);  
  21.             Font font = new Font("", (int) Math.round(Math.random() * 3), fontsize);  
  22.             Color color = new Color((float) (Math.random() * 0.7), (float) (Math.random() * 0.7), (float) (Math.random() * 0.7));  
  23.             g.setColor(color);  
  24.             g.setFont(font);  
  25. //            Character c = vcode.charAt(Math.round((float) Math.random() * 35));
  26.             Character c = vcode.charAt(Math.round((float) Math.random() * 9));  
  27.             code += c;  
  28.             g.drawString(c + ""18 * i + (int) (Math.random() * 10 - 5) + 224 + (int) (Math.random() * 10 - 5));  
  29.         }  
  30.         logger.info("code:{}",code);  
  31.     }  
執行服務之後,通過日誌,發現文字生成輸出正常,開始懷疑是否是jdk版本不一致導致的問題。因為我們開發環境裝的是jdk7,伺服器上裝的是jdk8,難道是jdk做向下相容的時候出現的問題;於是將專案發到另一臺也是jdk8的伺服器上,啟動測試,發現一切正常,排除jdk版本問題。此時,再次檢視程式碼,發現Graphics2D在生成文字的時候,其實呼叫了Font元件

進入font原始碼:

  1. public Font(String name, int style, int size) {  
  2.     this.name = (name != null) ? name : "Default";  
  3.     this.style = (style & ~0x03) == 0 ? style : 0;  
  4.     this.size = size;  
  5.     this.pointSize = size;  
  6. }  
發現用的是系統的預設字型,windows平臺預設是微軟雅黑,檢視對應伺服器上的系統字型:

以及系統的字型列表:

發現並沒有我們需要的字型,於是基本可以確定問題點是出在系統字型上面。

解決方法很直接,就是直接到windows的字型目錄下

選擇 微軟雅黑 字型,直接上傳到伺服器的字型檔案目錄下,可以建立自定義目錄:(我是新建了micro的目錄,將拷貝出來的字型放在了此目錄下)

然後利用命令:fc-cache 重新載入字型配置,清除字型快取。然後重啟專案,發現一切ok。