# 052. 基于 OpenResty 部署应用层 nginx 以及 nginx + lua 开发 hello world

我们这里玩儿 nginx,全都会在 nginx 里去写 lua 脚本,因为我们需要自定义一些特殊的业务逻辑

比如说,流量分发,自己用 lua 去写分发的逻辑,在分发层 nginx 里去写的

再比如说,要用 lua 去写多级缓存架构存取的控制逻辑,在应用层 nginx 里去写的

后面还要做热点数据的自动降级机制,也是用 lua 脚本去写降级机制的,在分发层 nginx 里去写的

因为我们要用 nginx+lua 去开发,所以会选择用最流行的开源方案,就是用 OpenResty

nginx+lua 打包在一起,而且提供了包括 redis 客户端,mysql 客户端,http 客户端在内的大量的组件

我们这一讲是去部署应用层 nginx,会采用 OpenResty 的方式去部署 nginx, 而且会带着大家写一个 nginx+lua 开发的一个 hello world

部署第一个 nginx,作为应用层 nginx,部署机器:eshop-01

# 部署 openresty

mkdir -p /usr/servers  
cd /usr/servers/
# 安装依赖
yum install -y readline-devel pcre-devel openssl-devel gcc

# 可能需要翻墙才能下载,所以可以离线下载好
wget http://openresty.org/download/ngx_openresty-1.7.7.2.tar.gz  
tar -xzvf ngx_openresty-1.7.7.2.tar.gz  
rm -rf ngx_openresty-1.7.7.2.tar.gz

# 安装 lua 等相关组件
cd /usr/servers/ngx_openresty-1.7.7.2/
cd bundle/LuaJIT-2.1-20150120/  
make clean && make && make install  
ln -sf luajit-2.1.0-alpha /usr/local/bin/luajit
cd ../
wget https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.tar.gz  
tar -xvf 2.3.tar.gz  
wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/v0.3.0.tar.gz  
tar -xvf v0.3.0.tar.gz  

#
cd /usr/servers/ngx_openresty-1.7.7.2  
./configure --prefix=/usr/servers --with-http_realip_module  --with-pcre  --with-luajit --add-module=./bundle/ngx_cache_purge-2.3/ --add-module=./bundle/nginx_upstream_check_module-0.3.0/ -j2  
make && make install

# 会发现多了好多目录
[root@eshop-cache01 servers]# ll
total 3316
drwxr-xr-x 2 root root    4096 Apr  1 23:38 bin
drwxr-xr-x 6 root root    4096 Apr  1 23:38 luajit
drwxr-xr-x 5 root root    4096 Apr  1 23:38 lualib
drwxr-xr-x 6 root root    4096 Apr  1 23:38 nginx
drwxrwxr-x 4 1000 1000    4096 Apr  1 23:35 ngx_openresty-1.7.7.2

# 启动nginx:
/usr/servers/nginx/sbin/nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# nginx+lua 开发的 hello world

vi /usr/servers/nginx/conf/nginx.conf

# 在 http 部分添加如下内容

lua_package_path "/usr/servers/lualib/?.lua;;";  
lua_package_cpath "/usr/servers/lualib/?.so;;";  

如下位置

http {
    lua_package_path "/usr/servers/lualib/?.lua;;";
    lua_package_cpath "/usr/servers/lualib/?.so;;";

    include       mime.types;
    default_type  application/octet-stream;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

/usr/servers/nginx/conf 下,创建一个 lua.conf,内容如下

server {  
    listen       80;  
    server_name  _;  
}  
1
2
3
4

接着在 nginx.conf 的 http 部分添加:include lua.conf;

验证配置是否正确:

[root@eshop-cache01 conf]# /usr/servers/nginx/sbin/nginx -t
nginx: the configuration file /usr/servers/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/servers/nginx/conf/nginx.conf test is successful
1
2
3

在 lua.conf 的 server 部分添加:

location /lua {  
    default_type 'text/html';  
    content_by_lua 'ngx.say("hello world")';  
}
1
2
3
4

添加完成后,再次测试验证是否正确:/usr/servers/nginx/sbin/nginx -t

重新加载 nginx 配置: /usr/servers/nginx/sbin/nginx -s reload

访问 http://192.168.99.170/lua 会看到页面输出 「hello world」

这里把嵌入配置文件的代码迁移到独立文件中

mkdir -p /usr/servers/nginx/conf/lua
vi /usr/servers/nginx/conf/lua/test.lua
# 在文件中写入迁入的代码
ngx.say("hello world");

# 并修改 lua.conf ,配置成 file 方式

location /lua {  
    default_type 'text/html';  
    content_by_lua_file conf/lua/test.lua;
}
1
2
3
4
5
6
7
8
9
10
11

查看异常日志 : tail -f /usr/servers/nginx/logs/error.log

# 工程化的 nginx+lua 项目结构

项目工程结构

|- hello  # 项目名
  |- hello.conf     
  |- lua              
    |- hello.lua
  |- lualib  # 该包的文件可以在之前的 /usr/servers/lualib 全部 copy 过来           
    |- *.lua
    |- *.so
1
2
3
4
5
6
7

放在 /usr/hello 目录下

# 搭建另外一个应用层 nginx

如法炮制,在另外一个机器上,也用 OpenResty 部署一个 nginx

部署机器:eshop-02

这次的 hello word 就按照工程化的目录来放置和配置

mkdir /usr/hello

vi hello.conf
# 内容如下
server {  
    listen       80;  
    server_name  _;  
    location /lua {  
      default_type 'text/html';  
      content_by_lua_file /usr/hello/lua/hello.lua;
    }
}

mkdir lua
vi lua/hello.lua
# 内容如下
ngx.say("hello world,工程化结构")

# 复制 lualib
scp -r /usr/servers/lualib/ ./

# 编辑 nginx.conf
vi /usr/servers/nginx/conf/nginx.conf

# 添加内容
http {
    lua_package_path "/usr/hello/lualib/?.lua;;";
    lua_package_cpath "/usr/hello/lualib/?.so;;";

    include /usr/hello/hello.conf;
    include       mime.types;

# 测试是否成功
/usr/servers/nginx/sbin/nginx -t
# 重新加载 nginx 配置
/usr/servers/nginx/sbin/nginx -s reload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

浏览器访问 http://eshop-cache02/lua 显示出信息,成功

# 讲师旁白

对于我的课程来说,主要还是关注我们核心的 topic:大型缓存的架构

那么对于课程里涉及到的各种技术来说,比如 nginx,lua 脚本,你说让我给你讲成 nginx从入门到精通,也不太现实; 讲一个 lua 脚本开发从入门到精通,也不太现实

我只能说,跟着整个项目的思路去走,把项目里涉及的相关技术的知识给你讲解一下,然后保证说,带着你手把手的去做,让你至少可以学会项目里讲解的这些知识,可以做出来

如果你后面真的是要自己去用 nginx+lua 去做项目,其实个人建议你还是得去查询和学习一些更多的资料,比如:nginx 的一些知识、lua 的一些语法

如龙果里面最受欢迎的一套课程,就是 dubbo 实战课程,里面也是 dubbo 整合了各种技术:active mq、zookeeper、redis 3.0 分布式集群、mysql读写分离

但是有个问题,每个课程,我相信一个好的课程,它总是可以让你学到很多知识的

但是任何一个好的课程,它都不是万能的,比如 dubbo 这个课程中,你可能能学习到 zookeeper 怎么当注册中心,但是 zookeeper 分布式锁、分布式协调、分布式选举等等技术,你能学到吗?

dubbo 它也不可能说是给你把 zookeeper、redis、mysql 全部讲解到从入门到精通这样子

topic 主题,基于 dubbo 复杂的分布式系统的通用架构,分布式系统,dubbo rpc 的调用,服务的开发; zookeeper 做注册中心; redis 分布式集群; mysql 读写分离; tomcat 集群; hudson 持续集成

它告诉你的是一个通用的分布式系统的架构

我这里的也会带着你做 nginx 的部署、openresty、nginx+lua 的开发,redis 集群/高可用/高并发/读写分离/持久化/数据备份恢复、zookeeper 分布式锁、kafka 去做消息通信,hystrix 去做限流

但是任何一个技术都不可能给你从入门到精通讲解完

大家可以去关注一下我的 es 的课程,你如果录一套课程,基本选择方向就两个,要不就是讲解技术本身,大量案例实战贯穿,把技术本身讲解的很细致

我之前有两个 es 顶尖高手系列的课程属于技术课程,把 es 这个技术讲解的非常非常的细致

像我们现在这个课程,大规模缓存、支撑高并发、高性能、海量数据,类似之前 dubbo 实战课程,它讲解的还是一种架构课程,那么就关注点在整个架构的整体、整合、架构方案、架构设计、架构思想

里面涉及的技术是不可能给你去深入讲解的