golang rand.Int,rand.Seed 踩坑記錄


https://blog.csdn.net/mingzhehaolove/article/details/77305832

情景描述:

30台服務器負載均衡,初始化建立rpc連接池,在rpc連接異常時,會進行重試,重試過程需要進行rand.Int 獲取隨機數,讀取一台連接,但是一開始沒有設定隨機種子導致,每一台第一次獲取的都是同一個機器,這樣所有的流量都打到一台,導致機器掛了。影響其它服務。

后來添加了隨機種子,但是有一次量上來的比較大,單個機器的內存飆升,接連影響其它機器的rpc連接,導致goroutinue達到250萬,pprof分析,是rand.Seed導致,查看文檔發現,官方給出這么一句

[php]  view plain  copy
 
  1. // Seed uses the provided seed value to initialize the generator to a deterministic state.  
  2. // Seed should not be called concurrently with any other Rand method.  

因為我們的獲取機器方法,每次都需要seed,所以導致了這個問題,后續把rand.Seed 提到初始化方法,實現一次,這個問題就規避了。

 

使用rand.Int 獲取隨機數,不加隨機種子,每次遍歷獲取都是重復的一些數據

[php]  view plain  copy
 
  1. package main  
  2.   
  3. import (  
  4.     "fmt"  
  5.     "math/rand"  
  6.     "sync"  
  7. )  
  8.   
  9. func main() {  
  10.     num := 10  
  11.     for j := 0; j < num; j++ {  
  12.         res := getRand(num)  
  13.         fmt.Println(res)  
  14.     }  
  15. }  
  16.   
  17. func getRand(num int) int {  
  18.     var mu sync.Mutex  
  19.     mu.Lock()  
  20.     v := rand.Intn(num)  
  21.     mu.Unlock()  
  22.     return v  
  23. }  
  24.   
  25. 結果:  
  26. 1  
  27. 7  
  28. 7  
  29. 9  
  30. 1  
  31. 8  
  32. 5  
  33. 0  
  34. 6  
  35. 0   

 添加隨機種子 rand.Seed(time.Now().UnixNano())  保證每次都是隨機的

[php]  view plain  copy
 
  1. package main  
  2.   
  3. import (  
  4.     "fmt"  
  5.     "math/rand"  
  6.     "sync"  
  7.     "time"  
  8. )  
  9.   
  10. func main() {  
  11.     num := 10  
  12.     for j := 0; j < num; j++ {  
  13.         res := getRand(num)  
  14.         fmt.Println(res)  
  15.     }  
  16. }  
  17.   
  18. func getRand(num int) int {  
  19.     rand.Seed(time.Now().UnixNano())  
  20.     var mu sync.Mutex  
  21.     mu.Lock()  
  22.     v := rand.Intn(num)  
  23.     mu.Unlock()  
  24.     return v  
  25. }  
  26. 結果:  
  27. 1  
  28. 5  
  29. 4  
  30. 8  
  31. 3  
  32. 1  
  33. 4  
  34. 4  
  35. 3  
  36. 0  

正常情況,做一些小的開發,這些無所謂,但是當開發一些高並發的處理時,rand.Seed就會發生問題,官方不建議在高並發情況下,使用rand.Seed,之所以我會遇到這種問題,也是因為,當時線上出了一個大問題,為了快速解決,就使用了rand.Seed. 為了得到隨機的線上機器,進行rpc調用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM