对于NGINX 支持epoll模型 epoll模型的优点
定义:
epoll是Linux内核为处理大批句柄而作改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著的减少程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。因为它会复用文件描述符集合来传递结果而不是迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一个原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select\poll那种IO事件的电平触发(Level Triggered)外,还提供了边沿触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提供应用程序的效率。
工作方式:
LT(level triggered):水平触发,缺省方式,同时支持block和no-block socket,在这种做法中,内核告诉我们一个文件描述符是否被就绪了,如果就绪了,你就可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错的可能性较小。传统的select\poll都是这种模型的代表。
ET(edge-triggered):边沿触发,高速工作方式,只支持no-block socket。在这种模式下,当描述符从未就绪变为就绪状态时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了(比如:你在发送、接受或者接受请求,或者发送接受的数据少于一定量时导致了一个EWOULDBLOCK错误)。但是请注意,如果一直不对这个fs做IO操作(从而导致它再次变成未就绪状态),内核不会发送更多的通知。
区别:LT事件不会丢弃,而是只要读buffer里面有数据可以让用户读取,则不断的通知你。而ET则只在事件发生之时通知。
因此 nginx是基于事件驱动且基于多线程的I/O复用,因此特别适用于在IO密集型应用中无疑是非常出色的。
I/O模型参考详见大神的博客I/O模型
下面编译安装nginx-1.10.0
1.首先前往nginx官网下载源码包
http://nginx.org/
2.创建nginx进程运行系统用户
groupadd -r nginx
useradd -r -g nginx -s /sbin/nologin
3.解压缩 配置 此配置文件可以在官网 http://nginx.org/en/linux_packages.html 查看详细
生成makefile过程中可能会报缺少pcre zlib openssl 等,因此安装相应的-devel包,或者下载源码包解压缩至指定位置
用with-openssl=/var/nginx/openssl-0.9.8zh 形式指定
./configure \
--prefix=/usr/local/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-threads --with-stream \
--with-stream_ssl_module \
--with-http_slice_module \
--with-mail \
--with-mail_ssl_module \
--with-file-aio \
--with-http_v2_module \
--with-ipv6 \
--with-pcre=/var/nginx/pcre-8.37 \
--with-openssl=/var/nginx/openssl-0.9.8zh
4.make && make install
安装完成 默认nginx启动命令为 /usr/sbin/nginx 无任何参数
nginx -s signal
Where signal may be one of the following:
-
stop
— fast shutdown -
quit
— graceful shutdown -
reload
— reloading the configuration file -
reopen
— reopening the log files
5.nginx常用命令
nginx -v 查看版本
nginx -V 查看安装时指定的配置参数 版本等
nginx -c 指定配置文件 替代缺省的
nginx -t 检查nginx配置是否有语法错误
6.nginx 启动脚本
vi /etc/init.d/nginx
############################################################
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and 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/sbin/nginx"
prog=$(basename $nginx) NGINX_CONF_FILE="/etc/nginx/nginx.conf" [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx lockfile=/var/lock/subsys/nginx # this function create the ..temp-path=
make_dirs() {
# make required directories
user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
options=`$nginx -V 2>&1 | grep 'configure arguments:'`
for opt in $options; do
if [ `echo $opt | grep '.*-temp-path'` ]; then
value=`echo $opt | cut -d "=" -f 2`
if [ ! -d "$value" ]; then
# echo "creating" $value
mkdir -p $value && chown -R $user $value
fi
fi
done
} start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
make_dirs
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
} 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 && exit 0
$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
############################################################
7.由于默认新创建文件都无执行权限
chmod u+x /etc/init.d/nginx
8.添加至服务列表 并开机启动
chkconfig --add nginx
chkconfig nginx on
service nginx start
9.nginx 配置注意的事项
首先对于nginx通过proxy_pass 开启反向代理后 访问日志在被代理端会完全记录为代理端的IP
因此代理端必须修改发送到被代理端的http请求头部 如下
location /bbs {
proxy_pass http://10.1.1.1/web // 此含义为访问本地服务器定义的/bbs 会被转向到10.1.1.1下的web目录
proxy_set_header X-Real-IP $remote_addr; //此行即为修改发送到被代理端的http
}
且必须修改被代理端的服务器日志记录格式,才能保证访问日志记录完整。
其次若location 使用了模式匹配则 proxy_pass http://10.1.1.1 只能到此位置,不能再加具体路径
location ~* /bbs {
proxy_pass http://10.1.1.1 // 访问/bbs 会被转向到10.1.1.1下面的bbs 此时必须保证10.1.1.1下面必须有此目录
proxy_set_header X-Real-IP $remote_addr;
}
其次若要通过upstream 实现被代理端负载均衡格式如下
upstream backservers {
server 10.2.1.1 weight= max_fails= fail_timeout=;
server 10.2.1.2 weight= max_fails= fail_timeout=;
} location /{
proxy_pass http://backservers
proxy_set_header X-Real-IP $remote_addr; }
其中weight=2 定义急群中服务器的权重 fail_timeout=2定义其在多长时间内无心跳显示则确认为down max_fails=2定义其最大down机次数
其次可以定义一个服务器当集群中所有机器down机后 则默认访问此服务器:
upstream backservers {
server 10.2.1.1 weight=1 max_fails=2 fail_timeout=2;
server 10.2.1.2 weight=2 max_fails=2 fail_timeout=2;
server 10.2.1.3:8899 backup;
}
location /{
proxy_pass http://backservers
proxy_set_header X-Real-IP $remote_addr;
} server {
listen 8899;
servername errorserver;
root /web/errorhtml;
index.html;
}
在负载均衡中为了维持会话不丢失,使用持久连接在upstream中,nginx支持的持久连接算法有round-robin ip_hash least_conn,但此时就不支持backup server
防止永久定向到backup server
upstream backservers {
least_conn;
server 10.2.1.1 weight=1 max_fails=2 fail_timeout=2;
server 10.2.1.2 weight=2 max_fails=2 fail_timeout=2;
}
upstream 也支持 fastcgi调用 形式如下
upstream imgservers {
server 10.2.1.1 weight=1 max_fails=2 fail_timeout=2;
server 10.2.1.2 weight=2 max_fails=2 fail_timeout=2;
} upstream jspservers {
server 10.2.1.3 weight=1 max_fails=2 fail_timeout=2;
server 10.2.1.4 weight=2 max_fails=2 fail_timeout=2;
} location / {
root /web/html;
index index.jsp index.html;
} location ~* "\.(jpg|jpeg|gif|png)$" {
proxy_pass http://imgservers
proxy_set_header X-Real-IP $remote_addr;
} location ~* \.jsp$ { fastcgi_pass http://jspservers
proxy_set_header X-Real-IP $remote_addr;
}
10 .nginx 防盗链
nginx配置文件中可以使用if语句,但if语句必须嵌套在location中使用 if的判定式:
location /img/ {
valid_referers none blocked www.exmample.com ;
if ($invalid_referer){
rewrite http://www.exmample.com;
if ($request_method = "PUT") { //上传服务的区分
proxy_pass http://img.example.com;
}
}
}
11.nginx status的开启
server{ ........ location /status { stub_status on; access_log off; allow 192.168.170.1; allow 127.0.0.1; deny all; }
12.对于location的匹配模式说明
匹配优先级:
字符字面量最精确匹配(即一个字符不差的完全匹配)、正则表达式检索(由多个时,由第一个匹配到的所处理),按字符字面量(即做最长字符字面量匹配)
(location =) > (location 完整路径 ) >(location ^~ 路径) >(location ~* 正则) >(location 路径部分匹配)
~ 匹配模式
!~ 不匹配模式
= 严格限定
!= 不严格限定
~* 不区分大小写
!~* 区分大小写
如果没有以上符号修定location 则 location中的匹配字符串表示以此字符串开始即算匹配
location /string { 表示以string开始的路径就算匹配
}