golang 实现tcp连接池

思路

为了复用tcp连接,减少建立新连接的开销,实现连接池思路如下:

1, 初始化连接池的容量大小
2, 客户端从连接池中获取连接,若无可用连接则创建新连接并放入连接池,若有则从连接池中取出
3,使用完连接后,将连接重新放回连接池中
4, 定期检查连接池连接是否可用,不可用则剔除连接池

代码

package main

import (
	"errors"
	"fmt"
	"net"
)

type ConnPool struct {
	address  string
	channel  chan net.Conn
	capacity int
}

func NewConnPool(address string, capacity int) *ConnPool {
	return &ConnPool{
		address:  address,
		channel:  make(chan net.Conn, capacity), // 初始化连接池
		capacity: capacity,
	}
}

func (p *ConnPool) GetConn() (net.Conn, error) {
	select {
	case conn := <-p.channel: // 有连接直接返回
		return conn, nil
	default: // 无连接则创建并塞入连接池
		if len(p.channel) < p.capacity {
			conn, err := net.Dial("tcp", p.address)
			if err != nil {
				return nil, err
			}
			p.channel <- conn
			return conn, nil
		}
		return nil, errors.New("connection pool overflow")
	}
}

func (p *ConnPool) PutConn(conn net.Conn) {
	select {
	case p.channel <- conn: // 释放连接后重新放回连接池
	default:
		conn.Close() // 连接池已满则直接关闭
	}
}

func main() {
	pool := NewConnPool("127.0.0.1:3306", 64)
	conn, err := pool.GetConn()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer pool.PutConn(conn)

	// transfer data ...

}


你可能感兴趣的:(golang,tcp/ip,开发语言)