国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

如何在Go語言中使用Redis連接池

開發 前端 Redis
我們就有了 keepalive 的機制,不會出現 timeout 的連接了,從 redis 連接池里面取出的連接都是可用的連接了。看似簡單的代碼,卻完美的解決了連接池里面超時連接的問題。同時,就算 Redis server 重啟等情況,也能保證連接自動重連。

一、關于連接池

一個數據庫服務器只擁有有限的資源,并且如果你沒有充分使用這些資源,你可以通過使用更多的連接來提高吞吐量。一旦所有的資源都在使用,那么你就不 能通過增加更多的連接來提高吞吐量。事實上,吞吐量在連接負載較大時就開始下降了。通常可以通過限制與可用的資源相匹配的數據庫連接的數量來提高延遲和吞 吐量。

 

如果不使用連接池,那么,每次傳輸數據,我們都需要進行創建連接,收發數據,關閉連接。在并發量不高的場景,基本上不會有什么問題,一旦并發量上去了,那么,一般就會遇到下面幾個常見問題:

  • 性能普遍上不去

  • CPU 大量資源被系統消耗

  • 網絡一旦抖動,會有大量 TIME_WAIT 產生,不得不定期重啟服務或定期重啟機器

  • 服務器工作不穩定,QPS 忽高忽低

要想解決這些問題,我們就要用到連接池了。連接池的思路很簡單,在初始化時,創建一定數量的連接,先把所有長連接存起來,然后,誰需要使用,從這里取走,干完活立馬放回來。 如果請求數超出連接池容量,那么就排隊等待、退化成短連接或者直接丟棄掉。

二、使用連接池遇到的坑

最近在一個項目中,需要實現一個簡單的 Web Server 提供 Redis 的 HTTP interface,提供 JSON 形式的返回結果。考慮用 Go 來實現。

首先,去看一下 Redis 官方推薦的 Go Redis driver。官方 Star 的項目有兩個:Radix.v2 和 Redigo。經過簡單的比較后,選擇了更加輕量級和實現更加優雅的 Radix.v2。

Radix.v2 包是根據功能劃分成一個個的 sub package,每一個 sub package 在一個獨立的子目錄中,結構非常清晰。我的項目中會用到的 sub package 有 redis 和 pool。

由于我想讓這種被 fork 的進程***簡單點,做的事情單一一些,所以,在沒有深入去看 Radix.v2 的 pool 的實現之前,我選擇了自己實現一個 Redis pool。(這里,就不貼代碼了。后來發現自己實現的 Redis pool 與 Radix.v2 實現的 Redis pool 的原理是一樣的,都是基于 channel 實現的, 遇到的問題也是一樣的。)

不過在測試過程中,發現了一個詭異的問題。在請求過程中經常會報 EOF 錯誤。而且是概率性出現,一會有問題,一會又好了。通過反復的測試,發現 bug 是有規律的,當程序空閑一會后,再進行連續請求,會發生3次失敗,然后之后的請求都能成功,而我的連接池大小設置的是3。再進一步分析,程序空閑300秒 后,再請求就會失敗,發現我的 Redis server 配置了 timeout 300,至此,問題就清楚了。是連接超時 Redis server 主動斷開了連接。客戶端這邊從一個超時的連接請求就會得到 EOF 錯誤。

然后我看了一下 Radix.v2 的 pool 包的源碼,發現這個庫本身并沒有檢測壞的連接,并替換為新的連接的機制。也就是說我每次從連接池里面 Get 的連接有可能是壞的連接。所以,我當時臨時的解決方案是通過增加失敗后自動重試來解決了。不過,這樣的處理方案,連接池的作用好像就沒有了。技術債能早點 還的還是早點還上。

三、使用連接池的正確姿勢

想到我們的 ngx_lua 項目里面也大量使用 redis 連接池,他們怎么沒有遇到這個問題呢。只能去看看源碼了。

經過抽象分離, ngx_lua 里面使用 redis 連接池部分的代碼大致是這樣的:

 

  1. server { 
  2.     location /pool { 
  3.         content_by_lua_block { 
  4.             local redis = require "resty.redis" 
  5.             local red = redis:new() 
  6.  
  7.             local ok, err = red:connect("127.0.0.1"6379
  8.             if not ok then 
  9.                 ngx.say("failed to connect: ", err) 
  10.                 return 
  11.             end 
  12.  
  13.             ok, err = red:set("hello""world"
  14.             if not ok then 
  15.                 return 
  16.             end 
  17.  
  18.             red:set_keepalive(10000100
  19.         } 
  20.     } 

發現有個 set_keepalive 的方法,查了一下官方文檔,方法的原型是 syntax: ok, err = red:set_keepalive(max_idle_timeout, pool_size) 貌似 max_idle_timeout 這個參數,就是我們所缺少的東西,然后進一步跟蹤源碼,看看里面是怎么保證連接有效的。

 

  1. function _M.set_keepalive(self, ...) 
  2.     local sock = self.sock 
  3.     if not sock then 
  4.         return nil, "not initialized" 
  5.     end 
  6.  
  7.     if self.subscribed then 
  8.         return nil, "subscribed state" 
  9.     end 
  10.  
  11.     return sock:setkeepalive(...) 
  12. end 

至此,已經清楚了,使用了 tcp 的 keepalive 心跳機制。

于是,通過與 Radix.v2 的作者一些討論,選擇自己在 redis 這層使用心跳機制,來解決這個問題。

四、***的解決方案

在創建連接池之后,起一個 goroutine,每隔一段 idleTime 發送一個 PING 到 Redis server。其中,idleTime 略小于 Redis server 的 timeout 配置。
連接池初始化部分代碼如下:

  1. p, err := pool.New("tcp", u.Host, concurrency) 
  2. errHndlr(err) 
  3. go func() { 
  4.     for { 
  5.         p.Cmd("PING"
  6.         time.Sleep(idelTime * time.Second) 
  7.     } 
  8. }() 

使用 redis 傳輸數據部分代碼如下:

 

  1. func redisDo(p *pool.Pool, cmd string, args ...interface{}) (reply *redis.Resp, err error) { 
  2.     reply = p.Cmd(cmd, args...) 
  3.     if err = reply.Err; err != nil { 
  4.         if err != io.EOF { 
  5.             Fatal.Println("redis", cmd, args, "err is", err) 
  6.         } 
  7.     } 
  8.  
  9.     return 

其中,Radix.v2 連接池內部進行了連接池內連接的獲取和放回,代碼如下:

 

  1. // Cmd automatically gets one client from the pool, executes the given command 
  2. // (returning its result), and puts the client back in the pool 
  3. func (p *Pool) Cmd(cmd string, args ...interface{}) *redis.Resp { 
  4.     c, err := p.Get() 
  5.     if err != nil { 
  6.         return redis.NewResp(err) 
  7.     } 
  8.     defer p.Put(c) 
  9.  
  10.     return c.Cmd(cmd, args...) 

這樣,我們就有了 keepalive 的機制,不會出現 timeout 的連接了,從 redis 連接池里面取出的連接都是可用的連接了。看似簡單的代碼,卻***的解決了連接池里面超時連接的問題。同時,就算 Redis server 重啟等情況,也能保證連接自動重連。

責任編輯:王雪燕 來源: 極客頭條
相關推薦

2013-06-25 09:52:32

GoGo語言Go編程

2019-12-30 15:30:13

連接池請求PHP

2011-06-01 13:54:10

MySQL

2022-09-29 10:01:05

Go編程語言文本文件

2022-11-03 20:38:01

CMD命令Go

2014-04-09 09:32:24

Go并發

2009-06-15 13:46:00

netbeans設置數據庫連接池

2011-05-25 13:22:05

PHPJSON

2024-04-01 00:02:56

Go語言代碼

2011-08-25 09:55:27

2025-03-27 00:45:00

2010-03-11 19:16:32

Python語言

2024-05-10 08:36:40

Go語言對象

2023-10-09 07:14:42

panicGo語言

2025-02-13 09:02:04

2012-06-17 13:04:45

2022-06-23 08:00:53

PythonDateTime模塊

2021-03-09 07:27:40

Kafka開源分布式

2022-05-17 08:25:10

TypeScript接口前端

2021-06-09 09:36:18

DjangoElasticSearLinux
點贊
收藏

51CTO技術棧公眾號

国产成人三级在线观看| 国产一区二区不卡视频在线观看| 久久综合色之久久综合| 国产99久久| 国产精品高颜值在线观看| 熟女少妇精品一区二区| 久久久久一区二区三区| 精品自在线视频| 在线日韩av片| 久久久久久久久99精品| 久久综合婷婷| 欧美 日韩 国产 一区| 9999在线精品视频| 国产www.大片在线| 啊啊啊啊啊啊啊视频在线播放| 亚洲日本理论电影| 国产精品久久久久久久久久直播 | 欧美在线观看一区二区| 99精品视频一区二区三区| 久久精品99国产精品| 国产伦精品一区二区三区视频青涩| 日韩视频二区| 一区二区毛片| 欧美xxx在线观看| 天天色综合色| 91精品二区| 久久精品久久久| 天堂美国久久| 黄色工厂这里只有精品| 欧美日韩国产色综合一二三四| 天美av一区二区三区久久| 日韩大胆成人| 久久精品欧美一区| 欧美精品一卡| 亚洲色诱最新| 黄色精品一二区| 91丨porny丨户外露出| 91原创在线视频| 97aⅴ精品视频一二三区| 国产不卡精品| 美女露胸视频在线观看| 亚洲xxx视频| 日韩欧美第一区| 日本va欧美va瓶| 新欧美整片sss第一页| 日韩高清中文字幕| 亚洲欧美日韩国产综合| 日韩电影在线一区| 国产欧美日韩精品一区二区三区| 欧美aaaaaaaa牛牛影院| 亚洲综合专区| 久久亚洲一区| 国产盗摄精品一区二区酒店| 成年人黄色片视频| 欧美男男video| 噜噜噜91成人网| 欧美性做爰猛烈叫床潮| 国产日韩一区二区| 久久bbxx| 日韩电影免费一区| 中文字幕亚洲一区二区三区| 人妻无码一区二区三区四区| 浪潮色综合久久天堂| 成人av电影免费在线播放| 欧美成人亚洲成人日韩成人| 草草久视频在线观看电影资源| 国产欧美日韩在线观看视频| 亚洲国产三级在线| 99久久精品免费看国产四区 | 伊人久久大香线蕉午夜av| 三级在线免费看| 国产成人a视频高清在线观看| 欧美理论电影大全| 日本成人在线电影网| 性感美女久久精品| 欧美成年人在线观看| 日本一区高清不卡| 在线观看av片| 亚洲制服一区| 成人高清视频在线| 色美美综合视频| 国产精品视频内| 欧美精品性生活| 国产精品诱惑| 久久亚洲综合av| 99热在线精品观看| 日本一区二区电影| 午夜国产在线| 黄色国产精品一区二区三区| 亚洲最大的免费| 欧美国产乱视频| 欧美日韩综合一区| 欧美色综合网站| 精品国产一区二区国模嫣然| 色哟哟国产精品| 久久美女高清视频| 99riav一区二区三区| 国产日韩欧美高清免费| 亚洲成人最新网站| 九九在线精品视频| 99久久伊人久久99| 亚洲制服丝袜一区| 欧美在线亚洲在线| 成人做爰视频www网站小优视频| 91福利国产精品| 成人免费一区二区三区视频网站| 午夜精品视频一区| 高清不卡日本v二区在线| 99热成人精品热久久66| 天堂资源最新在线| 美女精品导航| 亚洲一区二区三区| 国产黑丝在线一区二区三区| 亚洲午夜精品久久久久久性色 | 男人的天堂亚洲一区| 欧美性一二三区| 91亚色免费| 国产后进白嫩翘臀在线观看视频| www.亚洲天堂| 2020中文字幕在线| 亚洲一区中文| 国产精品男人的天堂| 经典三级在线| 91一区二区在线观看| 亚洲aa中文字幕| 理论不卡电影大全神| 亚洲视频精选在线| 久久艳妇乳肉豪妇荡乳av| 999精品视频在线观看| 亚洲爱爱爱爱爱| av777777| 欧美人体视频| 久久久精品蜜桃| 日韩欧美aaaaaa| 青青精品视频播放| 亚洲 国产 欧美一区| 免费日韩在线观看| 在线小视频网址| gay欧美网站| a级精品国产片在线观看| 欧美一级专区免费大片| 国产日韩欧美影视| 国产资源在线视频| 国产白丝在线观看| 亚洲一区日韩| 欧美在线制服丝袜| 色视频www在线播放国产成人| 美女主播视频一区| 国产欧美一区二区三区精品酒店| 久久综合成人精品亚洲另类欧美 | 亚洲妇熟xx妇色黄| 日韩精品伦理第一区| 欧美天堂一区| 亚洲欧美综合色| 亚洲一区二区三区四区中文| 欧美午夜寂寞| 在线综合+亚洲+欧美中文字幕| 亚洲在线视频一区二区| 日韩色淫视频| 一区在线中文字幕| 97人人模人人爽人人喊38tv| 国产日产一区| 成人免费看片网址| 六月婷婷综合| 奇米亚洲午夜久久精品| 一区二区三区色| 成人免费淫片视频软件| 日本黄色成人| 亚洲国产精品小视频| 成人伊人222| 97久久久精品综合88久久| 欧美日韩国产精品一卡| 精品久久99ma| 川上优的av在线一区二区| 亚洲精品视频在线| 成人免费观看在线网址| 国产三级一区二区三区| www.99av.com| 国产成a人亚洲精品| 久久一区二区三区av| 激情国产一区| 精品自在线视频| 哺乳挤奶一区二区三区免费看| 亚洲视频在线观看免费| 久草福利在线视频| 久久欧美中文字幕| 日韩久久在线| 国产专区一区| 国产精品99久久99久久久二8| 欧洲中文在线| 国产精品久久一级| 蜜臀av.com| 综合久久99| 欧美美女操人视频| www.综合网.com| 在线精品视频小说1| 国产精品丝袜久久久久久消防器材| 精品福利电影| 国产小视频国产精品| 日本少妇精品亚洲第一区|