目录
1.写在前面
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。官方测试nginx能够支撑5W并发连接。
2.Nginx和apache的优缺点
apache每当来一个连接都会对应一个进程,nginx也会有多进程,但是进程数量是和cpu物理核心数相等的,如果我们有一个4核的服务器,Nginx会设置为4个进程。apache当有1W个连接会产生1W个进程,假设只有一个cpu核,也可以实现多任务(底层使用切换),切换也是有成本的,在Nginx中只会产生一个Nginx进程,使用异步非阻塞方式调度多个连接。
Nginx是CPU有多少个核心,就有多少个进程,而apache则是一个连接一个进程。那么在进程切换对cpu和IO是有损耗的,在高并发情况下,apache会开辟非常多进程,对cpu和io有非常大的损耗,进程切换又有着额外开销,所以这是apache的弊端;而Nginx则是一个cpu有多少核心,就有多少进程,那么进程数量很少,一个或者两个进程对应多个客户端Client,那么Nginx是如何在单进程面对多Client请求下做到数据发生不发生交互错误,又高效处理呢?答案就是异步非阻塞IO。
首先我们要知道网络IO流的速度是很慢的(ms级别),而CPU的速度是很快的(ns级别)。CPU比IO速度要快100w倍!!!而Apache使用的是同步阻塞IO,也就是在等连接建立完成后,CPU会等待1ms的时间来等待数据包从客户端传输过来。这个1ms的时间被浪费了,CPU被占用等待了。而Nginx则不是这样,当连接建立后,Nginx不会让CPU进行等待,而是让CPU不断询问linux系统中的连接文件,问是否有数据传输过来了,如果没有,则询问下一个,如果有则挂起别的进程立刻执行有数据的进程。这种轮询的方式后续又得到了改善,变成一旦这个连接文件有数据传输过来,会立刻向CPU发送中断请求,而CPU会立刻去处理该连接的数据,更大效率提高了IO速度和CPU的使用率。
nginx支持热加载与热部署,在nginx服务启动的时候,依然能够修改配置文件,让其重新加载配置文件与继续服务。tomcat则没有。nginx这一点得益于它的模块化开发。
nginx为什么能这样,我们首先要知道一个基础概念,程序本质上没有运行的时候,就是一个文件。而当程序被加载到内存中,则才是程序。这个时候如果我们删除或者程序的原本文件,是不会影响内存的,因为内存已经加载到了程序文件。windows不可以这样是因为windows在运行程序时,会给程序文件加锁,如果打开了锁,windows也可以。linux显然也可以这样去做。那对于nginx的热加载,linux是如何处理的呢?
如下图所示,nginx启动后,会开启两个进程。一个是manager,一个是worker。manager进程从属于root,它会读取nginx.conf来创建一个worker进程,并将它交给nobody权限用户。所有连接处理和转发,都是交给worker进程来处理的。一旦发生热加载,那么manager进程会重新读取配置文件,并等待老worker进程处理完所有任务后,创建新worker进程,杀死老worker,从而平滑的不用停止服务器就实现了服务器加载和更新。
3.Tengine:Nginx的加强版(淘宝开源)
4.安装Nginx的增强版本tengine
首先把安装包传到linux服务器,解压缩,安装必要的软件:
我们进入到tengine中可以看到并没有Makefile文件。
安装一下,产生Makefile文件,安装目录为/opt/sxt/nginx:
这个目录就会出现Makefile文件:
执行make命令,如果make成功执行,执行make install命令(先编译,后安装):
安装完成之后,我们进入到安装目录 /opt/sxt/nginx ,先不要启动,先进入/etc/init.d这个目录下面看一下:
编写Nginx启动脚本,并加入系统服务 vim /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/local/nginx/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/subsys/nginx
make_dirs() {
# make required directories
user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=[]∗.*/\1/g' -`
if [ -z "`grep $user /etc/passwd`" ]; then
useradd -M -s /bin/nologin $user
fi
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
保存该文件,修改执行权限:
启动nginx:service nginx start,这个时候就可以使用了。
5.Nginx配置文件
5.1 配置文件介绍
Nginx是通过配置文件来做到各个功能的实现的。Nginx的配置文件的格式非常合乎逻辑,学习这种格式以及如何使用这种每个部分是基础,这将帮助我们有可能手工创建一个配置文件。其整体结构如下:
从图中我们可以看出主要包含以下几大部分内容:
- main(全局设置):设置的指令将影响其他所有设置;
- server(主机设置):指令主要用于指定主机和端口、
- upstream(负载均衡服务器设置):指令主要用于负载均衡,设置一系列的后端服务器
- location(URL匹配特定位置的设置):用于匹配网页位置。
这四者之间的关系式:server继承main,location继承server,upstream既不会继承其他设置也不会被继承。在这四个部分当中,每个部分都包含若干指令,这些指令主要包含Nginx的主模块指令、事件模块指令、HTTP核心模块指令,同时每个部分还可以使用其他HTTP模块指令,例如Http SSL模块、HttpGzip Static模块和Http Addition模块等。
默认配置文件位于 :/usr/local/nginx/conf/nginx.conf
nginx.conf 文件中常用配置选项:
#user nobody;
#工作的cpu的内核数 默认应该是和当前电脑的cpu一致 设置为auto自动获取当前机器
worker_processes auto;
#ngx_http_log_module模块功能
#语法为 error_log 存储的log文件路径 [debug | info | notice | warn | error | crit]
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#定义存储nginx主进程ID的file。 nigix可能建立虚拟主机是 会创建多个进程
#pid logs/nginx.pid;
#最顶层的指令 events一般用于指定连接处理参数
events {
#设置每个工作进程可以打开的最大并发连接数。(数量包含所有连接(比如,和后端服务器建立的连接,还有其他的), 而不仅仅是和客户端的连接)
worker_connections 1024;
}
# load modules compiled as Dynamic Shared Object (DSO)
#
#dso {
# load ngx_http_fastcgi_module.so;
# load ngx_http_rewrite_module.so;
#}
#配置http服务器
http {
#包含其他语法正确的配置文件
include mime.types;
#设置默认的mini类型
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
#是否启用内核级别拷贝 零拷贝 速度快
sendfile on;
#tcp_nopush on;
#长连接的超时是假呢
#keepalive_timeout 0;
keepalive_timeout 65;
#是否启用gzip压缩 压缩需要时间 但是压缩后 可以节省带宽
#gzip on;
#配置虚拟主机
server {
#虚拟主机监听端口
listen 80;
#虚拟主机监听的ip(同一电脑可能多个ip)或者域名
#添加虚拟ip ifconfig 网卡名(可以通过ifconfig查看):1 192.168.58.134 netmask 255.255.255.0 up
#删除虚拟ip ifconfig 网卡名(可以通过ifconfig查看):1 down
server_name localhost;
//当根路径访问时 必须 http://localhost/ 自动进入根目录 html下找 index.html文件
location / {
root html;
index index.html index.htm;
}
//出现以下错误状态码 自动进入 /50x.html
error_page 500 502 503 504 /50x.html;
//自动找 html 实际文件路径就是 /html/50x.html
location = /50x.html {
root html;
}
}
}
5.2 Nginx配置文件各部分详解
5.2.1 全局块
该部分配置主要影响Nginx全局,通常包括下面几个部分:
a、配置运行Nginx服务器用户(组)
如:user nobody nobody; user是个主模块指令,指定Nginx Worker进程运行以及用户组。
指令格式:user user [group];
user:指定可以运行Nginx服务器的用户;group:可选项,可以运行Nginx服务器的用户组。
如果user指令不配置或者配置为user nobody nobody,默认由nobody账户运行。
b、worker process数
如:worker_processes 2; woker_processes是个主模块指令,制定了Nginx要开启的进程数。每个Nginx进程平均耗费10M~12M内存。建议指定和CPU的数量一致即可。
Nginx服务器实现并发处理服务的关键。
指令格式:worker_processes number | auto;
number : Nginx 进程最多可以产生的worker process 数。
auto : Nginx 进程将自动检测
在按照上面的配置格式配置了之后,假如上面的数目是2,那么启动Nginx服务器后,在后台主机上查看Nginx的进程情况,可以看到应该是有2个Nginx进程。
c、错误日志的存放路径
如:error_log logs/error.log notice; error_log 是个主模块指令,用来定义全局错误日志文件。日志输出级别有debug,info,notice,warn,error,erit可供选择,其中,debug输出日志最为详细,而crit输出日志最少。
指定格式:error_log file | stderr;
file : 日志输出到某个文件file
stderr : 日志输出到标准错误输出 (日志输出级别)。
d、Nginx进程PID存放路径
如:pid logs/nginx.pid; pid是个主模块指令,用来指定进程pid的存储文件位置。
Nginx进程是作为系统守护进程在进行,需要在某个文件中保存当前运行程序的主进程号,Nginx支持该保存文件路径的定义。
指令格式:pid file;
file:指定存放路径和文件名称。
如果不指定,则默认置于路径 logs/nginx.pid
e、worker_rlimit_nofile
如:worker_rlimit_nofile 65535; 用来绑定worker进程和CPU,Linux内核2.4 以上可用
指定进程可以打开的最多文件描述数目,理论值应该是最多打开文件数(ulimit -n )与nginx进程数相除,但是Nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。
现在在Linux2.6 内核下开启文件打开数为65535,worker_rlimit_nofile 就相应应该填写65535.这是因为Nginx调度时请求到进程并不是那么均衡,所以假如填写10240,总并发量达到3-4万时就有进程超过10240了,这就会返回502。
events 事件指令是设定Nginx的工作模式及连接数上限。
5.2.2 events块
events事件指令是设定Nginx的工作模式及连接数上限。每个配置选项的含义解释如下:
a、use
如:use epoll;
use是事件模块指令,用来指定Nginx的工作模式。Nginx支持的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll 。其中select 和poll 都是标准的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平台上,而kqueue用在BSD系统中。对于Linux系统,epoll工作模式是首选。
b、worker_connections
如:worker_connections65536;
work_connections也是个事件模块指令,用于定义Nginx每个进程的最大连接数,默认是1024。可以通过ulimit -a命令查看open files大小:
5.2.3 http块
A、定义MIMI-Type
如:include mime.types;
指令格式:include file;该指令主要用于将其他的Nginx配置或第三方模块的配置引用到当前的主配文件中,减少主配置文件的复杂度。default_type application/octet-stream;
default_type属于HTTP核心模块指令,这里设定默认类型为二进制流。也就是当文件类型未定义时使用这种方式,
B、自定义服务日志
log_format 是Nginx的HttpLog模块指令,用于指定Nginx日志的输出日志。当然其中还有更为详细的配置,但是这里只做大略的研究学习,不过分深入细节。
C、允许sendfile方式传输文件
指令格式:sendfile on;
这个指令中的参数on是表示开启高效文件传输模式,默认是关闭状态(off),将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞;
D、连接超时时间
指令格式:keepalive_timeout number;
如:keepalive_timeout 65;
keepalive_timeout设置客户端连接保持活动的超时时间。在超过这个时间之后,服务器会关闭该连接;
5.2.4 server块
server 块是对虚拟主机的配置,server标志定义虚拟主机开始,
- A、listen用于指定虚拟主机的服务端口,
- B、server_name 用来指定IP地址或域名,多个域名之间用空格分开。
- C、index用于设定访问的默认首页地址.。
- D、root指令用于指定虚拟主机的网页根目录,这个目录可以是相对路径,也可以是绝对路径。
- E、charset用于设置网页的默认编码格式。
- F、access_log 用来指定虚拟主机的访问日志存放路径,最后的main 用于指定访问日志的输出格式。
5.2.5 location块
URL地址匹配是进行Nginx配置中最灵活的部分。 location支持正则表达式匹配,也支持条件判断匹配,用户可以通过location指令实现Nginx对动、静态网页进行过滤处理。使用location URL匹配配置还可以实现反向代理,用于实现PHP动态解析或者负载负载均衡。
- a、location配置
- b、请求根目录配置
- c、更改location的URI
- d、网站默认首页配置