Documentation
¶
Overview ¶
Package endpoint 定义了统一的服务调用端点抽象,封装负载均衡、熔断和连接池等基础设施。
核心类型 Endpoint 是一个函数签名,接收 context 和请求并返回响应,使上层逻辑与具体协议解耦。 HTTPEndpointFactory 和 GRPCEndpointFactory 分别为 HTTP 和 gRPC 协议创建 Endpoint, 内部集成负载均衡选择实例、gRPC 连接池复用连接、以及基于 gobreaker 的断路器保护。
Index ¶
- Variables
- type Endpoint
- type EndpointFactoryOption
- type GRPCEndpointFactory
- type GRPCPool
- func (p *GRPCPool) Acquire(ctx context.Context, addr string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
- func (p *GRPCPool) Close()
- func (p *GRPCPool) Get(ctx context.Context, addr string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
- func (p *GRPCPool) Release(addr string, conn *grpc.ClientConn)
- type GRPCRequest
- type HTTPEndpointFactory
- type HTTPRequest
Constants ¶
This section is empty.
Variables ¶
var ErrCircuitOpen = httpx.ErrCircuitOpen
ErrCircuitOpen 表示熔断器处于打开状态、请求被拒绝。
与 httpx.ErrCircuitOpen 是同一 sentinel:endpoint 工厂与 httpx.Client 的 熔断行为共用一个可判定错误,消费方 errors.Is 任一别名均可识别, 不必同时 import 两个包。
var ErrFactoryClosed = errors.New("nns-endpoint: endpoint factory closed")
ErrFactoryClosed 表示端点工厂已 Close(终结操作)后仍调用其端点(#148)。 errors.Is 可判定;Close 后存量端点闭包一律短路返回本哨兵(包装为 localError——本地确定性错误,不计熔断样本、不做节点 EWMA 惩罚), 不再触达底层连接池。优雅停机窗口在途请求、双路关停竞态下未同步的 消费方都拿到明确错误,而不是静默复活池里的连接。
var ErrPoolClosed = errors.New("nns-endpoint: grpc pool closed")
ErrPoolClosed 表示连接池已 Close(终结操作)后再取连接(#148)。 errors.Is 可判定;Close 后 Get/Acquire 一律返回本哨兵,不再静默新建 连接——新建连接进入已终结的池后无人再调 pool.Close,连接及其 gRPC channel/子连接只能泄漏到进程退出。
Functions ¶
This section is empty.
Types ¶
type EndpointFactoryOption ¶
type EndpointFactoryOption func(*factoryConfig)
EndpointFactoryOption 是端点工厂(HTTP/gRPC)的配置函数类型。
func WithBreakerSettings ¶
func WithBreakerSettings(tmpl gobreaker.Settings) EndpointFactoryOption
WithBreakerSettings 设置 per-service 熔断器的参数模板。
数值字段(MaxRequests/Interval/Timeout)整体取模板值——0 是 gobreaker 的合法显式语义(如 Interval 0 = 计数器跨窗口累计),不做零值回填; 函数字段(ReadyToTrip/OnStateChange/IsSuccessful)为 nil 时沿用工厂默认。
未传 IsSuccessful 时默认判定为"4xx 不计熔断失败"(调用方请求错误与 对端健康无关);显式传入则完全接管失败判定。
func WithMetrics ¶
func WithMetrics(reg prom.Registerer, namespace string) EndpointFactoryOption
WithMetrics 启用弹性指标(熔断状态/迁移/拒绝 + 重试尝试)。 reg 为 nil 时回退到 oekit/metrics 的平台 Registry(metrics.Registry, 平台 /metrics 端点暴露的自定义 registry,与 metrics#50 后 resilience.NewMetrics 的 nil 口径一致);确需进 prom 默认全局 registry 的调用方显式传 prom.DefaultRegisterer。namespace 为空时用 "nns_endpoint"。多个工厂共享同一 Registry + namespace 时复用已注册 collector。
注意:本仓与 httpx.WithMetrics 的 nil 语义**不同**(#144)——httpx 在调 NewMetrics 之前自行把 nil 回填为 prom.DefaultRegisterer,本仓把 nil 原样透传给 resilience.NewMetrics(回退 metrics.Registry)。两仓 nil 落 不同 registry,调用方跨仓对齐口径时以此为准。
func WithSelector ¶ added in v0.2.0
func WithSelector(sel loadbalance.Selector) EndpointFactoryOption
WithSelector 注入节点选择器(loadbalance.Selector),覆盖服务治理配置 中的 lb 策略;nil 被忽略。未注入时按服务配置的 Lb 字段经 loadbalance.NewSelector 构造(不可识别回退 roundrobin)。
type GRPCEndpointFactory ¶
type GRPCEndpointFactory struct {
// contains filtered or unexported fields
}
GRPCEndpointFactory gRPC 端点工厂,负责创建 gRPC 端点并管理连接池和熔断器。
balancer 与熔断器均按服务名分片:balancer 缓存避免有状态策略(轮询)因 计数器重置失效;熔断器按服务隔离,避免单个依赖故障熔断全工厂。 balancer/熔断器均在端点闭包内按调用获取(balancerCache 读锁命中,开销可忽略), 配置热更新(ResetBalancer)对已创建的端点同样生效。服务配置(超时等)在每次 调用时从内存读取,支持 WatchService 热更新。
func NewGRPCEndpointFactory ¶
func NewGRPCEndpointFactory(c *nnsclient.ServiceClient, opts ...EndpointFactoryOption) *GRPCEndpointFactory
NewGRPCEndpointFactory 根据服务客户端创建 gRPC 端点工厂实例。 opts 定制 per-service 熔断参数(WithBreakerSettings)等行为。 注意:gRPC 端点不做换实例重试——streaming/非幂等 RPC 的重试语义 复杂(需 header/ trailers 透传配合),如需重试在业务层按方法粒度实现。
func (*GRPCEndpointFactory) Close ¶
func (f *GRPCEndpointFactory) Close()
Close 关闭 gRPC 端点工厂持有的资源:先登记终态(此后存量端点闭包 短路返回 ErrFactoryClosed,#148),再注销构造期在 client 上注册的 配置变更回调(#135,不注销则 client 经回调闭包长持已废弃工厂、配置 事件继续打在死工厂上),最后关闭连接池。OffConfigChange 与 pool.Close 均幂等,Close 可安全重复调用。
func (*GRPCEndpointFactory) MakeEndpoint ¶
func (f *GRPCEndpointFactory) MakeEndpoint(serviceName string, opts ...grpc.DialOption) (Endpoint, error)
MakeEndpoint 为指定服务创建 gRPC 端点,包含负载均衡、连接池和熔断逻辑。 balancer 与熔断器在闭包内按调用获取,ResetBalancer/配置热更对存量端点生效。
传输安全(#77):opts 必须显式包含传输凭据——明文传 grpc.WithTransportCredentials(insecure.NewCredentials()),TLS 传对应 TransportCredentials。连接池不再默认注入 insecure 凭据,缺凭据的 调用会得到 grpc 的 "no transport security set" 错误(此前是静默明文)。
func (*GRPCEndpointFactory) ResetSelector ¶ added in v0.2.0
func (f *GRPCEndpointFactory) ResetSelector(serviceName string)
ResetSelector 清除指定服务的节点选择器缓存,下次调用时按最新配置重建。
type GRPCPool ¶
type GRPCPool struct {
// contains filtered or unexported fields
}
GRPCPool gRPC 连接池,复用 gRPC 客户端连接。 连接数超过 maxSize 时先全局驱逐空闲超龄条目,仍满则拒绝创建新连接。 空闲超过 idleTTL 的连接在 Get 时自动驱逐(同地址命中与满池创建两条 路径都会驱逐);有在途引用(Acquire 后未 Release)的连接不参与驱逐 (#99)——conn.Close 会终止其上全部活跃 RPC。
借还口径:Get 是无引用借出(与 v0.2.x 行为一致,适合短平快的一元 调用);长生命周期流式 RPC 必须用 Acquire/Release 配对——在途期间 连接不会被任何驱逐路径关闭。
实例一次性(#148):Close 是终结操作,Close 后 Get/Acquire 一律返回 ErrPoolClosed——不静默重建连接(否则新建连接进入已终结的池,此后无人 再 Close ⇒ 连接与 gRPC channel/子连接泄漏)。对齐矩阵 #124 以来 「停机后调用显式报错,不静默哑火」的纪律(timertask 同场景返回 ErrBackendStopped)。
传输凭据(#77):池**不注入**默认凭据——调用方必须经 opts 显式传入 grpc.WithTransportCredentials(insecure.NewCredentials())(明文)或 TLS 凭据。缺凭据时 grpc.NewClient 返回 "no transport security set" 错误 (fail-closed),不再静默降级明文。
func NewGRPCPool ¶
NewGRPCPool 创建一个新的 gRPC 连接池实例。
maxSize 可省略(缺省 defaultMaxPoolSize);显式传入 ≤0 的值同样回退 默认值(原 NewGRPCPoolWithSize 的守卫语义)。两个构造器除 maxSize 外 逐行相同、且带尺寸形态全工作区仅测试使用(#134)——合并为单一构造器, 公开面少一个入口。
func (*GRPCPool) Acquire ¶ added in v0.3.0
func (p *GRPCPool) Acquire(ctx context.Context, addr string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
Acquire 从连接池借出指定地址的 gRPC 连接并记在途引用(#99)。 与 Get 的差别只在引用记账:借出期间(直到 Release)该连接不会被任何 空闲驱逐路径关闭——lastUsed 的「借出时刻」口径覆盖不了「借出后仍在 用」的长生命周期流式 RPC。调用方用毕必须 Release(addr, conn) 配对归还; 未归还的连接永不被空闲驱逐(至多被 Shutdown 替换或池 Close 终结)。 池 Close 后调用返回 ErrPoolClosed(#148,终结语义:不静默重建连接)。
func (*GRPCPool) Close ¶
func (p *GRPCPool) Close()
Close 关闭连接池中的所有 gRPC 连接。 Close 是终结操作:有在途引用的连接同样关闭(其上活跃 RPC 会终止), 与「显式关停」语义一致。Close 后 Get/Acquire 一律返回 ErrPoolClosed (#148)——不静默重建连接,存量端点在工厂 Close 后的调用同样被闸拒绝。
func (*GRPCPool) Get ¶
func (p *GRPCPool) Get(ctx context.Context, addr string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
Get 从连接池获取指定地址的 gRPC 连接,不存在、已关闭或空闲超时时创建新连接。 opts 透传给 grpc.NewClient;必须包含传输凭据(明文 insecure / TLS), 缺凭据时返回 grpc 的 no transport security set 错误(#77)。 池 Close 后调用返回 ErrPoolClosed(#148,终结语义:不静默重建连接)。
Get 是**无引用借出**:不记在途引用,适合调用时长远小于 idleTTL 的 一元调用(端点工厂内部即此形态,超时上限有界)。调用时长可能超过 idleTTL 的长生命周期流式 RPC 必须改用 Acquire/Release(#99)——否则 借出后连接仍可能因空闲判据(按「借出时刻」计)被驱逐关闭,终止 在途 RPC。
并发安全说明:读锁读取 entry 与写锁校验之间存在窗口,期间该 entry 可能被 并发驱逐(Close 后删除)或替换。因此返回前必须在写锁内校验 p.conns[addr] 仍等于该 entry,否则重试——绝不把一个可能已被 Close 的连接返回给调用方。
type GRPCRequest ¶
type GRPCRequest struct {
ServiceName string
GrpcServiceName string
Method string
// Request 是请求消息,必须实现 proto.Message(默认 proto codec 只
// 接受该类型)。不满足时端点在发起调用前直接报错,而不是让编解码
// 失败发生在 Invoke 深处、错误形态晦涩。
Request any
// Reply 是接收响应的类型化消息指针,由调用方传入(如
// &helloworld.HelloReply{}),端点的返回值就是它。必填。
//
// #71/#73:此前解码目标是 var reply any(&reply 是 *any),默认
// proto codec 的 Unmarshal 要求 proto.Message,类型化响应永远拿
// 不到——gRPC happy path 从未跑通过。
Reply proto.Message
// Timeout 是单次调用超时;0 时回退服务治理 ReadTimeout,两级均
// 未配置时兜底 defaultCallTimeout(#75)。
Timeout time.Duration
}
GRPCRequest gRPC 端点请求参数。
type HTTPEndpointFactory ¶
type HTTPEndpointFactory struct {
// contains filtered or unexported fields
}
HTTPEndpointFactory HTTP 端点工厂,负责创建 HTTP 端点并管理 HTTP 客户端和熔断器。
func NewHTTPEndpointFactory ¶
func NewHTTPEndpointFactory(c *nnsclient.ServiceClient, opts ...EndpointFactoryOption) *HTTPEndpointFactory
NewHTTPEndpointFactory 根据服务客户端创建 HTTP 端点工厂实例。 opts 定制 per-service 熔断参数(WithBreakerSettings)、弹性指标 (WithMetrics)等行为。
func (*HTTPEndpointFactory) Close ¶
func (f *HTTPEndpointFactory) Close()
Close 关闭 HTTP 端点工厂持有的资源。 Hertz client 连接池无显式释放 API(随进程生命周期),httpx.Client 的 endpointManager 在本工厂场景未启用;此处注销构造期在 client 上 注册的配置变更回调(#135)——否则 client 经回调闭包长持已废弃工厂, selectorCache/breakers 无法回收,配置事件继续打在死工厂上。 OffConfigChange 幂等,Close 可安全重复调用。
func (*HTTPEndpointFactory) MakeEndpoint ¶
func (f *HTTPEndpointFactory) MakeEndpoint(serviceName string) (Endpoint, error)
MakeEndpoint 为指定服务创建 HTTP 端点。
重试语义(消费服务配置 ServiceBasic.Retry,Nacos 配置缺省 3): 失败时换实例重试,最多额外 Retry 次尝试;5xx 与网络错误重试, 4xx 不重试(确定性请求错误);本地确定性错误(序列化/解码/选点, #123)重试同一输入恒失败,同样不重试、不计熔断样本。熔断 Execute 包住整组尝试——一次调用计一次熔断样本(与 httpx.WithCircuitBreaker + WithRetryConfig 的层次结构一致),避免单次调用的多次尝试 撑爆连续失败计数。每次尝试独立 per-attempt 超时,最坏总耗时 为 (1+Retry) × ReadTimeout。
分层边界(#96/#98):实例发现与 selector 首建在 Execute 之外—— 「无实例」与「配置中心故障」都不是目标后端的故障,不构成熔断样本 (与 gRPC 路径的分层一致)。
func (*HTTPEndpointFactory) ResetSelector ¶ added in v0.2.0
func (f *HTTPEndpointFactory) ResetSelector(serviceName string)
ResetSelector 清除指定服务的节点选择器缓存(配置热更后强制重建)。