Nginx学习之基础(1)

141 阅读16分钟

Nginx学习之基础(1)

本笔记是参考《黑马程序员Nginx教程》总结,供学习查阅

1.介绍

官网文档

image-20220912121133496

2.目录

2.1 Linux目录

使用tree可以查看大致目录结构,如下:

tree /usr/local/nginx (tree后面跟的是Nginx的安装目录)

image-20220905211434983

没有tree,可以执行 yum install -y tree 进行安装

==说明:==

CGI配置信息:CGI(Common Gateway Interface):通用网关【接口】,主要解决的问题是从客户端发送一个请求和数据,服务端获取到请求和数据后可以调用调用CGI【程序】处理及相应结果给客户端的一种标准规范。下面是一些网关接口的配置,比如fast,scgi等。.default这类文件,是配置文件的一个副本,当配置文件坏了,可以通过这个恢复默认设置

fastcgi.conf fastcgi相关配置文件 fastcgi.conf.default fastcgi.conf的备份文件 fastcgi_params fastcgi的参数文件 fastcgi_params.default fastcgi的参数备份文件 scgi_params scgi的参数文件 **scgi_params.default:**scgi的参数备份文件 uwsgi_params uwsgi的参数文件 uwsgi_params.default uwsgi的参数备份文件

编码相关

koi-utf、koi-win、win-utf这三个文件都是与编码转换映射相关的配置文件,用来将一种编码转换成另一种编码

重点配置文件

mime.types 记录的是HTTP协议中的Content-Type的值和文件后缀名的对应关系 mime.types.default mime.types的备份文件 nginx.conf 这个是Nginx的核心配置文件,这个文件非常重要,也是我们即将要学习的重点 **nginx.conf.default: ** nginx.conf的备份文件

默认页面配置

html 存放nginx自带的两个静态的html页面

  • 50x.html:访问失败后的失败页面
  • index.html:成功访问的默认首页

日志配置

logs 记录入门的文件,当nginx服务器启动后,这里面会有 access.log,error.log 和nginx.pid三个文件出现。

  • access.log:只要访问nginx,就会在这里打印访问记录
  • error.log:只要报错,就会把日志打印到这里
  • nginx.pid:记录当前进程的进程号

可执行二进制

sbin 是存放执行程序文件nginx,nginx 是用来控制Nginx的启动和停止等相关的命令。

2.2 window下目录如下:

image-20220905211911448

2.3 docker中默认目录

conf

/etc/nginx/nginx.conf

html

/usr/share/nginx/html

log

/var/log/nginx

二进制文件

/usr/sbin

3.核心配置文件介绍

去掉注释#的内容,则默认配置内容如下:

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

3.3.1 全局块

除了events、http等外的部分,都属于全局块,例如worker_processes 1

指令名 指令值; #全局块,主要设置Nginx服务器整体运行的配置指令

3.3.1.1 user指令

user:用于配置运行Nginx服务器的worker进程的用户和用户组。

语法user user [group]
默认值nobody
位置全局块

1.设置一个用户信息"www"

user www;

注意:设置用户www,前提是linux有这个用户,若没有这个用户,就会报错,所以可以通过 useradd www 添加一个用户

image-20220911170800835

当我们在配置文件里加了user这个指令后,那么请求访问nginx的时候,nginx能跳转或访问的文件,只能是www这个用户下的文件,而不能再访问root的相关文件了,即会报拒绝访问的权限错误

image-20220911171423425

综上所述,使用user指令可以指定启动运行工作进程的用户及用户组,这样对于系统的权限访问控制的更加精细,也更加安全

3.3.1.2 work process指令

master_process用来指定是否开启工作进程。

语法master_process on|off;
默认值master_process on;
位置全局块

worker_processes用于配置Nginx生成工作进程的数量,这个是Nginx服务器实现并发处理服务的关键所在。理论上来说workder process的值越大,可以支持的并发处理量也越多,但事实上这个值的设定是需要受到来自服务器自身的限制,建议将该值和服务器CPU的内核数保存一致

语法worker_processes num/auto;
默认值1
位置全局块
3.3.1.3 其他指令

**daemon:**设定Nginx是否以守护进程的方式启动。 守护式进程是linux后台执行的一种服务进程,特点是独立于控制终端,不会随着终端关闭而停止。

语法daemon on|off;
默认值daemon on;
位置全局块

pid用来配置Nginx当前master进程的进程号ID存储的文件路径。

语法pid file;
默认值默认为:/usr/local/nginx/logs/nginx.pid
位置全局块

该属性可以通过./configure --pid-path=PATH来指定

error_log用来配置Nginx的错误日志存放路径

语法error_log file [日志级别];
默认值error_log logs/error.log error;
位置全局块、http、server、location

1.该属性可以通过./configure --error-log-path=PATH来指定

2.其中日志级别的值有: debug|info|notice|warn|error|crit|alert|emerg,翻译过来为试|信息|通知|警告|错误|临界|警报|紧急,这块建议大家设置的时候不要设置成info以下的等级,因为会带来大量的磁盘I/O消耗,影响Nginx的性能。

include用来引入其他配置文件,使Nginx的配置更加灵活

语法include file;
默认值
位置any

3.3.2 events块

#events块,主要设置,Nginx服务器与用户的网络连接,这一部分对Nginx服务器的性能影响较大

events {
指令名 指令值;
}  

accept_mutex用来设置Nginx网络连接序列化

语法accept_mutex on|off;
默认值accept_mutex on;
位置events

在某一个时刻,客户端发来一个请求连接,Nginx后台是以多进程的工作模式,也就是说有多个worker进程会被同时唤醒,但是最终只会有一个进程可以获取到连接,如果每次唤醒的进程数目太多,就会影响Nginx的整体性能。如果将上述值设置为on(开启状态),将会对多个Nginx进程一个个来唤醒接收,就防止了多个进程对连接的争抢。

multi_accept用来设置是否允许同时接收多个网络连接

语法multi_accept on|off;
默认值multi_accept off;
位置events

如果multi_accept被禁止了,nginx一个工作进程只能同时接受一个新的连接。否则,一个工作进程可以同时接受所有的新连接

**worker_connections:**用来配置单个worker进程最大的连接数

语法worker_connections number;
默认值worker_commections 512;
位置events

这里的连接数不仅仅包括和前端用户建立的连接数,而是包括所有可能的连接数。另外,number值不能大于操作系统支持打开的最大文件句柄数量。

use用来设置Nginx服务器选择哪种事件驱动来处理网络消息

语法use method;
默认值根据操作系统定
位置events

注意:此处所选择事件处理模型是Nginx优化部分的一个重要内容,method的可选值有select/poll/epoll/kqueue等,之前在准备centos环境的时候,我们强调过要使用linux内核在2.6以上,就是为了能使用epoll函数来优化Nginx

举例设置,如下:

events{
    #设置Nginx网络连接序列化
    accept_mutex on;
    #设置Nginx的worker进程是否可以同时接收多个请求
    multi_accept on;
    #设置Nginx的worker进程最大的连接数
    worker_connections 1024;
    #设置Nginx使用的事件驱动模型
    use epoll;
}

测试:

#检查有无语法错误
./nginx -t
#重新加载启动
./nginx -s reload

3.3.3 http块

是Nginx服务器配置中的重要部分,代理、缓存、日志记录、第三方模块配置...

http {
	指令名 指令值;
	server { #server块,是Nginx配置和虚拟主机相关的内容
	指令名 指令值;
	location / {
	#location块,基于Nginx服务器接收请求字符串与
	location后面的值进行匹配,对特定请求进行处理
	指令名 指令值;
		}
	} .
	...
}

http块中可以配置多个server块,每个server块又可以配置多个location块。

3.3.3.1 MIME-Type

浏览器中可以显示的内容有HTML、XML、GIF等种类繁多的文件、媒体等资源,浏览器为了区分这些资源,就需要使用MIMEType。所以说MIME Type是网络资源的媒体类型。Nginx作为web服务器,也需要能够识别前端请求的资源类型。

在Nginx的配置文件中,默认有两行配置

    include       mime.types;
    default_type  application/octet-stream;

default_type用来配置Nginx响应前端请求默认的MIME类型

语法default_type mime-type;
默认值default_type text/plain;
位置http、server、location

在default_type之前还有一句include mime.types ,include之前我们已经介绍过,相当于把mime.types文件中MIMT类型与相关类型文件的文件后缀名的对应关系加入到当前的配置文件中

例如:

有些时候请求某些接口的时候需要返回指定的文本字符串或者json字符串,如果逻辑非常简单或者干脆是固定的字符串,那么可以使用nginx快速实现,这样就不用编写程序响应请求了,可以减少服务器资源占用并且响应性能非常快

我们可以在http里配置相关url路径

location /get_text {
	#这里也可以设置成text/plain
    default_type text/html;
    return 200 "This is nginx's text";
} 
location /get_json{
    default_type application/json;
    return 200 '{"name":"TOM","age":18}';
}
3.3.3.2 自定义服务日志

Nginx中日志的类型分access.log、error.log。

  • access.log:用来记录用户所有的访问请求。
  • error.log:记录nginx本身运行时的错误信息,不会记录用户的访问请求。

Nginx服务器支持对服务日志的格式、大小、输出等进行设置,需要使用到两个指令,分别是access_log和log_format指令。

access_log用来设置用户访问日志的相关属性

语法access_log path[format[buffer=size]]
默认值access_log logs/access.log combined;
位置http , server , location

参考

log_format用来指定日志的输出格式

语法log_format name [escape=default|json|none] string....;
默认 值log_format combined "...";
位置http

默认配置如下:

#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;
3.3.3.3 其他指令

sendfile用来设置Nginx服务器是否使用sendfile()传输文件,该属性可以大大提高Nginx处理静态资源的性能

语法sendfile on|off;
默认值sendfile off;
位置http、server、location

启用sendfile()系统调用来替换read()和write()调用,减少系统上下文切换从而提高性能,当 nginx 是静态文件服务器时,能极大提高nginx的性能表现,而当 nginx 是反向代理服务器时,则没什么用了

参考

keepalive_timeout用来设置长连接的超时时间

语法keepalive_timeout time;
默认值keepalive_timeout 75s;
位置http、server、location

如何客户端向服务端发送多个请求,每个请求都需要重新创建一次连接,效率相对来说比较多,使用keepalive模式,可以告诉服务器端在处理完一个请求后保持这个TCP连接的打开状态,若接收到来自这个客户端的其他请求,服务端就会利用这个未被关闭的连接,而不需要重新创建一个新连接,提升效率,但是这个连接也不能一直保持,这样的话,连接如果过多,也会是服务端的性能下降,这个时候就需要我们进行设置其的超时时间。

keepalive_requests用来设置一个keep-alive连接使用的次数

语法keepalive_requests number;
默认值keepalive_requests 100;
位置http、server、location

这个参数的真实含义,是指一个keep alive建立之后,nginx就会为这个连接设置一个计数器,记录这个keep alive的长连接上已经接收并处理的客户端请求的数量。如果达到这个参数设置的最大值时,则nginx会强行关闭这个长连接,逼迫客户端不得不重新建立新的长连接。相当于一个长链接可以有许多客户请求进行发送

3.3.3.4 server块

listen用来配置监听端口

语法listen address[:port] [default_server]...; listen port [default_server]...;
默认值listen *:80 | *:8000
位置server

举例:

server {
    listen       80; //监听80端口
    listen 127.0.0.1:8000; // listen localhost:8000 监听指定的IP和端口
    listen 127.0.0.1;  //监听指定IP的所有端口
    listen 8000; //监听指定端口上的连接
    listen *:8000; //监听指定端口上的连接
}
server{
	listen 8080;
    server_name  localhost;
	...
} 
server{
	listen 8081 default_server;
    server_name  localhost;
    ...
}

1.当我们输入http://192.168.44.128:8080/访问的时候,nginx会去所有server里找匹配的IP和端口,显然上面两个8080和8081的IP都不满足,那么nginx就会默认使用第一个server来作为响应并返回给用户

2.当我们在某个server中添加了default_server,用来将此虚拟主机设置成默认主机。所谓的默认主机指的是如果没有匹配到对应的address:port,则会默认执行的。那么当没有匹配上IP和端口的时候,就默认使用这个server作为响应并返回给用户而不管谁先谁后

**server_name:**用来设置虚拟主机服务名称 、可以配置域名

127.0.0.1 、 localhost 、域名[www.baidu.com | www.jd.com]

语法server_name name ...; name可以提供多个中间用空格分隔
默认值server_name "";
位置server

server_name的配置方式有三种

配置方式一:精确匹配

server {
    listen 80;
    server_name www.test1.cn www.test2.cn;
    ...
}

配置方式二:使用通配符配置

server {
	listen 80;
	server_name *.test1.cn www.test2.*;
	...
}

server_name中支持通配符"*",但需要注意的是通配符不能出现在域名的中间,只能出现在首段或尾段

配置三:使用正则表达式配置

server_name中可以使用正则表达式,并且使用==~==作为正则表达式字符串的开始标记

server{
	listen 80;
	server_name ~^www\.(\w+)\.com$;
	default_type text/plain;
	return 200 $1 $2 ..;
} 
# 注意 ~后面不能加空格,括号可以取值

模拟演示:

1.修改host文件

vim /etc/hosts
127.0.0.1 www.test1.cn
127.0.0.1 www.test2.cn

hosts将一些常用的网址域名与其对应的IP地址建立一个关联“数据库” ,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交DNS域名解析服务器进行IP地址的解析

windows: C:\Windows\System32\drivers\etc centos:/etc/hosts

注意:nginx在哪台机子上,就去修改那台机子的hosts,输入域名访问,也需要在hosts所在主机的浏览器里输入,不然域名不生效,比如当前是修改linux的hosts,那么就需要去linux的浏览器里输入

2.修改nginx配置,再通过域名访问

image-20220912150039440

演示没成功,需要看一下dokcer映射出去的路径是否有问题

匹配执行顺序

先精确匹配,最后是找默认default_server,若没有,则直接找第一个返回
No1:准确匹配server_name
No2:通配符在开始时匹配server_name成功
No3:通配符在结束时匹配server_name成功
No4:正则表达式匹配server_name成功
No5:被默认的default_server处理,如果没有指定默认找第一个server
3.3.3.5 location块

location用来设置请求的URI

语法location [ = | ~ | * | ^ |@ ] uri{...}
默认值
位置server,location

不带符号,要求必须以指定模式开始

server {
    listen 80;
    server_name 127.0.0.1;
    location /abc{
        default_type text/plain;
        return 200 "access success";
    }
} 
以下访问都是正确的
http://192.168.200.133/abc
http://192.168.200.133/abc?p1=TOM
http://192.168.200.133/abcdef

= : 必须与指定的模式精确匹配 (用于不包含正则表达式的uri前)

server {
    listen 80;
    server_name 127.0.0.1;
    location =/abc{
        default_type text/plain;
        return 200 "access success";
    }
} 
可以匹配到
http://192.168.200.133/abc
http://192.168.200.133/abc?p1=TOM
匹配不到
http://192.168.200.133/abc/
http://192.168.200.133/abcdef

~ : 用于表示当前uri中包含了正则表达式,并且区分大小写 ~*: 用于表示当前uri中包含了正则表达式,并且不区分大小写

server {
    listen 80;
    server_name 127.0.0.1;
    location ~^/abc\w${
        default_type text/plain;
        return 200 "access success";
    }
} 
以下访问都是正确的
http://192.168.200.133/abc
http://192.168.200.133/abc?p1=TOM
http://192.168.200.133/abcdef

注意:^~: 用于不包含正则表达式的uri前,功能和不加符号的一致,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了

**root:**设置请求的根目录

语法root path;
默认值root html;
位置http、server、location

path为Nginx服务器接收到请求以后查找资源的根目录路径

**alias:**用来更改location的URI

语法alias path;
默认值
位置location

两个有啥区别?

在**/usr/local/nginx/html目录**下创建一个 images目录,并在目录下放入一张图片mv.png图片

root方式配置如下:

location /images {
	root /usr/local/nginx/html;
}

当进行http://192.168../images/mv.png 访问时,nginx会根据上面配置进行路径拼凑成/usr/local/nginx/html/images+mv.png,注意:images这个url需要和root一起拼凑起来才是文件的真实路径

alias方式配置如下:

location /images {
	alias /usr/local/nginx/html/images;
}

当进行http://192.168../images/mv.png 访问时,nginx会根据上面配置直接用alias路径拼凑成/usr/local/nginx/html/images+mv.png,注意:这个是直接用alias里的值就可以访问文件了

综上

root的处理结果是: root路径+location路径
alias的处理结果是:使用alias路径替换location路径
alias是一个目录别名的定义,root则是最上层目录的含义。
如果location路径是以/结尾,则alias也必须是以/结尾,root没有要求

index设置网站的默认首页

语法index file ...;
默认值index index.html;
位置http、server、location

index后面可以跟多个设置,如果访问的时候没有指定具体访问的资源,则会依次进行查找,找到第一个为止

error_page设置网站的错误页面 ,

语法error_page code ... [=[response]] uri;
默认值
位置http、server、location......

1.可以指定具体跳转的url地址 ,比如后面跟网址

server {
	error_page 404 http://www.test1.cn;
}

2.可以指定重定向地址,比如后面跟/50x.html

server{
	error_page 404 /50x.html;
	error_page 500 502 503 504 /50x.html;
	location =/50x.html{
		root html;
	}
}

3.使用location的@符合完成错误信息展示 ,例如后面跟@jump_to_error

server{
	error_page 404 @jump_to_error;
	location @jump_to_error {
		default_type text/plain;
		return 404 'Not Found Page...';
	}
}

注意:可选项=[response]的作用是用来将相应代码更改为另外一个 ,例如error_page 404 =200 /50x.html ,当报404时,会自动转换成200返回给用户

4.使用

4.1 启停

4.1.1 信号量控制

对于Nginx的启停在linux系统中也有很多种方式,常用两种方式:

  • Nginx服务的信号控制
  • Nginx的命令行控制

Nginx默认采用的是多进程的方式来工作的,当将Nginx启动后,我们通过ps -ef | grep nginx命令可以查看

image-20220911132938564

从上图中可以看到,Nginx后台进程中包含一个master进程和多个worker进程,master进程主要用来管理worker进程,包含接收外界的信息,并将接收到的信号发送给各个worker进程,监控worker进程的状态,当worker进程出现异常退出后,会自动重新启动新的worker进程。而worker进程则是专门用来处理用户请求的,各个worker进程之间是平等的并且相互独立,处理请求的机会也是一样的。

只需要通过给master进程发送信号就可以来控制Nginx,这个时候我们需要有两个前提条件,一个是要操作的master进程,一个是信号。

信号作用
TERM/INT立即关闭整个服务
QUIT"优雅"地关闭整个服务(master进程会控制所有的work进程不再接收新的请求,等所有请求处理完后,在把work进程都关闭掉。)
HUP重读配置文件并使用服务对新配置项生效(master进程会把控制旧的work进程不再接收新的请求,等处理完请求后将旧的work进程关闭掉,然后根据nginx的配置文件重新启动新的work进程)
USR1重新打开日志文件,可以用来进行日志切割(后面可以跟其他命令来进行执行)
USR2平滑升级到最新版的nginx
WINCH所有子进程不在接收处理新连接,相当于给work进程发 送QUIT指令(让master进程控制不让所有的work进程在接收新的请求了,请求处理完后关闭work进程。注意master进程不会被关闭掉)

命令格式:kill -signal PID

signal:即为信号;PID即为获取到的master线程ID

image-20220911133038336

4.1.2 命令行控制

此方式是通过Nginx安装目录下的sbin下的可执行文件nginx来进行Nginx状态的控制,我们可以通过nginx -h来查看都有哪些参数可以用:

image-20220911142021683

-v      可查看nginx的版本。
-V      可查看nginx的详细信息,包括编译的参数。
-t      可用来测试nginx的配置文件的语法错误。
-T      可用来测试nginx的配置文件语法错误,同时还可以通过重定向备份nginx的配置文件。
-q      如果配置文件没有错误信息时,不会有任何提示,如果有错误,则提示错误信息,与-t配合使用。
-s      发送信号给master处理:
        stop    立刻停止nginx服务,不管请求是否处理完
        quit    优雅的退出服务,处理完当前的请求退出
        reopen  重新打开日志文件,原日志文件要提前备份改名。
        reload  重载配置文件
-p      设置nginx的安装目录路径,默认是编译时的安装路径
-c      设置nginx的配置文件,默认是家目录下的配置文件
-g      设置nginx的全局变量,这个变量会覆盖配置文件中的变量。

image-20220911162715999

image-20220911162824642

image-20220911163747905

image-20220911163144655

image-20220911163343530

4.2 升级

如何实现不关闭现有nginx服务,然后升级nginx?例如下面1.14.2升级到1.16.1

下面是通过信号量方式进行升级

1.源码编译1.16.1

进入安装目录,执行如下命令(注意:不要执行安装命令make install,只执行编译即可)
./configure
make

2.将Nginx1.16.1安装目录编译后的objs目录下的nginx文件,拷贝到原来/usr/local/nginx/sbin目录下

cd ~/nginx/core/nginx-1.16.1/objs
cp nginx /usr/local/nginx/sbin

3.发送信号USR2给Nginx的1.14.2版本对应的master进程

4.发送信号QUIT给Nginx的1.14.2版本对应的master进程

发送信号QUIT给Nginx的1.14.2版本对应的master进程

大致原理如下:

image-20220911124020743

1.当需要升级的时候,nginx会把master和worker重新打开一份,这时候nginx.pid记录右边新的pid,而pid.oldbin记录旧的pid

2.当确认升级成功后,那么就给旧的master发送QUIT命令,则停掉老的服务,后续就直接用新的服务了

image-20220911135934121

发送USR2信号给master进程,告诉master进程要平滑升级,这个时候,会重新开启对应的master进程和work进程,整个系统中将会有两个master进程,并且新的master进程的PID会被记录在/usr/local/nginx/logs/nginx.pid而之前的旧的master进程PID会被记录在/usr/local/nginx/logs/nginx.pid.oldbin文件中,接着再次发送QUIT信号给旧的master进程,让其处理完请求后再进行关闭