最近有一个项目在用go语言重构,重构完项目表现很好,好记性不如烂笔头,其中遇到的问题记录下来,用到的组件记录下来

thrift pool 实现
const DEFAUL_TTIMEOUT = 300 * time.Millisecond
type ThriftPool struct {
Timeout time.Duration
MaxIdleConns int
mutex sync.Mutex
freeconn []*Thrift socket 
Addr string
}
type ThriftSocket struct {
time time.Time
tSocket *thrift.TSocket
err error
}
func New(addr string) *ThriftPool {
server := ThriftPool{}
server.Addr = addr
return &server
}
func (pool *ThriftPool) NetTimeOut() time.Duration {
if pool.Timeout != 0 {
return pool.Timeout
}
return DEFAUL_TTIMEOUT
}
func (socket *ThriftSocket) SetErr(err error) {
socket.err = err
}
func (socket *ThriftSocket) GetSocket()*thrift.TSocket {
return socket.tSocket
}
// release returns this connection back to the client's free pool
func (pool *ThriftPool) Release(socket *ThriftSocket) {
pool.mutex.Lock()
defer pool.mutex.Unlock()
//有错直接关闭服务
if socket.err !=  nil  {
 libs .Logger.Info("thrift_pool", zap.String("release err", socket.err.Error()))
socket.tSocket. Close ()
return
}
// 超过最大连接池限制直接关闭连接
if len(pool.freeconn) > pool.MaxIdleConns {
libs.Logger.Info("thrift_pool", zap.String("release msg", " > pool.MaxIdleConns"))
socket.tSocket.Close()
return
}
socket.time = time.Now()
socket.err = nil
socket.tSocket.Conn().SetDeadline(time.Now().Add(time.Duration(pool.Timeout)))
pool.freeconn = append(pool.freeconn, socket)
}
func (pool *ThriftPool) GetConn() (socket *ThriftSocket, err error) {
pool.mutex.Lock()
defer pool.mutex.Unlock()
if len(pool.freeconn) > 0 {
for {
if len(pool.freeconn) > 0 {
socket = pool.freeconn[len(pool.freeconn)-1]
pool.freeconn = pool.freeconn[:len(pool.freeconn)-1]
// 检查时间,在thrift socket 会调用 pushDeadline 设置连接的绝对时间
if time.Now().Sub(socket.time) < pool.NetTimeOut() {
return socket, nil
}
socket.tSocket.Close()
}
// 别忘了退出呀
break
}
}
thriftSocket := ThriftSocket{}
if socket,err := thrift.NewTSocketTimeout(pool.Addr, pool.Timeout); err == nil {
thriftSocket.tSocket = socket
thriftSocket.time = time.Now()
} else {
libs.Logger.Info("thrift_pool", zap.String("get err", err.Error()))
return nil, err
}
// 直接连接
if err := thriftSocket.tSocket.Open(); err != nil {
libs.Logger.Info("thrift_pool", zap.String("get err", err.Error()))
return nil, err
}
return &thriftSocket, nil
}
 

使用方法如下:

tSocket, err := dyanmicPool.GetConn()
defer dyanmicPool.Release(tSocket)
if err != nil {
tSocket.SetErr(err)
return err
}
socket := tSocket.GetSocket()
// 创建二进制协议
protocol := thrift.NewTBinaryProtocolTransport(socket)
// 接口需要context,以便在长操作时用户可以取消 RPC 调用
 ctx  := context.Background()
// DynamicTService 为thrift 服务
dynamicProtocol := thrift.NewTMultiplexedProtocol(protocol, "DynamicTService")
// 创建代理客户端,使用TMultiplexedProtocol访问对应的服务
c := thrift.NewTStandardClient(dynamicProtocol, dynamicProtocol)
client :=DynamicTService.NewDynamicTServiceClient(c)
// 调用具体的方法
if list, err := client.DynamicExtraInfo(ctx, int64(uid), dynamicIdList); err == nil {
dynamicInfoList = list
} else {
return err
}