缓冲区设置
- 发送缓冲区:适当增大发送缓冲区可以减少系统调用次数,提高发送效率。在Go语言的
net.Conn
接口中,SetWriteBuffer
方法可用于设置发送缓冲区大小。例如:
package main
import (
"fmt"
"net"
)
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:8080")
if err != nil {
fmt.Println("Dial error:", err)
return
}
defer conn.Close()
err = conn.(*net.TCPConn).SetWriteBuffer(32 * 1024) // 设置发送缓冲区为32KB
if err != nil {
fmt.Println("SetWriteBuffer error:", err)
return
}
// 发送数据逻辑
}
- 接收缓冲区:通过
SetReadBuffer
方法设置接收缓冲区大小,能更好地接收数据,减少丢包可能性。示例如下:
package main
import (
"fmt"
"net"
)
func main() {
listener, err := net.Listen("tcp", "127.0.0.1:8080")
if err != nil {
fmt.Println("Listen error:", err)
return
}
defer listener.Close()
conn, err := listener.Accept()
if err != nil {
fmt.Println("Accept error:", err)
return
}
defer conn.Close()
err = conn.(*net.TCPConn).SetReadBuffer(32 * 1024) // 设置接收缓冲区为32KB
if err != nil {
fmt.Println("SetReadBuffer error:", err)
return
}
// 接收数据逻辑
}
goroutine调度优化
- 控制goroutine数量:高并发场景下,过多的goroutine会导致调度开销增大。可以使用
sync.WaitGroup
和channel
来限制同时运行的goroutine数量。例如:
package main
import (
"fmt"
"sync"
)
func worker(id int, wg *sync.WaitGroup, sem chan struct{}) {
defer wg.Done()
sem <- struct{}{} // 获取信号量
fmt.Printf("Worker %d is working\n", id)
// 模拟工作
<-sem // 释放信号量
}
func main() {
var wg sync.WaitGroup
sem := make(chan struct{}, 10) // 最多允许10个goroutine同时运行
for i := 0; i < 100; i++ {
wg.Add(1)
go worker(i, &wg, sem)
}
wg.Wait()
}
- 使用无锁数据结构:在goroutine间共享数据时,无锁数据结构(如
sync.Map
)可以减少锁争用,提高性能。例如:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
m := sync.Map{}
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
m.Store(id, id*id)
}(i)
}
wg.Wait()
m.Range(func(key, value interface{}) bool {
fmt.Printf("Key: %d, Value: %d\n", key, value)
return true
})
}
连接复用
- TCP连接池:使用连接池可以避免频繁创建和销毁TCP连接的开销。可以通过实现一个简单的连接池来复用连接。例如:
package main
import (
"fmt"
"net"
"sync"
)
type ConnectionPool struct {
pool chan net.Conn
address string
}
func NewConnectionPool(address string, size int) *ConnectionPool {
pool := make(chan net.Conn, size)
for i := 0; i < size; i++ {
conn, err := net.Dial("tcp", address)
if err != nil {
fmt.Println("Dial error:", err)
continue
}
pool <- conn
}
return &ConnectionPool{
pool: pool,
address: address,
}
}
func (cp *ConnectionPool) Get() net.Conn {
select {
case conn := <-cp.pool:
return conn
default:
conn, err := net.Dial("tcp", cp.address)
if err != nil {
fmt.Println("Dial error:", err)
return nil
}
return conn
}
}
func (cp *ConnectionPool) Put(conn net.Conn) {
select {
case cp.pool <- conn:
default:
conn.Close()
}
}
网络优化
- 使用TCP_NODELAY:禁用Nagle算法,让数据立即发送,减少延迟。在Go语言中,通过
SetNoDelay
方法实现。例如:
package main
import (
"fmt"
"net"
)
func main() {
listener, err := net.Listen("tcp", "127.0.0.1:8080")
if err != nil {
fmt.Println("Listen error:", err)
return
}
defer listener.Close()
conn, err := listener.Accept()
if err != nil {
fmt.Println("Accept error:", err)
return
}
defer conn.Close()
err = conn.(*net.TCPConn).SetNoDelay(true) // 禁用Nagle算法
if err != nil {
fmt.Println("SetNoDelay error:", err)
return
}
// 数据处理逻辑
}