Master OpenResty: Install, Hello World, and Real‑World Lua Routing

This tutorial walks through installing OpenResty, creating a simple hello‑world service, and implementing a practical Lua‑based request routing example that distinguishes single‑ versus multiple‑UID POST bodies, complete with Nginx configuration, Go backend code, and testing steps.

Xiao Lou's Tech Notes
Xiao Lou's Tech Notes
Xiao Lou's Tech Notes
Master OpenResty: Install, Hello World, and Real‑World Lua Routing

OpenResty Introduction

OpenResty aggregates a collection of well‑designed Nginx modules (mostly developed by the OpenResty team) to turn Nginx into a powerful general‑purpose web application platform. Developers can use Lua scripts to invoke various C and Lua modules, building high‑performance web systems that handle tens of thousands to millions of concurrent connections. OpenResty aims to run your web service inside Nginx, leveraging its non‑blocking I/O model for both HTTP client requests and backend services such as MySQL, PostgreSQL, Memcached, and Redis.

OpenResty Installation

Refer to http://openresty.org/en/linux-packages.html Example for CentOS:

wget https://openresty.org/package/centos/openresty.repo

mv openresty.repo /etc/yum.repos.d/

yum check-update

yum install openresty

Hello World Program

mkdir -p /home/roshi/opensty/conf /home/roshi/opensty/logs

Create a configuration that outputs "hello world"

worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}

http {
    server {
        listen 6699;
        location / {
            default_type text/html;
            content_by_lua_block {
                ngx.say("HelloWorld")
            }
        }
    }
}

Run

With the installation method above, Nginx is placed in /usr/local/openresty. Execute:

/usr/local/openresty/nginx/sbin/nginx -p /home/roshi/openresty -c /home/roshi/openresty/conf/nginx.conf

Test

curl http://127.0.0.1:6699

Processing Flow

OpenResty processes a request as illustrated in the diagram below:

Practical Example

Nginx is often used as a reverse proxy, routing requests under the same domain to different backend clusters based on URL patterns, e.g.: http://example.com/user/1 and http://example.com/product/1 When routing criteria are not present in headers or URLs—such as when they reside in the POST body—native Nginx cannot handle it, but OpenResty’s Lua scripts can.

Scenario: a POST request contains a JSON body with an array of uids. If the array has a single element, route to backend A; if it contains multiple elements, route to backend B.

worker_processes  1;
error_log logs/error.log info;
events {
    worker_connections 1024;
}

http {
   upstream single.uid { server host.docker.internal:8888; }
   upstream multiple.uids { server host.docker.internal:9999; }

    server {
        listen 6699;
        location / {
            default_type application/json;
            set $upstream_name 'multiple.uids';
            rewrite_by_lua_block {
                cjson = require 'cjson.safe'
                ngx.req.read_body()
                local body = ngx.req.get_body_data()
                if body then
                    ngx.log(ngx.INFO, "body=" .. body)
                    local data = cjson.decode(body)
                    if data and type(data) == "table" then
                        local count = 0
                        for k,v in pairs(data["uids"]) do count = count + 1 end
                        ngx.log(ngx.INFO, "count = " .. count)
                        if count == 1 then
                            ngx.var.upstream_name = "single.uid"
                        end
                    end
                end
            }
            proxy_pass http://$upstream_name;
        }
    }
}

The second line changes the log level to info for easier debugging.

Two upstream blocks correspond to different back‑end services; because OpenResty runs inside a Docker container, host.docker.internal is used to reach the host machine. rewrite_by_lua_block parses the request body with cjson and sets the upstream based on the number of uids.

Lua code accesses Nginx variables via ngx.var.

Backend services are written in Go using the Echo framework:

package main

import (
    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
    "os"
    "strconv"
)

type Response struct {
    Success bool   `json:"success"`
    Message string `json:"message"`
    Port    int    `json:"port"`
    Uids    []int  `json:"uids"`
}

type Request struct {
    Uids []int `json:"uids"`
}

var port = 8888

func main() {
    e := echo.New()
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())
    e.POST("/post", post)
    if len(os.Args) >= 2 {
        p, err := strconv.Atoi(os.Args[1])
        if err == nil {
            port = p
        }
    }
    e.Logger.Fatal(e.Start(":" + strconv.Itoa(port)))
}

func post(c echo.Context) error {
    req := Request{}
    err := c.Bind(&req)
    if err != nil {
        c.JSON(500, Response{Success: false, Port: port, Message: "bind body error"})
        return err
    }
    response := Response{Success: true, Port: port}
    for _, uid := range req.Uids {
        response.Uids = append(response.Uids, uid+100)
    }
    c.JSON(200, response)
    return nil
}

The services listen on ports 8888 and 9999. After starting them, send requests to port 6699 (the Nginx listener) and observe the results:

Log output can be found in /home/roshi/openresty/logs/error.log:

Conclusion

This article introduced OpenResty from installation and basic principles to a real‑world example, demonstrating its capability to handle complex routing logic with Lua scripts. Readers should now be able to get started with OpenResty.

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.

Dockerweb performancereverse proxyLuaOpenResty
Xiao Lou's Tech Notes
Written by

Xiao Lou's Tech Notes

Backend technology sharing, architecture design, performance optimization, source code reading, troubleshooting, and pitfall practices

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.