OpenResty一些重要特性的整理

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

内容简介: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 框架

待续


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

查看所有标签

猜你喜欢:

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

简约至上

简约至上

[英] Giles Colborne / 李松峰、秦绪文 / 人民邮电出版社 / 2011-1-1 / 35.00

追求简单易用是人类的本性,无论是互联网产品。还是移动应用。亦或其他交互式设计,简单易用始终都是赢得用户的关键。同时,简单易用的程度也与产品寿命的长短密切相关。在《简约至上:交互式设计四策略》中,作者Giles托20多年交互式设计的探索与实践。提出了合理删除、分层组织、适时隐藏和巧妙转移这四个达成简约至上的终极策略,讲述了为什么应该站在主流用户一边,以及如何从他们的真实需求和期望出发,简化设计,提升......一起来看看 《简约至上》 这本书的介绍吧!

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

各进制数互转换器

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具