《深入理解Nginx》 学习笔记(二)

《深入理解Nginx》学习笔记(二)

运行中的Nginx进程间的关系

  • 正式提供服务的产品环境下,部署Nginx使用一个master进程管理多个worker进程;
  • worker进程的数量域服务器上的CPU核心数相等,worker进程在真正的提供互联网服务,master进程负责监控管理worker进程;
  • worker进程之间通过共享内存、原子操作等一些进程间通信机制实现负载均衡等功能;
    部署后的Nginx进程间的关系

Nginx配置的通用语法

nginx的配置文件只是一个普通的文本文件;

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

(1)块配置项

  • 由一个块配置项名和一堆大括号组成;
  • 大括号把一些列所属的配置项全包含进来,表示大括号内的配置同时生效;
  • 块配置项可以嵌套,内层块直接继承外层块;例如:示例配置中server块里的任意配置都是基于http块里已有的配置;
  • 当内外层块中的配置冲突时,由解析这个配置项的模块决定配置。

(2)配置项的语法格式

配置项名
	配置项值
1配置项值
2....
;
  1. 行首是配置项名,必须是Nginx的某一个模块想要处理的,否则Nginx会认为配置文件出现了非法的配置项名。配置项名输入结束后,以空格作为分隔符。
  2. 配置项值,可以是数字或字符串。对于一个配置项可包含多个配置项值,以空格符来分隔。
  3. 每行配置结尾需加分号。
  4. "#"注释一行配置。
  5. 当指定空间大小时,可以使用单位包括K、M;当指定时间时,可以使用单位包括:ms, s, h, d, w, M, y。

Nginx服务的基本配置

Nginx在运行时,至少必须加载几个核心模块和一个事件类模块。这些模块运行时所支持的配置项称为基本配置。

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

(1)是否以守护进程方式运行Nginx

语法:daemon on|off;
默认:daemon on;
守护进程(daemon)是脱离终端并且在后台运行的进程。进程不会被任何终端所产生的信息所打断;

(2)是否以master/worker方式工作

语法:master_process on|off;
默认:master_process on;

(2)error 日志的设置

语法:error_log pathfile level;
默认:error_log logs/error.log error;

  • pathfile 参数可以是具体的文件,也可以是*/dev/null*,这样就不会输出任何日志(关闭日志的唯一手段),也可以是stderr,这样日志会输出到标准错误文件中;

  • level 是日志的输出级别:

    debug
    info
    notice
    warn
    error
    crit
    alert
    emerg
    

    从上到下级别依次增大。当设定为一个级别时,大于或等于该级别的日志会被输出到pathfile文件中,小于该级别的日志则不会输出;

  • 正常运行的必备配置项;

  • 优化性能的配置项;

  • 事件类配置项;

(4)是否处理几个特殊的调试点

语法:debug_points[stop|abort];
用于帮助用户跟踪调试Nginx,Nginx在一些关键字的错误逻辑中设置了调试点。如果此处设置为stop,那么Nginx的代码执行到这些调试点时就会发出SIGSTOP信号用于调试。如果设置为abort,则会产生一个coredump文件,可以使用gdb来查看Nginx当时的各种信息。

(5)仅对指定的客户端输出debug级的日志

语法:debug_connection[IP|CIDR];
该配置属于事件类型配置,因此必须放在events{…}中才有效。

events{
		debug_connection 10.224.66.14;
		debug_connection 10.224.57.0/24;
}

这样,仅来自以上IP地址的请求才会输出到debug级别的日志,其他请求仍然沿用error_log中配置的日志级别(需要确保在执行configure时已经加入了–with-debug参数)。

(6)限制coredump核心转储文件的大小

语法:worker_rlimit_core size;
核心转储(core dumps):当进程发生错误或收到信号而终止时,系统会将进程执行时的内存内容(核心印象)写入一个文件(core文件),以作为调试只用。
当Nginx进程出现一些非法操作导致进程被操作系统强制结束时,会产生core文件,可以从core文件获取当时的堆栈、寄存器等信息,不加限制可能高达几GB,导致占满磁盘。

(7)指定coredump文件生成目录

语法:working_directory path;
确保worker进程有权限项working_directory指定的目录写入文件。

正常运行的配置项

(1)定义环境变量

语法:env VAR|VAR=VALUE;
可以让用户直接设置操作系统上的环境变量。例如:env TESTPATH=/tmp/;

(2)嵌入其他配置文件

语法:include pathfile;
include 配置可以将其他配置文件嵌入到当前的nginx.conf文件中,它的参数既可以时绝对路径,也可以是相对路径(相对域Nginx的配置目录)。

include mime.types;
include vhost/*.conf;

(3)pid文件的路径

语法:pid path/file;
默认:pid logs/nginx.pid
保存master进程ID的pid文件存放路径。默认与configure执行时的参数*–pid-path*所指定的路径是相同的,确保Nginx有权在目标中创建pid文件,该文件直接Nginx是否可以运行。

(4)Nginx worker进程运行的用户及用户组

语法:user username[groupname];
默认:user nobody nobody;
user用于设置master进程启动后,fork出的worker进程运行在哪个用户和用户组下。当按照user username; 设置时,用户名与用户组名相同。若用户在configure命令执行时使用了参数 –user=username–group=groupname,此时nginx.conf将使用参数中指定的用户和用户组。

(5)指定Nginx worker进程可以打开的最大句柄描述符个数

语法:worker_rlimit_nofile limit;

(5)限制信号队列

语法:worker_rlimit_sigpending limit;
当某个用户的信号队列满了,这个用户再发送的信号量会被丢掉。

优化性能的配置项

(1)Nginx worker进程个数

语法:worker_processes number;
默认:``worker_processer 1;

  • 每个worker进程都是单线程的进程;
  • 如果模块确认不会出现阻塞式的调用,有多少CPU内核就应该配置多少个进程,反之就需要多配置一些worker进程;
  • worker进程数量多于CPU内核数时,会增加进程间切换带来的消耗。
  • (2)绑定Nginx worker 进程到指定的CPU内核

语法:worker_cpu_addinity cpuimask[cpumask...];
如果多个worker进程都在抢同一个CPU,会出现同步问题,如果每一个worker进程独享一个CPU,就在内核的调度策略上实现了完全的并发。
例如,有4颗CPU内核

worker_processes 4;
worker_cpu_affinity 1000 0100 0010 0001;

(3)SSL硬件加速

语法:ssl_engine device;
使用OpenSSL提供的命令查看是否有SSL硬件加速设备:openssl engine -t

(4)系统调用gettimeofday的执行效率

语法:timer_resolutiong t;
默认情况下, 每次内核的事件调用(如epoll、 select、 poll、 kqueue等) 返回时, 都会执行一次gettimeofday, 实现用内核的时钟来更新Nginx中的缓存时钟。 在早期的Linux内核中,gettimeofday的执行代价不小, 因为中间有一次内核态到用户态的内存复制。 当需要降低
gettimeofday的调用频率时, 可以使用timer_resolution配置。 例如, “timer_resolution100ms; ”表示至少每100ms才调用一次gettimeofday。但在目前的大多数内核中, 如x86-64体系架构, gettimeofday只是一次vsyscall, 仅仅对共享内存页中的数据做访问, 并不是通常的系统调用, 代价并不大, 一般不必使用这个配置。
而且, 如果希望日志文件中每行打印的时间更准确, 也可以使用它。

(5)Nginx worker进程优先级设置

语法:worker_priority nice;
默认:worker_priority 0;
用于设置Nginx worker进程的nice优先级。

事件类配置项

(1)是否打开accept锁

语法:accept_mutex[on|off];
默认:accept_mutex on;
accept_mutex 是Nginx的负载均衡锁,可以让多个worker进程轮流地、序列化地与新的客户端建立TCP连接。当某一个worker进程建立连接的数量达到worker_connections配置的最大连接数的7/8时,会大大地减小该worker进程试图建立新TCP连接的机会,以此实现所有worker进程之上处理的客户端请求数尽量接近。如果关闭它,建立TCP连接的耗时会更短但worker进程之间的负载会非常不均衡。

(2)lock文件的路径

语法:lock_file path/file;
默认:lock_file logs/nginx.lock;
由于编译程序、操作系统架构等因素导致Nginx不支持原子锁,此时会用文件锁实现accept锁。

(3)使用accept锁后到真正建立连接之间的延迟时间

语法:accept_mutex_delay Nms;
默认:accept_mutex_delay 500ms;
在使用accept锁后, 同一时间只有一个worker进程能够取到accept锁。 这个accept锁不是阻塞锁, 如果取不到会立刻返回。 如果有一个worker进程试图取accept锁而没有取到, 它至少要等accept_mutex_delay定义的时间间隔后才能再次试图取锁。

(4)批量建立新连接

语法:multi_accept[on|off];
默认:multi_accept off;
当时间模型通知有新连接时,尽可能地对本次调度中客户端发起的所有TCP请求都建立连接。

(5)选择事件模型

语法:use[kqueue|rtsig|epoll|/dev/poll|select|poll|eventport];
默认:Nginx会自动使用最适合的事件模型

(6)每个worker的最大连接数

语法:worker_connections number;
定义每个worker进程可以同时处理的最大连接数

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

静态Web服务器的主要功能由ngx_http_core_module模块(HTTP框架的主要成员)实现。

虚拟主机与请求的分发

由于IP地址的数量有限,因此经常存在多个主机域名对应着同一个IP地址的情况,这时在nginx.conf中就可以按照server_name并通过server块来定义虚拟主机,每个server块就是一个虚拟主机,它只处理与之相对应的主机域名请求。

(1)监听端口

语法:listen address:port[default(deprecated in 0.8.21)|default_server|backlog=num|recvbuf=size|sndbuf=size|accept_filter|deferred|bind|ipv6only=[on|off]|ssl]];
配置块:server
listen 参数决定Nginx服务如何监听端口。在listen后可以只加IP地址、端口或主机名,非常灵活,例如:

listen 127.0.0.1:8000;
listen 127.0.0.1; #不加端口时,默认监听80端口
listen 8000;
listen *:8000;
listen localhost:8000;
#IPV6
listen [::]:8000;
listen [fe80::1];
listen [:::a8c9:1234]:80;
listen 443 default_server ssl;
listen 127.0.0.1 default_server accept_filter=dataready backlog=1024;
  • default: 将所在的server块最哦为整个Web服务的默认server块。如果没有此参数,那么会将以在nginx.conf中找到的第一个server块作为默认server块;
  • default_server: 同上;
  • backlog=num: 表示TCP中backlog队列的大小。默认为-1,表示不予设置。在TCP建立三次握手的过程中,进程还没有开始处理监听句柄,这是backlog队列将会放置这些新连接。如果backlog队列已满,还有新的客户端试图通过三次握手建立TCP连接,这是客户端将会建立连接失败;
  • rcvbuf=size: 设置监听句柄的SO_RCVBUF参数;
  • sndbuf=size: 设置监听句柄的SO_SNDBUF参数;
  • accpet_filter: 设置accpet过滤器,址对FressBSD操作系统有用;
  • deferred: 在设置该参数后,若用户发起建立连接请求,并且完成了TCP的三次握手,内核也不会为了这次的连接调度worker进程来处理,只有用户真的发送请求数据时(内核已经在网卡中收到请求数据包),内核才会唤醒worker进程处理这个连接。这个参数适用于大并发的情况下,它减轻了worker进程的负担。
  • bind: 绑定当前端口/地址对,127.0.0.1:8000.只有同时对一个端口监听多个地址时才会生效。
  • ssl: 在当前监听的端口上建立的连接必须基于SSL协议。

(2)主机名称

语法:server_name name[...];
默认:server_name "";
配置快:server
server_name 后可以跟多个主机名称。
在开始处理一个HTTP请求时,Nginx会提取出header头中的Host,与每个server中的server_name进行匹配,一次决定到底由哪一个server块来处理这个请求。有可能一个Host与多个server块中的server_name都匹配,这时就会根据匹配优先级来选择实际处理的server块。

  1. 首先选择所有字符串完全匹配的server_name,如www.testweb.com.
  2. 其次选择通配符在前面的server_name,如*.testweb.com;
  3. 再次选择通配符在后面的server_name,如www.testweb.*;
  4. 最后选择使用正则表达式才匹配的server_name,如~^.testweb.com$.

如果Host与所有server_name都不匹配,将会按下列顺序选择处理的server块:

  1. 优先选择在listen配置项后加入 [default|default_server] 的server块;
  2. 找到匹配listen端口的第一个server块;
    (Nginx正是使用server_name配置项针对特定Host域名的请求提供不同服务,以此实现虚拟主机功能)

(3)server_name_hash_bucket_size

语法:server_name_hash_bucket_size size;
默认:server_name_hash_bucket_size 32|64|128;
配置块:http、server、location
为了提高快速寻找到相应server name的能力,Nginx使用散列表来存储server name。server_names_hash_bucket_size设置了每个散列桶占用的内存大小。

(4)server_name_hash_max_size

语法:server_name_hash_max_size size;
默认:server_name_hash_max_size 512;
配置块:http、server、location
server_name_hash_max_size 会影响散列表的冲突率。server_name_hash_max_size 越大,消耗的内存越多,但散列key的冲突率则会降低,检索速度也会更快。反之消耗的内存越小,冲突率增高。

(5)重定向主机名称的处理

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

用HTTP proxy module配置一个反向代理服务器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值