cHttpServerStatistics 性能统计
简介
cHttpServerStatistics 是 HttpServer 的服务器级性能统计容器,通过 Public Long 字段实现零开销递增——无 Dictionary 查找、无 Property 调用,适合高频热路径埋点。
全局唯一实例,在 cHttpServer.Class_Initialize 中创建,通过两种途径访问:
' 方式一:通过 Server 对象(服务端生命周期内始终可用)
Server.Statistics.TotalRequests
' 方式二:通过请求上下文(控制器/中间件中使用更自然)
ctx.Statistics.TotalRequests两者指向同一个对象实例,ctx.Statistics 仅在 ProcessHttpRequest 中做了 Set .Statistics = Statistics 引用赋值,无额外开销。
生命周期说明:Statistics 是服务器级单例,
cHttpServerContext.ReleaseRequest和Release均不释放此引用。
字段一览
请求统计
| 字段 | 类型 | 说明 |
|---|---|---|
TotalRequests | Long | 累计请求总数(含正常和异常) |
GetRequests | Long | GET 请求数 |
PostRequests | Long | POST 请求数 |
PutRequests | Long | PUT 请求数 |
DeleteRequests | Long | DELETE 请求数 |
OptionsRequests | Long | OPTIONS 请求数 |
HeadRequests | Long | HEAD 请求数 |
PatchRequests | Long | PATCH 请求数 |
OtherRequests | Long | 上述以外方法的请求数 |
方法分类由 IncrementByMethod 内部完成,基于 cHttpServerRequest.EnumRequestMethod 枚举值:
| 枚举值 | 常量名 | 递增字段 |
|---|---|---|
| 1 | ReqPost | PostRequests |
| 2 | ReqGet | GetRequests |
| 3 | ReqPut | PutRequests |
| 4 | ReqDelete | DeleteRequests |
| 5 | ReqOptions | OptionsRequests |
| 6 | Head | HeadRequests |
| 7 | Patch | PatchRequests |
| 其他 | — | OtherRequests |
状态码统计
| 字段 | 类型 | 说明 |
|---|---|---|
Status1xx | Long | 1xx 响应数(Informational) |
Status2xx | Long | 2xx 响应数(Success) |
Status3xx | Long | 3xx 响应数(Redirection) |
Status4xx | Long | 4xx 响应数(Client Error) |
Status5xx | Long | 5xx 响应数(Server Error) |
状态码区间由 IncrementByStatusCode 内部完成,对传入的实际状态码整除 100 取百位分组。
前提:
cHttpServerResponse.StatusCode字段在SendHeader中赋值。如果响应未走到SendHeader(如连接已断开),StatusCode 为 0,此时不计入任何区间。
连接统计
| 字段 | 类型 | 说明 |
|---|---|---|
TotalConnectionsAccepted | Long | 累计接受的连接总数 |
RejectedConnections | Long | 因 MaxConnections 限制被拒绝的连接数 |
PeakConnections | Long | 峰值并发连接数 |
IdleConnectionsCleaned | Long | 因空闲超时被 CleanupIdleConnections 清理的连接数 |
错误统计
| 字段 | 类型 | 说明 |
|---|---|---|
RequestErrors | Long | 请求处理异常次数(ProcessHttpRequest 中 EH 路径) |
RequestSizeRejected | Long | 413 Payload Too Large 次数 |
SSEEntryErrors | Long | SSE Entry 失败次数(预留字段,当前版本未埋点) |
流量统计
| 字段 | 类型 | 说明 |
|---|---|---|
TotalBytesReceived | Long | 累计接收字节数 |
TotalBytesSent | Long | 累计发送字节数 |
当前状态:字段已预留,尚未在
cClientCallback.OnDataArrival和cHttpServerResponse.SendBodyByte中埋点。高流量场景下精确字节数采集可能影响性能,按需开启。
SSE 统计
| 字段 | 类型 | 说明 |
|---|---|---|
SSEConnectionsAccepted | Long | SSE 连接总数 |
Session 统计
| 字段 | 类型 | 说明 |
|---|---|---|
TotalSessionsCreated | Long | 累计创建的 Session 总数(仅 Session.HasID 的有效 Session) |
时间统计
| 字段 | 类型 | 说明 |
|---|---|---|
StartTime | Date | 服务器启动时间(Start 方法中赋值为 Now) |
计算属性
UptimeSeconds
服务器运行时长(秒)。
Public Property Get UptimeSeconds() As Long若 StartTime = 0(未启动),返回 0。
AverageQPS
每秒平均请求数。
Public Property Get AverageQPS() As Double计算方式:TotalRequests / UptimeSeconds。运行时长为 0 时返回 0。
Friend 方法
以下方法供 cHttpServer 内部调用,外部无需直接使用。
IncrementByMethod
按请求方法枚举值递增对应计数器。
Friend Sub IncrementByMethod(ByVal MethodValue As Long)映射关系见上方"请求统计"章节的枚举值表。
IncrementByStatusCode
按实际状态码递增对应区间计数器。
Friend Sub IncrementByStatusCode(ByVal StatusCode As Long)对 StatusCode \ 100 整除取百位,映射到 Status1xx~Status5xx。
UpdatePeakConnections
更新峰值连接数(仅在当前值大于历史峰值时更新)。
Friend Sub UpdatePeakConnections(ByVal CurrentCount As Long)Reset 方法
重置所有统计计数器为 0,StartTime 重置为 Now。
Public Sub Reset()示例:
' 每天零点重置统计
Server.Statistics.Reset埋点位置对照表
| 触发位置 | 统计字段 | 说明 |
|---|---|---|
ConnectionRequest 事件 | TotalConnectionsAccepted, PeakConnections, RejectedConnections | 新连接接入时 |
Start 方法 | StartTime = Now | 服务器启动时记录时间基线 |
| 413 路径(请求体超限) | RequestSizeRejected | OnDataArrival 检测超限 |
| SSE Entry 路径 | SSEConnectionsAccepted | SSE 长连接建立时 |
Router.Entry 之后 | TotalRequests, IncrementByMethod, IncrementByStatusCode | 路由完成后统计 |
Session.HasID 为 True | TotalSessionsCreated | 有效 Session 创建时 |
| EH 错误处理路径 | RequestErrors, TotalRequests | 异常也计入 TotalRequests |
CleanupIdleConnections | IdleConnectionsCleaned | 定时器或手动清理时 |
使用示例
监控接口
在控制器中暴露统计数据的 API 端点:
' GET /api/stats
Public Sub GetStats(ctx As cHttpServerContext)
Dim s As cHttpServerStatistics
Set s = ctx.Statistics
Dim result As New Scripting.Dictionary
' 请求指标
result("total_requests") = s.TotalRequests
result("get_requests") = s.GetRequests
result("post_requests") = s.PostRequests
' 状态码分布
result("status_2xx") = s.Status2xx
result("status_4xx") = s.Status4xx
result("status_5xx") = s.Status5xx
' 连接指标
result("current_connections") = ctx.Server.Parent.ConnectionCount
result("peak_connections") = s.PeakConnections
result("rejected_connections") = s.RejectedConnections
' 性能指标
result("uptime_seconds") = s.UptimeSeconds
result("average_qps") = s.AverageQPS
result("request_errors") = s.RequestErrors
ctx.Response.Json result, 0, "OK"
End Sub错误率告警
' 在中间件中检查错误率
Public Sub ErrorRateCheck(ctx As cHttpServerContext)
Dim s As cHttpServerStatistics
Set s = ctx.Statistics
If s.TotalRequests > 100 Then
Dim errorRate As Double
errorRate = (s.Status5xx + s.RequestErrors) / s.TotalRequests
If errorRate > 0.1 Then
' 5xx + 异常占比超过 10%,记录告警
Call WriteAlertLog("错误率过高: " & Format(errorRate, "0.00%"))
End If
End If
End Sub运行时间面板
Public Sub Dashboard(ctx As cHttpServerContext)
Dim s As cHttpServerStatistics
Set s = ctx.Statistics
Dim html As String
html = "<h1>服务器状态</h1>"
html = html & "<p>运行时间: " & s.UptimeSeconds & " 秒</p>"
html = html & "<p>总请求: " & s.TotalRequests & "</p>"
html = html & "<p>平均 QPS: " & Format(s.AverageQPS, "0.00") & "</p>"
html = html & "<p>峰值连接: " & s.PeakConnections & "</p>"
ctx.Response.Html html
End SubLong 溢出注意事项
VB6 的 Long 类型为 32 位有符号整数,上限 2,147,483,647。
| 场景 | QPS | 溢出时间 |
|---|---|---|
| 低流量 | 10 | ~6.8 年 |
| 中流量 | 100 | ~249 天 |
| 高流量 | 1,000 | ~24.9 天 |
| 极高流量 | 10,000 | ~2.5 天 |
建议:
- 高流量场景(QPS > 1000)下,定期调用
Reset或在达到阈值时记录快照后重置 - 监控接口读取时先检查
TotalRequests是否接近上限,接近时主动告警 - 如需更长区间累计,可在外部维护
Double类型的累加器,定期从TotalRequests读取增量
依赖关系
cHttpServer
│
├── Public Statistics As cHttpServerStatistics ← 服务器持有实例
│ ├── Public Long 字段 × 20+
│ ├── Property Get UptimeSeconds / AverageQPS
│ ├── Friend Sub IncrementByMethod / IncrementByStatusCode / UpdatePeakConnections
│ └── Public Sub Reset
│
└── ProcessHttpRequest
└── ctx.Statistics ──→ 同一实例引用cHttpServerResponse 新增 Public StatusCode As Long 字段,在 SendHeader 中赋值,为 IncrementByStatusCode 提供数据源。
最后更新: 2026-06-13