acquirePrewarmed 优先从预热池取出可用连接。
(addr string)
| 96 | |
| 97 | // acquirePrewarmed 优先从预热池取出可用连接。 |
| 98 | func acquirePrewarmed(addr string) (net.Conn, bool) { |
| 99 | poolAny, ok := prewarmPools.Load(addr) |
| 100 | if !ok { |
| 101 | return nil, false |
| 102 | } |
| 103 | pool := poolAny.(*prewarmPool) |
| 104 | pool.mu.Lock() |
| 105 | defer pool.mu.Unlock() |
| 106 | n := len(pool.idle) |
| 107 | if n == 0 { |
| 108 | pool.ensureLocked() |
| 109 | return nil, false |
| 110 | } |
| 111 | conn := pool.idle[n-1] |
| 112 | pool.idle = pool.idle[:n-1] |
| 113 | // 动态扩容逻辑: |
| 114 | // 需求:一旦“剩余预热可用连接” < desired 的 1/4,立即触发再次预热;新增数量 = 当前活跃使用中的连接数 * 2。 |
| 115 | // 当前活跃使用中的连接数近似估算:active = desired - idleLen(取出后) - warming |
| 116 | // 然后 desired += active*2 (至少 1),并受 prewarmPerTargetMax 限制。 |
| 117 | // 说明:这里不做回缩,保持简单;若未来需要收缩可添加基于空闲率的定时回收策略。 |
| 118 | remaining := len(pool.idle) // 取出后剩余 idle 数 |
| 119 | if pool.desired > 0 && remaining*4 < pool.desired { // 剩余 < 1/4 触发扩容 |
| 120 | oldDesired := pool.desired |
| 121 | active := pool.desired - remaining - pool.warming |
| 122 | if active < 0 { |
| 123 | active = 0 |
| 124 | } |
| 125 | growth := active * 2 |
| 126 | if growth < 1 { |
| 127 | growth = 1 |
| 128 | } |
| 129 | pool.desired += growth |
| 130 | if pool.desired > prewarmPerTargetMax { |
| 131 | pool.desired = prewarmPerTargetMax |
| 132 | } |
| 133 | utils.Logger.Debug("预热动态扩容", |
| 134 | zap.String("target", pool.addr), |
| 135 | zap.Int("remainingIdle", remaining), |
| 136 | zap.Int("activeApprox", active), |
| 137 | zap.Int("warming", pool.warming), |
| 138 | zap.Int("growth", growth), |
| 139 | zap.Int("oldDesired", oldDesired), |
| 140 | zap.Int("newDesired", pool.desired)) |
| 141 | } |
| 142 | pool.ensureLocked() |
| 143 | return conn, true |
| 144 | } |
| 145 | |
| 146 | // outboundDial 先尝试预热池,失败再发起新建连接。 |
| 147 | // 之前返回 (conn, usedFlag, error),由于当前不再区分来源,精简为 (conn, error)。 |
no test coverage detected