OpenResty là một nền tảng web mã nguồn mở dựa trên Nginx, tích hợp sẵn LuaJIT và hàng loạt module Lua, biến Nginx từ một web server tĩnh thành một application server đầy đủ chức năng. Nếu bạn đã quen với Nginx và muốn làm được nhiều hơn — API gateway, rate limiting phức tạp, logic routing động — mà không cần thêm một layer backend, thì OpenResty chính là câu trả lời.
Bài viết này giải thích OpenResty là gì, nó khác Nginx thường ở điểm nào, khi nào nên dùng, và hướng dẫn cài đặt cơ bản.
OpenResty là gì
OpenResty là một web platform dựa trên Nginx core, được phát triển bởi Zhang “agentzh” Yichun và cộng đồng. Nó bundle sẵn:
- Nginx core (bản patched, tối ưu hơn bản gốc)
- LuaJIT — Just-In-Time compiler cho ngôn ngữ Lua, cực nhanh
- ngx_lua module — cho phép chạy Lua script trực tiếp trong Nginx worker process
- Hàng loạt Lua libraries và Nginx modules bên thứ ba (ngx_http_redis, ngx_http_lua, lua-resty-mysql, lua-resty-http…)
Ý tưởng cốt lõi: thay vì chỉ dùng Nginx làm reverse proxy / static file server rồi đẩy mọi logic sang backend (Node.js, Python, Go…), bạn có thể viết logic trực tiếp bên trong Nginx bằng Lua. Nhờ LuaJIT, các script này chạy với hiệu suất gần C, không phải interpret chậm như các ngôn ngữ script thông thường.
OpenResty không phải là fork của Nginx. Nó là một platform bọc quanh Nginx, liên tục merge các bản cập nhật từ Nginx chính thức. Hầu hết patch của OpenResty đã được submit ngược lại upstream Nginx.
Nginx thường hoạt động thế nào
Nginx là web server phổ biến nhất thế giới, nổi tiếng với hiệu suất cao và khả năng xử lý đồng thời. Nó sử dụng kiến trúc event-driven, non-blocking I/O — một worker process có thể xử lý hàng nghìn kết nối đồng thời mà không cần tạo thread mới.
Nhưng Nginx thuần có một giới hạn: cấu hình tĩnh. Mọi thứ đều khai báo trong nginx.conf bằng directive. Nếu cần logic động (kiểm tra token, routing theo điều kiện, rate limit theo user), bạn phải:
- Viết module bằng C (phức tạp, dễ lỗi)
- Hoặc đẩy logic sang backend application
Cấu hình Nginx cơ bản trông như thế này:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend:3000;
}
location /static/ {
root /var/www/html;
}
}
Đơn giản, nhanh, nhưng không thể chạy code bên trong. Muốn kiểm tra API key trước khi proxy? Phải dùng module bên thứ ba hoặc đẩy sang backend.
OpenResty khác Nginx thường ở đâu
1. Chạy được Lua script trong Nginx
Đây là điểm khác biệt lớn nhất. OpenResty cho phép bạn viết Lua trực tiếp trong config:
server {
listen 80;
server_name example.com;
location /hello {
content_by_lua_block {
ngx.say("Hello from OpenResty!")
}
}
location /api/check {
access_by_lua_block {
local token = ngx.req.get_headers()["Authorization"]
if not token or token ~= "Bearer my-secret" then
ngx.exit(403)
end
}
proxy_pass http://backend:3000;
}
}
Ở ví dụ trên, /hello trả về response trực tiếp từ Lua — không cần backend. /api/check kiểm tra token trước khi proxy, tất cả chạy bên trong Nginx worker.
2. Non-blocking I/O với backend services
OpenResty cung cấp các Lua library kết nối non-blocking đến MySQL, PostgreSQL, Redis, Memcached, HTTP upstream… Tất cả đều chạy trên event loop của Nginx, không block worker:
location /user {
content_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local res, err = red:get("user:1001")
ngx.say("User data: ", res)
}
}
Truy vấn Redis trực tiếp từ Nginx, non-blocking, không cần backend. Đây là thứ Nginx thuần không làm được.
3. Xử lý logic phức tạp không cần backend
Với OpenResty bạn có thể xây dựng:
- API Gateway — authentication, rate limiting, routing, transformation
- WAF (Web Application Firewall) — kiểm tra request, block malicious traffic
- Dynamic routing — route request dựa trên header, cookie, geo IP, database query
- Caching logic — cache response theo key tùy chỉnh, invalidation thông minh
- A/B testing — phân luồng traffic ngay tại edge
Tất cả chạy bên trong Nginx, với hiệu suất gần C, xử lý hàng chục nghìn RPS trên một server bình thường.
Bảng so sánh OpenResty vs Nginx
| Tiêu chí | Nginx | OpenResty |
|---|---|---|
| Cơ sở | Web server / reverse proxy | Web platform dựa trên Nginx + LuaJIT |
| Ngôn ngữ mở rộng | C module (phức tạp) | Lua script (dễ viết, hiệu suất cao) |
| Logic động | Hạn chế, config tĩnh | Đầy đủ — routing, auth, transform, caching |
| Kết nối DB/Redis | Không trực tiếp | Có, non-blocking (lua-resty-*) |
| Hiệu suất static file | Xuất sắc | Tương đương (cùng Nginx core) |
| Hiệu suất dynamic | Phải delegate sang backend | Xử lý trực tiếp, gần C speed |
| Tài nguyên | Rất ít RAM/CPU | Hơi nhiều hơn (LuaJIT runtime) |
| Độ khó học | Dễ — config file đơn giản | Trung bình — cần học Lua + ngx_lua API |
| Module ecosystem | Nginx modules (C) | Nginx modules + Lua libraries (opm) |
| Phù hợp | Reverse proxy, static serving, load balancing | API gateway, WAF, dynamic routing, edge computing |
Cài đặt OpenResty
Ubuntu / Debian
# Thêm repository
wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
sudo apt-get -y install software-properties-common
sudo add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"
sudo apt-get update
# Cài đặt
sudo apt-get install -y openresty
CentOS / RHEL
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
sudo yum install -y openresty
Docker
docker run -d \
--name openresty \
-p 80:80 \
-v ./nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf \
openresty/openresty:alpine
Sau khi cài, binary nằm ở /usr/local/openresty/bin/openresty — nó hoạt động giống lệnh nginx nhưng có thêm Lua support.
Ví dụ thực tế: Rate Limiter với Redis
Một use case phổ biến của OpenResty — giới hạn số request per IP, sử dụng Redis làm counter:
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
listen 80;
server_name api.example.com;
location /api/ {
access_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
local ok, err = red:connect("127.0.0.1", 6379)
local ip = ngx.var.binary_remote_addr
local key = "rate:" .. ip
local count, err = red:incr(key)
if not count then
ngx.log(ngx.ERR, "redis error: ", err)
-- Fail open: cho qua nếu Redis lỗi
return
end
if count == 1 then
red:expire(key, 60) -- reset sau 60 giây
end
if count > 100 then
ngx.exit(429) -- Too Many Requests
end
}
proxy_pass http://backend:3000;
}
}
Toàn bộ logic rate limiting chạy bên trong Nginx worker, non-blocking, không cần thêm service riêng. Nếu Redis lỗi, request vẫn đi qua (fail open) — không làm sập hệ thống.
Khi nào nên dùng OpenResty thay Nginx
Nên dùng OpenResty khi
- Cần API Gateway — auth, rate limit, routing động, request/response transformation
- Muốn xây dựng WAF tùy chỉnh — filter request bằng Lua
- Cần dynamic routing — route dựa trên header, cookie, database, geo IP
- Muốn caching thông minh — cache key tùy chỉnh, invalidation theo logic riêng
- Chạy microservices — cần edge proxy xử lý logic trước khi forward đến service
- Cần xử lý hàng triệu RPS mà không muốn thêm layer backend
Nên dùng Nginx thường khi
- Chỉ cần reverse proxy hoặc load balancer đơn giản
- Phục vụ static files (HTML, CSS, JS, images)
- Cấu hình SSL/TLS termination
- Không cần logic động — backend lo hết
- Server ít tài nguyên, muốn tiêu thụ ít RAM nhất
- Team chưa quen Lua, không muốn thêm stack mới
Quy tắc đơn giản: nếu Nginx thường đã đủ, đừng thêm OpenResty. OpenResty sinh ra để giải quyết bài toán mà Nginx thuần không làm được — logic động bên trong web server. Nếu bạn không cần điều đó, Nginx thường luôn là lựa chọn đơn giản và ổn định hơn.
Các phase trong OpenResty
Một khái niệm quan trọng khi làm việc với OpenResty là request processing phases. Mỗi request đi qua nhiều phase, và bạn có thể hook Lua code vào từng phase:
| Phase directive | Chạy khi nào | Use case |
|---|---|---|
init_by_lua_block | Khi Nginx khởi động | Load config, khởi tạo shared dict |
set_by_lua_block | Set biến | Tính toán giá trị biến |
rewrite_by_lua_block | Rewrite phase | URL rewrite, redirect logic |
access_by_lua_block | Access control | Auth, rate limit, ACL |
content_by_lua_block | Tạo response | API endpoint, generate output |
header_filter_by_lua_block | Trước khi gửi header | Thêm/xóa response header |
body_filter_by_lua_block | Trước khi gửi body | Modify response body |
log_by_lua_block | Sau khi request xong | Logging, metrics |
Việc hiểu phases giúp bạn đặt code đúng chỗ. Ví dụ: auth check thì dùng access_by_lua_block (chạy trước khi request đến backend), không phải content_by_lua_block (đã quá muộn).
Shared Dictionary — chia sẻ dữ liệu giữa worker
OpenResty cung cấp ngx.shared.DICT — một shared memory zone cho phép các Nginx worker process chia sẻ dữ liệu với nhau. Đây là công cụ mạnh mẽ cho caching và state sharing:
# Trong http block
lua_shared_dict my_cache 10m;
server {
location /cached-api {
content_by_lua_block {
local cache = ngx.shared.my_cache
local data = cache:get("api:users")
if data then
ngx.say(data)
return
end
-- Cache miss: fetch từ backend
local http = require "resty.http"
local httpc = http.new()
local res, err = httpc:request_uri("http://backend:3000/users")
if res then
cache:set("api:users", res.body, 30) -- TTL 30 giây
ngx.say(res.body)
end
}
}
}
Shared dict nhanh hơn Redis cho dữ liệu nhỏ (in-memory, không network overhead), nhưng chỉ tồn tại trong phạm vi một Nginx instance. Dùng cho local cache, rate limit counter, feature flags…
Câu hỏi thường gặp
OpenResty có thay thế hoàn toàn Nginx không?
Về mặt kỹ thuật thì có — OpenResty bao gồm Nginx core và chạy được mọi config Nginx thường. Nhưng nếu bạn không dùng Lua, không có lý do gì để dùng OpenResty thay Nginx. Nó tiêu thụ nhiều tài nguyên hơn một chút và cần học thêm Lua. Dùng đúng công cụ cho đúng bài toán.
Lua khó học không?
Lua là một trong những ngôn ngữ đơn giản nhất. Cú pháp gọn gàng, ít concept, một dev quen Python/JavaScript có thể viết Lua cơ bản trong vài giờ. Phần khó hơn là học ngx_lua API — các phase, shared dict, cosocket. Nhưng tài liệu OpenResty rất chi tiết, có sẵn trên openresty.org.
OpenResty dùng ở đâu ngoài API Gateway?
Ngoài API Gateway, OpenResty được dùng cho WAF (Web Application Firewall), CDN edge logic, ad-tech (bid processing, tracking), IoT gateway, và thậm chí toàn bộ web application. Nhiều công ty lớn dùng OpenResty trong production — xử lý hàng tỷ request mỗi ngày với chỉ vài server.
Có thể chạy WordPress trên OpenResty không?
Có. Vì OpenResty bao gồm Nginx core, nó xử lý PHP-FPM giống Nginx thường. Thậm chí bạn có thể thêm Lua caching layer phía trước WordPress để tăng tốc — cache page bằng shared dict hoặc Redis, bypass PHP hoàn toàn cho visitor chưa đăng nhập.
Kết luận
OpenResty là Nginx “mang vũ khí hạng nặng” — giữ nguyên hiệu suất và ổn định của Nginx, thêm khả năng lập trình bằng Lua cho phép xử lý logic phức tạp ngay tại web server. Nó không thay thế Nginx trong mọi trường hợp, nhưng khi bạn cần API gateway, WAF, dynamic routing, hoặc edge computing, OpenResty là lựa chọn mạnh mẽ và hiệu quả hơn nhiều so với việc xây dựng thêm layer backend.
Nếu Nginx thường đã giải quyết được bài toán của bạn — tiếp tục dùng Nginx. Nếu bạn bắt đầu cần “nhúng logic vào proxy” — đó là lúc OpenResty phát huy tác dụng.