web应用服务器-Nginx笔记
- 第⼀部分:Nginx基础回顾(Nginx是什么?能做什么事情(应⽤在什么场合)?常⽤命令是什么?)
- 第⼆部分:Nginx核⼼配置⽂件解读
- 第三部分:Nginx应⽤场景之反向代理
- 第四部分:Nginx应⽤场景之负载均衡
- 第五部分:Nginx应⽤场景之动静分离
- 第六部分:Nginx底层进程机制剖析
第一部分 Ningx基础
Nginx 是⼀个⾼性能的HTTP和反向代理web服务器,核⼼特点是占有内存少,并发能⼒强
1.1 Nginx应用场景
-
Http服务器(Web服务器)
性能⾮常⾼,⾮常注重效率,能够经受⾼负载的考验。 ⽀持50000个并发连接数,不仅如此,CPU和内存的占⽤也⾮常的低,10000个没有活动的连 接才占⽤2.5M的内存。
-
反向代理服务器
-
正向代理
在浏览器中配置代理服务器的相关信息,通过代理服务器访问⽬标⽹站,代理服务器收 到⽬标⽹站的响应之后,会把响应信息返回给我们⾃⼰的浏览器客
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lc4idt3H-1590573880468)( https://typora-hb.oss-cn-shanghai.aliyuncs.com/typera/image-20200527162320816.png)]户端
-
反向代理
浏览器客户端发送请求到反向代理服务器(⽐如Nginx),由反向代理服务器选择原始 服务器提供服务获取结果响应,最终再返回给客户端浏览器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HPOmPaGQ-1590573880469)(/Users/hbsky/Library/Application Support/typora-user-images/image-20200527162331876.png)]
-
-
负载均衡服务器
负载均衡,当⼀个请求到来的时候(结合上图),Nginx反向代理服务器根据请求去找到⼀个 原始服务器来处理当前请求,那么这叫做反向代理。那么,如果⽬标服务器有多台(⽐如上 图中的tomcat1,tomcat2,tomcat3…),找哪⼀个⽬标服务器来处理当前请求呢,这样⼀ 个寻找确定的过程就叫做负载均衡。
⽣活中也有很多这样的例⼦,⽐如,我们去银⾏,可以处理业务的窗⼝有多个,那么我们会 被分配到哪个窗⼝呢到底,这样的⼀个过程就叫做负载均衡。
负载均衡就是为了解决⾼负载的问题
-
动静分离
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IxMBqQIc-1590573880470)( https://typora-hb.oss-cn-shanghai.aliyuncs.com/typera/image-20200527162459663.png)]
1.2 Nginx的安装
docker安装
-
运行一个nginx,方便获取配置文件
docker run -p 8080:80 -d --name nginx_web -it nginx
-
创建一个nginx文件夹并进入
mkdir nginx cd nginx
-
从容器nginx_web获取配置文件到nginx目录
#复制配置文件 docker cp nginx_web:/etc/nginx/ ./conf #复制日志 docker cp nginx_web:/var/log/nginx/ ./log #复制html文件 docker cp nginx_web:/usr/share/nginx/html/ ./html #删除容器 docker rm -f nginx_web
-
启动nginx容器
docker run \ -p 8088:80 \ --name nginx \ --privileged=true \ --restart=always \ -v /etc/localtime:/etc/localtime \ -v $PWD/log/:/var/log/nginx \ -v $PWD/conf:/etc/nginx \ -v $PWD/html/:/usr/share/nginx/html \ -d nginx
注意:我们这里没有设置–net=host ,所有监听的端口是80,而这个端口是容器里面的端口,对外端口我们映射为8088,所以不要去配置文件里修改监听端口,还有nginx.conf配置文件,与软件的配置文件有些不同
-
重启配置文件脚本
docker exec -it nginx /usr/sbin/nginx -s reload
第二部分 配置文件详细
Nginx的核⼼配置⽂件conf/nginx.conf包含三块内容:全局块、events块、http块
2.1 全局块
从配置⽂件开始到events块之间的内容,此处的配置影响nginx服务器整体的运⾏,⽐如worker进 程的数量、错误⽇志的位置等
#=============================================start 全局块============================================================================
#运行用户
#user nobody;
#worker进程数量,通常设置为cpu核数相等
worker_processes 1;
#全局错误文件
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid位置
#pid logs/nginx.pid;
#=============================================end 全局块=============================================================================
2.2 events块
events块主要影响nginx服务器与⽤户的⽹络连接,⽐如worker_connections 1024,标识每个 workderprocess⽀持的最⼤连接数为1024
#=============================================start events块========================================================================
events {
# 单个worker进程最大并发连接数
worker_connections 1024;
}
#=============================================end events块==========================================================================
2.3 http块
http块是配置最频繁的部分,虚拟主机的配置,监听端⼝的配置,请求转发、反向代理、负载均衡 等
#=============================================start http块==================================================================
http {
#引入mime类型的定义文件
include mime.types;
default_type application/octet-stream;
#设置日志格式
#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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#连接超时时间
#keepalive_timeout 0;
keepalive_timeout 65;
#开启gzip压缩
#gzip on;
server {
#监听端口
listen 80;
#定义使用的localhost访问
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#默认请求
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
#错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
#反向代理
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
#=============================================end http块=================================================================
2.4 最终
#=============================================start 全局块==================================================================
#运行用户
#user nobody;
#worker进程数量,通常设置为cpu核数相等
worker_processes 1;
#全局错误文件
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid位置
#pid logs/nginx.pid;
#=============================================end 全局块=====================================================================
#=============================================start events块================================================================
events {
# 单个worker进程最大并发连接数
worker_connections 1024;
}
#=============================================end events块==================================================================
#=============================================start http块==================================================================
http {
#引入mime类型的定义文件
include mime.types;
default_type application/octet-stream;
#设置日志格式
#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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#连接超时时间
#keepalive_timeout 0;
keepalive_timeout 65;
#开启gzip压缩
#gzip on;
server {
#监听端口
listen 80;
#定义使用的localhost访问
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#默认请求
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
#错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
#反向代理
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
#=============================================end http块=================================================================
第三部分 Nginx应⽤场景之反向代理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rn3bCyih-1590573880472)( https://typora-hb.oss-cn-shanghai.aliyuncs.com/typera/image-20200527174228978.png)]
3.1 配置文件
#反向代理
location /demo/ {
proxy_pass http://127.0.0.1/;
}
3.2 location 语法
location [=|~|~*|^~] /uri/ { … }
在nginx配置⽂件中,location主要有这⼏种形式:
-
正则匹配 location ~ /lagou { }
-
不区分⼤⼩写的正则匹配 location ~* /lagou { }
-
匹配路径的前缀 location ^~ /lagou { }
-
精确匹配 location = /lagou { }
-
普通路径前缀匹配 location /lagou { }
优先级 4>3>2>1>5
3.3 proxy_pass有无“/”的四种区别探究
访问地址都是以:http://www.wandouduoduo.com/wddd/index.html 为例。请求都匹配目录/wddd/
第一种:加"/"
location /wddd/ {
proxy_pass http://127.0.0.1:8080/;
}
测试结果,请求被代理跳转到:http://127.0.0.1:8080/index.html
第二种: 不加"/"
location /wddd/ {
proxy_pass http://127.0.0.1:8080;
}
测试结果,请求被代理跳转到:http://127.0.0.1:8080/wddd/index.html
第三种: 增加目录加"/"
location /wddd/ {
proxy_pass http://127.0.0.1:8080/sun/;
}
测试结果,请求被代理跳转到:http://127.0.0.1:8080/sun/index.html
第四种:增加目录不加"/"
location /wddd/ {
proxy_pass http://127.0.0.1:8080/sun;
}
测试结果,请求被代理跳转到:http://127.0.0.1:8080/sunindex.html
总结
location目录后加"/",只能匹配目录,不加“/”不仅可以匹配目录还对目录进行模糊匹配。而proxy_pass无论加不加“/”,代理跳转地址都直接拼接
第四部分 Nginx应⽤场景之负载均衡
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KOaYg5Ys-1590573880473)( https://typora-hb.oss-cn-shanghai.aliyuncs.com/typera/image-20200527174636815.png)]
4.1 Nginx负载均衡策略
1.轮询
默认策略,每个请求按时间顺序逐⼀分配到不同的服务器,如果某⼀个服务器下线,能⾃动剔除
upstream lagouServer{
server 111.229.248.243:8080;
server 111.229.248.243:8082;
}
server {
location /abc {
proxy_pass http://lagouServer/;
}
}
2.weight
weight代表权重,默认每⼀个负载的服务器都为1,权重越⾼那么被分配的请求越多(⽤于服务器 性能不均衡的场景)
upstream lagouServer{
server 111.229.248.243:8080 weight=1;
server 111.229.248.243:8082 weight=2;
}
3.ip_hash
每个请求按照ip的hash结果分配,每⼀个客户端的请求会固定分配到同⼀个⽬标服务器处理,可 以解决session问题
upstream lagouServer{
ip_hash;
server 111.229.248.243:8080;
server 111.229.248.243:8082;
}
第五部分 Nginx应⽤场景之动静分离
动静分离就是讲动态资源和静态资源的请求处理分配到不同的服务器上,⽐较经典的组合就是 Nginx+Tomcat架构(Nginx处理静态资源请求,Tomcat处理动态资源请求),那么其实之前的讲解 中,Nginx反向代理⽬标服务器Tomcat,我们能看到⽬标服务器ROOT项⽬的index.jsp,这本身就是 Tomcat在处理动态资源请求了。
所以,我们只需要配置静态资源访问即可。
location /static/ {
root 文件路径
}
第六部分 Nginx底层进程机制剖析
Nginx启动后,以daemon多进程⽅式在后台运⾏,包括⼀个Master进程和多个Worker进程,Master 进程是领导,是⽼⼤,Worker进程是⼲活的⼩弟。
6.1 master进程
主要是管理worker进程,⽐如:
-
接收外界信号向各worker进程发送信号(./nginx -s reload)
-
监控worker进程的运⾏状态,当worker进程异常退出后Master进程会⾃动重新启动新的 worker进程等
6.2 worker进程
worker进程具体处理⽹络请求。多个worker进程之间是对等的,他们同等竞争来⾃客户端的请 求,各进程互相之间是独⽴的。⼀个请求,只可能在⼀个worker进程中处理,⼀个worker进程, 不可能处理其它进程的请求。worker进程的个数是可以设置的,⼀般设置与机器cpu核数⼀致。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VCRVc4ZO-1590573880474)( https://typora-hb.oss-cn-shanghai.aliyuncs.com/typera/image-20200527175251709.png)]
6.3 ./nginx -s reload 来说明nginx信号处理这部分
- master进程对配置⽂件进⾏语法检查
- 尝试配置(⽐如修改了监听端⼝,那就尝试分配新的监听端⼝)
- 尝试成功则使⽤新的配置,新建worker进程
- 新建成功,给旧的worker进程发送关闭消息
- 旧的worker进程收到信号会继续服务,直到把当前进程接收到的请求处理完毕后关闭 所以reload之后worker进程pid是发⽣了变化的
6.4 worker进程处理请求部分的说明
例如,我们监听9003端⼝,⼀个请求到来时,如果有多个worker进程,那么每个worker进程都有 可能处理这个链接。
- master进程创建之后,会建⽴好需要监听的的socket,然后从master进程再fork出多个 worker进程。所以,所有worker进程的监听描述符listenfd在新连接到来时都变得可读。
- nginx使⽤互斥锁来保证只有⼀个workder进程能够处理请求,拿到互斥锁的那个进程注册 listenfd读事件,在读事件⾥调⽤accept接受该连接,然后解析、处理、返回客户端
6.5 nginx多进程模型好处
- 每个worker进程都是独⽴的,不需要加锁,节省开销
- 每个worker进程都是独⽴的,互不影响,⼀个异常结束,其他的照样能提供服务
- 多进程模型为reload热部署机制提供了⽀撑