《深入理解Nginx:模块开发与架构解析(第2版)》阅读笔记1 ——基础、静态Web服务器与反向代理服务器

1.基础

1.1 安装

1.安装依赖:参考ubuntu下安装nginx时PCRE库、zlib库、OpenSSL库的安装,具体如下:

sudo apt-get install libpcre3 libpcre3-dev  
sudo apt-get install zlib1g-dev
sudo apt-get install openssl libssl-dev 

2.准备四个目录:

  • Nginx源代码存放目录
  • Nginx编译阶段产生的中间文件存放目录。默认情况下,configure命令会将该目录命名为objs,并放在Nginx源代码目录下。
  • 部署目录:该目录存放实际Nginx服务运行期间所需要的二进制文件、配置文件等。默认情况下,该目录为/usr/local/nginx。
  • 日志文件存放目录:日志文件可能很大,所以分配一个大一点的磁盘。

3.修改Linux内核参数的优化,以实现高并发访问的Web服务器。修改/etc/sysctl.conf文件:

fs.file-max = 999999   # 的最大句柄数,即最大并发连接数,需根据实际情况配置。
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.ip_local_port_range = 1024 61000
net.ipv4.tcp_rmem = 4096 32768 262142
net.ipv4.tcp_wmem = 4096 32768 262142
net.core.netdev_max_backlog = 8096
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.rmem_max = 2097152
net.core.wmem_max = 2097152
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog=1024

上述参数的含义,具体见书中,这里就不抄录了。
书中将net.ipv4.tcp_max_syn_backlog不小心写成了net.ipv4.tcp_max_syn.backlog
执行sudo sysctl -p让配置生效。
sudo sysctl -a查询linux的内核参数。

4.下载安装
获取Nginx源码:http://nginx.org/en/download.html ,下载最新的稳定版就行。
下载:

wget http://nginx.org/download/nginx-1.22.1.tar.gz
tar -xvzf  nginx-1.22.1.tar.gz

编译和安装:

./configure --prefix=PATH  # 检测操作系统内核和已经安装的软件 生成makefile文件等。-prefix=指定安装路径
make # 根据Makefile文件编译Nginx工程,并生成目标文件、最终 的二进制文件
make install #根据configure执行时的参数将Nginx部署到指定的安装目录,包括相关目 录的建立和二进制文件、配置文件的复制

1.2 configure详解

  • configure的命令参数:参数分为了四大类型,我们现在知道有这些参数,如果使用nginx的过程中,出现问题再来重新安装相关功能或模块即可。
  • configure文件介绍:configure加载配置文件、加载第三方模块、生成编译所需的Makefile等文件。
    执行./configure以后,生成了Makefile和ngx_modules.c等文件,其中ngx_modules.c指明了每个模块在Nginx中的优先级,当一个请求同时符合多个模块的处理规则时,将按照它们在ngx_modules数组中的顺序选择最靠前的模块优先处理。对于HTTP过滤模块而言则是相反的。

1.3 Nginx的命令行控制(nginx命令后跟着的参数)

Nginx的命令行控制,大致介绍了nginx后面可以跟着下面几种参数:指定配置文件、测试和显示配置信息、(优雅)停止服务、日志回滚、升级而不停止服务。有需要了过来去书里查阅就可以。

1.4 nginx配置使用第三方模块、

nginx中有master和worker进程:

  • master进程用于管理worker进程,包括诸如启动服务、停止服务、重载配置文件、平滑升级程序等
  • worker进程数一般与CPU核心数相等,每个worker进程可以处理多个HTTP请求。

这样做的好处:

  • master管理worker,当一个worker出问题以后,可以调用其他worker对请求进行处理。
  • 多个worker接收并处理请求,提高了处理请求的效率。

1.5Nginx配置的通用语法与Nginx服务的基本配置

Nginx配置的通用语法:

  • 块配置项:块配置项名 {},或 块配置项名/xxx {}。内外层配置发生冲突时,以内层还是外层配置为准,不同的模块由不同的处理方法。
  • 配置项: 配置项名 配置项值1 配置项值2 ...;,以空格作为分隔符,配置项值可以是数字、字符串、正则表达式。
    【注】如果配置项值中包括语法符号,比如空格符,那么需要使用单引号或双引号括住配置项值。
  • 注释:使用#作为注释
  • 配置项的单位:空间单位(k,m等),时间单位(ms,s,m,h等)
  • 配置文件中的变量:使用$作为前缀进行表示。只有少数模块支持解析这种变量。

Nginx服务的基本配置:Nginx运行时至少要配置的配置项,当然有些配置项有默认值可以不需要手动进行配置。

  • 用于调试进程和定位问题的配置项
daemon on | off;         # off以后使其在终端运行,方便输出调试信息
master_process on| off; 
   # off关闭了master_process方式,就不会fork出worker子进程来处理请求,而是用master进程自身来处理请求。
error_log /path/file level;
   # 设置error日志输出到哪个文件中,已经日志的输出等级
debug_points [stop| abort]
   # 如果设置了debug_points 为stop,那么Nginx的代码执行到这些调试点时就会发出SIGSTOP信号以用于调试。
   # 如果debug_ points 设置为abort,则会产生一个coredump文件,可以使用gdb来查看Nginx当时的各种信息。
   # 通常不会使用这个配置项。
debug_connection [IP | CIDR] # 设置哪些IP的请求才会输出debug级别的请求
worker_rlimit_core size;  # 限制coredump核心转储文件的大小。
   # 在Linux系统中,当进程发生错误或收到信号而终止时,系统会将进程执行时的内存内容(核心映像)写入
   # 一个文件(core文件),以作为调试之用,这就是所谓的核心转储
working_directory path; # 指定coredump文件生成目录
  • 正常运行的配置项
env VAR|VAR=VALUE           # 定义系统的环境变量
include /path/file         # 导入其他配置文件
pid path/file;             # 保存master进程ID的pid文件存放路径。
user username [groupname]; # Nginx worker进程运行的用户及用户组
worker_rimit_nofile limit; # 指定Nginx worker进程可以打开的最大句柄描述符个数
worker_rlimit_sigpending limit; # 设置每个用户发往Nginx的信号队列的大小
  • 优化性能的配置项
worker_processes number; # 设置Nginx worker进程个数。
  # 如果这些模块确认不会出现阻塞式的调用,那么,有多少CPU内核就应该配置多少个进程;反
  # 之,如果有可能出现阻塞式调用,那么需要配置稍多一些的worker进程。
worker_cpu_affinity cpumask[cpumask...] # 绑定Nginx worker进程到指定的CPU内核。调用linux系统调用sched_setaffinity()实现  
ssl_engine device                       # 设置SSL硬件加速设备,加快SSL协议处理速度
timer_resolution t;                     # 设置gettimeofday执行频率。gettimeofday:实现用内核的时钟来更新Nginx中的缓存时钟。
worker_priority nice;                   # Nginx worker进程优先级设置
  • 事件类配置项
accept_mutex [on| off]   # 是否打开acept锁。打开以后,TCP连接会均匀分给各个worker进程,从而实现负载均衡
lock_file path/file;     # Nginx不支持原子锁的时候,lock_file指定的lock文件才会生效。
accept_ mutex_delay Nms; # 如果有一个worker进程试图取accept锁而没有取到,它至少要等acceptmutexdelav定义的时间间隔后才能再次试图取锁。
multi_accept [ on | off ]; # 当事件模型通知有新连接时,尽可能地对本次调度中客户端发起的所有TCP请求都建立连接。
use [ kqueue | rtsig | epoll | /dev/poll| select| poll | eventport ]; # 选择事件模型。可供选择的事件驱动模型有poll、select、 epoll 三种。epoll效率最高。
worker_ connections number; # 每个worker的最大连接数

2.静态Web服务器与反向代理服务器

2.1 用HTTP核心模块配置一个静态Web服务器

参考:Nginx快速入门

static_web.conf

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    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  on;

    ## 新服务(静态网站)
    server {
        listen 8081; 

        location / {
            root /home/ubuntu/softwares/nginx/myfile/www;
        }
        location /images/ {
            root /home/ubuntu/softwares/nginx/myfile;
        }
    }
}

/home/ubuntu/softwares/nginx/myfile/www下放入一个index.html,index.html的内容如下:

<h2> New Static WebSite Demo.</h2>

/home/ubuntu/softwares/nginx/myfile/images下放入一个名为logo.png的文件。

运行:

./nginx -c /home/ubuntu/softwares/nginx/conf/static_web.conf 

-c指定static_web.conf的路径。

浏览器输入:
127.0.0.1:8081既可以访问到index.html
127.0.0.1:8081/images/logo.png既可以访问到logo.png

2.1.1 HTTP配置项

HTTP配置项分为了八个类,下面进行逐一介绍:

1.虚拟主机与请求的分发:多个主机域名对应着同一个IP地址,每个主机域名对应一个server块,一个server块只处理与之相对应的主机域名请求。下面对书中的部分配置项进行摘录:

  • listen address:port; 决定Nginx服务如何监听端口。下面介绍部分listen后可以跟着的参数。
    default/default server:设置本server块为默认server块。当一个请求无法匹配配置文件中的所有主机域名时,就会使用默认server块进行处理。没有这个参数,那么第一个server块为默认server块。
    backlog num:表示TCP中backlog队列的大小。在进行三次握手的过程中,如果有新的客户试图通过三次握手建立新的连接,此时新客户的请求会被放入backlog队列。backlog队列满了就不能再接收客户请求了。
    defered:设置此参数后,三次握手时,不会调用worker进程。只有用户真的发送请求数据时(内核已经在网卡中收到请求数据包)。内核才会唤醒worker进程处理这个连接。
    ssl:在当前监听的端口,上建立的连接必须基于SSL协议。

  • server_name name […]; 在开始处理一个HTTP请求时,Nginx会取出header头中的Host,与每个server中的server_name 进行匹配,以此决定到底由哪一个server块来处理这个请求。

  • server_names_hash_bucket_size:设置散列桶占用内存的大小。散列桶代表每个key对应的链表。
    server_names_hash_max_size:应该是指最大可存储多少个key值。

  • server_name_in_redirect on| off; 该配置需要配合server_name使用。在使用on打开时,表示在重定向请求时会使用server_name里配置的第一个主机名代替原先请求中的Host头部,而使用off关闭时,表示在重定向请求时使用请求本身的Host头部。默认为on。

  • location [=|~|~*|^~|@] /uri/ { ... } 用户请求的uri匹配哪个location就用哪个location处理请求。

2.文件路径的定义

alias和root:
alias:直接将uri中的前缀替换为本地路径,alias只能放置到location块,alias后面还可以添加正则表达式。
root:将uri加到本地路径后面,root可以放置到http、server、 location 或if块中。
如下:

location /download/ {
    root /opt/web/html/;
}

URI是/download/index/test.html,按照上面的配置,返回的是/opt/web/html/download/index/test.html。
如果将location中的root换成alias时,URI是/download/index/test.html,则返回/opt/web/html/index/test.html。

访问首页:index file1 file2... fileN,从fileN开始依次访问,只要有一个可以访问,那么就不会再访问下一个了。
根据HTTP返回码重定向页面:error_ page,就是说遇到某个返回码就跳转到某个页面
是否允许递归使用error_page:recursive_ error_ pages
try_files path1 [path2] uri; 依次访问每个path,如果没有访问成功,就重定向到uri

3.内存及磁盘资源的分配

  • http的body存储在内存还是磁盘,分配多大的内存、存储在磁盘中时,如何命名文件名的。
  • http的header应该分配多大的内存,当header很大时应该如何分配内存
  • 给TCP连接分配的内存池大小
  • 给HTTP连接分配的内存池大小

4.网络连接的设置

  • 设置读取body、header的超时时间、发送响应的超时时间
  • keepalive等各种超时时间

5.设置MIME type与文件扩展名的映射
浏览器通常使用 MIME 类型(而不是文件扩展名)来确定如何处理URL,因此 We b服务器在响应头中添加正确的 MIME 类型非常重要。如果配置不正确,浏览器可能会无法解析文件内容,网站将无法正常工作,并且下载的文件也会被错误处理。(参考:链接

6.对客户端请求的限制:限制http方法、body大小、客户端每秒传输的字节数。

7.文件操作的优化:

  • 加速对文件的访问:sendfile、aio、directio
  • 文件在内存中的缓存:设置缓存的文件数量、多久没被访问就淘汰、检验缓存有效性等。

8.对客户端请求的特殊处理:见书

9.ngx_http_core_ module 模块提供的变量

2.2 配置一个反向代理服务器

可直接参考:配置一个反向代理服务器

反向代理服务器:用于接收互联上的请求,并将请求转发给局域网中的服务器进行处理。
nginx一般用于向客户端提供静态文件服务和作为反向代理服务器,对于复杂、多变的业务不适合放到Nginx服务器上,这时会用Apache、Tomcat等服务器来处理。

与反向代理服务器Squid相比,nginx反向代理服务器有如下特点:

  • nginx反向代理服务器会将完整的请求缓存下来(包括http的body部分),然后在将请求发送到上游服务器。而Squid等代理服务器则采用一边接收客户端请求,一边转发到上游服务器的方式。

  • 缺点:延长了一个请求的处理时间,并增加了用于缓存请求内容的内存和磁盘空间。
    优点:降低了上游服务器的负载,尽量把压力放在Nginx服务器上。起到如上作用的原因:公网上的请求发送到Nginx服务器速度比较慢,所以连接需要维持的时间比较久。Nginx服务器与内网服务器之间的通信一般会比较快,所以连接需要维持的时间比较短。所以Nginx反向代理服务器降低上游服务器的并发压力,即上游服务器可以很快的接收到Nginx反向代理服务器发送的请求。

2.2.1 负载均衡的基本配置

负载均衡:尽量把请求平均地分布到每一 台上游服务器上

负载均衡的基本配置项:

  • upstream块:定义了一个上游服务器的集群,便于反向代理中的proxy pass使用。upstream块中使用server指定一个上游服务器的名称。
  • ip_hash; 使得同一个用户的请求始终落在一个上游服务器上。
  • 记录日志时支持的变量

2.2.2 反向代理的基本配置

  • proxy_ pass:为当前的请求指定上游服务器
  • 隐藏头部字段、确定是否向上游服务器转发body和header
  • proxy_redirect:重定向到别的服务器
  • proxy_next_upstream:发生超时、错误等情况时,重新找一个上游服务器处理请求

3.开发一个简单的HTTP模块

HTTP模块:

  • worker进程检测到请求以后,会根据nginx.conf的配置将请求交给HTTP框架处理,HTTP框架解析头部后,根据URI和nginx.conf里的location配置项,将请求分发给HTTP模块进行处理。
  • HTTP模块会将响应发送给HTTP过滤模块进行处理,比如压缩响应。
  • 处理完毕以后,如果设置了subrequest,,那么HTTP框架还会继续异步地调用适合的HTTP模块处理子请求。

ngx_http_access_module模块用于过滤非法IP。

编写config文件指定模块名和模块代码路径,就可以使用configure --add-module=PATH
将模块编译进nginx源码中。

posted @ 2022-11-08 22:27  好人~  阅读(98)  评论(0编辑  收藏  举报