nginx
网络IO模型
同步 (关注的是消息通知机制)
nginx用户进程发指令给内核,内核需要获取一些资源返回给nginx,nginx需要等待内核返回消息,啥也干不了
异步
nginx用户进程发指令给内核,内核需要获取一些资源返回给nginx,内核会主动通知运行状态
阻塞 (关注的是nginx在等待内核通知之前所处的状态)
在内核返回结果之前,nginx被挂起停用
非阻塞
在内核返回结果的过程中,nginx可以去处理别的请求,直到内核通知去处理
同步阻塞
nginx下发请求后,一直等待
同步非阻塞
下发请求后,可以去处理别的情况,还是不是去看状态
异步阻塞
下发请求后,还是在旁边等着,内核会主动通知
异步非阻塞
下发请求后,可以去处理别的请求,内核会主动通知处理结果
nginx
就是一个web服务器
nginx优势
1.高性能,近w个连接请求时,他的响应要比其他的web要快。
2.高扩展性:nginx功能模块化。官方提供了很多的优秀模块。
3.高可靠性:9999 99999 (宕机时间)
4.热部署:不停止服务的情况下进行升级。
5.互联网公司都选择Nginx 代理、缓存、负载均衡、静态资源处理、动静分离、LNMP、LNMT、LNMG 架构。
nginx应用场景
web服务
负载均衡
代理缓存
安全服务 Https Lua
动静分离
静态资源服务
nginx基本组件
nginx二进制可执行文件 nginx的主体构成
nginx.conf配置文件 主要用来控制软件的行为
nginx access 日志 分析用户访问相关数据
nginx error 日志 用来分析运行过程中的错误
nginx配置文件
cat /etc/nginx/nginx.conf
全局配置
user nginx; (nginx进程是哪个用户来运行)
worker_processes 1; (启动了多少个work进程)
error_log /var/log/nginx/error.log warn; (错误日志的存放位置)
pid /var/run/nginx.pid; (每个进程运行起来的都会存在一个pid文件,里面存放的是该进程的ID)
事件驱动模型
events {
worker_connections 1024; (worker接收的连接数)
}
http模型
http {
include /etc/nginx/mime.types;
default_type application/octet-stream; (当nignx无法识别一个文件,默认已访问就下载)
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; (nginx操作日志)
sendfile on;
#tcp_nopush on;
keepalive_timeout 65; (长链接)
#gzip on;
include /etc/nginx/conf.d/*.conf; (包含所有.conf的文件)
}
cat /etc/nginx/conf.d/default.conf
server { (serve表示配置网站,每一个{}代表一个网站,简称虚拟主机)
listen 80; (监听端口)
server_name localhost; (网站的域名)
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / { (控制网站访问的路径)
root /usr/share/nginx/html; (定义网站源代码的存放位置)
index index.html index.htm; (默认访问哪个文件作为默认返回页)
}
包含关系
http {
server {
location {
}
}
}
nginx中的http、server、 location之间的关系是?
http:主要用来解决用户的请求和响应。
server:主要用来响应具体的某一个网站。
location:用于匹配网站的uri路径。
在本地自己做一个游戏网页
vim /etc/nginx/conf.d/文件名.conf
server{
listen 80;
server_name game.sang.com;
location / {
root /code;
index index.html;
}
}
}
创建 code目录
把代码包上传到code目录下
nginx -t 检查语法
windows电脑 点击C盘/Windows/system32/drives/etc/hosts
把 IP地址 域名 (10.0.0.7 game.sang.com 写上保存)
重启 systemctl restart nginx
nginx访问网站的原理(详细过程)
第一步:浏览器请求 game.oldxu.com
第二步:浏览会将请求的 game.oldxu.com --> http://game.oldxu.com/
第三步:浏览器对 域名进行解析 DNS解析 ( 我们域名是假的,所以,我们配置 hosts 劫持 )
第四步:浏览器通过随机端口,像服务端 80 端口建立TCP连接
第五步:浏览器发起HTTP的请求
第六步:请求被80端口对应的Nginx应用所接受,会交给http层,发现请求的域名是 game.oldxu.com
第七步:接下来检查所有配文件,看是否有配置文件 满足用户请求的域名。 server_name
第八步:满足域名匹配之后,检查用户 请求的路径, / 就会被location / 所匹配
第九步:返回结果,/code下面的index.html 给用户
第十步:nginx应用程序像内核发送请求,获取磁盘中的某个文件,磁盘将数据拷贝至内核的缓存区,然后在 拷贝到nginx应用进程的缓存区
第十一步:nginx应用进程封装数据报文,回传给客户端浏览器。
DAY 02
第一部分 基于多个IP实现方式 (很少)
[root@web01 ~]# cat /etc/nginx/conf.d/ip.conf
server {
listen 10.0.0.7:80;
location / {
root /ip1;
index index.html; (返回 hello 10.7)
}
}
server {
listen 172.16.1.7:80;
location / {
root /ip2;
index index.html; (返回 hello 172.7)
}
}
基于不同的端口方式 (测试)
[root@web01 ~]# cat /etc/nginx/conf.d/port.conf
server {
listen 8081;
location / {
root /port1;
index index.html; (8081)
}
}
server {
listen 8082;
location / {
root /port2;
index index.html; (8082)
}
}
基于不同的域名方式 (生产,实际生产都是一个域名对应一个文件,这样能够清晰找到对应的配置))
[root@web01 ~]# cat /etc/nginx/conf.d/all.oldxu.com.conf
server {
listen 80;
server_name docs.oldxu.com;
location / {
root /docs;
index index.html;
}
}
server {
listen 80;
server_name test.oldxu.com;
location / {
root /test;
index index.html;
}
}
记得配置域名解析(我们由于是假的域名,所以配置DNS劫持即可)
nginx模块
第二部分 阿里云镜像源站点搭建操作
[root@web01 mirror]# cat /etc/nginx/conf.d/mirror.oldxu.com.conf
server {
listen 80;
server_name mirror.oldxu.com;
charset utf-8;
root /mirror;
#跳转主页
location / {
index index.html;
}
#提供yum源的仓库
location /repo {
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}
}
同步源至本地
[root@web01 mirror]# rsync -avz rsync://rsync.mirrors.ustc.edu.cn/repo/centos/ /mirror/repo/
第三部分 访问控制
基于来源IP实现访问控制
allow 10.0.0.7/24; (允许10.0.0.7访问)
deny 10.0.0.7/24; (禁止10.0.0.7访问)
默认情况从第一条规则开始匹配
如果匹配成功,检查规则是允许还是拒绝,但不在继续匹配下面的内容
如果匹配不成功,则继续往下匹配
基于用户名和密码的访问控制
准备一个密码文件 touch /etc/nginx/auth_pass
yum install httpd-tools -y
htpasswd -cb /etc/nginx/auth_pass sang 123456
server {
listen 80;
server_name mirror.oldxu.com;
charset utf-8;
root /mirror;
location / {
index index.html;
}
location /repo {
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
auth_basic "hello";
auth_basic_user_file "/etc/nginx/auth_pass";
}
}
第四部分 nginx限流限速
[root@web01 mirror]# vim /etc/nginx/conf.d/limit.sang.com.conf
请求限制:定义了一个10m内存空间,名称叫req_one 限制的速率是 每S 1个请求,针对的来源的IP地址
limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;
连接限制: 定义了一个10m内存空间,名称叫conn_od,针对的是来源的IP
limit_conn_zone $binary_remote_addr zone=conn_od:10m;
server {
listen 80;
server_name limit.sang.com;
charset utf-8; (避免出现乱码)
limit_req zone=req_one burst=5 nodelay; (5个请求限制)
limit_conn conn_od 2; (2个连接限制)
limit_rate_after 100m; (先让其最快速下载100m,然后开始限速)
limit_rate 200k; (限速)
location / {
root /limit; (如果没有 需要自己建目录)
index index.html;
}
error_page 503 @err; (如果同时下载超过2个视频,会出现503错误,那么我们把503改成提示 "请联系oldxu进行会员充值"。)
location @err { (@err是一个特殊的重定向)
default_type text/html;
return 200 '请联系oldxu充值,联系qq:552408925';
}
}
注:在server层上面写
下载限制 使用nginx ngx_http_core_module
请求限制 使用nginx ngx_http_limit_req_module
连接限制 使用nginx ngx_http_limit_conn_module
总结 综合案例
[root@web01 mirror]# vim /etc/nginx/conf.d/mirror.oldxu.com.conf
limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;
limit_conn_zone $binary_remote_addr zone=conn_od:10m;
server {
listen 80;
server_name mirror.sang.com;
charset utf-8;
root /mirror;
limit_req zone=req_one burst=5 nodelay; (5个请求限制)
limit_conn conn_od 2; (2个连接限制)
limit_rate_after 100m; (先让其最快速下载100m,然后开始限速)
limit_rate 200k; (限速)
location / {
index index.html; (a标签 跳转主页)
}
location /repo { (提供yum源的仓库)
autoindex on; (以目录结构显示)
autoindex_exact_size off;
autoindex_localtime on;
auth_basic "hello";
auth_basic_user_file "/etc/nginx/auth_pass"; (登录网站的时候需要用户名密码)
}
error_page 503 @err; (如果同时下载超过2个视频,会出现503错误,那么我们把503改成提示 "请联系oldxu进行会员充值"。)
location @err { (@err是一个特殊的重定向)
default_type text/html;
return 200 '请联系oldxu充值,联系qq:552408925';
}
}
stub_status模块
location /status {
stub_status
}
访问game.sang.com/status
Active connections: 2
server accepts handled requests
3 3 17
Reading: 0 Writing: 1 Waiting: 1
状态 含义
Active connections 当前活跃连接数,包括Waiting等待连接数。
accepts 已接收的总TCP连接数量。
handled 已处理的TCP连接数量。
requests 当前总http请求数量。
Reading 当前读取的请求头数量。
Writing 当前响应的请求头数量。
Waiting 当前等待请求的空闲客户端连接数
Location匹配
location匹配规则
匹配符 匹配规则 优先级
= 精确匹配 1 必须是百分百匹配才行
^~ 以某个字符串开头 2
~ 区分大小写的正则匹配 3
~* 不区分大小写的正则匹配 4
/ 通用匹配,任何请求都会匹配到 5
The “/” request will match configuration A,
the “/index.html” request will match configuration B
the “/documents/document.html” request will match configuration C,
the “/images/1.gif” request will match configuration D,
the “/documents/1.jpg” request will match configuration E.
[root@web01 conf.d]# cat location2.oldxu.com.conf
server {
listen 80;
server_name location2.oldxu.com;
# 通用匹配,任何请求都会匹配到
location / {
root html;
index index.html;
}
# 精准匹配,必须请求的uri是/nginx_status
location = /nginx_status {
stub_status;
}
# 严格区分大小写,匹配以.php结尾的都走这个location
location ~ \.php$ {
default_type text/html;
return 200 'php访问成功';
}
# 严格区分大小写,匹配以.jsp结尾的都走这个location
location ~ \.jsp$ {
default_type text/html;
return 200 'jsp访问成功';
}
# 不区分大小写匹配,只要用户访问.jpg,gif,png,js,css 都走这条location
location ~* \.(jpg|gif|png|js|css)$ {
return 403;
}
# 不区分大小写匹配
location ~* \.(sql|bak|tgz|tar.gz|.git)$ {
deny all;
}
}
location @ 内部重定向
error_page 404 403 401 @err;
location @err {
default_type text/html;
return 200 '你可能是不小心走丢了。';
}
nginx 日志
log_format: 定义日志格式:
关键字 变量
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;
remote_user # 记录客户端用户名
time_iso8601 # 记录ISO8601标准格式下的本地时间
status # 记录请求状态码(用于定位错误信息)
bytes_sent # 发送给客户端的总字节数
http_referer # 记录从哪个页面链接访问过来的
http_x_forwarded_for #记录客户端IP地址
request_time # 请求花费的时间,单位为秒,精度毫秒
access_log 可以定义在 http、server、location?
每一个server都会定义一个access_log。为了区分网站的访问记录
http {
access_log /var/log/nginx/access.log main;
server {
# access_log /var/log/nginx/log.oldxu.com.log main;
}
#如果某个网站不想记录日志,则可以通过如下两种方式去实现?
server {
access_log off;
#access_log /dev/null;
}
}
error_log:错误日志
error_log /var/log/nginx/error.log warn; #几乎是所有Nginx统一的一个位置。(全局,作用于所有的网站)