Nginx宝典:理论到实际
发表于 2019-07-27 14:14
最近小猪站长花了一些时间对nginx常用的技能知识点进行了总结,并通过一些常见的实际案例将nginx的很多小知识点联系起来。
首先是进入nginx目录启动脚本,准备初始化环境:
[root@idea-centos nginx]# cd ./sbin/
[root@idea-centos sbin]# ll
total 3528
-rwxr-xr-x. 1 root root 3611160 Dec 26 16:43 nginx
[root@idea-centos sbin]# ps -ef|grep nginx
root 7270 7194 0 10:42 pts/1 00:00:00 grep --color=auto nginx
[root@idea-centos sbin]# ./nginx
[root@idea-centos sbin]# ps -ef|grep nginx
root 7272 1 0 10:42 ? 00:00:00 nginx: master process ./nginx
nobody 7273 7272 0 10:42 ? 00:00:00 nginx: master process ./nginx
root 7275 7194 0 10:42 pts/1 00:00:00 grep --color=auto nginx
启动成功后,可以通过curl执行访问测试。
首先使用ip add查看地址信息(小猪站长使用虚拟机):
[root@idea-centos sbin]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:ea:63:63 brd ff:ff:ff:ff:ff:ff
inet 192.168.43.235/24 brd 192.168.43.255 scope global noprefixroute dynamic ens33
valid_lft 2922sec preferred_lft 2922sec
inet6 2409:8955:3048:50d5:e7e8:636d:bdf1:7033/64 scope global noprefixroute dynamic
valid_lft 2964sec preferred_lft 2964sec
inet6 fe80::8a65:608b:505e:fe4/64 scope link noprefixroute
valid_lft forever preferred_lft forever
然后在这个虚拟机上用curl测试它:
[root@idea-centos sbin]# curl http://192.168.43.235/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
如果访问失败,请检查防火墙是否启用。如果启用该功能,你可以先关闭它,以方便随后的演示练习:
[root@idea-centos sbin]# firewall-cmd --state
running
[root@idea-centos sbin]# systemctl stop firewalld.service
[root@idea-centos sbin]# firewall-cmd --state
not running
访问成功之后,会看到nginx的首页:
nginx常用的基础命令总结
#默认方式启动:
./sbin/nginx
#指定配置文件启动
./sbing/nginx -c /tmp/nginx.conf
#指定nginx程序目录启动
./sbin/nginx -p /usr/local/nginx/
#快速停止
./sbin/nginx -s stop
#优雅停止 (会等当前的请求先处理完再杀死)
./sbin/nginx -s quit
# 热装载配置文件
./sbin/nginx -s reload
# 重新打开日志文件
./sbin/nginx -s reopen
# 检测配置是否正确
./sbin/nginx -t
启动nginx之后,可以通过日志来查看进程的相关信息
[root@idea-centos nginx]# ./sbin/nginx
[root@idea-centos nginx]# ps -ef|grep nginx
root 11059 1 0 16:34 ? 00:00:00 nginx: master process ./sbin/nginx
nobody 11060 11059 0 16:34 ? 00:00:00 nginx: worker process
root 11062 8193 0 16:34 pts/1 00:00:00 grep --color=auto nginx
master process 主要是负责日志的更新,热装载 主进程
worker process 工作进程 处理客户端的连接,处理请求
nginx的日志
在nginx日志文件夹下,在重新访问服务器之后,相应的访问日志将添加新的属性内容。
这里的日志搜索实际上是根据对象句柄查找指定的文件。
关于nginx处理机制的理解
ginx的高性能主要是由于其相应的独特的io多路复用。无论何时发送请求,都会将请求放置在select队列中,select队列存储客户机的http链接信息,然后通过一个特殊的选择器处理轮询,以监视客户机是否具有发送请求的数据。(总是轮询,直到发送数据时发生阻塞为止。)一旦接收到传输的数据,选择器将执行指定的处理。
当我们启动nginx时,将有两种类型的进程,主进程和工作进程。客户机发送请求通常只是为了与主进程通信。主进程负责接收这些请求,然后将它们分发给不同的工作进程并处理它。
从本质上说,工作进程是从主进程派生出来的。在主进程中,需要建立监听套接字,然后fork多个worker进程,多个worker进程(多核cpu环境)将竞争accept_mutex互斥锁,窃取锁的进程将注册相应的事件来处理任务。这个独立流程处理事件的优点是,它避免了原始的锁定开销,并且当流程中出现bug异常时,它不会影响其他流程并降低风险。
那么nginx处理高并发性的方式呢?当多个worker用于处理请求时,每个worker中只有一个主线程,但是并发事务的数量非常有限。当并发数很大时,需要创建数千个线程来实现请求的处理呢?
nginx设计的亮点在于这一点。它的机制有点类似于Linux中的epoll等系统调度。响应线程(临时命名为A)只有一个。当处理请求传入的事件时,它将主动通知A,而不是等待阻塞的请求。这种设计避免了活动轮询和等待事件处理所导致的事件消耗。
与传统的apache服务器相比,每个连接,apache都会创建一个进程,每个进程在一个线程内,apache最多可以创建256个进程。对于负载相对较高的网站,256个进程(即256个线程)是线程处理请求时的同步阻塞模式。接收到请求后,等待请求读取程序文件(IO)(同步),执行业务逻辑,返回到客户端,所有操作都可以在下一个请求(阻塞)之前处理。如果服务器已经达到256的限制,那么下一个访问需要排队,这就是为什么有些服务器没有加载的原因了。
小结
每个worker进程都是单线程的模式
每个io链接都建立在异步的、非阻塞的模型上。
结合服务器的cpu数量来设置worker进程的数量,从而达到调优的效果。
nginx里面的基本组成模块
当nginx处理一个请求时,它更有可能将这些请求形成一个请求链,链中的每个模块将处理不同的功能。例如,用于请求的解压缩和压缩处理,用于ssl的处理模块,等等。总的来说,nginx的基本模块归纳如下:
event module 事件处理机制模块为各种事件提供了特定的处理框架。nginx处理的事件类型取决于操作系统和编译设置,例如ngx_event_core_module和ngx_epoll_module。
phase handler 阶段处理程序主要负责处理客户机请求并生成要响应的内容。ngx_http_static_module就是其中之一。该模块主要是传输nginx请求来读取某些磁盘上的数据,然后做出输出响应,例如:uri is / At The end, index模块用于链接完整的路径名,然后在内部调用该模块。
output filter 此模块可以对响应的输出进行特定的修改,例如替换页面上的某些url。
upstream 相信大家对上游的这个模块都很熟悉。该模块主要用于反向代理工作。
load-balancer 该模块主要负责负载均衡功能。选择集群中的任何服务器作为请求的处理。
nginx的常用配置案例讲解
首先来查看一份最为基础的nginx基本配置:
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;
}
}
}
ps:此配置被划分为多个配置块,配置块和花括号之间的每个空格都需要标记,否则将无效
配置location的重定向
例如,我们在/usr/local/www/文件夹下创建了一个html页面,然后需要通过nginx访问它。当nginx匹配服务器的位置路径时,它将首先遵循完整的路径,然后从左到右。然后从右到左匹配顺序。
server {
listen 80;
server_name www.idea.com *.idea.com idea.*;
location / {
root /usr/local/www/;
}
}
注意,这里面的root配置是存在继承关系的,location里面的root会继承location外边的root信息。如果location里面有写root,就会按照location里面的root来判断。server外>server内>location内。
配置动静分离
所谓的动态和静态分离实际上意味着我们在nginx配置中对动态请求和静态文件进行了一些分离。例如,以下配置信息:
server {
listen 80;
server_name www.idea.com *.idea.com idea.*;
root /usr/local/www;
#这里面添加映射static的记录
location /static {
root /usr/local/static/;
}
location / {
root /usr/local/www/;
index idea.html;
}
}
ps:这里面的配置内容,我引入了host文件的修改
192.168.43.235 www.idea.com
192.168.43.235 test.idea.com
192.168.43.235 idea.test
图片的实际存储位置是:
/usr/local/static/img/logo.jpg
按照上述的配置来讲,访问的方式是:
http://www.idea.com/static/img/logo.jpg
然而,在这种情况下,我们通过nginx访问图像的方式将不会成功,因为地址将被nginx处理为:
前往root地址+static的最终地址进行查询:
/usr/local/static/static
为了避免这种情况,别名alias通常用于匹配。具体配置如下:
server {
listen 80;
server_name www.idea.com *.idea.com idea.*;
root /usr/local/www;
location /static {
alias /usr/local/static/;
}
location / {
root /usr/local/www/;
index idea.html;
}
}
此时,我们将访问http://www.idea.com/static/img/logo.jpg,访问将成功。
此外,对于别名,我们可以做更复杂的逻辑操作案例:
假设我们需要访问静态文件的内容,这次不需要携带相应的名称,直接通过访问
css可以访问/ usr/local/www/static/css/test.css的内容
因此,如果有许多类型的静态文件需要映射,如何配置它们?这一次您可以介绍正则表达式的配置:
server {
listen 80;
server_name www.idea.com *.idea.com idea.*;
root /usr/local/www;
location /static {
alias /usr/local/static/;
}
#这里的~是指忽略大小写
location ~* \.(gif|png|jpg|css|js) {
root /usr/local/static/;
}
location / {
root /usr/local/www/;
index idea.html;
}
}
添加这个正则表达式的配置(~* .(gif|png|css|js)$)后,通过访问路径:
我们可以在/ usr/local/static/css/css下访问文件的内容。
Nginx还提供了一个非常灵活的代理访问机制,让我们可以通过代理访问location
配置一个完全匹配的代理页面跳转通过nginx:
server {
listen 80;
server_name www.idea.com *.idea.com idea.*;
root /usr/local/www;
location /static {
alias /usr/local/static/;
}
location ~* \.(gif|png|jpg|css|js) {
alias /usr/local/static/;
}
location =/idea-serach {
proxy_pass http://www.baidu.com
}
location / {
root /usr/local/www/;
index idea.html;
}
}
通过proxy_pass配置来提供代理的请求转发,当我们访问http://www.idea.com/idea-serach的时候,就会匹配到访问百度的页面了。
小结
nginx对于访问的常见配置支持以下几种:
通过全路径访问location
通过关键字static匹配来访问location
通过正则表达式来访问location
通过反向代理进行访问location
防盗链匹配
设置一些链接只允许访问固定的网站,防止某些特殊域名在ip访问后窃取本网站的资源文件,所以可以设置这个防盗链的功能。具体配置如下:
server {
listen 80;
server_name www.idea.com *.idea.com idea.*;
root /usr/local/www/;
location /static {
alias /usr/local/static/;
}
# 防盗链配置
location ~* \.(gif|png|jpg|css|js) {
valid_referers none blocked *.idea.com;
if ($invalid_referer) {
return 403;
}
root /usr/local/static/;
}
location =/idea-serach {
proxy_pass http://www.baidu.com;
}
location / {
root /usr/local/www/;
}
}
网站黑名单
黑名单的配置相对简单。您只需要首先创建一个黑名单文件,然后在http块中引入它。
# 创建黑名单文件
echo 'deny 192.168.0.132;' >> balck.ip
#http 配置块中引入 黑名单文件
include black.ip;
记住,在配置成功之后,让nginx重新加载,并检查请求时nginx是否为203,如果是,则为缓存请求。
当我们需要查看客户端发送的数据的一些详细信息时,我们需要记录nginx的日志。相应的可选参数如下:
log_format格式变量:
$remote_addr #记录访问网站的客户端地址
$remote_user #远程客户端用户名
$time_local #记录访问时间与时区
$request #用户的http请求起始行信息
$status #http状态码,记录请求返回的状态码,例如:200、301、404等
$body_bytes_sent #服务器发送给客户端的响应body字节数
$http_referer #记录此次请求是从哪个连接访问过来的,可以根据该参数进行防盗链设置。
$http_user_agent #记录客户端访问信息,例如:浏览器、手机客户端等
$http_x_forwarded_for #当前端有代理服务器时,设置web节点记录客户端地址的配置,此参数生效的前提是代理服务器也要进行相关的x_forwarded_for设置
将日志配置放在http块里面即可。
通常我们会把日志的配置放在http模块中,例如,下面的一组情况:
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
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;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
ngixn里面的代理配置
正向代理
在客户机和服务器之间添加一个proxy代理机器。当请求发生时,代理服务器请求server服务器。最常见的正面代理案例是:vpn、局域网中的Internet客户端工具。
举个栗子来讲:
当我们需要通过路径匹配到 $host: $port /baidu.html
的时候,被代理请求百度页面,可以进行以下的配置:
location =/baidu.html {
proxy_pass http://www.baidu.com;
}
反向代理
当客户端请求服务器时,服务器的访问层上实际上有一个代理机器来转发请求,并且该层的转发对客户机是透明的。
反向代理请求内部服务器。虽然配置相似,但是功能不同。配置示例如下:
location =/baidu.html {
proxy_pass http:/127.0.0.1:8088;
}
代理相关参数
proxy_pass # 代理服务
proxy_redirect off; # 是否允许重定向
proxy_set_header Host $host; # 传 header 参数至后端服务
proxy_set_header X-Forwarded-For $remote_addr; # 设置request header 即客户端IP 地址
proxy_connect_timeout 90; # 连接代理服务超时时间
proxy_send_timeout 90; # 请求发送最大时间
proxy_read_timeout 90; # 读取最大时间
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
ngixn里面的负载均衡
nginx里面有个叫做upstream的模块,专门用于配置负载均衡的内容,upstream里面提供有以下的相关参数:
service 反向服务地址 加端口
weight 权重
max_fails 失败多少次 认为主机已挂掉则,踢出
fail_timeout 移除server之后重新请求的时间 当服务挂了之后,这段时间内重新连接
backup 备用服务 (当服务全部都挂了,那么就会请求这里的服务)
max_conns 允许最大连接数
slow_start 当节点恢复,不立即加入,而是等待 slow_start 后加入服务对列。
相应参数的具体配置如下:
upstream backend {
server 192.168.43.191:8080 weight=5 fail_timeout=10s;
server 192.168.43.191:8089 weight=5 fail_timeout=10s;
}
ngixn中默认支持的负载平衡策略是轮询加权权重。此外,nginx本身还支持多种负载均衡策略:
ll+weight:轮询加权重 (默认)
它容易失重。例如,某台机器的访问速度太慢,这可能导致请求的累积。
ip_hash : 基于Hash 计算 ,常用于保持session 一至性
基于hash计算,可以根据ip向指定的服务器发出哈希计算请求。
(通常,处理分布式会话一致性的最佳方法是将会话存储在第三方存储中心中)
在ip上执行哈希计算后,将该值与服务器数量进行比较。
url_hash: 静态资源缓存,节约存储,加快速度
根据图片的url请求更好的理解到指定的服务器。
least_conn : 最小链接数
每个请求只请求客户机连接数量最少的服务器。
least_time :最小的响应时间
计算节点的平均响应时间,然后取响应最快的节点,并赋予其较高的权重
配置案例
通过使用ip进行哈希计算的方式来请求后端服务器
upstream backend {
ip_hash;
server 192.168.43.191:8080 weight=1;
server 192.168.43.191:8089 weight=8 fail_timeout=10s;
}
location / {
#root html;
index index.html index.htm;
proxy_pass http://backend;
}
评论 (0人参与)
最新评论