All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m25s
- polling_handler: Status→RealStatus, UsedFlow→Used, parseRealnameStatus 参数改为 bool - mock_gateway: 同步接口路径和响应结构与上游文档一致
264 lines
7.0 KiB
Go
264 lines
7.0 KiB
Go
//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)
|
||
}
|