前言

在学习和使用 ngx_lua 的过程中我们发现,网络上资料其实非常多,但是非常零散,没有整体性,虽然技术本身是很清晰和易用的,但是对于刚接触这门技术的开发者来说,想要有条理、系统地把这些知识学完,可能会走一些弯路。

因为很多资料已经过时了,甄别和调试会耗费很多时间和精力,同时查阅英文文档也比较花时间。于是,我就有了把自己的学习过程和心得整理成书的想法。

随后的时间里,将自己学习Nginx下Lua开发的思路,以及这个过程中的资料一点点总结出来加以整理,终成本文。

希望本文可以帮助跟我有一样需求的研发工程师快速了解并掌握Nginx下Lua开发技术。

首先,我们看一下目录

 

其次,是主要内容的介绍

本文主要分五部分:

第一部分(第1~5章)介绍Nginx的基本操作,同时讲解了MySQL、PostgreSQL、Redis、Memcached、MongoDB、 OpenResty 的基本操作。通过对本部分的学习可以掌握这些服务的安装和使用方法,一般用于研发环境的搭建。这里还讲解了Nginx 核心技术和工作流程,用于帮助读者进一步掌握Nginx的架构和流程。各个层次的读者都可以从本部分读起。

第1章Nginx高效服务器,Nginx使用了大量的高并发和低内存占用技术,并使用了高可靠性技术,拥有高过Apache--个数量级以上的接人能力。因为并发能力强的特点,Nginx在中国的互联网公司中得到了大量应用,中国的大型互联网公司无一不使用了Nginx,以应对中国众多的网民,以及各种抢购热潮(如“双十一”)、 世界杯等热点事件。Nginx在这种大量的流量涌入、需要分流、导流、反向代理的场合下得到大量应用。

 

第2章数据库的基本操作,Nginx 应用系统通过以 ginx 为核心,合理搭配 is Memcac ed MySQL Postgre SQL Mongo 等服务器,可起到数据内存缓存、内存数据库、关系型数据库、 NoSQL 数据库等作用 互联网系统上有各种关系型数据需要存储,需要用到关系型数据库 互联网要应对大量的高并发请求,就需要高速处理 TTP 请求,需要用到各种数据缓存、页面缓存、操作缓存等 同时互联网上有大量的结构 非关系型数据要存储,还有各类音/视频、图片要缓存,需要用到各类内存型数据库、 NoSQ 数据库等,以形成完整的应用 所以本章将从这些数据库、缓存产品的作用 特点 安装方法、常用命令及配置文件解析展开。

 

第3章OpenResty,一个典型的互联网系统或云计算系统大量使用到关系型数据库、非关系型数据库、缓存、内存数据库等,以提供高速、高扩展性的服务,通常组成集群。以前协调这些系统开发是非常麻烦的,现在OpenResty提供的Nginx+Lua+Module的机制,使我们可以实现快速开发,让开发者着眼于应用,使用同一语言开发。在这种架构的应用领域里,其效率是其他语言和技术不能比拟的。

本章介绍OpenResty的组成及安装、配置方法。

 

第4章Nginx核心技术,在开发Nginx时,Apache 已经是-一个成熟的Web服务器了,性能不错、功能丰富、应用广泛。Nginx从设计之初就定位为高性能、高可靠性、高扩展性、高并发性的Web服务器,比Apache性能更好。Nginx 是基于HTTP协议的Web服务器,受HTTP协议的制约,有些问题解决起来比较棘手,所以采用了一系列技术解决这些问题。

本章介绍这些有特色的技术,以便我们更了解Nginx,知道Lua开发的工作机制,这些技术和思想也可以应用到我们的项目中去。

 

第5章Nginx的工作流程,详细了解Nginx的主要工作流程,可以让我们更好地认识Nginx,从而更好地使用Nginx,同时可以让我们更好地掌握Lua在Nginx中的工作流程。根据对Nginx核心技术和架构的了解,我们知道了管理进程1工作进程机制,以及HTTP核心模块和配置对Nginx的重要性,也知道了Nginx 的框架代码不多,只负责环境管理,本章将介绍这些部分的工作流程。

 

第二部分(第6~7章)详细讲解了Lua脚本语言和Lua通用库。学习Lua语言或查阅Lua语法的初学者可以直接阅读该部分相应章节。

第6章Lua教程,Lua是一种轻量、小巧的脚本语言,用标准C语言编写并以源代码形式开放。其设计目的是嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。目前Lua大量应用于Nginx、嵌入式设备、游戏逻辑开发等方面。

在Nginx中,Lua中的例程机制可以很好地和Nginx的全异步、非阻塞的多阶段处理机制结合,使开发者使用同步的模式,开发全异步的应用,而不用考虑异步的处理机制。

本章介绍Lua的基础语法知识。

 

第7章Lua通用库,Lua提供了-一些通用库,使用者在Lua中可以直接进行字符串操作、表操作、文件操作、访问操作系统、进行科学计算等。本章汇总这些常用函数和操作,方便读者使用中查找。

 

第三部分(第8~10章)讲解了在Nginx开发中经常使用的一-些技术,如JSON数据交换格式、nginx.conf 配置方法和配置指令;还讲解了Nginx' 下Lua开发的实现机制。学习Nginx配置的读者,学习和查阅JSON的读者可以直接阅读该部分相应章节,也可以跳过其他章节,直接学习Nginx'下Lua的实现机制。

第8章JSON数据交换格式,JSON是JavaScript Object Notation ( JavaScript对象表示法)的缩写,JSON是一种存储和交换文本信息的语法,类似XML。JSON比XML更小、更快,更易解析,是JavaScript内部使用的- - 种格式。JSON因为其特点,在互联网应用、嵌入式应用上得到了大量应用。我们在Nginx下的Lua开发中也大量使用JSON进行数据交换。本章介绍JSON这种常用的数据交换格式。

 

第9章nginx.conf文件配置,nginx.conf是Nginx的配置文件。Nginx 的工作流程是:在编译阶段选择要使用的模块并编译进整体工程中去。模块和业务的使用通过nginx.conf配置文件中配置指令的配置得以控制和实现,复杂的业务和自定义的业务逻辑使用Lua脚本实现。所以,nginx.conf 是我们开始开发及调整服务行为的首要途径。

配置正确的nginx.conf为我们提供一个正常运行且高效的服务框架,可以在框架内选择我们要介,人的HTTP请求处理阶段,编写Lua代码提供具体实现。

 

第10章Nginx 下Lua实现机制,Nginx中的大部分功能是通过模块提供的,这种方式使得Nginx开发和扩展很方便,模块可以依次串起来形成-一个过滤器。一个模块的失效不会影响其他部分,是Nginx扩展性和可靠性的一个保证。系统提供了如http模块、

mail模块、event 等模块。根据业务需要,通过配置或编译将不同的模块组合起来,形成自己业务特有的Web服务器,实现一些特定的功能。Nginx使用比较多的场合是反向代理,使用Nginx在前端做登录校验、JS合并、数据库访问、访问鉴权等,具体业务由反向代理实现,发挥Nginx业务开发灵活、有大并发接人和会话保持能力的优点。

 

第四部分(第11~26章)详细介绍了常用Lua库和数据库等组件的使用方法,包括Redis、MySQL、Memcached、PostgreSQL、 MongoDB、 Bit、 lfs、 restry.http、 leurl、 FFI、cjson、Template 、WebSocket。要了解和学习这些内容的读者,可以直接阅读对应章节。这里同时给出了两个Lua编程实例代码,要总体了解这项编程技术的读者可直接翻阅相应章节。

第11章Redis操作,Redis在系统中经常作为数据缓存、内存数据库使用,在大型系统中扮演着非常重要的作用。在Nginx核心系统中,Redis 是常备组件。本章主要介绍常用的Redis操作方法。

 

第12章MySQL操作,MySQL是- -个使用广泛的关系型数据库,用来保存关系型数据。根据应用,MySQL规模可大可小。大的系统可以做读写分离的大型集群。

在ngx_ lua 中,MySQL有两种访问模式:

1)使用ngx. _lua 模块和lua-resty-mysql模块:这两个模块是安装OpenResty时默认安装的。

2)使用drizzle. nginx_ module ( HttpDrizzeModule)模块:需要单独安装,这个库现不在OpenResty中。

本章分别介绍这两种MySQL操作方法。

 

第13章Memcached操作,访问Memcached有两种方式: mem-nginx-module 访问方式和lua-resty-memcached访问方式。lua-restry- memcached是由OpenResty实现的,mem-nginx-module也 被包含在OpenResty内。用OpenResty可以直接使用这两种方式访问Memcached,自行安装Nginx的需要加入这两个模块才可以使用。

 

第14章PostgreSQL操作,ngx_ postgres 用于和PostgreSQL数据库通信。应答包是RDS格式,可以和rds-json-nginx模块的drizzle nginx-module一起工作。

默认在OpenResty下没有使能本模块,需要在编译OpenResty时使用-with-http_postgres_ module选项打开。本模块需要系统中首先安装libpq。

 

第15章MongoDB操作,Nginx下使用lua-resty-mongol模块访问MongoDB,但lua-resty -mongol模块并没有打包在OpenResty内,需要单独安装,即在OpenResty的lualib目录下复制进对应的脚本文件。lua-resty mongol库提供了很好的性能和灵活性,内存占用率低。

 

第16章bit库的使用,Lua提供了bit库,可以对变量数据进行位运算,在某些应有场景,我们需要在Lua中对数据进行位移,或进行“与、或、非”及进制转换等操作。

例如,用一个32位的整数表示RGB颜色。32 位整数,被分为4个部分,每个部分8位,8位可表示的十进制数的范围是0 ~ 255。

 

第17章lfs库的使用,Ifs-file system operations ( LuaFileSystem)用于补充标准Lua发布版本的文件操作函数。LuaFileSystem提供了一个访问底层目录文件属性的轻便方法。Lua系统库里的文件函数只能打开文件以及对文件进行读写,Ifs 库提供了对文件和目录操作的方法。

 

第18章resty.http库的使用,resty.http用于访问外部HTTP资源、location等,如访问非本地location、外部Web服务、RESTFul、Web Service等。resty.http 是- -个轻量级HTTP库。

 

第19章lcurl库的使用,lcurl库封装了libcurl 的函数,为Lua提供了使用curl 的接口。

libcurl的主要功能是用不同的协议连接,与不同的服务器沟通,相当于封装了的sock。

libcurl当前支持http、https、 ftp、 gopher、 telnet、 dict、 file、 ldap协议。libcurl 同样支持

HTTPS证书授权,支持HTTP POST、HTTP PUT、FTP. 上传、HTTP基本表单上传、代理、cookies和用户认证。

lcurl功能强大,可以为Lua提供方便而强大的网络访问能力。

 

第20章FFI扩展C库,FFI库是LuaJIT中最重要的一个扩展库,允许在纯Lua代码内调用扩展的C例数或使用C数据结构。FFI库用于扩展Lua的功能,使Lua成为纯的“胶水”语言,可以整合丰富的C/C++库,实现高性能的功能。使用FFI库可以从C工程头文件复制代码进Lua代码,把开发者从开发Lua扩展C (语言1功能绑定库)的繁重工作中解放出来。

FFI被紧密地整合进LuaJIT中,JIT编译器为Lua代码直接访问C数据结构产生适配代码,等同于C编译器产生的代码。在JIT编译过的代码中,调用C函数被当作内联函数处理,不同于基于Lua/C API函数调用。

 

第21章cjson库的使用,Luacjson库为Lua提供了JSON处理能力,是一个快速的JSON处理库,包含在OpenResty内,可以使用编译开关打开或关闭,默认是打开的。

Lua cjson模块特点如下:

●快速,支持标准的编解码操作。

●完全支持UTF-8。

●可选运行期JSON异常支持。

●不支持UTF-16和UTF-32。

 

第22章lua-resty-template类的使用,Web开发中经常使用到动态Web网页开发技术,如淘宝商品页,详情页面显示非常复杂,逻辑也非常复杂,-.般都是使用动态页面技术实现的,常见的Web端动态页面技术是PHP、JSP等。但在商品详情这种页面中变动又不是那么快速,使用PHP、 JSP等又不完全合适,需要组建复杂的系统,使用CGI缓存等技术提高系统整体并发能力,这时可以使用模板技术实现。Lua 中有许多模板引擎,这里介绍OpenResty团队提供的lua-resty-template,可以渲染很复杂的页面,在LuaJIT上的性能表现不错。

 

第23章WebSocket的使用,WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(fll-duple),一开始的握手需要借助HTTP请求完成。

在WebSocket出现之前,网站为了实现即时通信,所用的技术是轮询( polling)。轮询是在特定的时间间隔(如每1秒)内,由浏览器对服务器发出HTTPrequest,然后由服务器返回最新的数据给客户端的浏览器。这种传统的HTTPrequest的模式带来很明显的缺点:浏览器需要不断地向服务器发出请求,然而HTTPrequest的header是非常长的,其中包含的有用数据可能只是一个很小的值,这样会占用很多的带宽。

 

第24章TCP私有服务器实例,本章描述一个使用Nginx架构实现一个私有的TCP服务器的实例,这个服务器用于实现物联网网关类设备使用私有协议接入功能。系统定义了基于JSON格式的交互协议,使

用TCP作为传输层协议。服务器使用stream模块实现TCP服务的功能,因为整体仍是Nginx架构,所以整个系统具备高并发处理能力,接入能力以w为单位。

ngx_ lua 模块使用例程机制,使得每- - 个请求都拥有一个独立的例程。因为网关类设备需要具备双向通信能力,所以与服务器是长连接,服务器会不定时将客户端请求转发到网关设备,也会不定期发送各种通知、消息。每个连接会在VM中保持-一个例程, 一个例程为一个连接处理,而我们编程也只需要考虑单个例程的工作流程即可,不用考虑自行编写服务器要考虑的:异步机制、状态机。通过ngx_ lua实现的完全是非阻塞异步的服务器,而编写代码只考虑同步风格。

 

第25章WebSocket接入服务器实战,WebSocket接入服务器实战这个实例实现了通用的Web接口,供客户端调用,同时使用了WebSocket协议实现了一个客户长连接接人的机制,客户端和服务器之间可以随时交换各种数据,完全等同于自已使用C\C++等编写的接人业务服务器。

WebSocket服务器启动后在9512端口上监听,接收来自于WebSocket客户端的连接。因为HTML5支持WebSocket协议,所以Nginx也支持该协议。客户端和服务端的连接方式是长连接,双方可以在任意时间内主动向对方发起通信。通信协议为JSON格式。

 

第26章Nginx应用简述,Nginx作为-个高速 Web服务器,用于典型的HTTP环境中。本章重点介绍小、中、大型以Nginx为核心的系统进化方式,为初入Nginx应用开发的使用者提供一个思路, 从开始就全面考虑或知道后面系统会遇到的问题更有利于系统的设计和后续的开发。

以Nginx为核心的系统进化方式分为4种,下面将具体展开论述。

 

第五部分(第27~28章)详细介绍了ngx._lua的配置指令和ngx._luaAPI,目的是帮助读者在工作中快速检索配置指令和API。

第27章 ngx lua module模块配置指令详解,ngx_ lua (ngx. _lua_ module 的简称)是Nginx的内嵌Lua模块,并不在Nginx发行的源码中。现在流行的Nginx下的Lua开发方式是OpenResty, OpenResty 打包了Nginx、LuaJIT、ngx_ lua. module 等,方便用户使用,具体请参见第3章。

ngx_ lua由配置指令和API两部分组成。本章详细介绍ngx_ lua的配置指令。

 

第28章ngx_ lua API详解,Nginx API包含方法、常量、状态码、变量等,服务于方法。各种*. _by_ _lua、 *. _by_lua_ block和*. by_ lua. file 指令是nginx.conf到Lua API的桥梁和网关。本章描述的NginxLua API只能在这些指令内编写和运行。

 

这份阿里P9大牛整理总结出的【NginxLua开发实战】共有582页,因为文章篇幅限制只能给大家介绍部分内容,每个小节还有更加细化的内容,需要完整版的朋友可以转发关注小编,👇👇👇

总结

Nginx上的Lua技术是近些年来由中国人章亦春整合出来的架构,将高效、轻量级的Lua脚本语言和Nginx结合起来,可以快捷、方便地开发应用系统。使用同步式的编程习惯实现异步非阻塞的高效模式,使新上手的工程师也可以快速开发高性能应用。据资深互联网专家描述以及本人亲身体会,在典型应用下,使用Lua可以使代码量减少90%左右,带来的经济效益和抢得的市场先机自不待言。对于工程师本身来讲,减少加班、多点时间喝杯咖啡也是极具吸引力的。

传统分布式平台要升级为云平台都是通过将已有的分布式平台改造成云服务,进行互联网部署,往往需要多位资深服务器开发工程师花费大量时间共同提供支持,而Nginx+Lua+Redis架构的出现,从根本上简化了这种方式,少量工程师花费少于原有体系的工作时间即可完成业务服务搭建。

Nginx+Lua架构不仅可以节约时间和成本,从做大型系统的角度来看,它还具有诸多优势:

  • 调试方便:不需要编译代码,相关访问模块是成熟稳定的,只需要调试新加的业务代码即可。大型系统,特别是分布式系统,一个功能或代码的调试链条很长,非常容易出错。
  • 降低耦合:因为架构的限制,Lua代码只能在必须的阶段管理器中开发,代码是一个一个.Iua文件,耦合性大幅降低。
  • 框架良好:先进的异步式多进程架构,可以充分利用系统资源。而如果自行开发并维护这样一个框架, 则需要大量的人力、物力。
  • 上手容易: Lua代码具有良好的结构和可读性,上手速度更快。团队成员经过快速培训就可以上手。

希望大家能够学以致用,以加大自己的知识储备,增加自己的技术深度和宽度。