Nginx的配置文件默认在Nginx程序安装目录的conf目录下,主配置文件为nginx.conf
,假设你的Nginx安装在/usr/local/webserver/nginx
目录下,那么默认的主配置文件为/usr/local/webserver/nginx/nginx.conf
,下面的代码是Nginx作为Web Server的完整配置示例
# 使用的用户和组
user www www;
# 制定工作衍生进程数(一般等于CPU的总核数或者总核数的两倍,例如两个四核CPU,则总核数为8)
worker_processes 8;
# 指定错误日志存放路径,错误日志记录级别可选项为:[ debug | info | notice| warn | error | crit]
error_log /data1/logs/nginx_error.log crit
# 指定pid存放路径
pid user/local/webserver/nginx/nginx.pid
# 指定文件描述符数量
worker_rlimit_nofile 51200;
events{
# 使用的网络I/O模型,Linux系统推荐采用epoll模型,FreeBSD系统推荐采用kqueque模型
use epoll;
# 允许的连接数
worker_connections 51200;
}
http{
include mime.types;
default_type application/octet-stream;
# 设置使用的字符集,如果一个网站有多种字符集,请不要随便设置,应该让程序员在HTML代码中通过Meta标签设置
#charset gb2312
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
larger_client_header_buffers 4 32k;
client_max_body_size 8m sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
# 开启gzip 压索
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m;
server {
listen 80;
server_name www.yourdomain.com yourdomain.com;
index index.html index.htm index.php;
root /data0/htdocs;
#limit_conne crawler 20;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 1h;
}
log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
' "$http_user_agent" $http_x_forwarded_for';
access_log /data1/logs/access.log access;
}
}
通过上面的nginx.conf配置文件示例,可以看出nginx.conf配置文件结构 主要由以下几部分构成:
events{
......
}
http{
......
server{
......
}
server{
......
}
......
}
虚拟主机使用的示特殊的软硬件技术,它把一台运行在因特网上是服务器主机分成台台的“虚拟主机”,每台虚拟主机都可以是一个独立的网站,可以具有独立的域名,具有完整的Intenet服务器功能(WWW 、FTP、Email等),同一台的虚拟主机之间是相互独立的。从网站访问者来看,每一台虚拟主机和一台独立的主机完全一样。
利用虚拟主机,不用为每一个要运行的网站提供一台单独的Nginx服务器或单独运行一组Nginx进程,虚拟主机提供了在同一台服务器、同一组Nginx进程上运行多个网站的功能。
在Nginx配置文件nginx.conf中,一个简化的虚拟主机的配置如下:
http{
server {
listen 80 default;
server_name _ *;
access_log logs/default.access.log combined;
location / {
index index.html;
root /data0/htdocs/htdocs;
}
}
}
和apache 一样,nginx 也可以配置多种类型的虚拟主机:一是基于IP的虚拟主机;二是基于域名的虚拟主机;三是基于端口的虚拟主机。
Linux和FreeBSD都允许添加IP别名,IP别名背后的概念很简单:可以在一块物理网卡上绑定多个IP地址。这样九能够使用在使用单一网卡的同一个服务器上运行过个基于IP的虚拟主机。设置IP的别名也非常容易,只需要配置系统上的网络接口,让它监听额外的IP地址。在Linux系统上,可以使用标准的网络配置工具(比如ifconfig
和route
命令)添加ip别名,以下是添加ip别名的示例。
先用ifconfig
命令查看改服务器的IP地址。下面这台服务器有一块物理网卡设备eth0和本地回环设备lo,eth0的IP地址为172.16.0.10,本地回环lo的IP地址为:127.0.0.1。
本地回环代表设备的本地虚拟接口,所以默认被看作是永远不会宕掉的接口。它的主要作用有两个:一是测试本机的网络配置,能PING 通127.0.0.1说明本机的网卡和IP协议安装都没有问题;另一个作用是某些server/client的应有程序在运行时必须调用服务器上的资源。一般要指定server的ip地址。但当程序要在一同台服务器上运行且没有别的server时就可以把server的资源装在本机上,server的ip地址为127.0.0.1也同样可以运行,如下面的代码所示:
[root@VM_0_10_centos nginx]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.0.10 netmask 255.255.240.0 broadcast 172.16.15.255
inet6 fe80::5054:ff:fe74:23c8 prefixlen 64 scopeid 0x20<link>
ether 52:54:00:74:23:c8 txqueuelen 1000 (Ethernet)
RX packets 20833987 bytes 2311384369 (2.1 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 21134010 bytes 4238378312 (3.9 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 37033 bytes 3048229 (2.9 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 37033 bytes 3048229 (2.9 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
如果要在网卡设备上添加两个ip别名172.16.0.11和172.16.0.12,可以通过以下的ifconfig
和route
命令实现
[root@VM_0_10_centos ~]# /sbin/ifconfig eth0:1 172.16.0.11 broadcast 172.16.15.255 netmask 255.255.240.0 up
[root@VM_0_10_centos ~]# /sbin/route add -host 172.16.0.11 dev eth0:1
[root@VM_0_10_centos ~]# /sbin/ifconfig eth0:2 172.16.0.12 broadcast 172.16.15.255 netmask 255.255.240.0 up
[root@VM_0_10_centos ~]# /sbin/route add -host 172.16.0.12 dev eth0:2
这时再执行ifconfig命令,就可以看到eth0
网卡设备上绑定了两个ip别名,如下所示:
[root@VM_0_10_centos ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.0.10 netmask 255.255.240.0 broadcast 172.16.15.255
inet6 fe80::5054:ff:fe74:23c8 prefixlen 64 scopeid 0x20<link>
ether 52:54:00:74:23:c8 txqueuelen 1000 (Ethernet)
RX packets 20841174 bytes 2312014292 (2.1 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 21141061 bytes 4239608974 (3.9 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.0.11 netmask 255.255.240.0 broadcast 172.16.15.255
ether 52:54:00:74:23:c8 txqueuelen 1000 (Ethernet)
eth0:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.0.12 netmask 255.255.240.0 broadcast 172.16.15.255
ether 52:54:00:74:23:c8 txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 37033 bytes 3048229 (2.9 MiB)
这时候从另外一台服务器Ping 172.16.0.11 和 172.16.0.12两个IP,如果能够 ping 通 ,则证明配置无误。但是通过 ifconfig
和 route
命令配置的IP别名会在服务器重启后会消失。不过可以通过将ifconfig
和route
两条命令添加到/etc/rc.local
文件中,让系统开机时自动运行。以下是相关命令:
在文件末尾添加以下内容,然后输入wq命令保存即可
/sbin/ifconfig eth0:1 172.16.0.11 bradcast 172.16.15.255 netmask 255.255.240.0 up
/sbin/route add -host 172.16.0.11 dev eth0:1
/sbin/ifconfig eth0:2 172.16.0.12 broadcast 172.16.15.255 netmask 255.255.240.0 up
/sbin/route add -host 172.16.0.12 dev eth0:2
下面开始配置基于IP的虚拟主机。无论是通过IP别名在一台服务器上配置多个IP地址,还是通过多块网卡在服务器上配置多个网卡,在Nginx中都能将其适配成基于IP的虚拟主机。
接下来,在Nginx配置文件(nginx.conf
)中分分别对 172.16.0.11 和 172.16.0.12 两个IP配置三个纯静态HTML支持的虚拟主机,代码如下所示:
http {
# 第一个虚拟主机
server {
# 监听的IP和端口
listen 172.16.0.11:80;
# 主机名
server_name: 172.16.0.11;
# 访问日志文件存放路径
access_log logs/server1.access.log combinbed;
location / {
# 默认首页文件,顺序从左到右,如果找不到index.html文件,则查找index.htm作为首页文件
index index.html index.htm;
# HTML 网页文件存放的目录
root /data0/htdocs/server1;
}
}
# 第二个虚拟主机
server {
# 监听的IP和端口
listen 172.16.0.12:80;
# 主机名
server_name 172.16.0.12;
# 访问日志文件存放路径
access_log logs/server2/.access.log combined;
location / {
# 默认首页文件,顺序从左到右,如果找不到index.html文件,则查找index.htm作为首页文件
index index.html index.htm;
# HTML 网页文件存放的目录
root /data0/htdocs/server2;
}
}
}
从上面的配置文件中可以看出,一段server{......}就是一个虚拟主机,如果要配置多个虚拟主机,建立多段server{}配置即可,非常方便。监听的IP和端口也可以不写IP地址,只写端口,把它配置成 listen 80,则表示监听该服务器上所有IP的80端口,可以通过server_name区分不同的虚拟主机。
基于域名的虚拟主机是最常见的一种虚拟主机,只需配置你的DNS服务器,将每个主机名映射到正确的IP地址,然后配置Nginx服务器,令其识别不同的主机名即可。这种虚拟机技术,让很多虚拟机可以共享一个IP地址,有效解决了IP地址不足的问题。如果没有特殊要求你必须使用基于IP的虚拟主机,那么建议你最好还是使用基于域名的虚拟主机。
接下了配置基于域名的虚拟主机。在以下的示例中配置了三个虚拟主机,第一个虚拟主机表示对所有域名为aaa.domain.com
的访问都由它来处理;第二个虚拟主机表示对所有域名为bbb.otherdomain.com
的访问都由它来处理;第三个虚拟主机表示对域名www.domain.com
、domain.com
以及除了aaa.domain.com
之外的所有*.domain.com
二级域名的访问都由它来处理。每个虚拟主机的网页文件都存放在了不同的目录,每个虚拟主机都使用了不同的日志文件来记录访问日志。配置代码如下所示:
http {
# 第一个虚拟主机
server {
# 监听的端口
listen 80;
# 主机名称
server_name aaa.domain.com;
# 访问日志文件存放路径
access_log logs/aaa.domain.com.access.log combined;
location / {
index index.html index.htm;
# HTML网页文件存放目录
root /data0/htdocs/aaa.domain.com;
}
}
# 第二个虚拟主机
server {
listen 80;
server_name bbb.otherdomain.com;
access_log logs/bbb.otherdomain.com.access.log combined;
location / {
index index.html index.htm;
root /data0/htdocs/bbb.otherdomain.com;
}
}
# 第三个虚拟主机
server {
listen 80;
server_name www.domain.com domain.com *.domain.com;
access_log logs/bbb.domain.com.access.log combined;
location /{
index index.html index.htm;
root /data0/htdocs/domain.com;
}
}
}
在前面的虚拟机配制中,已经使用了access_log作为日志记录。在这里我们详细介绍Nginx
访问日志文件的配置。
与Nginx日志相关的指令主要有两条:一条是log_format,用来设置日志的格式;另外一条是access_log,用来指定日志文件的存放路径、格式和缓存大小。两条指令在Nginx配置文件中的位置可以在http{...}之间,也可以在虚拟主机之间,即server{......}两个大括号之间。
log_format指令用来设置日志格式的语法如下:
log_format name format [format...]
其中的name用来定义格式名称,format用来定义。log_format有一个默认、无需设置的combined
的日志格式设置,相当于apache的日志格式,其具体参数如下:
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
你可以自定义一份日志记录格式,不过需要注意,log_format
指令设置的name
属性在nginx
配置文件中是不能重复的。
假设你将Nginx服务器作为web服务器,用于负载均衡设备、Squid、Nginx反向代理之后,就不能获取到客户端真实的IP地址了。原因是经过反向代理后,由于客户端和Web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的IP,通过$remote_addr
拿到的将是反向代理服务器的IP地址。但是,反向代理服务器在转发请求的HTTP头信息中可以增加X-Forwarded--For IP地址:
log_format mylogformat '$http_x_forwarded_for $remote_user [$time_local] '
'"$request" status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
在日志格式中:
$remote_user
用来记录远程客户端名称;$time_local
用来记录访问时间与时区;$request
用于记录请求URL与Http协议;$status
用于记录请求状态,例如成功时状态为200, 失败时状态为500, 页面找不到时状态为404;$body_bytes_sent
用于记录发送给客户端文件主体内容的大小;$http_referer
用于记录从哪个页面链接访问过来的;$http_user_agent
用于记录客户端浏览器相关信息用log_format
指令设置了日志格式之后,需要用access_log
指令指定日志文件存放路径。access_log
指令的语法如下:
access_log path [format [buffer=size | off]]
其中path
表示日志文件的存放路径,format
表示用log_format
指令设置的日志格式的名称;buffer=size
表示设置内存缓冲区的大小,例如可以设置buffer=32k
(1)如果不想记录日志,也可以使用以下指令关闭日志记录:
access_log off;
(2)如果要使用默认的conbined格式日志记录,可以使用以下示例:
access_log /data/logs/filename.log
或者 access_log /data/logs/filename.log conbined
(3) 如果使用自定义的日志格式记录,可以使用以下示例
log_format mylogformat '$http_x_forwarded_for $remote_user [$time_local] '
'"$request" status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /data1/logs/access.log mylogformat buffer=32k;
(4)在Nginx 0.7.4版本之后,access_log指令中的日志文件可以包含变量,例如:
access_log /data1/logs/$server_name.log combined;
假设server_name
指令设置的虚拟主机名称为test.domain.com
,那么access_log指令将把访问日志记录在
/data1/logs/test.domain.com.log
文件中。
如果日志文件路径中存在一些变量,将存在以下一些限制:
(1) Nginx
进程设置的用户和组必须有对该路径创建文件的权限,假设nginx
的user
设置的用户名和用户组都是www
,而/data1/logs/
目录的用户名和用户组为root,则日志文件/data1/logs/test.domain.com.log
将无法被nginx创建;
(2)缓冲不会被使用;
(3) 对于每一条日志记录,日志文件都将先打开文件,再写入日志记录,然后马上关闭。为了提高包含变量的日志文件存放路径的性能,须使用open_log_file_cache
指令设置经常被使用的日志文件描述符缓存。open_log_file_cache
主要是用来设置含有变量的日志路径的文件描述符缓存,它的语法如下:
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time] | off
该指令默认是禁止的,等他于open_log_file_cache off
open_log_file_cache
指令的各项参数如下:
open_log_file_cache
指令的设置示例如下:
open_log_file_cache max=1000 inactive=20s min_uses=2 valid=1m;
以上valid=1m
表示设置1分钟检查一次。
生产环境的日志服务器,由于访问日志文件增长速度非常快,日志文件太大会严重影响服务器的运行效率。同时,为了方便对日志进行分析计算,必须对日志文件进行定时切割。定时切割的方式有按月切割、按天切割和按小时切割。最常用的是按天切割。
Nginx不支持像Apache一样使用cronolog
来轮训日志,但是可以使用以下方式来实现日志文件的切割:
mv /data1/logs/access.log /data1/logs/20210720.log
kill -USER1 Nginx 主进程号
首先,通过mv
命令将日志文件重命名为/data1/logs/20210720.log
,然后发送kill -User1
信号给Nginx 的主进程号,让Nginx重新生成一个日志文件/data1/logs/access.log
。如果nginx.conf
配置文件中使用了
pid/usr/local/webserver/nginx/nginx.pid;
指令,指定了pid文件的存放路径,我们可以通过cat 这个pid文件获得Nginxd 的主进程号,命令如下:
kill -USER1 `cat /usr/local/webserver/nginx/nginx.pid`
如果想每天定时切割日志,还需要借助crontab
。我们可以写一个按天切割的日志,按年、月份目录存放日志的shell脚本:
vim /usr/local/webserver/nginx/cut_nginx_log.sh
以下是添加的脚本内容,添加完后保存退出
# !/bin/bash
# 这个脚本必须在每天的 00:00 运行
logs_path="/data1/logs"
mkdir -p ${logs_path}$(date -d "yesterday" + "%Y")/$(date -d "yesterday" + "%m")/
mv ${logs_path}access.log ${logs_path}$(date -d "yesterday" + "%Y")/$(date -d "yesterday" + "%m")/access_$(date -d "yesterday" + "%Y%m%d").log
kill -USER1 `cat /usr/local/webserver/nginx/nginx.pid`
另外,配置crontab
每天凌晨00:00执行这个脚本
crontab -e
输入以下内容后保存
00 00 * * * /bin/bash /usr/local/webserver/nginx/sbin/nginx_cut_log.sh
gizp(GNU-ZIP)是一种压缩技术,经过gip压缩后页面大小可以变为原来的30%甚至更小,这样用户浏览页面时速度就快得多。gzip的压缩页面需要浏览器和服务双方都支持,实际上就是服务端压缩传到浏览器后浏览器解压并解析。目前主流的浏览器包括Google Chrome、IE、Firfox、Opera等大多数都支持gip压缩。
Nginx的压缩输出由一组gzip压缩指令来实现,gzip压缩输出的相关指令位于http{....}两个大括号之间:
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/java-script text/css applciation/xml;
gzip_vary on;
我们经常看到一些开源软件的下载页面是可以自动列目录的,这一功能Apache可以实现,Nginx同样可以实现。前提条件时当前目录下不存在用index
指令设置的默认首页文件。如果须在某虚拟主机的location /{...}
目录控制中配置自动列目录,只需加上如下配置代码:
location / {
autoindex on;
}
另外还有两项跟自动列目录相关的指令,分别为:
# 设定索引文件的大小单位(B、KB、MB或GB)
autoindex_exact_size [on|off];
# 开启以本地时间来显示文件时间的功能。默认为关闭(GMT时间)
autoindex_localtime [on|off];
浏览器缓存(Browser Caching)是为了加速浏览是为了加速浏览,浏览器在用户磁盘上对用户最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示这个文档,这样就可以加速页面的浏览。缓存的方式节约了网络的资源,提高了网络的效率。
浏览器缓存可以通过expires
指令输出Headers
头来实现,expires
指令的语法如下:
expires [time|epoch|max|off]
expires off
Header
头信息的Expires
和Cache-control
,起到控制页面缓存的作用。Expires
头标的值将通过当前系统时间加上设定的times
值来获得。epoch
指定 Expires
的值为 1 January,1970,00:00:01 GMT。max
指定 Expires
的值为 31 December 2037 23:59:59 GMT, "Cache-Control"的值为10年;-1为指定Expires
的值为服务器当前时间-1s,即永远过期。Cache-Control
头标的值由指定的时间来决定:
负数 :Cache-Control: no-cache
; 正数或零:Cache-Control: max-age=#,#
(单位:秒) Expires
和Cache-Control
的值假设一个HTML页面中会引用一些JavaScript文件
、图片文件,而这些格式的文件很少被修改,则可以通过expires
指令设置浏览器缓存。
例如对常见格式的图片、Flash文件在浏览器本地缓存30d,对js和css文件在浏览器本地缓存1小时,配置示例如下:
location ~ .*\.(git|jpg|jpeg|png|bmp|swf)${
expires 30d;
}
location ~ .*\.(js|css)?${
expires 1h;
}
《实战Nginx》第三章内容:Nginx的基本配置与优化
[1] 我想在同一个域名下部署多个项目怎么办?一文搞懂Nginx同域名下部署多个vue项目