1、Go 連接redis的方法:
package que
import (
"fmt"
"time"
"github.com/gomodule/redigo/redis"
)
var (
pool *redis.Pool
localhost = "" // 127.0.0.1
port = "6379"
addr = localhost + ":" + port
Password = ""
)
func init() {
initRides()
// InitReceiver()
}
func initRides() {
pool = &redis.Pool{
IdleTimeout: 180 * time.Second,
Dial: func() (redis.Conn, error) {
conn, err := redis.Dial("tcp", addr, redis.DialPassword(Password))
if err != nil {
return nil, err
}
return conn, nil
},
}
}
其中如果沒有 redis.DialPassword(Password),則連接redis時可能會報錯:NOAUTH Authentication required.
或者可以使用下面這種設定方式解決認證問題:
func initRides() {
pool = &redis.Pool{
IdleTimeout: 180 * time.Second,
Dial: func() (redis.Conn, error) {
conn, err := redis.Dial("tcp", addr)
if err != nil {
return nil, err
}
if _, err := conn.Do("AUTH", Password); err != nil {
conn.Close()
return nil, err
}
return conn, nil
},
}
}
2、根據業務需求,在main的init里面呼叫InitReceiver方法,當需要處理大量資料的時候,介面不能做出及時反饋,這時就需要類似的模型來解決該問題了:
func init() {
initRides()
InitReceiver()
}
func InitReceiver() {
go func() {
for {
var conn = pool.Get()
defer conn.Close()
// Do some thing
conn.Do("set", "test", "test1111")
line, _ := redis.String(conn.Do("get", "test"))
fmt.Println(line)
}
}()
}
3、代碼跑起來之后,使用命令:
netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
查看TCP的狀態資訊,其中ESTABLISHED狀態的存在1萬多個:
CLOSE_WAIT 1
ESTABLISHED 10015
SYN_SENT 1
TIME_WAIT 15
下面是 TCP正常連接建立和終止所對應的狀態圖:

相關TCP狀態解釋:
LISTEN: 偵聽來自遠方的TCP埠的連接請求;
SYN_SENT: 在發送連接請求后等待匹配的連接請求;
SYN_RECV: 在收到和發送一個連接請求后等待對方對連接請求的確認;
ESTABLISHED: 代表一個打開的連接;
FIN_WAIT1: 等待遠程TCP連接中斷請求, 或先前的連接中斷請求的確認;
FIN_WAIT2: 從遠程TCP等待連接中斷請求;
CLOSE_WAIT: 等待從本地用戶發來的連接中斷請求;
CLOSING: 等待遠程TCP對連接中斷的確認;
LAST_ACK: 等待原來的發向遠程TCP的連接中斷請求的確認;
TIME_WAIT: 等待足夠的時間以確保遠程TCP接收到連接中斷請求的確認;
CLOSE: 沒有任何連接狀態;
注(參考出處:https://blog.csdn.net/dujianxiong/article/details/83180633)
4、當我們推出程式之后:
[root ~]# netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
CLOSE_WAIT 1
ESTABLISHED 15
SYN_SENT 1
TIME_WAIT 10013
ESTABLISHED狀態的連接被中斷了,會通過TIME_WAIT的狀態保留一段時間,這段時間過了才會釋放這個埠,但是如果再這段時間內還有大量的請求的時候,就會產生大量的TIME_WAIT狀態的連接,這些連接占著埠,也會占用大量的資源,
5、解決方法,增加 MaxIdle 和 MaxActive :
func initRides() {
pool = &redis.Pool{
MaxIdle: 30,
MaxActive: 30,
IdleTimeout: 180 * time.Second,
Dial: func() (redis.Conn, error) {
conn, err := redis.Dial("tcp", addr, redis.DialPassword(Password))
if err != nil {
return nil, err
}
return conn, nil
},
}
}
maxIdle,最大空閑數,資料庫連接的最大空閑時間,超過空閑時間,資料庫連
接將被標記為不可用,然后被釋放,設為0表示無限制,
MaxActive,連接池的最大資料庫連接數,設為0表示無限制,
maxActive是最大激活連接數,這里取值為30,表示同時最多有30個資料庫連接,
maxIdle是最大的空閑連接數,這里取值為30,表示即使沒有資料庫連接時依然可以保持30空閑的
連接,而不被清除,隨時處于待命狀態,
設定了之后效果顯著:
[root ~]# netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
CLOSE_WAIT 2
ESTABLISHED 25
TIME_WAIT 67
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286830.html
標籤:其他
上一篇:日常學習筆記
