简单tcp服务
源码
gitee: https://gitee.com/luyue_zhang/go_rpc_2/tree/master/tcp_server_demo
演示
连接池
在简单tcp服务中,每次请求耗费一个连接net.dial()。创建一个连接是昂贵的:
- 发起系统调用
- TCP三次握手
- 高并发场景可能耗尽文件描述符
所以我们可以考虑复用连接,实现连接池
连接池原理
取连接流程图

还连接流程图

源码
gitee: https://gitee.com/luyue_zhang/go_rpc_2/tree/master/conn_pool
说明:仅简单测试,未提供完备测试用例
思考
idleConnList(空闲队列)使用channel还是切片?
切片(并发阻塞队列) | channel | |
---|---|---|
并发控制 | 加锁 | 天然支持 |
性能 | 锁竞争就可能影响性能,但sql.DB就用的切片 // 影响可能还好 | 无锁设计,性能不错,适合高并发场景 |
阻塞机制 | 需要自行控制等待机制,如使用sync.Cond | 天然支持 |
代码灵活性 | 支持复杂管理,比如: 1. 遍历,处理过期连接 2. 连接健康检查,比如随机访问 3. 连接优先级、权重 4. 查看队首、队尾元素,判断出队时机 | FIFO,相较来说,支持简单操作 |
开源实现
sql.DB、silenceper