为什么要使用连接池

一个数据库服务器只拥有有限的连接资源,一旦所有的连接资源都在使用,那么其它需要连接的资源就只能等待释放连接资源。所以,在连接资源有限的情况下,提高单位时间的连接的使用效率,缩短连接时间,就能显著缩短请求时间。

所以就有了连接池的概念,在初始化时,创建一定数量的连接,先把所有连接存起来,然后,谁需要使用,从这里取走,干完活立马放回来。 如果请求数超出连接池容量,那么就排队等待或者直接丢弃掉。这样就可以省掉每次都创建和关闭连接的资源消耗和时间。

如果不使用连接池,那么,每次传输数据,我们都需要耗费大量的系统资源进行创建连接,收发数据,关闭连接。很明显,重复创建连接 关闭连接这样的消耗是可以节省。

怎么使用Redis连接池

先看下简单的使用案例。

首先当然是下载类库包

go get github.com/gomodule/redigo/redis

贴下简单的使用代码

package main

import (
red "github.com/gomodule/redigo/redis"
"time"
"fmt"
) type Redis struct {
pool *red.Pool
} var redis *Redis func initRedis() {
redis = new(Redis)
redis.pool = &red.Pool{
MaxIdle: 256,
MaxActive: 0,
IdleTimeout: time.Duration(120),
Dial: func() (red.Conn, error) {
return red.Dial(
"tcp",
"127.0.0.1:6379",
red.DialReadTimeout(time.Duration(1000)*time.Millisecond),
red.DialWriteTimeout(time.Duration(1000)*time.Millisecond),
red.DialConnectTimeout(time.Duration(1000)*time.Millisecond),
red.DialDatabase(0),
//red.DialPassword(""),
)
},
}
} func Exec(cmd string, key interface{}, args ...interface{}) (interface{}, error) {
con := redis.pool.Get()
if err := con.Err(); err != nil {
return nil, err
}
defer con.Close()
parmas := make([]interface{}, 0)
parmas = append(parmas, key) if len(args) > 0 {
for _, v := range args {
parmas = append(parmas, v)
}
}
return con.Do(cmd, parmas...)
} func main() {
initRedis() Exec("set","hello","world")
fmt.Print(2)
result,err := Exec("get","hello")
if err != nil {
fmt.Print(err.Error())
}
str,_:=red.String(result,err)
fmt.Print(str)
}

使用类库操作连接池就比较简单,只要从连接池获取一个连接,进行数据操作,然后关闭连接。连接池对连接的创建 回收等的管理,都是连接池内部实现。

执行看下结果是不是预想的

go build -o test_web.bin
./test_web.bin
2world

结果跟预想的一毛一样

基本配置说明

MaxIdle:最大的空闲连接数,表示即使没有redis连接时依然可以保持N个空闲的连接,而不被清除,随时处于待命状态。

MaxActive:最大的连接数,表示同时最多有N个连接。0表示不限制。

IdleTimeout:最大的空闲连接等待时间,超过此时间后,空闲连接将被关闭。如果设置成0,空闲连接将不会被关闭。应该设置一个比redis服务端超时时间更短的时间。

DialConnectTimeout:连接Redis超时时间。

DialReadTimeout:从Redis读取数据超时时间。

DialWriteTimeout:向Redis写入数据超时时间。

连接流程大概是这样的

1.尝试从空闲列表MaxIdle中,获得一个可用连接;如果成功直接返回,失败则尝试步骤2

2.如果当前的MaxIdle < 连接数 < MaxActive,则尝试创建一个新连接,失败则尝试步骤3

3. 如果连接数 > MaxActive就等待,直到满足步骤2的条件,重复步骤2

遇到过的问题

目前为止,连接池的问题只遇到过一次问题,而且是在测试环境的,当时的配置是

DialConnectTimeout:time.Duration(200)*time.Millisecond
DialReadTimeout:time.Duration(200)*time.Millisecond
DialWriteTimeout:time.Duration(200)*time.Millisecond

配置的都是200毫秒。有一次使用hgetall的时候,就一直报错,大概类似下面的提示

read tcp 127.0.0.1:6379: i/o timeout

字面意思就是 read tcp 超时,可能某些写入大点数据的时候也会报,write tcp timeout。

后来将读写超时时间都改为1000毫秒,就再也没有出现过类似的报错。

当然了,想了解更多的Redis使用,可以看下官方的文档,里面有各种情况的各种说明。

https://github.com/gomodule/redigo/

golang开发:类库篇(二) Redis连接池的使用的更多相关文章

  1. golang开发:类库篇(五)go测试工具goconvey的使用

    为什么要使用goconvey测试程序 goconvey 集成go test,go test 无缝接入.管理运行测试用例,而且提供了丰富的函数断言.非常友好的WEB界面,直观的查看测试结果. 如果没有g ...

  2. golang开发:类库篇(一) Zap高性能日志类库的使用

    为什么要用zap来写日志 原来是写PHP的,一直用的error_log,第一次写Go项目的时候,还真不知道该怎么写日志,后来就按照PHP的写法自己不成规范的捣鼓写.去了新公司之后,发现用的是zap.后 ...

  3. golang开发:类库篇(三)命令行工具cli的使用

    为什么要使用命令行 觉得这个问题不应该列出来,又觉得如果初次进行WEB开发的话,可能会觉得所有的东西都可以使用API去做,会觉得命令行没有必要. 其实,一个生产的项目命令行是绕不过去的.比如运营需要导 ...

  4. golang开发:类库篇(四)配置文件解析器goconfig的使用

    为什么要使用goconfig解析配置文件 目前各语言框架对配置文件书写基本都差不多,基本都是首先配置一些基础变量,基本变量里面有环境的配置,然后通过环境变量去获取该环境下的变量.例如,生产环境跟测试环 ...

  5. python 基础 10.0 nosql 简介--redis 连接池及管道

    一. NOSQL 数据库简介 NoSQL 泛指非关系型的数据库.非关系型数据库与关系型数据库的差别 非关系型数据库的优势: 1.性能NOSQL 是基于键值对的,可以想象成表中的主键和值的对应关系,而且 ...

  6. Go语言之从0到1实现一个简单的Redis连接池

    Go语言之从0到1实现一个简单的Redis连接池 前言 最近学习了一些Go语言开发相关内容,但是苦于手头没有可以练手的项目,学的时候理解不清楚,学过容易忘. 结合之前组内分享时学到的Redis相关知识 ...

  7. 压测过程中,获取不到redis连接池,发现redis连接数高

    说明:图片截得比较大,浏览器放大倍数看即可(涉及到隐私,打了码,请见谅,如果有疑问,欢迎骚扰). 最近在压测过程中,出现获取不到redis连接池的问题 xshell连接redis服务器,查看连接数,发 ...

  8. 转 JDBC连接数据库(二)——连接池

    https://www.cnblogs.com/xiaotiaosi/p/6398371.html 数据库保持长连接,不过一直都是idle,除非有用户激活连接,这样后果是无法删除用户,但是不影响数据库 ...

  9. Django day35 redis连接池,redis-list操作,django中使用redis,支付宝支付

    一:redis连接池, 二:redis-list操作, 三:django中使用redis, 四:支付宝支付

随机推荐

  1. Jmeter 专题

    Jmeter是一个非常好用的压力测试工具.  Jmeter用来做轻量级的压力测试,非常合适,只需要十几分钟,就能把压力测试需要的脚本写好. 为什么要建立线程组?原因很简单,因为我们要模拟多个线程(用户 ...

  2. [Unity3D]Unity3D圣骑士模仿游戏开发传仙灵达到当局岛

    大家好,我是秦培.欢迎关注我的博客.我的博客地址blog.csdn.net/qinyuanpei. 在前面的文章中.我们分别实现了一个自己定义的角色控制器<[Unity3D]Unity3D游戏开 ...

  3. WPF中画虚线

    原文:WPF中画虚线 在WPF中,画线的方法十分简单,只要声明一个Line然后添加到指定的位置就可以了,但Line并不仅仅只能画一条直线,还可以对直线进行修饰. 1.Line.StrokeDashAr ...

  4. android 获取 cpu 频率信息

    cpu的频率信息可以在/sys/devices/system/cpu/cpu0/cpufreq/路径下读取 比如最高频率路径为:/sys/devices/system/cpu/cpu0/cpufreq ...

  5. CoolFormat(Qt Creator也可管理VC的Project)

    http://download.csdn.net/download/akof1314/8457593 https://github.com/akof1314/CoolFormat http://dow ...

  6. C# 遍历窗体控件顺序问题

    今天在做C# winform 窗体控件遍历时遇到控件顺序的问题,也就是控件被遍历的先后问题.实际情况如下所述. 窗体界面如下: 界面构成是:主界面有一个 Panel (Panel_14),Panel_ ...

  7. QT字符编码转换,可用于中文内码传输

    串口.TCP.UDP传输中文字符时,先将字符串转内码.客户端接收到数据后,将内码转为字符串就OK了 QByteArray CommonFunction::strToInterCode(constQSt ...

  8. Delphi中Menu设置Images属性后快捷按键下划线被隐藏解决方法

    现象:MainMenu设置Images属性后,看不到快捷按键的下划线,如:新建(&N) 分析:VCL中Menus.pas单元的代码,看到如下语句procedure TMenuItem.Adva ...

  9. Ubuntu下使用Docker搭建MySQL步骤备忘

    docker 安装和 pull MySQL镜像这里就不介绍了,很多介绍,建议去docker官方网站查看. 本文主要介绍MySQL container 运行起来之后的一些配置 在往下看之前,确保 doc ...

  10. ring3层一种占用文件的方法(DuplicateHandle以后,把占用文件的句柄丢给系统进程,导致被占用)

    前段时间,一个测试工程师问我关于怎样长时间的占用一个文件,而使别的程序无法再访问这个文件,想起以前很多病毒木马经常劫持hosts文件不放,除非你找到占用文件的程序,并强行结束掉,否则怎么也访问不了ho ...