删除请求超时
This commit is contained in:
+2
-2
@@ -27,7 +27,7 @@ OT_MASTER_KEY=change-me-master-key
|
||||
OT_PROXY_UPSTREAM_KEY=
|
||||
OT_PROXY_UPSTREAM_BASE_URL=https://api.openai.com
|
||||
OT_PROXY_DEFAULT_MODEL=gpt-4o-mini
|
||||
OT_PROXY_TIMEOUT=120s
|
||||
OT_PROXY_TIMEOUT=300s
|
||||
|
||||
# 渠道健康检查
|
||||
OT_PROXY_HEALTH_INTERVAL=60s
|
||||
@@ -50,4 +50,4 @@ OT_ADMIN_EMAIL=admin@localhost
|
||||
OT_ADMIN_PASSWORD=admin123
|
||||
|
||||
# 记录原始请求日志
|
||||
OT_PROXY_LOG_RAW=false
|
||||
OT_PROXY_LOG_RAW=false
|
||||
|
||||
@@ -31,7 +31,7 @@ func serve() error {
|
||||
}
|
||||
defer a.Shutdown(context.Background())
|
||||
|
||||
gw := proxy.NewGateway(a.DB, a.Enc, a.Usage, a.Limit, cfg.RateLimit.UserRPS, cfg.Proxy.LogRaw)
|
||||
gw := proxy.NewGateway(a.DB, a.Enc, a.Usage, a.Limit, cfg.RateLimit.UserRPS, cfg.Proxy.LogRaw, cfg.Proxy.Timeout)
|
||||
router := api.NewRouter(a, gw)
|
||||
|
||||
srv := &http.Server{
|
||||
@@ -59,4 +59,4 @@ func serve() error {
|
||||
}
|
||||
a.Usage.Close()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,14 +59,14 @@ type AuthConfig struct {
|
||||
}
|
||||
|
||||
type ProxyConfig struct {
|
||||
DefaultChannelName string // 首次启动自动创建的渠道名(如 openai)
|
||||
UpstreamBaseURL string // 渠道 base_url 默认值
|
||||
UpstreamKey string // 渠道上游 key 默认值
|
||||
DefaultModel string // 渠道模型导入时使用的模型名
|
||||
Timeout time.Duration
|
||||
HealthInterval time.Duration // 渠道健康检查周期
|
||||
HealthFailThreshold int // 连续失败 N 次进 cooldown
|
||||
LogRaw bool // 记录管理员原始请求体+响应到 usage_logs(调试用,默认关)
|
||||
DefaultChannelName string // 首次启动自动创建的渠道名(如 openai)
|
||||
UpstreamBaseURL string // 渠道 base_url 默认值
|
||||
UpstreamKey string // 渠道上游 key 默认值
|
||||
DefaultModel string // 渠道模型导入时使用的模型名
|
||||
Timeout time.Duration
|
||||
HealthInterval time.Duration // 渠道健康检查周期
|
||||
HealthFailThreshold int // 连续失败 N 次进 cooldown
|
||||
LogRaw bool // 记录管理员原始请求体+响应到 usage_logs(调试用,默认关)
|
||||
}
|
||||
|
||||
// loadDotEnv 读取 .env 并把 KEY=VALUE 注入环境变量(AutomaticEnv 自动映射 OT_ 前缀)。
|
||||
@@ -127,7 +127,7 @@ func Load() (*Config, error) {
|
||||
v.SetDefault("proxy.upstream_base_url", "https://api.openai.com")
|
||||
v.SetDefault("proxy.upstream_key", "")
|
||||
v.SetDefault("proxy.default_model", "gpt-4o-mini")
|
||||
v.SetDefault("proxy.timeout", "120s")
|
||||
v.SetDefault("proxy.timeout", "300s")
|
||||
v.SetDefault("proxy.health_interval", "60s")
|
||||
v.SetDefault("proxy.health_fail_threshold", 2)
|
||||
v.SetDefault("proxy.log_raw", false)
|
||||
|
||||
@@ -109,7 +109,7 @@ func contains(list []string, s string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func NewGateway(db *gorm.DB, enc *crypto.Encryptor, rec *usage.Recorder, lim *ratelimit.Limiter, userRPS int, logRaw bool) *Gateway {
|
||||
func NewGateway(db *gorm.DB, enc *crypto.Encryptor, rec *usage.Recorder, lim *ratelimit.Limiter, userRPS int, logRaw bool, gw_timeout time.Duration) *Gateway {
|
||||
return &Gateway{
|
||||
db: db,
|
||||
ch: channel.NewService(db, enc),
|
||||
@@ -118,7 +118,7 @@ func NewGateway(db *gorm.DB, enc *crypto.Encryptor, rec *usage.Recorder, lim *ra
|
||||
lim: lim,
|
||||
userRPS: userRPS,
|
||||
logRaw: logRaw,
|
||||
hc: &http.Client{Timeout: 120 * time.Second},
|
||||
hc: &http.Client{Timeout: gw_timeout * time.Second},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,10 +272,10 @@ func upstreamPath(proto string) string {
|
||||
|
||||
// upstreamPlan 描述一次代理请求的上游访问方式。
|
||||
type upstreamPlan struct {
|
||||
proto string // 上游协议(用于分协议 base_url)
|
||||
path string // 上游路径
|
||||
body []byte // 已转换的请求体
|
||||
lineConv func([]byte) []byte // 流式逐行转换(nil=直通)
|
||||
proto string // 上游协议(用于分协议 base_url)
|
||||
path string // 上游路径
|
||||
body []byte // 已转换的请求体
|
||||
lineConv func([]byte) []byte // 流式逐行转换(nil=直通)
|
||||
bodyConv func([]byte) ([]byte, error) // 非流式响应体转换(nil=直通)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package proxy
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
@@ -218,9 +217,7 @@ func (g *Gateway) proxyOne(c *gin.Context, ch *store.Channel, plan *upstreamPlan
|
||||
}
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(c.Request.Context(), time.Duration(ch.TimeoutMS)*time.Millisecond)
|
||||
defer cancel()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, upstreamURL(ch, plan.proto, plan.path), bytes.NewReader(upBody))
|
||||
req, err := http.NewRequest(http.MethodPost, upstreamURL(ch, plan.proto, plan.path), bytes.NewReader(upBody))
|
||||
if err != nil {
|
||||
return false, false, http.StatusInternalServerError, []byte("failed to build upstream request")
|
||||
}
|
||||
@@ -242,9 +239,6 @@ func (g *Gateway) proxyOne(c *gin.Context, ch *store.Channel, plan *upstreamPlan
|
||||
start := time.Now()
|
||||
resp, err := g.hc.Do(req)
|
||||
if err != nil {
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
return false, true, http.StatusGatewayTimeout, []byte("upstream request timed out")
|
||||
}
|
||||
return false, true, http.StatusBadGateway, []byte("upstream request failed: " + err.Error())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
Reference in New Issue
Block a user