Documentation
¶
Overview ¶
Package invocation 定义面向 service-to-service 调用模型的核心错误。
Index ¶
- Constants
- Variables
- func DefaultDialFunc(_ context.Context, target Target, options []grpc.DialOption) (*grpc.ClientConn, error)
- type Authorizer
- type AuthzContext
- type Caller
- type ConnectionManager
- type ConnectionManagerOptions
- type DialFunc
- type Dialer
- type InvocationContext
- type InvokeOption
- type InvokeOptions
- type Invoker
- type Locator
- type ServiceEndpoint
- type ServiceRef
- type StaticLocator
- type Target
- type TargetOptions
- type UnaryInvokeFunc
- type UnaryInvoker
Constants ¶
const ( // DefaultClusterDomain 是 K8s Service 的默认集群域。 // 在标准 K8s + Istio 路径下,最终拨号目标通常会落到该域名体系下。 DefaultClusterDomain = "svc.cluster.local" // DefaultResolverScheme 是 gRPC 推荐使用的 DNS resolver scheme。 // 统一生成 dns:/// 前缀可以让 target 在不同实现中保持一致。 DefaultResolverScheme = "dns" )
Variables ¶
var ( // ErrServiceNameEmpty 表示服务名为空,无法构造逻辑服务身份。 ErrServiceNameEmpty = errors.New("service name is empty") // ErrNamespaceEmpty 表示命名空间为空。 ErrNamespaceEmpty = errors.New("namespace is empty") // ErrTargetHostEmpty 表示目标主机为空,无法生成最终拨号地址。 ErrTargetHostEmpty = errors.New("target host is empty") // ErrTargetPortInvalid 表示端口既未显式提供,也无法从默认值中补齐。 ErrTargetPortInvalid = errors.New("target port is invalid") // ErrLocatorIsNil 表示定位器为空,调用方无法把服务身份解析为最终目标。 ErrLocatorIsNil = errors.New("locator is nil") // ErrDialFnIsNil 表示底层拨号函数为空。 ErrDialFnIsNil = errors.New("dial function is nil") // ErrConnectionManagerClosed 表示连接管理器已经关闭,不能再创建新连接。 ErrConnectionManagerClosed = errors.New("connection manager is closed") // ErrInvokerDialerIsNil 表示调用器缺少拨号器依赖。 ErrInvokerDialerIsNil = errors.New("invoker dialer is nil") // ErrInvokeMethodEmpty 表示调用方法名为空。 ErrInvokeMethodEmpty = errors.New("invoke method is empty") )
Functions ¶
func DefaultDialFunc ¶
func DefaultDialFunc(_ context.Context, target Target, options []grpc.DialOption) (*grpc.ClientConn, error)
DefaultDialFunc 是默认的 grpc.ClientConn 创建逻辑。
当前实现采用 grpc.NewClient,并默认启用: - insecure credentials:便于在内部受控网络中快速起步; - otelgrpc client handler:保证调用链路自动接入 OTel。
后续若需要在具体实现中启用 mTLS、自定义 resolver 或更多 dial option, 可以通过 ConnectionManagerOptions 覆盖该行为。
Types ¶
type Authorizer ¶
type Authorizer interface {
Authorize(ctx context.Context, input AuthzContext) error
}
Authorizer 定义外挂 Authz 的最小能力集合。
返回 nil 表示允许调用; 返回非 nil error 表示拒绝调用或 Authz 本身发生错误。
type AuthzContext ¶
type AuthzContext struct {
// Service 表示目标服务身份。
Service ServiceRef `json:"service"`
// FullMethod 表示完整 gRPC 方法,例如 /acme.user.v1.UserService/GetUser。
FullMethod string `json:"full_method"`
// TraceID 表示链路 ID。
TraceId string `json:"trace_id"`
// Caller 表示调用方身份。
Caller Caller `json:"caller"`
// Metadata 表示构造判定时附带的完整 metadata 副本。
Metadata metadata.MD `json:"-"`
}
AuthzContext 表示外挂 Authz 所需的标准化输入。
该对象不直接绑定某个 Authz 实现, 只表达“做权限判断时必须稳定得到的字段”。
func NewAuthzContext ¶
func NewAuthzContext(ref ServiceRef, method string, invocation InvocationContext) AuthzContext
NewAuthzContext 根据 ServiceRef、方法名和 InvocationContext 生成标准 AuthzContext。
type Caller ¶
type Caller struct {
// UserId 表示当前用户身份,可为空。
UserId string `json:"user_id"`
// AppId 表示当前应用身份,可为空。
AppId string `json:"app_id"`
// TenantId 表示当前租户身份,可为空。
TenantId string `json:"tenant_id"`
// OrgIds 表示当前组织范围,可为空。
OrgIds []string `json:"org_ids"`
// RoleIds 表示当前角色范围,可为空。
RoleIds []string `json:"role_ids"`
}
Caller 表示一次服务调用的发起方身份。
这里聚焦的是调用治理与 Authz 所需的统一字段, 避免让每个服务都手工拼装一套不同的 metadata。
type ConnectionManager ¶
type ConnectionManager struct {
// contains filtered or unexported fields
}
ConnectionManager 负责缓存基于 ServiceRef 创建出的 grpc.ClientConn。
它把“服务身份 -> 目标解析 -> 连接缓存”统一收敛在一处, 让业务层无需关心: - target 拼装; - resolver scheme; - 拨号选项; - 多次调用的连接复用。
func NewConnectionManager ¶
func NewConnectionManager(options ConnectionManagerOptions) (*ConnectionManager, error)
NewConnectionManager 创建连接管理器。
func (*ConnectionManager) Close ¶
func (m *ConnectionManager) Close() error
Close 关闭连接管理器及其持有的全部 grpc.ClientConn。
Close 会尽最大努力关闭所有连接; 若中途出现错误,当前实现返回第一条错误并继续关闭剩余连接。
func (*ConnectionManager) Dial ¶
func (m *ConnectionManager) Dial(ctx context.Context, ref ServiceRef) (*grpc.ClientConn, error)
Dial 根据 ServiceRef 获取或创建对应的 grpc.ClientConn。
连接缓存键采用最终 gRPC target,而不是 ServiceRef 原始字段, 这样可以保证: - 逻辑上等价的服务身份只会生成一条连接; - 端口覆盖、cluster domain、resolver scheme 的变化都能体现在缓存键上。
type ConnectionManagerOptions ¶
type ConnectionManagerOptions struct {
// Locator 用于把 ServiceRef 解析为最终 Target。
Locator Locator
// DialFunc 用于创建新的 grpc.ClientConn。
// 若为空,则使用默认拨号实现。
DialFunc DialFunc
// DialOptions 表示创建 grpc.ClientConn 时使用的附加选项。
DialOptions []grpc.DialOption
}
ConnectionManagerOptions 定义连接管理器的配置。
type DialFunc ¶
type DialFunc func(ctx context.Context, target Target, options []grpc.DialOption) (*grpc.ClientConn, error)
DialFunc 表示底层拨号函数。
把拨号过程抽象成函数有两个目的: 1. 让 ConnectionManager 在不依赖具体后端的情况下复用连接; 2. 让单元测试可以替换真实拨号逻辑,避免触发真实网络连接。
type Dialer ¶
type Dialer interface {
Dial(ctx context.Context, ref ServiceRef) (*grpc.ClientConn, error)
Close() error
}
Dialer 定义“如何把服务身份变成 grpc.ClientConn”。
这一层通常会组合 Locator 与连接缓存, 从而让业务侧始终面向 ServiceRef 而不是 host:port 字符串。
type InvocationContext ¶
type InvocationContext struct {
// TraceId 表示当前调用使用的链路 ID。
TraceId string `json:"trace_id"`
// Caller 表示调用者身份。
Caller Caller `json:"caller"`
// Metadata 表示调用方额外附带的 metadata。
// 这里允许业务侧做补充,但核心库仍会统一注入标准字段。
Metadata metadata.MD `json:"-"`
// Timeout 表示本次调用的超时时间。
Timeout time.Duration `json:"timeout"`
}
InvocationContext 表示一次调用附带的统一上下文。
它的职责不是替代 context.Context, 而是把“应当被稳定传递和审计的调用元信息”沉淀为一个结构化对象。
func (InvocationContext) BuildMetadata ¶
func (c InvocationContext) BuildMetadata() metadata.MD
BuildMetadata 将 InvocationContext 转换为标准 gRPC metadata。
约定: - 调用方显式提供的 Metadata 会被保留; - 标准字段由核心库统一写入,避免上层重复设置; - 对于切片字段,会整体覆盖为当前上下文中的值。
func (InvocationContext) Clone ¶
func (c InvocationContext) Clone() InvocationContext
Clone 返回 InvocationContext 的深拷贝。 该方法用于避免调用方复用同一个 metadata 引起数据串扰。
func (InvocationContext) NewOutgoingContext ¶
func (c InvocationContext) NewOutgoingContext(parent context.Context) (context.Context, context.CancelFunc)
NewOutgoingContext 基于父上下文构造新的 gRPC 出站上下文。
行为说明: - 若 parent 为 nil,则使用 Background; - metadata 会统一写入 outgoing context; - 若 Timeout > 0,则自动附加超时控制。
type InvokeOption ¶
type InvokeOption func(*InvokeOptions)
InvokeOption 表示单个调用选项。
func WithCallOptions ¶
func WithCallOptions(callOptions ...grpc.CallOption) InvokeOption
WithCallOptions 追加底层 gRPC CallOption。
func WithInvocationContext ¶
func WithInvocationContext(invocation InvocationContext) InvokeOption
WithInvocationContext 设置本次调用使用的 InvocationContext。
type InvokeOptions ¶
type InvokeOptions struct {
// InvocationContext 表示本次调用要附带的统一上下文。
InvocationContext InvocationContext
// CallOptions 表示附加的 gRPC CallOption。
CallOptions []grpc.CallOption
}
InvokeOptions 表示一次调用的附加配置。
type Invoker ¶
type Invoker interface {
Invoke(ctx context.Context, ref ServiceRef, method string, req any, resp any, options ...InvokeOption) error
}
Invoker 定义统一调用入口。
与业务代码直接操作 grpc.ClientConn 不同, Invoker 允许框架在调用前统一完成: - 服务目标解析; - metadata 注入; - Authz 预检查; - 底层连接复用。
type Locator ¶
type Locator interface {
Resolve(ctx context.Context, ref ServiceRef) (Target, error)
}
Locator 定义“如何把服务身份解析为可拨号目标”。
标准实现下,Locator 可能只是把 service + namespace 组装成 DNS; 轻量实现下,Locator 也可以在内部维护 watch、缓存、CoreDNS 同步等复杂逻辑。 这些差异都不应泄漏给业务调用方。
type ServiceEndpoint ¶
type ServiceEndpoint struct {
// Address 表示实例地址,通常是 ip:port 或 host:port。
Address string `json:"address"`
// Weight 表示实例权重。
Weight int `json:"weight"`
// Healthy 表示实例当前健康状态。
Healthy bool `json:"healthy"`
// Meta 表示实例附带的轻量元信息,例如标签、版本、可用区等。
Meta map[string]string `json:"meta"`
}
ServiceEndpoint 表示底层实例级端点。
它只服务于 Locator、Dialer、轻量实现内部缓存等基础设施场景, 不再作为业务调用侧的中心模型暴露。
type ServiceRef ¶
type ServiceRef struct {
// Service 表示目标服务名。
Service string `json:"service"`
// Namespace 表示目标命名空间。
// 在 K8s 主路径下,最终 DNS 主要依赖 service + namespace 组合生成。
Namespace string `json:"namespace"`
// Env 表示逻辑环境。
// 它更适合参与平台治理、配置域和策略域选择,而不一定直接进入 DNS。
Env string `json:"env"`
// Port 表示可选端口覆盖项。
// 大多数场景建议由核心库使用默认端口补齐;只有个别服务端口特殊时才显式设置。
Port uint16 `json:"port"`
}
ServiceRef 表示一次调用面向的“服务身份”。
这里表达的是“我要调用哪个服务”,而不是“我要连接哪个节点”。 因此它只保留服务级别的最小身份信息,不承载节点列表等旧 registry 语义。
func (ServiceRef) EffectivePort ¶
func (s ServiceRef) EffectivePort(defaultPort uint16) (uint16, error)
EffectivePort 返回最终应使用的端口。
规则如下: 1. 若 ServiceRef 自身显式提供端口,则优先使用; 2. 否则尝试使用调用方提供的默认端口; 3. 若两者都不可用,则返回错误。
func (ServiceRef) NamespaceName ¶
func (s ServiceRef) NamespaceName() string
NamespaceName 返回去除首尾空格后的命名空间。
func (ServiceRef) Validate ¶
func (s ServiceRef) Validate() error
Validate 校验 ServiceRef 是否具备生成逻辑目标所需的最小字段。
当前版本仍然要求 namespace 显式存在, 因为这是最稳定、最容易排障的入参形式。
func (ServiceRef) WithPort ¶
func (s ServiceRef) WithPort(port uint16) ServiceRef
WithPort 返回带端口覆盖项的新 ServiceRef。 该方法适合在默认端口不满足时,以不可变方式构造新的服务身份。
type StaticLocator ¶
type StaticLocator struct {
// Options 控制 target 的构造方式,例如默认端口、集群域和 resolver scheme。
Options TargetOptions
}
StaticLocator 是最简单的 Locator 实现。
它不依赖任何外部注册中心,也不维护节点列表, 只负责按照统一规则把 ServiceRef 转换为标准 Target。
该实现非常适合作为: - `go-k8s/invocation` 的默认基础; - 单元测试中的轻量定位器; - 未来 etcd / consul 轻量实现的公共兜底逻辑。
func (StaticLocator) Resolve ¶
func (s StaticLocator) Resolve(_ context.Context, ref ServiceRef) (Target, error)
Resolve 按照 StaticLocator 的固定规则,把 ServiceRef 转换为 Target。
type Target ¶
type Target struct {
// ResolverScheme 表示 gRPC resolver scheme,例如 dns。
ResolverScheme string `json:"resolver_scheme"`
// Host 表示目标主机名。
Host string `json:"host"`
// Port 表示目标端口。
Port uint16 `json:"port"`
}
Target 表示最终可拨号的服务目标。
它是 Locator 解析后的结果: - Host/Port 用于实际网络连接; - ResolverScheme 用于生成标准的 gRPC target; - Address 是 host:port 的网络地址表示。
func BuildTarget ¶
func BuildTarget(ref ServiceRef, options TargetOptions) (Target, error)
BuildTarget 根据 ServiceRef 构造标准 Target。
该函数是 K8s + Istio 主路径的默认实现形态: 通过 service + namespace + clusterDomain 生成统一主机名, 再配合端口和 resolver scheme 得到最终 gRPC target。
func (Target) GRPCTarget ¶
GRPCTarget 返回适合 grpc.NewClient 使用的 target 字符串。
例如: - dns:///auth.default.svc.cluster.local:9000 - 若 ResolverScheme 为空,则退化为普通 host:port。
type TargetOptions ¶
type TargetOptions struct {
// DefaultPort 表示默认 gRPC 端口。
// 当 ServiceRef.Port 为空时,会使用该字段补齐。
DefaultPort uint16
// ClusterDomain 表示集群域,默认值为 svc.cluster.local。
ClusterDomain string
// ResolverScheme 表示 gRPC resolver scheme,默认值为 dns。
ResolverScheme string
}
TargetOptions 表示将 ServiceRef 解析为 Target 时使用的公共选项。
type UnaryInvokeFunc ¶
type UnaryInvokeFunc func(ctx context.Context, conn *grpc.ClientConn, method string, req any, resp any, options ...grpc.CallOption) error
UnaryInvokeFunc 表示底层 unary 调用函数。
通过把真实调用抽象成函数, 可以让 UnaryInvoker 在测试中替换掉真实的 grpc.ClientConn.Invoke。
type UnaryInvoker ¶
type UnaryInvoker struct {
// Dialer 负责连接获取与复用。
Dialer Dialer
// Authorizer 是可选依赖;若为空,则跳过 Authz 预检查。
Authorizer Authorizer
// InvokeFunc 是可选依赖;若为空,则默认调用 grpc.ClientConn.Invoke。
InvokeFunc UnaryInvokeFunc
}
UnaryInvoker 是默认的 Invoker 实现。
它的执行流程非常明确: 1. 基于 ServiceRef 获取连接; 2. 基于 InvocationContext 构造统一 metadata; 3. 在真正发起 gRPC 调用前执行 Authz 判定; 4. 使用 grpc.ClientConn.Invoke 发起 unary 调用。
func (*UnaryInvoker) Invoke ¶
func (u *UnaryInvoker) Invoke(ctx context.Context, ref ServiceRef, method string, req any, resp any, options ...InvokeOption) error
Invoke 执行一次标准 unary 调用。