nginx常见问题总结

1.nginx是什么

nginx是一款免费开源的高性能HTTP服务器及反向代理服务器产品。

2.nginx的功能有哪些

  • 反向代理
  • 负载均衡
  • 静态文件服务器
  • web缓存
  • 动静分离
  • 邮件服务器

3.nginx的工作模式

  • single:单进程模式,不适合生产。
  • master-worker:一个master,多个worker进程。master进程负责读取nginx配置文件,管理worker进程,每一个worker进程都维护一个线程(避免线程切换),处理连接和请求。由配置文件中的worker_processes N/auto定义。一般是cpu核数的2倍。

4.nginx如何做到热启动

热启动就是修改配置文件后,不需要stop Nginx,不需要中断请求,就能让配置文件生效。nginx采取的方法如下:

修改配置文件nginx.conf后,重新生成新的worker进程,并且会以新的配置进行处理,新的请求都必须交给新的worker进程,至于老worker进程,等把那些以前的请求处理完毕,kill掉即可。

nginx -t
nginx -s reload

5.nginx如何做到高并发下的高效处理

首先可以修改worker进程数量,其次nginx采用了Linux的epoll模型,epoll模型基于事件驱动机制,它可以监控多个事件是否准备完毕,如果OK,那么放入epoll队列中,这个过程是异步的。worker只需要从epoll队列循环处理即可。

6.nginx的事件驱动模型

select:

复杂度是O(n)。

首先,创建所关注事件的描述符fd集合,包括读,写,异常。
其次,调用底层提供的select()函数,等待事件发生。
然后,轮询所有fd集合中的每一个fd,检查是否有相应的事件发生,如果有,就进行处理。

缺点:

  • 当fd很多时,轮询时间很长,效率差。
  • 单个进程可监视的fd数量被限制,即能监听端口的大小有限。
  • 需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大。

poll:

复杂度是O(n)。

poll与select的基本工作方式是相同的,都是现创建一个fd集合,再去等待这些事件发生,然后再轮询fd集合,检查有没有事件发生,如果有,就进行处理。但是它没有最大连接数的限制,因为poll是基于链表来存储的。

缺点:

  • 大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。
  • poll有一个特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd。

水平触发:只要满足条件就触发一个事件。
边缘触发:每当状态变化时,触发一个事件。

epoll:

复杂度是O(1)。

首先,epoll库通过相关调用通知内核创建一个fd集合。
然后,给这些fd设置所关注的事件,并把它添加到内核的事件列表中去。
epoll库就开始等待内核通知fd。某一事件发生后,内核将发生事件的fd列表上报给epoll库。得到事件列表的epoll库,就可以进行事件处理了。

优点:

  • 没有最大并发连接的限制。(1G的内存上能监听约10万个端口)
  • 效率提升,不是轮询的方式,不会随着FD数目的增加效率下降。只关注活跃的连接,与总连接数无关。
  • 内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销。

kqueue:

是用于支持BSD系列平台的高效事件驱动模型。

resig:

Real-Time Signal,实时信号。
使用rtsig模型时,工作进程会通过系统内核建立一个rtsig队列用于存放标记事件发生(在Nginx服务器应用中特指客户端请求发生)的信号。每个事件发生时,系统内核就会产生一个信号存放到rtsig队列中等待工作进程的处理。

当rtsig队列发生溢出时,Nginx将暂时停止使用rtsig模型,而调用poll库处理未处理的事件,直到rgsit信号队列全部清空,然后再次启动rtsig模型,以防止新的溢出发生。

/dev/poll:

在下面的平台中使用;Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+, and Tru64 UNIX 5.1A+

eventport:

在Solaris 10+的平台中使用。

7.nginx挂了怎么办

keepalived+nginx实现高可用。请求发送到keepalived的vip上,vip再转发到nginx上。keepalived通过健康检查脚本检测nginx的状态,异常就进行切换。

8.什么是nginx的惊群现象

一个连接到来,多个睡眠的进程被同时叫醒,但只有一个进程能获得连接,这样会影响系统性能。
解决方式:设置连接序列化,默认为on

events {
    accept_mutex on;
}

9.nginx怎么实现http跳转到https

使用301跳转

server {
    listen      80:80;
    listen      [::]:80;
    server_name .wghdr.top;
    return      301 https://wghdr.top$request_uri;
}

使用rewrite

server {
    listen 80;
    server_name .wghdr.top;;
    rewrite ^(.*)$ https://wghdr.top;$1 permanent;
}

10.nginx如何配置静态资源映射

location /img/ {
   alias /home/img/;
   autoindex on;
}

11.nginx如何配置跨域

#允许跨域请求的域,* 代表所有
add_header 'Access-Control-Allow-Origin' *;
#允许请求的header
add_header 'Access-Control-Allow-Headers' *;
#允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
#允许请求的方法,比如 GET,POST,PUT,DELETE
add_header 'Access-Control-Allow-Methods' *;

12.nginx如何配置限制连接

location / {
    root   /var/www/test;
    index  index.html index.htm;
    limit_conn addr 5; #是限制每个IP只能发起5个连接
}

13.nginx如何配置限制下载速度

location /download { 
       limit_rate_after 10m; 
       limit_rate 128k; 
 }

14.nginx如何限制IP访问

# 允许部分ip访问
allow 192.168.1.1;
allow 172.16.1.1;
 # 禁止其余ip访问
deny all;

15.nginx如何配置HTTP Basic认证

location /
{
    auth_basic "网站名称";
    auth_basic_user_file conf.d/passwd;
    autoindex on;
}

16.nginx如何配置超时时间

proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)

17.nginx请求体过大怎么办

wordpress更新插件或版本时,可能会报错:413 Request Entity Too Large,这个就是请求体过大,调整下面的值即可:

client_max_body_size 200m;

18.nginx如何配置负载均衡

nginx有6种负载均衡策略。轮询、权重、ip_hash、最少连接、fair、url_hash。

轮询

upstream  backup-server {
   server    192.168.1.1:8080; 
   server    192.168.1.2:8080;
}

权重

upstream  backup-server {
   server    192.168.1.1:8080 weigh=10; 
   server    192.168.1.2:8080 weigh=90;
}

ip-hash

upstream  backup-server {
   ip_hash;
   server    192.168.1.1:8080 weigh=10; 
   server    192.168.1.2:8080 weigh=90;
}

注意:内网使用ip-hash模式会有问题。
因为该模式采用的是客户端ip地址的前三个八位字节用作哈希密钥,内网环境下,一般都是ip地址的最后一位不同,这会导致不同client的请求都发送到了同一个server。

最少连接

upstream  backup-server {
   least_conn;
   server    192.168.1.1:8080 weigh=10; 
   server    192.168.1.2:8080 weigh=90;
}

fair

upstream  backup-server {
   fair;
   server    192.168.1.1:8080; 
   server    192.168.1.2:8080;
}

url_hash

upstream  backup-server {
   hash $request_uri;
   server    192.168.1.1:8080 weigh=10; 
   server    192.168.1.2:8080 weigh=90;
}

19.nginx安全策略

19.1 隐藏nginx版本信息

server_tokens off;

19.2 限制HTTP请求方式

只允许GET与POST:

if ($request_method !~ ^(GET|POST)$ ) {
    return 405;
}

19.3 自定义Nginx缓存

proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传

19.4 过滤非法USER-AGENT(UA)

if ($http_user_agent ~* "java|python|perl|ruby|curl|bash|echo|uname|base64|decode|md5sum|select|concat|httprequest|httpclient|nmap|scan" ) {
    return 403;
}

19.5 过滤不支持URL

location ~* \.(bak|save|sh|sql|mdb|svn|git|old)$ {
    rewrite ^/(.*)$  $host  permanent;
}

19.6 强制域名访问(必须开启SSL保护)

if ( $host !~* 'wghdr.top' ) {
    return 403;
}

19.7 用户降低权限

user nginx www;

19.8 禁止目录浏览

autoindex off;

19.9 开启黑名单

参考上面第14条

19.10 开启http认证

参考上面第15条

20.nginx如何优化

nginx 配置文件优化:

20.1 调整worker进程数

# 全局块
worker_processes 4;

20.2 为每个进程分配CPU

# 全局块
worker_cpu_affinity 0001 0010 0100 1000

20.3 调整一个进程能打开的fd数量

理论值应该是最多打开文件数ulimit -n与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。

# 全局块
worker_rlimit_nofile 65535;

20.4 使用epoll

events {
    use epoll;
}

20.5 调整每个进程的最大连接数

events {
    worker_connections 65535;
}

20.6 指定keepalive超时时间

# http和server块
keepalive_timeout 60;

20.7 设置客户端请求头部的缓冲区大小

# http块,设置为系统分页大小
client_header_buffer_size 4k;

查看系统分页大小

getconf PAGESIZE

file

20.8 内核优化

  • net.ipv4.tcp_max_tw_buckets = 6000
    timewait 的数量,默认是180000。
  • net.ipv4.ip_local_port_range = 1024 65000
    允许系统打开的端口范围。
  • net.ipv4.tcp_tw_recycle = 1
    启用timewait 快速回收。
  • net.ipv4.tcp_tw_reuse = 1
    开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接。
  • net.ipv4.tcp_syncookies = 1
    开启SYN Cookies,当出现SYN 等待队列溢出时,启用cookies 来处理。
  • net.core.somaxconn = 262144
    web 应用中listen 函数的backlog 默认会给我们内核参数的net.core.somaxconn 限制到128,而nginx 定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。
  • net.core.netdev_max_backlog = 262144
    每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
  • net.ipv4.tcp_max_orphans = 262144
    系统中最多有多少个TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS 攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。
  • net.ipv4.tcp_max_syn_backlog = 262144
    记录那些尚未收到客户端确认信息的连接请求的最大值。
  • net.ipv4.tcp_timestamps = 0
    时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。
  • net.ipv4.tcp_synack_retries = 1
    为了打开对端的连接,内核需要发送一个SYN 并附带一个回应前面一个SYN 的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。
  • net.ipv4.tcp_syn_retries = 1
    在内核放弃建立连接之前发送SYN 包的数量。
  • net.ipv4.tcp_keepalive_time = 30
    当keepalive 起用的时候,TCP 发送keepalive 消息的频度。缺省是2 小时。

21.nginx中的信号

master进程可以控制的信号如下:

  • TERM, INT 快速关闭
  • QUIT 从容关闭
  • HUP 重载配置,用新的配置开始新的工作进程,从容关闭旧的工作进程
  • USR1 重新打开日志文件
  • USR2 平滑升级可执行程序
  • WINCH 从容关闭工作进程

快速关闭nginx

kill -TERM nginxpid
kill -TERM `cat /tmp/nginx.pid`

从容停止nginx

kill -QUIT nginxpid

强制停止nginx

kill -9 nginxpid

重载nginx配置

nginx -t
nginx -s reload
kill -HUP nginxpid

平滑升级nginx

当nginx版本升级或者重新编译时,可以不中断服务。

  • 首先,使用新的nginx程序替换旧的(最好做好备份);
  • 然后,发送 USR2 (kill -USR2 nginxpid)信号给master进程。master进程将重命名它的 .pid 文件为 .oldbin (比如:/tmp/nginx.pid.oldbin);
  • 然后执行新的可执行程序,依次启动新的master进程和新的worker进程。
  • 这时,两个nginx实例会同时运行,一起处理输入的请求。要逐步停止旧的实例,你必须发送 WINCH 信号给旧的master进程,然后,它的工作进程就将开始从容关闭:
  • 一段时间后,旧的worker进程处理了所有已连接的请求后退出,就仅由新的工作进程来处理输入的请求了:
  • 发送QUIT信号给旧的master进程,从容退出。
kill -USER2 oldpid
kill -WINCH oldpid
kill -QUIT oldpid

回滚nginx

上面升级的最后一步前,存在2个nginx master进程,这时可以:

  • 发送 HUP 信号给旧的master进程 – 它将在不重载配置文件的情况下启动它的worker进程
  • 发送 QUIT 信号给新的master进程,要求其从容关闭其worker进程
  • 发送 TERM 信号给新的master进程,迫使其退出
  • 如果因为某些原因新的worker进程不能退出,向其发送 KILL 信号
  • 新的master进程退出后,旧的master进程会由移除 .oldbin 前缀,恢复为之前的 .pid 文件,这样,一切就都恢复到升级之前了。
kill -USER2 oldpid
kill -WINCH oldpid
kill -HUP oldpid
kill -QUIT newpid
kill -TERM newpid / kill -9 newpid
0 0 投票数
文章评分
订阅评论
提醒
guest

0 评论
内联反馈
查看所有评论

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部
0
希望看到您的想法,请您发表评论x