Golang Gin 中间件与监控服务健康控制器

本文介绍了如何使用 Gin 框架实现 Golang HTTP 服务器,重点介绍了健康检查控制器和超时中间件的集成,以增强系统可靠性和安全性。健康检查控制器通过 /api/v1/health 端点返回 “OK” 响应来确认服务的运行状态。超时中间件通过终止超过 60 秒的请求来缓解潜在的拒绝服务攻击。

在前一篇文章中,演示了一个简单的 Golang 项目。在我们目前的工作中,需要添加一个 Gin 中间件来处理超过 60 秒超时限制的请求。

简单的 Golang HTTP 服务器

健康控制器

在微服务架构中,健康控制器通常实现为一个简单的端点,返回 “OK” 响应,表明服务运行正常。这种机制被广泛用于监控各个服务的状态,确保系统可靠性。通过提供实时反馈,此类端点可帮助开发人员及时发现并解决问题。

Router.go

package app

func (a *Application) Routes() {
 api := a.Router.Group("/api/v1/")
 api.GET("/health", HealthHandler)
}
package app

import (
 "net/http"
 "time"

 "github.com/gin-gonic/gin"
)

func HealthHandler(c *gin.Context) {
 c.JSON(http.StatusOK, gin.H{
  "message": "OK",
 })
}

test.go

package test

import (
 "encoding/json"
 "io"
 "net/http"
 "testing"
 "time"

 application "go-simple/cmd/web/app"
)

func startTestServer() {
 a := application.New()
 a.Routes()
 a.StartServer()
 time.Sleep(200 * time.Millisecond) // 给服务器启动时间
}

func TestHealthEndpoint(t *testing.T) {
 t.Parallel()
 startTestServer()

 resp, err := http.Get("http://localhost:4000/api/v1/health")
 if err != nil {
  t.Fatalf("Failed to send GET request: %v", err)
 }
 defer resp.Body.Close()

 if resp.StatusCode != http.StatusOK {
  t.Errorf("Expected status 200 OK, got %d", resp.StatusCode)
 }

 body, err := io.ReadAll(resp.Body)
 if err != nil {
  t.Fatalf("Failed to read response body: %v", err)
 }

 // 解析 JSON
 var data map[string]string
 err = json.Unmarshal(body, &data)
 if err != nil {
  t.Fatalf("Expected JSON response, got error: %v", err)
 }

 // 验证消息
 message, ok := data["message"]
 if !ok {
  t.Fatalf("Missing 'message' field in response: %v", data)
 }
 if message != "OK" {
  t.Errorf("Expected message 'hello world', got '%s'", message)
 }
}

超时中间件

黑客常用的一种技术是发送大量处理请求来压垮系统。为了缓解这种情况,必须在 60 秒后终止连接。Gin 框架通过实现自动管理和关闭此类连接的中间件,有效地解决了这个问题,从而提高了系统安全性。

func (a *Application) Routes() {
 api := a.Router.Group("/api/v1/")
 api.GET("/slow", SlowHandler)
}
func SlowHandler(c *gin.Context) {
 // 模拟一个慢响应
 time.Sleep(70 * time.Second)
 c.JSON(http.StatusOK, gin.H{
  "message": "This is a slow response",
 })
}
func New() *Application {
 // 设置发布模式
 gin.SetMode(gin.DebugMode)

 // 如果你对内置程序感到满意,请使用 New() 进行完全控制,或者使用 Default()
 router := gin.New()

 // 显式添加中间件
 router.Use(gin.Logger())
 router.Use(gin.Recovery())
 router.Use(timeout.New(timeout.WithTimeout(60 * time.Second))) // 超时中间件

 port := os.Getenv("PORT")
 if port == "" {
  port = defaultPort
 }
 return &Application{Port: port, Router: router}
}

test.go

func startTestServer() {
 a := application.New()
 a.Routes()
 a.StartServer()
 time.Sleep(200 * time.Millisecond) // 给服务器启动时间
}
func TestSlowEndpoint(t *testing.T) {
 t.Parallel()
 startTestServer()

 resp, err := http.Get("http://localhost:4000/api/v1/slow")
 if err != nil {
  t.Fatalf("Failed to send GET request: %v", err)
 }
 defer resp.Body.Close()

 if resp.StatusCode != http.StatusRequestTimeout {
  t.Errorf("Expected status 408 OK, got %d", resp.StatusCode)
 }
}

GitHub 代码

feat: add Health controller and time out middleware · mobintmu/go-simple@a2ede81

结论

在本文中,我们探讨了使用 Gin 框架实现 Golang HTTP 服务器,重点介绍了健康控制器和超时中间件的集成,以增强系统可靠性和安全性。 健康控制器实现为一个简单的 /api/v1/health 端点,返回 “OK” 响应以确认服务的运行状态,这是微服务架构中监控的关键功能。 随附的测试通过验证响应状态和 JSON 有效负载来确保端点正常工作。 此外,我们引入了一个超时中间件,通过终止超过 60 秒的请求来减轻潜在的拒绝服务攻击,如 /api/v1/slow 端点所示。 该中间件与强大的测试相结合,确保服务器通过返回 408 Request Timeout 状态来适当地处理长时间的请求。 总之,这些组件——健康检查和超时处理——为构建安全可靠的 Golang 应用程序奠定了坚实的基础。 包含这些功能的完整代码可在 GitHub 存储库中找到,为旨在实现类似功能的开发人员提供了实用的参考。

  • 原文链接: blog.blockmagnates.com/g...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
blockmagnates
blockmagnates
The New Crypto Publication on The Block