ngnix基础知识

lxf2023-12-18 02:30:02

本文正在参加「」

nginx优势

  • 高并发高性能
  • 可扩展性好
  • 高可靠性
  • 热布署
  • 开源许可证

分类

  • 同步阻塞IO
  • 同步非阻塞IO
  • 异步阻塞IO(IO多路复用)

多个文件描述符的IO操作都能在一个线程里并发交替顺序完成,复用线程

  • 异步非阻塞IO

同步异步: 相对于用户和操作系统内核而言。

阻塞非阻塞: 相对于操作系统内核的操作文件而言。

事件模型

  • 目前支持I/O多路复用的系统调用有 select、poll和epoll
  • I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作
  • 但select、poll和epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的
事件模型描述
select单个进程能打开的最大连接数为1024,因为需要对所有的文件描述符进行线性遍历,所以文件描述符太多会导致性能下降。
poll和select基本一样,因为用链表存储文件描述符,没有最大连接数限制
epollepoll是在每个文件描述符上设置callback来实现,FD就绪后才会调用callback,活跃socket少的话性能高,socket活跃多的话性能低

安装nginx

rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm 

yum install -y nginx 

systemctl start nginx.service 

systemctl status nginx.service

访问当前云服务器的ip,如果出现welcom nginx页面表示启动成功。

如果没有启动成功,那么需要关闭防火墙。systemctl stop firewalld.service

配置文件

  • /etc/nginx/nginx.conf #主配置文件
  • /etc/nginx/conf.d/*.conf #包含conf.d目录下面的所有配置文件
  • /etc/nginx/conf.d/default.conf

nginx配置语法

# 使用#可以添加注释,使用$符号可以使用变量
# 配置文件由指令与指令块组成,指令块以{}将多条指令组织在一起
http {
# include语句允许把多个配置文件组合起来以提升可维护性    
    include       mime.types;
# 每条指令以;(分号)结尾,指令与参数之间以空格分隔
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
# 有些指令可以支持正则表达式        
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

http配置

  • /etc/nginx/nginx.conf
  • 一个HTTP下面可以配置多个server
user  nginx;   设置nginx服务的系统使用用户  
worker_processes  1;  工作进程数,一般和CPU数量相同 

error_log  /var/log/nginx/error.log warn;   nginx的错误日志  
pid        /var/run/nginx.pid;   nginx服务启动时的pid

events {
    worker_connections  1024;每个进程允许的最大连接数 10000
}

http {
    include       /etc/nginx/mime.types;//文件后缀和类型类型的对应关系
    default_type  application/octet-stream;//默认content-type

    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        on;//启用sendfile
    #tcp_nopush     on;//懒发送

    keepalive_timeout  65;//超时时间是65秒

    #gzip  on; # 启用gzip压缩

    include /etc/nginx/conf.d/*.conf;//包含的子配置文件
}

server

  • /etc/nginx/conf.d/default.conf
  • 一个server下面可以配置多个location
server {
    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;  //首页的索引文件
    }

    #error_page  404              /404.html;  //指定错误页面

    # redirect server error pages to the static page /50x.html
    # 把后台错误重定向到静态的50x.html页面
    error_page   500 502 503 504  /50x.html; 
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    # 代理PHP脚本到80端口上的apache服务器
    #location ~ .php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    # 把PHP脚本9000端口上监听的FastCGI服务
    #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
    # 不允许访问.htaccess文件
    #location ~ /.ht {
    #    deny  all;
    #}
}

nginx.conf文件解读

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
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"'; # 定义一个日志格式,名称叫main

    access_log  /var/log/nginx/access.log  main;

    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; # 默认的content-type

    # 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;

    server { # 每个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 / { # 匹配所有路径
        }

        error_page 404 /404.html; # 错误页面
            location = /40x.html {  # 当路径是/40x.html时的精确匹配。
        }

        error_page 500 502 503 504 /50x.html; # 把服务器端错误状态码重定向到50x.html
            location = /50x.html { # 当路径是/50x.html时的精确匹配。
        }
    }

跟踪访问日志

 tail -f /var/log/nginx/access.log

内置变量

ngx_http_log_module 

log_format

名称含义
$remote_addr客户端地址
$remote_user客户端用户名称
$time_local访问时间和时区
$request请求行
$statusHTTP请求状态
$body_bytes_sent发送给客户端文件内容大小

HTTP请求变量

  • 注意要把-转成下划线,比如User-Agent对应于$http_user_agent
名称含义例子
arg_PARAMETER请求参数$arg_name
http_HEADER请求头httprefererhttp_referer http_host httpuseragenthttp_user_agent http_x_forwarded_for(代理过程)
sent_http_HEADER响应头sent_http_cookie

测试

# /etc/nginx/nginx.conf
// 更改访问日志格式
log_format main2 '$arg_name $http_host $sent_http_date';

# access_log  /var/log/nginx/access.log  main;
access_log  /var/log/nginx/access.log  main2;

ngnix基础知识

限制请求

limit_req_zone

    # 可以以IP为key zone为空间的名称 size为申请空间的大小
    limit_req_zone key zone=name:size rate=rate;
  • limit_req
    # zone名称 number限制的数量
    limit_req zone=name [burst=number] [nodelay];
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
server {
  location /{
      # 缓存区队列burst=3个,不延期,即每秒最多可处理rate+burst个, 同时处理rate个。burst表示可以等待多少个请求
      limit_req req_zone burst=3 nodelay;
  }
}
  • $binary_remote_addr 表示远程的IP地址
  • zone=req_zone:10m 表示一个内存区域大小为10m,并且设定了名称为req_zone
  • rate=1r/s 表示请求的速率是1秒1个请求
  • zone=req_zone 表示这个参数对应的全局设置就是req_zone的那个内存区域
  • burst=3 表示请求队列的长度。表示可以等待多少个请求。
  • nodelay 表示不延时

连接限制

  • limit_conn_zone
    # 可以以IP为key zone为空间的名称 size为申请空间的大小 
    limit_conn_zone key zone=name:size;
  • limit_conn
    # zone名称 number限制的数量 
    limit_conn zone number;

例子

limit_conn_zone $binanry_remote_addr zone=conn_zone:10m;
server {
  location /{
      limit_conn conn_zone 1; # 表明以ip为key,来限制每个ip访问文件时候,最多只能有一个在线,否则其余的都要返回不可用
  }
}

访问控制

  • 基于IP的访问控制 -http_access_module
  • 基于用户的信任登录 -http_auth_basic_module

http_access_module

allow address|all;

deny address|CIDR|all;
server {
 location ~ ^/admin.html{ # 表示匹配到/admin.html路径的访问地址后,设置访问控制。
      deny 被限制的ip;
      allow all;
    }
}    
server {
+ location ~ ^/admin.html{
+    if ($http_x_forwarded_for !~* "^8.8.8.8") {
+       return 403;
+    }
}    
符号含义
=严格匹配。如果这个查询匹配,那么将停止搜索并立即处理此请求。
~为区分大小写匹配(可用正则表达式)
!~为区分大小写不匹配
~*为不区分大小写匹配(可用正则表达式)
!~*为不区分大小写不匹配
^~如果把这个前缀用于一个常规字符串,那么告诉nginx 如果路径匹配那么不测试正则表达式。

http_auth_basic_module

auth_basic string|off;

auth_basic_user_file [filepath];
htpasswd -c /etc/nginx/users.conf zhangsan
server {
+    auth_basic '请登录';
+    auth_basic_user_file /etc/nginx/users.conf;

给文件赋予最高权限

    chmod 777 文件路径

配置语法

sendfile

  • 不经过用户内核发送文件。通过网络节点缓存获取文件。
类型种类
语法sendfile on / off
默认sendfile off;
上下文http,server,location,if in location

tcp_nopush

  • 在sendfile开启的情况下,合并多个数据包,提高网络包的传输效率。
类型种类
语法tcp_nopush on / off
默认tcp_nopush off;
上下文http,server,location

tcp_nodelay, 与tcp_nopush互斥

  • 在keepalive连接下,提高网络包的传输实时性。
类型种类
语法tcp_nodelay on / off
默认tcp_nodelay on;
上下文http,server,location

gzip

  • 压缩文件可以节约带宽和提高网络传输效率。
类型种类
语法gzip on / off
默认gzip off;
上下文http,server,location

gzip_comp_level

  • 压缩比率越高,文件被压缩的体积越小。
类型种类
语法gzip_comp_level level
默认gzip_comp_level 1;
上下文http,server,location

gzip_http_version

  • 压缩版本。表示大于当前指定的版本号时才进行压缩。防止低版本的协议不支持解压。
类型种类
语法gzip_http_version 1.0/1.1
默认gzip_http_version 1.1;
上下文http,server,location

http_gzip-static_module

  • 先找磁盘上找同名的.gz这个文件是否存在,节约CPU的压缩时间和性能损耗。
  • http_gzip_static_module 预计gzip模块
  • http_gunzip_module 应用支持gunzip的压缩方式
类型种类
语法gzip_static on/off
默认gzip_static off;
上下文http,server,location
    location ~ .*.(jpg|png|gif)$ {
        gzip off;#关闭压缩
        root /data/www/images;
    }

    location ~ .*.(html|js|css)$ {
        gzip on; #启用压缩
        gzip_min_length 1k;    #只压缩超过1K的文件
        gzip_http_version 1.1; #启用gzip压缩所需的HTTP最低版本
        gzip_comp_level 9;     #压缩级别,压缩比率越高,文件被压缩的体积越小
        gzip_types  text/css application/javascript;#进行压缩的文件类型
        root /data/www/html;
    }

    location ~ ^/download {
        gzip_static on; #启用压缩
        tcp_nopush on;  # 不要着急发,攒一波再发
        root /data/www; # 注意此处目录是`/data/www`而不是`/data/www/download`
    } 

expires设置缓存时间

    location ~ .*\.(jpg|png|gif)$ { 
        root /data/www/html;
        expires 24h; 
    }

跨域设置

  • 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源
类型种类
语法add_header name value
默认add_header --;
上下文http,server,location
https://github.com/creationix/nvm
location ~ .*.json$ {
        add_header Access-Control-Allow-Origin http://localhost:3000;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        root /data/json;
}

防盗链 

网页直接访问连接是可以的,但是不能通过img引入。

  • 防止网站资源被盗用。
  • 保证信息安全
  • 防止流量过量
  • 需要区别哪些请求是非正常的用户请求
  • 使用http_refer防盗链
类型种类
语法valid_referers none、block、server_names、IP
默认-
上下文server,location
location ~ .*.(jpg|png|gif)$ {
        expires 1h;
        gzip off;
        gzip_http_version 1.1;
        gzip_comp_level 3;
        gzip_types image/jpeg image/png image/gif;
        # none没有refer blocked非正式HTTP请求 特定IP
+       valid_referers none blocked 47.104.184.134; # 设置可以访问的内容 没有refer可以 不是http可以 指定该ip可以
+       if ($invalid_referer) { # 验证通过为0,不通过为1
+           return 403;
+       }
        root /data/images;
    }
-e, --referer       Referer URL (H) 表示修改referer
curl -e "http://www.baidu.com" http://192.171.207.104/girl.jpg
curl -e "192.171.207.100" http://192.171.207.104/girl.jpg

代理服务

配置

类型种类
语法proxy_pass URL
默认-
上下文server,location

正向代理

  • 正向代理的对象是客户端,服务器端看不到真正的客户端
  • 通过公司代理服务器上网

ngnix基础知识

C:\Windows\System32\drivers\etc

192.168.20.150 www. .cn
resolver 8.8.8.8; #谷歌的域名解析地址, 域名解析器        配置在server外面
location / {
    # $http_host 要访问的主机名 $request_uri请求路径
    proxy_pass http://$http_host$request_uri;
}
  • Win+R系统热键打开运行窗口,输入ipconfig /flushdns命令后按回车,就可以清空电脑的DNS缓存

反向代理

  • 反向代理的对象的服务端,客户端看不到真正的服务端
  • nginx代理应用服务器

ngnix基础知识

location ~ ^/api {
    proxy_pass http://localhost:3000;
    proxy_redirect default; #重定向

    proxy_set_header Host $http_host;        #向后传递头信息
    proxy_set_header X-Real-IP $remote_addr; #把真实IP传给应用服务器

    proxy_connect_timeout 30; #默认超时时间
    proxy_send_timeout 60;    # 发送超时
    proxy_read_timeout 60;    # 读取超时


    proxy_buffering on;             # 在proxy_buffering 开启的情况下,Nginx将会尽可能的读取所有的upstream端传输的数据到buffer,直到proxy_buffers设置的所有buffer们 被写满或者数据被读取完(EOF)
    proxy_buffers 4 128k;           # proxy_buffers由缓冲区数量和缓冲区大小组成的。总的大小为number*size
    proxy_busy_buffers_size 256k;   # proxy_busy_buffers_size不是独立的空间,他是proxy_buffers和proxy_buffer_size的一部分。nginx会在没有完全读完后端响应的时候就开始向客户端传送数据,所以它会划出一部分缓冲区来专门向客户端传送数据(这部分的大小是由proxy_busy_buffers_size来控制的,建议为proxy_buffers中单个缓冲区大小的2倍),然后它继续从后端取数据,缓冲区满了之后就写到磁盘的临时文件中。
    proxy_buffer_size 32k;          # 用来存储upstream端response的header
    proxy_max_temp_file_size 256k; # response的内容很大的 话,Nginx会接收并把他们写入到temp_file里去,大小由proxy_max_temp_file_size控制。如果busy的buffer 传输完了会从temp_file里面接着读数据,直到传输完毕。
}
curl http://localhost/api/users.json

 负载均衡

ngnix基础知识

  • 使用集群是网站解决高并发、海量数据问题的常用手段。
  • 当一台服务器的处理能力、存储空间不足时,不要企图去换更强大的服务器,对大型网站而言,不管多么强大的服务器,都满足不了网站持续增长的业务需求。
  • 这种情况下,更恰当的做法是增加一台服务器分担原有服务器的访问及存储压力。通过负载均衡调度服务器,将来自浏览器的访问请求分发到应用服务器集群中的任何一台服务器上,如果有更多的用户,就在集群中加入更多的应用服务器,使应用服务器的负载压力不再成为整个网站的瓶颈。

upstream

nginx把请求转发到后台的一组upstream服务池

类型种类
语法upstream name {}
默认-
上下文http
var http = require( 'http' );
var server =http.createServer( function ( request ,response ){
          response.end('server3 000');
} );
server.listen( 3000 ,function(){
console.log( 'HTTP服务器启动中,端口:3000' );
});
upstream upstreamName {
  server 127.0.0.1:3000 weight=10;
  server 127.0.0.1:4000;
  server 127.0.0.1:5000;
}

server {
    location / {
        proxy_pass http://upstreamName;
    }

后端服务器调试状态

状态描述
down当前的服务器不参与负载均衡
backup当其它节点都无法使用时的备份的服务器
max_fails允许请求失败的次数,到达最大次数就会休眠。达到请求次数后,将不会再将请求转发到该服务上。
fail_timeout经过max_fails失败后,服务暂停的时间,默认10秒
max_conns限制每个server最大的接收的连接数,性能高的服务器可以连接数多一些
upstream upstreamName {
  server localhost:3000 down;
  server localhost:4000 backup;
  server localhost:5000 max_fails=1 fail_timeout=10s;
}

分配方式

类型种类
轮询(默认)每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除
weight(加权轮询)指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况
ip_hash每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题
least_conn哪个机器上连接数少就分发给谁
url_hash(第三方)按访问的URL地址来分配 请求,每个URL都定向到同一个后端 服务器上(缓存)
fair(第三方)按后端服务器的响应时间来分配请求,响应时间短的优先分配
正定义hashhash自定义key
upstream upstreamName{
  ip_hash;
  server 127.0.0.1:3000;
}
upstream upstreamName{
  least_conn;
  server 127.0.0.1:3000;
}
upstream upstreamName{
  url_hash;
  server 127.0.0.1:3000;
}
upstream upstreamName{
  fair;
  server 127.0.0.1:3000;
}
upstream upstreamName{
  hash $request_uri;
  server 127.0.0.1:3000;
}

rewrite

可以实现url重写及重定向

用途

  • URL页面跳转
  • 兼容旧版本
  • SEO优化(伪静态)
  • 维护(后台维护、流量转发)
  • 安全(伪静态)

语法

类型种类
语法rewrite regex replacement [flag]
默认-
上下文server,location,if
  • regex 正则表达式指的是要被改写的路径
  • replacement 目标要替换成哪个URL
  • flag 标识

实例

# 将任何路径都匹配到指定的文件上
rewrite ^(.*)$ /www/reparing.html break;
本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!