目录
Go 语言高性能网络编程:从 TCP/UDP 到 gRPC 的完整实战指南
作者:文文
Go 语言为什么适合网络编程?
Go 语言天生为并发和网络编程设计,具有以下核心优势:
核心优势
- 轻量级 Goroutine:可轻松创建数百万个并发任务
- 原生并发模型:channel 和 goroutine 的完美配合
- 高效的调度器:M:N 调度模型,充分利用多核 CPU
- 内置网络库:net、net/http 等标准库功能完整
- 快速编译:编译为静态二进制文件,部署简单
TCP 编程基础
创建 TCP 服务器
package main
import (
"fmt"
"net"
)
func handleConnection(conn net.Conn) {
defer conn.Close()
buffer := make([]byte, 1024)
for {
n, err := conn.Read(buffer)
if err != nil {
return
}
// 回显数据
conn.Write(buffer[:n])
}
}
func main() {
listener, _ := net.Listen("tcp", ":8000")
defer listener.Close()
fmt.Println("Server listening on :8000")
for {
conn, _ := listener.Accept()
// 每个连接用独立的 goroutine 处理
go handleConnection(conn)
}
}
性能优化
- 缓冲池:复用 buffer,减少 GC 压力
var bufferPool = sync.Pool{
New: func() interface{} {
return make([]byte, 1024)
},
}
- 连接池:维护可复用的连接
- 批量处理:将多个请求合并处理
gRPC 高性能 RPC 框架
定义服务 (proto3)
syntax = "proto3";
package user;
service UserService {
rpc GetUser(UserRequest) returns (UserResponse);
rpc ListUsers(Empty) returns (stream UserResponse);
}
message UserRequest {
int32 id = 1;
}
message UserResponse {
int32 id = 1;
string name = 2;
string email = 3;
}
message Empty {}
实现服务
type UserServiceServer struct {}
func (s *UserServiceServer) GetUser(ctx context.Context, req *UserRequest) (*UserResponse, error) {
return &UserResponse{
Id: req.Id,
Name: "Alice",
Email: "alice@example.com",
}, nil
}
func main() {
lis, _ := net.Listen("tcp", ":50051")
s := grpc.NewServer()
user.RegisterUserServiceServer(s, &UserServiceServer{})
s.Serve(lis)
}
gRPC 的性能优势
| 特性 | HTTP/1.1 | gRPC |
|---|---|---|
| 协议 | 文本 | 二进制 (Protocol Buffers) |
| 多路复用 | ✗ | ✓ |
| 推送 | ✗ | ✓ (Server Push) |
| 性能 | 一般 | 高效 |
| 吞吐量 | 低 | 高 |
WebSocket 实时通信
import "github.com/gorilla/websocket"
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func handleWebSocket(w http.ResponseWriter, r *http.Request) {
conn, _ := upgrader.Upgrade(w, r, nil)
defer conn.Close()
for {
messageType, data, _ := conn.ReadMessage()
// 处理消息
conn.WriteMessage(messageType, data)
}
}
func main() {
http.HandleFunc("/ws", handleWebSocket)
http.ListenAndServe(":8000", nil)
}
性能监控与优化
使用 pprof 分析性能
import _ "net/http/pprof"
func main() {
// 后台运行 pprof 服务
go func() {
http.ListenAndServe(":6060", nil)
}()
// 主服务
}
访问 http://localhost:6060/debug/pprof/ 查看性能数据。
CPU 和内存优化
- 减少内存分配:使用对象池
- 避免 Goroutine 泄漏:确保所有 goroutine 都会退出
- 合理的缓冲区大小:不要过大也不要过小
- 批量提交:减少系统调用次数
最佳实践
- 超时控制:为所有网络操作设置超时
- 错误处理:正确处理网络错误
- 日志记录:记录关键操作和错误
- 优雅关闭:正确关闭连接和资源
- 负载均衡:分散流量,避免单点瓶颈
文文,2026 年 3 月 16 日
