编辑推荐

适读人群:追求高性能的Web应用研发工程师微服务、API网关、Web应用防火墙的研发工程师通用的HTTP/TCP/UDP应用服务研发工程师基于OpenResty/Nginx深度定制的研发工程师工作在Linux系统上的的运维、测试工程师计算机编程爱好者

OpenResty完全开发指南:构建百万级别并发的Web应用》由一线技术专家基于自己的工作经验精心撰写而成,主要包括OpenResty的组成、运行平台、工作语言、内部运行机制、功能接口、各种服务的配置和开发方式。

OpenResty完全开发指南:构建百万级别并发的Web应用》作者技术功底强,写作水平高,写作的图书不唯市场论,不唯风头论,只写自己一线工作经验,对于自己的技术书籍出版也从来都是一丝不苟,一心只为大家奉献优质、实用且实战的优秀技术图书!

内容简介

OpenResty是一个基于Nginx的高性能Web平台,能够方便地搭建处理超高并发的动态Web应用、Web服务和动态网关。

与现有的其他开发语言/环境相比,OpenResty有着高性能、高灵活性、易于学习和扩展等许多优点,近年来得到了越来越多开发者的关注,也有了很多成功的应用范例,如Adobe、Dropbox、GitHub等知名公司都基于OpenResty构建了自己的后端业务应用。

OpenResty自带完善的帮助文档,开发社区也很活跃,但相关的学习资料——特别是中文资料较少。《OpenResty完全开发指南:构建百万级别并发的Web应用》基于作者多年使用OpenResty的经验,系统地阐述了OpenResty相关的各方面知识和要点,帮助读者快速掌握这个高效易用的Web开发平台,进而实现HTTP/HTTPS/TCP/UDP等多种网络应用。

《OpenResty完全开发指南:构建百万级别并发的Web应用》结构严谨、详略得当,具有较强的实用性,适合广大软件开发工程师、系统运维工程师、编程爱好者和计算机专业学生阅读参考。

作者简介

罗剑锋(网名Chrono),96年就读于东北财经大学1997年开始接触C/C++1998年参加计算机软件专业技术资格和水平考试,获高级程序员资质2003年毕业于北京理工大学,获计算机专业硕士学位主要研究方向为C/C++、设计模式、高性能网络服务器开发业余爱好是阅读、旅游、欣赏音乐和电影。

目录

第0章导读1

0.1关于《OpenResty完全开发指南:构建百万级别并发的Web应用》1

0.2读者对象1

0.3读者要求3

0.4运行环境3

0.5《OpenResty完全开发指南:构建百万级别并发的Web应用》的结构3

0.6如何阅读《OpenResty完全开发指南:构建百万级别并发的Web应用》5

0.7《OpenResty完全开发指南:构建百万级别并发的Web应用》的源码5

第1章总论7

1.1简介7

1.2历史8

1.3组成9

1.4版本11

1.5安装12

1.5.1直接安装12

1.5.2源码安装13

1.5.3定制安装13

1.6目录结构14

1.7启停服务15

1.8组件管理工具15

1.9命令行工具16

1.10参考手册18

1.11性能对比18

1.12应用架构21

1.13总结22

第2章Nginx平台23

2.1简介23

2.2进程模型24

2.3配置文件25

2.4变量26

2.5HTTP服务27

2.5.1server配置28

2.5.2location配置28

2.6TCP/UDP服务29

2.7反向代理29

2.7.1上游集群30

2.7.2代理转发31

2.8运行日志31

2.8.1访问日志32

2.8.2错误日志32

2.9总结32

第3章Lua语言35

3.1简介35

3.2注释36

3.3数据类型36

3.4字符串37

3.5变量38

3.6运算39

3.6.1算术运算39

3.6.2关系运算39

3.6.3逻辑运算40

3.6.4字符串运算40

3.6.5注意事项41

3.7控制语句41

3.7.1语句块41

3.7.2赋值语句41

3.7.3分支语句42

3.7.4循环语句43

3.8函数44

3.8.1定义函数44

3.8.2参数和返回值45

3.9表46

3.9.1定义表46

3.9.2操作表46

3.9.3范围循环47

3.9.4作为函数的参数48

3.10模块48

3.11面向对象49

3.11.1基本特性49

3.11.2原型模式50

3.11.3self参数51

3.12标准库51

3.12.1base库52

3.12.2package库52

3.12.3string库53

3.12.4table库54

3.12.5math库55

3.12.6io库56

3.12.7os库57

3.12.8debug库57

3.12.9使用技巧57

3.13高级特性58

3.13.1闭包58

3.13.2保护调用58

3.13.3可变参数59

3.14总结59

第4章LuaJIT环境61

4.1简介61

4.2goto语句62

4.3jit库62

4.4table库63

4.5bit库63

4.6ffi库65

4.7编译为字节码67

4.8编译为机器码68

4.9总结68

第5章开发概述71

5.1应用示例71

5.1.1编码实现71

5.1.2测试验证73

5.2运行命令74

5.3目录结构75

5.4配置指令76

5.5运行机制77

5.5.1处理阶段77

5.5.2执行程序79

5.5.3定时任务81

5.5.4流程图81

5.6功能接口83

5.7核心库83

5.8应用开发流程84

5.9总结85

第6章基础功能87

6.1系统信息87

6.2运行日志88

6.3时间日期89

6.3.1当前时间90

6.3.2时间戳90

6.3.3格式化时间戳90

6.3.4更新时间91

6.3.5睡眠91

6.4数据编码92

6.4.1Base6492

6.4.2JSON92

6.4.3MessagePack94

6.5正则表达式95

6.5.1配置指令95

6.5.2匹配选项96

6.5.3匹配96

6.5.4查找98

6.5.5替换99

6.5.6切分100

6.6高速缓存101

6.6.1创建缓存101

6.6.2使用缓存102

6.7总结103

第7章HTTP服务105

7.1简介105

7.2配置指令106

7.3常量107

7.3.1状态码107

7.3.2请求方法108

7.4变量108

7.4.1读变量108

7.4.2写变量109

7.5基本信息110

7.5.1请求来源110

7.5.2起始时间110

7.5.3请求头110

7.5.4暂存数据111

7.6请求行111

7.6.1版本112

7.6.2方法112

7.6.3地址112

7.6.4参数113

7.7请求头114

7.7.1读取数据114

7.7.2改写数据115

7.8请求体115

7.8.1丢弃数据115

7.8.2读取数据115

7.8.3改写数据116

7.9响应头117

7.9.1改写数据117

7.9.2发送数据118

7.9.3过滤数据118

7.10响应体118

7.10.1发送数据118

7.10.2过滤数据119

7.11手动收发数据120

7.12流程控制121

7.12.1重定向请求121

7.12.2终止请求121

7.13检测断连122

7.14综合示例123

7.15总结126

第8章访问后端127

8.1简介127

8.2子请求128

8.2.1接口说明128

8.2.2应用示例129

8.2.3使用建议130

8.3协程套接字131

8.3.1配置指令131

8.3.2创建对象132

8.3.3超时设置133

8.3.4建立连接133

8.3.5复用连接134

8.3.6关闭连接134

8.3.7发送数据135

8.3.8接收数据135

8.3.9应用示例136

8.4DNS客户端137

8.4.1创建对象138

8.4.2查询地址138

8.4.3缓存地址139

8.5HTTP客户端140

8.5.1创建对象140

8.5.2发送请求140

8.6WebSocket客户端142

8.6.1创建对象142

8.6.2建立连接143

8.6.3关闭连接143

8.6.4复用连接143

8.6.5发送数据144

8.6.6接收数据144

8.7Redis客户端145

8.7.1创建对象145

8.7.2建立连接145

8.7.3关闭连接146

8.7.4复用连接146

8.7.5执行命令146

8.7.6管道147

8.7.7脚本148

8.8MySQL客户端148

8.8.1创建对象149

8.8.2建立连接149

8.8.3服务器版本号150

8.8.4关闭连接150

8.8.5复用连接150

8.8.6简单查询150

8.8.7高级查询152

8.8.8防止SQL注入152

8.9总结153

第9章反向代理155

9.1简介155

9.2上游集群156

9.2.1静态服务器信息157

9.2.2动态服务器信息158

9.2.3服务器下线159

9.2.4当前上游集群159

9.3负载均衡160

9.3.1使用方式160

9.3.2功能接口161

9.4总结162

第10章高级功能163

10.1共享内存163

10.1.1配置指令163

10.1.2写操作164

10.1.3读操作165

10.1.4删除操作166

10.1.5计数操作166

10.1.6队列操作166

10.1.7过期操作167

10.1.8其他操作168

10.2定时器168

10.2.1配置指令168

10.2.2单次任务169

10.2.3周期任务170

10.3进程管理171

10.3.1进程类型171

10.3.2工作进程172

10.3.3监控进程173

10.3.4特权进程173

10.4轻量级线程174

10.4.1启动线程175

10.4.2等待线程175

10.4.3挂起线程176

10.4.4停止线程177

10.4.5信号量178

10.5总结179

第11章HTTPS服务181

11.1简介181

11.1.1密码学181

11.1.2网络协议182

11.2服务配置184

11.3应用开发185

11.4基本信息185

11.4.1协议版本号185

11.4.2主机名186

11.4.3地址186

11.5加载证书187

11.5.1清除证书187

11.5.2设置证书187

11.5.3设置私钥188

11.5.4测试验证189

11.6查验证书189

11.6.1发送查询189

11.6.2通知客户端191

11.7会话复用191

11.7.1SessionID191

11.7.2SessionTickets193

11.8总结193

第12章HTTP2服务195

12.1简介195

12.2服务配置196

12.3应用开发197

12.4测试验证197

12.5总结198

第13章Websocket服务199

13.1简介199

13.2服务配置200

13.3应用开发200

13.4总结202

第14章TCP/UDP服务203

14.1简介203

14.2配置指令204

14.3运行机制205

14.3.1处理阶段205

14.3.2执行程序206

14.3.3流程图206

14.4功能接口208

14.5应用示例208

14.6总结210

第15章结束语211

附录A推荐书目215

附录B定制OpenResty217

精彩书摘

  开发概述
  由于Nginx的模块化架构具有良好的扩展性,OpenResty实现了ngx_lua和stream_lua等模块,把Lua/LuaJIT完美地整合进了Nginx,从而让我们能够在Nginx内部的多个关键节点里嵌入Lua脚本,用Lua这种便捷的语言来实现复杂的HTTP/TCP/UDP业务逻辑,同时依然保持着高度的并发服务能力。
  本章将先从一个简单的应用服务例子开始,从宏观的层次介绍开发OpenResty应用的基本流程、配置指令、运行机制等重要知识。
  5.1应用示例
  在第3章和第4章我们学习了OpenResty里使用的Lua语言,也编写了一些Lua程序,但它们都是使用resty-cli命令行工具运行的,并不能对外提供服务。
  本节将使用OpenResty开发出一个简单的Web服务:“HelloWorld”。
  5.1.1编码实现
  与其他的编程语言不同,使用OpenResty开发服务应用首先要做的并不是编写程序代码,而是要编写配置文件。这是因为OpenResty使用了Nginx作为运行平台,Nginx本身需要使用配置文件来定义Web服务。这里我们将配置文件命名为“hello.conf”。
  基本配置
  作为Web服务,我们应该依据实际情况决定应用的服务能力,例如开多少个worker进程、可能的最大并发数量等。
  “HelloWorld”应用的功能很简单,所以我们只开启一个worker进程,并发连接最多512个,其他的都使用默认配置。
  在配置文件hello.conf里要使用的指令是“worker_processes”和“worker_connections”,如下:[其实worker_processes和worker_connections都可以不写,默认值就是1个worker进程和最多512个连接,但配置块events{}不能省略。]
  worker_processes1;#设置worker进程的数量为1
  events{#设置并发连接需要在events块里
  worker_connections512;#单个worker的最大并发连接数
  }
  服务配置
  接下来需要决定Web服务的协议和端口号,我们使用最常用的HTTP协议,端口80,域名任意。
  配置HTTP服务需要编写http{}配置块,并在里面使用指令server、listen、server_name依次定义端口号和域名:
  http{#定义HTTP服务
  server{#server块,定义Web服务
  listen80;#服务使用的是80端口
  server_name*.*;#HTTP服务对应任意域名
  }#server块结束
  }#http块结束
  处理请求
  有了Web服务,我们还要有处理请求时的URI入口。因为“HelloWorld”应用总是返回唯一的结果,所以应当使用“location/”来匹配所有的URI:
  http{#定义HTTP服务
  server{#server块,定义Web服务
  listen80;#服务使用的是80端口
  server_name*.*;#HTTP服务对应任意域名
  
  location/{}#location块,匹配任意URI
  }#server块结束
  }#http块结束
  应用程序
  经过前面的三个步骤,现在Web服务的基本框架已经建立起来了,缺的只是服务的内容,这是要真正编写Lua代码的地方。
  OpenResty提供一个专用指令“content_by_lua_block”,可以在配置文件里书写Lua代码,产生响应内容:
  content_by_lua_block{--我们的第一个OpenResty应用
  ngx.print("hello,world")--打印经典的“hello,world”
  }#Lua代码结束
  指令里调用了OpenResty的功能接口ngx.print,向客户端输出了“hello,world”字符串。
  完整代码
  这样,我们的第一个OpenResty应用就完成了,完整的代码如下:
  worker_processes1;#设置worker进程的数量为1
  events{#设置并发连接需要在events块里
  worker_connections512;#单个worker的最大连接数
  }
  
  http{#定义HTTP服务
  server{#server块,定义Web服务
  listen80;#服务使用的是80端口
  server_name*.*;#HTTP服务对应任意域名
  
  location/{#location块,匹配任意URI
  content_by_lua_block{--我们的第一个OpenResty应用
  ngx.print("hello,world")--打印经典的“hello,world”
  }#Lua代码结束
  }#location块结束
  }#server块结束
  }#http块结束
  5.1.2测试验证
  OpenResty应用开发完成之后不需要编译,可以部署后直接运行对外提供Web服务。但注意不能简单地执行“bin/openresty”,那将会使用OpenResty默认的配置文件而不是我们刚编写的配置文件。
  启动应用需要使用“-c”参数,让OpenResty以指定的配置文件运行:
  /usr/local/openresty/bin/openresty-c"`pwd`/hello.conf"
  现在就可以使用curl来验证“HelloWorld”应用的运行情况了:
  curl-v127.0.0.1#curl命令发送HTTP请求
  curl-v127.0.0.1/hello#总会得到“hello,world”
  停止应用时同样需要加上“-c”参数:
  /usr/local/openresty/bin/openresty-c"`pwd`/hello.conf"-sstop
  ……

前言/序言

  随感
  《OpenResty完全开发指南:构建百万级别并发的Web应用》肇始于三年多前我的《Nginx模块开发指南》一书。最初是以书末的附录形式出现,只有短短的几页,粗略地介绍了OpenResty的核心组件ngx_lua。连我自己也没有想到,几年后的今天它竟然“脱胎换骨”,进化成了一本颇具规模的正式图书。
  写作《OpenResty完全开发指南:构建百万级别并发的Web应用》还是有感于目前国内技术书刊市场的现状。
  十几二十几年前只有少数资深专家掌握核心技术,通过著书立说的方式来分享知识,普惠大众。但随着互联网的高速发展,知识的获取方式变得越来越简单了,任何人都可以在网上轻松地查找到所需的资料,也可以在网上很容易地发表文章。书——曾经被誉为“进步的阶梯”“精神的食粮”——已经不是那么重要了。
  另一方面,互联网的普及也降低了书的严肃性和出版门槛。个人“恶意推测”,也许是为了“图省事”或者“赚快钱”,有相当多的人只是把若干博客文章集合在一起,再加以少量修改就“攒”成了一《OpenResty完全开发指南:构建百万级别并发的Web应用》。这种“乱炖”“杂烩”形式的书籍拼凑的痕迹十分明显,缺乏内在的逻辑和连贯性,不过凭借着网络上积累的“人气”也能够获得不错的销量,但在我看来实在是对读者的不尊重和不负责。
  一个极端的例子是前段时间偶然遇到的名为《□□开发实战》的书,其粗制滥造程度简直是“超乎想象”,“不料,也不信竟会凶残到这地步”[原文出自鲁迅《记念刘和珍君》。]——几乎90%的内容都是原封不动地拷贝网络上现成的材料,再有就是直接复制数十页全无注释的杂乱代码,通篇看下来可能只有前言是“原创”,着实是“钦佩”该书作者厚颜无耻的“功力”。
  单纯地感慨“世风日下”“人心不古”是没有用的,我所能做的,就是尽自己“微茫”的努力,写出一些无愧于己于人的文字。
  关于OpenResty
  有这样一种说法:“Nginx是网络世界里的操作系统,而OpenResty则是Nginx上的Web服务器”。
  Nginx在WebServer业内的领军地位早已经得到了公认,是高性能服务器的杰出代表。它采用C语言开发,能够跨平台运行,把性能挖掘优化技术发挥到了极致。正因为如此,Nginx也很自然地成为了一个超越原生操作系统的开发平台,程序员可以完全无视底层系统之间的差异,在Nginx的框架里调用丰富的数据结构和功能接口,开发出高性能高可移植的各种应用程序。[通常来说Nginx适合运行单线程的I/O密集型应用,但实际上它也可以使用多线程技术运行CPU密集型应用。]
  但基于Nginx开发主要使用的语言是C/C++,开发难度高周期长,虽然没有达到“望而生畏”的程度但亦不远矣。好在OpenResty应运而生,在Nginx里嵌入了LuaJIT环境和Lua语言,就如同给裸系统添加了一个高效易用的Shell,瞬间就让Nginx开发的难度直线下降,降低到了普通的心智模型可以理解掌握的水平。
  早期OpenResty对于自身的定位主要还是HTTPServer(其实也是受到Nginx的限制),可以利用“胶水语言”Lua来操纵Nginx,灵活定制业务逻辑,方便快捷地搭建出超高并发的各种Web服务,从而节约时间和人力成本。多年来的实践证明,这方面它的确工作得非常出色。
  近两年OpenResty的发展开始加速,支持了TCP/UDP协议,扩充了众多的专用库、应用框架以及外围工具,逐渐形成了一个比较独立自洽的生态体系。虽然Nginx仍然是核心,但看得出OpenResty有淡化自身“NginxBundle”色彩的趋势,力图成为一个更伟大的存在。
  随着软件基金会和商业公司的成立,OpenResty获得了前所未有的成长动力。“路远,正未有穷期”,在此借《OpenResty完全开发指南:构建百万级别并发的Web应用》送上诚挚的祝福与期待。
  致谢
  首先要感谢Nginx的作者IgorSysoev和OpenResty的作者agentzh,正是因为他们多年来持续无私的奉献,我们才能够拥有如此强大易用的WebServer。
  接下来我要感谢父母多年来的养育之恩,感谢妻子和两个可爱的女儿(“点心”组合)在生活中的陪伴,愿你们能够永远幸福快乐。
  我也要感谢读者选择《OpenResty完全开发指南:构建百万级别并发的Web应用》,希望读者能从中汲取有用的知识,让OpenResty成为工作中的得力助手。
  您的朋友罗剑锋
  2018年7月18日于北京798园区

其他推荐