1 nginx是什么
nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。
基本功能:
Web服务器
提供静态内容服务
反向代理
压缩和解压缩
Web内容缓存
2 nginx安装
见http://nginx.org/en/linux_packages.html#distributions
sudo apt-key add nginx_signing.key
nginx_signing.key内容如下:
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)
mQENBE5OMmIBCAD+FPYKGriGGf7NqwKfWC83cBV01gabgVWQmZbMcFzeW+hMsgxH
W6iimD0RsfZ9oEbfJCPG0CRSZ7ppq5pKamYs2+EJ8Q2ysOFHHwpGrA2C8zyNAs4I
QxnZZIbETgcSwFtDun0XiqPwPZgyuXVm9PAbLZRbfBzm8wR/3SWygqZBBLdQk5TE
fDR+Eny/M1RVR4xClECONF9UBB2ejFdI1LD45APbP2hsN/piFByU1t7yK2gpFyRt
97WzGHn9MV5/TL7AmRPM4pcr3JacmtCnxXeCZ8nLqedoSuHFuhwyDnlAbu8I16O5
XRrfzhrHRJFM1JnIiGmzZi6zBvH0ItfyX6ttABEBAAG0KW5naW54IHNpZ25pbmcg
a2V5IDxzaWduaW5nLWtleUBuZ2lueC5jb20+iQE+BBMBAgAoAhsDBgsJCAcDAgYV
CAIJCgsEFgIDAQIeAQIXgAUCV2K1+AUJGB4fQQAKCRCr9b2Ce9m/YloaB/9XGrol
kocm7l/tsVjaBQCteXKuwsm4XhCuAQ6YAwA1L1UheGOG/aa2xJvrXE8X32tgcTjr
KoYoXWcdxaFjlXGTt6jV85qRguUzvMOxxSEM2Dn115etN9piPl0Zz+4rkx8+2vJG
F+eMlruPXg/zd88NvyLq5gGHEsFRBMVufYmHtNfcp4okC1klWiRIRSdp4QY1wdrN
1O+/oCTl8Bzy6hcHjLIq3aoumcLxMjtBoclc/5OTioLDwSDfVx7rWyfRhcBzVbwD
oe/PD08AoAA6fxXvWjSxy+dGhEaXoTHjkCbz/l6NxrK3JFyauDgU4K4MytsZ1HDi
MgMW8hZXxszoICTTiQEcBBABAgAGBQJOTkelAAoJEKZP1bF62zmo79oH/1XDb29S
YtWp+MTJTPFEwlWRiyRuDXy3wBd/BpwBRIWfWzMs1gnCjNjk0EVBVGa2grvy9Jtx
JKMd6l/PWXVucSt+U/+GO8rBkw14SdhqxaS2l14v6gyMeUrSbY3XfToGfwHC4sa/
Thn8X4jFaQ2XN5dAIzJGU1s5JA0tjEzUwCnmrKmyMlXZaoQVrmORGjCuH0I0aAFk
RS0UtnB9HPpxhGVbs24xXZQnZDNbUQeulFxS4uP3OLDBAeCHl+v4t/uotIad8v6J
SO93vc1evIje6lguE81HHmJn9noxPItvOvSMb2yPsE8mH4cJHRTFNSEhPW6ghmlf
Wa9ZwiVX5igxcvaIRgQQEQIABgUCTk5b0gAKCRDs8OkLLBcgg1G+AKCnacLb/+W6
cflirUIExgZdUJqoogCeNPVwXiHEIVqithAM1pdY/gcaQZmIRgQQEQIABgUCTk5f
YQAKCRCpN2E5pSTFPnNWAJ9gUozyiS+9jf2rJvqmJSeWuCgVRwCcCUFhXRCpQO2Y
Va3l3WuB+rgKjsQ=
=EWWI
-----END PGP PUBLIC KEY BLOCK-----
编辑/etc/apt/sources.list文件,在末尾加上:
deb http://nginx.org/packages/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/ubuntu/ trusty nginx
运行命令:
apt-get update
apt-get install nginx
3 nginx启动、停止和重新加载配置文件
nginx 启动
nginx-s stop 快速关闭
nginx-s quit 优雅的关闭
nginx -s reload重新加载配置文件
nginx -s reopen重新打开日志文件
4 nginx静态内容
nginx作为Web服务器提供的一项重要功能是提供静态内容,例如图片和静态HTML页面。
server {
listen 80;
server_name localhost;
location / {
root /data/www;
}
location /images/ {
root /data/images;
}
}
如果有多个匹配的location都满足条件,nginx会选择有最长前缀的那一个。上面的配置中的第一个location提供了最短的前缀(/),因此只有当所有其他location匹配失败时,才会匹配这个location块。
例如:上面的配置,用户一个http://localhost/images/example.png的请求,会响应/data/images/example.png文件给用户。如果这个文件不存在,nginx会响应一个404错误。而其他不是以/images/开头的URI请求会匹配到/data/www目录下。例如,用户一个http://localhost/some/example.html的请求会响应/data/www/some/example.html文件给用户。
5 nginx设置代理服务器
代理服务器接收请求,把他们分发到代理的服务器上,然后接收他们的响应,再发送给客户端(本例子中所有服务都在同一个nginx实例上)。
server {
listen 8080;
root /data/up1;
location / {
proxy_pass http://localhost:8080;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
6 nginx作为HTTP的负载均衡器
nginx支持的负载均衡方法:
round-robin 轮询。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除(默认方式)。
least-connected 最少连接。下一个请求发送到有最少连接的服务器上。
ip-hash 基于ip的哈希值。使用哈希算法(基于客户端的ip)来决定选择哪个服务器。
6.1默认负载均衡方法(round-robin)
http{
upstream myapp1 {
server srv1.example.com:9380;
server srv2.example.com:9380;
server srv3.example.com:9380;
}
server {
listen 80;
location/ {
proxy_passhttp://myapp1;
}
}
}
当没有指定负载均衡方法时,默认使用round-robin(轮询)的方式。
6.2最少连接负载均衡方法(least-connected)
upstream myapp1{
least_conn;
server srv1.example.com:9380;
server srv2.example.com:9380;
server srv3.example.com:9380;
}
使用最少连接的负载方法,nginx会尽量避免访问过度繁忙的服务器,而将新的请求发送到不那么繁忙的服务器上。
6.3会话保持(ip-hash)
upstream myapp1{
ip_hash;
server srv1.example.com:9380;
server srv2.example.com:9380;
server srv3.example.com:9380;
}
注意,round-robin或者least-connected的负载方法,同一个客户端的后续请求会被分配到不同的服务器上。无法保证同一个客户端总是定向到同一个服务器上。如果需要将某个客户端绑定到同一个指定的服务器上的话,就可以选择ip-hash的负载方法。ip-hash是根据客户端的IP地址的hash值来决定将请求发送到哪个服务器上,这样保证了同一个客户端的请求总是会定位到同一个服务器上,除非该服务器不可用。
6.4加权负载均衡方法
upstreammyapp1 {
server srv1.example.com:9380weight=3;
server srv2.example.com:9380;
server srv3.example.com:9380;
}
使用上面的配置,平均5个请求发过来的话,3个会定向到srv,1个定向到srv2,另外一个定向到srv3。如果不设置,默认是平均的。
7 nginx+tomcat实现动静分离
location~ \.jsp$ {
indexindex.jsp;
proxy_pass myapp1;
}
location~ \.(html|js|css|ico|gif|jpg|png|bmp|swf|eot|svg|ttf|woff)$ {
expires30d;
root/usr/local/apache-tomcat-8.5.8/webapps;
}
location / {
proxy_pass http://myapp1;
}
用正则表达式将所有满足条件的请求匹配到该location中。
第一个location:它将匹配到JSP请求都转发给Tomcat去处理
第二个location:将常见图片、css、js等请求匹配到该location中,通过root关键字,将匹配到的请求都到tomcat/webapps/ROOT目录下直接查找,expires 30d则表示使用expires缓存模块,缓存到客户端30天。
第三个location:其他未匹配到的地址,转发给tomcat去处理
8 nginx配置HTTPS服务
8.1 生成证书
# 1、首先,进入你想创建证书和私钥的目录,例如:
cd /etc/nginx/
# 2、创建服务器私钥,命令会让你输入一个口令:
openssl genrsa -des3 -out zhuyun.key 1024
# 3、创建签名请求的证书(CSR):
openssl req -new -key zhuyun.key -out zhuyun.csr
# 4、在加载SSL支持的Nginx并使用上述私钥时除去必须的口令:
cp zhuyun.key zhuyun.key.org
openssl rsa -in zhuyun.key.org -out zhuyun.key
# 5、最后标记证书使用上述私钥和CSR:
openssl x509 -req -days 365 -in zhuyun.csr-signkey zhuyun.key -out zhuyun.crt
# 5、删除多余的文件zhuyun.csr、zhuyun.key.org
rm zhuyun.csr
rm zhuyun.key.org
8.2 配置default.conf
server{
listen 9443 ssl;
ssl_certificate zhuyun.crt;
ssl_certificate_key zhuyun.key;
}
可以和http的配置放在同一个文件中。
示例配置文件如下:
nginx.conf
user root;
worker_processes 8;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
upstream myapp {
server 192.168.9.13:9380 weight=3;
server 192.168.9.14:9380 weight=1;
server 192.168.9.15:9380 weight=1;
}
include /etc/nginx/conf.d/*.conf;
}
default.conf
server {
listen 9390;
listen 9443 ssl;
ssl_certificate zhuyun.crt;
ssl_certificate_key zhuyun.key;
# server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
proxy_pass http://myapp;
}
# location ~ /(cbs|newton|docs|examples|manager)/.*\.(html|js|css|ico|gif|jpg|png|bmp|swf|eot|svg|ttf|woff)$ {
# expires 30d;
# root /usr/local/apache-tomcat-8.5.8/webappss;
# }
location ~ \.(html|js|css|ico|gif|jpg|png|bmp|swf|eot|svg|ttf|woff)$ {
expires 30d;
root /usr/local/apache-tomcat-8.5.8/webapps;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
10 nginx高可用keepalived
10.1 keepalived安装
sudoapt-get install keepalived wget
10.2 keepalived配置
在/etc/keepalived下创建文件keepalived.conf,内容如下:
vrrp_scriptchk_nginx_service {
script"/etc/keepalived/nginx-ha-check"
interval 2 #每2秒检测一次nginx的运行状态
weight -20 #失败一次,将自己的优先级-20
}
vrrp_instanceVI_1 {
interface em1 # 绑定VIP的网络接口,通过ifconfig查看自己的网络接口
priority 101 # 节点优先级,值范围0~254,MASTER要比BACKUP高
virtual_router_id 51 # 虚拟路由的ID号,两个节点设置必须一样
advert_int1 #组播信息发送时间间隔,两个节点必须设置一样,默认为1秒
# 设置验证信息,两个节点必须一致
authentication {
auth_type PASS
auth_pass 123456
}
track_script {
chk_nginx_service # nginx存活状态检测脚本
}
# 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个
virtual_ipaddress {
192.168.10.16/24
}
}
在/etc/keepalived下创建文件nginx-ha-check,内容如下:
#!/bin/bash
#代码一定注意空格,逻辑就是:如果nginx进程不存在则启动nginx,如果nginx无法启动则kill掉keepalived所有进程
A=`ps -Cnginx --no-header |wc -l`
if [ $A-eq 0 ];then
/etc/init.d/nginx start
sleep 3
if [ `ps-C nginx --no-header |wc -l`-eq 0 ];then
killall keepalived
fi
fi
给/etc/keepalived/nginx-ha-check添加可执行权限
chmod +x nginx-ha-check
10.3 keepalived启动和关闭
sudo service keepalived start
sudo service keepalived stop
10.4 keepalived日志
/var/log/syslog
11 nginx性能测试
测试环境:
操作系统 | 14.04.1-Ubuntu 64位 |
内存 | 32G |
CPU | 8核 |
磁盘大小 | 1T |
网络带宽 | 1000mbps |
服务器数量 | 5台,ip分别是11,12,13,14,15 其中,11做客户端发送测试数据 |
测试结果
测试条件 | 总请求数 | 吞吐率 |
动态数据,请求发送到tomcat | 3W | 3000-5000 |
动态数据,请求发送到nginx(12),再转发到三台tomcat(13,14,15) | 3W | 13000-15000 |
静态数据(0.1k),请求发送到nginx(12),再转发到一台tomcat(12) | 10W | 50000 |
静态数据(0.1k),请求发送到nginx(12),再转发到三台tomcat(13,14,15) | 10W | 53000 |
静态数据(0.1k),请求发送到nginx(12),直接本地读取文件(动静分离) | 10W | 53000 |
静态数据(0.1k),请求发送到tomcat(12) | 10W | 53000 |
静态数据(0.1k),请求发送到nginx(12),再转发到三台tomcat(13,14,15),同时启用nginx缓存 | 10W | 53000 |
静态数据的测试结果跟想象中的不太一样,预想中nginx本地的速率应该比转发到tomcat要快,转发到三台tomcat的速率比转发到一台的速率快,但是测试结果却是差不多,
可能是nginx或者tomcat或者带宽或者文件读写,其中某一个已经达到了瓶颈,具体还不清楚。