package main import ( "log" "net/http" "net/http/httputil" "net/url" "os" "time" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" ) var serviceMap = map[string]string{ "/user/login": "http://user_login:80", "/user/register": "http://user_register:80", "/user/delete": "http://user_delete:80", "/user/update/account": "http://user_update_account:80", "/user/update/password": "http://user_update_password:80", } // 日志中间件(记录网关接收的请求) func loggerMiddleware() gin.HandlerFunc { return func(c *gin.Context) { startTime := time.Now() c.Next() endTime := time.Now() log.Printf( "[网关请求] %s %s | 状态码: %d | 耗时: %s | 客户端IP: %s", c.Request.Method, c.Request.URL.Path, c.Writer.Status(), endTime.Sub(startTime), c.ClientIP(), ) } } // 反向代理处理(添加详细转发日志) func reverseProxy(target string) gin.HandlerFunc { return func(c *gin.Context) { // 解析目标服务地址 targetURL, err := url.Parse(target) if err != nil { log.Printf("[代理错误] 目标服务地址解析失败: %s, 错误: %v", target, err) c.JSON(http.StatusInternalServerError, gin.H{ "success": false, "message": "服务配置错误", }) return } // 创建反向代理实例 proxy := httputil.NewSingleHostReverseProxy(targetURL) // 记录转发前的请求信息 reqStart := time.Now() log.Printf( "[开始转发] 方法: %s | 原始路径: %s | 目标服务: %s | 客户端IP: %s", c.Request.Method, c.Request.URL.Path, targetURL.String(), c.ClientIP(), ) // 自定义请求转发逻辑(并记录请求头) originalDirector := proxy.Director proxy.Director = func(req *http.Request) { originalDirector(req) // 传递关键头信息 req.Header.Set("Origin", c.Request.Header.Get("Origin")) req.Host = targetURL.Host req.Header.Set("X-Forwarded-By", "user-gateway") // 打印转发的请求头(调试用,生产环境可注释) log.Printf("[转发请求头] 目标服务: %s | Origin: %s | Host: %s", targetURL.Host, req.Header.Get("Origin"), req.Host, ) } // 记录响应信息 proxy.ModifyResponse = func(resp *http.Response) error { // 计算转发耗时 proxyDuration := time.Since(reqStart) // 打印响应状态 log.Printf( "[转发响应] 目标服务: %s | 状态码: %d | 耗时: %s | 响应头Origin: %s", targetURL.Host, resp.StatusCode, proxyDuration, resp.Header.Get("Access-Control-Allow-Origin"), ) return nil } // 执行代理转发 proxy.ServeHTTP(c.Writer, c.Request) } } func main() { r := gin.Default() // 注册日志中间件 r.Use(loggerMiddleware()) // 跨域配置 r.Use(cors.New(cors.Config{ AllowOrigins: []string{"*"}, AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"}, AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Authorization"}, ExposeHeaders: []string{"Content-Length"}, AllowCredentials: true, MaxAge: 12 * time.Hour, })) // 注册路由 for path, target := range serviceMap { r.Any(path, reverseProxy(target)) r.Any(path+"/*any", reverseProxy(target)) } // 启动服务 port := os.Getenv("GATEWAY_PORT") if port == "" { port = "80" } log.Printf("网关服务启动在 %s 端口", port) if err := r.Run(":" + port); err != nil { log.Fatalf("服务启动失败: %v", err) } }