centos 下 nginx 简单优化_虚拟主机_负载均衡_动静分离_主备模式
# 用了nginx for win很久,安装也是超级简单。
# 还是用一下linux版的吧。环境是centos 6.5 或7.5 x64
# 安装开始: # 先安装依赖 yum install gcc-c++ yum -y install pcre* yum -y install openssl*
###### yum 方式:
yum install epel-release # 使用 epel 库,这个库带有很多第三方软件 如 nginx
yum update # 全部更新
yum install nginx # 安装 nginx
###### tar 包方式: # 下载,可以wget 目前最新1.15.3 cd /opt wget http://nginx.org/download/nginx-1.12.2.tar.gz tar zxf nginx-1.12.2.tar.gz cd nginx-1.12.2 # 指定安装目录 、编译安装 ./configure --prefix=/opt/nginx make && make install
# 如果安装的组件模块比较多,则需要的依赖也多. 比如,我装了这些依赖,
yum install -y zip unzip redhat-rpm-config gd-devel libX11-common libX11 perl-devel perl-ExtUtils-Embed gperftools libtool-ltdl openssl openssl-devel
# 并且准备了模块文件: nginx-upload-module-2.255.zip
# 然后编译命令如下:
./configure –user=nginx –group=nginx --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules \
--conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log \
--http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy \
--http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi \
--http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx \
--with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-stream_ssl_preread_module \
--with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --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_degradation_module --with-http_slice_module \
--with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic \
--with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module \
--with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong \
--param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' \
--with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E' --add-module=/opt/nginx-upload-module-2.255
# 检查测试 /opt/nginx/sbin/nginx -t
# 启动 停止 退出
/opt/nginx/sbin/nginx -h # 帮助
/opt/nginx/sbin/nginx # 启动 /opt/nginx/sbin/nginx -s stop /opt/nginx/sbin/nginx -s quit
# 如果是centos7以上,已经注册为系统服务的:
systemctl stop nginx
systemctl start nginx
#---------------- 官方文档: -s 参数------------
# nginx -h # 可在帮助中看到以下信息
# stop — fast shutdown # quit — graceful shutdown # reload — reloading the configuration file # reopen — reopening the log files #----------------------------------------------
如果需要开机启动,可安装为系统服务,以centos7为例:
# 安装完成时,自动添加了 /usr/lib/systemd/system/nginx.service 文件 [Unit] Description=The nginx HTTP and reverse proxy server After=network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/run/nginx.pid # Nginx will fail to start if /run/nginx.pid already exists but has the wrong # SELinux context. This might happen when running `nginx -t` from the cmdline. # https://bugzilla.redhat.com/show_bug.cgi?id=1268621 ExecStartPre=/usr/bin/rm -f /run/nginx.pid ExecStartPre=/usr/sbin/nginx -t ExecStart=/usr/sbin/nginx ExecReload=/bin/kill -s HUP $MAINPID KillSignal=SIGQUIT TimeoutStopSec=5 KillMode=process PrivateTmp=true [Install] WantedBy=multi-user.target # 接下来,只需要简单几步即可: systemctl enable nginx # 设为开机启动 systemctl status nginx # 查看状态,可以看到服务脚本路径 systemctl start nginx systemctl stop nginx
# 查看进程,端口 检查运行情况
ps aux |grep nginx # master worker 至少各一个 netstat -tulnp | grep :80 # 如果想要命令方便执行,可将路径加入PATH变量中 vim /etc/profile # 加入 2 行 export NGINX_HOME=/opt/nginx export PATH=$NGINX_HOME/sbin:$PATH source /etc/profile # 生效
# 或者使用添加软连接的方式:
ln -s /opt/nginx/sbin/nginx /usr/bin/nginx
#-------------------- 配置文件 nginx.conf ---------------------------
以下版本有一些简单的优化, 注意那些写有注释的行。
user nginx; worker_processes auto; # 进程数,一般设置为CPU核数,或者 auto pid /var/run/nginx.pid; # 记录进程PID文件,可以不启用 # Load dynamic modules. See /usr/share/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { use epoll; # 使用高效的 epoll 方式 worker_connections 65535; # 单个worker进程同时打开的最大连接数 跟系统的 ulimit -n 有关 } http { 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; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; server_tokens off; # 隐藏web出错时的版本号
CentOS 本身也要修改一下最大进程数和最大打开文件数 vim /etc/security/limits.conf 永久修改,重启后生效。
root soft nofile 65535 root hard nofile 65535 * soft nofile 65535 * hard nofile 65535
* soft nproc 16384
* hard nproc 16384
使用 ulimit -a 查看结果 。 另外,ulimit -n 65535 可以改 open files , ulimit -u 可以改 max user process 。 但是都不是永久更改。
可能还需要更改下 90-nproc.conf ( CentOS 7是 20-nproc.conf )中的 数字 vim /etc/security/limits.d/90-nproc.conf
有人改 /etc/systemd/system.conf 的两行:DefaultLimitNOFILE=65534 和 DefaultLimitNPROC=65534 。亲测不起作用。重启后 ulimit -a 得到的还是 /etc/security/limits.conf 中设置的值。
虚拟主机
超简单配置 基于不同域名的虚拟主机,其实就是:根据访问的不同网址对应不同的nginx中的不同文件夹。
先备份一个conf/nginx.conf文件,然后修改 http{}中的server, 删除原有的,示例如下:
## 注意:下面仅仅是http{}部分,不是nginx.conf的全部 http { server_tokens on; include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { # 创建服务 listen 80; server_name wwww.node-6.com; # 域名 ## location 匹配URL路径地址,/ 表示匹配所有路径 =开头表示精确匹配 ~区分大小写 ~*不区分大小写(默认不区分) location / { root data/www; # 根目录对应真实文件夹 index index.html index.htm index.jsp; } } server { listen 80; server_name bbs.node-6.com; location / { root data/bbs; index index.html index.htm index.jsp; } } }
对应地,需要在nginx下建立目录 data/www 和 data/bbs 以及各自目录下的文件。
执行 nginx -s reload 重新载入配置文件。 配置好DNS解析或hosts文件,浏览器测试访问。
超简单配置 基于不同端口号的虚拟主机,其实就是:根据访问网址的不同端口 对应不同的nginx中的不同文件夹。
和上面的配置差不多,只不过域名相同,listen不同:
server { # 服务 listen 80; server_name wwww.node-6.com; # 域名 location / { root data/www; # 根目录对应真实文件夹 index index.html index.htm index.jsp; } } server { listen 81; server_name wwww.node-6.com; location / { root data/bbs; index index.html index.htm index.jsp; } } server { listen 82; server_name wwww.node-6.com; location / { root data/img; index index.html index.htm index.jsp; } }
同样,nginx -s reload 即可生效。
配置 nginx 反向代理
和上面的虚拟主机配置差不多,既可以不同端口,也可以不同域名,关键词 proxy_pass 示例如下:
## 不同端口的反向代理 server{}部分 server { # 服务 listen 80; server_name wwww.node-6.com; # 域名 location / { proxy_pass http://127.0.0.1:8080; # 反向代理本地 tomcat index index.html index.htm index.jsp; } } server { listen 81; server_name www.node-6.com; # 域名 location / { proxy_pass http://127.0.0.1:8081; # 反向代理 index index.html index.htm index.jsp; } }
## 不同域名的反向代理 server{}部分 server { # 服务 listen 80; server_name wwww.node-6.com; # 域名 location / { proxy_pass http://127.0.0.1:8080; # 反向代理本地 tomcat index index.html index.htm index.jsp; } } server { listen 80; server_name bbs.node-6.com; # 域名 location / { proxy_pass http://127.0.0.1:8081; # 本地另一个 tomcat index index.html index.htm index.jsp; } }
配置完成后,同样,nginx -s reload 即可生效。
不同Location 做反向代理,示例如下:
## 不同Location的反向代理 server{}部分 ## 注意目标地址末尾要有/ server { # 服务 listen 80; server_name www.node-6.com; # 域名 location /www { # 末尾有无/不影响 proxy_pass http://127.0.0.1:8080/; # 末尾一定要/ index index.html index.htm index.jsp; } location /bbs { proxy_pass http://127.0.0.1:8081/; index index.html index.htm index.jsp; } }
负载均衡:
使用 upstream 方式,配置也很简单:在server{} 上面定义一个 upstream backServer 然后在proxy_pass中指向backServer 示例如下:
## 以下部分全部应在 http{}内: ## 定义多个上游服务器(真实业务)服务器的IP和端口,默认采用轮询机制 upstream backServer{ server 127.0.0.1:8080; server 192.168.112.5:8080; } server { listen 80; server_name www.node-6.com; # 域名 location / { proxy_pass http://backServer/; # 末尾一定要/ index index.html index.htm index.jsp; } }
负载均衡的方式:
轮询机制:轮流访问,非常均匀
权重机制:使用weight配置比例
ip hash: nginx获取IP地址hash运算固定分配到某服务器上,可以解决session共享问题
fair :第三方
url绑定:第三方
权重机制的设置和上面的简单设置差不多,只在目标后面加了weight。示例如下:
upstream backServer{ server 127.0.0.1:8080 weight=1; server 192.168.112.5:8080 weight=3; }
IP绑定方式,只是多了行 ip_hash;
upstream backServer{ server 127.0.0.1:8080; server 192.168.112.5:8080; ip_hash; }
一般情况下,可能实际生产环境,配置轮询机制或者权重机制比较多见。
如果上游服务器有个突然挂了怎么办?
所以,要设置好nginx的故障转移,示例如下:
## http{}中的两段配置
upstream backServer{ server 127.0.0.1:8080; server 127.0.0.1:8081; server 192.168.112.5:8080; } server { listen 80; server_name www.node-6.com; # 域名 location / { proxy_pass http://backServer/; # 末尾一定要/ ## 故障转移:设置超时时间 proxy_connect_timeout 1s; proxy_send_timeout 1s; proxy_read_timeout 1s; index index.html index.htm index.jsp; } }
上面是在阿里云ECS中的设置。
在另一个案例中,2台nginx互为主备,upstream 和 location 有不一样的写法:
upstream au_boxes { server 10.170.1.135:15202 weight=10 max_fails=3 fail_timeout=120s; server 10.170.1.136:15202 weight=10 max_fails=3 fail_timeout=120s; keepalive 3600; } # max_fails=3, 最多失败3次,将此后端服务器标记为down
# fail_timeout=120s 标记为down后等待120秒,再尝试恢复访问。
# keepalive 3600 是最多保持3600个长连接。在此用处不大
server { listen 8080; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location ~ (etc/passwd|\.php|\.asp|win.ini)$ { deny all; } location / { root /usr/share/nginx/html; index index.html index.htm; } location /au/{ proxy_pass http://au_boxes; # 当出现这些错误时,向其它的后端服务器发送请求
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 non_idempotent; # nginx向后端服务器请求重试次数,包含第一次正常请求时出错,再向其它服务器重试一次,一共2次。
# 这里只写2次,是因为,我只有2台nginx, 如果一台出错,只能重试另一台。多试也无意义。
proxy_next_upstream_tries 2; # nginx与后端服务器的连接超时时间。5秒内没有回应,判为超时。
proxy_connect_timeout 5s; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Remote-Addr $remote_addr; proxy_set_header X-Remote-User $remote_user; proxy_set_header X-Time-Local $time_local; proxy_set_header X-Request $request; proxy_set_header X-Status $status; proxy_set_header X-Body-Bytes-Sent $body_bytes_sent; proxy_set_header X-Http-Referer $http_referer; proxy_set_header X-Http-User-Agent $http_user_agent; }
结合 Keepalived 实现主备模式
虽然有了负载均衡,但nginx本身挂了怎么办?所以需要主备模式。
一旦主nginx挂了,备nginx自动接替。而主nginx恢复后又会自动承担主机。
简单的方法是结合keepalived来实现:
# keepalived 实现主备模式 ---------------------------------------------- yum install keepalived # MASTER: vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.52.5
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_script chk_http_port {
script "/opt/scripts/nginx_check.sh" # file path
interval 2 # per 2s
weight 2
}
vrrp_instance VI_1 {
state MASTER # in backup server would be "BACKUP"
interface ens33 # Ethernet card
virtual_router_id 51 # MASTER & BACKUP must be same.
priority 100 # MASTER big than BACKUP
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_http_port # execute check
}
virtual_ipaddress {
192.168.52.16 # VRRP H virtual addr
}
}
# BACKUP: vim /etc/keepalived/keepalived.conf
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.52.5
smtp_connect_timeout 30
router_id lvsback
}
vrrp_script chk_http_port {
script "/opt/scripts/nginx_check.sh" # file path
interval 2 # per 2s check
weight 2
}
vrrp_instance VI_1 {
state BACKUP # in backup server
interface ens33 # Ethernet card
virtual_router_id 51 # MASTER & BACKUP must be same.
priority 90 # MASTER big than BACKUP
advert_int 1 # heartbeat 1s
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_http_port # execute check
}
virtual_ipaddress {
192.168.52.16 # virtual addr
}
}
# 注意keepalived.conf文件主备稍有不同,详见带有注释的行。 # router_id 测试中并不重要,没有影响。 # vrrp_script chk_http_port 定义了检测脚本及间隔秒数 # virtual_router_id 51 主备必须一致 # priority 90 优先级备比主数字稍低一些 # track_script 调用脚本并执行 # virtual_ipaddress 用来对外公布的地址. 主备相同为了实现故障转移. # MASTER & BACKUP: vim /opt/scripts/nginx_check.sh
#!/bin/bash A=`ps -C nginx --no-header | wc -l` if [ $A -eq 0 ]; then /opt/nginx/sbin/nginx || killall keepalived fi
# 此脚本的作用是检查有无 nginx 进程,如果没有则试图启动 nginx, # 若nginx尝试启动失败,则杀死keepalived进程,从而实现故障自动转移。 # 测试时访问 192.168.52.16 可以看到主内容,故意给主nginx制造错误后,杀死 nginx 进程,
# 而在尝试启动 nginx 失败后,keepalived 进程将被结束,备机自动接管并将内容呈现。
# 测试时若 nginx 没有错误,即使手动结束 nginx 进程,keepalived 也会借助以上脚本,自动启动 nginx
URL重写:
参考:http://www.cnblogs.com/czlun/articles/7010604.html
https://www.linuxidc.com/Linux/2014-01/95493.htm
rewrite <regex> <replacement> [flag];
关键字 正则 替代内容 flag标记
。关键字:其中关键字error_log不能改变
。正则:perl兼容正则表达式语句进行规则匹配
。替代内容:将正则匹配的内容替换成replacement
。flag标记:rewrite支持的flag标记
flag标记说明:
last #本条规则匹配完成后,继续向下匹配新的location URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
rewrite参数的标签段位置:
server, location, if
SSL
现如今,很多网站都使用了https 。 nginx对https的设置很简单,在拥有证书的前提下。将证书文件放入 nginx/cert目录下:
然后配置文件中添加 SSL设置即可,以下示例: 也可参考 :https://www.cnblogs.com/tianhei/p/7726505.html
server { listen 443 ssl;
listen [::]:443 ssl default_server; server_name aaa.bbb.com; root /var/www/html/aaa/Public; ssl_certificate cert/2254667_aaa.bbb.com.pem; ssl_certificate_key cert/2254667_aaa.bbb.com.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location / { index index.html index.htm index.php; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
# 最后一行用来处理同一端口 http 请求。
error_page 497 https://$host:28080$request_uri; }
最后验证 https://aaa.bbb.com 若出现 小锁标志,点击小锁后显示证书有效,即设置成功。
如果自己生成证书的话,可参考: https://www.cnblogs.com/linus-tan/p/13571507.html
缺点是浏览器会提示证书无效。
实际配置文件示例: nginx/default.conf