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

httpx

package module
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2026 License: MIT Imports: 34 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.3.1

这个仓库做什么

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 单级时间轮 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、心跳续约) concurrency、logx
middleware Hertz 自研标准中间件栈 + contrib 桥接 + hmw + SheddingMiddleware 自适应降载 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/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 WithPriority

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

WithPriority 将优先级注入 context。

Types

type BalanceStrategy

type BalanceStrategy interface {
	// Pick 从 endpoints 中选择一个。
	Pick(endpoints []string, req *http.Request) string
}

BalanceStrategy 负载均衡策略接口。

func NewBalanceAdapter

func NewBalanceAdapter(b loadbalance.Balancer) BalanceStrategy

NewBalanceAdapter 创建适配器,将 loadbalance.Balancer 包装为 httpx.BalanceStrategy。

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) 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 方法发送请求。

func (*Client) DoRaw

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

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

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 WithBalance

func WithBalance(strategy BalanceStrategy) ClientOption

WithBalance 设置负载均衡策略。

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 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 ConsistentHashBalance

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

ConsistentHashBalance 一致性哈希负载均衡:同一 key 稳定路由到同一 endpoint, endpoint 增减仅引起相邻键的重新映射(对比 HashBalance 的全量重排)。 适合有状态粘滞路由(同用户/同租户粘住同实例)且实例列表动态变化的场景。

key 缺省取请求路径(可用 WithConsistentKeyFunc 定制,如同租户取 header); 实现了 WeightedBalanceStrategy——resolver 提供实例权重时按权重折算各节点 虚拟副本数,注册中心权重配置照常生效。

func NewConsistentHashBalance

func NewConsistentHashBalance(opts ...ConsistentHashOption) *ConsistentHashBalance

NewConsistentHashBalance 创建一致性哈希负载均衡策略。

func (*ConsistentHashBalance) Pick

func (b *ConsistentHashBalance) Pick(endpoints []string, req *http.Request) string

Pick 按一致性哈希选择 endpoint。

func (*ConsistentHashBalance) SetWeights

func (b *ConsistentHashBalance) SetWeights(weights []float64)

SetWeights 更新实例权重(WeightedBalanceStrategy 实现):权重按比例折算 各节点虚拟副本数(等权均值归一),下次 Pick 触发重建环。

type ConsistentHashOption

type ConsistentHashOption func(*ConsistentHashBalance)

ConsistentHashOption ConsistentHashBalance 的可选参数。

func WithConsistentHashFunc

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

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

func WithConsistentKeyFunc

func WithConsistentKeyFunc(fn func(req *http.Request) string) ConsistentHashOption

WithConsistentKeyFunc 自定义路由 key 提取(默认请求路径)。nil 被忽略。 key 语义由业务保证(如同租户取 header 值);恒为空的 key 会把全部请求 路由到同一节点。

func WithConsistentReplicas

func WithConsistentReplicas(n int) ConsistentHashOption

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

type EndpointManager

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

EndpointManager endpoint 管理器。 支持静态配置、动态刷新、缓存降级。

func NewEndpointManager

func NewEndpointManager(resolver ServiceResolver, balance BalanceStrategy, refreshInterval time.Duration) *EndpointManager

NewEndpointManager 创建 endpoint 管理器。

func (*EndpointManager) GetEndpoints

func (m *EndpointManager) GetEndpoints() []string

GetEndpoints 获取 endpoint 列表(优先使用最新,降级使用缓存)。

func (*EndpointManager) Pick

func (m *EndpointManager) Pick(req *http.Request) string

Pick 选择一个 endpoint。

func (*EndpointManager) SetEndpoints

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

SetEndpoints 设置静态 endpoint 列表。

func (*EndpointManager) Stop

func (m *EndpointManager) Stop()

Stop 停止刷新。

type HashBalance

type HashBalance struct{}

HashBalance 哈希负载均衡(基于请求路径 CRC32)。

func (*HashBalance) Pick

func (b *HashBalance) Pick(endpoints []string, req *http.Request) string

Pick 基于请求路径 CRC32 哈希选择 endpoint(同一路径总是路由到同一节点)。

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 服务发现解析器。

func NewNNSResolver

func NewNNSResolver(serviceName string, nnsClient NNSClient) *NNSResolver

NewNNSResolver 创建 NNS 解析器。

func (*NNSResolver) Resolve

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

Resolve 解析服务名称,返回可用的 endpoint 列表(丢弃权重)。

func (*NNSResolver) ResolveWeighted

func (r *NNSResolver) ResolveWeighted(ctx context.Context) ([]WeightedEndpoint, error)

ResolveWeighted 解析服务名称,返回带实例权重的 endpoint 列表。 权重来自注册中心(registry.Instance.Weight),使加权 LB 策略在 httpx 路径上生效;透传 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 列表。

type WeightedBalanceStrategy

type WeightedBalanceStrategy interface {
	BalanceStrategy
	SetWeights(weights []float64)
}

WeightedBalanceStrategy 是 BalanceStrategy 的可选增强接口: 接受实例权重分布的策略。仅对经 NewBalanceAdapter 适配 network/loadbalance.Balancer 的策略生效;自定义 BalanceStrategy 实现不感知权重(等权语义)。

type WeightedEndpoint

type WeightedEndpoint struct {
	Addr   string
	Weight float64
}

WeightedEndpoint 带权重的 endpoint 视图。 Weight 为实例注册权重(<=0 由负载均衡策略按 1 处理),0 值在 注册中心未提供权重时与等权语义等价。

type WeightedResolver

type WeightedResolver interface {
	// ResolveWeighted 解析服务名称,返回带权重的 endpoint 列表。
	ResolveWeighted(ctx context.Context) ([]WeightedEndpoint, error)
}

WeightedResolver 是 ServiceResolver 的可选增强接口:提供带实例权重的 endpoint 视图。EndpointManager 检测到 resolver 实现本接口时,会把真实 权重喂给支持权重的负载均衡策略(见 WeightedBalanceStrategy); 仅实现 ServiceResolver 的 resolver 保持等权语义(历史行为)。

Directories

Path Synopsis
Package loadbalance 提供与具体服务发现实现解耦的负载均衡策略。
Package loadbalance 提供与具体服务发现实现解耦的负载均衡策略。

Jump to

Keyboard shortcuts

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