OpenResty一些重要特性的整理

栏目: 服务器 · Nginx · 发布时间: 7年前

内容简介:OpenResty (简称OR) 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的Lua Api,第三方模块以及常用的依赖项,基于这些能力,我们可以利用OR快速方便的搭建能够处理超高并发的,极具动态性和扩展的Web应用、Web服务和动态网关。这篇文章选择OR中具有重要意义的一些模块、命令、Api和框架介绍如下:OR 作为一款 Web 服务器,提供了如:

OpenResty (简称OR) 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的Lua Api,第三方模块以及常用的依赖项,基于这些能力,我们可以利用OR快速方便的搭建能够处理超高并发的,极具动态性和扩展的Web应用、Web服务和动态网关。

这篇文章选择OR中具有重要意义的一些模块、命令、Api和框架介绍如下:

基础的Http处理

OR 作为一款 Web 服务器,提供了如:

  • ngx.print() | ngx.say()
  • ngx.req.get_headers()
  • ngx.resp.get_headers()
  • ngx.header.HEADER
  • ngx.exit()

    等函数和方法控制http请求的输入和输出,我们可以通过这些 api 灵活的控制 Web Server 中包括输入输出,转发到上游或者发起子请求在内的各个环节。

ngx.print

同ngx.say(), 通过该 api 可以指定返回的请求的消息体,其中每一次函数的调用,都是在nginx的输出链上增加了一个结点,所以我们可以多次调用该函数而不用担心后者会覆盖前者,如:

location =/hello {
    content_by_lua_block {
        ngx.print("Hello")      
        ngx.print(" ")      
        ngx.print("World!")      
    }
}

GET /hello 将会得到如下结果
======
Hello World!

请求头和响应头控制

ngx.exit() 和 ngx.status

ngx.exit,通过该 api可以指定请求响应体的 http status, 如:

location =/error {
    content_by_lua_block {
        return ngx.exit(500)    
    }
}

GET /error
======
<html>
<head><title>500 Internal Server Error</title></head>
<body bgcolor="white">
<center><h1>500 Internal Server Error</h1></center>
<hr><center>openresty</center>
</body>
</html>

当我们访问 /error 接口的时候,可以得到一个默认的 500 页面,如上所示,当然我们可以通过ngx.status + ngx.print 的组合方式得到自定义的错误页面,如:

location =/error {
    content_by_lua_block {
        ngx.status = 500
        ngx.print("error here!")
        return ngx.exit(500)    
    }
}

GET /erro
======
error here!

以上方式同样适用于其它错误,如 404、502、503 等页面,通过这样的方式我们可以更灵活的控制当这些错误,从而返回更友好的页面或者其它输出,当然你也可用使用 nginx 原生的 error_page 指令对错误页面进行控制,只是灵活性相对差一些

ngx.timer.at

在OR内部通过 nginx 事件机制实现的定时器,我们可以通过它来实现延迟运行的任务逻辑,甚至于通过一些特殊的调用方法实现定时任务的功能,比如:

local delay = 5
 local handler
 handler = function (premature)
     -- do some routine job in Lua just like a cron job
     if premature then
         return
     end
     local ok, err = ngx.timer.at(delay, handler)
     if not ok then
         ngx.log(ngx.ERR, "failed to create the timer: ", err)
         return
     end
 end

 local ok, err = ngx.timer.at(delay, handler)
 if not ok then
     ngx.log(ngx.ERR, "failed to create the timer: ", err)
     return
 end

可以看到我们给ngx.timer.at的第二个参数是这个函数体本身,通过这样的写法,我们可以实现每个delay的间隔执行一次handler

当然这种“不友好”的技巧在v0.10.9这个版本之后被ngx.timer.every给“优化”了(上述技巧依旧有效)。

当然除此之外,这个API还有其它“非凡”的意义。

OR的各个API其实都有其“生命周期”或者说作用域,比如其中非常重要的cosocket,它的作用域如下

rewrite_by_lua , access_by_lua , content_by_lua , ngx.timer. , ssl_certificate_by_lua , ssl_session_fetch_by_lua

也就是说我们只能在上述阶段使用 cosocket,由于很多第三方组件的实现都是基于它,比如

resty-redis,resty-memcached,resty-mysql

所以 cosocket 的作用域就等同于上述这些依赖它的模块的作用域

我们再来看看ngx.timer.at的作用域

init_worker_by_lua , set_by_lua , rewrite_by_lua , access_by_lua , content_by_lua*,

header_filter_by_lua , body_filter_by_lua , log_by_lua , ngx.timer. , balancer_by_lua*,

ssl_certificate_by_lua , ssl_session_fetch_by_lua , ssl_session_store_by_lua*

这意味着,如果我们希望在 cosocket 不支持的作用域内使用它,那么我们可以通过 ngx.timer.at 的方式桥接,完成“跨域”, 比如:

init_worker_by_lua_block {
    local handler = function()
        local redis = require "resty.redis"
        redc = redis:new(anyaddre)
        redc:set('foo', 'bar')
    end
    
    ngx.timer.at(0, handler)
}

这就是前文所说的,这个API的”非凡“意义,当然我更期望的是 cosocket 能够支持更多的作用域 ^_^!

跨进程共享 ngx.shared.DICT

通常来说,我们会将一些系统的配置写入lua代码中,通过require的方式在不同worker之间共享,这种看起来像是跨worker的共享方式其实是利用了”一个模块只加载一次“的特性(lua_code_cache on), 但是这种方式只适合于一些只读数据的共享,并不适合一些可写的(严格来说, 可以通过一些技术手段实现这个级别的缓存,由于能实现table类型的缓存,它的效率并不差,这里不做讨论),或者动态变化的数据,比如从关系型数据库、kv数据库,上游、第三方服务器获取的数据的缓存。

ngx.shared.DICT 方法集提供了解决跨 worker 且自带互斥锁的共享数据方案,配合 cjson 或者 resty-dkjson 这样的 json 解析库,极大丰富了这个API集合的应用空间,需要注意的是:

  1. 它需要在nginx的配置文件中被预先定义好大小且不可动态扩容, 如: lua_shared_dict cache 16m;
  2. 尽可能的使用 cjson 而非 dkjson, 它们之间效率相差 50 倍以上;
  3. 它是一个内存数据集,并不具备持久化的能力;
  4. 宁愿定义多个容量更小的存储体,而非一个更大的;

ssl_certificate_by_lua_xxx

待续

ssl_session_fetch_by_lua_xxx 和 ssl_session_store_by_lua_xxx

待续

Web 框架

待续


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Persuasive Technology

Persuasive Technology

B.J. Fogg / Morgan Kaufmann / 2002-12 / USD 39.95

Can computers change what you think and do? Can they motivate you to stop smoking, persuade you to buy insurance, or convince you to join the Army? "Yes, they can," says Dr. B.J. Fogg, directo......一起来看看 《Persuasive Technology》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

在线进制转换器
在线进制转换器

各进制数互转换器