How to Build a Million‑User Ticket‑Spike System with Nginx, Go, and Redis

This article explores the architecture and implementation of a high‑concurrency ticket‑spike system, covering load‑balancing strategies, Nginx weighted round‑robin configuration, Go‑based local stock deduction, Redis‑backed unified inventory control, and performance testing with ApacheBench to achieve stable, scalable ticket sales during peak demand.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
How to Build a Million‑User Ticket‑Spike System with Nginx, Go, and Redis

Ticket Spike System Overview

During holidays, users in major cities face the challenge of抢火车票 (snatching train tickets) on 12306, which experiences extreme QPS. The author studies 12306's backend architecture and shares a simulation of handling 1 million concurrent users buying 10 000 tickets.

Load Balancing Overview

High‑concurrency systems use distributed clusters with multiple layers of load balancers and disaster‑recovery mechanisms (dual data centers, node fault tolerance, server backup) to ensure high availability.

OSPF (Open Shortest Path First)

OSPF is an interior gateway protocol that builds a link‑state database, calculates the shortest path tree, and assigns Cost values based on interface bandwidth. Equal‑Cost paths can perform load balancing across up to six links.

LVS (Linux Virtual Server)

LVS is a cluster technology that uses IP load balancing and content‑based request distribution, providing high‑throughput scheduling and automatic server fault masking.

Nginx

Nginx is a high‑performance HTTP/reverse‑proxy server commonly used for load balancing. It supports three balancing methods: round‑robin, weighted round‑robin, and IP‑hash round‑robin.

Nginx Weighted Round‑Robin Configuration

upstream load_rule {
    server 127.0.0.1:3001 weight=1;
    server 127.0.0.1:3002 weight=2;
    server 127.0.0.1:3003 weight=3;
    server 127.0.0.1:3004 weight=4;
}
server {
    listen 80;
    server_name load_balance.com www.load_balance.com;
    location / {
        proxy_pass http://load_rule;
    }
}

The above configuration assigns weights 1‑4 to four backend services listening on ports 3001‑3004.

Go Service Implementation

Four HTTP services are created in Go, each listening on a different port. The main handler processes "/buy/ticket" requests, logs results, and returns JSON responses.

package main
import (
    "net/http"
    "os"
    "strings"
)
func main() {
    http.HandleFunc("/buy/ticket", handleReq)
    http.ListenAndServe(":3001", nil)
}
func handleReq(w http.ResponseWriter, r *http.Request) {
    // handle request and log
}
func writeLog(msg string, logPath string) {
    fd, _ := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
    defer fd.Close()
    content := strings.Join([]string{msg, "
"}, "")
    fd.Write([]byte(content))
}

Local Stock Deduction Logic

func (spike *LocalSpike) LocalDeductionStock() bool {
    spike.LocalSalesVolume = spike.LocalSalesVolume + 1
    return spike.LocalSalesVolume < spike.LocalInStock
}

This function increments local sales volume and checks against local inventory.

Redis Unified Deduction with Lua Script

const LuaScript = `
local ticket_key = KEYS[1]
local ticket_total_key = ARGV[1]
local ticket_sold_key = ARGV[2]
local ticket_total_nums = tonumber(redis.call('HGET', ticket_key, ticket_total_key))
local ticket_sold_nums = tonumber(redis.call('HGET', ticket_key, ticket_sold_key))
if (ticket_total_nums >= ticket_sold_nums) then
    return redis.call('HINCRBY', ticket_key, ticket_sold_key, 1)
end
return 0
`
func (RemoteSpikeKeys *RemoteSpikeKeys) RemoteDeductionStock(conn redis.Conn) bool {
    lua := redis.NewScript(1, LuaScript)
    result, err := redis.Int(lua.Do(conn, RemoteSpikeKeys.SpikeOrderHashKey, RemoteSpikeKeys.TotalInventoryKey, RemoteSpikeKeys.QuantityOfOrderKey))
    if err != nil { return false }
    return result != 0
}

The Lua script ensures atomic check‑and‑decrement of total inventory stored in a Redis hash.

System Initialization

Local inventory, Redis hash keys, and a Redis connection pool are initialized. A channel of size 1 implements a distributed lock.

func init() {
    localSpike = LocalSpike{LocalInStock: 150, LocalSalesVolume: 0}
    remoteSpike = RemoteSpikeKeys{SpikeOrderHashKey: "ticket_hash_key", TotalInventoryKey: "ticket_total_nums", QuantityOfOrderKey: "ticket_sold_nums"}
    redisPool = NewPool()
    done = make(chan int, 1)
    done <- 1
}

Testing with ApacheBench

Requests are generated using ab -n 1000 -c 100 http://www.load_balance.com/buy/ticket and later a larger test ab -n 10000 -c 100 http://127.0.0.1:3005/buy/ticket. The logs show successful ticket sales until inventory is exhausted.

Results

Single‑machine throughput reaches over 4 000 requests per second, and with Nginx weighted balancing the load is evenly distributed across servers (e.g., ports 3001‑3004 receive 100, 200, 300, 400 requests respectively). Redis handles the unified inventory with high QPS.

Conclusion

The design demonstrates effective use of load balancing, local pre‑deduction, Redis atomic operations, and Go’s concurrency model to build a high‑performance ticket‑spike system that avoids database bottlenecks, prevents overselling, tolerates server failures, and scales to millions of concurrent users.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

load balancingGohigh concurrencyticketing system
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.