场景:最近在写一个注册服务的时候,注册密码采用的是SHA256+盐的方式,其中使用SecureRandom来生成随机盐;这里存在一个严重的坑就是SecureRandom的性能问题。该问题困扰了很久,使用本机启动服务访问注册服务都是毫秒级,但部署到linux服务器上就到了分钟级,这导致网关那边无限超时,功能无法正常使用。先查了问题看到有报数据库异常是mysql8小时问题,于是把mysql的wait_timeout改为了8小时,同时tomcat连接池增加查询心态机制(mysql8小时),调整好后,但未能真正解决服务响应慢的结局,最终发现是SecureRandom引起的问题
String result = transactionTemplate.execute(new TransactionCallback<String>() { @Override public String doInTransaction(TransactionStatus status) { String result = null; try { // 生成唯一标识 String uid = Uid(); // 生成盐 byte[] bytes = SecureRandom.getSeed(32); String salt = Base64.encodeBuffer(bytes); // 加密密码 String cipherPassword = CipherUtils.SHA256(password + salt); //具体业务 result = uid; } catch (DataAccessException e) { logger.error(e.getMessage(), e); status.setRollbackOnly(); } catch (Exception e) { logger.error(e.getMessage(), e); status.setRollbackOnly(); } return result; } });
具体解决方案及参考:
添加启动参数 -Djava.security.egd=file:/dev/./urandom,由于Linux生成随机数机制跟window不同,所以加上这个就可以避免生成随机数时时快时慢的问题
http://stackoverflow.com/questions/28201794/slow-startup-on-tomcat-7-0-57-because-of-securerandom
http://www.tuicool.com/articles/JfiQjiu