是一个高性能的HTTP和反向代理服务器,优点是内存少,并发能力强。最高支持5万并发量
正向代理与反向代理
+ 正向代理在客户端(浏览器)配置代理服务器,通过代理服务器进行或联网访问
- 反向代理
反向代理中客户对代理是无感知的,客户端不需要任何配置。反向代理服务器跟目标服务对外就是一个服务器,暴露的是代理服务器的地址,隐藏了真实服务器ip地址。客户向方向代理服务器发起请求时有反向代理服务来确定访问哪个服务。
命令
start nginx:启动nginx -v:版本号
nginx -s stop:停止
nginx -s reload:重新加载
配置文件
#user nobody;
worker_processes 1; # 支持的并发处理量
#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 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 on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#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 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;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
全局块
从配置文件到events宽之间的内容,主要设置影响nginx服务整体运行的配置指令events块
events块涉及的指令主要影响nginx服务器与用户的网络连接http块
http块的指令包括文件引入、MIME-TYPE定义、日志自定义、连接超时时间、单链请求数上限等每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。
而每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块。
全局 server 块
最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。location 块
一个 server 块可以配置多个 location 块。这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称
(也可以是 IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓
存和应答控制等功能,还有许多第三方模块的配置也在这里进行。
location语法
- 修饰语“=”:完全匹配 URI 中除访问参数以外的内容,Linux 系统下会区分大小写,Windows 系统下则不会。
location = /images {
root /data/web;
}
- 修饰语“~”:完全匹配 URI 中除访问参数以外的内容,Linux 系统下会区分大小写,Windows 系统下则会无效。匹配项的内容必须是正则表达式。
location ~ /images/.*\.(gif|jpg|png)$ {
root /data/web;
}
- 修饰语“~*”:完全匹配 URI 中除访问参数以外的内容,不区分大小写。匹配项的内容必须是正则表达式。
location ~* \.(gif|jpg|png)$ {
root /data/web;
}
- 修饰语“^~”:完全匹配 URI 中除访问参数以外的内容,匹配项的内容如果不是正则表达式,则不再进行正则表达式测试。
location ^~ /images {
root /data/web;
}
- 修饰语“@”:定义一个只能内部访问的 location 区域,可以被其他内部跳转指令使用,如 try_files 或 error_page。
location @images {
proxy_pass http://images;
}
匹配顺序
- 先检测非正则的location,再检测正则的location
- 正则与非正则都匹配的location,按照内容为正则匹配的执行
- 所有location都为非正则时,安装完全匹配的内容长短进行选择,匹配内容多的location执行
- 所有location都为正则时,按照书写的先后顺序进行匹配,匹配后就执行不再做后续检测
location中斜线的位置的区别
- proxy_pass是ip+端口+/的话:就不要location的映射部分,proxy_pass+映射后面的url。例如A、B
- proxy_pass是ip+端口的话:就要location的映射部分,proxy_pass+映射部分+映射后面的url。例如C、D
- proxy_pass是ip+端口+url的话:就不要location的映射部分,即将实际请求url中location映射部分,按严格字符匹配替换为proxy_pass部分:例如:E、F、G、H
nginx 服务器及端口 127.0.0.1:80
后端服务:127.0.0.1:8080
测试url:http://127.0.0.1:80/day06api/api/abc
A.配置
nginx配置如下:location /day06api/ {
proxy_pass http://127.0.0.1:8080/;
}
实际访问的端口服务:http://127.0.0.1:8080/api/abc
B.配置
location /day06api {
proxy_pass http://127.0.0.1:8080/;
}
实际访问的端口服务:http://127.0.0.1:8080//api/abc
C.配置
location /day06api/ {
proxy_pass http://127.0.0.1:8080;
}
实际访问的端口服务:http://127.0.0.1:8080/day06api/api/abc
D.配置
location /day06api {
proxy_pass http://127.0.0.1:8080;
}
实际访问的端口服务:http://127.0.0.1:8080/day06api/api/abc
E.配置
location /day06api/ {
proxy_pass http://127.0.0.1:8080/server/;
}
实际访问的端口服务:http://127.0.0.1:8080/server/api/abc
F.配置
location /day06api {
proxy_pass http://127.0.0.1:8080/server/;
}
实际访问的端口服务:http://127.0.0.1:8080/server//api/abc
G.配置
location /day06api/ {
proxy_pass http://127.0.0.1:8080/server;
}
实际访问的端口服务:http://127.0.0.1:8080/serverapi/abc
H.配置
location /day06api {
proxy_pass http://127.0.0.1:8080/server;
}
实际访问的端口服务:http://127.0.0.1:8080/server/api/abc
负载均衡
将客户请求转发到不同服务器上,分摊负载压力
- 轮询策略(默认)
upstream myserver {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#root html;
proxy_pass http://myserver/hello;
#index index.html index.htm;
}
}
- 权重策略
upstream myserver {
server 127.0.0.1:8080 weight=10;
server 127.0.0.1:8081 weight=10;
}
- iphash策略
每个请求按访问ip的hash结果分配,这样每个访客可固定访问一个后端服务器,可解决session问题
upstream myserver {
ip_hash;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
- fair策略
按后端服务的响应时间来分配请求,响应时间短的优先分配
upstream myserver {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
fair;
}
- url_hash策略
根据url定向到固定的后端服务器,后端服务器为缓存时比较有效
upstream myserver {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
hash $request_url;
hash_method crc32;
}
upstream myserver {
server 127.0.0.1:8080 down; #(down标识当前server不参加负载)
server 127.0.0.1:8081 weight=2;#(weight默认为1,weight越大分配到的记录越大)
server 127.0.0.1:8083 backup;#(其他所有非backup机器down或者忙时,请求backup机器)
hash $request_url;
hash_method crc32;
}
代理mysql
stream{
upstream mysql{
server 192.168.122.111:3336 weight=9;
server 192.168.122.112:3336 weight=1;
}
server{
listen 3336;
proxy_pass mysql;
}
}
动静分离
将静态文件(html,css,js)放到反向代理服务中
动静分离是指动态请求跟静态请求分开,可以理解成使用 Nginx
处理静态页面,Tomcat 处理动态页面。
动静分离分为两种:
- 一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;
- 另外一种方法就是动态跟静态文件混合在一起发布,通过 nginx 来分开
优点
- api接口服务化,接口功能更加纯粹,节省后端人力
- 前后端分离有利于并行开发
- 减轻后端服务器压力
高可用
1. 两台nginx服务器安装keepalivedyum -y install keepalived
- 修改keepalived.conf配置
! Configuration File for keepalived
# 全局配置
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL # 主机域名
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
# 健康监测脚本配置
vrrp_script_chk_http_port {
scrip "/user/local/src/nginx_check.sh"
interval 2 #监测脚本执行间隔s
weight 2 #权重,脚本条件成立则权重加2
}
vrrp_instance VI_1 {
state MASTER # MASTER:主服务器; BACKUP:备份服务器
interface eth0 # 网卡
virtual_router_id 51 # 主备机的路由id,主备机id必须相同
priority 100 # 优先级,主机值大,备机值小
advert_int 1 # 心跳监测间隔
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟ip
virtual_ipaddress {
192.168.200.16
192.168.200.17
192.168.200.18
}
}
nginx监控检测脚本nginx_check.sh
原理
master&worker进程
nginx 采用的是多进程的工作模式,在nginx启动后,会有一个master进程和多个互相独立的worker进程。master进程负责接收外部信号,然后通知各个worker进程有信号到了,每个worker进程通过抢占式的方式来处理这个连接。惊群效应
master 进程首先通过 socket() 来创建一个 sock 文件描述符用来监听,然后fork生成worker 进程,worker进程将继承父进程的 sockfd,之后worker进程 accept() 后将创建已连接描述符,然后通过已连接描述符来与客户端通信。
由于所有worker进程都继承了master进程的 sockfd,那么当连接进来时,所有子进程都将收到通知并“争着”与它建立连接,这就叫“惊群现象”。大量的进程被激活又挂起,只有一个进程可以accept() 到这个连接,这当然会消耗系统资源。
nginx 提供 accept_mutex ,这是一个加在accept上的一把互斥锁。即每个 worker 进程在执行 accept 之前都需要先获取锁,获取不到就放弃执行 accept()。有了这把锁之后,同一时刻,就只会有一个进程去 accpet(),这样就不会有惊群问题了。accept_mutex 是一个可控选项,我们可以显示地关掉,默认是打开的
优点
- 可以用于实现 nginx –s reload 热部署,利用 nginx 进行热部署操作
- 每个 woker 是独立的进程,如果有其中的一个 woker 出现问题,其他 woker 独立的, 继续进行争抢,实现请求过程,不会造成服务中断
worker的数量
worker的数量与cup核数相等是最适宜的
worker的连接数(worker_connection)
- 一个请求占用worker多少连接数?
2个或者4个,访问静态资源占用两个,访问动态资源占用4个
- worker_connection=1024,支持的最大并发数是多少?
静态访问:worker_connection*work_数量/2
动态访问:worker_connection*work_数量/4