Spring BcryptPasswordEncorder Log Rounds引數說明
Spring BcryptPasswordEncorder log rounds引數說明
今天在做使用者上傳Excel表格
匯入資料到Mongodb
資料庫的時候遇到一個超時的問題,比較有意思,在這裡記錄一下!需求是這樣的,使用者通過頁面選擇本地的Excel表格,通過介面將Excel表格上傳到後臺,由後端解析Excel表格中的資料,解析成功後儲存到資料庫中。對於Excel表格的處理我表示輕車熟路,本來這個功能已經做好了,而且之前還測試過上傳有上萬條記錄的Excel表格的匯入,完全沒有壓力。但是今天在匯入新使用者的時候突然提示500超時
了!以下是我的解決過程:
1. 首先想到的時候Spring MVC
的介面預設超時時間設定得太短了,Spring
的文件說如果不設定預設超時時間,那麼會根據伺服器的超時時間進行設定,Tomcat
一般是10s。然後我就修改了Spring
的配置,增加了如下兩處超時時間配置:
server:
connection-timeout: 60000
spring:
mvc:
async:
request-timeout: 60000
再次上傳該使用者表,WTF,還是超時。
- 接著考慮是不是前端訪問介面的時候有設定預設的超時時間,仔細
F12
看呼叫過程,否定了這個想法。 - 然後只能單步除錯了,但是類似這樣的問題設定斷點進行除錯往往會影響程式執行,不易復現問題,所以我選擇
分步列印時間戳
的辦法。很順利,發現了出現問題的程式碼塊,如下:
//使用者賬號資訊批量初始化設定
users.stream().forEach(tempStudent -> {
//設定預設使用者角色
tempUser.setRoles(Arrays.asList(DefaultRole));
//設定使用者預設登入名為編號
tempUser.setUsername(tempUser.getCode());
//設定使用者預設密碼為編號
String md5Hex = DigestUtils.md5Hex(tempUser.getCode());
tempUser.setPassword(md5Hex);
});
再次使用逐行註釋法
,最終定位到出現問題的程式碼是:
tempUser.setPassword(md5Hex);
而我在該程式碼塊裡面做的工作如下:
public static final PasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder(4);
public void setPassword(String password) {
this.password = PASSWORD_ENCODER.encode(password);
}
設定使用者密碼時使用Spring
框架的BCryptPasswordEncoder
對密碼進行了加密。發現這個問題時感覺很困惑,按理說Spring
框架這麼成熟,不會有這麼明細的效能瓶頸啊!再仔細去看裡面的建構函式和加密方法,大概發現了問題所在,關鍵程式碼如下:
public BCryptPasswordEncoder() {
this(-1);
}
public String encode(CharSequence rawPassword) {
String salt;
if (strength > 0) {
if (random != null) {
salt = BCrypt.gensalt(strength, random);
}
else {
salt = BCrypt.gensalt(strength);
}
}
else {
salt = BCrypt.gensalt();
}
return BCrypt.hashpw(rawPassword.toString(), salt);
}
public static String gensalt() {
return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS);
}
private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10;
原來是如果構造BCryptPasswordEncoder
時不傳引數就預設使用長度為10的LOG ROUND
,我試著傳入最小的構造引數4
之後,一下子就處理完了,500
錯誤也沒有了。搜尋了相關的關鍵詞,LOG ROUND
這個引數大概的意思是做加密時重複處理的輪數,而且其複雜度是指數級
遞增,也就是傳4
的時候是2
的4
次方,預設傳輸為10
的時候是2
的10
次方!難怪其速度會差距這麼大!
最後呢,顯然這種在介面裡面同步處理大批量資料的方法是不可取的,應該使用ActiveMQ
之類的協議進行非同步處理。嗯,功能完善後再迭代吧!
相關文章
- mysql relay log相關引數說明MySql
- TOP引數說明
- mysqldump引數說明MySql
- mysqldump 引數說明MySql
- MySQL引數說明MySql
- Elasticsearch 引數配置說明Elasticsearch
- kafka 引數配置說明Kafka
- redis 3.0 引數說明Redis
- golden gate 引數說明Go
- oracle引數說明(zt)Oracle
- Oracle Table建立引數說明Oracle
- Oracle Table 建立引數 說明Oracle
- mysqldump引數詳細說明MySql
- mosquitto命令引數說明UI
- Oracle Sequence Cache 引數說明Oracle
- 【MYSQL】MHA引數列表說明MySql
- Mysql JDBC Url引數說明MySqlJDBC
- Nginx的gzip配置引數說明Nginx
- linux常用核心引數說明Linux
- GoldenGate HANDLECOLLISIONS引數使用說明Go
- 【7】JVM引數說明和分析JVM
- 2.--Goldgate常用引數說明Go
- 【MySQL】SemisynchronousReplication配置和引數說明MySql
- Linux SHELL if 命令引數說明Linux
- Redis配置檔案引數說明Redis
- MySQL CMake引數說明手冊MySql
- mysql innodb相關引數說明MySql
- Goldengate引數簡要說明Go
- 【ASM學習】ASM引數說明ASM
- 編譯引數-ObjC的說明編譯OBJ
- Mysql my.cnf部分引數說明MySql
- Azure Blob (三)引數設定說明
- postgresql資料庫重要引數說明SQL資料庫
- MYSQL: Handler_read_%引數說明MySql
- sql注入工具sqlmap使用引數說明SQL
- Oracle 啟動例程 STARTUP引數說明Oracle
- 【MySQL】Semisynchronous Replication 配置和引數說明MySql
- DBCP連線池配置引數說明