golang轻量级单文件HTTP服务器模板插件kickstart.go的使用
golang轻量级单文件HTTP服务器模板插件kickstart.go的使用
概述
kickstart.go是一个极简的Go语言HTTP服务器模板,具有以下特点:
- 代码量小(少于300行)
- 单文件实现
- 仅依赖标准库
这不是一个框架,而是构建Go语言HTTP服务的起点。该项目在GopherCon Korea 2024上首次展示。
主要特性
- 优雅关闭:处理
SIGINT
和SIGTERM
信号实现优雅关闭 - 健康检查端点:返回服务器健康状态,包括版本和修订信息
- OpenAPI端点:使用
embed
包提供OpenAPI规范 - 调试信息:提供各种调试指标,包括
pprof
和expvars
- 访问日志:使用
slog
记录HTTP请求详情 - 崩溃恢复:优雅地捕获和记录HTTP处理程序中的panic
- 完整文档:包含所有导出函数和类型的注释和文档
快速开始
要求
Go 1.22或更高版本
构建并运行服务器
$ make run
这将构建服务器并在8080端口上运行
端点说明
- GET /health: 返回服务健康状态,包括版本、修订和修改状态
- GET /openapi.yaml: 返回服务的OpenAPI规范
- GET /debug/pprof: 返回pprof调试信息
- GET /debug/vars: 返回expvars调试信息
完整示例代码
package main
import (
"context"
"embed"
"errors"
"flag"
"fmt"
"io/fs"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
//go:embed openapi.yaml
var openapiSpec embed.FS
func main() {
var port int
flag.IntVar(&port, "port", 8080, "HTTP server port")
flag.Parse()
// 创建HTTP服务器
srv := &http.Server{
Addr: fmt.Sprintf(":%d", port),
Handler: newRouter(),
}
// 优雅关闭处理
done := make(chan os.Signal, 1)
signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go func() {
slog.Info("Starting server", "port", port)
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
slog.Error("Server error", "error", err)
}
}()
<-done
slog.Info("Server is shutting down...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
slog.Error("Server shutdown error", "error", err)
}
slog.Info("Server stopped")
}
func newRouter() *http.ServeMux {
mux := http.NewServeMux()
// 健康检查端点
mux.HandleFunc("GET /health", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"status": "ok"}`))
})
// OpenAPI端点
mux.HandleFunc("GET /openapi.yaml", func(w http.ResponseWriter, r *http.Request) {
spec, _ := fs.ReadFile(openapiSpec, "openapi.yaml")
w.Header().Set("Content-Type", "text/yaml")
w.Write(spec)
})
// 调试端点
mux.HandleFunc("GET /debug/pprof/", func(w http.ResponseWriter, r *http.Request) {
http.DefaultServeMux.ServeHTTP(w, r)
})
mux.HandleFunc("GET /debug/vars", func(w http.ResponseWriter, r *http.Request) {
http.DefaultServeMux.ServeHTTP(w, r)
})
return mux
}
如何开始新项目
- 使用此模板创建新仓库
- 或者fork仓库并根据需要进行修改
- 查找并替换所有字符串
raeperd/kickstart.go
为你的仓库/镜像名称
如何移除所有注释
$ sed -i '' '/^\/\/go:embed/! {/^\s*\/\/.*$/d; /^\s*\/\*\*/,/\*\//d;}' *.go
参考
- GopherCon Korean 2024 Session (韩语)
- How I write HTTP services in Go after 13 years | Grafana Labs
更多关于golang轻量级单文件HTTP服务器模板插件kickstart.go的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang轻量级单文件HTTP服务器模板插件kickstart.go的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用 kickstart.go 创建轻量级 HTTP 服务器
kickstart.go 是一个简洁的 Go 语言单文件 HTTP 服务器模板,非常适合快速启动小型 Web 项目或 API 服务。下面我将详细介绍如何使用它。
基本使用方法
首先,获取 kickstart.go 文件(假设你已经有了这个模板文件),然后可以这样使用:
package main
import (
"fmt"
"net/http"
)
func main() {
// 设置路由
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "欢迎使用 kickstart.go HTTP 服务器!")
})
// 启动服务器
fmt.Println("服务器启动在 :8080...")
http.ListenAndServe(":8080", nil)
}
增强功能模板
下面是一个更完整的 kickstart.go 模板,包含常用功能:
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"time"
)
// 配置结构体
type Config struct {
Port string `json:"port"`
Env string `json:"env"`
Version string `json:"version"`
}
// 应用结构体
type Application struct {
Config Config
Logger *log.Logger
}
func main() {
// 初始化配置
cfg := Config{
Port: ":8080",
Env: "development",
Version: "1.0.0",
}
// 初始化应用
app := &Application{
Config: cfg,
Logger: log.New(log.Writer(), "kickstart: ", log.LstdFlags|log.Lshortfile),
}
// 设置路由
mux := http.NewServeMux()
mux.HandleFunc("/", app.homeHandler)
mux.HandleFunc("/api/data", app.dataHandler)
mux.HandleFunc("/health", app.healthHandler)
// 创建自定义服务器
srv := &http.Server{
Addr: cfg.Port,
Handler: app.logRequest(mux),
IdleTimeout: time.Minute,
ReadTimeout: 10 * time.Second,
WriteTimeout: 30 * time.Second,
}
// 启动服务器
app.Logger.Printf("启动 %s 服务器在 %s", cfg.Env, cfg.Port)
err := srv.ListenAndServe()
app.Logger.Fatal(err)
}
// 处理器函数
func (app *Application) homeHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
fmt.Fprintf(w, "欢迎使用 kickstart.go (v%s)", app.Config.Version)
}
func (app *Application) dataHandler(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{
"status": "success",
"message": "这是API数据",
"version": app.Config.Version,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(data)
}
func (app *Application) healthHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK"))
}
// 中间件:记录请求
func (app *Application) logRequest(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
app.Logger.Printf("%s %s %s %v", r.Method, r.URL.Path, r.RemoteAddr, time.Since(start))
})
}
功能特点
- 简洁结构:单文件包含所有必要组件
- 配置管理:使用结构体管理配置
- 日志记录:内置请求日志中间件
- 优雅超时:设置读写和空闲超时
- 路由处理:支持多个路由处理器
- JSON API:内置JSON响应支持
如何扩展
你可以根据需要添加以下功能:
- 添加数据库支持:
import "database/sql"
import _ "github.com/lib/pq"
// 在Application结构体中添加
type Application struct {
Config Config
Logger *log.Logger
DB *sql.DB
}
// 初始化数据库
db, err := sql.Open("postgres", "your-connection-string")
if err != nil {
log.Fatal(err)
}
app.DB = db
- 添加环境变量支持:
import "os"
// 在配置中
Port: getEnv("PORT", "8080"),
Env: getEnv("ENV", "development"),
// 辅助函数
func getEnv(key, defaultValue string) string {
if value, exists := os.LookupEnv(key); exists {
return value
}
return defaultValue
}
- 添加静态文件服务:
// 在路由设置中添加
fs := http.FileServer(http.Dir("./static"))
mux.Handle("/static/", http.StripPrefix("/static", fs))
这个 kickstart.go 模板提供了足够的基础功能,同时保持简洁,你可以根据项目需求轻松扩展它。