ในฐานะนักพัฒนาที่เคยรับผิดชอบระบบ AI สำหรับแพลตฟอร์มอีคอมเมิร์ซขนาดใหญ่ ผมเคยเจอปัญหาหนักใจมากกว่าจะสร้าง AI API Relay Station ที่ต้องรองรับ load spike ที่ไม่สามารถคาดเดาได้ โดยเฉพาะช่วง Flash Sale หรือเทศกาลจับจ่ายใช้สอยต่างๆ

บทความนี้จะพาคุณสร้างระบบ Relay Station ที่ใช้ Nginx เป็น Reverse Proxy ร่วมกับ Lua scripting เพื่อจัดการ request routing, rate limiting, caching และ failover อย่างมีประสิทธิภาพ โดยเราจะใช้ HolySheep AI เป็น API provider หลักเพื่อประหยัดค่าใช้จ่ายได้ถึง 85% เมื่อเทียบกับ OpenAI โดยตรง

ทำไมต้องสร้าง AI API Relay Station?

ก่อนจะลงมือทำ เรามาดูกันว่าทำไมระบบ Relay Station ถึงสำคัญสำหรับองค์กรที่ใช้ AI ในระดับ Production

กรณีศึกษา: ระบบ AI Customer Service ของ E-Commerce

สมมติว่าคุณพัฒนาระบบ AI Chatbot สำหรับแพลตฟอร์ม E-Commerce ที่มีลูกค้าวันละ 50,000 คน โดยแต่ละคนถามเฉลี่ย 5 คำถาม ระบบต้องรองรับ request พุ่งสูงถึง 500 requests/วินาทีในช่วง peak hour

ปัญหาที่พบบ่อยเมื่อไม่มี Relay Station:

สร้าง Nginx + Lua Relay Station

1. ติดตั้ง OpenResty (Nginx + LuaJIT)

# สำหรับ Ubuntu/Debian
apt-get update
apt-get install -y build-essential curl

ติดตั้ง OpenResty

wget https://openresty.org/package/openresty-2.0.0b2.tar.gz tar -zxf openresty-2.0.0b2.tar.gz cd openresty-2.0.0b2/

ติดตั้ง dependencies

apt-get install -y libpcre3 libpcre3-dev openssl libssl-dev zlib1g zlib1g-dev

Configure และติดตั้ง

./configure --prefix=/usr/local/openresty \ --with-luajit \ --with-http_ssl_module \ --with-http_v2_module \ --with-stream \ --with-stream_ssl_module make -j$(nproc) make install

เพิ่ม PATH

export PATH=/usr/local/openresty/nginx/sbin:$PATH

2. โครงสร้าง Project และ Configuration

# โครงสร้างไดเรกทอรี
ai-relay-station/
├── nginx/
│   ├── nginx.conf
│   └── conf.d/
│       ├── upstream.conf
│       ├── routes.conf
│       └── lua/
│           ├── init.lua
│           ├── handler.lua
│           ├── cache.lua
│           └── metrics.lua
├── certs/
│   ├── server.crt
│   └── server.key
├── logs/
│   ├── access.log
│   └── error.log
└── docker-compose.yml

3. Nginx Configuration หลัก

# nginx.conf
worker_processes auto;
error_log /usr/local/openresty/nginx/logs/error.log warn;
pid /usr/local/openresty/nginx/logs/nginx.pid;

events {
    worker_connections 10240;
    use epoll;
    multi_accept on;
}

http {
    # Lua paths
    lua_package_path '/etc/nginx/conf.d/lua/?.lua;;';
    lua_package_cpath '/usr/local/openresty/luajit/lib/lua/5.1/?.so;;';
    
    # Init phases
    init_by_lua_file /etc/nginx/conf.d/lua/init.lua;
    init_worker_by_lua_file /etc/nginx/conf.d/lua/handler.lua;

    # Basic settings
    include /etc/nginx/mime.types;
    default_type application/json;
    
    # Logging
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" $request_time $upstream_response_time';
    
    access_log /usr/local/openresty/nginx/logs/access.log main;

    # Performance
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # Gzip
    gzip on;
    gzip_types text/plain application/json application/javascript;

    # Include upstream and routes
    include /etc/nginx/conf.d/upstream.conf;
    include /etc/nginx/conf.d/routes.conf;

    # Rate limiting zone
    limit_req_zone $binary_remote_addr zone=general:10m rate=100r/s;
    limit_req_zone $api_key zone=byapikey:10m rate=500r/s;
    limit_conn_zone $binary_remote_addr zone=addr:10m;
}

4. Upstream Configuration สำหรับ HolySheep

# upstream.conf

HolySheep AI upstream (Asia-Pacific optimized)

upstream holysheep_api { server api.holysheep.ai:443; keepalive 64; }

Backup upstream (DeepSeek)

upstream deepseek_api { server api.deepseek.com:443; keepalive 32; }

Upstream health check

server { listen 8080; server_name _; location /health { access_log off; return 200 "OK\n"; add_header Content-Type text/plain; } location /upstream/health { content_by_lua_block { local http = require("resty.http") local h = http.new() local results = {} -- Check HolySheep local res1, err1 = h:request_uri("https://api.holysheep.ai/v1/models", { ssl_verify = true, headers = {["Authorization"] = "Bearer dummy"} }) results.holysheep = res1 and "up" or "down" -- Check DeepSeek backup local res2, err2 = h:request_uri("https://api.deepseek.com/v1/models", { ssl_verify = true, headers = {Authorization = "Bearer dummy"} }) results.deepseek = res2 and "up" or "down" ngx.say(cjson.encode(results)) } } }

5. Main Route Handler (Lua)

-- handler.lua
local cjson = require("cjson")
local http = require("resty.http")
local crypto = require("crypto")

-- Global configuration
local _M = {
    config = {
        primary_provider = "holysheep",
        backup_provider = "deepseek",
        base_url = "https://api.holysheep.ai/v1",
        backup_url = "https://api.deepseek.com/v1",
        api_key = os.getenv("HOLYSHEEP_API_KEY") or "YOUR_HOLYSHEEP_API_KEY",
        cache_ttl = 300, -- 5 minutes
        timeout = 30000, -- 30 seconds
        max_retries = 2
    },
    stats = {
        requests_total = 0,
        requests_success = 0,
        requests_failed = 0,
        cache_hits = 0,
        cache_misses = 0
    }
}

-- Cache storage (shared dict)
local cache_dict = ngx.shared.ai_cache

-- Generate cache key from request
function _M.generate_cache_key(request_body, model)
    local key_data = request_body .. model
    local hash = crypto.md5(key_data)
    return "ai:cache:" .. hash
end

-- Check and set cache
function _M.get_from_cache(key)
    local value = cache_dict:get(key)
    if value then
        _M.stats.cache_hits = _M.stats.cache_hits + 1
        return cjson.decode(value)
    end
    _M.stats.cache_misses = _M.stats.cache_misses + 1
    return nil
end

function _M.set_to_cache(key, value, ttl)
    ttl = ttl or _M.config.cache_ttl
    local encoded = cjson.encode(value)
    cache_dict:set(key, encoded, ttl)
end

-- Metrics endpoint
function _M.get_metrics()
    return {
        requests_total = _M.stats.requests_total,
        requests_success = _M.stats.requests_success,
        requests_failed = _M.stats.requests_failed,
        cache_hits = _M.stats.cache_hits,
        cache_misses = _M.stats.cache_misses,
        hit_rate = _M.stats.cache_hits / math.max(_M.stats.requests_total, 1)
    }
end

return _M

6. API Route Handler

# routes.conf
server {
    listen 443 ssl http2;
    server_name relay.yourdomain.com;

    ssl_certificate /etc/nginx/certs/server.crt;
    ssl_certificate_key /etc/nginx/certs/server.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    # Rate limiting
    limit_req zone=general burst=50 nodelay;
    limit_conn addr 20;

    # Main proxy endpoint
    location /v1/chat/completions {
        content_by_lua_file /etc/nginx/conf.d/lua/proxy_handler.lua;
    }

    # Embeddings endpoint
    location /v1/embeddings {
        content_by_lua_file /etc/nginx/conf.d/lua/embeddings_handler.lua;
    }

    # Metrics
    location /metrics {
        content_by_lua_block {
            local handler = require("handler")
            ngx.say(cjson.encode(handler.get_metrics()))
        }
    }

    # API key validation endpoint
    location /v1/validate-key {
        internal;
        proxy_pass https://api.holysheep.ai/v1/models;
        proxy_method GET;
        proxy_set_header Authorization "Bearer $http_x_api_key";
        proxy_ssl_name api.holysheep.ai;
        proxy_ssl_server_name on;
    }
}
-- proxy_handler.lua
local cjson = require("cjson")
local http = require("resty.http")
local handler = require("handler")

local config = handler.config

-- Main request handler
local function handle_chat_completion()
    handler.stats.requests_total = handler.stats.requests_total + 1
    
    -- Read request body
    ngx.req.read_body()
    local request_body = ngx.req.get_body_data()
    
    if not request_body then
        ngx.status = 400
        ngx.say(cjson.encode({error = {message = "Request body required", type = "invalid_request_error"}}))
        return
    end
    
    local ok, parsed_body = pcall(cjson.decode, request_body)
    if not ok then
        ngx.status = 400
        ngx.say(cjson.encode({error = {message = "Invalid JSON body", type = "invalid_request_error"}}))
        return
    end
    
    -- Get API key from header or query
    local api_key = ngx.req.get_headers()["x-api-key"] or ngx.var.arg_api_key or config.api_key
    
    -- Check cache for GET-like requests (streaming disabled)
    if not parsed_body.stream then
        local cache_key = handler.generate_cache_key(request_body, parsed_body.model or "default")
        local cached = handler.get_from_cache(cache_key)
        
        if cached then
            ngx.header["X-Cache"] = "HIT"
            ngx.header["X-Cache-Key"] = cache_key
            ngx.say(cjson.encode(cached))
            return
        end
    end
    
    -- Make request to upstream
    local h = http.new()
    h:set_timeout(config.timeout)
    
    local target_url = config.base_url .. "/chat/completions"
    
    local res, err = h:request_uri(target_url, {
        method = "POST",
        ssl_verify = true,
        headers = {
            ["Content-Type"] = "application/json",
            ["Authorization"] = "Bearer " .. api_key,
            ["X-Forwarded-For"] = ngx.var.remote_addr,
            ["X-Request-ID"] = ngx.var.request_id
        },
        body = request_body
    })
    
    if not res then
        -- Try backup provider
        handler.stats.requests_failed = handler.stats.requests_failed + 1
        
        local h2 = http.new()
        h2:set_timeout(config.timeout)
        
        local backup_url = config.backup_url .. "/chat/completions"
        
        -- Convert request for DeepSeek format if needed
        local backup_body = handler.convert_to_deepseek(request_body)
        
        local res2, err2 = h2:request_uri(backup_url, {
            method = "POST",
            ssl_verify = true,
            headers = {
                ["Content-Type"] = "application/json",
                ["Authorization"] = "Bearer " .. os.getenv("DEEPSEEK_API_KEY"),
            },
            body = backup_body
        })
        
        if not res2 then
            ngx.status = 502
            ngx.say(cjson.encode({
                error = {
                    message = "All upstream providers failed: " .. err .. " | " .. err2,
                    type = "upstream_error"
                }
            }))
            return
        end
        
        -- Success with backup
        handler.stats.requests_success = handler.stats.requests_success + 1
        ngx.header["X-Provider"] = "deepseek"
        ngx.say(res2.body)
        return
    end
    
    -- Success with primary
    handler.stats.requests_success = handler.stats.requests_success + 1
    ngx.header["X-Provider"] = "holysheep"
    ngx.header["X-Response-Time"] = res.headers["X-Response-Time"]
    
    -- Cache non-streaming response
    if not parsed_body.stream then
        local cache_key = handler.generate_cache_key(request_body, parsed_body.model or "default")
        local ok_cache = pcall(cjson.decode, res.body)
        if ok_cache then
            handler.set_to_cache(cache_key, cjson.decode(res.body), config.cache_ttl)
        end
    end
    
    ngx.say(res.body)
end

-- Execute handler with error catching
local ok, err = pcall(handle_chat_completion)
if not ok then
    ngx.log(ngx.ERR, "Handler error: ", err)
    ngx.status = 500
    ngx.say(cjson.encode({error = {message = "Internal server error", type = "server_error"}}))
end

7. Docker Compose for Easy Deployment

# docker-compose.yml
version: '3.8'

services:
  nginx-relay:
    image: openresty/openresty:alpine
    container_name: ai-relay-station
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf:ro
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./certs:/etc/nginx/certs:ro
      - ./logs:/usr/local/openresty/nginx/logs
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - HOLYSHEEP_API_KEY=${HOLYSHEEP_API_KEY}
      - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}
    shm_size: '256mb'
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 256M

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    restart: unless-stopped

networks:
  default:
    name: ai-relay-network

วิธีใช้งาน Relay Station

หลังจากติดตั้งเสร็จแล้ว คุณสามารถเรียกใช้งานได้โดยเปลี่ยน API endpoint ในโค้ดของคุณ

# ก่อนหน้า (ใช้ OpenAI โดยตรง)
import openai
openai.api_key = "sk-xxx"
response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello!"}]
)

หลังจากติดตั้ง Relay Station

import openai

ชี้ไปที่ Relay Station ของคุณ

openai.api_base = "https://relay.yourdomain.com/v1" openai.api_key = "YOUR_INTERNAL_API_KEY" # Key สำหรับ internal service

โค้ดเดิมไม่ต้องเปลี่ยน

response = openai.ChatCompletion.create( model="gpt-4", # หรือใช้ชื่อ model อื่นที่ HolySheep รองรับ messages=[{"role": "user", "content": "Hello!"}] )

เหมาะกับใคร / ไม่เหมาะกับใคร

กลุ่มเป้าหมาย เหมาะกับ ไม่เหมาะกับ
Startup/SaaS ต้องการประหยัดค่า API ในขณะที่ยังต้องการ reliability สูง ทีมที่มีงบประมาณ API สูงมากและไม่มี technical skill ด้าน DevOps
Enterprise ต้องการ unified API gateway, logging และ compliance องค์กรที่มี existing API gateway อยู่แล้ว (เช่น Kong, AWS API Gateway)
นักพัฒนาอิสระ สร้าง portfolio project หรือสินค้าขายแบบ SaaS ที่ต้องควบคุมค่าใช้จ่าย โปรเจกต์ที่ใช้ AI น้อยมาก (น้อยกว่า 1000 requests/เดือน)
E-Commerce ระบบ chatbot, product recommendations, customer support ร้านค้าขนาดเล็กที่มี traffic ต่ำมาก

ราคาและ ROI

การสร้าง Relay Station ใช้ infrastructure ขั้นต่ำ 1 server ราคาประมาณ $20-50/เดือน แต่สามารถประหยัดค่า API ได้อย่างมหาศาลเมื่อใช้ HolySheep AI

Model ราคา OpenAI ($/MTok) ราคา HolySheep ($/MTok) ประหยัด
GPT-4.1 $60.00 $8.00 86.7%
Claude Sonnet 4.5 $15.00 $15.00 เท่ากัน
Gemini 2.5 Flash $2.50 $2.50 เท่ากัน
DeepSeek V3.2 $2.50 $0.42 83.2%

ตัวอย่างการคำนวณ ROI:

ทำไมต้องเลือก HolySheep

ในฐานะผู้ที่ใช้งาน HolySheep มาหลายเดือน ผมเลือกใช้เพราะเหตุผลเหล่านี้:

ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข

1. Error: "upstream prematurely closed connection"

สาเหตุ: เกิดจาก keepalive connection หมดอายุหรือ upstream server ปิด connection ก่อนที่ Nginx จะปิด

# วิธีแก้ไข - เพิ่ม keepalive_timeout และปรับ proxy configuration

upstream holysheep_api {
    server api.holysheep.ai:443;
    keepalive 64;
    keepalive_timeout 60s;
    keepalive_requests 1000;
}

ใน location block

location /v1/chat/completions { proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Keep-Alive ""; proxy_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; # เพิ่ม buffering proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; }

2. Error: "API key validation failed" หรือ 401 Unauthorized

สาเหตุ: API key ไม่ถูกส่งไปยัง upstream หรือ format ผิด

# วิธีแก้ไข - ตรวจสอบ header mapping

ต้องแน่ใจว่าส่ง header ถูกต้อง

location /v1/chat/completions { # รับ key จากหลาย source set_by_lua $api_key ' local key = ngx.req.get_headers