nginx之研究和实践

发布于 2020-09-10 · 本文总共 3548 字 · 阅读大约需要 11 分钟

Nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。

正向代理:客户端代理

反向代理:服务端代理

历史

2002年,俄罗斯程序员(Igor)发明;

2004年发布第一个公开发行版,之前都是作为俄罗斯访问量第二的网站Rambler的内部使用;

在此之前,C10K(Concurrency 10K,1万并发)问题还是困扰绝大多数web服务器的一个难题;

Nginx利用异步事件驱动的架构写成,是C10K问题的一个很好的答卷;

架构

master worker模式

master进程的作用:

1.读取并验证配置文件nginx.conf

2.管理worker进程;

worker进程的作用:

1.每一个worker进程维护一个线程,处理连接和请求;worker进程个数由配置文件决定;

特点

轻:很低的资源占用,甚至能在很多嵌入式设备上运行;

快:响应速度超快,几乎不会由于高并发影响响应速度;

活:配置灵活,广泛的模块支持;

热部署

配置nginx.conf之后,不需要重启nginx;nginx -s reload重新加载配置即可

nginx -t:检查配置;

原理:修改配置文件之后,重新生成新的worker进程,新的请求交给新的worker进程,老的worker把已有请求处理完之后

高并发

nginx采用了Linux的epoll模型,epoll模型基于事件驱动机制,可以监控多个事件是否准备完毕,如果数据准备好了,则放入epoll队列;

即异步非阻塞;

反向代理–proxy_pass

负载均衡–upstream

缓存

实践

nginx.conf示例说明

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

# 运行nginx服务器用户
user nginx;

# 允许生成的 worker process 数
worker_processes auto;

# 错误日志的存放路径
error_log /var/log/nginx/error.log;

# nginx 进程 PID 存放路径
pid /run/nginx.pid;

# 配置文件的引入
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

# 最大连接数
events {
    worker_connections 1024;
}

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 方式传输文件
    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;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    map $http_upgrade $connection_upgrade {                             
        default upgrade;                                                
        '' close;                                                       
    } 

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location /atlas/streaming {
            proxy_pass http://127.0.0.1:5002;

            proxy_read_timeout 300s;                                    
                                                                        
            proxy_set_header Host $host;                                     
            proxy_set_header X-Real-IP $remote_addr;                    
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                                                            
            proxy_http_version 1.1;                         
            proxy_set_header Upgrade $http_upgrade;         
            proxy_set_header Connection $connection_upgrade;
        }

        location /atlas/backend {
            proxy_pass http://127.0.0.1:5001;
         }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

websocket配置

nginx版本必须是1.3以上

# 根据客户端请求中的$http_upgrade的值创建新的$connection_upgrade
# 默认会upgrade,为空则变成close
map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
}

# 正向代理;监听websocket
upstream websocket {
    #ip_hash;

    # 转发到服务器上相应的ws端口
    server localhost:3344;
}

server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  _;
    root         /usr/share/nginx/html;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location /atlas/streaming {

        # 转发到目的地址
        proxy_pass http://127.0.0.1:5002;

        # nginx会等待多长时间来获得请求的响应。 这个时间不是获得整个response的时间,而是两次reading操作的时间。
        proxy_read_timeout 300s;    

        # 
        proxy_send_timeout 300s;                                
                                                                    
        proxy_set_header Host $host;                                     
        proxy_set_header X-Real-IP $remote_addr;                    
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # 升级http1.1到websocket                          
        proxy_http_version 1.1;                         
        proxy_set_header Upgrade $http_upgrade;         
        proxy_set_header Connection $connection_upgrade;
    }


    }
}

注释

sendfile

sendfile是Linux2.0+以后推出的一个系统调用;

传统的网络传输过程:

read(file, buf, len);

write(socket, buf, len);

硬盘—-kernel buffer—-user buffer—-kernel socket buffer—-协议栈

sendfile网络传输:

sendfile(socket, file, len);

硬盘—-kernel buffer—-协议栈

在nginx配置文件里打开sendfile on能提高web server的性能;

refs

http://nginx.org/en/docs/

https://juejin.im/post/6844903944267759624

https://zhuanlan.zhihu.com/p/34943332




本博客所有文章采用的授权方式为 自由转载-非商用-非衍生-保持署名 ,转载请务必注明出处,谢谢。
声明:
本博客欢迎转发,但请保留原作者信息!
博客地址:邱文奇(qiuwenqi)的博客;
内容系本人学习、研究和总结,如有雷同,实属荣幸!
阅读次数:

文章评论

comments powered by Disqus


章节列表