针对线上配置应用规范和配置调整规范,在这章着重说明。
4.1 Nginx的配置结构
4.1.1 服务结构
-
主进程 (Master Process): 主进程负责读取和验证配置文件、管理子进程、接收并处理信号以及在需要时重新加载配置文件或重启服务。主进程并不会直接处理客户端请求。
-
工作进程 (Worker Processes): 主进程在启动时会根据配置创建一定数量的工作进程。工作进程是真正处理客户端请求的部分,每个工作进程都是单线程的,利用事件驱动和非阻塞IO模型来高效处理并发连接。每个工作进程都能够同时处理数千个连接请求。
-
模块化结构 (Modular Architecture): Nginx 内部设计高度模块化,模块负责实现不同的功能,如HTTP处理、SSL支持、缓存、访问控制、负载均衡等。模块分为核心模块、HTTP模块、邮件服务模块、第三方模块等类别。
-
事件驱动机制: Nginx 采用高效事件处理模型,如epoll、kqueue或select等,能够在同一时间等待多个网络连接事件而不阻塞,并在事件发生时立即处理,这种设计使得Nginx在高并发场景下性能优异。
-
请求处理流程: 当接收到客户端请求时,工作进程会依次经过以下步骤:
- 解析请求头和URI
- 根据配置文件中的location指令匹配规则处理请求
- 可能会进行代理、重写、缓存等操作
- 最终将请求转发给后端服务器(如果是反向代理)或者直接处理静态资源请求
-
连接管理: Nginx 可以通过配置实现连接池和持久连接,优化对后端服务器的连接管理,以减少网络开销和提高性能。
4.1.2 配置文件整体结构
... #全局块
events {
...#events块
}
http #http块 {
... #http全局块
server #server块 {
... #server全局块
location [PATTERN] #location块 {
...
}
location [PATTERN] {
...
}
}
server {
...
}
... #http全局块
}
各个结构的功能作用
- 全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
- events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
- http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
- server块:配置虚拟主机的相关参数,一个http中可以有多个server。 5、location块:配置请求的路由,以及各种页面的处理情况。
配置文件详解:
user www www; #定义Nginx运行的用户和用户组
worker_processes 8; #nginx进程数,建议设置为等于CPU总核心数。
error_log /var/log/nginx/error.log info; #全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
pid /var/run/nginx.pid;#进程文件
#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相乘,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。 worker_rlimit_nofile 65535;
events {
use epoll; #选择事件模型
worker_connections 65535;#单个进程最大连接数(最大连接数=连接数*进程数)
}
4.2 线上调整配置的规范
4.2.1 配置文件应用规范
域名配置文件独立
- 对于每个网站或服务,创建独立的Nginx配置文件(如
example.com.conf
),并在其中定义该域名的监听端口、ServerName、Location规则、SSL证书路径等信息。这样有助于隔离不同服务之间的配置,便于维护和故障排查。 - 通常线上我们会在nginx.conf增加include vhosts/*.conf;配置,在/usr/local/nginx/conf/目录下新建vhosts目录,所有的域名配置均独立存放在vhosts文件中。
- 这台机器上服务多少域名,有多少配置?直接到对应配置目录下查看,一目了然。如果想要调整或修改哪个配置文件,直接打开对应文件即可,修改的内容不会影响到其他服务。
封禁文件独立
- 有时候,提供的服务会有一些非法恶意爬虫过来,会导致你的服务异常,而我们会去封禁对应的IP,或满足某一类条件的请求。
- 封禁操作是一个有效且危险的操作,因为你一旦配置错误会影响线上正常的用户,而有的人配置的封禁操作都柔和服务配置里面,配置越多,操作错误的概率越大,所以为了解决该类文件,建议将封禁文件独立出来,只需要在域名服务的配置中inexclude该文件即可。
- 为封禁IP、禁止恶意爬虫等规则创建独立的配置文件,比如
deny_list.conf
。当需要添加或修改封禁规则时,只需改动这个文件,然后重新加载Nginx配置即可。
证书文件独立
- SSL证书及其私钥不应直接放置在Nginx配置文件中,而是应该放在独立且受保护的目录下。在配置文件中通过绝对路径引用这些证书文件。这样做可以更好地保护敏感信息,同时使得证书管理和替换更加方便。
- 除了将证书文件独立目录以外,更应该保护该证书文件,例如例用堡垒机正对证书目录进行限制,不允许人为访问或修改,连看都不让看。
代码文件不要放在默认html下
- 不要把Web应用的代码(如PHP、Python、Java等)的静态资源或动态脚本直接放在Nginx默认的html目录下(如
/usr/local/nginx/html
)。应该将它们放置在专门的应用目录,并在Nginx配置中通过root
指令指向这个目录。这样有助于更好的文件管理,以及避免因默认设置带来的潜在安全风险。
日志跟随域名独立配置
- 对于每个域名或服务,为其分配独立的日志文件,可以在配置文件中通过
access_log
和error_log
指令指定。这样可以根据不同域名或服务产生的日志进行独立的分析和监控。 - 在生产环境,每个域名都有独立的access,error日志,一般会这样配置,例如在
example.conf中,
-
access_log logs/example_access.log main; error_log logs/example_error.log error;
-
- 如果在独立域名文件中你不配置相关日志配置时,单在nginx.conf中有配置日志信息,则该独立域名的日志默认记录在nginx.conf中配置日志目录文件中。
日志文件放在独立盘
- 将Nginx的访问日志和错误日志存储在非系统盘,如独立挂载的数据盘。这样可以避免日志文件占用过多系统盘空间,同时在系统盘满载时不会影响服务的正常运行。
- 一定要记得,生产环境下,记录日志磁盘可以满了,日志可以不记录,但是nginx服务不能停。
日志按需切割
- 使用日志切割工具(如logrotate)定期分割和归档日志文件,以保持日志文件的大小可控,同时方便长期保存和查询历史日志。在logrotate配置中,可以设置按日期、大小或其他条件进行日志文件的滚动和压缩。
- 规范日志和切割日志很有必要的,如果把所有域名的日志糅杂到一个日志文件access.log中,如果流量较大的情况下,这access.log日志文件必然会很大,假如你要查询其中某个域名的某个时间点的日志,你会非常痛苦。即便现在生产环境下,日志都是实时被收集到ELK中,如果你的原始文件过大,动辄几百G,再牛的程序读取也会慢的。
权限和所有权设置
- 确保Nginx运行的用户和组对配置文件、网页资源和日志目录具有适当的读写权限,但不宜赋予过高的权限,避免潜在的安全风险。
4.2.2 配置文件调整规范
备份原有文件
- 在调整Nginx配置文件之前,一定要先备份当前正在运行的配置文件。这一步是为了在修改过程中出现问题时,能够迅速恢复到先前正常工作的状态,避免服务长时间不可用。备份方法可以简单地复制文件,例如:
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
。
每一个location都有注释
- 在编写Nginx配置文件时,应在每个
location
区块前面或内部加入注释,清晰地说明该location的作用、匹配的URL规则以及处理逻辑。这有助于后期的维护和理解,使得其他开发者或运维人员能迅速明白配置的目的和作用。
新增location默认放在最后
- 在Nginx配置文件中,新增的
location
区块通常建议放在已有location列表的最后。这是因为在Nginx处理请求时,会按照配置文件中location出现的顺序进行匹配。越靠后的location具有更高的优先级,当URL匹配到多个location时,Nginx会选择最匹配的那个进行处理。将新增location放在后面,可以确保它不会无意间覆盖掉之前的配置。
加载配置文件之前必须要检查配置文件正确
-
正确检查和应用配置文件,可以确保服务的稳定性和一致性,避免因配置问题造成的意外停机。1nginx -s reload
4.3 系统自带日志切割程序logrotate
简介 logrotate是Linux操作系统上自带的一个日志文件管理工具,主要用于定期对系统和服务产生的日志文件进行切割、压缩、清理等操作,以避免日志文件过大导致磁盘空间不足,同时方便日志文件的归档和查阅。
4.3.1 logrotate服务参数
logrotate配置文件通常位于 /etc/logrotate.conf
,以及 /etc/logrotate.d/
下的独立服务配置文件。常用配置参数包括:
rotate count
: 表示日志文件最多保留多少个副本,默认是4个。daily
,weekly
,monthly
: 指定日志切割的频率。size size
: 当日志文件达到指定大小(单位KB、MB或GB)时进行切割。create mode owner group
: 创建新日志文件时的权限、属主和属组。prerotate
和postrotate
: 在日志切割前后执行的命令。compress
: 是否对转储的日志文件进行压缩。dateext
: 添加日期后缀到转储的文件名。missingok
: 如果日志文件不存在,不报错继续执行其他日志文件的处理。notifempty
: 如果日志文件为空,则不进行转储操作。copytruncate
: 转储后清空原日志文件而非重新创建一个新的日志文件。
4.3.2 logrotate最佳实践
- 分类管理:根据服务的不同,为每个服务的日志创建独立的配置文件,这样更易于管理和维护。
- 定期审查:定期检查logrotate的配置文件,确保其满足当前服务日志管理的需求,及时更新或清理不再使用的日志文件。
- 日志清理策略:设定合理的日志保留期限,避免无限制地保留日志导致磁盘空间紧张。
- 配合系统cron:logrotate通常由系统cron自动执行,确保在
/etc/cron.daily/
目录下的logrotate脚本正确设置和激活。
/path/to/nginx/access.log {
daily
rotate 7
compress
delaycompress
notifempty
create 0640 nginx nginx
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
在这个示例中,nginx的访问日志每天会被切割,保留7天的历史日志,切割后立即压缩,并在压缩完成后清除原文件。新日志文件的权限设置为nginx
用户和组,并在切割后通过发送信号给Nginx进程来通知其重新打开日志文件。
4.3.3 logrotate服务启停:
logrotate是由系统cron计划任务自动执行的,无需手动启动或停止。只需要确保系统cron服务正常运行,并检查/etc/crontab或/etc/cron.daily/logrotate文件确保其已被正确调度。在某些系统中,可以通过systemd.timer单元来安排logrotate的执行时间。
执行logrotate :
如果需要手动执行logrotate,可以使用以下命令:
1sudo logrotate /etc/logrotate.conf
或者,如果只想针对某一个配置文件执行:
1sudo logrotate /etc/logrotate.d/<specific_config_file>