【服务器知识】nginx不够,那我们就试试openresty

文章目录

概述

OpenResty是一个基于Nginx和LuaJIT的高性能Web平台,它集成了大量精良的Lua库、第三方模块以及大多数的依赖项。这使得OpenResty能够方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。

OpenResty的核心特性包括:

  1. Nginx核心:OpenResty基于Nginx,一个高性能的HTTP和反向代理服务器,以其稳定性和丰富的功能著称。

  2. LuaJIT集成:OpenResty集成了LuaJIT,这是一个快速的Lua解释器,它使用即时编译技术将Lua代码编译成机器码,从而提高执行效率。

  3. 动态Web平台:OpenResty提供了一个动态Web平台,允许开发者使用Lua脚本语言调动Nginx支持的各种C以及Lua模块,快速构造出足以胜任10K乃至1000K以上单机并发连接的高性能Web应用系统。

  4. API Gateway:OpenResty常被用作API Gateway,处理API请求,提供负载均衡、动态上游、灰度发布、服务熔断、身份认证等功能。

  5. 扩展性:通过集成的第三方模块和库,OpenResty可以轻松扩展,支持各种Web应用和服务的需求。

  6. 高性能:OpenResty的性能接近或超过Nginx的C模块,而且开发效率更高,这得益于LuaJIT的优化和Nginx的非阻塞I/O模型。

  7. 社区支持:OpenResty有一个活跃的社区,提供大量的文档、教程和第三方模块,支持开发者快速上手和解决问题。

OpenResty的工作原理:

OpenResty的工作原理涉及到几个关键组件:

  • Nginx:作为基础服务器,处理HTTP请求和响应。
  • LuaJIT:提供脚本执行环境,允许在Nginx事件模型中运行Lua代码。
  • Cosocket:OpenResty中的核心技术,结合Lua协程和Nginx的事件机制,实现了非阻塞网络IO。
  • Worker进程:每个Worker使用一个LuaVM,每个请求在LuaVM中创建一个协程。

如何使用OpenResty:

  1. 安装OpenResty:可以通过包管理器、源码编译或Docker安装OpenResty。
  2. 配置Nginx :在Nginx配置文件中使用OpenResty提供的指令,如content_by_lua,来嵌入Lua脚本。
  3. 编写Lua脚本:使用Lua脚本处理业务逻辑,如数据库操作、HTTP请求处理等。
  4. 启动和测试:启动OpenResty服务,并通过HTTP请求测试配置的Lua脚本是否按预期工作。

OpenResty的灵活性和高性能使其成为构建现代Web应用和服务的理想选择,特别是在需要处理高并发请求的场景下。

OpenResty勾子函数

OpenResty提供了一系列的钩子函数,允许你在Nginx处理HTTP请求的不同阶段执行Lua代码。以下是OpenResty中一些常用的钩子函数及其使用方式的详细介绍:

  1. init_by_lua

    • 这个钩子在Nginx启动时执行一次,常用于预加载Lua模块或初始化共享内存字典。
    • 使用方式:在nginx.conf中添加init_by_lua 'lua_code';
  2. init_worker_by_lua

    • 这个钩子在每个Nginx工作进程启动时执行,适用于初始化工作进程特定的数据。
    • 使用方式:在nginx.conf中添加init_worker_by_lua 'lua_code';
  3. set_by_lua

    • 在重写阶段执行,可以设置请求变量或执行其他逻辑。
    • 使用方式:在nginx.confserverlocation块中添加set_by_lua 'lua_code';
  4. rewrite_by_lua

    • 在重写URL时执行,常用于实现复杂的转发或重定向逻辑。
    • 使用方式:在nginx.confserverlocation块中添加rewrite_by_lua 'lua_code';
  5. access_by_lua

    • 在访问控制阶段执行,可以用于实现访问控制逻辑。
    • 使用方式:在nginx.confserverlocation块中添加access_by_lua 'lua_code';
  6. content_by_lua

    • 作为内容生成器执行,用于生成响应体。
    • 使用方式:在nginx.conflocation块中添加content_by_lua 'lua_code';
  7. header_filter_by_lua

    • 在响应头发送前执行,可以修改响应头。
    • 使用方式:在nginx.confserverlocation块中添加header_filter_by_lua 'lua_code';
  8. body_filter_by_lua

    • 在响应体发送前执行,可以修改响应体内容。
    • 使用方式:在nginx.confserverlocation块中添加body_filter_by_lua 'lua_code';
  9. log_by_lua

    • 在请求日志记录时执行,可以用于记录自定义日志或进行日志处理。
    • 使用方式:在nginx.confserverlocation块中添加log_by_lua 'lua_code';
  10. balancer_by_lua

    • 作用于upstream,作为负载均衡器运行。
    • 使用方式:在nginx.confupstream块中添加balancer_by_lua 'lua_code';
  11. ssl_certificate_by_lua

    • 在Nginx准备启动下游SSL连接的SSL握手之前执行。
    • 使用方式:在nginx.confserver块中添加ssl_certificate_by_lua 'lua_code';

这些钩子函数都可以在Nginx配置文件中以指令的方式配置生效,允许开发者在不同的处理阶段插入自定义的Lua代码来实现业务逻辑。通过合理利用这些钩子函数,可以构建出功能强大且灵活的Web应用和服务。更多详细信息可以参考OpenResty的官方文档 。

🔍 我如何使用OpenResty的钩子函数来实现权限校验?

在OpenResty中实现权限校验通常涉及到使用Nginx的钩子函数来执行Lua脚本,这些脚本可以检查用户的权限。以下是一些常用的方法和步骤:

  1. 使用access_by_luaaccess_by_lua_file钩子

    这些钩子在Nginx的访问控制阶段执行,允许你在请求处理的早期进行权限校验。

    nginx 复制代码
    location /some/path {
        access_by_lua_block {
            -- Lua代码来验证用户权限
            if not user_has_permission(ngx.var.user) then
                ngx.exit(401) -- 如果没有权限,返回401状态码
            end
        }
    }

    或者使用外部Lua文件:

    nginx 复制代码
    location /some/path {
        access_by_lua_file /path/to/lua/script.lua;
    }

    在Lua脚本中,你可以使用各种方法来验证用户权限,例如检查HTTP头、查询数据库或调用外部服务。

  2. 使用JWT进行身份验证

    JSON Web Tokens (JWT)是一种流行的方法来在无状态的HTTP环境中传递安全信息。你可以使用OpenResty中的lua-resty-jwt库来验证JWT。

    lua 复制代码
    local jwt = require "resty.jwt"
    
    -- 从请求头中获取JWT
    local token = ngx.req.get_headers()["Authorization"]
    
    -- 验证JWT
    local jwt_obj, err = jwt:verify(token)
    if not jwt_obj then
        ngx.log(ngx.ERR, "failed to verify token: ", err)
        ngx.exit(401)
    end
    
    -- 根据JWT中的信息进行权限校验
    local user_id = jwt_obj.sub
    if not is_user_allowed(user_id) then
        ngx.exit(403)
    end
  3. 使用OpenResty进行API网关权限控制

    你可以将OpenResty用作API网关,并在网关级别实现权限控制。这通常涉及到检查白名单URI、解析和验证Token、查询数据库获取用户权限等步骤。

    nginx 复制代码
    location / {
        access_by_lua_file /usr/local/openresty/nginx/conf/lua/scripts/check权限.lua;
    }

    在Lua脚本check权限.lua中,你可以实现具体的权限检查逻辑,例如:

    lua 复制代码
    -- 白名单URI
    local white_uris = {"/user/login", "/user/validate"}
    local uri = ngx.var.request_uri
    
    -- 检查是否为白名单URI
    if not is_include(uri, white_uris) then
        local token = ngx.req.get_headers()["token"]
        if not token then
            ngx.status = 401
            ngx.say('无法获取token')
            return
        end
    
        -- 验证token
        local jwt_obj = jwt:verify(vars.jwt_salt(), token)
        if not jwt_obj['verified'] then
            ngx.status = 401
            ngx.say('无效的token')
            return
        end
    
        -- 获取用户权限
        local user_id = jwt_obj['payload']['sub']
        local permissions = get_permissions_from_db(user_id)
        if not is_include(uri, permissions) then
            ngx.status = 403
            ngx.say('没有权限')
            return
        end
    end

    在这个例子中,我们首先检查请求的URI是否在白名单中。如果不在白名单中,我们提取请求头中的token,验证token的有效性,然后根据token中的用户ID查询数据库获取用户权限,并最终检查用户是否有权限访问请求的URI。

这些是在OpenResty中实现权限校验的一些常见方法。具体的实现可能会根据你的应用需求和安全要求有所不同。更多详细信息可以参考OpenResty的官方文档和相关社区资源 。

Lua简单语法

Lua是一种轻量级的脚本语言,它以其简洁的语法和强大的功能而受到许多开发者的喜爱。以下是Lua语言的一些基本语法说明:

1. 变量

Lua中变量的类型声明使用类型前缀来表示:

  • local:局部变量,只在声明它的代码块中可见。
  • number:数字类型,用于表示整数和浮点数。
  • string:字符串类型,使用单引号'或双引号"括起来。
  • boolean:布尔类型,值为truefalse
  • nil:表示空值或无值。
  • table:表类型,Lua中唯一的复合数据类型,用作数组、字典或多维数组等。
lua 复制代码
local x = 10        -- 局部变量
local name = "Kimi"  -- 字符串
local is_active = true -- 布尔值
local nothing = nil   -- 空值
local points = {1, 2, 3} -- 表作为数组
local matrix = {
  {10, 20},        -- 表作为二维数组
  {30, 40}
}

2. 控制结构

Lua中的控制结构包括条件语句和循环语句。

if语句

lua 复制代码
if age >= 18 then
  print("You are an adult.")
elseif age >= 13 then
  print("You are a teenager.")
else
  print("You are a child.")
end

while循环

lua 复制代码
local count = 1
while count <= 5 do
  print("Count is", count)
  count = count + 1
end

for循环

lua 复制代码
for i = 1, 5 do
  print("Index is", i)
end

for-in循环:遍历表中的所有元素

lua 复制代码
for key, value in pairs(my_table) do
  print("Key:", key, "Value:", value)
end

3. 函数

Lua中的函数定义使用function关键字:

lua 复制代码
function greet(name)
  print("Hello, " .. name .. "!")
end

greet("Lua")  -- 输出:Hello, Lua!

4. 表(Table)

Lua中的表是一种非常灵活的数据结构,可以作为数组、字典或多维数组使用。

数组表示

lua 复制代码
local numbers = {10, 20, 30}
print(numbers[1])  -- 输出:10

字典表示

lua 复制代码
local person = {
  name = "Kimi",
  age = 30
}
print(person.name)  -- 输出:Kimi

5. 模块

Lua使用模块来组织代码,模块在Lua中是通过表来实现的。

定义模块

lua 复制代码
local mymodule = {
  secret = "something",
  public = "everything"
}

function mymodule.publicFunction()
  print("I am public.")
end

return mymodule

使用模块

lua 复制代码
local mod = require("mymodule")
mod.publicFunction()  -- 输出:I am public.
print(mod.secret)  -- 输出:something

Lua语言的简洁性和灵活性使其成为嵌入式脚本和游戏开发的理想选择。以上只是Lua语言的一些基本语法,Lua还提供了许多高级特性,如元表、闭包、协程等。更多详细信息可以参考Lua的官方文档。

相关文献

弄懂nginx看这一篇文章就够了

相关推荐
LIKEYYLL2 小时前
GNU Octave:特性、使用案例、工具箱、环境与界面
服务器·gnu
云云3212 小时前
搭建云手机平台的技术要求?
服务器·线性代数·安全·智能手机·矩阵
云云3212 小时前
云手机有哪些用途?云手机选择推荐
服务器·线性代数·安全·智能手机·矩阵
CircleMouse3 小时前
Centos7, 使用yum工具,出现 Could not resolve host: mirrorlist.centos.org
linux·运维·服务器·centos
木子Linux3 小时前
【Linux打怪升级记 | 问题01】安装Linux系统忘记设置时区怎么办?3个方法教你回到东八区
linux·运维·服务器·centos·云计算
不惑_4 小时前
小白入门 · 腾讯云轻量服务器部署 Hadoop 3.3.6
服务器·hadoop·腾讯云
阿甘知识库4 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
m0_748250745 小时前
高性能Web网关:OpenResty 基础讲解
前端·openresty
zhou周大哥6 小时前
linux 安装 ffmpeg 视频转换
linux·运维·服务器
loong_XL7 小时前
服务器ip:port服务用nginx 域名代理
服务器·tcp/ip·nginx