连接池
- 思路:在高并发场景下,频繁创建和销毁TCP连接会带来较大开销。使用连接池可以复用已有的连接,减少连接建立和关闭的开销,从而提高服务器性能。
- 具体实现:
- Go语言标准库中的
net/http
包默认已经对HTTP连接进行了一定程度的优化,如HTTP/1.1的持久连接。但对于更复杂的场景,可以使用第三方库如go-pool
来实现自定义连接池。例如,创建一个数据库连接池:
package main
import (
"database/sql"
"fmt"
"github.com/coocood/freecache"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/test")
if err != nil {
panic(err.Error())
}
defer db.Close()
// 设置最大打开连接数
db.SetMaxOpenConns(100)
// 设置最大空闲连接数
db.SetMaxIdleConns(20)
// 测试连接
err = db.Ping()
if err != nil {
panic(err.Error())
}
fmt.Println("Connected to the database!")
}
协程调度
- 思路:Go语言的协程(goroutine)是轻量级的线程,在高并发场景下,合理调度协程可以充分利用系统资源。通过控制协程的数量避免过度创建协程导致的资源耗尽,同时利用
sync
包中的工具来实现协程间的同步和通信。
- 具体实现:
- 使用
sync.WaitGroup
来等待一组协程完成任务。例如,处理多个HTTP请求:
package main
import (
"fmt"
"net/http"
"sync"
)
func handler(w http.ResponseWriter, r *http.Request) {
// 处理请求逻辑
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", handler)
var wg sync.WaitGroup
numWorkers := 10
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
http.ListenAndServe(":8080", nil)
}()
}
wg.Wait()
}
缓存机制
- 思路:在HTTP服务器中,缓存可以减少对后端数据源的访问次数,提高响应速度。可以对经常访问的静态资源(如图片、CSS、JS文件)以及动态生成但不常变化的数据进行缓存。
- 具体实现:
- 对于静态资源,Go语言的
net/http
包提供了http.FileServer
来实现简单的静态文件服务器,并且可以设置适当的缓存头(如Cache-Control
)。
package main
import (
"net/http"
)
func main() {
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
http.ListenAndServe(":8080", nil)
}
- 对于动态数据缓存,可以使用第三方库如`freecache`。例如:
package main
import (
"fmt"
"github.com/coocood/freecache"
)
func main() {
cache := freecache.NewCache(1024 * 1024) // 1MB缓存
key := []byte("test_key")
value := []byte("test_value")
cache.Set(key, value, 0)
val, err := cache.Get(key)
if err == nil {
fmt.Println(string(val))
}
}