//go:build ignore // +build ignore package main import ( "encoding/json" "fmt" "log" "math/rand" "net/http" "os" "sync/atomic" "time" ) // 统计计数器 var ( totalRequests int64 successRequests int64 failedRequests int64 startTime time.Time fastMode bool // 快速模式:低延迟 ) // GatewayResponse 模拟网关响应 type GatewayResponse struct { Code int `json:"code"` Msg string `json:"msg"` TraceID string `json:"traceId"` Data json.RawMessage `json:"data"` } func main() { startTime = time.Now() rand.Seed(time.Now().UnixNano()) // 检查是否启用快速模式 if os.Getenv("FAST_MODE") == "1" || os.Getenv("FAST_MODE") == "true" { fastMode = true fmt.Println("⚡ 快速模式已启用(延迟: 10-50ms)") } else { fmt.Println("🐢 真实模式(延迟: 200ms-4s)") fmt.Println(" 提示: 设置 FAST_MODE=1 可启用快速模式") } // 实名查询接口(匹配 gateway client 的路径) http.HandleFunc("/flow-card/realName", handleRealnameQuery) // 流量查询接口 http.HandleFunc("/flow-card/flow", handleFlowQuery) // 停机接口 http.HandleFunc("/flow-card/cardStop", handleStopCard) // 复机接口 http.HandleFunc("/flow-card/cardStart", handleStartCard) // 卡状态查询接口 http.HandleFunc("/flow-card/status", handleCardStatus) // 统计接口 http.HandleFunc("/stats", handleStats) fmt.Println("=== Mock Gateway 服务器启动 ===") fmt.Println("监听端口: 8888") fmt.Println("模拟响应时间: 200ms - 4s") fmt.Println("") fmt.Println("接口列表:") fmt.Println(" POST /flow-card/realName - 实名查询") fmt.Println(" POST /flow-card/flow - 流量查询") fmt.Println(" POST /flow-card/status - 卡状态查询") fmt.Println(" POST /flow-card/cardStop - 停机操作") fmt.Println(" POST /flow-card/cardStart - 复机操作") fmt.Println(" GET /stats - 查看统计") fmt.Println("") fmt.Println("按 Ctrl+C 停止服务器") log.Fatal(http.ListenAndServe(":8888", nil)) } // simulateLatency 模拟网络延迟 func simulateLatency() { var delay time.Duration if fastMode { // 快速模式:10-50ms delay = time.Duration(10+rand.Intn(40)) * time.Millisecond } else { // 真实模式:200ms - 4s // 80% 概率 200-500ms(正常) // 15% 概率 500ms-2s(较慢) // 5% 概率 2s-4s(很慢) r := rand.Float64() if r < 0.80 { delay = time.Duration(200+rand.Intn(300)) * time.Millisecond } else if r < 0.95 { delay = time.Duration(500+rand.Intn(1500)) * time.Millisecond } else { delay = time.Duration(2000+rand.Intn(2000)) * time.Millisecond } } time.Sleep(delay) } // handleRealnameQuery 处理实名查询 func handleRealnameQuery(w http.ResponseWriter, r *http.Request) { atomic.AddInt64(&totalRequests, 1) simulateLatency() // 90% 成功,10% 失败 if rand.Float64() < 0.90 { atomic.AddInt64(&successRequests, 1) // 随机返回实名状态(匹配文档:realStatus 为 bool 类型) realStatus := rand.Float64() < 0.5 resp := GatewayResponse{ Code: 200, Msg: "success", TraceID: fmt.Sprintf("trace-%d", time.Now().UnixNano()), Data: json.RawMessage(fmt.Sprintf(`{"iccid": "mock-iccid", "realStatus": %t}`, realStatus)), } json.NewEncoder(w).Encode(resp) } else { atomic.AddInt64(&failedRequests, 1) resp := GatewayResponse{ Code: 500, Msg: "upstream error", TraceID: fmt.Sprintf("trace-%d", time.Now().UnixNano()), } json.NewEncoder(w).Encode(resp) } } // handleFlowQuery 处理流量查询 func handleFlowQuery(w http.ResponseWriter, r *http.Request) { atomic.AddInt64(&totalRequests, 1) simulateLatency() if rand.Float64() < 0.90 { atomic.AddInt64(&successRequests, 1) // 随机返回流量数据(匹配文档:used 字段) usedFlow := rand.Intn(10000) resp := GatewayResponse{ Code: 200, Msg: "success", TraceID: fmt.Sprintf("trace-%d", time.Now().UnixNano()), Data: json.RawMessage(fmt.Sprintf(`{"iccid": "mock-iccid", "used": %d, "unit": "MB"}`, usedFlow)), } json.NewEncoder(w).Encode(resp) } else { atomic.AddInt64(&failedRequests, 1) resp := GatewayResponse{ Code: 500, Msg: "upstream error", TraceID: fmt.Sprintf("trace-%d", time.Now().UnixNano()), } json.NewEncoder(w).Encode(resp) } } // handleStopCard 处理停机操作 func handleStopCard(w http.ResponseWriter, r *http.Request) { atomic.AddInt64(&totalRequests, 1) simulateLatency() if rand.Float64() < 0.95 { atomic.AddInt64(&successRequests, 1) resp := GatewayResponse{ Code: 200, Msg: "success", TraceID: fmt.Sprintf("trace-%d", time.Now().UnixNano()), Data: json.RawMessage(`{"result": "stopped"}`), } json.NewEncoder(w).Encode(resp) } else { atomic.AddInt64(&failedRequests, 1) resp := GatewayResponse{ Code: 500, Msg: "stop failed", TraceID: fmt.Sprintf("trace-%d", time.Now().UnixNano()), } json.NewEncoder(w).Encode(resp) } } // handleStartCard 处理复机操作 func handleStartCard(w http.ResponseWriter, r *http.Request) { atomic.AddInt64(&totalRequests, 1) simulateLatency() if rand.Float64() < 0.95 { atomic.AddInt64(&successRequests, 1) resp := GatewayResponse{ Code: 200, Msg: "success", TraceID: fmt.Sprintf("trace-%d", time.Now().UnixNano()), Data: json.RawMessage(`{"result": "started"}`), } json.NewEncoder(w).Encode(resp) } else { atomic.AddInt64(&failedRequests, 1) resp := GatewayResponse{ Code: 500, Msg: "start failed", TraceID: fmt.Sprintf("trace-%d", time.Now().UnixNano()), } json.NewEncoder(w).Encode(resp) } } // handleCardStatus 处理卡状态查询 func handleCardStatus(w http.ResponseWriter, r *http.Request) { atomic.AddInt64(&totalRequests, 1) simulateLatency() if rand.Float64() < 0.90 { atomic.AddInt64(&successRequests, 1) // 随机返回卡状态:1-正常,0-停机 cardStatus := rand.Intn(2) resp := GatewayResponse{ Code: 200, Msg: "success", TraceID: fmt.Sprintf("trace-%d", time.Now().UnixNano()), Data: json.RawMessage(fmt.Sprintf(`{"status": %d}`, cardStatus)), } json.NewEncoder(w).Encode(resp) } else { atomic.AddInt64(&failedRequests, 1) resp := GatewayResponse{ Code: 500, Msg: "query failed", TraceID: fmt.Sprintf("trace-%d", time.Now().UnixNano()), } json.NewEncoder(w).Encode(resp) } } // handleStats 返回统计信息 func handleStats(w http.ResponseWriter, r *http.Request) { elapsed := time.Since(startTime).Seconds() total := atomic.LoadInt64(&totalRequests) success := atomic.LoadInt64(&successRequests) failed := atomic.LoadInt64(&failedRequests) qps := float64(total) / elapsed successRate := float64(0) if total > 0 { successRate = float64(success) * 100 / float64(total) } stats := map[string]interface{}{ "uptime_seconds": elapsed, "total_requests": total, "success_count": success, "failed_count": failed, "qps": qps, "success_rate": fmt.Sprintf("%.2f%%", successRate), } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(stats) }