Nginx实战:基于Lua语言的配置、开发与架构详解
  • 推荐2
  • 收藏12
  • 浏览2.3K

Nginx实战:基于Lua语言的配置、开发与架构详解

王力 , 王力 (作者)  牛勇 (责任编辑)

  • 书  号:978-7-121-35460-1
  • 出版日期:2019-03-01
  • 页  数:344
  • 开  本:16(185*235)
  • 出版状态:上市销售
  • 维护人:付睿
电子书 ¥47.40
购买电子书
纸质版 ¥79.00
本书主要讲解了Nginx在反向代理和应用开发中的作用,阅读本书可以了解Nginx在互联网开发中扮演的多个角色,充分利用这些角色的各项功能有助于提升服务的整体性能。本书所介绍的大部分功能是通过Nginx+Lua进行开发和配置的,但并不要求读者精通Lua,在必要的位置本书会对Lua进行选择性讲解。涉及实战的内容会有配套源码,方便读者学习和使用。
本书适合广大运维人员和开发人员学习,对使用Nginx完成各种服务架构感兴趣的架构师也可以阅读本书。阅读本书需要有Nginx初级或中级配置经验。
本书深入浅出地讲解了Nginx+Lua在实战场景中的各种使用技巧和方法,涉及配置、模块、缓存、日志分析、静态容灾、反向代理、爬虫、性能分析与优化等众多方面,帮助提升服务性能。
·王力·
折800运维架构师,Nginx开发工程师,具有多年互联网相关项目的开发经验。喜欢使用小众技术完成运维、开发和测试任务,擅长通过架构设计降低开发难度,擅长搭建Nginx高性能服务。
·汤永全·
折800运维主管,具有多年互联网相关项目的运维工作经验。历经传统运维和互联网运维,一步一个脚印,积累了不少运维相关的经验和感悟。活跃于成都运维管理人员的线下组织“运维罗汉堂”。
前  言
Nginx自2004年发布第一个公开版本以来,就因其稳定性强、配置灵活、占用内存少、反向代理功能强大,而被越来越多的人喜爱和使用。随着人们对Nginx关注度的不断上升,Nginx有了更多的使用场景,但在大多数公司中仍然只是扮演着反向代理的角色。
笔者在折800电商平台(以下简称折800)工作多年,深感对一个电商平台来说,在成本控制和服务性能之间取得平衡是能够可持续发展的前提之一。与同类型且流量级别相近的公司相比,折800的计算机硬件成本要低很多,这主要得益于公司对软件技术的极致追求。在这样的背景下,我们热衷于研究Nginx反向代理等小众技术,并使用Nginx实现了大量功能,极大地提升了服务的性能和灵活度。
目前,Nginx在国内的影响力还比较有限,因此很多开发人员并不了解Nginx的魅力,笔者写这本书的目的就是和大家分享Nginx的使用技巧,并一起来推广Nginx。
市面上已经有一些介绍Nginx技术的书籍,但大多偏向于对Nginx配置和原理的讲解,还有一些书籍是基于C或C++来介绍Nginx模块的。这样的书籍要求读者对Nginx的原理和源码有所了解,甚至还要有深厚的C语言或C++语言的开发功底,这对大多数初学者来说要求太高了。
怎样才能做到既发挥出Nginx的威力,又尽量降低学习成本呢?笔者选择使用OpenResty的核心组件,因为OpenResty是Nginx+Lua的完美结合,它既能够实现Nginx的异步功能,又兼有Lua的易学优势,这样,在使用Nginx进行开发的过程中就不需要深入了解Nginx的原理了(如果已经掌握了Nginx原理当然更好)。所以,与市面上的大多数同类书籍不同,本书不会过多介绍Nginx配置和原理方面的内容,学习难度较低。
近几年来,OpenResty的热度不断上升,各大互联网公司纷纷尝试使用Nginx+Lua的开发模式,在反向代理、网关系统、API调度服务中都能看到这种开发模式的“身影”。希望本书可以让更多的开发人员了解Nginx+Lua 的魅力,也让更多技术团队能够合理地使用Nginx,降低硬件的投入成本,同时提升服务的性能。
本书由王力、汤永全编写。全书内容共分18章,其中第1~5章介绍Nginx常见的配置方式,属于Nginx的入门知识;第6~10章对Nginx+Lua核心功能进行解读,是熟悉Nginx+Lua开发模式的必备知识;第11~18章是Nginx+Lua开发模式在实际业务中的实践应用,是灵活运用该模式的具体体现。
感谢杨明翰、冯浩、刘凯、屈耀华对本书的支持;也感谢折800技术平台,在这里我得到了持续的历练和成长。同时,感谢电子工业出版社博文视点的编辑付睿和崔志伟,他们在本书的语言表述方面给了很多建议。
本书包含了作者的技术实践,如果你对本书内容有任何建议和疑惑,可以发电子邮件至leehomewl@gmail.com。谢谢!

王力
2018年12月

目录

第1章 Nginx学前必知 1
1.1 HTTP请求报文 1
1.2 HTTP响应报文 2
1.3 安装Nginx 2
1.4 支持HTTPS 4
1.5 添加模块 4
1.6 小结 4
第2章 基础配置 5
2.1 Nginx指令和指令块 5
2.2 Nginx基本配置说明 6
2.2.1 Main配置 6
2.2.2 与客户端有关的配置 7
2.2.3 server块 7
2.2.4 location块 8
2.3 include的使用 9
2.4 常见配置 9
2.4.1 常见配置注解 10
2.4.2 常见配置实战技巧 11
2.5 内置变量 13
2.5.1 常见内置变量 13
2.5.2 常见内置变量实战技巧 15
2.6 小结 16

第3章 强化基础配置 17
3.1 牢记Context标识 17
3.2 获取请求的IP地址 18
3.2.1 获取用户的真实IP地址 18
3.2.2 防止IP地址伪造 19
3.2.3 后端服务器对IP地址的需求 19
3.3 管理请求的行为 20
3.3.1 限制IP地址的访问 20
3.3.2 auth身份验证 21
3.3.3 利用LDAP服务加强安全 22
3.3.4 satisfy二选一的访问限制功能 23
3.4 proxy代理 23
3.4.1 proxy_pass请求代理规则 24
3.4.2 减少后端服务器的网络开销 24
3.4.3 控制请求头和请求体 25
3.4.4 控制请求和后端服务器的交互时间 26
3.5 upstream使用手册 26
3.5.1 代理多台服务器 27
3.5.2 故障转移 28
3.5.3 负载均衡 29
3.5.4 通过hash分片提升缓存命中率 29
3.5.5 利用长连接提升性能 30
3.5.6 利用resolver加速内部域名访问 31
3.6 rewrite使用手册 32
3.6.1 内部重定向 32
3.6.2 域名跳转 33
3.6.3 跳转POST请求 34
3.6.4 设置变量的值 34
3.7 限速白名单 35
3.8 日志 36
3.8.1 记录自定义变量 36
3.8.2 日志格式规范 36
3.8.3 日志存储 37
3.9 HTTP执行阶段 38
3.10 小结 39
第4章 常用模块精解 40
4.1 定制HTTP头信息 40
4.1.1 使用ngx_http_headers_module设置响应头 40
4.1.2 使用headers-more-nginx控制请求头和响应头 43
4.2 第三方模块set-misc-nginx 45
4.2.1 设置变量 46
4.2.2 防止SQL注入 46
4.2.3 字符串非转义和转义 47
4.2.4 基于键值的集群分片 48
4.2.5 base编码 48
4.2.6 md5编码 50
4.2.7 生成随机数 50
4.2.8 本地时间的输出 52
4.2.9 实战经验 52
4.3 图片的处理 53
4.3.1 image_filter图片处理 53
4.3.2 采用渐进式方式打开JPEG图片 55
4.3.3 WebP格式 56
4.3.4 优化图片 56
4.3.5 实战经验:动态切图 58
4.4 TCP和UDP代理 58
4.4.1 代理配置说明 58
4.4.2 DNS服务的反向代理 62
4.4.3 MySQL集群代理配置 62
4.4.4 实战经验 63
4.5 常用模块介绍 63
4.5.1 基于访问IP地址跳转到对应城市 63
4.5.2 修改响应内容 65
4.5.3 零像素文件的生成及其作用 66
4.5.4 图片的防盗链 67
4.6 小结 68
第5章 缓存系统 69
5.1 缓存配置说明 69
5.2 控制缓存有效期 71
5.3 性能优化 72
5.3.1 缓存未命中的最佳实践 72
5.3.2 横向扩展最佳实践 75
5.3.3 避免硬盘I/O阻塞 76
5.3.4 集群模式 77
5.4 高可用方案 77
5.5 proxy_cache配置模板 78
5.6 小结 81
第6章 引入Lua 82
6.1 为什么要引入Lua 82
6.2 Lua和LuaJIT 83
6.3 环境搭建 83
6.4 Lua的数据类型 84
6.4.1 类型说明 84
6.4.2 类型示例 85
6.5 表达式 89
6.5.1 算术运算符 89
6.5.2 关系运算符 90
6.5.3 逻辑运算符 91
6.5.4 字符串连接和字符串长度计算 92
6.5.5 运算符优先级 93
6.6 变量 93
6.6.1 全局变量 94
6.6.2 局部变量 94
6.6.3 变量赋值 94
6.7 流程控制 95
6.7.1 if-else 95
6.7.2 for循环 96
6.7.3 while循环 97
6.7.4 break和return 97
6.8 函数 98
6.8.1 函数格式 98
6.8.2 传参方式 99
6.8.3 函数的创建位置 100
6.9 模块 100
6.9.1 模块格式 101
6.9.2 加载模块 101
6.10 Lua常见操作 102
6.10.1 操作table 102
6.10.2 定义字符串 103
6.10.3 字符串连接 104
6.11 引入Lua的插曲 104
6.12 小结 105
第7章 Lua-Nginx-Module常用指令 106
7.1 Nginx和OpenResty 106
7.2 安装Ngx_Lua 107
7.3 牢记Context标识 108
7.4 Hello world 108
7.5 避免I/O阻塞 109
7.6 定义模块搜索路径 109
7.6.1 定义Lua模块的搜索路径 109
7.6.2 定义C模块的搜索路径 110
7.7 读/写Nginx的内置变量 110
7.8 控制请求头 111
7.8.1 添加请求头 111
7.8.2 清除请求头 112
7.8.3 获取请求头 112
7.9 控制响应头 113
7.9.1 获取响应头 113
7.9.2 修改响应头 114
7.9.3 清除响应头 116
7.10 读取请求体 116
7.10.1 强制获取请求体 116
7.10.2 用同步非阻塞方式获取请求体 117
7.10.3 使用场景示例 118
7.10.4 使用建议 121
7.11 输出响应体 121
7.11.1 异步发送响应体 121
7.11.2 同步发送响应体 122
7.12 正则表达式 124
7.12.1 单一捕获 124
7.12.2 全部捕获 125
7.12.3 更高效的匹配和捕获 126
7.12.4 替换数据 128
7.12.5 转义符号 129
7.13 子请求 130
7.13.1 请求方法 130
7.13.2 单一子请求 130
7.13.3 并发子请求 134
7.14 获取Nginx的环境变量 135
7.14.1 获取环境所在的模块 135
7.14.2 确认调试模式 136
7.14.3 获取prefix路径 136
7.14.4 获取Nginx的版本号 136
7.14.5 获取configure信息 136
7.14.6 获取Ngx_Lua的版本号 137
7.14.7 判断worker进程是否退出 137
7.14.8 获取worker进程的ID 137
7.14.9 获取worker进程的数量 137
7.15 定时任务 138
7.15.1 创建定时任务 138
7.15.2 性能优化 140
7.15.3 禁用的Lua API 141
7.16 常用指令 142
7.16.1 请求重定向 142
7.16.2 日志记录 144
7.16.3 请求中断处理 146
7.17 提升开发和测试效率 149
7.17.1 断开客户端连接 149
7.17.2 请求休眠 150
7.17.3 获取系统时间 150
7.17.4 编码与解码 152
7.17.5 防止SQL注入 154
7.17.6 判断是否为子请求 155
7.17.7 设置MIME类型 156
7.18 小结 156
第8章 Ngx_Lua的执行阶段 157
8.1 init_by_lua_block 157
8.1.1 阶段说明 157
8.1.2 初始化配置 158
8.1.3 控制初始值 159
8.1.4 init_by_lua_file 160
8.1.5 可使用的Lua API指令 160
8.2 init_worker_by_lua_block 160
8.2.1 阶段说明 160
8.2.2 启动Nginx的定时任务 161
8.2.3 动态进行后端健康检查 162
8.3 set_by_lua_block 165
8.3.1 阶段说明 165
8.3.2 变量赋值 165
8.3.3 rewrite阶段的混用模式 166
8.3.4 阻塞事件 167
8.3.5 被禁用的Lua API指令 167
8.4 rewrite_by_lua_block 168
8.4.1 阶段说明 168
8.4.2 利用rewrite_by_lua_no_postpone改变执行顺序 168
8.4.3 阶段控制 169
8.5 access_by_lua_block 169
8.5.1 阶段说明 169
8.5.2 利用access_by_lua_no_postpone改变执行顺序 170
8.5.3 阶段控制 170
8.5.4 动态配置黑白名单 170
8.6 content_by_lua_block 170
8.6.1 阶段说明 170
8.6.2 动态调整执行文件的路径 171
8.7 balancer_by_lua_block 171
8.7.1 阶段说明 171
8.7.2 被禁用的Lua API指令 172
8.8 header_filter_by_lua_block 172
8.8.1 阶段说明 172
8.8.2 被禁用的Lua API指令 173
8.9 body_filter_by_lua_block 173
8.9.1 阶段说明 173
8.9.2 控制响应体数据 173
8.9.3 被禁用的Lua API指令 175
8.10 log_by_lua_block 176
8.10.1 阶段说明 176
8.10.2 被禁用的Lua API指令 176
8.11 Lua和ngx.ssl 177
8.12 Ngx_Lua执行阶段 177
8.13 小结 180
第9章 Nginx与数据库的交互 181
9.1 安装cjson 181
9.2 与MySQL交互 183
9.2.1 安装lua-resty-mysql模块 183
9.2.2 读取MySQL数据 183
9.2.3 执行多条SQL语句 187
9.2.4 防止SQL注入 189
9.3 与Redis交互 189
9.3.1 安装lua-resty-redis 189
9.3.2 读/写Redis 189
9.3.3 管道命令 191
9.3.4 密码登录 193
9.3.5 其他执行命令 194
9.4 与数据库交互的常见问题 194
9.4.1 连接池 194
9.4.2 读/写分离 197
9.4.3 分离配置文件和代码 197
9.5 小结 198
第10章 缓存利器 199
10.1  worker进程的共享内存 200
10.1.1 创建共享内存区域 200
10.1.2 操作共享内存 201
10.1.3 制造消息队列 205
10.1.4 lua-resty-core 207
10.1.5 配置环境 208
10.2 Lua模块下的共享内存 209
10.2.1 安装lua-resty-lrucache 209
10.2.2 使用lua-resty-lrucache进行缓存的方法 209
10.3 当前请求在各执行阶段间的数据共享 213
10.3.1 ngx.ctx的使用 213
10.3.2 子请求和内部重定向的缓存区别 214
10.4 利用共享内存配置动态IP地址认证 215
10.5 缓存和数据库的交互 218
10.5.1 从数据库获取数据 218
10.5.2 避免因缓存失效引起的“风暴” 223
10.6 小结 228
第11章 动态管理upstream 229
11.1 实战需求分析 230
11.2 ngx_http_dyups_module 230
11.2.1 安装模块 230
11.2.2 动态管理upstream 230
11.2.3 确保upstream数据的完整性 232
11.3 nginx-upsync-module 233
11.3.1 安装nginx-upsync-module和Consul 233
11.3.2 Consul的键值操作 234
11.3.3 动态管理upstream 235
11.3.4 验证动态配置功能 237
11.3.5 高可用、高并发设计 237
11.4 基于balancer_by_lua_block的灵活控制 238
11.5 小结 239
第12章 Nginx日志分析系统 240
12.1 实战需求分析 240
12.2 ngxtop实时分析 241
12.3 Flume方案的日志分析 243
12.4 智能化nginx_log_analysis 244
12.4.1 架构重构 244
12.4.2 日志远程传输 245
12.4.3 时序数据库 245
12.4.4 日志规则设计 245
12.5 lua-resty-logger-socket传输方案 246
12.5.1 安装lua-resty-logger-socket 246
12.5.2 远程传输配置 247
12.5.3 参数解读 248
12.6 时序数据库InfluxDB 249
12.6.1 安装InfluxDB 249
12.6.2 基本概念和操作 249
12.6.3 数据分析之查询函数 250
12.6.4 数据存放之保留策略 251
12.6.5 定时任务之连续查询 251
12.6.6 客户端操作之API 252
12.6.7 使用UDP模式传输数据 253
12.7 利用lua-resty-http实现API交互 254
12.7.1 安装lua-resty-http 254
12.7.2 使用方式 254
12.8 提升InfluxDB性能 255
12.9 小结 255
第13章 静态容灾系统 256
13.1 荆棘之路 257
13.2 设计之路 259
13.3 架构流程图 261
13.3.1 反向代理系统 261
13.3.2 日志分析系统 261
13.3.3 后台系统 261
13.3.4 爬虫系统 262
13.3.5 容灾的缓存系统 262
13.3.6 时间版本的用途 263
13.3.7 异地容灾 263
13.4 核心代码解说 264
13.4.1 Ngx_Lua应用 264
13.4.2 爬虫和日志系统的关系 266
13.4.3 全部容灾和部分容灾功能 266
13.5 静态容灾的智能关闭方案 267
13.5.1 从日志分析系统中复制请求 267
13.5.2 利用goreplay复制流量 267
13.5.3 Nginx的镜像功能 268
13.5.4 灰度验证容灾系统缓存 269
13.6 小结 269
第14章 深入挖掘反向代理 270
14.1 验证码防御中心 270
14.2 鉴权管理中心 272
14.2.1 利用auth_request管理鉴权 272
14.2.2 利用Ngx_Lua子请求实现鉴权功能 273
14.3 并行访问 274
14.3.1 轻线程的启动和终止 275
14.3.2 等待和终止轻线程 276
14.3.3 URL的外部合并和内部并发 278
14.3.4 使用cosocket实现外部访问 281
14.4 小结 281
第15章 爬虫 282
15.1 区分搜索引擎爬虫和恶意爬虫 282
15.2 应对搜索引擎爬虫 284
15.2.1 搜索引擎的User-Agent 284
15.2.2 Robots协议 285
15.2.3 控制搜索引擎爬虫实战 286
15.3 应对恶意爬虫 288
15.3.1 发现恶意爬虫 288
15.3.2 抵御恶意爬虫之禁止访问 289
15.3.3 抵御恶意爬虫之验证码拦截 290
15.4 小插曲——使用假数据迷惑恶意爬虫 290
15.5 小结 291
第16章 性能分析和优化 292
16.1 性能分析场景搭建 292
16.1.1 安装SystemTap 292
16.1.2 LuaJIT的Debug模式 293
16.1.3 开启PCRE的Debug模式 294
16.1.4 分析工具下载 294
16.1.5 找出Debug不支持的包 295
16.2 流量复制 295
16.3 各项指标分析和优化建议 295
16.3.1 连接池使用状态分析 295
16.3.2 找出读/写频繁的文件 297
16.3.3 执行阶段耗时分析 297
16.3.4 连接数和文件打开数分析 298
16.3.5 找出CPU“偷窃者” 298
16.3.6 正则表达式耗时分析 299
16.3.7 找出消耗CPU资源较多的指令 301
16.3.8 利用火焰图展示和分析数据 303
16.4 检查全局变量 305
16.5 小结 305
第17章 值得拥有的OpenResty 306
17.1 OPM 307
17.2 使用DNS提升访问效率 309
17.3 TCP和UDP服务 310
17.4 多层级缓存 312
17.5 lua-resty-core扩展 313
17.6 字符串分割 313
17.7 Nginx进程管理 313
17.8 全局唯一标识符UUID 315
17.9 “全家福”awesome-resty 316
17.10 OpenResty,未来! 316
第18章 开发环境下的常见问题 317
18.1 被截断的响应体 317
18.2 “邪恶”的if 317
18.3 “贪婪”的正则匹配 318
18.4 规范HTTP状态码 319
18.5 规范URL 319
18.6 proxy_set_header的误操作 320
18.7 开发环境下的证书问题 320
18.8 深层次的错误重定向 323
18.9 压测环境下的限速和短连接 323
18.10 小结 323

本书勘误

印次
  • 页码:10  •  行数:29  •  印次: 20190301

    在gzip_on上一行的client_header_buffer_size 32K; #对文件上传大小的限制。此处的client_header_buffer已经在网上数4行的内容中出现,并且和注释内容不一致。

    刚达R 提交于 2019/9/1 23:56:22
    付睿 确认于 2019/9/29 16:28:59
  • 页码:11  •  行数:5  •  印次: 20190301

    第5行的upstream backend{}内容下的server,很明显是需要放在{}中的。

    刚达R 提交于 2019/9/1 23:57:27
    付睿 确认于 2019/9/29 16:28:50
  • 页码:58  •  行数:倒数第四行  •  印次: 1

    发现拼写错误一例:
    原文:Nginx在1.9.0版本之后加入了 ngx_stream_proxy_modulea 。此处应为 ngx_stream_proxy_module,多了一个a

    wuhuaji 提交于 2019/9/21 12:59:50
    付睿 确认于 2019/9/29 16:15:49
  • 页码:149  •  行数:中间  •  印次: 1

    7.17 小节中,”注意”部分: 把 lua_cade_cache 设置为 on 只适合在开发环境中使用
    此处 on 应为 off 。off 即关闭缓存,只适合在开发环境中使用。

    wuhuaji 提交于 2019/9/22 9:58:31
    付睿 确认于 2019/9/29 16:28:35

读者评论

  • 第61页第11行,“Valid=time”应该是“valid=time”

    buzzerrookie发表于 2019/10/31 16:26:55
  • 第59页代码第13行括号(upstream块的闭括号)缩进有问题。

    buzzerrookie发表于 2019/10/31 16:25:41
  • 第41页第14行,“ache-control”应该是“cache-control”

    buzzerrookie发表于 2019/10/29 16:08:41
  • 第32页表3-7,“如10.19.7.33:5353”应该是“10.19.7.33:53”

    buzzerrookie发表于 2019/10/24 16:31:25

电子书版本

  • Epub

推荐用户

相关图书

Terraform:多云、混合云环境下实现基础设施即代码(第2版)

Yevgeniy Brikman ( (作者) 白宇 (译者)

Terraform工具已经成为DevOps领域的关键角色。在各种云平台和虚拟化环境(如AWS、Goolge Cloud、Azure等)中,可以对基础设施即代码(...

¥108.00

DevOps安全:云安全服务

Julien Vehent (作者) 覃宇 (译者)

本书主要介绍了 DevOps 实践中最容易被忽视的一环——安全,并且对云原生服务的安全保障也做了全面的阐述。书中详细介绍了 Web 攻击防范、权限验证、日志监控...

¥108.00

企业级DevOps技术与工具实战

刘淼 张笑梅 (作者)

本书包含DevOps理论的介绍,深入浅出地解析了DevOps体系所包括的Agile/Lean/ITSM/TPS各种方法的精粹和脉络,为DevOps爱好者提供了较...

 

SRE生存指南:系统中断响应与正常运行时间最大化

Nat Welch (作者) 冯文辉 冯文辉 (译者)

站点可靠性工程(Site Reliability Engineering,简称SRE)是一个令人兴奋的新兴领域,它专注于如何确保系统稳定、可靠地运行。本书基于一...

 

Zabbix企业级分布式监控系统(第2版)

吴兆松 (作者)

本书基于稳定版本Zabbix 4.0,对Zabbix的各项功能进行了详细而深入的讲解,包括监控系统规划、安装包定制、架构高可用、性能调优、指标数据采集、自动化处...

 

容器云运维实战——Docker与Kubernetes集群

黄靖钧 (作者)

本书围绕当前容器云运维的主流框架:Docker、Kubernetes详细介绍了容器云运维的实战技巧,在内容上分为三大部分:第一部分(第1~2章)介绍了在Linu...

¥53.40