Help us shape the future of Go! Take the 2026 Go Developer Survey

httpx

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: MIT Imports: 33 Imported by: 0

README

httpx

高级 HTTP 客户端——服务发现/熔断/重试/指标/链路透传

🌐 项目主页:https://oekit.github.io/ · 名称由来:Open Easy Kit(开源 · 易用 · 工具集合) 🤖 AI Agent:本仓规范与硬规则见 AGENTS.md;机器可读索引见 llms.txt(接口签名以源码为准)。

安装

go get github.com/oekit/httpx@v0.5.0

这个仓库做什么

httpx 是基于 Hertz Client 的高级 HTTP 客户端:把服务发现、熔断、重试、指标、 链路透传这些“每次都要手写一遍”的东西变成构造选项。

核心能力

  • WithNNS:对接 NNS 服务发现(实例列表自动刷新)
  • WithCircuitBreaker:熔断(per-service,错误可判定 ErrCircuitOpen)
  • WithRetryConfig:指数退避 + 抖动重试(Hertz 官方引擎,连接池感知)
  • WithMetrics:Prometheus 弹性指标(熔断/重试计数)
  • WithTracePropagation:OTel 链路透传
  • WithDialFunc / WithHertzOption:拨号层/原生 Hertz 选项透传(出站 SSRF 防护)
  • DoDetail:返回 status + 原始 body(2xx 也带 body,区别于 DoJSON)
  • 实例权重贯通:注册中心的权重配置真实生效于负载均衡

快速使用

import "github.com/oekit/httpx"

c := httpx.NewClient("payment-svc", httpx.WithTimeout(5*time.Second))
var out Result
err := c.GetJSON(ctx, "/api/v1/pay", &out)

需要原始响应(状态码 + body)时用 DoDetail:

status, body, err := c.DoDetail(ctx, http.MethodPost, "/api/v1/pay", req)
// 2xx: err == nil,body 为原始响应体
// 非 2xx: status、body 仍有值,err 为 *ServiceError

出站 SSRF 防护套路

调用方 URL 来自不受信输入时(用户配置的回调/推送地址、任意外链抓取、 开放平台跳转等),需要两层防线:

  1. URL 层字面量检查(请求前):拒绝非 http(s) scheme、字面量内网 IP (127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、169.254.0.0/16、 ::1、fc00::/7 等)、.local/.internal 等内部主机名。
  2. 拨号层解析后 IP 检查(建连时):WithDialFunc 在真正建立 TCP 连接前 校验目标解析出的 IP——字面量检查通过的域名仍可能解析到内网(DNS rebinding: 第一次解析公网、第二次解析 127.0.0.1),必须以建连瞬间的解析结果为准。
c := httpx.NewClient("user-callback",
    httpx.WithDialFunc(func(addr string) (network.Conn, error) {
        host, _, err := net.SplitHostPort(addr)
        if err != nil {
            return nil, err
        }
        ips, err := net.LookupIP(host) // 以本次解析结果为准
        if err != nil {
            return nil, err
        }
        for _, ip := range ips {
            if isBlockedIP(ip) { // 内网/黑名单判定
                return nil, fmt.Errorf("ssrf guard: blocked ip %s", ip)
            }
        }
        return dialer.DialConnection(context.Background(), network.TCP, addr)
    }),
)

尚未封装的 Hertz 原生能力用 WithHertzOption(opts ...config.ClientOption) 逃生舱透传。

边界

  • 轻量 WebSocket/NATS 等不经过服务发现的场景 → network
  • 服务治理语义(实例缓存/多级降级)在 nns

矩阵总览(24 活跃模块,自动生成)

模块 内容 矩阵内依赖
pkg 微工具集 19 合 1(errors/bloomx/contextx/container/stringx/slicex/enumx/convert/encoding/jsonrepair/httpjson/mathx/pathx/pagination/ptrx/timex/cache/bufiox/strmap;v0.10.0 起 uidgen/validator 拆至 kitx);cache(v0.4.0 起)含缓存接口 CacheAside + BatchGetter 批量能力(MGet)+ LocalCache/SingleFlightCache + cachetest 契约 + Checker;container(v0.9.0 起,收编原 collectionx)泛型容器 Set/Ring/Queue/SafeMap + Map(sync.Map 背书)/Slice(并发安全);timex/stringx(v0.7.0 起)时间段边界 BeginningOf/EndOf 七对(分/时/日/周/月/季/年,周起始显式参数)+ trie 多模式替换器 Replacer(最长匹配)/ NewMask 敏感词遮罩;singleflighttest(v0.8.0 起)singleflight 共享契约测试套件(internal 与 concurrency 双侧引用) —
concurrency 并发与流控原语(async/gopool/group/singleflight/progress/syncx/ratelimit/retry)+ window 滑动窗口 / breaker 自适应熔断(规范哨兵 ErrCircuitOpen)/ shedding CPU 自适应降载 / batch 攒批执行器(满条数/满字节/窗口去重)/ timewheel 单级时间轮;v0.5.0 起 retry 指数退避+抖动(MaxDelay 封顶/溢出饱和)、loop 周期原语(忙时丢 tick/单轮 panic 收编/FirstDelay 可打断)、async labeled RunSafe(panic 按任务标签上报)、syncx.FanInErr 逐槽错误(panic 槽显式标记)、KeyedLimiter 增强(容量护栏/RetryAfter/速率热更)并接入 pkg/singleflighttest 契约测试 pkg
logx 统一日志门面(多后端可替换 + Sink + caller 归属)+ 优雅关停;桥接子包 hlog/hertzlog/kitexlog 为嵌套模块按需引入 —
core 应用基建件(governance 治理 schema / config 配置加载 + default/env/range/options tag 校验 / lifecycle 契约 / network IP 工具 / version) —
kitx 标识与校验——uidgen(Snowflake 全局单例+Extract 元数据、手写 RFC 4122 v4 UUID 零第三方依赖、RandomHex/RandomString 拒绝采样随机串)+ validator(go-playground/validator v10 接口化门面:struct tag 校验/自定义规则注册/ValidationError Unwrap 为 BizError 400 对接 middleware.Fail),自 pkg v0.10.0 拆出 pkg
metrics Prometheus 门面 + 弹性指标族 core
tracing OpenTelemetry 追踪 + trace_id 真相源 logx
registry 注册发现核心 + Nacos 实现 + Nacos 配置源 + sdbridge core、logx
data 数据访问门面——复刻 ekit data/ 能力面:cache/rediscache/crud/distlock/gormx/redisx/timertask/cachetest 八子包 re-export(类型同一,实现住 pkg 与各子仓)+ cached 缓存读写编排(写后失效/事务提交后失效/查询缓存版本号失效/GetByIDs 批量点读 MGet 快路径/bloom 防穿透)+ twolevel 两级缓存与跨实例失效广播(v0.7.0 起本仓唯二非 re-export 实现);all/ 聚合模块已废弃 retract concurrency、gormx、logx、pkg、redisx、timertask
gormx SQL/GORM 全家——连接池增强、框架无关 CRUD Service、仓储(原 oekit/gorm,v0.3.0 更名) logx、pkg
redisx Redis 全家——客户端封装(根包)、分布式缓存 cache/、分布式锁 distlock、分布式限流 ratelimit(Lua 三态 + 故障本地兜底) concurrency、logx、pkg
etcdx etcd 全家——客户端封装(根包:生产默认值/Health 探活/Close(ctx) 幂等)、registry 注册发现实现(SPI 对接 registry/nacos 链路:Lease KeepAlive 注册 + 丢约指数退避自动重注册、prefix Watch 订阅推送、ConfigStore KV 配置监听)、distlock 分布式锁(Session+concurrency.Mutex 公平排队,接口与 redisx/distlock.Locker 同形可互换,可选无 etcd 降级放行) concurrency、core、logx、registry
httpx HTTP 客户端 + 负载均衡——服务发现/熔断(规范哨兵 ErrCircuitOpen)/重试/指标/OTel 透传/一致性哈希(权重感知虚拟副本) concurrency、core、logx、metrics、registry、tracing
network 轻量网络客户端——WebSocket/NATS/MQ 抽象、连接与流工具 concurrency、logx、tracing
timertask 分片定时任务(FNV-1a、心跳续约);v0.1.5 起可选可靠投递 DeliveryAtLeastOnce(租约 + Ack + 可见性超时;过期租约回扫重投/死信、停机 best-effort 收租,v0.1.7 接入生命周期真正生效) concurrency、logx
middleware Hertz 自研标准中间件栈 + contrib 桥接 + hmw + SheddingMiddleware 自适应降载;v0.6.0 起 accesslog 凭证路径脱敏(WithAccessLogRedactPathPrefixes)、ratelimit 默认 KeyFunc 去端口(连接桶→地址桶) concurrency、core、logx、metrics、pkg、registry、tracing
k8s Kubernetes 客户端封装——RESTConfig/Clientset/DynamicClient 构建(显式 kubeconfig → in-cluster 自动 → KUBECONFIG/~/.kube/config 逐级回退,QPS/Burst 限流默认 50/100)+ leaderelection 子包 Lease 选主简化封装(OnStartedLeading/OnStoppedLeading/OnNewLeader 回调,主备单活,仅要求 Lease CRUD 权限) logx
nns NNS 服务治理客户端——provider 无关发现/配置/实例缓存 concurrency、core、logx、registry
nns-endpoint NNS 端点工厂——per-service 熔断、换实例重试、gRPC 池 concurrency、core、httpx、logx、metrics、nns、registry
bootstrap 应用生命周期引导——bootstrap.Run 骨架 + healthz concurrency、logx
hertz Hertz 运行时集成——日志桥接、生命周期、SSE/health/metrics、适配器、OTel、crudh/validatorh(基于 kitx/validator)/versionh(原 handler 微库收编) bootstrap、concurrency、core、gormx、kitx、logx、metrics、middleware、nns、pkg、registry、tracing
kitex Kitex 生态——日志桥接、治理热更、生命周期、BizError 桥接、kitexotel、istio(xDS 动态熔断,原 istio 微库收编) bootstrap、concurrency、core、logx、metrics、nns、pkg、registry
workflow 组合式流程编排——串行/并行/异步/条件分支 + Hook AOP concurrency、logx
kitex-examples Kitex echo 示例——client/server + IDL + 治理配置 bootstrap、concurrency、core、kitex、logx、metrics、nns、pkg、registry、tracing

依赖严格自底向上;微库已合并为 pkg,旧微库仓已删除。

本仓在矩阵中的位置与依赖见上表「矩阵内依赖」列。历史沿革:源自 ekit 单体库 (git.enjoye.top/enjoydream/ekit v0.34.0,冻结维护),2026-10 拆分为独立 module。

License

MIT — 见 LICENSE

Documentation

Overview

Package httpx 提供 JSON HTTP 客户端。

所有 enjoydream 后端服务共享此包,统一 HTTP 调用方式。

核心特性

  • JSON 请求/响应自动序列化
  • Prometheus 指标采集
  • 熔断器(gobreaker)
  • 指数退避重试
  • OpenTelemetry 追踪
  • 文件上传(multipart/form-data)
  • DoDetail:status + 原始 body(2xx 也返回)
  • WithDialFunc/WithHertzOption:拨号层拦截与 Hertz 原生选项透传(SSRF 防护)

快速接入

创建客户端:

client := ehttp.NewClient("user-service",
    ehttp.WithBaseURL("http://user-service:8080"),
    ehttp.WithTimeout(5*time.Second),
    ehttp.WithTracePropagation(),
)

GET 请求:

var users []User
err := client.GetJSON(ctx, "/api/users", &users)

POST 请求:

var result CreateUserResp
err := client.PostJSON(ctx, "/api/users", req, &result)

需要状态码与原始响应体时用 DoDetail(2xx 也返回 body;非 2xx 额外返回 *ServiceError):

status, body, err := client.DoDetail(ctx, http.MethodPost, "/api/users", req)

出站 SSRF 防护

调用方 URL 来自不受信输入时做两层检查:URL 层字面量拒绝内网 IP/主机名; 拨号层用 WithDialFunc 在建连前校验解析后的 IP(防 DNS rebinding)。 详见 README「出站 SSRF 防护套路」。

监控集成

使用 WithMetrics 启用 Prometheus 指标:

client := ehttp.NewClient("user-service",
    ehttp.WithMetrics(metrics.Registry, "myservice"),
)

指标包括(namespace 未显式指定时前缀为 http_client):

  • {ns}_requests_total{service, target, method, status_code}
  • {ns}_request_duration_seconds{service, target, method}
  • {ns}_requests_in_flight{service, target, method}

同一 Registry + namespace 下创建多个 Client 是安全的:同名指标自动复用 已注册的 collector。禁止 host/IP/port/path 等高基数 label。

熔断器

使用 WithCircuitBreaker 启用熔断保护:

client := ehttp.NewClient("user-service",
    ehttp.WithCircuitBreaker("user-service", gobreaker.Settings{
        MaxRequests: 3,
        Interval:    10 * time.Second,
        Timeout:     30 * time.Second,
    }),
)

熔断器状态变化会自动记录到日志。

错误处理

返回 ServiceError 类型,包含服务名、操作、状态码和响应体:

var svcErr *ehttp.ServiceError
if errors.As(err, &svcErr) {
    log.Printf("service: %s, action: %s, code: %d, message: %s",
        svcErr.Service, svcErr.Action, svcErr.Code, svcErr.Message)
}

Index

Constants

This section is empty.

Variables

View Source
var ErrCircuitOpen = breaker.ErrCircuitOpen

ErrCircuitOpen 表示熔断器处于打开状态,请求被拒绝。

规范哨兵定义于 concurrency/breaker(错误消息逐字为 "circuit breaker is open"), httpx 此处仅别名它:gobreaker 熔断路径与 adaptive 熔断器(concurrency/breaker) 拒绝时返回同一 sentinel,errors.Is 全链统一判定。判定一律用 errors.Is。

Functions

func NodesFromEndpoints added in v0.4.0

func NodesFromEndpoints(endpoints []string) []loadbalance.Node

NodesFromEndpoints 把字符串端点列表合成为等权节点(权重 1、无元数据)。

func SelectorNodes added in v0.4.0

func SelectorNodes(insts []registry.Instance) []loadbalance.Node

SelectorNodes 把注册中心实例切片适配为 Selector 节点(字段闭包映射, 地址补 "http://" 前缀,与历史 endpoint 形态一致)。

func WithPriority

func WithPriority(ctx context.Context, priority Priority) context.Context

WithPriority 将优先级注入 context。

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client 是封装了 Hertz HTTP 客户端的高层 HTTP 调用器,支持服务发现、负载均衡、熔断和指标。

func NewClient

func NewClient(service string, opts ...ClientOption) *Client

NewClient 创建 HTTP 客户端实例,应用指定的配置选项。

func (*Client) Close

func (c *Client) Close()

Close 关闭客户端,释放资源。

func (*Client) DoCodec added in v0.4.0

func (c *Client) DoCodec(ctx context.Context, codecName, method, path string, body any, out any) error

DoCodec 使用指定编解码器发送请求:body 经 codec.Marshal 序列化并设置 对应 Content-Type;响应按其 Content-Type 反查 codec 反序列化到 out (查不到回退请求 codec)。

func (*Client) DoDetail

func (c *Client) DoDetail(ctx context.Context, method, path string, body any) (int, []byte, error)

DoDetail 使用指定的 HTTP 方法发送请求,返回状态码与原始响应体。 与 DoJSON/DoRaw 不同:2xx 也返回原始 body(DoJSON 只把 body 解到 out, DoRaw 仅在成功时返回 body),非 2xx 同时返回 status、body 与 *ServiceError,调用方可自行判定如何处理响应内容。 传输层失败时 status 为 0、body 为 nil。

func (*Client) DoJSON

func (c *Client) DoJSON(ctx context.Context, method, path string, body any, out any) error

DoJSON 使用指定的 HTTP 方法发送 JSON 请求(等价 DoCodec(codec.DefaultName, ...))。

func (*Client) DoRaw

func (c *Client) DoRaw(ctx context.Context, method, path string, body any) ([]byte, error)

DoRaw 使用指定的 HTTP 方法发送 JSON 请求,返回原始响应字节数据。

func (*Client) GetJSON

func (c *Client) GetJSON(ctx context.Context, path string, out any) error

GetJSON 发送 GET 请求并将响应反序列化到 out。

func (*Client) Hertz

func (c *Client) Hertz() *client.Client

Hertz 返回底层 Hertz Client 实例,用于直接操作。

func (*Client) PostJSON

func (c *Client) PostJSON(ctx context.Context, path string, body any, out any) error

PostJSON 发送 POST 请求。

func (*Client) SetTarget

func (c *Client) SetTarget(target string)

SetTarget 运行时更新 target label。

func (*Client) UploadBytes

func (c *Client) UploadBytes(ctx context.Context, path string, data []byte, fieldName, fileName string, extraFields map[string]string, out any) error

UploadBytes 上传字节数据 (multipart/form-data)。

func (*Client) UploadFile

func (c *Client) UploadFile(ctx context.Context, path, filePath, fieldName string, extraFields map[string]string, out any) error

UploadFile 上传文件 (multipart/form-data)。

type ClientOption

type ClientOption func(*Client)

ClientOption 是 Client 的配置函数类型。

func WithBaseURL

func WithBaseURL(u string) ClientOption

WithBaseURL 设置客户端的基础 URL。

func WithBasicAuth

func WithBasicAuth(user, password string) ClientOption

WithBasicAuth 为所有请求设置 Basic Auth 认证。

func WithBearerToken

func WithBearerToken(token string) ClientOption

WithBearerToken 为所有请求设置 Bearer Token 认证。

func WithCircuitBreaker

func WithCircuitBreaker(name string, settings gobreaker.Settings) ClientOption

WithCircuitBreaker 为客户端启用熔断器,使用指定的名称和配置。

func WithCookieJar

func WithCookieJar(jar http.CookieJar) ClientOption

WithCookieJar 为客户端设置 Cookie Jar。 Hertz client 不支持运行时设置 CookieJar;此选项记录警告并忽略。

func WithDebug

func WithDebug() ClientOption

WithDebug 开启调试日志。 Hertz client 不支持运行时调试开关(日志由 hlog 全局控制),此选项留作占位。

func WithDialFunc

func WithDialFunc(fn network.DialFunc, dialers ...network.Dialer) ClientOption

WithDialFunc 注入自定义拨号函数,透传至 Hertz client.WithDialFunc。 典型用途是出站 SSRF 防护的拨号层拦截:在真正建连前校验 addr 解析出的 IP 是否落在内网/黑名单(URL 层字面量检查挡不住 DNS rebinding)。 dialers 可选,用于覆盖 Hertz 默认传输实现。

func WithEndpoints

func WithEndpoints(endpoints ...string) ClientOption

WithEndpoints 设置静态 endpoint 列表。

func WithHertzOption

func WithHertzOption(opts ...config.ClientOption) ClientOption

WithHertzOption 透传任意 Hertz client 配置项(逃生舱)。 优先使用语义化选项(WithTimeout/WithDialFunc/WithRetryConfig 等); 仅当某项 Hertz 能力尚未封装时使用,按传入顺序追加到 client.NewClient 的选项列表尾部。

func WithMetrics

func WithMetrics(registry prom.Registerer, namespace string) ClientOption

WithMetrics 为客户端启用 Prometheus 指标采集。

func WithNNS

func WithNNS(serviceName string, nnsClient NNSClient) ClientOption

WithNNS 启用 NNS 服务发现。

func WithOnBeforeRequest

func WithOnBeforeRequest(fn func(ctx context.Context, req *protocol.Request) error) ClientOption

WithOnBeforeRequest 注册请求前置钩子。 ⚠️ Breaking: 签名从 func(*req.Client, *req.Request) 改为 func(ctx context.Context, req *protocol.Request)(hertz protocol 类型)。

func WithPriorityQueue

func WithPriorityQueue(capacity int) ClientOption

WithPriorityQueue 启用请求优先级队列。

func WithRefreshInterval

func WithRefreshInterval(d time.Duration) ClientOption

WithRefreshInterval 设置 endpoint 刷新间隔。

func WithRetryConfig

func WithRetryConfig(maxAttempts uint, initDelay, maxDelay, maxJitter time.Duration) ClientOption

WithRetryConfig 配置请求重试策略,走 Hertz 官方 client.WithRetryConfig。 参数语义:

  • maxAttempts:总尝试次数(>=1,含首次请求);0 = 走 Hertz 默认 1 次
  • initDelay:首次重试前的等待时间(指数退避基数,对应 retry.Config.Delay)
  • maxDelay:重试延迟上限(避免退避无界增长,retry.Delay 内部封顶)
  • maxJitter:随机抖动上限(避免雪崩,对应 retry.Config.MaxJitter)

DelayPolicy 必须显式设置:hertz WithRetryConfig 的默认 DelayPolicy 是 retry.DefaultDelayPolicy(恒返回 0,参见 hertz pkg/app/client/retry/retry.go), 不设置的话 initDelay/maxDelay/maxJitter 三个参数全部无效、重试零等待。 ekit 固定注入 CombineDelay(BackOffDelayPolicy, RandomDelayPolicy): 每次重试延迟 = initDelay<<attempts + [0, maxJitter) 随机抖动,MaxDelay 封顶。

⚠️ 重试触发条件(与 Hertz 默认不同):

Hertz 官方 DefaultRetryIf 仅在网络错误时重试,不重试 5xx 响应(只检查
idempotent 方法 — 参见 vendor 源码 protocol/client/client.go:82)。
ekit WithRetryConfig 默认同时重试 5xx + network error,语义对齐旧
WithRetry(手写 middleware) 行为。如果需要更严格的条件(例如只重试
GET/HEAD/OPTIONS/TRACE/特定状态码),可通过 WithRetryIfFunc 覆盖。

官方依据:https://www.cloudwego.io/zh/docs/hertz/tutorials/basic-feature/client/ (Client 配置表 WithRetryConfig 示例明确列出 retry.WithDelayPolicy; 退避/抖动语义见 hertz pkg/app/client/retry 包:BackOffDelayPolicy = Delay<<attempts, RandomDelayPolicy = fastrand.Int63n(MaxJitter),CombineDelay 求和)

用法:

cli := httpx.NewClient("my-svc",
    httpx.WithRetryConfig(3, 100*time.Millisecond, 1*time.Second, 50*time.Millisecond),
)

func WithRetryIfFunc

func WithRetryIfFunc(fn func(req *protocol.Request, resp *protocol.Response, err error) bool) ClientOption

WithRetryIfFunc 覆盖 ekit 默认重试触发条件(5xx + network error), 由用户传更严格的 predicate(例如只对 GET 重试、特定状态码范围等)。 不调 WithRetryIfFunc 时,WithRetryConfig 注入默认 5xx + network error 条件。

func WithSelector added in v0.4.0

func WithSelector(sel loadbalance.Selector) ClientOption

WithSelector 设置节点选择器(roundrobin/random/weighted/一致性哈希等, 经 loadbalance.NewSelector 或 NewConsistentHashSelector 构造)。 v0.4.0 起替代 WithBalance。

func WithServiceResolver

func WithServiceResolver(resolver ServiceResolver) ClientOption

WithServiceResolver 设置自定义服务发现解析器。

func WithTLSSkipVerify

func WithTLSSkipVerify() ClientOption

WithTLSSkipVerify 跳过 TLS 证书验证。

func WithTarget

func WithTarget(target string) ClientOption

WithTarget 设置指标 target label 的值。

func WithTimeout

func WithTimeout(d time.Duration) ClientOption

WithTimeout 设置 HTTP 请求超时时间。

func WithTracePropagation

func WithTracePropagation() ClientOption

WithTracePropagation 启用 OpenTelemetry 上下文透传(traceparent / tracestate / baggage), 走 Hertz client.UseAsLast 注入,在所有自定义中间件之后执行,

避免 trace 头被其他中间件覆盖或重复。

propagator 通过 otel.GetTextMapPropagator() 读取(默认 W3C TraceContext + Baggage), 与 ekit observability/tracing 全局配置保持一致 — 调用方只需先初始化 tracer + propagator。

官方依据:https://www.cloudwego.io/zh/docs/hertz/tutorials/basic-feature/client/ (UseAsLast 章节:"中间件设置在 ctx.lastMiddleware 中,使用 Use 设置的中间件链存放在 ctx.mws 中,两者相对独立,只是在执行客户端中间件链的最后才执行 ctx.lastMiddleware")

type ConsistentHashOption

type ConsistentHashOption func(*ConsistentHashSelector)

ConsistentHashOption ConsistentHashSelector 的可选参数。

func WithConsistentHashFunc

func WithConsistentHashFunc(fn func([]byte) uint64) ConsistentHashOption

WithConsistentHashFunc 自定义哈希函数(默认 FNV-1a 64)。nil 被忽略。

func WithConsistentReplicas

func WithConsistentReplicas(n int) ConsistentHashOption

WithConsistentReplicas 设置每个节点的虚拟副本数(默认 100)。 n <= 0 被忽略。

type ConsistentHashSelector added in v0.4.0

type ConsistentHashSelector struct {
	// contains filtered or unexported fields
}

ConsistentHashSelector 一致性哈希选择器:同一 key 稳定路由到同一节点, 节点增减仅引起相邻键的重新映射。适合有状态粘滞路由(同用户/同租户 粘住同实例)且实例列表动态变化的场景。

key 取 SelectOption WithKey 值(httpx EndpointManager 默认传请求 PATH); 节点权重按比例折算虚拟副本数(等权均值归一,clamp 到 [1, 4×base]), 注册中心权重配置照常生效。

v0.4.0 起替代 ConsistentHashBalance(BalanceStrategy 形态已删除)。

func NewConsistentHashSelector added in v0.4.0

func NewConsistentHashSelector(opts ...ConsistentHashOption) (*ConsistentHashSelector, error)

NewConsistentHashSelector 创建一致性哈希选择器。

func (*ConsistentHashSelector) Select added in v0.4.0

Select 按一致性哈希选择节点。

type EndpointManager

type EndpointManager struct {
	// contains filtered or unexported fields
}

EndpointManager endpoint 管理器:动态刷新节点快照 + 缓存降级, 选择经 loadbalance.Selector 完成。

func NewEndpointManager

func NewEndpointManager(resolver ServiceResolver, selector loadbalance.Selector, refreshInterval time.Duration) *EndpointManager

NewEndpointManager 创建 endpoint 管理器。 selector 为 nil 时回退 roundrobin;refreshInterval > 0 且 resolver 非空时 启动刷新循环。

func (*EndpointManager) GetNodes added in v0.4.0

func (m *EndpointManager) GetNodes() []loadbalance.Node

GetNodes 获取节点快照(优先最新,降级缓存)。

func (*EndpointManager) Pick

Pick 选择一个节点地址,返回地址与结果回写句柄(调用结束后以最终 错误调用 done;done 为 nil 表示无需回写)。 key 用于一致性选点类 Selector(httpx 以请求 PATH 为默认键)。

func (*EndpointManager) SetEndpoints

func (m *EndpointManager) SetEndpoints(endpoints []string)

SetEndpoints 设置静态端点列表(等权合成,停止动态刷新语义不变)。

func (*EndpointManager) SetNodes added in v0.4.0

func (m *EndpointManager) SetNodes(nodes []loadbalance.Node)

SetNodes 直接设置节点快照。

func (*EndpointManager) Stop

func (m *EndpointManager) Stop()

Stop 停止刷新。

type InstanceResolver added in v0.4.0

type InstanceResolver interface {
	// ResolveInstances 解析服务名称,返回实例列表。
	ResolveInstances(ctx context.Context) ([]registry.Instance, error)
}

InstanceResolver 是 ServiceResolver 的可选增强接口:提供完整实例视图 (含权重与元数据)。EndpointManager 检测到 resolver 实现本接口时, 实例的权重与 Metadata 贯通到 Selector(加权策略与 WithFilter 生效); 仅实现 ServiceResolver 的 resolver 等权合成(权重 1、无元数据)。

type NNSClient

type NNSClient interface {
	GetInstances(ctx context.Context, serviceName string) ([]registry.Instance, error)
}

NNSClient NNS 客户端接口,与顶层 nns.NNSClient.GetInstances 签名一致。

type NNSResolver

type NNSResolver struct {
	// contains filtered or unexported fields
}

NNSResolver NNS 服务发现解析器(实现 ServiceResolver 与 InstanceResolver)。

func NewNNSResolver

func NewNNSResolver(serviceName string, nnsClient NNSClient) *NNSResolver

NewNNSResolver 创建 NNS 解析器。

func (*NNSResolver) Resolve

func (r *NNSResolver) Resolve(ctx context.Context) ([]string, error)

Resolve 解析服务名称,返回地址列表(丢弃权重与元数据)。

func (*NNSResolver) ResolveInstances added in v0.4.0

func (r *NNSResolver) ResolveInstances(ctx context.Context) ([]registry.Instance, error)

ResolveInstances 解析服务名称,返回实例列表(地址合成 "http://ip:port")。 透传 context 到 NNS,保留超时和 trace_id 语义。

type Priority

type Priority int

Priority 请求优先级。

const (
	PriorityLow    Priority = 0
	PriorityNormal Priority = 1
	PriorityHigh   Priority = 2
)

func GetPriority

func GetPriority(ctx context.Context) Priority

GetPriority 从 context 获取优先级。

type PriorityQueue

type PriorityQueue struct {
	// contains filtered or unexported fields
}

PriorityQueue 分级准入控制队列。

注意语义:这是分级准入控制而非严格优先级队列——high/normal/low 三级 各自独立计数(同级 FIFO),不保证跨级抢占;高优先级请求不会抢占已获准的 低优先级请求,仅在自身级别容量内准入。未知优先级按 PriorityNormal 处理。

func NewPriorityQueue

func NewPriorityQueue(capacity int) *PriorityQueue

NewPriorityQueue 创建优先级队列。

func (*PriorityQueue) Acquire

func (q *PriorityQueue) Acquire(ctx context.Context, priority Priority) bool

Acquire 获取许可(按优先级)。

func (*PriorityQueue) Len

func (q *PriorityQueue) Len() int

Len 返回队列长度。

func (*PriorityQueue) Release

func (q *PriorityQueue) Release(priority Priority)

Release 释放许可。

priority 必须与 Acquire 时一致;未知优先级按 PriorityNormal 释放 (与 Acquire 的 default 分支对齐),避免静默泄漏许可。

type ServiceError

type ServiceError struct {
	Service string
	Action  string
	Code    int
	Message string
}

ServiceError 表示 HTTP 服务调用返回的业务错误。

func (*ServiceError) Error

func (e *ServiceError) Error() string

Error 实现 error 接口,返回格式化的错误信息。

type ServiceResolver

type ServiceResolver interface {
	// Resolve 解析服务名称,返回可用的 endpoint 列表。
	Resolve(ctx context.Context) ([]string, error)
}

ServiceResolver 服务发现解析器接口。

type StaticResolver

type StaticResolver struct {
	// contains filtered or unexported fields
}

StaticResolver 静态 endpoint 解析器。

func NewStaticResolver

func NewStaticResolver(endpoints []string) *StaticResolver

NewStaticResolver 创建静态解析器。

func (*StaticResolver) Resolve

func (r *StaticResolver) Resolve(ctx context.Context) ([]string, error)

Resolve 返回静态配置的 endpoint 列表。

Directories

Path Synopsis
Package codec 提供请求/响应编解码器的注册制抽象(参照 go-kratos encoding)。
Package codec 提供请求/响应编解码器的注册制抽象(参照 go-kratos encoding)。
Package loadbalance 提供与具体服务发现实现解耦的节点选择抽象(Selector, 参照 go-kratos selector)。
Package loadbalance 提供与具体服务发现实现解耦的节点选择抽象(Selector, 参照 go-kratos selector)。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL