Openresty+lua 演示(可用于后续网关开发)

OpenResty简介

  • 一款基于 NGINX 和 LuaJIT 的 Web 平台
  • https://openresty.org/en/

OpenResty是什么?

  • OpenResty(也称为 ngx_openresty)是一个全功能的 Web 应用服务器。它打包了 雅虎中国的一个公司项目,起步于 2007 年 10 月。
  • 它通过揉和众多设计良好的 Nginx 模块,OpenResty 有效地把 Nginx 服务器转变为一个强大的 Web 应用服务器。
  • 可以充分利用 Nginx 的事件模型来进行非阻塞 I/O 通信。不仅仅是和 HTTP 客户端间的网 后端之间的网络通信也是非阻塞的。

优点

  • 1、只需安装 openresty 即可拥有常规LNMP架构等效的能力。 (Nginx + Lua + MySQL + Redis + Memcached + ZeroMQ + WebSocket …)
  • 2、并发能力超强,充分利用 Nginx 的事件模型来进行非阻塞 I/O 通信,(相当于一个Lua版本的NodeJs服务器)
  • 3、业务逻辑代码热更新,在生产环境中完成热加载(代码有变动时,自动加载最新 Lua 代码,本的 Nodejs 服务器)但是 Nginx 本身,不做任何 reload)
  • 4、在请求真正到达上游服务之前,Lua 可以随心所欲的做复杂的访问控制和安全检测 (http请求流转的各个环节都可以用lua介入到nginx,并可以随心所欲的操控响应头里面的信息)

缺点

  • 1、不易调试
  • 2、周边第三方库不太成熟,缺乏成熟Web 框架
  • 3、i/o操作受限于nginx模型

Lua语言

  • Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能
  • Lua 是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto Ierusalimschy、 Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于 1993年开发。
  • 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

Lua特性

  • 轻量级:它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
  • 可扩展:Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
  • 基本特性:
    1. 自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;
    2. 语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程支持;
    3. 通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,继承和重载等。

Lua 应用场景

  • 1、游戏开发辅助脚本(暴雪魔兽、网易大话西游)
  • 2、独立应用脚本(Kong)
  • 3、Web 应用脚本(新浪 Vanilla 框架 http://www.tuicool.com/articles/vM7NNva)
  • 4、扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench
  • 5、安全系统,如入侵检测系统

Lua 优势

  • 1、极小的体积和简单的语法提供相对全面的功能
  • 2、简洁的API实现与宿主语言最方便的接口
  • 3、与平台无关,几乎可以运行于所有系统

Lua 嵌入式编程语言

  • lua可以独立进行编程,但这不是主要的使用方式。Lua虽然有动态、灵活的语法提供强大的功能,但并不能像Java、Python等一样有一个完善的库,这不是缺陷,而是和其定位有关。
  • “嵌入式”,lua作为一个库,嵌入到其他大型语言(称之为宿主语言)的应用程序之中,为应用程序提供参数配置或逻辑描述等功能,带来前所未有的灵活性。

lua的经典使用方式

  • lua作为配置文件,为宿主语言提供参数
  • 宿主语言为底层库,lua作为逻辑处理

工作流程

  • 宿主语⾔言建⽴立Lua解释器器对象。
  • 将宿主语⾔言实现的Lua扩展,如函数等,注册到Lua解释器器中,供其使⽤用
  • 读⼊入Lua源程序或预先编译后的Lua程序
  • 执⾏行行读⼊入的Lua程序

Lua与宿主语言的交互方式

  • 1、宿主语言通过虚拟机对Lua脚本中的变量实现增、删、读、写
  • 2、宿主语言通过虚拟机调用Lua脚本中的函数
  • 3、宿主语言定义新的数据类型供Lua脚本使用
  • 4、Lua调用宿主语言编写的函数

Lua 基本类型

赋值
a=3
x, y, z = 12, 'Hello', true
基本类型:

-空类型 nil

-数值 number:123,3.14159,1.6e-9

-运算:+ - * / % ^(乘幂) -(负)

-布尔 boolean:true,false
运算:or and not
字符串 string:'www.hello.com',"你好"
运算:..(连接),# (⻓长度)
其他通用运算符:

== ~= > < >= <= (~= 表示不等于)

Lua 中的表table

  • Lua使用table类型作为一切数据结构的基础:

    t = {1234, nil, ‘hello’, true, {‘nested’, 1.414}}

  • table本质为哈希表,保存键-值对的集合,若不指定键,则默认为从1开始的整数。也可显式指定键 rec = {['name'] = '111', favorite = '222', [10] = true}

  • 引用表的元素:

rec.name rec[‘favorite'] rec[10]

  • 活用表类型,可以构成结构体、链表、数组、对象等各种复杂数据结构。

OpenResty 指令

set_by_lua / set_by_lua_file access_by_lua / access_by_lua_file rewrite_by_lua / rewrite_by_lua_file content_by_lua / content_by_lua_file

详细参考: http://www.111cn.net/sys/linux/64574.htm

set_by_lua

location = /adder {
    set_by_lua $res "
        local a = tonumber(ngx.arg[1])
        local b = tonumber(ngx.arg[2])
        return a + b"  $arg_a $arg_b;
        
    echo $res;
}

http://ip:8083/adder?a=100&b=100
和set指令一样用于设置Nginx变量并且在rewrite阶段执行,只不过这个变量是由lua脚本计算并返回的

access_by_lua

location /auth{
    root    html;
    index   index.html  index.htm;
    default_type text/html;
    
    access_b_lua '
        if  ngx.var.remote_user == "chenyz" and ngx.var.remote_passwd == "123" then
            return
        end
        ngx.header.www_authenticate = [[Basic realm="Restricted"]]
        ngx.exit(401)
    ';
}

http://ip:8083/auth
运行在access阶段,用于访问控制。Nginx原生的allow和deny是基于ip的 通过access_by_lua能完成复杂的访问控制,比如,访问数据库进行用户名、密
码验证等

rewrite_by_lua

location = /rew{
    rewrite_by_lua 'ngx.exec("/go")';
    echo 'this rew';
}

location /go{
    echo 'this is go';
}

http://ip:8083/rew
实现url重写,在rewrite阶段执行

content_by_lua

location /hello1{
    root    html;
    index   index.html  index.htm;
    default_type    text/html;
    content_by_lua '
        ngx.say("hello world");
    ';
}

location /hello2{
    root    html;
    index   index.html  index.htm;
    defaul_type text/html;
    content_by_lua_file 'conf/hello.lua';
}

http://ip:8083/hello1

在content阶段执行,生成http响应

使用memcached

require('Memcached')

memcache = Memcached.Connect('memcached.product.house.163.com', 11211)
memcacheobject = memcacge:get('hello')

memcache:set('hello', 'chenyz', 60*60)

在lua 脚本内部,可以像PHP那样连接Memcached,读写数据

IP控制

location /ip_area{
    access_by_lua '
    if ngx/var.remote_addr == "113.108.224.230" then
        return
    end
    ngx.redirect('/post-error')
    ';
}

当发现访问IP为指定IP时,重定向到指定⻚页面

相关资料

  • OpenResty XMind脑图
    http://naotu.baidu.com/file/e24b5f1e8e5abea8a04312d87b334434? token=3bcfeb5ba50491f7

  • 《OpenResty 最佳实践》 https://www.gitbook.com/book/moonbingbing/openresty-best-practices/
    details

  • OpenResty 技能图谱
    https://github.com/TeamStuQ/skill-map/blob/master/data/designbyStuQ/ png-OpenResty-by-StuQ.png

文章转载自:码农启示录

你可能感兴趣的:(linux)