nginx之研究和实践
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