Easegress Source Code Reading Guide

Categories: Easegress

阅读中文

Easegress Source Code Reading Guide

Table of Contents


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 wasmhost build 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 the go 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 Object implementation via MetaSpec.Kind.
  • Spec holds both raw data (rawSpec) and the deserialized Go struct (objectSpec), facilitating validation and passthrough.
  • jsonschema struct 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:

  1. Holds ObjectRegistry (pkg/supervisor/object.go:39-45) — a local cache of configurations stored in etcd
  2. Holds ObjectEntityWatcher (pkg/supervisor/object.go) — watches etcd for config create/update/delete events
  3. Initializes and starts SystemControllers (supervisor.go:103)
  4. Runs the event loop (go s.run() at line 105) — upon receiving config change events, creates/updates/deletes ObjectEntity instances
// 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:

  1. cmd/server.go — Startup flow orchestration, establish a global understanding
  2. pkg/supervisor/registry.go — Object interface definition, understand the object system
  3. pkg/supervisor/spec.go — Spec/MetaSpec definitions, understand the configuration model
  4. pkg/supervisor/supervisor.go — Supervisor lifecycle management
  5. pkg/cluster/cluster_interface.go — Cluster interface, understand configuration storage
  6. pkg/registry/registry.go — See the big picture: all registered filters and objects

Path B: Deep Dive into Traffic Processing

  1. pkg/context/context.go — Context, Handler, MuxMapper
  2. pkg/protocols/protocols.go — Request/Response/Protocol interfaces
  3. pkg/object/pipeline/pipeline.go — How Pipeline organizes Filter chains
  4. pkg/filters/filters.go — Filter interface and Kind definition
  5. pkg/filters/httpproxy/ — Pick a specific filter (e.g., HTTP proxy) for deep reading
  6. pkg/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

  1. pkg/filters/filters.go — Understand the Filter interface
  2. pkg/filters/registry.go — Learn the registration mechanism
  3. pkg/filters/httpproxy/ or pkg/filters/ratelimiter/ — Reference existing Filter implementations
  4. pkg/context/context.go — Understand Handle(*Context) input parameters

Path E: Developing a New Object (Controller/TrafficGate)

  1. pkg/supervisor/registry.go — Object interface and registration mechanism
  2. pkg/object/trafficcontroller/ — SystemController reference implementation
  3. pkg/object/httpserver/ — TrafficGate reference implementation
  4. pkg/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
Read More

APISIX CLI ops.lua Source Code Analysis

【2026-07-29】APISIX CLI ops.lua source code analysis - command routing, init config generation, start/stop/reload process management, security & design highlights