Fork me on GitHub
Fork me on GitHub

安装部署Openresty

由于公司的一个产品用了Nginx Lua写了认证,所以在选型时选了OpenResty。

什么是OpenResty

Nginx 是俄罗斯人发明的, Lua 是巴西几个教授发明的,中国人章亦春把 LuaJIT VM 嵌入到 Nginx 中,实现了 OpenResty 这个高性能服务端解决方案。

最先将Nginx,Lua组合到一起的是OpenResty,它有一个ngx_lua模块,将Lua嵌入到了Nginx里面;随后Tengine也包含了ngx_lua模块。至于二者的区别:OpenResty是Nginx的Bundle;而Tengine则是Nginx的Fork。值得一提的是,OpenResty和Tengine均是国人自己创建的项目,前者主要由章亦春和晓哲开发,后者主要由淘宝打理。

Nginx特性

HTTP服务器

即web服务器,具有支持一个基本的web服务器应该具备的绝大多数功能。 (http://www.netcraft.com/ 在这个站点上随时统计更新的有全球web服务器的占有状况)
灵活的配置:nginx和apache差不多,也是一个进程生成许多子进程,而这个子进程本身有worker进程,专门负责响应用户请求的。nginx是一个进程响应多个请求,事实上可以称为一个线程响应多个请求。除此之外还有许多其他进程,比如说管理缓存的进程,管理会话的进程。有了这样的架构设计,将来在重新添加配置之后,可以将新的连接都使用新配置,而老的连接即已经建立的连接使用原有的配置,所以在线升级的时候不需要中断正在处理的请求,这称为nginx热部署(无非就是平滑升级)。
重写(rewrite)模块:web服务器httpd的重写功能异常强大,但是也比较复杂。nginx比较简单,只需要使用正则表达式重写URL。对于任何一个web服务器来说,URL重写是个非常重要的功能,尤其是反向代理的服务器。

模块化设计

nginx是高度模块化的:

  • 核心模块:core module
  • Standard HTTP modules
  • Optional HTTP modules
  • Mail modules
  • 3rd party modules

支持热部署

不停机更新配置文件、更换日志、更新服务器程序版本。

主要用途

nginx有两个作用。第一,web服务器。具有web服务器要求的所有功能。第二,轻量级的反向代理服务器,能够反向代理两种应用:web和mail,只不过反向代理mail的功能很少被提到。我们的主要着眼点也是它的web服务器和web服务器反向代理。
Nginx基于File AIO(异步I/O),在文件级别上磁盘I/O上基于异步I/O来实现的;同时对于异步通信,nginx基于事件驱动加上边缘触发来完成一个线程处理多个请求,这对于c10k问题是十分有效的解决方案。

Nginx工作模式、框架、模型

nginx会按需同时运行多个进程:一个主进程(master)和几个工作进程(worker),配置了缓存时还会有缓存加载器进程(cache loader)和缓存管理器进程(cache manager)等。所有进程均是仅含有一个线程,并主要通过“共享内存”的机制实现进程间通信。主进程以root用户身份运行,而worker、cache loader和cache manager均应以非特权用户身份运行。

  • master进程(线程)监控worker进程(线程),包括运行是否正常等。
  • worker进程:master的子进程,响应用户请求。
  • cache loader进程:在反向代理的时候用于管理缓存的进程。
  • ·······

    注意:master进程是以管理员启动的,因为nginx要启动为web服务器或反向代理的时候,它应该工作在80端口,只有管理员才有权限启用小于1023的端口,所以启动主进程的时候必须使用管理员身份。然后由master进程启动worker进程,而且master启动worker进程的时候完全以普通用户的身份运行,所以让我们的系统安全性得到提升。
    nginx是高度模块化的,所以nginx的核心模块,像master进程、worker进程所处理的web应用非常简单,最多就是个web服务器,而额外的更多功能比如SSL、FLV流等都不是worker进程自己提供的,而是由额外的模块提供,所以在每个worker进程内部,它可能调用很多个模块,用到哪个模块再去加载哪个模块,而这些模块以流水线的方式工作,也就是一个模块只负责一个功能。比如说第一个分析头部,第二个帮助去的数据,第三个创建响应等等。每个请求,在内部串联起来的模块还不一样,所以每个请求到来了,worker一分析,到底要使用几个模块,这几个模块组成流水线,随时等待响应。
    正是由于这种机制的存在,master负责装在主配置文件,如果我们改了nginx配置文件,由master分析一下配置文件中有没有语法错误,就算重新装在配置文件有语法错误,但是并不会影响worker进程,最多master返回错误告诉你配置文件有语法错误,需要重新装载。一装载成功了,并不会让运行中的worker进程都使用这个配置是文件的,让这些已经建立的连接继续使用老的配置文件,当某个worker进程建立的连接都退出了,此时把worker进程挂了,再重新启动个新worker进程,新worker进程响应新请求,而这个新worker进程用的就是新配置。
    【nginx进程分工】:
    主进程master:
  1. 读取并验正配置信息;
  2. 创建、绑定及关闭套接字;
  3. 启动、终止及维护worker进程的个数;
  4. 无须中止服务而重新配置工作特性;
  5. 控制非中断式程序升级,启用新的二进制程序并在需要时回滚至老版本; ——nginx自身升级
  6. 重新打开日志文件,实现日志滚动;
  7. 编译嵌入式perl脚本;

worker进程:

  1. 接收、传入并处理来自客户端的连接;
  2. 提供反向代理及过滤功能;
  3. nginx任何能完成的其它任务;

cache loader进程:

  1. 检查缓存存储中的缓存对象;
  2. 使用缓存元数据建立内存数据库;

cache manager进程:

  1. 缓存的失效及过期检验;
    【注意】:cache loader和cache manager只是在使用nginx作为反向代理并使用了缓存功能的时候才启动,不是所有时候都运行的。

安装OpenResty

使用的版本是openresty-1.9.7.3.tar.gz
1.安装依赖包

# yum install readline-devel pcre-devel openssl-devel gcc -y

2.安装openresty

# cd /usr/local
# wget https://openresty.org/download/openresty-1.9.7.3.tar.gz
# tar zxf openresty-1.9.7.3.tar.gz
# cd openresty-1.9.7.3/

查看可配置的选项:

# ./configure --help


常用的配置参数:

  • –-prefix=path
    设置安装目录,默认为/usr/local/openresty
  • –user=name
    设置工作进程使用的非特权用户的用户名,默认为nobody。安装完成后可以在nginx.conf中通过user指令修改。
  • –group=name
    设置工作进程使用的非特权用户组的名称,默认组名和–user的名称一致。安装完成后可以在nginx.conf配置文件中通过user指令指定。
  • –-with-http_ssl_module
    启用添加HTTPS协议支持到HTTP服务器的模块,该模块默认不启用。构建和运行该模块需要OpenSSL库。

配置:

# ./configure

编译和安装:

# gmake && gmake install

安装完成后,在/usr/local/下多了个openresty目录,nginx部署安装在/usr/local/openresty/nginx。

3.将nginx加入系统服务
【Redhat7之前的版本】:
(1) 上传脚本nginx启动脚本到/etc/init.d/目录下
(2) 授权脚本执行权限

# chmod a+x nginx

(3) 加入系统服务

# chkconfig --add nginx

(4) nginx开启自启动

# chkconfig nginx on

(5) nginx启停重载

# service nginx start/stop/restart/reload

【Redhat7版本】:
(1) 启动服务单元
把写好的nginx.service放到/etc/systemd/system/目录下。
(2) 设置开机启动

# systemctl enable nginx.service

(3) 启动/停止/重载nginx服务

# systemctl start/stop/reload nginx.service

脚本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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxyand IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /etc/sysconfig/nginx
# pidfile: /var/run/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/openresty/nginx/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/usr/local/openresty/nginx/conf/nginx.conf"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/subsys/nginx
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
killall -9 nginx
}
restart() {
configtest || return $?
stop
sleep 1
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac

服务单元nginx.service的内容如下:

[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/openresty/nginx/logs/nginx.pid
ExecStartPre=/usr/local/openresty/nginx/sbin/nginx -t -c /usr/local/openresty/nginx/conf/nginx.conf
ExecStart=/usr/local/openresty/nginx/sbin/nginx -c /usr/local/openresty/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

【补充】:
RHEL/CentOS 7.0中一个最主要的改变,就是切换到了systemd。它用于替代红帽企业版Linux前任版本中的SysV和Upstart,对系统和服务进行管理。systemd兼容SysV和Linux标准组的启动脚本。
Systemd 是 Linux 系统中最新的初始化系统(init),它主要的设计目标是克服 sysvinit 固有的缺点,提高系统的启动速度。systemd 和 ubuntu 的 upstart 是竞争对手,已经取代了UpStart。
Systemd也是一个Linux操作系统下的系统和服务管理器。它被设计成向后兼容SysV启动脚本,并提供了大量的特性,如开机时平行启动系统服务,按需启动守护进程,支持系统状态快照,或者基于依赖的服务控制逻辑。
先前的使用SysV初始化或Upstart的红帽企业版Linux版本中,使用位于/etc/rc.d/init.d/目录中的bash初始化脚本进行管理。而在RHEL 7/CentOS 7中,这些启动脚本被服务单元取代了。服务单元以.service文件扩展结束,提供了与初始化脚本同样的用途。要查看、启动、停止、重启、启用或者禁用系统服务,你要使用systemctl来代替旧的service命令。
注:为了向后兼容,旧的service命令在CentOS 7中仍然可用,它会重定向所有命令到新的systemctl工具。

Nginx日志切割

日志对于统计排错来说非常有利的。nginx日志相关的配置如access_log、log_format、error_log等。这部分配置内容将在下一篇博文中讲解,这里先来简单提一下。

log_format res '$http_host $remote_addr [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time $upstream_response_time'; #定义日志格式,并给这个日志格式命名为res
access_log  logs/res.access.log  res; #access_log在虚拟主机段中配置,logs/res.access.log定义了存放该虚拟主机日志文件的名字及存放路径,记录的日志格式为上面定义的res所对应的日志格式

Nginx每个虚拟主机都应该使用一个单独的日志,这里使用Linux自带的logrotate进行切割。如果不切割,每个日志文件会越来越大。
关于logrotate的介绍及配置这里不多介绍,可以自行google。下面开始定义切割Nginx的logrotate的配置文件:

# vim /etc/logrotate.d/nginx
/usr/local/openresty/nginx/logs/*.log {
    notifempty
    weekly
    rotate 4
    nocompress
    copytruncate
    postrotate
    systemctl reload nginx.service 
    endscript
}

上面的配置是每周切割一次Nginx日志,保留最近的4个日志文件。
对于配置中的 systemctl reload nginx.service 需要换成服务器上重载Nginx的命令,如果是centos6系列,可能命令就是 service nginx reload

关于Nginx的具体配置将在下篇博文中分享。