总结高并发下Nginx性能如何优化


Posted in Servers onNovember 01, 2021

我们终将在,没有黑暗的地方相见。 ~乔治《1984》

Nginx同Apache一样都是一种WEB服务器。基于REST架构风格,以统一资源描述符(UniformResources ldentifier)URl或者统一资源定位符(Uniform Resources Locator)URL作为沟通依据,通过HTTP协议提供各种网络服务。

Apache的发展时期很长,而且是毫无争议的世界第一大服务器。它有着很多优点:稳定、开源、跨平台等等。它出现的时间太长了,它兴起的年代,互联网产业远远比不上现在。所以它被设计为一个重量级的。它不支持高并发的服务器。在Apache上运行数以万计的并发访问,会导致服务器消耗大量内存sz操作系统对其进行进程或线程间的切换也消耗了大量的CPU资源,导致HTTP请求的平均响应速度降低。

这些都决定了Apache不可能成为高性能WEB服务器,轻量级高并发服务器Nginx就应运而生了。

特点

是一个高性能的HTTP和反向代理web服务器,轻量级提供了IMAP/POP3/SMTP服务发布于2004年10月4日(第一个公开版本0.1.0 )Nginx的1.4.0稳定版已经于2013年4月24日发布C语言编写Nginx是一个跨平台服务器Nginx有自己的函数库,并且除了zlib、PCRE和OpenSSL之外,标准模块只使用系统C库函数。

优势

占有内存少(在3W并发连接中,开启的10个nginx进程消耗内存大约150M)高并发能力强(官方测试能够支撑5W并发连接,在实际生产环境中能到2-3W并发连接数)简单(配置文件通俗易懂)价格(免费、开源)支持Rewriter重写(能够根据域名、URL的不同,将HTTP请:求分到不同的后端服务器群组)内置健康检查(如果nginx后端有几个服务宕机了,不会影响前端访问,能自动检测服务状态)节省带宽(支持GZIP压缩,可以添加浏览器本地缓存的Header头)
稳定性高,反向代理,很少宕机中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等

功能:web服务器、轻量级;负载、均衡;缓存;高并发

应用场景:代理服务器;IP负载、静态负载;动静分离;限流、健康监控

安装和命令

安装:

sudo apt-get install nginx

查看版本

nginx -v                  
nginx version: nginx/1.18.0 (Ubuntu)

基本命令

# nginx的访问页面(welcome to nginx)具体所在位置
vi /usr/share/nginx/html/index.html
# 访问IP
curl 192.168.100.111
# 关闭nginx进程
nginx -s stop
# 启动nginx进程
/usr/sbin/nginx          # yum安装的nginx也可以使用         servic nginx start
# 检查配置文件是否有误
nginx ?t
# 重新加载配置文件
nginx ?s reload
# 查看日志
tail -f filename #显示文件默认10行,刷新显示
# 例:tail -f /var/log/lvs-agent.log          tail -f /etc/nginx/nginx.conf
# 查看文件后几行
tail -n 行数 文件名 例: tail -n 100 /var/log/aa.log
# 删除网卡ip
ip addr del 192.168.11.5/32 dev lo (lo eth1 eth2)
# lvs清空所有集群服务
ipvsadm ?C
# 获取eth0网卡上的所挂的ip值
ip a|grep eth0|grep inet|awk ‘{print $2}'|cut -d “/” -f1
# 验证该ip或者网址是否通 可用返回200
curl -I -m 10 -o /dev/null -s -w %{http_code} 10.110.26.10:8080
# 后台启动jar包
nohup java -jar /usr/sbin/项目名.jar >>/var/log/项目名.log 2>&1 &
# 查看上一个命令是否执行成功 返回0执行成功 其他不成
echo $?
# 查看nginx进程是否启动。此命令用在代码判断nginx进程是否启动,如果只用ps aux | grep nginx 即使没有启动也会用内容返回,影响判断
ps aux | grep nginx | greo ?v grep

配置文件

nginx.conf

# nginx.conf
# 全局配置区
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
# 网络事件配置区
events {
	worker_connections 768;
	# multi_accept on;
}
# HTTP模块
http {
	##
	# HTTP 全局设置
	##
	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	# server_tokens off;
	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;
	include /etc/nginx/mime.types;
	default_type application/octet-stream;
	##
	# SSL 设置
	##
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;
	##
	# 日志设置
	##
	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;
	##
	# 资源压缩设置
	##
	gzip on;	# 默认开启
	# gzip_vary on;
	# gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	# gzip_http_version 1.1;
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
	##
	# 虚拟主机配置
	##
	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}

/etc/nginx/sites-enabled/*

server {	# 虚拟主机配置
	listen 80 default_server;	# 监听端口
	listen [::]:80 default_server;
	# SSL 配置
	#
	# listen 443 ssl default_server;
	# listen [::]:443 ssl default_server;
	#
	# Note: You should disable gzip for SSL traffic.
	# See: https://bugs.debian.org/773332
	#
	# Read up on ssl_ciphers to ensure a secure configuration.
	# See: https://bugs.debian.org/765782
	#
	# Self signed certs generated by the ssl-cert package
	# Don't use them in a production server!
	#
	# include snippets/snakeoil.conf;	
	# 数据缓存位置
	root /var/www/html;
	# Add index.php to the list if you are using PHP
	index index.html index.htm index.nginx-debian.html;	
	# 域名,可以有多个
	server_name _;	
	# 对/进行反向代理
	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		# uwsgi_pass 127.0.0.1:8000;
		# include /etc/nginx/uwsgi_params;
		try_files $uri $uri/ =404;
	}
	# pass PHP scripts to FastCGI server
	#
	#location ~ \.php$ {
	#	include snippets/fastcgi-php.conf;
	#
	#	# With php-fpm (or other unix sockets):
	#	fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
	#	# With php-cgi (or other tcp sockets):
	#	fastcgi_pass 127.0.0.1:9000;
	#}
	# deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	#
	#location ~ /\.ht {
	#	deny all;
	#}
}

代理模式和配置反向代理

正向代理(forward proxy) :

是一个位于客户端(用户A)和原始服务器(origin server)(目标服务器)之间的服务器(代理服务器),为了从原始服务器取得内容,客户端向代理服务器发送一个请求并指定目标(原始服务器),然后代理服务器向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的配置才能使用正向代理。一般情况下,如果没有特别说明,代理技术默认是指正向代理技术。

相当于是一个职业中介,且客户端和实际服务器不能沟通,客户端知道他是中介

反向代理(reverse proxy)?

和正向代理正好相反,对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容原本就是它自己的一样。

相当于是一个买房和卖房的人,买房的时候相对于卖房的是一个买房的,卖房的时候相对于买房的是一个卖房的。
客户端不知道他是一个代理服务器,服务器也认为他只是客户端而不是代理服务器

透明代理∶

透明代理的意思是客户端根本不需要知道有代理服务器的存在,它改编你的requestfields(报文),并会传送真实IP。注意,加密的透明代理则是属于匿名代理,意思是不用设置使用代理了。透明代理实践的例子就是时下很多公司使用的行为管理软件

总结高并发下Nginx性能如何优化

# 反向代理默认是关闭的
# upstream localhost是第三方模块,均衡
upstream localhost {
	# 实际服务器
	server 192.168.136.133:8081;
	server 192.168.136.133:8081;
	server 192.168.136.133:8081;
} 
# 负载
server {
	listen 80	# 代理服务器的端口
	server_name localhost;
	location / {
		proxy_pass http://localhost;	# 将请求发送给其中一台实际服务器
	}
}

负载均衡方法:

轮询法(默认)

加权轮询法(权重)

Fair

url_hash

源地址哈希法

最小连接法(least_conn)

动静分离

Nginx动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离

严格意义上说应该是动态请求跟静态请求分开,可以理解成使用Nginx处理静态页面,Tomcat处理动态页面

动静分离从目前实现角度来讲大致分为两种:

  • 一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案
  • 一种是动态跟静态文件混合在一起发布,通过nginx来分开

mkdir static # 存放静态文件

server {	# 虚拟主机配置
	listen 80 default_server;	# 监听端口
	listen [::]:80 default_server;
	
	# 数据缓存位置
	root /var/www/html;

	# Add index.php to the list if you are using PHP
	index index.html index.htm index.nginx-debian.html;
	
	# 域名,可以有多个
	server_name _;
	
	# 对/进行反向代理
	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		# uwsgi_pass 127.0.0.1:8000;
		# include /etc/nginx/uwsgi_params;
		try_files $uri $uri/ =404;
	}
	# 如果是这些文件后缀就去这里面找
	location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css) $ {
		root /static;
		expires 30d;	# 缓存有效期
	}
}

日志管理

日志格式

日志生成的到Nginx根目录logs/access.log文件,默认使用“main”日志格式,也可以自定义格式默认“main”日志格式

og_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
$remote_addr:客户端的ip地址(代理服务器,显示代理服务ip)
$remote_user:用于记录远程客户端的用户名称(一般为“-”)
$time_local:用于记录访问时间和时区
$request:用于记录请求的url以及请求方法
$status:响应状态码,例如:200成功、404页面找不到等。
$body_bytes_sent:给客户端发送的文件主体内容字节数

日志切割

nginx的日志文件没有rotate功能

编写每天生成一个日志,我们可以写一个nginx日志切割脚本来自动切割日志文件

  • 第一步就是重命名日志文件 (不用担心重命名后nginx找不到日志文件而丢失日志。在你未重新打开原名字的日志文件前,nginx还是会向你重命名的文件写日志,Linux是靠文件描述符而不是文件名定位文件 )
  • 第二步向nginx主进程发送USR1信号
    nginx主进程接到信号后会从配置文件中读取日志文件名称
    重新打开日志文件 (以配置文件中的日志名称命名) ,并以工作进程的用户作为日志文件的所有者
    重新打开日志文件后,nginx主进程会关闭重名的日志文件并通知
    工作进程使用新打开的日志文件工作进程立刻打开新的日志文件并关闭重名名的日志文件,然后你就可以处理旧的日志文件了。[或者重启nginx服务]

nginx日志按每分钟自动切割脚本如下 :

新建shell脚本

高并发架构分析

什么是高并发?

高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。

高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS (Query Per Second),并发用户数等。

  • 响应时间:系统对请求做出响应的时间
  • 吞吐量:单位时间内处理的请求数量。
  • QPS:每秒响应请求数

如何提升系统的并发能力?

互联网分布式架构设计,提高系统并发能力的方式,方法论上主要有两种:垂直扩展(ScaleUp)与水平扩展(Scale Out)。

垂直扩展:提升单机处理能力。垂直扩展的方式又有两种。

  • 增强单机硬件性能
  • 提升单机架构性能

在互联网业务发展非常迅猛的早期,如果预算不是问题,强烈建议使用“增强单机硬件性能”的方式提升系统并发能力,因为这个阶段,公司的战略往往是发展业务抢时间,而“增强单机硬件性能”往往是最快的方法。

不管是提升单机硬件性能,还是提升单机架构性能,都有一个致命的不足:单机性能总是有极限的。所以互联网分布式架构设计高并发终极解决方案还是水平扩展。

水平扩展:只要增加服务器数量,就能线性扩充系统性能。

服务器都有极限

三种方式实现

limit_conn_zone(限制连接流)

limit_req_zone(限制请求流)

ngx_http_upstream_module(后台服务限制)

此处插上一个小工具:限制测试工具下载

yum install http-tools -y
key 含义
Document Path 测试的页面
Document Length 页面的大小
Concurrency Level 并发数量、并发用户数
Time taken for tests 测试耗费总时间
Complete requests 请求总量、并发连接数
Failed requests 请求失败的数量
Write errors 错误数量
Requests per second 每秒钟的请求量吞吐率
Time per request 每次请求需要时间响应时间

限制连接流

http {
	# binary_remote_addr:IP
	# zone=one:10m;申请一块10M的空间存放连接的IP
	limit_conn_zone $binary_remote_addr zone=one:10m;
	
	server {
		# zone区域中每次放出10个连接nginx处理
		limit_conn one 10;
	}
}

限制请求流(限速)

http {
	# rate意思是每个连接每秒能发一个连接
	limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;
	
	server {
		# brust:令牌,每次新增一个,120个发完后会报错503
		limit_req zone=req_one brust=120;
	}
}

后台服务限制

该模块是提供了我们需要的后端限流功能的

该模块有一个参数: max_conns可以对服务端进行限流,可惜在商业版nginx中才能使用

在nginx1.11.5版本以后,官方已经将该参数从商业版中脱离出来了,也就是说只要我们将生产上广泛使用的nginx1.9.12版本和1.10版本升级即可使用

server {
	# max_conns最大接收服务数量
	server 127.0.0.1:8080 max_conns=100;
}

安全配置

版本安全

http {
	server_tokens off;
}

IP安全

http {
	location / {
		allow 127.0.0.1;	# 白名单
		deny all;	# 黑名单
	}
}

文件安全

http {
	location /logs{
		autoindex on;	# 展示目录
		root /static;
	}
	location ^/logs~*\.(log|txt)$ {
		add_header Content_Type text/plain;
		root /static;
	}
}

连接安全

http {
	# SSL settings
}

Nginx优化

调整Nginx的主配置文件,增加并发量

worker_processes 2;# 调整与CPU一致
events {
	# 每个worker最大并发数量
	worker_connection 65535;
}

Nginx长连接:HTTP1.1之后,HTTP协议支持持久连接,也就是长连接,优点在于在一个TCP连接上可以传送多个HTTP请求和响应,

nginx长连接短连接,可以增强服务器的容灾能力

减少了建立和关闭连接的消耗和延迟。如果我们使用了nginx去作为反向代理或者负载均衡,从客户端过来的长连接请求就会被转换成短连接发送给服务器端,为了支持长连接,我们需要在nginx服务器上做一些配置

使用nginx时,想要做到长连接,我们必须做到以下两点:

  • 从client到nginx是长连接(events)
  • 从nginx到server是长连接(http)

对于客户端而言,nginx其实扮演着server的角色,反之,之于server,nginx就是一个client

events {
	# keepalive超时时间,默认是60s,切记这个参数也不能设置过大!否则会导致许多无效的http连接占据着nginx的连接数,终nginx崩溃!
	keepalive_timeout 60;
}
http {
	keepalive_timeout 60;
}

Nginx压缩

gzip压缩作用:将响应报文发送至客户端之前可以启用压缩功能,这能够有效地节约带宽,并提高响应至客户端的速度,压缩会消耗nginx的cpu性能。

gzip压缩可以配置http,server和location模块下

http {
    #gzip模块设置
    #开启压缩
    gzip on;
    # 设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。
    默认值是0,不管页面多大都压缩。建议设置成大于2k的字节数,小于2k可能会越压越大。
    gzip_min_length 2k;
    # 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。 例如 4 4k 代表以4k为单
    位,按照原始数据大小以4k为单位的4倍申请内存。 4 8k 代表以8k为单位,按照原始数据大小以8k
    为单位的4倍申请内存。
    # 如果没有设置,默认值是申请跟原始数据相同大小的内存空间去存储gzip压缩结果。
    gzip_buffers 4 16k;
    #压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间
    gzip_comp_level 5;
    # 默认值: gzip_types text/html (默认不对js/css文件进行压缩)
    # 压缩类型,匹配MIME类型进行压缩
    # 不能用通配符 text/*
    # (无论是否指定)text/html默认已经压缩
    # 设置哪压缩种文本文件可参考 conf/mime.types
    gzip_types text/plain application/xjavascript text/css application/xml;
    # 值为1.0和1.1 代表是否压缩http协议1.0,选择1.0则1.0和1.1都可以压缩
    gzip_http_version 1.0
    # IE6及以下禁止压缩
    gzip_disable "MSIE [1-6]\.";
    # 默认值:off
    # 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 - 无条件启用压缩
        gzip_proxied expired no-cache no-store private auth;
    # 给CDN和代理服务器使用,针对相同url,可以根据头信息返回压缩和非压缩副本
    gzip_vary on
}

状态监控

server {
	location /NginxStatus {
		stub_status on;
		access_log off;
	}
}

插件安装

./configure --prefix=... --with-http_stub_status _module

以上就是总结高并发下Nginx性能如何优化的详细内容,更多关于高并发下Nginx性能优化的资料请关注三水点靠木其它相关文章!

Servers 相关文章推荐
nginx实现发布静态资源的方法
Mar 31 Servers
nginx location优先级的深入讲解
Mar 31 Servers
详解Nginx 被动检查服务器的存活状态
Oct 16 Servers
Nginx下SSL证书安装部署步骤介绍
Dec 06 Servers
Nginx虚拟主机的搭建的实现步骤
Jan 18 Servers
nginx中封禁ip和允许内网ip访问的实现示例
Mar 17 Servers
Nginx工作模式及代理配置的使用细节
Mar 21 Servers
解决Windows Server2012 R2 无法安装 .NET Framework 3.5
Apr 29 Servers
windows server 2012安装FTP并配置被动模式指定开放端口
Jun 10 Servers
Windows Server 修改远程桌面端口的实现
Jun 25 Servers
Nginx安装配置详解
Jun 25 Servers
阿里云服务器(windows)手动部署FTP站点详细教程
Aug 05 Servers
Rhit高效可视化Nginx日志查看工具
Nginx+Tomcat负载均衡集群的实现示例
Nginx反向代理学习实例教程
使用Nginx搭载rtmp直播服务器的方法
Oct 16 #Servers
详解Nginx 被动检查服务器的存活状态
Oct 16 #Servers
教你利用Nginx 服务搭建子域环境提升二维地图加载性能的步骤
Sep 25 #Servers
Nginx进程调度问题详解
You might like
sony ICF-2010 拆解与改装
2021/03/02 无线电
VFP与其他应用程序的集成
2006/10/09 PHP
PHP中使用gettext来支持多语言的方法
2011/05/02 PHP
destoon实现调用当前栏目分类及子分类和三级分类的方法
2014/08/21 PHP
php实现阳历阴历互转的方法
2015/10/28 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
Smarty模板变量与调节器实例详解
2019/07/20 PHP
超强的IE背景图片闪烁(抖动)的解决办法
2007/09/09 Javascript
JavaScript 异步调用框架 (Part 6 - 实例 & 模式)
2009/08/04 Javascript
20款非常优秀的 jQuery 工具提示插件 推荐
2012/07/15 Javascript
自己动手实现jQuery Callbacks完整功能代码详解
2013/11/25 Javascript
分享10个原生JavaScript技巧
2015/04/20 Javascript
学习JavaScript设计模式之策略模式
2016/01/12 Javascript
JavaScript事件对象event用法分析
2018/07/27 Javascript
VUE+Element实现增删改查的示例源码
2020/11/23 Vue.js
python进阶教程之异常处理
2014/08/30 Python
利用python批量给云主机配置安全组的方法教程
2017/06/21 Python
使用apidocJs快速生成在线文档的实例讲解
2018/02/07 Python
python实现名片管理系统
2018/11/29 Python
Django异步任务之Celery的基本使用
2019/03/23 Python
Python SMTP发送电子邮件的示例
2020/09/23 Python
python GUI计算器的实现
2020/10/09 Python
TensorFlow低版本代码自动升级为1.0版本
2021/02/20 Python
用canvas实现图片滤镜效果附演示
2013/11/05 HTML / CSS
SteelSeries赛睿官网:游戏外设和配件的领先制造商(耳机、键盘、鼠标和鼠标垫)
2018/06/17 全球购物
欧洲领先的火车票和大巴票预订平台:Trainline
2018/12/26 全球购物
德国的大型美妆个护电商:Flaconi
2020/06/26 全球购物
随机分配座位,共50个学生,使学号相邻的同学座位不能相邻
2014/01/18 面试题
怎样有效的进行自我评价
2013/10/06 职场文书
大学毕业生简单自荐信
2013/11/05 职场文书
光盘行动倡议书
2014/02/02 职场文书
世博会口号
2014/06/20 职场文书
投标文件签署授权委托书范本
2014/10/12 职场文书
2014年小班保育员工作总结
2014/12/23 职场文书
2015大学自主招生自荐信范文
2015/03/04 职场文书
刑事附带民事诉讼答辩状
2015/05/22 职场文书