gedis:自己实现go语言的redis客户端 第二节(tcp连接池模块实现)

在大多数实际业务场景中,为满足高并发的需求,往往需要提供连接池的支持,包括连接池的管理,连接的创建、销毁等等,还要保证并发安全。实现如下:

package client

import (
	"errors"
	"net"
	"sync"
	"protocol"
)

type ConnConfig struct {
	ConnString string
	Pwd        string
}

type ConnPool struct {
	connPool   chan *net.TCPConn
	initActive int
}

var pool *ConnPool
var oSingle sync.Once

/**
 * 单例的连接池(线程安全)
 */
func NewSingleConnPool(initActive int, config ConnConfig) *ConnPool {
	oSingle.Do(func() {
		pool, _ = NewConnPool(initActive, config)
	})
	return pool
}

/**
 * 初始化连接池
 */
func NewConnPool(initActive int, config ConnConfig) (*ConnPool, error) {
	if initActive <= 0 {
		return nil, errors.New("maxActive must gt than 0")
	}

	var pool ConnPool
	channel := make(chan *net.TCPConn, initActive)
	pool.initActive = initActive

	for index := 0; index < initActive; index++ {
		//初始化一个连接
		conn := Connect(config.ConnString)
		//设置keepalive
		conn.SetKeepAlive(true)
		//为当前连接授权
		auth(conn, config.Pwd)
		//将连接加入连接池
		channel <- conn
	}

	pool.connPool = channel
	return &pool, nil
}

func auth(conn *net.TCPConn, pwd string){
	SendCommand(conn, protocol.AUTH, protocol.SafeEncode(pwd))
}

/**
 * 从连接池中获取连接
 */
func GetConn(pool *ConnPool) (*net.TCPConn, error) {
	if PoolSize(pool) == 0 {
		return nil, errors.New("连接数已不足")
	}

	conn := <-pool.connPool
	if conn == nil {
		return nil, errors.New("连接数已不足")
	}

	return conn, nil
}

/**
 * 将连接归还到连接池
 */
func (pool *ConnPool) PutConn(conn *net.TCPConn) error {
	if conn == nil {
		return errors.New("连接为空")
	}
	pool.connPool <- conn
	return nil
}

/**
 * 返回连接池当前连接数
 */
func PoolSize(pool *ConnPool) int {
	return len(pool.connPool)
}

项目地址:

https://github.com/zhangxiaomin1993/gedis

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值