fix(service): 对齐新版服务发现与稳定依赖链(by AI)

This commit is contained in:
Star 2026-07-18 18:45:24 +08:00
parent e8369d4680
commit ba1a909d49
8 changed files with 100 additions and 76 deletions

View File

@ -1,5 +1,11 @@
# CHANGELOG - go/service # CHANGELOG - go/service
## v1.5.21 (2026-07-18)
- **依赖校验修复**: 升级 `discover``v1.5.7``redis``v1.5.11`,并使用稳定版 `redigo v1.9.3`
- **依赖对齐**: 升级 `cast``v1.5.4``crypto``v1.5.4``encoding``v1.5.5``starter``v1.5.6`
- **Discover API 对齐**: 服务注册与代理调用改用新版包级 Discover API调用配置转换为统一的协议、超时和 Token 字符串格式。
- **Header 命名对齐**: 内部引用统一采用 `RequestId``SessionId``DeviceId``UserId``ClientIp` Go 命名。
## v1.5.20 (2026-06-22) ## v1.5.20 (2026-06-22)
- **Client Key 应答头条件化**: - **Client Key 应答头条件化**:
- `Device-Id` / `Session-Id` 仅当请求头未携带时才写入应答头,避免客户端已持有 ID 时重复返回。 - `Device-Id` / `Session-Id` 仅当请求头未携带时才写入应答头,避免客户端已持有 ID 时重复返回。

12
TEST.md
View File

@ -1,10 +1,14 @@
# Service Module Test Report # Service Module Test Report
## v1.5.21 验证
- `go list -m all`:模块图使用 `discover v1.5.7``redis v1.5.11` 与稳定版 `redigo v1.9.3`
- `go test -v ./...``go test -bench=. ./...` 全部通过。
## 性能测试 (Benchmark) ## 性能测试 (Benchmark)
- 测试日期: 2026-06-22 - 测试日期: 2026-07-18
- 版本: v1.5.20 - 版本: v1.5.21
- 指标: `BenchmarkRouting`: **5394 ns/op** - 指标: `BenchmarkRouting`: **2382 ns/op**
- 环境: Darwin / Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz - 环境: Darwin / Apple M3 Max
## 单元测试覆盖 (Unit Test) ## 单元测试覆盖 (Unit Test)
- [x] `TestServeHTTP`: 基础请求与响应 - [x] `TestServeHTTP`: 基础请求与响应

14
go.mod
View File

@ -3,17 +3,17 @@ module apigo.cc/go/service
go 1.25.0 go 1.25.0
require ( require (
apigo.cc/go/cast v1.5.3 apigo.cc/go/cast v1.5.4
apigo.cc/go/config v1.5.3 apigo.cc/go/config v1.5.3
apigo.cc/go/discover v1.5.3 apigo.cc/go/discover v1.5.7
apigo.cc/go/file v1.5.5 apigo.cc/go/file v1.5.5
apigo.cc/go/http v1.5.3 apigo.cc/go/http v1.5.3
apigo.cc/go/id v1.5.6 apigo.cc/go/id v1.5.6
apigo.cc/go/jsmod v1.5.3 apigo.cc/go/jsmod v1.5.3
apigo.cc/go/log v1.5.8 apigo.cc/go/log v1.5.8
apigo.cc/go/redis v1.5.10 apigo.cc/go/redis v1.5.11
apigo.cc/go/safe v1.5.2 apigo.cc/go/safe v1.5.2
apigo.cc/go/starter v1.5.5 apigo.cc/go/starter v1.5.6
apigo.cc/go/timer v1.5.0 apigo.cc/go/timer v1.5.0
apigo.cc/go/watch v1.5.2 apigo.cc/go/watch v1.5.2
github.com/gorilla/websocket v1.5.3 github.com/gorilla/websocket v1.5.3
@ -21,13 +21,13 @@ require (
) )
require ( require (
apigo.cc/go/crypto v1.5.3 // indirect apigo.cc/go/crypto v1.5.4 // indirect
apigo.cc/go/encoding v1.5.4 // indirect apigo.cc/go/encoding v1.5.5 // indirect
apigo.cc/go/rand v1.5.3 // indirect apigo.cc/go/rand v1.5.3 // indirect
apigo.cc/go/shell v1.5.4 // indirect apigo.cc/go/shell v1.5.4 // indirect
github.com/fsnotify/fsnotify v1.10.1 // indirect github.com/fsnotify/fsnotify v1.10.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect github.com/gobwas/glob v0.2.3 // indirect
github.com/gomodule/redigo v2.0.0+incompatible // indirect github.com/gomodule/redigo v1.9.3 // indirect
golang.org/x/crypto v0.52.0 // indirect golang.org/x/crypto v0.52.0 // indirect
golang.org/x/sys v0.45.0 // indirect golang.org/x/sys v0.45.0 // indirect
golang.org/x/text v0.37.0 // indirect golang.org/x/text v0.37.0 // indirect

38
go.sum
View File

@ -1,51 +1,57 @@
apigo.cc/go/cast v1.5.3 h1:jk6VX0rGFhjKtfPhsaV6IKYpiGmORRk9qPTtuNS53tw= apigo.cc/go/cast v1.5.4 h1:OH5Vkrc1K19wuazf9VecjwwMwKDFgLQkI3UvwB4umcs=
apigo.cc/go/cast v1.5.3/go.mod h1:GMjjrYn93tWat1U409G7h1jR3ejfLLI7r0efBo9Sbd4= apigo.cc/go/cast v1.5.4/go.mod h1:GMjjrYn93tWat1U409G7h1jR3ejfLLI7r0efBo9Sbd4=
apigo.cc/go/config v1.5.3 h1:peq1FM2xO+vzPHJf8Dwg3DXm8PtFQMfTFKQj6fpoG7A= apigo.cc/go/config v1.5.3 h1:peq1FM2xO+vzPHJf8Dwg3DXm8PtFQMfTFKQj6fpoG7A=
apigo.cc/go/config v1.5.3/go.mod h1:ZiOAjWa1mQIzszaJZN+kO6YU4GXreng+NxkcK/TAkqQ= apigo.cc/go/config v1.5.3/go.mod h1:ZiOAjWa1mQIzszaJZN+kO6YU4GXreng+NxkcK/TAkqQ=
apigo.cc/go/crypto v1.5.3 h1:2JUHC2cgR2zrnn36EzwkUAdxmmTXAA/8yTNo+2X1mPE= apigo.cc/go/crypto v1.5.4 h1:7rFcF9Mns+7BIB13lystvLVsAeYapKsrD26KOrQq2Zk=
apigo.cc/go/crypto v1.5.3/go.mod h1:PheYKHEXmoEFI1AK5PpY1borQWcRlkkSaWncT3cWbhE= apigo.cc/go/crypto v1.5.4/go.mod h1:PheYKHEXmoEFI1AK5PpY1borQWcRlkkSaWncT3cWbhE=
apigo.cc/go/discover v1.5.3 h1:WW1A7qReYytebETDb5MhVRPmT10KReGM4QbPTfqS/iw= apigo.cc/go/discover v1.5.7 h1:wb2hXr+6mGxZ+yjOuTNzeLSZ8tNaPvn+dl1AuedPRm0=
apigo.cc/go/discover v1.5.3/go.mod h1:rylFiGvfNro090rGtlc9K31KATn6WZbnn1Fk2AbQZEU= apigo.cc/go/discover v1.5.7/go.mod h1:Vg41wYA5+M7t883imlQEOwdeUPZPoNrzDWVshum7KYo=
apigo.cc/go/encoding v1.5.4 h1:Fk8TrveZATyy8SHukC4ZiqdTSp+QIfsRHtt55xmMK7w= apigo.cc/go/encoding v1.5.5 h1:kduNLWQgtcQqHYobOuu1djbgg8LedkGOe8f18ZMfqzs=
apigo.cc/go/encoding v1.5.4/go.mod h1:dShEsZ3gKqBINz7TSOYf4e7/fBCqCY9VzlenoGUQUFM= apigo.cc/go/encoding v1.5.5/go.mod h1:Big9q1Zwy4071dXtnrQ3SJDzfa/G7/A60KE/5+M//P8=
apigo.cc/go/file v1.5.5 h1:/+HmDumLu6Qk2KuQL63M9lpgzHTDL+QJ8dStOl7e9gs= apigo.cc/go/file v1.5.5 h1:/+HmDumLu6Qk2KuQL63M9lpgzHTDL+QJ8dStOl7e9gs=
apigo.cc/go/file v1.5.5/go.mod h1:xRVNhctvqOKeBemmcRW/BQfgkc3B+vT/UZVdSc7duUo= apigo.cc/go/file v1.5.5/go.mod h1:xRVNhctvqOKeBemmcRW/BQfgkc3B+vT/UZVdSc7duUo=
apigo.cc/go/http v1.5.3 h1:nvJh9bqPPcPRv6p8WEw7bJAd0UC+r2zvQA8/QioVLTQ= apigo.cc/go/http v1.5.3 h1:nvJh9bqPPcPRv6p8WEw7bJAd0UC+r2zvQA8/QioVLTQ=
apigo.cc/go/http v1.5.3/go.mod h1:cFrPK61y9f1PrsNSJscZT/QVOgkT15o9OP7O8cuMb8Q= apigo.cc/go/http v1.5.3/go.mod h1:cFrPK61y9f1PrsNSJscZT/QVOgkT15o9OP7O8cuMb8Q=
apigo.cc/go/id v1.5.5 h1:fQXfb2WZ4hEtzXkpb9w9o8AOcTZ44fYQfTV6iZ49l8o= apigo.cc/go/id v1.5.6 h1:Z3PPp8H8FgNHMwHerxtT2GgstueDv4aCDnUUCoQZoFQ=
apigo.cc/go/id v1.5.5/go.mod h1:hCTQq+KC1ALWe1FpPERf+W4B6FSulg9FAgOUJDDySiY= apigo.cc/go/id v1.5.6/go.mod h1:HcJK691qfBPzvQ/lt8bo/incKUFtG5vENX/rDEgzJh0=
apigo.cc/go/jsmod v1.5.3 h1:S3W317bH0QV2NMeRO1E0v6ySIBOfMWYv/NuQJbvqKWU= apigo.cc/go/jsmod v1.5.3 h1:S3W317bH0QV2NMeRO1E0v6ySIBOfMWYv/NuQJbvqKWU=
apigo.cc/go/jsmod v1.5.3/go.mod h1:bmyeZtOAP/j5am+YRnaiM89smysK24K7ebk0koFtsSw= apigo.cc/go/jsmod v1.5.3/go.mod h1:bmyeZtOAP/j5am+YRnaiM89smysK24K7ebk0koFtsSw=
apigo.cc/go/log v1.5.8 h1:/IYtGPWhRjT3OayylDIphkWZIQbpLjqVeSnFEiD3Dy0= apigo.cc/go/log v1.5.8 h1:/IYtGPWhRjT3OayylDIphkWZIQbpLjqVeSnFEiD3Dy0=
apigo.cc/go/log v1.5.8/go.mod h1:HfFPANMYxJx197SSTXB21Pgxcz/gGqPP8nlSErgd5WE= apigo.cc/go/log v1.5.8/go.mod h1:HfFPANMYxJx197SSTXB21Pgxcz/gGqPP8nlSErgd5WE=
apigo.cc/go/rand v1.5.3 h1:O4bPIwyaOWEBCr0nL9A4G4qG48AqiGTCzfPeckm3Ius= apigo.cc/go/rand v1.5.3 h1:O4bPIwyaOWEBCr0nL9A4G4qG48AqiGTCzfPeckm3Ius=
apigo.cc/go/rand v1.5.3/go.mod h1:q1BTFkY/cXE229dDD5Q22lF7T0DoKPV6xAu+6bCrDH4= apigo.cc/go/rand v1.5.3/go.mod h1:q1BTFkY/cXE229dDD5Q22lF7T0DoKPV6xAu+6bCrDH4=
apigo.cc/go/redis v1.5.9 h1:h77XPjQWcIDgxrtwjtS/gwT6PS5nSk6/x785t0OMlbY= apigo.cc/go/redis v1.5.11 h1:r/kiY3EUD+3YwTd+zMZaRD7eOQZEIvSJwAVnzG96zoQ=
apigo.cc/go/redis v1.5.9/go.mod h1:YZRDLA3gWw9LAc4Z/4GrDEy8eMDMdDPDA0iqSEAu1fE= apigo.cc/go/redis v1.5.11/go.mod h1:sCzxIWN+nNIRvR5ePaHsP19hjR52NPfXsq7L1c6A5ec=
apigo.cc/go/safe v1.5.2 h1:EnuEOW/SGwf/5A0nw9LnqfKJE071+TIc6ez8HI9R9Lg= apigo.cc/go/safe v1.5.2 h1:EnuEOW/SGwf/5A0nw9LnqfKJE071+TIc6ez8HI9R9Lg=
apigo.cc/go/safe v1.5.2/go.mod h1:2GqCCLLGex4OAhdET3iBWm1R+LIYtmTrvHP8W0iESSw= apigo.cc/go/safe v1.5.2/go.mod h1:2GqCCLLGex4OAhdET3iBWm1R+LIYtmTrvHP8W0iESSw=
apigo.cc/go/shell v1.5.4 h1:Kn6lP6I6d9U0hbyUjpKKFdFZ8RPo4vi4V6AYW8YFzrc= apigo.cc/go/shell v1.5.4 h1:Kn6lP6I6d9U0hbyUjpKKFdFZ8RPo4vi4V6AYW8YFzrc=
apigo.cc/go/shell v1.5.4/go.mod h1:FdZWUrcXHGJXo725oSyHqAeFoX0E9yY3PDhrz9hujgY= apigo.cc/go/shell v1.5.4/go.mod h1:FdZWUrcXHGJXo725oSyHqAeFoX0E9yY3PDhrz9hujgY=
apigo.cc/go/starter v1.5.5 h1:4ST02o4qP8IIekxtd9Jhx5RHTrSGXtVQUguSIXV0iWc= apigo.cc/go/starter v1.5.6 h1:hcZbR/70q0XW8xZII8BnGDmIomus//+8sWxGqluyj0U=
apigo.cc/go/starter v1.5.5/go.mod h1:WAGhdtmZdpP1Jn/z0pCqHwpTbqqaFhm5OqH7QVtcanY= apigo.cc/go/starter v1.5.6/go.mod h1:abqfSu+lUz/FySn1VxjT8QeAa3mfKo6WrP5xLddw7QE=
apigo.cc/go/timer v1.5.0 h1:iPo/IQn+iuhBRI1/MR1txwZnamef/RBBfOiIlBiqkgk= apigo.cc/go/timer v1.5.0 h1:iPo/IQn+iuhBRI1/MR1txwZnamef/RBBfOiIlBiqkgk=
apigo.cc/go/timer v1.5.0/go.mod h1:kOnqTTX+zA4AH7SfC+LpUm4ZvS+DVyWWMqul/V5QWJs= apigo.cc/go/timer v1.5.0/go.mod h1:kOnqTTX+zA4AH7SfC+LpUm4ZvS+DVyWWMqul/V5QWJs=
apigo.cc/go/watch v1.5.2 h1:zG56PD8Vml5gVJeo2yNuX9s6stOaIJRYqqKGqXK+xTU= apigo.cc/go/watch v1.5.2 h1:zG56PD8Vml5gVJeo2yNuX9s6stOaIJRYqqKGqXK+xTU=
apigo.cc/go/watch v1.5.2/go.mod h1:MW1XnI0MVyUZpRy590no1vrDT+U4y20L0UZW9/LgU+k= apigo.cc/go/watch v1.5.2/go.mod h1:MW1XnI0MVyUZpRy590no1vrDT+U4y20L0UZW9/LgU+k=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho=
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo= github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= github.com/gomodule/redigo v1.9.3 h1:dNPSXeXv6HCq2jdyWfjgmhBdqnR6PRO3m/G05nvpPC8=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/gomodule/redigo v1.9.3/go.mod h1:KsU3hiK/Ay8U42qpaJk+kuNa3C+spxapWpM+ywhcgtw=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w=

View File

@ -30,10 +30,10 @@ func (rh *RouteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer atomic.AddInt64(&rh.webRequestingNum, -1) defer atomic.AddInt64(&rh.webRequestingNum, -1)
tracker := timer.Start() tracker := timer.Start()
requestId := r.Header.Get(discover.HeaderRequestID) requestId := r.Header.Get(discover.HeaderRequestId)
if requestId == "" { if requestId == "" {
requestId = IDMaker.Get10Bytes14MPerSecond() requestId = IDMaker.Get10Bytes14MPerSecond()
r.Header.Set(discover.HeaderRequestID, requestId) r.Header.Set(discover.HeaderRequestId, requestId)
} }
request := NewRequest(r) request := NewRequest(r)
@ -458,7 +458,7 @@ func (ws *WebServer) handleClientKeys(request *Request, response *Response) {
}) })
} }
} }
request.Request.Header.Set(discover.HeaderSessionID, sessionId) request.Request.Header.Set(discover.HeaderSessionId, sessionId)
if !hasRequestSessionId { if !hasRequestSessionId {
response.Header().Set(ws.usedSessionIdKey, sessionId) response.Header().Set(ws.usedSessionIdKey, sessionId)
} }
@ -487,7 +487,7 @@ func (ws *WebServer) handleClientKeys(request *Request, response *Response) {
}) })
} }
} }
request.Request.Header.Set(discover.HeaderDeviceID, deviceId) request.Request.Header.Set(discover.HeaderDeviceId, deviceId)
if !hasRequestDeviceId { if !hasRequestDeviceId {
response.Header().Set(ws.usedDeviceIdKey, deviceId) response.Header().Set(ws.usedDeviceIdKey, deviceId)
} }

View File

@ -1,6 +1,7 @@
package service package service
import ( import (
"apigo.cc/go/discover"
gohttp "apigo.cc/go/http" gohttp "apigo.cc/go/http"
"apigo.cc/go/log" "apigo.cc/go/log"
"fmt" "fmt"
@ -172,12 +173,12 @@ func (ws *WebServer) processProxy(request *Request, response *Response, logger *
copyResponse(res, response, logger) copyResponse(res, response, logger)
} else { } else {
// Discover 代理 // Discover 代理
if ws.discoverer == nil { if !ws.discoverStarted {
logger.Error("proxy failed: Discoverer is not initialized") logger.Error("proxy failed: Discoverer is not initialized")
response.WriteHeader(http.StatusBadGateway) response.WriteHeader(http.StatusBadGateway)
return true return true
} }
caller := ws.discoverer.NewCaller(request.Request, logger) caller := discover.NewCaller(request.Request, logger)
caller.NoBody = true caller.NoBody = true
res, _ := caller.ManualDoWithNode(request.Method, app, "", path, request.Body) res, _ := caller.ManualDoWithNode(request.Method, app, "", path, request.Body)
copyResponse(res, response, logger) copyResponse(res, response, logger)

View File

@ -188,22 +188,22 @@ func (r *Request) MakeUrl(path string) string {
// DeviceId 获取设备 ID // DeviceId 获取设备 ID
func (r *Request) DeviceId() string { func (r *Request) DeviceId() string {
return r.Header().Get(discover.HeaderDeviceID) return r.Header().Get(discover.HeaderDeviceId)
} }
// SessionId 获取会话 ID // SessionId 获取会话 ID
func (r *Request) SessionId() string { func (r *Request) SessionId() string {
return r.Header().Get(discover.HeaderSessionID) return r.Header().Get(discover.HeaderSessionId)
} }
// SetUserId 设置用户 ID传递给下游 // SetUserId 设置用户 ID传递给下游
func (r *Request) SetUserId(userId string) { func (r *Request) SetUserId(userId string) {
r.Header().Set(discover.HeaderUserID, userId) r.Header().Set(discover.HeaderUserId, userId)
} }
// ClientIp 获取真实 IP // ClientIp 获取真实 IP
func (r *Request) ClientIp() string { func (r *Request) ClientIp() string {
ip := r.Header().Get(discover.HeaderClientIP) ip := r.Header().Get(discover.HeaderClientIp)
if ip == "" { if ip == "" {
ip = r.Header().Get(discover.HeaderForwardedFor) ip = r.Header().Get(discover.HeaderForwardedFor)
} }

View File

@ -5,7 +5,6 @@ import (
"apigo.cc/go/discover" "apigo.cc/go/discover"
"apigo.cc/go/log" "apigo.cc/go/log"
"apigo.cc/go/redis" "apigo.cc/go/redis"
"apigo.cc/go/safe"
"apigo.cc/go/starter" "apigo.cc/go/starter"
"apigo.cc/go/watch" "apigo.cc/go/watch"
"context" "context"
@ -34,7 +33,7 @@ type WebServer struct {
listener net.Listener listener net.Listener
Addr string Addr string
useDiscover bool useDiscover bool
discoverer *discover.Discoverer discoverStarted bool
logger *log.Logger logger *log.Logger
// 运行时状态 // 运行时状态
@ -153,9 +152,25 @@ func NewWebServer() *WebServer {
return ws return ws
} }
// SetDiscovererForTest 提供给测试用例使用的后门方法,用于模拟断开或重置服务发现 func makeDiscoverCallConfig(call CallConfig, fallbackTimeout int) string {
func SetDiscovererForTest(d *discover.Discoverer) { protocol := "http"
DefaultServer.discoverer = d if call.SSL {
protocol = "https"
} else if call.Http2 {
protocol = "h2c"
}
parts := []string{protocol}
timeout := call.Timeout
if timeout <= 0 {
timeout = fallbackTimeout
}
if timeout > 0 {
parts = append(parts, fmt.Sprintf("%dms", timeout))
}
if call.Token != "" {
parts = append(parts, call.Token)
}
return strings.Join(parts, ":")
} }
// ApplyConfig 将 ServiceConfig 中的路由策略应用到内部的文件级策略中 // ApplyConfig 将 ServiceConfig 中的路由策略应用到内部的文件级策略中
@ -395,30 +410,14 @@ func (ws *WebServer) Start(ctx context.Context, logger *log.Logger) error {
ip := GetServerIp() ip := GetServerIp()
discoverAddr := fmt.Sprintf("%s:%s", ip, port) discoverAddr := fmt.Sprintf("%s:%s", ip, port)
discConf := discover.Config{ weight := ws.Config.Weight
Weight: ws.Config.Weight, if weight <= 0 {
CallRetryTimes: 10, weight = 100
Calls: make(map[string]discover.CallConfig),
}
if discConf.Weight <= 0 {
discConf.Weight = 100
} }
calls := make(map[string]string, len(ws.Config.Calls))
for name, call := range ws.Config.Calls { for name, call := range ws.Config.Calls {
dc := discover.CallConfig{ calls[name] = makeDiscoverCallConfig(call, ws.Config.RedirectTimeout)
Http2: call.Http2,
SSL: call.SSL,
}
if call.Timeout > 0 {
dc.Timeout = time.Duration(call.Timeout) * time.Millisecond
} else if ws.Config.RedirectTimeout > 0 {
dc.Timeout = time.Duration(ws.Config.RedirectTimeout) * time.Millisecond
}
if call.Token != "" {
dc.Token = safe.NewSafeBuf([]byte(call.Token))
}
discConf.Calls[name] = dc
} }
registry := ws.Config.Register registry := ws.Config.Register
@ -427,8 +426,15 @@ func (ws *WebServer) Start(ctx context.Context, logger *log.Logger) error {
} }
if registry != "" { if registry != "" {
ws.discoverer = discover.Start(registry, appName, discoverAddr, logger, discConf) discover.Init()
if ws.discoverer != nil { discover.Config.Registry = registry
discover.Config.App = appName
discover.Config.Weight = weight
discover.Config.CallRetryTimes = 10
discover.Config.Calls = calls
discover.SetLogger(logger)
ws.discoverStarted = discover.Start(discoverAddr)
if ws.discoverStarted {
logger.Info("discover registered", "app", appName, "addr", discoverAddr) logger.Info("discover registered", "app", appName, "addr", discoverAddr)
} }
} }
@ -468,8 +474,9 @@ func (ws *WebServer) Stop(ctx context.Context) error {
ws.shutdownHooks = nil ws.shutdownHooks = nil
ws.shutdownHooksLock.Unlock() ws.shutdownHooksLock.Unlock()
if ws.discoverer != nil { if ws.discoverStarted {
ws.discoverer.Stop() discover.Stop()
ws.discoverStarted = false
} }
if ws.server != nil { if ws.server != nil {
if err := ws.server.Shutdown(ctx); err != nil { if err := ws.server.Shutdown(ctx); err != nil {