草庐IT

Nginx 我们必须知道的那些事

云原生生态圈 2023-03-28 原文
1、Nginx介绍Nginx

       NGINX写入解决服务器的少数之一C10K问题。不同于传统的服务器,NGINX不依靠线程来处理请求。相反,它使用一个更可扩展的事件驱动的(异步)架构。这种结构采用小,但更重要的是,可预测的量的负荷下存储器。即使你不希望处理成千上万的并发请求,你仍然可以从NGINX的高性能和小内存占用受益。NGINX扩展在所有方向:从最小的VPS一路攀升到服务器的大型集群

[扩展]

C10k

       指的是服务器同时支持成千上万个客户端的问题,也就是conncurrent10 000     connection;而Nginx就是能解决这样的一个问题

Nginx的应用

       Netflix, Hulu,Pinterest, CloudFlare, Airbnb, WordPress.com, GitHub, SoundCloud, Zynga,Eventbrite, Zappos, Media Temple, Heroku, RightScale, Engine Yard, MaxCDN

官方站点

       http://nginx.org/

选择一个新的程序包注意的问题

       1.序包的新功能是否是我们需要的

       2.新的程序包之前必须做测试

作用

       一个自由的,开放源码的,高性能的http和反向、代理服务器,以及一个IMAP/POP3代理服务器

Nginx的特点

高性能,高稳定性,功能丰富,配置简单,资源消耗低

二次开发版:tengine, openresty

Nginx的特性:

       模块化设计,较好的扩展性;

       高可靠性

              master/worker

       支持热部署

              不停机更新配置文件、更换日志文件、更新服务器程序版本;

       低内存消耗

              10000个keep-alive连接模式下的非活动连接仅消耗2.5M内存;

       Nginx支持事件驱动机制,支持异步,支持内存映射

【扩展】

什么是代理:

       即代表处理,代表处理已授权的事情;

       

       上图知,对于客户端来说,中间的服务器是一个代理服务器,而对于服务器来说,中间的那个服务器称之为反向代理

基本功能

       静态资源的web服务器;

       http协议反向代理服务器;

       pop3/imap4协议反向代理服务器;

       支持fastCGI(lnmp), uWSGI等协议

       模块化(非DSO),著名模块支持的有zip, SSL等等;        

web服务器相关的功能:

       虚拟主机、keepalive机制、访问日志、错误日志、url 重写、路径别名、基于ip及用户的访问控制、支持速率限制及并发数限制,...;

Nginx的程序架构:

解释:

       两个补充的管理缓存的组件      

              Cache loader:负责加载/装载缓存

              Cache Manager:管理缓存的

       中间的proxycache是需要开启才能使用的,基于本地磁盘上与本地磁盘打交道时,支持高级I/O机制,支持sendfile机制,支持异步IO机制,支持mmap,支持

       实现并发请求响应上可以基于kevent,epoll(需要系统调用),.select机制,使用的方式都是不一样的

架构:

       master/worker

              一个master进程,可生成一个或多个worker进程;

                     master:加载配置文件、管理worker进程(创建和销毁)、平滑升级、...

                     worker:http服务、http代理、fastcgi代理                 

模块类型:

       核心模块:core module

       标准模块:自己代理的核心模块

              标准http模块

              可选的http木块

              邮件模块

       第三方模块(3rd party modules):           

模块

       配置模块即配置模块中的指令,没有配置指令就没有相对应的有效的模块;

       模块中存在一些相关的变量;(内建变量)随着模块的不同而变化

Nginx能作什么

       静态资源的web服务器

       http协议反向代理

nginx如何作为web服务器

安装nginx:(nginx不再iso中,可以使用epel源安装)

       推荐epel源:http://mirrors.aliyun.com/epel/7Server/x86_64/n/

配置yum源:

       [root@bogon yum.repos.d]#cat epel.repo

       [epel]

       name=centos epel

       baseurl=http://mirrors.aliyun.com/epel/7Server/x86_64/c/

       gpgcheck=0

配置nginx的yum源

       [nginx]

       name=nginx repo

       baseurl=http://nginx.org/packages/mainline/OS/OSRELEASE/$basearch/

       gpgcheck=0

       enabled=1

下载nginx

       wget http://nginx.org/download/nginx-1.10.0.tar.gz

编译安装:按需安装

配置安装开发环境:

       准备支持的模块

       yum install –y pcre-devel openssl-devel zlib-devel

       安装开发包组

第一步:tar xfnginx-1.8.1.tar.gz

第二部:cdnginx-1.8.1

第三步:./configure\

       --prefix=/etc/nginx     nginx安装的位置

       --sbin-path=/usr/sbin/nginx     nginx程序文件的安装路径

       --conf-path=/etc/nginx/nginx.conf   nginx的主配置文件路径

       --error-log-path=/var/log/nginx/error.log     错误日志文件路径

       --http-log-path=/var/log/nginx/access.log    http访问日志路径

       --pid-path=/var/run/nginx.pid  nginx的pid配置文件的路径

       --lock-path=/var/run/nginx.lock      锁文件

       --http-client-body-temp-path=/var/cache/nginx/client_temp    

       --http-proxy-temp-path=/var/cache/nginx/proxy_temp

       --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp

       --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp

       --http-scgi-temp-path=/var/cache/nginx/scgi_temp

       以上是临时文件路径,如果服务器允许使用put机制的话,客户端可能会向服务器端请求大量的数据,服务器端收到的请求报文中的body中可能会有很多的数据,而这些数据都会存放内存中,倘若有很多的用户并发发出请求,服务器端内存无法存放,因此就会把数据临时存放在磁盘上的这些临时文件内,上述都是代理服务器时缓存文件的存放路径

       --user=nginx       指明那个用户来运行nginx的work进程

       --group=nginx    

       --with-http_ssl_module      支持ssl认证

       --with-http_realip_module  记录用户的真实ip

       --with-http_addition_module

       --with-http_sub_module

       --with-http_dav_module

       --with-http_flv_module

       --with-http_mp4_module

       --with-http_gunzip_module

       --with-http_gzip_static_module

       --with-http_random_index_module

       --with-http_secure_link_module

       --with-http_stub_status_module

       --with-http_auth_request_module

       --with-threads

       --with-stream

       --with-stream_ssl_module

       --with-http_slice_module

       --with-mail

       --with-mail_ssl_module

       --with-file-aio      文件的异步IO机制

       --with-http_v2_module

       --with-ipv6

--with-* 指明编译哪些功能

第四部:make&& make install

直接安装:

       yum install –y nginx

nginx命令

       -?或者h:显示帮助信息

       -v:显示版本信息和退出

       -V:显示版本信息和配置选项以及退出

       -t:测试配置文件是否存在错误

       -q:在配置测试过程中抑制错误消息

       -s:发送信号给主进程(stop(平滑停止),quit(及时有人正在使用,也会立即终止),reopen,reload)

       -p:设置前缀路径

       -c:设置主置文件

       -g:设置全局指令的配置文件

启动nginx

       前提是关闭占用80端口的应用程序,比如http

       [root@www ~]# nginx

 

Nginx配置

       配置文件的组成部分:

       主配置文件:nginx.conf

       片段化配置文件实现:(相对于主配置文件的路径,参照httpd)

1)创建一个conf.d目录

2)在主配置文件中键入指令:include conf.d/*.conf

            Fastcgi,scgi,uwscgi的相关配置以及mime.types

配置指令

注意:必须以分号结尾

指令格式:directive  value1 [value2...];

支持使用变量:

内置变量:由模块引入,可直接引用;

自定义变量:set  variable_name value;

            引用变量:$variable_name

整体配置文件结构:

     main block:全局配置;对http及mail模块都有效;

            event{ ... }:事件驱动的相关配置;

            http { ...}:http协议的相关配置

            mail{ ... }:mail相关的配置;

       http相关的配置:

            http{ ...   ...

                   server{ ...       #一个sever一个虚拟主机

                          server_name  #当前主机名

                          root        #跟文档的路径

                          alias      #别名映射

                          location/url/ { ...   #这里的url可以使用正则表达式做通配

                                 }    #定义访问特定url目录时的一些配置:

                          ...}

                   server { ... ...

                                 }

                          }

细化配置文件结构                           

       main block:配置指令的类别:

正常运行必备的配置;

优化性能的配置;

用于调试、定位问题的配置;

正常运行必备的配置

            1、user USERNAME [GROUPNAME];指定用于运行worker进程的用户和组;

                   usernginx nginx;

            2、pid /PATH/TO/PID_FILE;指定nginx进程的pid文件路径;

              pid /var/run/nginx.pid;

            3、worker_rlimit_nofile number;单个worker进程所能够打开的最大文件数;


性能优化相关的配置

            1、worker_processes number | auto;

                   worker的进程数;通常应该为CPU的核心数减1;

            2、worker_cpu_affinity cpumask ...;#指定worker进程运行在那颗cpu上

                worker_cpu_affinity auto [cpumask]; 1.8版本不支持auto

                               CPUMASK:cpu掩码

                                        00000001      第0颗

                                        00000010      第1颗CPU

                                        00000100

                                        ...

范例:编辑配置文件添加:

                     worker_processes 2;#指定运行两个worker_processes

                     Worker_cpu_affinity 0010 0100;

                     重新加载:nginx –s reload

                     查看worker运行在那颗cpu上:显示命令,进程号,cpu,优先级

                          psaxo command,pid,psr,ni

            3、worker_priority nice;指明进程的优先级

                   [-20,19]对应的是100-139

调试、定位问题

1、daemon on | off;是否以守护进程方式启动nginx进程;

守护进程:启动在后台运行

非守护进程:启动在前台消耗资源运行

            2、master_process on | off; 是否以master/worker模型启动nignx进程;

            3、error_log file | stderr |syslog:server=address[,parameter=value] | memory:size [debug | info | notice |warn | error | crit | alert | emerg];#错误日志文件的记录方式,及其日志级别:

            方式:

                   file /PATH/TO/SOME_LOG_FILE;      #日志文件的路径

                   stderr:                                            #发送到错误输出;                                           syslog:server=address[,parameter=value]:#发送给syslog服务器;

                   memory:size                                     #记录在内存中

            日志级别:

                   debug依赖于configure时的--with-debug选项;

nginx.conf

main block;

event{

…}

     1、worker_connections number;每个worker进程所能够并发打开的最大连接数;默认是512个

当前系统能响应的最大并发连接数:worker_processes *worker_connections

     2、use method;指明并发连接请求处理时使用的方法;

            use  epoll;

2、accept_mutex on | off;启用时,表示用于让多个worker轮流地、序列化地响应新请求;

http{

         }       

         定义套接字相关功能

     1、server { ... }

配置一个虚拟主机;

                   server {

                   listen PORT;

                   server_name  HOSTNAME;

                   root /PATH/TO/DOCUMENTROOT;

                   …}

注意:

            (1) 基于port的虚拟主机:

            listen指令要使用不同的端口;

            (2) 基于Hostname的虚拟主机;

            server_name指令指向不同的主机名;

            (3) 基于ip的虚拟主机:

            listen IP:PORT;

     2、listen address[:port] [default_server][ssl] [backlog=number] [rcvbuf=size] [sndbuf=size];

            listenport [default_server] [ssl];

            listenunix:path [default_server] [ssl] ;

            default_server:默认虚拟主机;

            ssl:限制只能通过ssl连接提供服务;

            backlog:后缓队列的长度;

            rcvbuf:接收缓冲大小;

            sndbuf:发送缓冲区大小;

     3、server_name name ...;

            指明当前server的主机名;后可跟一个或空白字符分隔的多个主机;

支持使用*任意长度的任意字符;

支持~起始的正则表达式模式字符串;

应用策略:

             (1) 首先精确匹配;

             (2) 左则*通配符匹配;

             (3) 右侧*通配符匹配;

             (4) 正则表达式模式匹配;

                   server_name  www.magedu.com;

                   server_name*.magedu.com;

                   server_name  www.magedu.*;

                   server_name~^.*\.magedu\..*$;

                   mail.magedu.com,www.magedu.com

     4、tcp_nodelay  on|off;

            对keepalived模式下的连接是否启用TCP_NODELAY选项;


     5、sendfile on | off;

            是否启用sendfile功能;

定义路径相关配置

     6、root path;

            设置web资源路径映射;用于指明用户请求的url所对应的本地文件系统上的文档所在目录路径;

可用上下文:http, server, location, if

     7、location [ = | ~ | ~* | ^~ ] uri { ...}

          location @name { ... }

          根据用户请求的URI来匹配定义的location,匹配到时,此请求将被相应的location块中的指令所处理;

     server {

            ...

            location {

            }

            location {

            ...

            }

            }

     =:URI精确匹配;

     ~:做正则表达式模式匹配,区分字符大小写;

     ~*:做正则表达式模式匹配,不区分字符大小写;

     ^~:对URI的左半部分做匹配检查,不区分字符大小写;

            匹配优先级:=、^~、~/~*、不带符号;

     8、alias path;

            定义路径别名,文档映射的一种机制;仅能用于location上下文;


                          alias  /bbs/ /web/forum/


                          http://www.magedu.com/bbs/a.jpg          


                                 location  /bbs/ {

                                        alias  /web/forum/;

                                 }


                                 /web/forum/a.jpg


                                 location  /bbs/ {

                                        root  /web/forum/;

                                 }


                                 /web/forum/bbs/a.jpg



注意:

                                 root指令:给定的路径对应于location中的/uri/左侧的/;

                                 alias指令:给定的路径对应于location中的/uri/右侧的/;


9、index file ...;

可用位置:http, server, location


默认主面;


10、error_page code ... [=[response]] uri;

根据用户请求的资源的http响应的状态码实现错误页重定向;


                          http://www.magedu.com/hello.html--> 因为资源不存在而被改为对

                                 http://www.magedu.com/404.html


定义客户端请求的相关配置


12、keepalive_timeout timeout[header_timeout];

设定保持连接的超时时长,0表示禁止长连接 ;默认为75s;


13、keepalive_requests number;

在一次长连接上所允许请求的资源的最大数量,默认为100;


14、keepalive_disable none | browser ...;

对哪种浏览器禁用长连接;


15、send_timeout time;

向客户端发送响应报文的超时时长; 特别地,是指两次写操作之间的间隔时长;


16、client_body_buffer_size size;

用于接收客户端请求报文的body部分的缓冲区大小;默认为16k;超时此大小时,其将被暂存到磁盘上;


17、client_body_temp_path path [level1[level2 [level3]]];

设定用于存储客户端请求报文的body部分的临时存储路径及子目录结构和数量;


                          /var/tmp/body  2 1 2

                                 00-ff



对客户的请求进行限制的相关配置

18、limit_rate rate;

限制响应给客户端的传输速率,单位是bytes/second,0表示无限制;


19、limit_except method ... { ... };

限制对指定的请求方法之外的其它方法的使用客户端;


                          limit_exceptGET POST {

                                 allow  172.18.0.0/16;

                                 denyall;

                          }


表示除了GET和POST之外的其它方法仅允许172.18.0.0/16中的主机使用;


文件操作优化的配置:

20、aio on | off | threads[=pool];

是否启用aio功能;


21、directio size | off;


22、open_file_cache off;

                          open_file_cachemax=N [inactive=time];

                                 nginx可以缓存以下三种信息:

                                        (1)文件的描述符、文件大小和最近一次的修改时间;

                                        (2)打开的目录的结构;

                                        (3)没有找到的或者没有权限访问的文件的相关信息;


                                 max=N:可缓存的缓存项上限;达到上限后会使用LRU算法实现缓存管理;


                                 inactive=time:缓存项的超时时长,在此处指定的时长内未被命中的缓存项即为非活动项;


23、open_file_cache_errors on | off;

是否缓存查找时发生错误的文件一类的信息;


24、open_file_cache_min_uses number;

在open_file_cache指令的inactive参数指定的时长内,至少命中此处指定的次数方可不被归类到非活动项;


25、open_file_cache_valid time;

缓存项有效性的检查频率;默认是60s;


            ngx_http_access_module模块:

实现基于ip的访问控制功能;


26、allow address | CIDR | unix: | all;

27、deny address | CIDR | unix: | all;


可用上下文:http, server, location,limit_except


            ngx_http_auth_basic_module模块:

28、auth_basic string | off;

使用basic机制进行用户认证;


29、auth_basic_user_file file;

认证用的账号密码文件;


文件格式:

                                 name:password:commet


                          密码格式:

                                 htpasswd命令;


                                 location/admin/ {

                                 auth_basic"Admin Area";

                                 auth_basic_user_file/etc/nginx/.ngxpasswd;

                                 }


            ngx_http_stub_status_module模块:

用于输出nginx的基本状态信息;


                   Activeconnections: 1

                   serveraccepts handled requests

                   155155 298

                   Reading:0 Writing: 1 Waiting: 0              


                   Activeconnections:  处于活动状态的客户端连接的数量;

                   accepts:已经接受的客户端请求的总数;

                   handled:已经处理完成的客户端请求的总数;

                   requests:客户端发来的总的请求数;

                   Reading:处于读取客户端请求报文首部的连接数;

                   Writing:处于向客户端发送响应报文过程中的连接数;

                   Waiting:处于等待客户端发出请求的空闲连接数;


            ngx_http_referer_module模块:

                   Thengx_http_referer_module module is used to block access to a site for requestswith invalid values in the “Referer” header field.


 30、valid_referers none | blocked |server_names | string ...;

定义合法的referer数据;


         none:请求报文首部没有referer首部;

         blocked:请求报文的referer首部没有值;

         server_names:其值是主机名;

        arbitrarystring:直接字符串,可以使用*作为通配符;

        regularexpression:被指定的正则表达式模式匹配到的字符串;要使用~起始;


        valid_referersnone blocked server_names *.magedu.com magedu.* ~\.magedu\.;


                          if($invalid_referer) {

                                 return403;

                          }


有关Nginx 我们必须知道的那些事的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - EventMachine - 你怎么知道你是否落后了? - 2

    我正在研究使用EventMachine支持的twitter-streamruby​​gem来跟踪和捕获推文。我对整个事件编程有点陌生。我如何判断我在事件循环中所做的任何处理是否导致我落后?有没有简单的检查方法? 最佳答案 您可以通过使用周期性计时器并打印出耗时来确定延迟。如果您使用的是1秒的计时器,您应该已经过了大约1秒,如果它更长,您就知道您正在减慢react器的速度。@last=Time.now.to_fEM.add_periodic_timer(1)doputs"LATENCY:#{Time.now.to_f-@last}"@

  3. ruby-on-rails - 如何用不同的用户运行nginx主进程 - 2

    A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(

  4. ruby - 为什么必须明确指定 2 个参数才能 curry :> - 2

    考虑这个,它工作正常::>.to_proc.curry(2)[9][8]#=>true,because9>8然而,即使>是一个二元运算符,如果没有指定的元数,上面的代码将无法工作::>.to_proc.curry[9][8]#=>ArgumentError:wrongnumberofarguments(0for1)为什么两者不等价?注意:我特别想用提供的一个参数创建中间柯里化(Currying)函数,然后然后调用然后用第二个参数调用它。 最佳答案 curry必须知道传入的过程的数量,对吧?:-1来自arity的负值令人困惑,但基本上

  5. ruby-on-rails - 为什么用户必须输入 7 位数的 Twitter PIN 才能授予我的应用程序访问权限? - 2

    我正在为我的用户实现一些ruby​​onrails代码推特内容。我正在创建正确的oauth链接...类似http://twitter.com/oauth/authorize?oauth_token=y2RkuftYAEkbEuIF7zKMuzWN30O2XxM8U9j0egtzKv但在我的测试帐户授予对twitter的访问权限后,它会弹出一个页面,上面写着“您已成功授予对.我不知道用户应该在哪里输入此PIN以及他们为什么必须这样做。我认为这不是必要的步骤。Twitter应该将用户重定向到我在应用程序设置中提供的回调URL。有谁知道为什么会这样?更新我找到了thisarticle声明我需

  6. ruby-on-rails - Ruby 如何知道在哪里可以找到所需的文件? - 2

    这里还有一个新手问题:require'tasks/rails'我在每个Rails项目的根路径中的Rakefile中看到了这一行。我猜这行用于要求vendor/rails/railties/lib/tasks/rails.rb加载所有rake任务:$VERBOSE=nil#LoadRailsrakefileextensionsDir["#{File.dirname(__FILE__)}/*.rake"].each{|ext|loadext}#LoadanycustomrakefileextensionsDir["#{RAILS_ROOT}/lib/tasks/**/*.rake"].so

  7. ruby - 在 Ruby 中,如果我们定义了一个方法调用 "c=",为什么 c = 3 不能调用它? - 2

    例如,如果我们defc=(foo)p"hello"endc=3c=(3)并且不会打印“hello”。我知道它可以被self.c=3调用,但为什么呢?可以通过哪些其他方式调用它? 最佳答案 c=3(和c=(3),完全等同于它)总是被解释为局部变量赋值。你可能会说只有当方法c=没有在self上定义时,它才应该被解释为局部变量赋值,但是这有很多问题:至少MRI需要在解析时知道在给定范围内定义了哪些局部变量。但是,在解析时并不知道给定的方法是否已定义。所以ruby​​直到运行时才知道c=3是否定义了变量c或者调用了方法c=,这意味着它不会知

  8. ruby-on-rails - 在 Rails 中,我从 Guard 那里收到这个错误,说我必须更新到新的 :cmd syntax - 2

    我刚刚更新了我的gem,当我尝试运行Guard时,出现以下错误:Guard::RSpecDEPRECATIONWARNING:The:clioptionisdeprecated.Pleasecustomizethenew:cmdoptiontofityourneed.这是我的Guard文件:guard'rspec',cli:'--drb'dowatch(%r{^spec/.+_spec\.rb$})watch(%r{^lib/(.+)\.rb$}){|m|"spec/lib/#{m[1]}_spec.rb"}watch('spec/spec_helper.rb'){"spec"}#Ra

  9. ruby - 我们如何在不同的 Ruby 类之间复制单例方法? - 2

    我试图定义一个带有方法的类,以及一个缺少这些方法的类,然后允许后一个类的对象从前一个类的实例“学习”这些方法。这是我的尝试(Ruby1.9.2)-当我尝试更改lambda绑定(bind)中“self”的值时,它中断了(在注释为“BREAKS!”的行处)。如果您能想出如何解决这个问题-我很想知道。classSkillattr_accessor:nameattr_accessor:techniquedefinitialize(name,&technique_proc)@name=name@technique=lambda(&proc)endendclassPersonattr_access

  10. ruby - 为什么我必须对 Net::HTTP 请求的安全字符进行 URI.encode? - 2

    我尝试使用Net::HTTP向Twitter发送GET请求(出于隐私原因替换了用户ID):url=URI.parse("http://api.twitter.com/1/friends/ids.json?user_id=12345")resp=Net::HTTP.get_response(url)这会在Net::HTTP中引发异常:NoMethodError:undefinedmethodempty?'for#from/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/http.rb:1

随机推荐