Nginx
主要功能
1、静态资源服务器
2、反向代理服务(缓存、负载均衡)
3、API服务
1、静态资源服务器
创建静态服务器,配置nginx.conf
server {
listen 80;
server_name www.xuecheng.com;
ssi on;
ssi_silent_errors on;
location / {
alias E:/BaiduNetdiskDownload/xueChengWeb/xc-ui-pc-static-portal/;
index index.html;
}
2.反向代理服务
实现方式
1.仅使用模块ngx_http_proxy_module和ngx_stream_proxy_module实现简单的反向代理。指令为proxy_pass。
2.使用fastcgi模块提供的功能,反向代理动态内容。指令为fastcgi_pass。
3.使用ngx_http_memcached_module模块提供的功能,反向代理memcached缓存内容,指令为memcached_pass。
4.结合upstream模块实现更人性化的分组反向代理
各种情况
# uri后缀代理。
location ~ \.(jpeg|jpg|png|bmp|gif)$ {
proxy_pass ...
}
# 目录代理。
location ~ /forum/ {
proxy_pass ...
}
# 浏览器类型代理。
location / {
if ($http_user_agent ~ "MSIE") {
proxy_pass...
}
if ($http_user_agent ~ "Chrome") {
proxy_pass...
}
}
proxy_pass的具体用法
ngx_stream_proxy_module模块的proxy_pass指令只能在server段使用使用, 只需要提供域名或ip地址和端口。可以理解为端口转发,可以是tcp端口,也可以是udp端口。
ngx_http_proxy_module模块的proxy_pass指令需要在location段,location中的if段,limit_except段中使用,处理需要提供域名或ip地址和端口外,还需要提供协议,如"http"或"https",还有一个可选的uri可以配置。
ngx_stream_proxy_module
模块的proxy_pass
指令
server {
listen 127.0.0.1:12345;
proxy_pass 127.0.0.1:8080;
}
server {
listen 12345;
proxy_connect_timeout 1s;
proxy_timeout 1m;
proxy_pass example.com:12345;
}
server {
listen 53 udp;
proxy_responses 1;
proxy_timeout 20s;
proxy_pass dns.example.com:53;
}
server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
ngx_http_proxy_module
模块的proxy_pass
指令
server {
listen 80;
server_name www.test.com;
# 正常代理,不修改后端url的
location /some/path/ {
proxy_pass http://127.0.0.1;
}
# 修改后端url地址的代理(本例后端地址中,最后带了一个斜线)
location /testb {
proxy_pass http://www.other.com:8801/;
}
# 使用 if in location
location /google {
if ( $geoip_country_code ~ (RU|CN) ) {
proxy_pass http://www.google.hk;
}
}
location /yongfu/ {
# 没有匹配 limit_except 的,代理到 unix:/tmp/backend.socket:/uri/
proxy_pass http://unix:/tmp/backend.socket:/uri/;;
# 匹配到请求方法为: PUT or DELETE, 代理到9080
limit_except PUT DELETE {
proxy_pass http://127.0.0.1:9080;
}
}
}
在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走。
场景
server {
listen 80;
server_name www.test.com;
# 情形A
# 访问 http://www.test.com/testa/aaaa
# 后端的request_uri为: /testa/aaaa
location ^~ /testa/ {
proxy_pass http://127.0.0.1:8801;
}
# 情形B
# 访问 http://www.test.com/testb/bbbb
# 后端的request_uri为: /bbbb
location ^~ /testb/ {
proxy_pass http://127.0.0.1:8801/;
}
# 情形C
# 下面这段location是正确的
location ~ /testc {
proxy_pass http://127.0.0.1:8801;
}
# 情形D
# 下面这段location是错误的
#
# nginx -t 时,会报如下错误:
#
# nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular
# expression, or inside named location, or inside "if" statement, or inside
# "limit_except" block in /opt/app/nginx/conf/vhost/test.conf:17
#
# 当location为正则表达式时,proxy_pass 不能包含URI部分。本例中包含了"/"
location ~ /testd {
proxy_pass http://127.0.0.1:8801/; # 记住,location为正则表达式时,不能这样写!!!
}
# 情形E
# 访问 http://www.test.com/ccc/bbbb
# 后端的request_uri为: /aaa/ccc/bbbb
location /ccc/ {
proxy_pass http://127.0.0.1:8801/aaa$request_uri;
}
# 情形F
# 访问 http://www.test.com/namea/ddd
# 后端的request_uri为: /yongfu?namea=ddd
location /namea/ {
rewrite /namea/([^/]+) /yongfu?namea=$1 break;
proxy_pass http://127.0.0.1:8801;
}
# 情形G
# 访问 http://www.test.com/nameb/eee
# 后端的request_uri为: /yongfu?nameb=eee
location /nameb/ {
rewrite /nameb/([^/]+) /yongfu?nameb=$1 break;
proxy_pass http://127.0.0.1:8801/;
}
access_log /data/logs/www/www.test.com.log;
}
server {
listen 8801;
server_name www.test.com;
root /data/www/test;
index index.php index.html;
rewrite ^(.*)$ /test.php?u=$1 last;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
access_log /data/logs/www/www.test.com.8801.log;
}
fastcgi模块
server {
listen 80;
server_name www.longshuai.com;
location / {
root /www/longshuai/;
index index.php index.html index.htm;
}
location ~ \.php$ {
root /php/;
fastcgi_pass 192.168.100.27:9000;
fastcgi_index test.php;
include fastcgi.conf;
}
}
ngx_http_upstream_module模块
前面只使用了ngx_http_proxy_module来实现反向代理,但是其缺陷在于在nginx-proxy上定义的每条代理规则都只能转发到后台的某一台服务器上,即后端服务器无法分组。例如当图片服务器压力太大,添加一台服务器想要减轻图片服务器压力,但是仅使用proxy模块无法实现此类负载均衡到多台图片服务器上。
这时需要借助ngx_http_upstream_module模块,该模块用于定义后端服务器池,后端服务器也称为上游服务器(upstream),可以为每一种类型的后端服务器分一个组。然后在结合proxy_pass或其他代理指令将相应的请求转发到池内。
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# define server pool
upstream dynamic_pool {
server IP1:80;
}
upstream pic_pool {
server IP3:80 weight=2;
server IP4:80 weight=1;
}
upstream static_pool {
server IP5:80 weight=1;
server IP6:80 weight=1;
}
server {
listen 80;
server_name www.longshuai.com;
# define how to proxy
location ~ \.(php|php5)$ {
proxy_pass http://dynamic_pool;
}
location ~ \.(png|jpeg|jpg|bmp|gif)$ {
proxy_pass http://pic_pool;
}
location / {
proxy_pass http://static_pool;
}
}
}
nginx代理memcached
upstream memcached {
hash "$uri$args" consistent;
server 127.0.0.1:11211;
server 127.0.0.1:11212;
server 127.0.0.1:11213;
server 127.0.0.1:11214;
}
server {
listen 80;
server_name dev.hwtrip.com;
location ^~ /cache/ {
set $memcached_key "$uri$args";
memcached_pass memcached;
nginx代理memcached时,需要以变量 m e m c a c h e d k e y 作 为 k e y 去 访 问 m e m c a c h e d s e r v e r 上 的 数 据 。 例 如 此 处 将 memcached_key作为key去访问memcached server上的数据。例如此处将 memcachedkey作为key去访问memcachedserver上的数据。例如此处将uri a r g s 变 量 赋 值 给 args变量赋值给 args变量赋值给memcached_key变量作为key去访问memcached服务器上对应的数据。
3.缓存
nginx的ngx_http_proxy_module自带了缓存功能。有几种缓存:网页内容缓存,日志缓存,打开文件缓存,fastcgi缓存。fastcgi缓存功能应慎用,因为动态程序的前后逻辑可能改变了,缓存后的结果可能并非实际所需结果。
nginx的缓存功能主要用于缓存体积较小的页面资源,当数据较大时很容易出现瓶颈。在页面资源的缓存功能上,它属于业余玩家。而squid是科班出身,功能最全面,可以缓存大量数据,但架构太老,性能一般。varnish则是此类缓存的新贵,架构较新,内存管理完全交由操作系统内核,性能是squid的几倍之强,但缓存的内容不足squid。
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream web_group {
server 192.168.100.28 weight=2 max_fails=2 fail_timeout=2s;
server 192.168.100.30 weight=1 max_fails=2 fail_timeout=2s;
server 127.0.0.1:80 backup;
}
proxy_cache_path /usr/local/nginx/cache_dir levels=1:2 keys_zone=cache_one:20m max_size=1g;
server {
listen 127.0.0.1:80;
root /www/longshuai/;
index index.html;
}
server {
listen 80;
server_name www.longshuai.com;
# 在响应报文中添加缓存首部字段
add_header X-Cache "$upstream_cache_status from $server_addr";
location / {
proxy_pass http://web_group;
proxy_cache cache_one;
proxy_cache_valid 200 1h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 5m;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
#"add_header X-Cache "$upstream_cache_status from $server_addr";"表示在响应报文的头部加上一字段X-Cache,其值为是否命中缓存的状态($upstream_cache_status),从哪台服务器上($server_addr)取得的缓存。 重载代理服务器的配置文件后,在客户端打开"开发者工具"进行测试。
指令
proxy_cache_path
proxy_cache_path /usr/local/nginx/cache_dir levels=1:2 keys_zone=cache_one:20m max_size=1g;
1.path:定义缓存放在磁盘的哪个目录下。此处表示定义在/usr/local/nginx/cache_dir目录下。目录不存在会自动创建。
2.levels:定义缓存目录的级别,同时定义缓存目录名称的字符数。例如levels=1:2:2表示3级目录,且第一级目录名1个字符,第二级目录2个字符,第三级目录2个字符。目录最多3级,目录名最多为2个字符。例如上例中"levels=1:2"产生的缓存文件路径可能是这样的"/usr/local/nginx/cache_dir/d/f1/50a3269acaa7774c02d4da0968124f1d",注意其中加粗的字体。
3.keys_zone:定义缓存标识名称和内存中缓存的最大空间。name部分必须唯一,在后面会引用name来表示使用该缓存方法。
4.max_size:定义磁盘中缓存目录的最大空间。即path定义的文件最大空间。
该指令定义后只是定义了一种缓存方法,并非开启了缓存。
proxy_cache:定义要使用哪个缓存方法。
proxy_cache cache_one;
proxy_cache_valid 根据状态码来指定缓存有效期。
下面的表示状态码为200和302的状态缓存1小时,状态码为404时即page not found的缓存只有1分钟,防止客户端请求一直错误,状态码为其他的则缓存5分钟。 如果不指定状态码,只指定时间,则默认只缓存状态码200、301、302各5分钟,其他的状态码不缓存。
proxy_cache_valid 200 302 1h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 5m;
负载均衡的算法
负载均衡的核心目的:分流
说明:不需要掌握10个,不常用的了解即可!
(1)rr轮询(默认调度算法)
特点:雨露均沾,按照客户端请求顺序把客户端的请求逐一分配到不同后端节点服务器,不考虑其它因素!
适用场景:静态资源的处理,服务器的性能一致,目的:减轻大量请求时,后端服务器的压力!
补充:nginx自带健康检查的策略,如果后端服务器down掉,能自动剔除。
(2)wrr权重轮序
特点:在轮询算法的基础上加上权重(weight),权重值越大,转发的请求越多,可以根据服务器状态进行指定权重值大小
适用场景:用于后端服务器性能不均的情况,weight和访问比率成正比!
常见的配置
upstream wzj {
server 172.25.2.1:80 weight=1;
server 172.25.2.2:80 weight=2;
}
说明:假设有三次访问,因为weight的值,weight=1访问一次,weight=2访问两次!
upstream更详细的参数
(3) ip_hash
特点: 每个请求按照客户端IP的hash结果分配,新的请求到达时,先将客户端IP通过哈希算法哈希出一个值(基本不会有hash碰撞),在随后的的客户端请求中,客户IP的哈希值只要相同,就会被(定向)分配至同一台服务器,该调度算法可以解决动态网页的session共享问题,但是会导致请求分配不均!
核心:将同一用户的ip请求影射到相同的服务器上!
实质:每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题!
注意:在upstream里配置,如果是ip_hash,不能有weight和bakcup!
应用场景:当你服务端的一个特定url路径会被同一个用户连续访问时,如果负载均衡策略还是轮询的话,那该用户的多次访问会被打到各台服务器上,这显然并不高效(由于http协议是无状态的,所以会建立多次http链接等问题)。甚至考虑一种极端情况,用户需要分片上传文件到服务器下,然后再由服务器将分片合并,这时如果用户的请求到达了不同的服务器,那么分片将存储于不同的服务器目录中,导致无法将分片合并
补充:ip_hash的缺点!
(4)url_hash(第三方)
每个请求按访问url的hash结果分配,这样每个url请求固定访问一个后端服务器。
配置实例:
upstream wzj {
hash $request_uri;
server 172.25.2.20:80;
server 172.25.2.10:80;
}
应用场景:一般来讲,要用到urlhash,是要配合缓存命中来使用。
案例:举一个我遇到的实例:有一个服务器集群A,需要对外提供文件下载,由于文件上传量巨大,没法存储到服务器磁盘中,所以用到了第三方云存储来做文件存储。服务器集群A收到客户端请求之后,需要从云存储中下载文件然后返回,为了省去不必要的网络带宽和下载耗时,在服务器集群A上做了一层临时缓存(缓存一个月,缓存有效期)。由于是服务器集群,所以同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。在此类场景下,为了使得缓存命中率提高,很适合使用url_hash策略,同一个url(也就是同一个资源请求)会到达同一台机器,一旦缓存住了资源,再此收到请求,就可以直接从缓存中读取,既减少了带宽,也减少的下载时间。
(5)fair
按后端服务器的响应时间来分配请求。响应时间短的优先分配。
upstream favresin{
server 10.0.0.10:8080;
server 10.0.0.11:8080;
fair;
}
upstream相关参数的说明
upstream还能够为每一个设备设置状态值,这些状态值的含义分别例如以下:
#(1)down 表示单前的server临时不參与负载;
#(2)weight 默觉得1.weight越大,负载的权重就越大;
#(3)max_fails :同意请求失败的次数,默认是1,当超过最大次数时,返回proxy_next_upstream 模块定义的错误;
#(4)fail_timeout : max_fails次失败后,暂停的时间;
#(5)backup: 其他全部的非backup机器down或者忙的时候,请求backup机器,所以这台机器压力会最轻(备机)
继续深入:负载均衡session会话保持方法总结
————————————————
原文链接:https://blog.csdn.net/wzj_110/article/details/100676286
其他:nginx高级配置