资讯专栏INFORMATION COLUMN

Linux运维:Nginx(1)

KitorinZero / 2028人阅读

摘要:作为反向代理的时候启用,决定开启或者关闭后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含的头。

软件介绍

与 Apache软件类似, Nginx ( “engme x")是一个开源的,支持高性能、高并发的 WWW服务器和代理服务软件。它是由俄罗斯人 Igor Sysoev开发的,最初被应用在勘罗斯的大型网站 www.rambler.ru 上,后来作者将源代码以类BSD许可证的形式开源出来供全球使用。

Nginx因具有高并发(特别是静态资源)占用系统资源少等特性,且功能丰富而逐渐流行起来。

在功能应用发面,Nginx不但是一个优秀的Web服务软件,还具有反向代理负载均衡功能和缓存服务功能。在反向代理负载均衡功能方面,它类似于大名鼎鼎的LVS负载均衡及Haproxy等专业代理软件,但是Nginx部署起来更为简单、方便;在缓存服务功能方面,它又类似于Squid等专业的缓存服务软件。
Nginx 的官方介绍见 http://nginx.org/en

nginx软件特性

HTTP服务器的特色及优点:

支持高并发:能支持几万并发连接(特别是静态小文件业务环境)

资源消耗少:在3万并发连接下,开启10个Nginx线程消耗的内存不到200MB

可以做HTTP反向代理及加速缓存、即负载均衡功能,内置对RS节点服务器健康检查功能这相当于专业的Haproxy软件或LVS的功能。

具备Squid等专业缓存软件等的缓存功能。

支持异步网络I/O事件横型epoll(Linux2.6+)

nginx的安装

nginx的安装可参考上一篇博文,这里不再啰嗦了。介绍几个nginx管理的命令吧。
启动

 $ /usr/local/nginx/sbin/nginx 

重新加载

 $ /usr/local/nginx/sbin/nginx -s reload

检查语法

$  /usr/local/nginx/sbin/nginx -t 

杀死进程

 $ pkill nginx
 或者 
 $ killall nginx
 # 如果现实没有killall命令,执行:yum install -y psmisc

nginx配置文件详解

nginx.conf配置文件全局结构大致如下:

全局配置(user,worker_process,error_log,pid)

events(网络连接部分,worker_connections)

http(最重要的部分,大部分功能都在这里)

server(虚拟主机相关,在http块里)

location(server里面)

全局配置部分
user nobody;
# 定义运行nginx服务的用户,还可以加上组,如 user nobody nobody;
worker_processes 1;
# 定义nginx子进程数量,即提供服务的进程数量,该数值建议和服务cpu核数保持一致。
# 除了可以定义数字外,还可以定义为auto,表示让系统自动调整。
error_log logs/error.log;
# 定义错误日志的路径,可以是相对路径(相对prefix路径的),也可以是绝对路径。
# 该配置可以在此处定义,也可以定义到http、server、location里。
error_log logs/error.log notice;
# 定义错误日志路径以及日志级别.
# 错误日志级别:常见的错误日志级别有[debug|info|notice|warn|error|crit|alert|emerg],级别越高记录的信息越少。
# 如果不定义默认是error
pid logs/nginx.pid;
# 定义nginx进程pid文件所在路径,可以是相对路径,也可以是绝对路径。
worker_rlimit_nofile 100000;
# 定义nginx最多打开文件数限制。如果没设置的话,这个值为操作系统(ulimit -n)的限制保持一致。
# 把这个值设高,nginx就不会有“too many open files”问题了。
events配置部分
worker_connections 1024;

定义每个work_process同时开启的最大连接数,即允许最多只能有这么多连接。

accept_mutex on;

当某一个时刻只有一个网络连接请求服务器时,服务器上有多个睡眠的进程会被同时叫醒,这样会损耗一定的服务器性能。Nginx中的accept_mutex设置为on,将会对多个Nginx进程(worker processer)接收连接时进行序列化,防止多个进程争抢资源。 默认就是on。

multi_accept on;

nginx worker processer可以做到同时接收多个新到达的网络连接,前提是把该参数设置为on。
默认为off,即每个worker process一次只能接收一个新到达的网络连接。

use epoll;

Nginx服务器提供了多个事件驱动器模型来处理网络消息。
其支持的类型有:select、poll、kqueue、epoll、rtsing、/dev/poll以及eventport

select:只能在Windows下使用,这个事件模型不建议在高负载的系统使用

poll:Nginx默认首选,但不是在所有系统下都可用

kqueue:这种方式在FreeBSD 4.1+, OpenBSD2.9+, NetBSD 2.0, 和 MacOS X系统中是最高效的

epoll: 这种方式是在Linux 2.6+内核中最高效的方式

rtsig:实时信号,可用在Linux 2.2.19的内核中,但不适用在高流量的系统中

/dev/poll: Solaris 7 11/99+,HP/UX 11.22+, IRIX 6.5.15+, and Tru64
UNIX 5.1A+操作系统最高效的方式

eventport: Solaris 10最高效的方式

http配置部分

官方文档 http://nginx.org/en/docs/

参考链接: https://segmentfault.com/a/11...

参考链接: https://segmentfault.com/a/11...

参考链接:http的header https://kb.cnblogs.com/page/9...

常见配置:

include       mime.types;  //cat conf/mime.types

定义nginx能识别的网络资源媒体类型(如,文本、html、js、css、流媒体等)

default_type  application/octet-stream;

定义默认的type,如果不定义改行,默认为text/plain.

log_format main  "$remote_addr - $remote_user [$time_local] "$request" "
                  "$status $body_bytes_sent "$http_referer" "
                  ""$http_user_agent" "$http_x_forwarded_for"";

定义nginx日志格式,其中main为日志格式的名字,后面的为nginx的内部变量组成的一串字符串。

access_log logs/access.log main; 

定义日志的路径以及采用的日志格式,该参数可以在server配置块中定义。

sendfile on;

是否调用sendfile函数传输文件,默认为off,使用sendfile函数传输,可以减少user mode和kernel mode的切换,从而提升服务器性能。对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。

sendfile_max_chunk 128k;

该参数限定Nginx worker process每次调用sendfile()函数传输数据的最大值,默认值为0,如果设置为0则无限制。

tcp_nopush on;

当tcp_nopush设置为on时,会调用tcp_cork方法进行数据传输。
使用该方法会产生这样的效果:当应用程序产生数据时,内核不会立马封装包,而是当数据量积累到一定量时才会封装,然后传输。这样有助于解决网络堵塞问题。默认值为on。举例:快递员收快递、发快递,包裹累积到一定量才会发,节省运输成本。

keepalive_timeout 65 60;

该参数有两个值,第一个值设置nginx服务器与客户端会话结束后仍旧保持连接的最长时间,单位是秒,默认为75s。
第二个值可以省略,它是针对客户端的浏览器来设置的,可以通过curl -I看到header信息中有一项Keep-Alive: timeout=60,如果不设置就没有这一项。
第二个数值设置后,浏览器就会根据这个数值决定何时主动关闭连接,Nginx服务器就不操心了。但有的浏览器并不认可该参数。

send_timeout

这个超时时间是发送响应的超时时间,即Nginx服务器向客户端发送了数据包,但客户端一直没有去接收这个数据包。
如果某个连接超过send_timeout定义的超时时间,那么Nginx将会关闭这个连接。

client_max_body_size 10m;

浏览器在发送含有较大HTTP包体的请求时,其头部会有一个Content-Length字段,client_max_body_size是用来限制Content-Length所示值的大小的。
这个限制包体的配置不用等Nginx接收完所有的HTTP包体,就可以告诉用户请求过大不被接受。会返回413状态码。
例如,用户试图上传一个1GB的文件,Nginx在收完包头后,发现Content-Length超过client_max_body_size定义的值,
就直接发送413(Request Entity Too Large)响应给客户端。

gzip on;

是否开启gzip压缩。

gzip_min_length 1k;

设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是20。建议设置成大于1k的字节数,小于1k可能会越压越大。

gzip_buffers 4 16k;

设置系统获取几个单位的buffer用于存储gzip的压缩结果数据流。4 16k代表分配4个16k的buffer。

gzip_http_version 1.1;

用于识别 http 协议的版本,早期的浏览器不支持 Gzip 压缩,用户会看到乱码,所以为了支持前期版本加上了这个选项。
如果你用了Nginx反向代理并期望也启用Gzip压缩的话,由于末端通信是http/1.1,故请设置为 1.1。

gzip_comp_level 6;

gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu)

gzip_types mime-type ... ;

匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的。在conf/mime.conf里查看对应的type。
示例:gzip_types text/plain application/x-javascript text/css text/html application/xml;

gzip_vary on;

和http头有关系,会在响应头加个 Vary: Accept-Encoding ,可以让前端的缓存服务器缓存经过gzip压缩的页面,例如,用Squid缓存经过Nginx压缩的数据。

gzip_proxied any;

Nginx作为反向代理的时候启用,决定开启或者关闭后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含”Via”的 header头。
以下为可用的值:

off - 关闭所有的代理结果数据的压缩

expired - 启用压缩,如果header头中包含 "Expires" 头信息

no-cache - 启用压缩,如果header头中包含 "Cache-Control:no-cache" 头信息

no-store - 启用压缩,如果header头中包含 "Cache-Control:no-store" 头信息

private - 启用压缩,如果header头中包含 "Cache-Control:private" 头信息

no_last_modified - 启用压缩,如果header头中不包含 "Last-Modified" 头信息

no_etag - 启用压缩 ,如果header头中不包含 "ETag" 头信息

auth - 启用压缩 , 如果header头中包含 "Authorization" 头信息

any - 无条件启用压缩

nginx服务优化 虚拟主机

1、虚拟主机概念

虚拟主机指的是,在web服务里是一个独立的网站站点,这个站点对应独立的域名,也可能是IP或端口,具有独立的程序及资源目录,可以独立地对外提供服务供用户访问。Nginx软件是使用一个server{}标签来标识一个虚拟主机的。一个web服务里可以有多个虚拟主机标签对,即可同时支持多个虚拟主机站点。

2、虚拟主机类型

常见的虚拟主机类型分三种

基于域名的虚拟主机

基于端口的虚拟主机

基于IP的虚拟主机

基于域名的虚拟主机是通过不同域名区分不同的虚拟主机,是企业应用最广泛的虚拟主机类型。
基于端口的虚拟主机是通过不同端口区分不同的虚拟主机,常用于公司内部的网站,比如不希望用户访问的网站后台等。
基于IP地址的虚拟主机是通过不同IP地址区分不同的虚拟主机,不常用很少见。

3、基于域名的虚拟主机配置
第一、编辑nginx配置文件nginx.conf,找到http{}块,在http{}块里面添加server{}标签,一个server{}代表一个虚拟主机。默认nginx.conf中有一个server{},这里修改一下,并配置两个基于域名的虚拟主机。
配置内容如下:

server {
        listen 80;
        server_name www.syushin.com;
        location / {
                root    html/com;
                index   index.html index.htm;
                }               
        }
server {
        listen 80;
        server_name www.syushin.org;
        location / {
                root    html/org;
                index   index.html index.htm;
                }               
        }        

可以看到基于域名的虚拟是在server_name中定义。

第二、创建域名对应的站点目录及文件。

$ mkdir ../html/com ../html/org
$ echo "I am syushin.com" >> ../html/com/index.html
$ echo "I am syushin.org" >> ../html/org/index.html

第三、配置域名解析
linux下
echo "192.168.30.7 www.syushin.com www.syushin.org" >> /etc/hosts

windows下
找到域名解析文件,通常在C:WindowsSystem32driversetchosts
添加内容:192.168.30.7 www.syushin.com www.syushin.org

第四、检查nginx语法,重新加载

$ /usr/local/nginx/sbin/nginx -t
$ /usr/local/nginx/sbin/nginx -s reload

第五、测试
linux下用curl命令测试

[root@lnmp conf]$ curl www.syushin.com
I am syushin.com
[root@lnmp conf]$ curl www.syushin.org
I am syushin.org

windows下用浏览器访问

这样就可以实现基于域名的虚拟主机了,用户输入不同的域名,访问不同的站点内容。而基于端口的虚拟主机是在server{}标签里的listen处修改监听的端口,比如listen 8080;或者listen 8090;
基于IP地址也是在listen里修改,格式如下:192.168.30.7:80;或者192.168.30.8:81
都很简单,就不再实际操作了。

规范优化nginx配置文件

nginx主配置文件是nginx.conf,可以将主配置文件包含所有虚拟主机的子配置文件统一放入extra目录里。
使用include参数实现,它可以放在nginx配置文件的任何地方,用法示例如下:

$ include extra/web01.conf

下面是我的使用方案:
$ vim nginx.conf在http{}删除默认的server{}标签,使用include extra/*.conf;

http
{
    include mime.types;
    default_type application/octet-stream;
    ...(这里省略)
    include extra/*.conf; #就是这一行
}

创建虚拟主机配置保存的目录

$ mkdir /usr/local/nginx/conf/extra

进入extra目录,创建虚拟主机配置文件。

$ vim web01.conf
# 内容如下
server {
        listen 80;
        server_name localhost;
        index index.html index.htm ;
        root html;
    }

这样通过主配置文件加上include包含的配置使得Nginx配置更加简单,清晰,规范。

域名重定向

在一个虚拟主机上有多个域名的时候,可以针对这多个域名做域名重定向。即访问A域名,浏览器会跳转到B域名。

server {
        listen 80;
        server_name www.syushin.com blog.syushin.cc;
        if ($host = "blog.syushin.cc" ) {
                rewrite  /(.*)  http://syushin.com/$1  permanent;
        }
        index index.html index.htm index.php;
        root html/web01;
}

虚拟主机配置如上:其中if语句就是域名重定向的配置了。$host变量就是域名,当访问域名是blog.syushin.cc的时候,就将域名跳转到www.syushin.com。
测试:

[root@lnmp ~]$ curl -x127.0.0.1:80 www.syushin.com -I
HTTP/1.1 200 OK # 正常访问状态码200
Server: nginx/1.14.2
Date: Sun, 10 Mar 2019 13:00:16 GMT
Content-Type: text/html
Content-Length: 12
Last-Modified: Sun, 10 Mar 2019 12:38:09 GMT
Connection: keep-alive
ETag: "5c850531-c"
Accept-Ranges: bytes

[root@lnmp ~]$ curl -x127.0.0.1:80 blog.syushin.cc -I 
HTTP/1.1 301 Moved Permanently # 状态码301
Server: nginx/1.14.2
Date: Sun, 10 Mar 2019 13:00:25 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: http://www.syushin.com/ # 重定向域名
用户认证 nginx访问日志

nginx访问日志就是用户访问网站的记录。可以针对不同格式记录日志。
配置nginx访问日志格式(这里只使用其中一部分):

   
  # 在nginx主配置文件中的http{}块里定义
 log_format main "$remote_addr $http_x_forwarded_for [$time_local]"
    " $host "$request_uri" $status"
    " "$http_referer" "$http_user_agent"";

参数说明:

变量 描述
$remote_addr 客户端IP(公网IP)
$http_x_forwarded_for 代理服务器的IP
$time_local 服务器本地时间
$host 访问主机名(域名)
$request_url 访问的url地址
$status 状态码
$http_referer referer
$http_user_agent user_agent

虚拟主机配置文件爬配置nginx访问日志保存目录以及使用主配置文件里的日志格式:

server {
        listen 80;
        server_name www.syushin.com blog.syushin.cc;
        if ($host = "blog.syushin.cc" ) {
                rewrite  /(.*)  http://www.syushin.com/$1  permanent;
        }
        index index.html index.htm index.php;
        root html/web01;
        location ~ .php$
        {
            include fastcgi_params;
            fastcgi_pass unix:/tmp/php-fcgi.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;
        }
        access_log /var/log/nginx/syushin_access.log main; # 这一行就是配置访问日志

}

创建日志文件目录

$ mkdir -p /var/log/nginx

检查语法、重新加载

[root@lnmp conf]$ $ /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@lnmp conf]$ /usr/local/nginx/sbin/nginx -s reload

测试,浏览器访问一次域名和在本地curl一下,查看是否有日志生成。

[root@lnmp nginx]$ curl -x127.0.0.1:80 blog.syushin.cc 

301 Moved Permanently

301 Moved Permanently


nginx/1.14.2
[root@lnmp nginx]$ cat syushin_access.log 192.168.30.1 - [11/Mar/2019:12:55:01 +0800] www.syushin.com "/" 304 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko" 127.0.0.1 - [11/Mar/2019:12:56:32 +0800] blog.syushin.cc "/" 301 "-" "curl/7.29.0"

这样配置访问日志就成功了。

日志切割

生产环境下,访问日志的量是很大的,如果把访问日志都放在一个文件里是会有很大影响的。因此将nginx访问日志进行切割是很有必要的。
如何切割日志?Linux有个日志切割工具logrotate。它的配置文件在/etc/logrotate.conf
查看配置文件

# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
dateext

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp and btmp -- we"ll rotate them here
/var/log/wtmp {
    monthly
    create 0664 root utmp
        minsize 1M
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

其中weekly表示按周切割;
rotate 4表示一次存储4个归档文件,对于第5个归档文件,时间最久的文档会被覆盖;
create以指定的权限创建全新的日志文件,同时logrotate也会重命名原始日志文件。
dataext表示以日期为格式命令新的日志文件

/var/log/wtmp {
        monthly
        create 0664 root utmp
            minsize 1M
        rotate 1
    }

上面代码块表示针对/var/log/wtmp这个目录下做日志切割,时间为一个月,只对文件大小大于1M文件进行切割。

对于nginx的日志切割
如果是yum安装的nginx,logrotate已经有默认的切割策略了/etc/logrotate.d/nginx
而编译安装的nginx就没有,需要手动定义,也可以用这个日志配置

$ cat /etc/logrotate.d/nginx 
/var/log/nginx/*.log {
    daily
    rotate 5
    missingok
    notifempty
    create 644 www www
    postrotate
      if [ -f /application/nginx/logs/nginx.pid ]; then
          kill -USR1 `cat /application/nginx/logs/nginx.pid`
      fi
endscript
}

logrotate工具对于防止因庞大的日志文件而耗尽存储空间是十分有用的。配置完毕后,进程是全自动的,可以长时间在不需要人为干预下运行。除了样例之外,自己还可以定制不同的样式满足需求。

访问日志不记录静态文件

在访问日志里,过滤掉一些图片、js、css等的请求日志。因为这样的日志没有多大意义,而且会占用很大的磁盘空间。
配置,编辑虚拟主机配置文件,添加location:

location ~* .(png|jpeg|jpg|gif|js|css|bmp)$
        {
                access_log off;
        }

上面规则表示凡是匹配到以.png|jpeg|jpg|gif|js|css|bmp结尾的文件,访问日志功能就关闭,即不记录访问静态文件的访问记录。*号表示不区分大小写,.号前面需要只用转义字符,|表示或者。
测试
在虚拟主机站点目录里添加资源文件test.png,然后curl访问一下、再查看日志是否有记录这条访问记录,如果没有则表示配置成功。
清空日志

$ > /var/log/nginx/syushin_access.log 

创建以png结尾的文件

$ touch /usr/local/nginx/html/web01/test.png    

访问

# 成功访问
[root@lnmp web01]$ curl -x127.0.0.1:80 www.syushin.com/test.png -I
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Mon, 11 Mar 2019 05:19:58 GMT
Content-Type: image/png
Content-Length: 0
Last-Modified: Mon, 11 Mar 2019 05:16:14 GMT
Connection: keep-alive
ETag: "5c85ef1e-0"
Accept-Ranges: bytes

查看日志

[root@lnmp web01]# cat /var/log/nginx/syushin_access.log 
[root@lnmp web01]# 

无日志记录,说明配置成功。

防盗链

盗链是指服务提供商自己不提供服务的内容,通过技术手段绕过其它有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其它服务提供商的服务内容,骗取最终用户的浏览和点击率。受益者不提供资源或提供很少的资源,而真正的服务提供商却得不到任何的收益。

防盗链就是防止上面情况的。常见的盗链是图片盗链,音频盗链,文件盗链。

Referer 防盗链
Referer在HTTP协议里有特殊的用途,当浏览器向服务器发送请求时,一般会带上
Referer头,告知服务器该请求是从哪个页面链接过来的。Referer经常被用于页面访问统计、图片防盗链等。

配置图片防盗链

location ~ .(png|gif|jpeg|bmp|mp3|mp4|flv)$
        {
                valid_referers none blocked server_name *.syushin.com;
                if ($invalid_referer){
                    return 403;
                }
        }

valid referers指的是白名单内的域名可以引用站点图片
none表示空referer,即直接打开站点的图片,而不是从其他网站打开本站点的图片文件,因此对直接访问站点内容的不做限制。
blocked指的是非法链接
server_name就是虚拟主机域名
后面的*.syushin.com就是白名单域名
这样配置后,当从其他网站引用本站的图片的时候,就引用不了了。
测试:使用curl -e选项测试,-e指定referer

$ curl -I -e "http://www.aaa.com/1.txt" http://www.syushin.com/test.png

出现403说明配置成功

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/40373.html

相关文章

  • Linux运维:CentOS7安装LNMP(nginx1.14.2、mariadb10.3.13、p

    摘要:启动服务启动查看端口进程进入数据库设置软连接设置密码用户登录至此安装完毕。编译安装下载软件包解压编译安装添加启动脚本内容如下设置开机启动启动,查看进程端口确定至此安装完毕。 前言 系统环境 [root@lnmp mysql]# cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) [root@lnmp mysql]...

    cocopeak 评论0 收藏0
  • 宝塔面板优惠券永久版:宝塔Linux面板仅2088元;宝塔windows面板仅2488元

    摘要:宝塔面板优惠券永久授权版多少钱宝塔面板让运维简单高效。目前,很多站长及企业可能会购买宝塔面板专业版或企业版,宝塔面板专业版仅元宝塔面板专业版仅元宝塔面板企业版仅元年宝塔面板企业版仅元年起。如宝塔数据同步工具主从复制。宝塔面板优惠券永久授权版多少钱?宝塔面板让运维简单高效。面板支持Linux与Windows系统。一键配置:LAMP/LNMP、网站、数据库、FTP、SSL,通过Web端轻松管理云...

    laznrbfe 评论0 收藏0
  • IT运维必备技能

    摘要:熟练使用等抓包工具底层大神级,内核其它素养处理方式除了技能,我觉得素养态度也可以谈谈安全运维人员的权限很大,所以一定要保证帐号私钥的安全。应该第一时间和开发部门确认,要求优化代码。进取心不断学习运维的知识范围很广,要不断学习。 写代码写了10多年, 从小公司到大公司, 前端, 后端, 数据库, 运维什么都做, 最后还是专职做运维了. 整理下运维的一些技能, 部分是网上资料并整理. Li...

    lily_wang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<