package healthcheck import ( "encoding/json" "net/http" "time" ) // Response 是 gateway HTTP health endpoint 的稳定 JSON 契约。 type Response struct { Status string `json:"status"` Service string `json:"service"` NodeID string `json:"node_id"` TimeUnixMS int64 `json:"time_unix_ms"` Checks []Check `json:"checks,omitempty"` } // HTTPHandler 暴露 /healthz/live 和 /healthz/ready 两个只读入口。 type HTTPHandler struct { state *State } // NewHTTPHandler 创建 gateway health HTTP handler。 func NewHTTPHandler(state *State) *HTTPHandler { return &HTTPHandler{state: state} } // Live 返回进程自身是否仍可运行。 func (h *HTTPHandler) Live(writer http.ResponseWriter, request *http.Request) { checks := h.state.Live() statusCode := http.StatusOK if !Healthy(checks) { statusCode = http.StatusInternalServerError } h.write(writer, statusCode, checks) } // Ready 返回当前 gateway 实例是否可以接新 HTTP 请求。 func (h *HTTPHandler) Ready(writer http.ResponseWriter, request *http.Request) { checks := h.state.Ready(request.Context()) statusCode := http.StatusOK if !Healthy(checks) { statusCode = http.StatusServiceUnavailable } h.write(writer, statusCode, checks) } func (h *HTTPHandler) write(writer http.ResponseWriter, statusCode int, checks []Check) { status := componentStatus if !Healthy(checks) { status = failStatus } response := Response{ Status: status, Service: h.state.ServiceName(), NodeID: h.state.NodeID(), TimeUnixMS: time.Now().UnixMilli(), } if status != componentStatus { response.Checks = checks } writer.Header().Set("Content-Type", "application/json") writer.WriteHeader(statusCode) _ = json.NewEncoder(writer).Encode(response) }