Easegress Source Code Reading Guide
Categories: Easegress
Easegress Source Code Reading Guide
Table of Contents
- 1. Project Overview
- 2. Build & Run
- 3. Startup Flow
- 4. Core Architecture
- 5. Object Categories in Detail
- 6. Suggested Reading Paths
1. Project Overview
Easegress is a cloud-native traffic orchestration gateway written in Go, using a declarative configuration + controller pattern to manage all components. It uses etcd for distributed configuration storage and supports HTTP/gRPC/MQTT multi-protocol proxying.
- Repository:
github.com/megaease/easegress/v2 - Go Version: 1.26
- Current Version: v2.11.0
- License: Apache License 2.0
Directory Overview
easegress/
├── cmd/ # Entry points for three binaries
│ ├── server/main.go # easegress-server entry point
│ ├── client/main.go # egctl CLI tool entry point
│ └── builder/main.go # egbuilder custom build tool entry point
├── cmd/server.go # RunServer() orchestration function
├── pkg/ # All core library code (22 packages)
├── build/ # Dockerfile and integration tests
├── docs/ # Documentation site
├── example/ # Cluster example configurations
├── helm-charts/ # Helm Chart
├── scripts/ # Helper scripts
├── Makefile # Build system
└── go.mod # Single module definition
Three Binary Artifacts
| Binary | Entry Point | Purpose |
|---|---|---|
easegress-server |
cmd/server/main.go:26 |
Core gateway service process |
egctl |
cmd/client/main.go:53 |
Management CLI tool (built on Cobra) |
egbuilder |
cmd/builder/main.go:36 |
Custom module build tool |
2. Build & Run
Build Commands
# Build all three binaries
make build
# Build server only
make build_server
# Build Docker image
make build_docker
# Run tests
make test
# Code formatting and linting
make fmt
make vet
Key Makefile Variables (Makefile:20)
RELEASE = v2.11.0- Server build includes
wasmhostbuild tag, requires CGO enabled - GoReleaser config in
.goreleaser.yml, supports linux/darwin + amd64/arm64 cross-compilation
3. Startup Flow
The complete server startup flow is in the RunServer() function at cmd/server.go:40-147. In order:
1. option.New().Parse() — Parse startup options and config file
2. env.InitServerDir() — Initialize server directory structure
3. logger.Init(opt) — Initialize structured logging (zap-based)
4. cluster.New(opt) — Start embedded etcd or connect to external cluster
5. supervisor.MustNew(opt, cls) — Create Supervisor, initialize SystemControllers
6. api.MustNewServer(...) — Start Admin API HTTP server
7. Register Graceful Upgrade signal handling
8. Block waiting for SIGINT/SIGTERM, graceful shutdown
Key points:
- Steps 4-6 have strict sequential dependencies: the cluster must be ready before Supervisor can watch config changes, and the API Server can then expose the management interface.
- In step 5, Supervisor internally initializes all
SystemControllers (in dependency order), then starts thego s.run()goroutine to listen for config changes.
4. Core Architecture
4.1 Object System (Registration & Lifecycle)
All managed components in Easegress implement the Object interface — the most important abstraction for understanding the entire project.
Core definition at pkg/supervisor/registry.go:30-47:
type Object interface {
Category() ObjectCategory // Object category (determines startup/shutdown order)
Kind() string // Unique type identifier
DefaultSpec() interface{} // Returns default config (must be a pointer to a struct)
Status() *Status // Runtime status
Close() // Called on teardown
}
Object categories (pkg/supervisor/registry.go:102-113) sorted by startup priority:
| Category | Description | Examples |
|---|---|---|
SystemController |
Built-in system controllers, started first | TrafficController, MeshController, AutoCertManager |
BusinessController |
User-created controllers | IngressController, GatewayController, WAFController |
Pipeline |
Traffic processing pipeline | Pipeline |
TrafficGate |
Protocol listener entry points | HTTPServer, gRPCServer, MQTTProxy |
Object registration mechanism: Self-registration via calling supervisor.Register(&MyObject{}) in init() functions. pkg/registry/registry.go uses blank imports to trigger init() across all filter and object packages:
// pkg/registry/registry.go
import (
_ "github.com/megaease/easegress/v2/pkg/filters/httpproxy"
_ "github.com/megaease/easegress/v2/pkg/object/httpserver"
// ... all filter and object packages
)
cmd/server/main.go imports pkg/registry to complete automatic registration of all modules.
4.2 Spec System (Declarative Configuration)
Definition at pkg/supervisor/spec.go:
// Spec (pkg/supervisor/spec.go:34) — Generic object configuration
type Spec struct {
super *Supervisor
category ObjectCategory
jsonConfig string // Raw JSON configuration
meta *MetaSpec // Metadata
rawSpec map[string]interface{} // Un-deserialized raw map
objectSpec interface{} // Deserialized Go struct
}
// MetaSpec (pkg/supervisor/spec.go:45) — Common metadata
type MetaSpec struct {
Name string `json:"name" jsonschema:"required,format=urlname"`
Kind string `json:"kind" jsonschema:"required"`
Version string `json:"version,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
CreatedAt string `json:"createdAt,omitempty"`
}
Design highlights:
- All object configurations are stored in etcd as JSON/YAML, routed to the corresponding
Objectimplementation viaMetaSpec.Kind. Specholds both raw data (rawSpec) and the deserialized Go struct (objectSpec), facilitating validation and passthrough.jsonschemastruct tags drive automatic validation, see 4.10 Validation System.
4.3 Supervisor (Lifecycle Management)
Definition at pkg/supervisor/supervisor.go:36:
Supervisor is the lifecycle manager for objects. Core responsibilities:
- Holds ObjectRegistry (
pkg/supervisor/object.go:39-45) — a local cache of configurations stored in etcd - Holds ObjectEntityWatcher (
pkg/supervisor/object.go) — watches etcd for config create/update/delete events - Initializes and starts SystemControllers (
supervisor.go:103) - Runs the event loop (
go s.run()at line 105) — upon receiving config change events, creates/updates/deletesObjectEntityinstances
// ObjectEntity (pkg/supervisor/object.go:39-45) — Runtime wrapper for Object
type ObjectEntity struct {
instance Object // Actual Object implementation
spec *Spec // Associated configuration
generation int64 // Generation (incremented on each update, for CAS detection)
}
4.4 Cluster (Clustering & Storage)
Definition at pkg/cluster/cluster_interface.go:33:
type Cluster interface {
IsLeader() bool
Layout() *Layout
// KV operations
Get(key string) (*string, error)
GetPrefix(prefix string) (map[string]string, error)
Put(key, value string) error
Delete(key string) error
DeletePrefix(prefix string) error
// Atomic operations (based on etcd STM)
STM(apply func(concurrency.STM) error) error
// Config change watching
Watcher() (Watcher, error)
Syncer(pullInterval time.Duration) (Syncer, error)
// Leader election
Mutex(name string, ttl time.Duration) concurrency.Locker
}
Key sub-interfaces:
- Watcher (
pkg/cluster/cluster_interface.go:76): Real-time monitoring of change events for specified keys/prefixes in etcd - Syncer (
pkg/cluster/cluster_interface.go:91): Maintains a local cache, keeping in sync with etcd via periodic full pulls
4.5 Traffic Pipeline
pkg/context/context.go defines the context carrier for traffic processing.
// Handler (pkg/context/context.go:35) — Interface for all traffic processors
type Handler interface {
Handle(ctx *Context) string // Returns result string (empty string means continue on success)
}
// MuxMapper (pkg/context/context.go:40) — Look up Handler by name
type MuxMapper interface {
GetHandler(name string) (Handler, bool)
}
Pipeline structure (pkg/object/pipeline/pipeline.go:63):
type Pipeline struct {
filters map[string]filters.Filter // All Filter instances (indexed by name)
flow []FlowNode // Processing flow definition (sequential + conditional jumps)
}
Traffic processing flow:
TrafficGate (e.g. HTTPServer)
→ Route matching
→ Pipeline
→ FlowNode[0] → Filter A → Jump based on result
→ FlowNode[1] → Filter B
→ ...
→ Return response
Context carries Request and Response throughout the entire chain, with each Filter able to read and write to Context.
4.6 Filter System
Core interfaces at pkg/filters/filters.go:
// Kind (pkg/filters/filters.go:33) — Metadata describing a Filter type
type Kind struct {
Name string
Description string
Results []string // All possible results beyond empty string
CreateInstance func(spec Spec) Filter // Factory function
DefaultSpec func() Spec // Returns a copy of default config
}
// Filter (pkg/filters/filters.go:54) — Base filter interface
type Filter interface {
Name() string
Kind() *Kind
Handle(*context.Context) string
}
Filter plugin registry at pkg/filters/registry.go, registered via filters.Register(k *Kind).
Built-in Filter list (27 types):
| Category | Filter | Function |
|---|---|---|
| Proxy | httpproxy |
HTTP reverse proxy |
| Proxy | grpcproxy |
gRPC proxy |
| Proxy | aigatewayproxy |
AI gateway proxy |
| Security | validator |
Request validation |
| Security | waf |
Web Application Firewall (Coraza-based) |
| Security | oidcadaptor |
OIDC authentication adapter |
| Security | corsadaptor |
CORS handling |
| Traffic Control | ratelimiter |
Rate limiting |
| Traffic Control | circuitbreaker |
Circuit breaking (resilience module) |
| Routing | redirector / redirectorv2 |
Redirection |
| Routing | headerlookup |
Header-based route matching |
| Routing | headertojson |
Header to JSON conversion |
| Messaging | kafka / kafkabackend |
Kafka message processing |
| Messaging | mqttclientauth |
MQTT client authentication |
| Messaging | topicmapper |
MQTT topic mapping |
| Service Mesh | meshadaptor |
Mesh adaptation |
| Extension | wasmhost |
WebAssembly sandbox |
| Extension | remotefilter |
Remote filter invocation |
| Extension | builder |
Build-time dynamic Filter |
| Policy | opafilter |
OPA policy engine |
| Utility | fileserver |
Static file serving |
| Utility | mock |
Mock responses |
| Utility | fallback |
Degradation fallback |
| Utility | certextractor |
Certificate extraction |
| Utility | connectcontrol |
Connection control |
4.7 Protocol Abstraction
Definition at pkg/protocols/protocols.go:
// Request (pkg/protocols/protocols.go:39) — Protocol-agnostic request interface
type Request interface {
Header() Header
RealIP() string
IsStream() bool
SetPayload(payload interface{})
// ...
}
// Response (pkg/protocols/protocols.go:84) — Protocol-agnostic response interface
type Response interface {
Header() Header
SetPayload(payload interface{})
// ...
}
// Protocol (pkg/protocols/protocols.go:143) — Protocol implementation
type Protocol interface {
CreateRequest(r io.Reader) (Request, error)
CreateResponse(body io.Reader) (Response, error)
// ...
}
Implemented protocols:
| Protocol | Package Path |
|---|---|
| HTTP | pkg/protocols/httpprot/ |
| gRPC | pkg/protocols/grpcprot/ |
| MQTT | pkg/protocols/mqttprot/ |
Protocols are registered in the global registry via protocols.Register(name, p).
4.8 Resilience
Definition at pkg/resilience/resilience.go:
// Wrapper (pkg/resilience/resilience.go:46) — Wraps a HandlerFunc
type Wrapper interface {
Wrap(HandlerFunc) HandlerFunc
}
// HandlerFunc (pkg/resilience/resilience.go:43)
type HandlerFunc func(ctx context.Context) error
Resilience and fault-tolerance strategies wrap Filter Handle calls using the decorator pattern:
Wrapper(Filter.Handle) → Execute Filter logic, tolerate faults per policy
Built-in strategies:
| Strategy | File |
|---|---|
| CircuitBreaker | pkg/resilience/circuitbreaker.go |
| Retry | pkg/resilience/retry.go |
4.9 Admin API
Definitions at pkg/api/api.go and pkg/api/server.go.
The Admin API uses go-chi/chi as the HTTP routing framework, providing dynamic route registration (pkg/api/dynamicmux.go supports hot-reloading the route table).
// Entry (pkg/api/server.go:59)
type Entry struct {
Path string // API path
Method string // HTTP method
Handler http.HandlerFunc // Handler function
}
APIs are registered via api.RegisterAPIs(group), grouped by functionality (e.g., v2 APIs, health checks, profiles), and ultimately mounted on the API Server.
4.10 Validation System
Definition at pkg/v/v.go.
Easegress uses JSON Schema for configuration validation. JSON schemas are auto-generated from jsonschema tags on Go structs and used during validation.
Custom format validators (pkg/v/format.go:31):
| Format | Description |
|---|---|
urlname |
URL-safe name |
duration |
Time interval (e.g., 10s, 5m) |
ipcidr |
IP CIDR format |
regexp |
Regular expression |
base64 |
Base64 encoding |
byteurl |
Byte size + URL format |
5. Object Categories in Detail
All managed objects in Easegress are lifecycle-managed by Supervisor, categorized by runtime dependencies as follows:
SystemController
Built-in, single-instance, initialized first when Supervisor starts.
| Object | Package Path | Responsibility |
|---|---|---|
| TrafficController | pkg/object/trafficcontroller/ |
Manages TrafficGate and Pipeline creation/destruction |
| MeshController | pkg/object/meshcontroller/ |
Service mesh control plane (supports Eureka/Consul/Nacos service discovery) |
| AutoCertManager | pkg/object/autocertmanager/ |
Automatic TLS certificate management (ACME) |
BusinessController
Business controllers created by users via Admin API or configuration files.
| Object | Package Path | Responsibility |
|---|---|---|
| IngressController | pkg/object/ingresscontroller/ |
Kubernetes Ingress controller |
| GatewayController | pkg/object/gatewaycontroller/ |
Kubernetes Gateway API controller |
| WAFController | pkg/object/wafcontroller/ |
WAF management |
| GlobalFilter | pkg/object/globalfilter/ |
Global filter management |
| AIGatewayController | pkg/object/aigatewaycontroller/ |
AI gateway (LLM proxy) management |
| StatusSyncController | pkg/object/statussynccontroller/ |
Status synchronization |
| Function | pkg/object/function/ |
Serverless Function |
| RawConfigTrafficController | pkg/object/rawconfigtrafficcontroller/ |
Raw-config-based traffic management |
Service registry adapters:
| Service Discovery | Package Path |
|---|---|
| Consul | pkg/object/consulserviceregistry/ |
| Etcd | pkg/object/etcdserviceregistry/ |
| Eureka | pkg/object/eurekaserviceregistry/ |
| Nacos | pkg/object/nacosserviceregistry/ |
| ZooKeeper | pkg/object/zookeeperserviceregistry/ |
TrafficGate
Protocol listener entry points, responsible for receiving external traffic and forwarding it to Pipelines based on routing rules.
| Object | Package Path | Protocol |
|---|---|---|
| HTTPServer | pkg/object/httpserver/ |
HTTP/HTTPS |
| gRPCServer | pkg/object/grpcserver/ |
gRPC |
| MQTTProxy | pkg/object/mqttproxy/ |
MQTT |
Pipeline
Located at pkg/object/pipeline/, assembles a set of Filters into a processing chain. A Pipeline can be referenced by multiple routes, and a TrafficGate can mount multiple Pipelines.
6. Suggested Reading Paths
Based on different learning goals, the following source code reading orders are recommended:
Path A: Understanding the Overall Architecture (Recommended for Everyone)
cmd/server.go— Startup flow orchestration, establish a global understandingpkg/supervisor/registry.go— Object interface definition, understand the object systempkg/supervisor/spec.go— Spec/MetaSpec definitions, understand the configuration modelpkg/supervisor/supervisor.go— Supervisor lifecycle managementpkg/cluster/cluster_interface.go— Cluster interface, understand configuration storagepkg/registry/registry.go— See the big picture: all registered filters and objects
Path B: Deep Dive into Traffic Processing
pkg/context/context.go— Context, Handler, MuxMapperpkg/protocols/protocols.go— Request/Response/Protocol interfacespkg/object/pipeline/pipeline.go— How Pipeline organizes Filter chainspkg/filters/filters.go— Filter interface and Kind definitionpkg/filters/httpproxy/— Pick a specific filter (e.g., HTTP proxy) for deep readingpkg/object/httpserver/— See how the entry Gate creates and routes to Pipelines
Path C: Studying Specific Features
| What You Want to Learn | Start Here |
|---|---|
| Service Mesh | pkg/object/meshcontroller/ + pkg/filters/meshadaptor/ |
| OIDC Authentication | pkg/filters/oidcadaptor/ |
| AI Gateway | pkg/object/aigatewaycontroller/ + pkg/filters/aigatewayproxy/ |
| WAF Firewall | pkg/object/wafcontroller/ + pkg/filters/waf/ |
| Kubernetes Integration | pkg/object/ingresscontroller/ + pkg/object/gatewaycontroller/ |
| MQTT Proxy | pkg/protocols/mqttprot/ + pkg/object/mqttproxy/ |
| WebAssembly Extension | pkg/filters/wasmhost/ |
| Distributed Tracing | pkg/tracing/ |
| OPA Policy Engine | pkg/filters/opafilter/ |
Path D: Developing a New Filter
pkg/filters/filters.go— Understand the Filter interfacepkg/filters/registry.go— Learn the registration mechanismpkg/filters/httpproxy/orpkg/filters/ratelimiter/— Reference existing Filter implementationspkg/context/context.go— UnderstandHandle(*Context)input parameters
Path E: Developing a New Object (Controller/TrafficGate)
pkg/supervisor/registry.go— Object interface and registration mechanismpkg/object/trafficcontroller/— SystemController reference implementationpkg/object/httpserver/— TrafficGate reference implementationpkg/object/pipeline/— Pipeline reference implementation
Appendix: Key File Index
| File | Core Content |
|---|---|
cmd/server.go:40-147 |
RunServer() startup orchestration |
pkg/supervisor/registry.go:30-113 |
Object/ObjectCategory interface definitions |
pkg/supervisor/spec.go:34-53 |
Spec/MetaSpec types |
pkg/supervisor/supervisor.go:36 |
Supervisor struct |
pkg/supervisor/object.go:39 |
ObjectEntity/ObjectRegistry |
pkg/cluster/cluster_interface.go:33 |
Cluster interface |
pkg/context/context.go:35-42 |
Handler/MuxMapper interfaces |
pkg/context/context.go:70 |
Context struct |
pkg/protocols/protocols.go:39-143 |
Request/Response/Protocol interfaces |
pkg/filters/filters.go:33-60 |
Kind/Filter interfaces |
pkg/filters/registry.go |
Filter registry |
pkg/resilience/resilience.go:30-116 |
Policy/Wrapper interfaces |
pkg/v/v.go |
JSON Schema validation |
pkg/v/format.go:31 |
Custom format validators |
pkg/api/server.go:37-80 |
Admin API Server |
pkg/registry/registry.go |
Global registry (blank imports) |
go.mod:1 |
Module definition (v2) |
Makefile:20 |
Version number and build configuration |