最近总结了一些技术文档,原本用于组内分享的,发到博客里备忘。
Nginx概述
简介
Nginx是一个自由、开源、高性能及轻量级的HTTP服务器及反转代理服务器,以其高性能、稳定、功能丰富、配置简单及占用系统资源少而著称。
Nginx 超越 Apache 的高性能和稳定性,使得国内使用 Nginx 作为 Web 服务器的网站也越来越多。
基础功能
- 处理静态文件,索引文件以及自动索引;
- 反向代理加速(无缓存),简单的负载均衡和容错;
- FastCGI,简单的负载均衡和容错;
- 模块化的结构。过滤器包括gzipping, byte ranges, chunked responses, 以及 SSI-filter 。在SSI过滤器中,到同一个proxy或FastCGI的多个子请求并发处理;
- SSL 和 TLS SNI 支持。
优势
Nginx专为性能优化而开发,性能是其最重要的考量, 实现上非常注重效率 。它支持内核Poll模型,能经受高负载的考验, 有报告表明能支持高达50,000个并发连接数。
Nginx作为负载均衡服务器: Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务, 也可以支持作为 HTTP代理服务器对外进行服务。
Nginx具有很高的稳定性。其它HTTP服务器,当遇到访问的峰值,或者有人恶意发起慢速连接时,也很可能会导致服务器物理内存耗尽频繁交换,失去响应,只能重启服务器。例如当前apache一旦上到200个以上进程,web响应速度就明显非常缓慢了。而Nginx采取了分阶段资源分配技术,使得它的CPU与内存占用率非常低。
nginx官方表示保持10,000个没有活动的连接,它只占2.5M内存,就稳定性而言, nginx比lighthttpd更胜一筹。
Nginx支持热部署。它的启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够在不间断服务的情况下,对软件版本进行进行升级。
Nginx采用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多。
Nginx安装
下载
到官网下载最新的稳定版: nginx: download
环境准备
准备gcc等编译环境:
sudo apt-get install libpcre3 libpcre3-dev openssl libssl-dev make build-essential gcc
编译安装
将下载到的.tar.gz包解压,进入解压后的目录,输入以下命令进行编译:
./configure
make
sudo make install
即可安装到/usr/local/nginx中。
如果需要SSL,可安装OpenSSL,有些Linux发行版自带OpenSSL无需额外安装,需要安装的到OpenSSL官网下载.tar.gz包解压编译即可。
启动&关闭
启动
执行
sudo /usr/local/nginx/sbin/nginx
启动Nginx。
一般make install后会安装到PATH中,可以直接执行sudo nginx。
执行nginx -v显示Nginx版本。
重新加载配置文件
sudo nginx -s reload
关闭
Nginx没有提供关闭的方法,只能通过ps找到进程ID后,用kill命令关闭。
如 强制退出 sudo kill-9 [PID],或发送其他退出的指令如TERM。
注:nginx包含worker和master两个进程,强制关闭时两者均需关闭:
Nginx配置
下面以DSP业务平台的Nginx配置为例进行讲解:
#user nobody;
worker_processes 1;
#根据CPU核数设定worker工作的CPU核心mask
#worker_cpu_affinity 1000;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format mylog '$remote_addr$time_local$request$http_referer$status$body_bytes_sent$request_time';
access_log logs/access.log mylog buffer=32k flush=5s;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 1000;
#gzip on;
server {
listen 80;
server_name iad.turing.asia;
location / {
#设置真实ip
proxy_set_header real_ip $remote_addr;
proxy_pass http://dsp:8080;
}
}
server {
listen 80;
server_name tag.turing.asia;
location / {
#设置真实ip
proxy_set_header real_ip $remote_addr;
proxy_pass http://tag:8080;
}
}
server {
listen 80;
server_name cm.turing.asia;
location / {
#设置真实ip
proxy_set_header real_ip $remote_addr;
## proxy_redirect off;
proxy_pass http://cm:8080;
}
}
}
基本配置
user
- 语法: user user [group]
- 缺省值: nobody nobody
指定Nginx Worker进程运行用户,默认是nobody帐号。
error_log
- 语法: error_log file [ debug | info | notice | warn | error | crit ]
- 缺省值: ${prefix}/logs/error.log
制定错误日志的存放位置和级别。
worker_processes
- 语法: worker_processes number
- 缺省值: 1
指定工作进程数。nginx可以使用多个worker进程。
worker_cpu_affinity
- 语法: 3.1.4.worker_cpu_affinity cpumask
执行Nginx在哪个/些CPU上工作,默认由系统接管(可以在所有核心上运行)。
如,有8个CPU线程(包括超线程),指定使用第0个CPU则配置为00000001,指定使用第7和第1个CPU线程则配置为10000010。
Event模块
Nginx的默认配置中包含一个默认的Event模块,其中只包含worker_connections配置。
worker_connections
- 语法:worker_connections number
每个worker的最大连接数。通过worker_connections和worker_proceses可以计算出maxclients: max_clients = worker_processes * worker_connections。作为反向代理,max_clients为: max_clients = worker_processes * worker_connections/4,因为浏览器访问时会通过连接池建立多个连接。
HTTP模块
Nginx最常用的是HTTP模块。
基本配置
HTTP中大部分基本配置无需修改,除了:
- keepalive_timeout 1000;配置Keep-Alive的超时,单位为秒;
- gzip on;配置是否开启Gzip压缩,开启后可以提高网站访问速度;
- log_format 配置日志格式,access_log配置日志路径和使用的格式,在此不细述。
server作用域
HTTP模块中最常配置的是server作用域。
server {
listen 80;
server_name cm.turing.asia;
location / {
#设置真实ip
proxy_set_header real_ip $remote_addr;
proxy_pass http://cm:8080;
}
}
listen
- 语法: listen address:port
- 默认值: listen 80
- 作用域: server 指定当前虚拟机的监听端口。
server_name
当前server匹配的用户请求路径的主机名,主要用于配置基于名称的虚拟主机,支持通配符和正则表达式(以波浪线~起头)。
server_name指令在接到请求后的匹配顺序分别为:准确的server_name匹配,以通配符开始的字符串,以通配符结束的字符串、匹配正则表达式。nginx按以上顺序依次匹配,只要有一项匹配以后就会停止搜索。
举例: 先后配置了两个server, server_name分别配置为cm.turing.asia和.turing.asia,当用户请求cm.turing.asia时,访问第一个server,用户访问test.turing.asia时访问第二个server。
location
- 语法:location 匹配字符串 { 操作语句 }
一个server中可以有多个location,用于匹配请求路径。
匹配的优先级与server_name相同。
location的操作语句中:
可以用proxy_set_header设定/增加HTTP请求头。上面的例子中,用proxy_set_header real_ip $remote_addr;将远程主机的真实IP加到HTTP请求头的real_ip字段中,因为收到Nginx转发的服务器读取到的远程主机IP为Nginx的IP,丢失了真实的用户IP信息,所以在此加上。
location中还可以使用if语句结合正则表达式进行请求的判断,比如根据请求中的Refer和请求资源类型,使用valid_referers禁用外站Refer的图片资源请求,以实现防盗链,在此不细述。
更常用的是proxy_pass 作反向代理,将请求转发到指定的服务器。
在上面的例子中,因为同一台Tomcat服务器中有多个项目,而经过Nginx转发的请求,会将请求的主机替代为proxy_pass中配置的主机,所以如果proxy_pass中填写的是Tomcat服务器的内网地址,则Tomcat无法分辨用户原本想访问的域名,亦即难以在server.xml中配置不同的域名绑定不同项目。
因此,我们在Nginx的服务器中配置hosts,将多个自定义的主机名绑定到Tomcat服务器的IP中;同时,在Nginx的配置中,location的proxy_pass不再配置为Tomcat服务器的IP而是hosts中我们设定的server_name对应的主机名。最后Tomcat的server.xml也相应地配置Host节点的name属性:
<!--Tomcat服务器的server.xml 片段:-->
<Host name="cm" appBase="cmserv" unpackWARs="true" autoDeploy="true">
<Context path="turingcm" docBase="turingcm" reloadable="true" />
</Host>
负载均衡配置
首先在HTTP模块中定义多台服务器构成的负载均衡:
upstream rtb{
server 127.0.0.1:8080 weight=5;
server 127.0.0.1:8081 weight=5;
…………
server 127.0.0.1:8085 backup;
}
每台服务器为一行,填写IP和端口,并在weight中填入负载均衡的权重(正整数,默认为1),注意分号。以上例子将该负载均衡配置命名为”rtb”。IP和端口后面填backup的表示备用服务器,当其他非backup的服务器均忙或宕机时,会分发请求到backup服务器上。
然后在location中,配置proxy_pass http://[负载均衡名]; 即可,即该server和location定义的域名规则和访问路径规则匹配到的请求将按weight分发到以上几台服务器/服务中。
动静分离
tomcat是一个比较全面的web容器,对静态网页的处理,应该是比较费资源的,特别是每次都要从磁盘读取静态页面,然后返回。这中间会消耗Tomcat的资源,可能会使那些动态页面解析性能影响。
//静态资源
location ~ .*\.(js|css|htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ { //静态资源到nginx服务器下static获取
root static;
expires 30d; //设置缓存期限
}
//动态资源
location ~ .*$ { //动态请求转发到tomcat服务器
proxy_pass http://127.0.0.1:8080;
}
动静分离的原理:Nginx配置中,通过location的配置,结合正则表达式,根据请求路径判断当前请求是否静态资源,如果是,则通过** root static;** 配置直接读取/usr/local/nginx/static下面对应相对路径的资源。如果是jsp等动态资源,则转发到Tomcat服务器。
注意,可以使用** root [绝对路径];**, 不一定要将静态资源放在Nginx目录下。
这里将静态资源的location放在前面优先匹配(同样是正则匹配的情况下)。
在此基础上,也可以通过不同的正则对不同的静态资源类型配置不同的缓存期限,如创意等图片可能会变动,缓存期限设小一点,而js/css等静态资源基本不变,缓存期限可以设长一点。