黑马程序员Redis教程学习笔记(第2部分):Lua语法与OpenResty实践

2026-04-02
2
-
- 分钟
|

黑马程序员Redis教程学习笔记(第2部分):Lua语法与OpenResty实践

课程概述

本篇笔记涵盖黑马程序员Redis教程中关于Lua语法基础、OpenResty安装与使用的重要章节。主要包含Lua的函数与条件控制、OpenResty的安装与配置、以及如何使用OpenResty实现多级缓存架构中的业务逻辑。

1. Lua语法进阶:函数与条件控制

函数定义

在Lua中,函数的定义语法如下:

function 函数名(参数列表)
    -- 函数体
    return 返回值  -- 可选
end

例如,封装一个打印数组的函数:

local function print_arr(arr)
    for index, value in ipairs(arr) do
        print(value)
    end
end

-- 使用函数
local arr = {'java', 'lua', 'python'}
print_arr(arr)

条件控制

Lua中的条件控制语法与Java类似,但有一些区别:

if 条件 then
    -- 条件为真时执行
elseif 其他条件 then
    -- 其他条件为真时执行
else
    -- 都不满足时执行
end

逻辑运算符使用英文单词: - and 代表 逻辑与 - or 代表 逻辑或
- not 代表 逻辑非

特别注意:not nil 代表 true,因为nil代表false

实际应用:带条件判断的函数

local function print_table(t)
    if not t then  -- 如果t是nil
        print("数组不能为空")
        return
    end
    
    for key, value in pairs(t) do
        print(key, value)
    end
end

2. OpenResty安装与配置

OpenResty简介

OpenResty是一个基于Nginx的高性能Web平台,为Nginx提供了大量的Lua库、语言接口和第三方模块,使其具备了编写自定义业务逻辑的能力。

安装步骤

  1. 安装OpenResty依赖库
  2. 配置OpenResty仓库地址
  3. 安装OpenResty及其管理插件
  4. 配置环境变量

安装完成后,OpenResty的主要目录结构: - /usr/local/openresty/ - 主目录 - /usr/local/openresty/nginx/ - Nginx相关文件 - /usr/local/openresty/lualib/ - Lua库文件 - /usr/local/openresty/bin/ - 可执行文件

启动与管理

  • 启动:nginx
  • 重新加载配置:nginx -s reload
  • 停止:nginx -s stop

配置简化

OpenResty的配置文件位于/usr/local/openresty/nginx/conf/nginx.conf,为便于开发,通常使用简化版配置,移除大量注释。

3. OpenResty快速入门:业务逻辑实现

OpenResty与Nginx的关系

  • Nginx:反向代理服务器,本身不具备业务逻辑处理能力
  • OpenResty:基于Nginx,增加了Lua支持,可编写业务逻辑

实现商品详情页查询

在nginx.conf中配置:

# 加载OpenResty的Lua模块
lua_package_path "/usr/local/openresty/lualib/?.lua;;";
lua_package_cpath "/usr/local/openresty/lualib/?.so;;";

server { listen 8080;

# 拦截商品查询请求
location ~ /api/item/(\d+) {
    # 指定响应类型
    default_type application/json;
    
    # 由Lua文件处理请求
    content_by_lua_file lua/item.lua;
}

}

lua/item.lua中实现业务逻辑:

-- 返回假数据作为测试
ngx.say([[{
    "id": 1001,
    "name": "华为手机",
    "price": 1999,
    "image": "xxx.jpg",
    "stock": 100
}]])

4. OpenResty获取请求参数

五种请求参数获取方式

  1. 路径占位符参数(最复杂)

    location ~ /api/item/(\d+) {
        # 参数会存到ngx.var[1]数组中
        content_by_lua_file lua/item.lua;
    }

    在Lua中获取:

    local id = ngx.var[1]  -- 获取路径中的数字参数
  2. 请求头参数

    local headers = ngx.req.get_headers()
    local user_agent = headers.user_agent
  3. GET请求参数

    local args = ngx.req.get_uri_args()
    local id = args.id
  4. POST表单参数

    ngx.req.read_body()  -- 先读取请求体
    local args = ngx.req.get_post_args()
    local username = args.username
  5. JSON参数

    ngx.req.read_body()
    local data = ngx.req.get_body_data()
    -- 需要使用JSON解析库处理

实际应用:动态获取商品ID

-- 获取路径参数
local id = ngx.var[1]

-- 返回包含动态ID的数据
ngx.say([[{ 
    "id": ]] .. id .. [[,
    "name": "商品名称",
    "price": 999
}]])

5. OpenResty封装HTTP请求工具

发起HTTP请求

使用ngx.location.capture API发起内部请求:

local res = ngx.location.capture(
    "/backend",  -- 请求路径
    { 
        method = ngx.HTTP_GET,  -- 请求方法
        args = {id = 123},      -- GET参数
        body = "data"           -- POST请求体
    }
)

-- 获取响应
local status = res.status  -- 状态码
local header = res.header  -- 响应头
local body = res.body      -- 响应体

配置反向代理

由于capture请求会被Nginx内部捕获,需要配置反向代理:

location /item {
    proxy_pass http://192.168.150.1:8081;  -- Tomcat服务器地址
}

这样内部请求/item会被代理到Tomcat服务器。

封装通用HTTP请求工具

创建common.lua文件:

-- 封装GET请求函数
local function read_http(path, params)
    local res = ngx.location.capture(
        path,
        {
            method = ngx.HTTP_GET,
            args = params
        }
    )
    
    -- 检查请求是否成功
    if not res then
        ngx.log(ngx.ERR, "http not found: ", path, " ", params)
        ngx.exit(404)
    end
    
    return res.body
end

-- 导出函数
local _M = {
    read_http = read_http
}

return _M

使用通用工具

-- 导入工具模块
local common = require "common"
local read_http = common.read_http

-- 使用工具发起请求
local item_json = read_http("/item/" .. id, nil)

6. OpenResty向Tomcat发送HTTP请求

完整的商品查询流程

-- 导入工具
local common = require "common"
local cjson = require "cjson"

-- 获取路径参数
local id = ngx.var[1]

-- 查询商品信息
local item_json = common.read_http("/item/" .. id, nil)
local item_data = cjson.decode(item_json)  -- JSON转Lua table

-- 查询库存信息
local stock_json = common.read_http("/item/stock/" .. id, nil)
local stock_data = cjson.decode(stock_json)

-- 合并数据
item_data.stock = stock_data.stock
item_data.sold = stock_data.sold

-- 返回结果
ngx.say(cjson.encode(item_data))  -- Lua table转JSON

JSON处理

使用cjson库处理JSON数据: - cjson.encode(table) - Lua table转JSON - cjson.decode(json_string) - JSON转Lua table

总结

本篇笔记介绍了Lua的高级语法、OpenResty的安装配置以及如何在OpenResty中实现业务逻辑。通过封装HTTP请求工具和处理JSON数据,我们能够实现从OpenResty到Tomcat的请求转发,为多级缓存架构奠定了基础。这些技术使得我们可以在Nginx层面处理业务逻辑,减少对后端服务的直接依赖。

评论交流

文章目录