diff --git a/CHANGELOG.md b/CHANGELOG.md index f7d0c6f..979cb00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # 更新日志 +3.0.1 -2025-04-08 +--- +- CHANGE: 加入`memLimit`指示gc +- CHANGE: 加入`hlog`输出路径配置 +- CHANGE: 修正H2C配置问题 + +25w27a - 2025-04-07 +--- +- PRE-RELEASE: 此版本是v3.0.1的预发布版本,请勿在生产环境中使用; +- CHANGE: 加入`memLimit`指示gc +- CHANGE: 加入`hlog`输出路径配置 +- CHANGE: 修正H2C配置问题 + 3.0.0 - 2025-04-04 --- - RELEASE: Next Gen; 下一个起点; diff --git a/DEV-VERSION b/DEV-VERSION index ae7572d..03ab3b3 100644 --- a/DEV-VERSION +++ b/DEV-VERSION @@ -1 +1 @@ -25w26a \ No newline at end of file +25w27a \ No newline at end of file diff --git a/VERSION b/VERSION index 56fea8a..13d683c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0 \ No newline at end of file +3.0.1 \ No newline at end of file diff --git a/config/config.go b/config/config.go index 1ec7707..1bf1bdc 100644 --- a/config/config.go +++ b/config/config.go @@ -32,6 +32,7 @@ type ServerConfig struct { Port int `toml:"port"` Host string `toml:"host"` SizeLimit int `toml:"sizeLimit"` + MemLimit int64 `toml:"memLimit"` H2C bool `toml:"H2C"` Cors string `toml:"cors"` Debug bool `toml:"debug"` @@ -86,9 +87,10 @@ type PagesConfig struct { } type LogConfig struct { - LogFilePath string `toml:"logFilePath"` - MaxLogSize int `toml:"maxLogSize"` - Level string `toml:"level"` + LogFilePath string `toml:"logFilePath"` + MaxLogSize int `toml:"maxLogSize"` + Level string `toml:"level"` + HertZLogPath string `toml:"hertzLogPath"` } /* @@ -179,6 +181,7 @@ func DefaultConfig() *Config { Port: 8080, Host: "0.0.0.0", SizeLimit: 125, + MemLimit: 0, H2C: true, Cors: "*", Debug: false, @@ -204,9 +207,10 @@ func DefaultConfig() *Config { StaticDir: "/data/www", }, Log: LogConfig{ - LogFilePath: "/data/ghproxy/log/ghproxy.log", - MaxLogSize: 10, - Level: "info", + LogFilePath: "/data/ghproxy/log/ghproxy.log", + MaxLogSize: 10, + Level: "info", + HertZLogPath: "/data/ghproxy/log/hertz.log", }, Auth: AuthConfig{ Enabled: false, diff --git a/config/config.toml b/config/config.toml index ef27c6d..92b81f8 100644 --- a/config/config.toml +++ b/config/config.toml @@ -2,6 +2,7 @@ host = "0.0.0.0" port = 8080 sizeLimit = 125 # MB +memLimit = 0 # MB H2C = true cors = "*" # "*"/"" -> "*" ; "nil" -> "" ; debug = false @@ -30,6 +31,7 @@ staticDir = "/data/www" logFilePath = "/data/ghproxy/log/ghproxy.log" maxLogSize = 5 # MB level = "info" # dump, debug, info, warn, error, none +hertzLogPath = "/data/ghproxy/log/hertz.log" [auth] method = "parameters" # "header" or "parameters" diff --git a/deploy/config.toml b/deploy/config.toml index 1c7e69a..a25acf1 100644 --- a/deploy/config.toml +++ b/deploy/config.toml @@ -2,6 +2,7 @@ host = "127.0.0.1" port = 8080 sizeLimit = 125 # MB +memLimit = 0 # MB H2C = true cors = "*" # "*"/"" -> "*" ; "nil" -> "" ; debug = false @@ -30,6 +31,7 @@ staticDir = "/usr/local/ghproxy/pages" logFilePath = "/usr/local/ghproxy/log/ghproxy.log" maxLogSize = 5 # MB level = "info" # dump, debug, info, warn, error, none +hertzLogPath = "/usr/local/ghproxy/log/hertz.log" [auth] authMethod = "parameters" # "header" or "parameters" diff --git a/docs/config.md b/docs/config.md index a9cb18f..ccd1ce2 100644 --- a/docs/config.md +++ b/docs/config.md @@ -13,6 +13,7 @@ host = "0.0.0.0" port = 8080 sizeLimit = 125 # MB +memLimit = 0 # MB H2C = true cors = "*" # "*"/"" -> "*" ; "nil" -> "" ; debug = false @@ -41,6 +42,7 @@ staticDir = "/data/www" logFilePath = "/data/ghproxy/log/ghproxy.log" maxLogSize = 5 # MB level = "info" # dump, debug, info, warn, error, none +hertzLogPath = "/data/ghproxy/log/hertz.log" [auth] method = "parameters" # "header" or "parameters" @@ -85,6 +87,10 @@ url = "socks5://127.0.0.1:1080" # "http://127.0.0.1:7890" * 类型: 整数 (`int`) * 默认值: `125` (MB) * 说明: 限制允许接收的请求体最大大小,单位为 MB。用于防止过大的请求导致服务压力过大。 + * `memLimit`: `runtime`内存限制 + * 类型: 整数 (`int64`) + * 默认值: `0` (不传入) + * 说明: 给`runtime`的指标, 让gc行为更高效 * `H2C`: 是否启用 H2C (HTTP/2 Cleartext) 传输。 * 类型: 布尔值 (`bool`) * 默认值: `true` (启用) @@ -193,6 +199,10 @@ url = "socks5://127.0.0.1:1080" # "http://127.0.0.1:7890" * `"warn"`: 输出警告和错误日志。 * `"error"`: 仅输出错误日志。 * `"none"`: 禁用所有日志输出。 + * `hertzLogPath`: `HertZ`日志文件路径。 + * 类型: 字符串 (`string`) + * 默认值: `"/data/ghproxy/log/hertz.log"` + * 说明: 设置 `HertZ` 日志文件的存储路径。 * **`[auth]` - 认证配置** diff --git a/go.mod b/go.mod index fe29791..9b03803 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/cloudwego/base64x v0.1.5 // indirect github.com/cloudwego/gopkg v0.1.4 // indirect github.com/cloudwego/netpoll v0.7.0 // indirect - github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/nyaruka/phonenumbers v1.6.0 // indirect @@ -30,9 +30,9 @@ require ( github.com/tidwall/pretty v1.2.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - golang.org/x/arch v0.15.0 // indirect + golang.org/x/arch v0.16.0 // indirect golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect google.golang.org/protobuf v1.36.6 // indirect ) diff --git a/go.sum b/go.sum index f8d62b2..730be7f 100644 --- a/go.sum +++ b/go.sum @@ -29,8 +29,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= -github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= @@ -81,8 +81,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= -golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= +golang.org/x/arch v0.16.0 h1:foMtLTdyOmIniqWCHjY6+JxuC54XP1fDwx4N0ASyW+U= +golang.org/x/arch v0.16.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= @@ -113,8 +113,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -127,8 +127,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/main.go b/main.go index aabb054..cd21df2 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "io/fs" "net/http" "os" + "runtime/debug" "time" "ghproxy/api" @@ -23,6 +24,7 @@ import ( "github.com/cloudwego/hertz/pkg/app/middlewares/server/recovery" "github.com/cloudwego/hertz/pkg/app/server" "github.com/cloudwego/hertz/pkg/common/adaptor" + "github.com/cloudwego/hertz/pkg/common/hlog" "github.com/hertz-contrib/http2/factory" ) @@ -31,6 +33,7 @@ var ( cfg *config.Config r *server.Hertz configfile = "/data/ghproxy/config/config.toml" + hertZfile *os.File cfgfile string version string runMode string @@ -129,7 +132,29 @@ func setupLogger(cfg *config.Config) { fmt.Printf("Log Level: %s\n", cfg.Log.Level) logDebug("Config File Path: ", cfgfile) logDebug("Loaded config: %v\n", cfg) - logInfo("Init Completed") + logInfo("Logger Initialized Successfully") +} + +func setupHertZLogger(cfg *config.Config) { + var err error + + if cfg.Log.HertZLogPath != "" { + hertZfile, err = os.OpenFile(cfg.Log.HertZLogPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) + if err != nil { + hlog.SetOutput(os.Stdout) + logWarning("Failed to open hertz log file: %v", err) + } else { + hlog.SetOutput(hertZfile) + } + } + +} + +func setMemLimit(cfg *config.Config) { + if cfg.Server.MemLimit > 0 { + debug.SetMemoryLimit((cfg.Server.MemLimit) * 1024 * 1024) + logInfo("Set Memory Limit to %d MB", cfg.Server.MemLimit) + } } func loadlist(cfg *config.Config) { @@ -315,7 +340,9 @@ func init() { loadConfig() if cfg != nil { // 在setupLogger前添加空值检查 setupLogger(cfg) + setupHertZLogger(cfg) InitReq(cfg) + setMemLimit(cfg) loadlist(cfg) setupRateLimit(cfg) @@ -346,12 +373,17 @@ func main() { addr := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port) - r := server.New( - server.WithHostPorts(addr), - server.WithH2C(true), - ) - - r.AddProtocol("h2", factory.NewServerFactory()) + if cfg.Server.H2C { + r = server.New( + server.WithHostPorts(addr), + server.WithH2C(true), + ) + r.AddProtocol("h2", factory.NewServerFactory()) + } else { + r = server.New( + server.WithHostPorts(addr), + ) + } // 添加Recovery中间件 r.Use(recovery.Recovery()) @@ -414,5 +446,13 @@ func main() { r.Spin() defer logger.Close() + defer func() { + if hertZfile != nil { + err := hertZfile.Close() + if err != nil { + logError("Failed to close hertz log file: %v", err) + } + } + }() fmt.Println("Program Exit") } diff --git a/proxy/chunkreq.go b/proxy/chunkreq.go index dd2b1ee..0212e0d 100644 --- a/proxy/chunkreq.go +++ b/proxy/chunkreq.go @@ -70,6 +70,7 @@ func ChunkedProxyRequest(ctx context.Context, c *app.RequestContext, u string, c // 错误处理(404) if resp.StatusCode == 404 { c.String(http.StatusNotFound, "File Not Found") + //c.Status(http.StatusNotFound) return }