Nginx入门必备

1. 安装nginx

安装nginx之前,linux系统需要先安装先决条件,可以参考以下文章:https://www.cnblogs.com/zrbfree/p/6419043.html

nginx官方下载路径:http://nginx.org/download/

选择合适的版本下载下来之后解压:

[root@VM_92_224_centos nginx]# cd /usr/local/src
[root@VM_92_224_centos src]# ls
nginx-1.4.2  nginx-1.4.2.tar.gz

使用nginx目录下的configure检测一下安装条件:

[root@VM_92_224_centos src]# ./configure --prefix=/usr/local/nginx

编译并且安装:

[root@VM_92_224_centos src]# make && make install

在此过程中如果发生错误,类如:

根据文章顶部给出的链接,将需要的环境安装好就没问题了。另外确保不出现make: *** No targets specified and no makefile found. Stop.错误,每次安装完需环境后再次configure一下,然后再编译。如果你configure完之后输出的结果类如下图:

这是configure检测出的error,还是那句话,缺什么补什么。直至你能看到类似下图:

编译安装成功之后,在/usr/local/nginx能看到如下内容:

启动nginx:

[root@VM_92_224_centos nginx]# ./sbin/nginx 

到此,已经完成nginx的安装工作。

2. nginx配置

nginx在使用的过程中有三个会经常使用的文件,分别是/conf/nginx.conf,/logs/access.log,error.log。

nginx.conf文件中具体每个参数有什么用这里不多说,本文接下来该文件有相关配置时我会贴出来。

access.log文件记录着所有访问的请求,不管成功还是有异常都会记录请求信息和响应状态。

210.21.30.20 - - [02/Aug/2018:15:47:56 +0800] "GET /image/1.jpg HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
210.21.30.20 - - [02/Aug/2018:15:48:02 +0800] "GET /root/image/1.jpg HTTP/1.1" 404 570 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
210.21.30.20 - - [02/Aug/2018:15:48:37 +0800] "GET /image/1.jpg HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
60.191.38.78 - - [02/Aug/2018:15:50:24 +0800] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:47.0) Gecko/20100101 Firefox/47.0"

error.log文件记录着所有异常的访问请求,比如发生403和404等错误时,在error.log文件中能看到访问请求。

2018/08/02 15:12:59 [error] 15851#0: *35 open() "/root/image/root/image/1.jpg" failed (13: Permission denied), client: 210.21.30.20, server: localhost, request: "GET /root/image/1.jpg HTTP/1.1", host: "139.199.226.199"
2018/08/02 15:16:08 [emerg] 16000#0: getpwnam("nginx") failed in /usr/local/nginx/conf/nginx.conf:3
2018/08/02 15:17:25 [notice] 16061#0: signal process started
2018/08/02 15:18:11 [error] 16062#0: *36 open() "/root/image/root/image/1.jpg" failed (13: Permission denied), client: 210.21.30.20, server: localhost, request: "GET /root/image/1.jpg HTTP/1.1", host: "139.199.226.199"

在nginx服务启动之后,主进程master会创建work工作线程来处理nginx的请求。

[root@VM_92_224_centos logs]# ps -ef|grep nginx
root      5954     1  0 11:42 ?        00:00:00 nginx: master process ./sbin/nginx
root     16891  5954  0 15:35 ?        00:00:00 nginx: worker process
root     17713 16690  0 15:55 pts/2    00:00:00 grep nginx

对于nginx重启停止等操作时,我们关注的是nginx的master进程。比如nginx -s stop 或者kill -TERM 主进程号 或者kill -INT 主进程号。

2.1 访问静态文件

举个列子,通过nginx访问/root/image/下的图片文件。

配置一下nginx.conf:

location  ^~ /root/image/{
            root   /;
}
nginx的location配置详解
语法规则: location [=|~|~*|^~] /uri/ { … }
= 开头表示精确匹配
^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。
~ 开头表示区分大小写的正则匹配
~*  开头表示不区分大小写的正则匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则
/ 通用匹配,任何请求都会匹配到。

多个location配置的情况下匹配顺序为:
首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

在/root/image/目录下存放图片文件:

[root@VM_92_224_centos nginx]# cd /root/image/
[root@VM_92_224_centos image]# ls
1.jpg

修改完nginx.conf配置文件之后,使用nginx -s reload重启nginx服务。

此时在浏览器中访问http://139.199.226.199/root/image/1.jpg,查看access.log日志文件可以发现该请求。

210.21.30.20 - - [02/Aug/2018:16:06:24 +0800] "GET /root/image/1.jpg HTTP/1.1" 200 77850 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"

如果你再在尝试上面操作时发生403时,类似下图:

2018/08/02 15:06:18 [error] 15552#0: *34 open() "/root/image/root/image/1.jpg" failed (13: Permission denied), client: 210.21.30.20, server: localhost, request: "GET /root/image/1.jpg HTTP/1.1", host: "139.199.226.199"

请检查worker线程的用户权限问题,nginx的worker默认是nodoby。在使用ps -ef|grep nginx时可以查看到worker线程用户,可以改为你现在登陆的用户,修改该配置是在nginx.conf文件完成。

#user  nobody;
user root;

如果你再在尝试上面操作时发生404时,类似下图:

2018/08/02 15:25:04 [error] 16395#0: *37 open() "/root/image/root/image/1.jpg" failed (2: No such file or directory), client: 210.21.30.20, server: localhost, request: "GET /root/image/1.jpg HTTP/1.1", host: "139.199.226.199"

从日志中你就可以查看到是nginx.conf配置的location有错误的问题,检查一下修改之后,重新启动就可以了。

 

2.2 负载

2.2.1 使用nginx代理

准备一台通过8080端口访问的tomcat 8向外提供服务。

02-Aug-2018 17:47:39.329 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
02-Aug-2018 17:47:39.336 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
02-Aug-2018 17:47:39.338 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 704 ms

通过http://139.199.226.199:8080/就可以访问到tomcat的主页面了。

修改nginx.conf文件:

 location / {
            proxy_pass   http://139.199.226.199:8080;
 }

此时再通过访问http://139.199.226.199,不需要加8080端口,也可以提供tomcat服务。这就已经完成了一个简单的nginx代理服务。

代理多个tomcat服务,更改nginx.conf配置文件:

upstream yzr{
        server 139.199.226.199:8080;
        ip_hash;
}
 location / {
            proxy_pass   http://yzr/;
            proxy_set_header Host $host;
 }

通过http://139.199.226.199照样也可以访问到tomcat的主页面了。

2.2.2 nginx负载

准备一台通过8090端口访问的tomcat 7(以作区别)向外提供服务。

INFO: Starting ProtocolHandler ["http-bio-8090"]
Aug 02, 2018 6:12:05 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8099"]
Aug 02, 2018 6:12:05 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 1150 ms

通过http://139.199.226.199:8090/就可以访问到tomcat 7的主页面了。

对于Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
At least one of these environment variable is needed to run this program错误问题,请参考以下文章:

https://blog.csdn.net/to_baidu/article/details/52848620

更改nginx.conf配置文件:

upstream yzr{
        server 139.199.226.199:8090;
        server 139.199.226.199:8080;
}

重启nginx:

[root@VM_92_224_centos sbin]# ./nginx -s reload

nginx多台服务时默认会采用轮询的方式进行选择,刷新http://139.199.226.199/,你会发现一会是访问的tomat7的主页,一会是tomcat8的主页。

假设让其中一台宕机之后,看看nginx还能不能正常运行:

停掉tomcat8服务:

^C02-Aug-2018 18:37:57.338 INFO [Thread-5] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-8080"]
02-Aug-2018 18:37:57.343 INFO [Thread-5] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-8009"]
02-Aug-2018 18:37:57.343 INFO [Thread-5] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
02-Aug-2018 18:37:57.371 INFO [Thread-5] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-8080"]
02-Aug-2018 18:37:57.372 INFO [Thread-5] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-8009"]
02-Aug-2018 18:37:57.374 INFO [Thread-5] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-8080"]
02-Aug-2018 18:37:57.376 INFO [Thread-5] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-8009"]
[root@VM_92_224_centos bin]# 

刷新http://139.199.226.199/,完全没问题,一直都可以访问tomcat7.

 

2.3 均衡

 轮询(默认)

niginx默认采用的就是轮询的方式在多个server服务中选择其一:

upstream yzr{
        server 139.199.226.199:8090;
        server 139.199.226.199:8080;
}

指定权重

因为可能每个server机子的性能不一样,手动指定权重可以让性能更好的server处理更多请求。当不指定weight时,每个server的weight=1.

upstream yzr{
        server 139.199.226.199:8090 weight=1;
        server 139.199.226.199:8080 weight=2;
}

指定weight轮询几率,weight和访问比率成正比,此时8080端口server的访问量是8090server的接近两倍。

使用此种轮询的默认方式在均衡和容灾方面表现可以,但是存在一致性问题,由于是成比例的轮询,所以会导致类如session丢失等方面的问题。

 ip_hash

upstream yzr{
        server 139.199.226.199:8090;
        server 139.199.226.199:8080;
        ip_hash;
}

按请求访问ip的hash结果分配server,每个请求会固定访问同一个server,除非这个server宕机。这种方式可以解决正常情况下的一致性问题,可以避免类如session丢失。但是要求ip请求一致性,因为要根据具体的每个ip来选择server,均衡这方面会稍微比较差,像性能不一的server这种情况没办法控制有效均衡。

fair

upstream yzr{
        server 139.199.226.199:8090;
        server 139.199.226.199:8080;
        fair;
}

第三方的一种均衡策略,按server的响应时间来分配请求,响应时间短的优先分配,这种策略确实具有很强的自适应性,可以实时根据响应能力来选择server,但是实际的网络环境可能并没有那么理想客观,而且这种策略选择的方案在一致性和均衡相比前面都会稍差,因为有可能会照成性能好的server一直处于忙碌状态,而其他server相对空闲,另外不同server切换也会有类如session丢失等一致性问题。

url_hash

upstream yzr{
        server 139.199.226.199:8090;
        server 139.199.226.199:8080;
        hash $request_uri;
}

url_hash也是一种第三方的一致性hash策略,根据访问的url进行hash选择相应的server。这种方式一般都是配合缓存,或者说为了缓存命中一起使用。因为在多个server中每台server都有自己的缓存,如果请求被分配到不同的server中这会导致一个请求每台被分配到的server都会处理一次,照成资源(时间,流量)等浪费,缓存在每一台被分配到的server中会存在(缓存命中率低,因为理想情况下不管有多少server,请求只有第一次访问时会被处理,接下来同一个请求应该都走缓存)。所以为了确定缓存命中率,同一个url的请求会被分配到同一个server中(url_hash),配合缓存可以提高响应性能。url_hash在一致性和均衡性上和ip_hash策略相近,但是容灾能力差,因为一旦被分配到的server宕机,这部分请求将不会被处理。

补充:

在server中指定down,表示当前server不参与负载工作。

在server中指定backup,表示当前server只有在所有非backupserver都处于 忙碌或者down的时候,才会参与负载工作。

更多相关的五种nginx均衡的比较,可以参考:https://www.cnblogs.com/wpjamer/articles/6443332.html

2.4 日志管理

2.4.1 log_format

nginx.conf配置文件可以指定请求访问日志的格式,默认是main。

添加一种json格式的日志:

log_format logJson '{
                         "@timestamp": "$time_local", '
                         '"@fields": { '
                         '"remote_addr": "$remote_addr", '
                         '"remote_user": "$remote_user", '
                         '"time_local": "$time_local", '
                         '"request_time": "$request_time", '
                         '"status": "$status", '
                         '"http_host": "$http_host", '
						 '"request": "$request", '
                         '"request_method": "$request_method", '
						 '"request_body": "$request_body", '
                         '"http_referrer": "$http_referer", '
                         '"body_bytes_sent":"$body_bytes_sent", '
                         '"http_x_forwarded_for": "$http_x_forwarded_for", '
                         '"http_user_agent": "$http_user_agent" }
                         }';

字段

说明

$remote_addr客户端地址
$remote_user客户端用户名称
$time_local访问时间和时区
$request请求的URI和HTTP协议
$http_host请求地址,即浏览器中你输入的地址(IP或域名)
$statusHTTP请求状态
$upstream_statusupstream状态
$body_bytes_sent发送给客户端文件内容大小
$http_refererurl跳转来源
$http_user_agent用户终端浏览器等信息
$ssl_protocolSSL协议版本
$ssl_cipher交换数据中的算法
$upstream_addr后台upstream的地址,即真正提供服务的主机地址
$request_time整个请求的总时间
$upstream_response_time请求过程中,upstream响应时间

指定格式:

access_log  logs/access.log logJson;

get方式时打印的日志:

{
    "@timestamp": "03/Aug/2018:12:14:13 +0800",
    "@fields": {
        "remote_addr": "210.21.30.20",
        "remote_user": "-",
        "time_local": "03/Aug/2018:12:14:13 +0800",
        "request_time": "0.168",
        "status": "200",
        "http_host": "139.199.226.199",
        "request": "GET / HTTP/1.1",
        "request_method": "GET",
        "request_body": "-",
        "http_referrer": "-",
        "body_bytes_sent": "11253",
        "http_x_forwarded_for": "-",
        "http_user_agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
    }
}
curl -i  -d "arg1=1&arg2=2" "http://139.199.226.199"

post方式时打印的日志:

{
    "@timestamp": "03/Aug/2018:12:17:10 +0800",
    "@fields": {
        "remote_addr": "139.199.226.199",
        "remote_user": "-",
        "time_local": "03/Aug/2018:12:17:10 +0800",
        "request_time": "0.006",
        "status": "200",
        "http_host": "139.199.226.199",
        "request": "POST / HTTP/1.1",
        "request_method": "POST",
        "request_body": "arg1=1&arg2=2",
        "http_referrer": "-",
        "body_bytes_sent": "11253",
        "http_x_forwarded_for": "-",
        "http_user_agent": "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
    }
}

2.4.2 日志缓存

日志文件添加缓存机制:

open_log_file_cache max=1000 inactive=60s;

nginx日志在访问量大的情况下会频繁的执行打开写入操作,为了提高日志文件的性能,可以设置将新增的访问放在缓存里,然后根据设定一定的间隔一次性打开写入。

2.4.3 日志分割

同样是当访问量大的时候,access.log和error.log日志文件将会非常大,使用日志切割可以将日志按一定规则切割到不同的文件中

创建cut_ngnix_log.sh文件:

##自动分割Nginx日志脚本
#!/bin/bash
year=`date +%Y`
month=`date +%m`
day=`date +%d`
logs_backup_path="/usr/local/nginx/logs_backup/$year$month"           #日志存储路径

logs_path="/usr/local/nginx/logs/"                                        #要切割的日志路径
logs_access="access"                                                      #要切割的日志
logs_error="error"
pid_path="/usr/local/nginx/logs/nginx.pid"                                #nginx的pid

[ -d $logs_backup_path ]||mkdir -p $logs_backup_path
rq=`date +%Y%m%d`
#mv ${logs_path}${logs_access}.log ${logs_backup_path}/${logs_access}_${rq}.log
mv ${logs_path}${logs_error}.log ${logs_backup_path}/${logs_error}_${rq}.log
kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)

新增linux定时任务,有两种方式:

1.vi  /etc/crontab 

59 23 * * * root /usr/local/nginx/shell/cut_ngnix_log.sh   #定时每天23:59以root身份执行脚本

2.使用命令 crontab -e  然后直接编辑定时脚本,注意这里不需要指定用户

59 23 * * * /usr/local/nginx/shell/cut_ngnix_log.sh

nginx日志切割之后,在logs_backup下就能看到201808目录下的日志文件了。

[root@VM_92_224_centos 201808]# pwd
/usr/local/nginx/logs_backup/201808
[root@VM_92_224_centos 201808]# ll
total 68
-rw-r--r-- 1 root root 62217 Aug  3 16:28 error_20180803.log

然后logs目录下的nginx日志(access.log,error.log)只会存在切割之后的日志内容。

如果你在执行上面操作时操作切割动作没有执行,你会收到一封邮件(自动发过来)

You have new mail in /var/spool/mail/root

查看这个邮件内容可以看到执行定时任务发生的错误,类如没有权限:

又类如 定时任务编写错误(多添加了用户参数):

检查发现错误之后重新启动crond:

/etc/init.d/crond restart  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值