lb

package
v0.0.0-...-3882d63 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package lb chọn backend cho mỗi request (phase 6): round robin, least connections, P2C+EWMA, consistent hashing; kèm hai cơ chế sức khoẻ song song — active health check (goroutine nền) và passive outlier ejection (đếm lỗi trên traffic thật). Chỉ dùng net + httpx; không net/http.

Ranh giới với proxy: proxy gọi đúng hai hàm — Pick(key) trước khi lấy connection, Done(b, latency, failed) sau khi exchange xong (D2). Inflight đếm theo REQUEST, không theo connection trong pool (P5-3).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Hash32

func Hash32(s string) uint32

Hash32: FNV-1a 64 + bước trộn cuối của MurmurHash3 (fmix64), lấy 32 bit thấp.

Bản đầu chỉ FNV-1a gập 64→32: FNV không có avalanche, các vnode "addr#0", "addr#1", … của CÙNG một backend rơi gần nhau trên ring ⇒ 150 vnode vẫn lệch tải 3.57x, và 1000 vnode vẫn 2.85x (đo ở turn 1, xem phase6-log §1). Vnode chỉ làm mịn khi hash rải đều; fmix64 đưa về 1.17x. Export để test tính `hash % N` đối chứng.

Types

type Backend

type Backend struct {
	Addr string
	// contains filtered or unexported fields
}

Backend là một upstream. Mọi trường đếm là atomic vì Pick/Done chạy từ nhiều goroutine client cùng lúc; health checker ghi healthy từ goroutine riêng.

func (*Backend) Inflight

func (b *Backend) Inflight() int64

Inflight: số request đang gánh (test và stats).

func (*Backend) State

func (b *Backend) State(now time.Time) string

State: "closed" | "open" | "half-open" (stats, chaoslab).

type BackendStats

type BackendStats struct {
	Addr      string
	Picks     int64
	Inflight  int64
	Fails     int64
	Ejections int64
	EWMA      time.Duration // điểm EWMA hiện tại (đã decay tới lúc chụp)
	Healthy   bool          // active
	Ejected   bool          // passive
	State     string        // breaker: closed | open | half-open (phase 7)
	Probes    int64         // số request thử ở half-open
	Reopens   int64         // half-open thử hỏng ⇒ open lại
}

BackendStats: ảnh chụp một backend.

type Balancer

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

Balancer = danh sách backend + picker + sức khoẻ. Proxy chỉ gọi Pick và Done.

func New

func New(addrs []string, cfg Config) (*Balancer, error)

New: addrs không rỗng, Algo hợp lệ. Mọi backend ban đầu healthy (D6).

func (*Balancer) Backends

func (bl *Balancer) Backends() []*Backend

Backends: danh sách gốc (không lọc).

func (*Balancer) Close

func (bl *Balancer) Close()

Close dừng health check và chờ goroutine thoát.

func (*Balancer) Done

func (bl *Balancer) Done(b *Backend, latency time.Duration, failed bool)

Done: request trên b đã xong (exchange trả về — client đã nhận response VÀ connection đã put/discard trong defer của exchange; D2 ghi "trước put" là sai, chênh vài µs, xem diary phase 6 câu 2). latency nuôi EWMA; failed nuôi outlier.

func (*Balancer) Pick

func (bl *Balancer) Pick(key string) *Backend

Pick chọn backend cho request có khoá key (chỉ chash dùng) và tăng inflight (D2: đếm theo request, từ ĐÂY). nil ⇒ không còn backend nào dùng được ⇒ 503.

func (*Balancer) PickExcept

func (bl *Balancer) PickExcept(key string, ex *Backend) *Backend

PickExcept: như Pick nhưng không bao giờ trả ex (P7-1, trả 2026-10-02). Proxy dùng cho lượt chọn lại D9 sau khi dial ex lỗi — bản cũ gọi Pick ⇒ least-conn hoà inflight / rr một backend chọn lại CHÍNH ex ⇒ 2× DialTimeout rồi 502.

func (*Balancer) Start

func (bl *Balancer) Start()

Start chạy active health check (nếu bật). Gọi nhiều lần vô hại.

func (*Balancer) Stats

func (bl *Balancer) Stats() Stats

type Config

type Config struct {
	// Algo: "rr" | "leastconn" | "p2c" | "chash".
	Algo string
	// Tau: hằng thời gian EWMA của p2c. Mặc định 1 s. Quá dài ⇒ phản ứng chậm (G3).
	Tau time.Duration
	// HashHeader: header làm khoá cho chash; rỗng ⇒ proxy dùng IP client sau
	// ranh giới tin cậy. Header thiếu ⇒ cũng rơi về IP.
	HashHeader string
	// VNodes: điểm ảo / backend cho chash. Mặc định 150.
	VNodes int

	Health  HealthConfig
	Outlier OutlierConfig

	Logf func(format string, args ...any)
}

Config của Balancer. Zero value: rr, tau 1 s, 150 vnode, health + outlier bật.

type HealthConfig

type HealthConfig struct {
	Disabled bool
	Interval time.Duration
	Timeout  time.Duration
	// Path: nếu khác rỗng, sau khi dial gửi `GET Path` raw và đòi status < 400.
	// Rỗng = chỉ cần TCP connect thành công.
	Path string
	Fall int // lỗi liên tiếp ⇒ unhealthy (nginx max_fails)
	Rise int // tốt liên tiếp ⇒ healthy
	// Dial (P8-3): thay net.DialTimeout — proxy đặt khi upstream nói TLS để
	// probe bắt tay TLS trước khi gửi GET Path. nil = TCP trần. lb không biết
	// TLS: cert/SNI là việc của proxy, lb chỉ cần một net.Conn đã sẵn sàng.
	Dial func(addr string, timeout time.Duration) (net.Conn, error)
}

HealthConfig: active health check (D6). Zero value = bật, Interval 2 s, Timeout 1 s, chỉ dial TCP (Path rỗng), Fall 3, Rise 2.

type OutlierConfig

type OutlierConfig struct {
	Disabled        bool
	Consecutive     int
	BaseEject       time.Duration
	MaxEject        time.Duration
	MaxEjectPercent int
}

OutlierConfig: passive outlier ejection (D7, Envoy consecutive_5xx). Zero value = bật, 5 lỗi liên tiếp, eject 30 s × 2^(n-1), trần 5 phút, không eject quá 50 % backend.

type Picker

type Picker interface {
	Pick(all []*Backend, now time.Time, key string) *Backend
}

Picker chọn một backend đang available trong all; nil nếu không còn ai. Nhận cả danh sách (không lọc trước) vì consistent hash cần vị trí gốc trên ring.

type Stats

type Stats struct {
	Algo         string
	Backends     []BackendStats
	NoAvailable  int64 // Pick trả nil
	EjectRefused int64 // vượt trần MaxEjectPercent
}

Stats: ảnh chụp toàn bộ.

Jump to

Keyboard shortcuts

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