本文最后更新于:2025年2月11日 晚上
1.安装哪个版本? nginx、openresty、tengine是三大主流,当然还有一些小众的定制,例如VeryNginx(基于openresty),他们各有优点,但从开箱即用上来说,openresty默认带的模块最多,而且内置了lua-nginx-module以及一些lua模块,免去了给nginx添加模块的烦恼。
为已安装好的nginx添加模块 手动安装的nginx需要在源码包手动configue以及make,在使用时可能会有额外的需求,这时可以重新编译一份nginx
这里以添加ssl模块为例
切换到源码包path:
1 cd /usr/local/software/nginx-1.18.0/
查看nginx原有的模块
1 /usr/local/nginx/sbin/nginx -V
在configure arguments:后面显示的原有的configure参数如下:
1 --prefix=/usr/local /nginx --with -http_gzip_static_module
那么我们的新配置信息就应该这样写:
1 ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module
运行上面的命令即可,等配置完
配置完成后,运行命令
这里不要接着进行make install,否则就会覆盖安装了
然后备份原有已安装好的nginx
1 cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
然后将刚刚编译好的nginx覆盖掉原有的nginx(这个时候nginx要是停止状态)
1 cp ./objs/nginx /usr/local/nginx/sbin/
然后可以通过命令查看是否已经加入成功
1 /usr/local/nginx/sbin/nginx -V
2.配置文件 nginx.conf main(全局模块) 1 2 3 4 5 6 7 8 9 10 worker_processes 1 ;
events(nginx工作模式) 1 2 3 4 5 events { use epoll ; worker_connections 1024 ; }
http(http设置) upstream(负载均衡服务器设置)
server(主机设置)
location(url 匹配)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 http { include mime.types; default_type application/octet-stream; sendfile on ; keepalive_timeout 65 ; server { listen 80 ; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
3.负载均衡 轮询 通过统计判断实现负载均衡
1 2 3 4 5 upstream fuzaijunheng { server 127.0.0.1:1001 ; server 127.0.0.1:1002 ; ..... }
修改location
内容
1 2 3 4 5 location / { proxy_pass http://fuzaijunheng; }
权重 权重值越大,优先级越高,按照百分比实现负载均衡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 upstream fuzaijunheng{ server 47.102.145.80:8080 weight=10 ; server 47.114.72.89:8070 weight=5 ; } server { listen 80 ; server_name test; location / { proxy_pass http://fuzaijunheng; proxy_redirect default; proxy_connect_timeout 1 ; proxy_send_timeout 1 ; proxy_read_timeout 1 ; }
iphash 根据访问者ip地址的hash来分配服务器
1 2 3 4 5 6 upstream ~ { ip_hash; server 127.0.0.1:1001 weight =1; server 127.0.0.1:1002 weight =2; .. .. . }
最少连接 将请求分配到连接最少的服务器上,理论上绝对平衡
1 2 3 4 5 6 upstream ~ { least_conn; server 127.0.0.1 :1001; server 127.0.0.1 :1002; ..... }
fair 按后端服务器的响应时间来分配请求,响应时间短的优先分配。需要插件来实现
1 2 3 4 5 6 upstream ~ { server 127.0.0.1:1001 weight =1; server 127.0.0.1:1002 weight =2; fair; .. .. . }
例子 以轮询为例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 worker_processes 1 ;events { worker_connections 1024 ; }http { upstream fuzaijunheng{ server localhost:8080 ; server localhost:8081 ; } server { listen 80 ; server_name localhost; location / { proxy_pass http://fuzaijunheng; proxy_redirect default; } }
4.限流 令牌桶算法
令牌以固定速率产生,并缓存到令牌桶中
令牌桶放满时,多余的令牌被丢弃
请求要消耗等比例的令牌才能被处理
令牌不够时,请求被缓存
漏桶算法
请求存放在漏桶中,以固定速率流出
漏桶满后,多余请求将被丢弃
中文文档已过时 配置示例(过时) 1 2 3 4 5 6 7 8 9 10 11 12 http { : limit_zone one $binary_remote_addr 10 m; : ... : server { : ... : location /download/ { : limit_conn one 1 ; : }
limit_zone(过时) 语法: limit_zone zone_name $variable the_size
默认值: no
作用域: http
本指令定义了一个数据区,里面记录会话状态信息。 $variable 定义判断会话的变量;the_size 定义记录区的总容量。
例子:
1 limit_zone one $binary_remote_addr 10m ;
定义一个叫“one”的记录区,总容量为 10M,以变量 $binary_remote_addr 作为会话的判断基准(即一个地址一个会话)。
您可以注意到了,在这里使用的是 $binary_remote_addr 而不是 $remote_addr。
$remote_addr 的长度为 7 至 15 bytes,会话信息的长度为 32 或 64 bytes。 而 $binary_remote_addr 的长度为 4 bytes,会话信息的长度为 32 bytes。
当区的大小为 1M 的时候,大约可以记录 32000 个会话信息(一个会话占用 32 bytes)。
limit_conn(过时) 语法: limit_conn zone_name the_size
默认值: no
作用域: http, server, location
指定一个会话最大的并发连接数。 当超过指定的最发并发连接数时,服务器将返回 “Service unavailable” (503)。
例子:
1 2 3 4 5 6 limit_zone one $binary_remote_addr 10m ;server { location /download/ { limit_conn one 1 ; }
定义一个叫“one”的记录区,总容量为 10M,以变量 $binary_remote_addr 作为会话的判断基准(即一个地址一个会话)。 限制 /download/ 目录下,一个会话只能进行一个连接。 简单点,就是限制 /download/ 目录下,一个IP只能发起一个连接,多过一个,一律503。
limit req module Example Configuration 1 2 3 4 5 6 7 8 9 10 11 12 http { limit_req_zone $binary_remote_addr zone =one:10m rate =1r/s; .. . server { .. . location /search/ { limit_req zone =one burst =5; }
rate设置产生令牌的速率,burst设置缓冲大小
不过,单独使用 burst 参数并不实用。假设 burst=50 ,rate依然为10r/s,排队中的50个请求虽然每100ms会处理一个,但第50个请求却需要等待 50 * 100ms即 5s,这么长的处理时间自然难以接受。
因此,burst 往往结合 nodelay 一起使用。
nodelay 针对的是 burst 参数,burst=20 nodelay 表示这20个请求立马处理,不能延迟,相当于特事特办。不过,即使这20个突发请求立马处理结束,后续来了请求也不会立马处理。burst=20 相当于缓存队列中占了20个坑,即使请求被处理了,这20个位置这只能按 100ms一个来释放。
这就达到了速率稳定,但突然流量也能正常处理的效果。
limit_conn_module 1 2 3 4 5 6 7 limit_conn_zone $binary_remote_addr zone =perip:10m; limit_conn_zone $server_name zone =perserver:10m;server { .. . limit_conn perip 10; limit_conn perserver 100; }
limit_conn perip 10 作用的key 是 $binary_remote_addr ,表示限制单个IP同时最多能持有10个连接。
limit_conn perserver 100 作用的key是 $server_name ,表示虚拟主机(server) 同时能处理并发连接的总数。
需要注意的是:只有当 request header 被后端server处理后,这个连接才进行计数
设置白名单 限流主要针对外部访问,内网访问相对安全,可以不做限流,通过设置白名单即可。利用 Nginx ngx_http_geo_module 和 ngx_http_map_module两个工具模块即可搞定。
在 nginx.conf 的 http 部分中配置白名单:
1 2 3 4 5 6 7 8 9 10 11 geo $limit { default 1; 10.0.0.0/8 0; 192.168.0.0/24 0; 172.20.0.35 0; } map $limit $limit_key { 0 "" ; 1 $binary_remote_addr ; } limit_req_zone $limit_key zone =myRateLimit:10m rate =10r/s;
geo 对于白名单(子网或IP都可以) 将返回0,其他IP将返回1。
map 将 $limit 转换为 $limit_key ,如果是 $limit 是0(白名单),则返回空字符串;如果是1,则返回客户端实际IP。
limit_req_zone 限流的key不再使用 $binary_remote_addr ,而是 $limit_key 来动态获取值。如果是白名单,limit_req_zone 的限流key则为空字符串,将不会限流 ;若不是白名单,将会对客户端真实IP进行限流。
ab测试 安装 1 2 3 4 5 6 7 8 yum -y install apr-util yum -y install yum-utilscd /opt mkdir abtmpcd abtmp yumdownloader httpd-tools* rpm2cpio httpd-*.rpm | cpio -idmv # 在/opt /abtmp目录下会生成一个usr目录,ab 就在此目录中
简单使用
1 2 3 ./ab -n100 -c10 http:/ /127.0.0.1/
5.动静分离 在server {}段中加入带正则匹配的location 来指定匹配项针对服务的动静分离
静态页面交给nginx处理
动态请求交给服务器或apache处理
实现整个网站的动静分离,要求如下:
1.前端Nginx收到静态请求,直接从NFS中返回给客户端
2.前端Nginx收到动态请求,通过FastCGI交给服务器处理
——如果得到静态结果直接从NFS取出结果交给Nginx然后返回给客户端
——如果需要数据处理服务器连接数据库后将结果返回给Nginx
3.前端Nginx收到图片请求以.jpg .png .gif等请求交给后端Images服务器处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 upstream jing { server localhost:8080 ; }upstream dong { server localhost:8081 ; }location /test.html{ proxy_pass http://jing; }location ~*\.(jpg|gif)$ { proxy_pass http://dong; }
6.镜像服务器 1 2 3 4 5 6 7 8 9 10 11 proxy_store on ;proxy_store_access user:rw group:rw all:rw proxy_temp_path 缓存目录;if ( !-e $request_filename ) { proxy_pass http://.....; }
整体配置如下
1 2 3 4 5 6 7 8 9 10 11 location / { expires 3d ; proxy_set_header Accept-Encoding '' ; root /home/mpeg/nginx; proxy_store on ; proxy_store_access user:rw group:rw all:rw; proxy_temp_path /home/mpeg/nginx; if ( !-e $request_filename ) { proxy_pass http://192.168.0.1; } }
7.热备部署 双主模式 用Nginx做负载均衡,作为架构的最前端或中间层,随着日益增长的访问量,需要给负载均衡做高可用架构,利用keepalived解决单点风险,一旦Nginx宕机能快速切换到备份服务器
keepalived 配置Keepalived高可用
1 cp /etc/keepalived/keepalived.conf keepalived.conf.bak
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 global_defs { vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance_VI_1 { state MASTER interface enp0s8 virtual_router_id 50 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168 .56.120 } }
nginx服务热备 1 2 3 4 upstream ... { server 127.0.0.1:8080 ; server 127.0.0.1:8081 backup; }
8.安全认证(通常不会面向用户) htppasswd 生成密码文件 1 yum install httpd-tools -y
htpasswd指令用来创建和更新用于基本认证的用户认证密码文件。htpasswd指令必须对密码文件有读写权限,否则会返回错误码。
htpasswd参数列表:
参数
参数说明
-b
密码直接写在命令行中,而非使用提示输入的方式
-c
创建密码文件,若文件存在,则覆盖文件重新写入
-n
不更新密码文件,将用户名密码进行标准输出
-m
使用MD5算法对密码进行处理
-d
使用CRYPT算法对密码进行处理
-s
使用SHA算法对密码进行处理
-p
不对密码进行加密处理,使用明文密码
-D
从密码文件中删除指定用户记录
htpasswd生成Nginx密码文件
1 htpasswd -bc /usr/local/nginx/conf/nginxpasswd Securitit 000000
若要在已有Nginx密码文件中追加用户,则无需-c参数
1 htpasswd -b /usr/local/nginx/conf/nginxpasswd www 111111
启用安全认证 1 2 3 4 5 6 location / { root html auth_basic "Restricted" auth_basic_user_file /usr/local/nginx/conf/nginxpasswd .... }
9. Http $\rightarrow$ Https 同时监听80和443端口,用if判断端口,给80端口的域名进行重写,做到访问80自动跳转到443
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 server{ listen 80 ; listen 443 ssl; server_name jenscc.me; ssl_certificate cert/jenscc.pem; ssl_certificate_key cert/jenscc.key; ssl_session_cache shared:SSL:1m ; 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 ; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" ; if ($server_port != '443' ) { rewrite ^/(.*)$ https://$host /$1 permanent ; } location / { root html; index index.html index.htm; } }