-
introduction
-
1. The concept of performance monster-Nginx is explained in simple terms
-
Two, Nginx environment construction
-
Three, Nginx reverse proxy - load balancing
-
Four, Nginx dynamic and static separation
-
Five, Nginx resource compression
-
Six, Nginx buffer
-
Seven, Nginx cache mechanism
-
Eight, Nginx implements IP black and white list
-
Nine, Nginx cross-domain configuration
-
10. Nginx anti-leech design
-
Eleven, Nginx large file transfer configuration
-
12. Nginx configures SLL certificate
-
Thirteen, Nginx high availability
-
Fourteen, Nginx performance optimization
-
Fifteen, put it at the end
introduction
The early business was deployed based on a single node. Since the access traffic in the early stage was not large, the single structure can also meet the demand. However, as the business grows, the traffic is also increasing, so the access pressure on a single server is also increasing. will gradually increase. Over time, if the performance of a single server cannot keep up with business growth, it will cause frequent online downtime, and eventually cause the system to be paralyzed and unable to continue processing user requests.
❝From the above description, there are two main problems: ① The deployment method of the single structure cannot carry the growing business traffic. ②When the back-end node goes down, the whole system will be paralyzed, making the whole project unavailable.
❞
Therefore, in this context, the benefits that can be brought by the introduction of load balancing technology:
-
"High availability of the system:" When a node goes down, the traffic can be quickly transferred to other nodes.
-
"High performance of the system:" Multiple servers jointly provide services to the outside world, providing a higher throughput for the entire system.
-
"System scalability:" When the business grows or slumps again, nodes can be added/reduced for flexible scaling.
OK~, since the introduction of load balancing technology can bring us such huge benefits, what options are there for us? There are mainly two load solutions, "hardware level and software level" . There are more commonly used hardware loaders A10、F5
, but these machines often cost tens of thousands or even hundreds of thousands of dollars, so generally large enterprises will adopt this solution, such as Banks, state-owned enterprises, central enterprises, etc. And the cost is limited, but still want to do load balancing projects, so it can be realized at the software level, such as typical, Nginx
etc. The load of the software layer is also the focus of this article. After all, Boss
one of our guidelines is: ""What can be achieved by technology is Try not to spend money.""
❝Of course, if you think this article is helpful to you, remember to like, bookmark, and pay attention to Sanlian!
❞
1. The concept of performance monster-Nginx is explained in simple terms
Nginx
It is the mainstream solution in the current load balancing technology. It is used by almost most projects. It Nginx
is a lightweight high-performance HTTP
reverse proxy server. At the same time, it is also a general-purpose proxy server that supports most protocols, such TCP、UDP、SMTP、HTTPS
as .
Nginx
Like Redis, it is a product built based on the multiplexing model, so it also Redis
has the characteristics of "low resource occupation and high concurrency support" . In theory, a single node Nginx
supports 5W
concurrent connections at the same time, but in actual production In the environment, this value can indeed be achieved after the hardware foundation is in place and combined with simple tuning.
Let’s take a look at Nginx
the comparison of the client request processing flow before and after the introduction:
Originally, the client directly requests the target server, and the target server directly completes the request processing work, but after joining, Nginx
all requests will go through first Nginx
, and then be distributed to specific servers for processing, and then return after processing Nginx
, and finally Nginx
the final The response result is returned to the client.
After understanding Nginx
the basic concepts, let's quickly build the environment and understand some Nginx
advanced features, such as dynamic and static separation, resource compression, cache configuration, IP
blacklist, high availability guarantee, etc.
Two, Nginx environment construction
❶First create Nginx
the directory and enter:
[root@localhost]# mkdir /soft && mkdir /soft/nginx/
[root@localhost]# cd /soft/nginx/
❷ The downloaded Nginx
installation package can be FTP
uploaded to the offline environment package through the tool, or wget
the installation package can be obtained online through the command:
[root@localhost]# wget https://nginx.org/download/nginx-1.21.6.tar.gz
If there is no wget
command, it can yum
be installed by command:
[root@localhost]# yum -y install wget
❸ Decompressed Nginx
compressed package:
[root@localhost]# tar -xvzf nginx-1.21.6.tar.gz
❹ Download and install Nginx
the required dependencies and packages:
[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ gcc-c++
[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ pcre pcre-devel4
[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ zlib zlib-devel
[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ openssl openssl-devel
It can also yum
be downloaded with one click through the command (which method above is recommended):
[root@localhost]# yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
After the execution is complete, and then ls
look at the directory file, you will see a lot of dependencies:
Then rpm
build the dependent packages one by one through the command, or install all the dependent packages with one click through the following command:
[root@localhost]# rpm -ivh --nodeps *.rpm
❺Enter the decompressed nginx
directory, and then execute Nginx
the configuration script to configure the environment in advance for the subsequent installation, which is located /usr/local/nginx/
in the directory by default (you can customize the directory):
[root@localhost]# cd nginx-1.21.6
[root@localhost]# ./configure --prefix=/soft/nginx/
❻Compile and install Nginx
:
[root@localhost]# make && make install
❼Finally, go back to the previous /soft/nginx/
directory and enter ls
to see nginx
the files generated after the installation is complete.
❽ Modify the configuration file conf
in the directory generated after installation nginx.conf
:
[root@localhost]# vi conf/nginx.conf
修改端口号:listen 80;
修改IP地址:server_name 你当前机器的本地IP(线上配置域名);
❾Make configuration file and start Nginx
:
[root@localhost]# sbin/nginx -c conf/nginx.conf
[root@localhost]# ps aux | grep nginx
Nginx
Other operating commands:
sbin/nginx -t -c conf/nginx.conf # 检测配置文件是否正常
sbin/nginx -s reload -c conf/nginx.conf # 修改配置后平滑重启
sbin/nginx -s quit # 优雅关闭Nginx,会在执行完当前的任务后再退出
sbin/nginx -s stop # 强制终止Nginx,不管当前是否有任务在执行
❿Open 80
the port and update the firewall:
[root@localhost]# firewall-cmd --zone=public --add-port=80/tcp --permanent
[root@localhost]# firewall-cmd --reload
[root@localhost]# firewall-cmd --zone=public --list-ports
⓫ Windows/Mac
In your browser, directly enter IP
the address you just configured to visit Nginx
:
Finally see the above Nginx
welcome interface, which means Nginx
the installation is complete. Recommended: Java Interview Questions
Three, Nginx reverse proxy - load balancing
First, SpringBoot+Freemarker
quickly build a project: springboot-web-nginx, and then create a file WEB
in this project , the logic is as follows:IndexNginxController.java
@Controller
public class IndexNginxController {
@Value("${server.port}")
private String port;
@RequestMapping("/")
public ModelAndView index(){
ModelAndView model = new ModelAndView();
model.addObject("port", port);
model.setViewName("index");
return model;
}
}
In Controller
this class , there is a member variable: port
, whose value is application.properties
obtained from the configuration file server.port
. When there is a request to access /
resources, jump to the front-end index
page and return the value with it.
The front-end index.ftl
file code is as follows:
<html>
<head>
<title>Nginx演示页面</title>
<link href="nginx_style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div style="border: 2px solid red;margin: auto;width: 800px;text-align: center">
<div id="nginx_title">
<h1>欢迎来到熊猫高级会所,我是竹子${port}号!</h1>
</div>
</div>
</body>
</html>
It can be seen from the above that its logic is not complicated, only the output is obtained from the response port
.
OK~, after the prerequisite work is ready, simply modify nginx.conf
the configuration:
upstream nginx_boot{
# 30s内检查心跳发送两次包,未回复就代表该机器宕机,请求分发权重比为1:2
server 192.168.0.000:8080 weight=100 max_fails=2 fail_timeout=30s;
server 192.168.0.000:8090 weight=200 max_fails=2 fail_timeout=30s;
# 这里的IP请配置成你WEB服务所在的机器IP
}
server {
location / {
root html;
# 配置一下index的地址,最后加上index.ftl。
index index.html index.htm index.jsp index.ftl;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 请求交给名为nginx_boot的upstream上
proxy_pass http://nginx_boot;
}
}
❝At this point, all the prerequisite work is ready, then start again
❞Nginx
, and then start two services. Whenweb
the first service starts, in the configuration file, change the port number to . When the second service starts, change its port number to Change to .WEB
application.properties
8080
WEB
8090
Finally, let's see the effect:
Load Balancing Effect-Gift Demonstration
Because the weight of request distribution is configured, 8080、8090
the weight ratio is 2:1
, so the request will be distributed to each machine according to the weight ratio, that is, 8080
once, 8090
twice, 8080
once...
Nginx request distribution principle
The request sent by the client 192.168.12.129
will eventually be transformed into: http://192.168.12.129:80/
, and then IP
initiate a request to the target, the process is as follows:
Principle of Request Distribution
-
Due to the
Nginx
listening192.168.12.129
port80
, the request will eventually findNginx
the process; -
Nginx
location
First, it will match according to the configured rules, and/
locatelocation /{}
the rules according to the client's request path; -
Then according to
location
the configuration in thisproxy_pass
will find thenginx_boot
namedupstream
; -
Finally, according to
upstream
the configuration information in , the request is forwarded toWEB
the machine running the service for processing. Since multiple services are configuredWEB
and the weight value is configured,Nginx
the request will be distributed according to the weight ratio in turn.
Four, Nginx dynamic and static separation
Dynamic and static separation should be a performance optimization solution that is listened to more often, so first think about a question: "Why do you need to do dynamic and static separation? What are the benefits it brings?" Actually, this question is not difficult to answer, when you After understanding the essence of the website, it is natural to understand the importance of the separation of dynamic and static. Let’s take Taobao as an example to analyze:
Taobao Homepage
When the browser enters www.taobao.com
to visit the Taobao homepage, open the developer debugging tool and you can clearly see 100+
the number of requests that will occur when the homepage loads. However, during normal project development, static resources are generally placed in resources/static/
the directory:
IDEA project structure
When the project is launched and deployed, these static resources will be packaged together, so think about a question at this time: "" Assuming that Taobao does the same, where will the request when the home page loads eventually go to be processed?" The answer is beyond doubt , 100+
all requests for the home page will come to WEB
the machine where the service is deployed for processing, which means that a client requesting the Taobao home page will cause 100+
concurrent requests to the back-end server. There is no doubt that the pressure on the back-end server is particularly huge.
❝But at this time, you might as well analyze and see
❞100+
if there are at least requests60+
for*.js、*.css、*.html、*.jpg.....
this type of static resources among the requests on the home page? The answer isYes
.
Since there are so many requests that are static and there is a high probability that these resources will not change for a long time, why should these requests be processed at the backend? Can it be dealt with ahead of time? Of course OK
, after the analysis, it can be made clear: "After the dynamic and static separation, at least the concurrency of the back-end service can be reduced by more than half." At this point, everyone should understand the performance benefits that the dynamic and static separation can bring. how big.
OK~, after figuring out the necessity of dynamic and static separation, how to achieve dynamic and static separation? It's actually very simple, let's see it in practice.
① First create a directory under the directory of the deployed Nginx
machine :Nginx
static_resources
mkdir static_resources
②Copy all the static resources in the project to this directory, and then remove and repackage the static resources in the project.
③Slightly modify nginx.conf
the configuration and add a location
matching rule:
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){
root /soft/nginx/static_resources;
expires 7d;
}
Then start nginx
and remove the static resource WEB
service as usual, and you will find that the original styles, js
effects, pictures, etc. are still valid, as follows:
The files in static
the directory nginx_style.css
have been removed, but the effect still exists (green font + blue big border):
Effect animation after removal
Finally, read the location rule:
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)
-
~
Represents case-sensitive matching -
.*
Represents that any character can appear zero or more times, that is, the resource name is not limited -
\.
Represents matching suffix delimiters. -
(html|...|css)
Represents matching all static resource types in brackets
To sum up, a simple sentence overview: This configuration represents all resource requests .html~.css
that the suffix.
"Finally, you can also upload static resources to the file server, and then location
configure a new upstream
point in it."
Five, Nginx resource compression
Based on the separation of dynamic and static resources, if a static resource is Size
smaller, the natural transmission speed will be faster, and it will also save bandwidth. Therefore, when we deploy a project, we can also achieve Nginx
compressed transmission of static resources. On the one hand, it can save bandwidth resources, and on the other hand, it can also speed up the response speed and improve the overall throughput of the system.
It also Nginx
provides three modules that support resource compression ngx_http_gzip_module、ngx_http_gzip_static_module、ngx_http_gunzip_module
, which ngx_http_gzip_module
are built-in modules, which means that some compression instructions under this module can be used directly. Subsequent resource compression operations are based on this module. Let’s take a look at some parameters of the compression configuration/ instruction:
After understanding Nginx
the basic compression configuration in , you can simply Nginx
configure it in :
http{
# 开启压缩机制
gzip on;
# 指定会被压缩的文件类型(也可自己配置其他类型)
gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
# 设置压缩级别,越高资源消耗越大,但压缩效果越好
gzip_comp_level 5;
# 在头部中添加Vary: Accept-Encoding(建议开启)
gzip_vary on;
# 处理压缩请求的缓冲区数量和大小
gzip_buffers 16 8k;
# 对于不支持压缩功能的客户端请求不开启压缩机制
gzip_disable "MSIE [1-6]\."; # 低版本的IE浏览器不支持压缩
# 设置压缩响应所支持的HTTP最低版本
gzip_http_version 1.1;
# 设置触发压缩的最小阈值
gzip_min_length 2k;
# 关闭对后端服务器的响应结果进行压缩
gzip_proxied off;
}
In the above compression configuration, the last gzip_proxied
option can be determined according to the actual situation of the system, and there are a variety of options in total:
-
off
: CloseNginx
the compression of the response result of the background server. -
expired
: Turn on compression if the response header containsExpires
information. -
no-cache
: Turn on compression if the response header containsCache-Control:no-cache
information. -
no-store
: Turn on compression if the response header containsCache-Control:no-store
information. -
private
: Turn on compression if the response header containsCache-Control:private
information. -
no_last_modified
: Turn on compression if the response header does not containLast-Modified
information. -
no_etag
: Turn on compression if the response header does not containETag
information. -
auth
: Turn on compression if the response header containsAuthorization
information. -
any
: Unconditionally enable the compression mechanism for the response result of the backend.
OK~, after simply modifying the compression configuration, you can introduce a file into the Nginx
original page :index
jquery-3.6.0.js
<script type="text/javascript" src="jquery-3.6.0.js"></script>
Compare the difference before and after compression:
It can be clearly seen from the figure that when accessing before the compression mechanism is enabled, the original js
size of the file is .230K
Nginx
230KB→69KB
❝Points to note: ① For image and video data, the compression mechanism will be enabled by default, so generally there is no need to enable compression again. ②For
❞.js
files, you need to specify the compression type asapplication/javascript
, nottext/javascript、application/x-javascript
.
Six, Nginx buffer
Let’s think about a problem first. Nginx
The general request process of an access project is: "client → Nginx
→ server". In this process, there are two connections: "client → Nginx
、Nginx
→ server", then two different connection speeds Inconsistency will affect the user experience (for example, the loading speed of the browser cannot keep up with the response speed of the server).
In fact, it is similar to the fact that the memory of a computer cannot keep up with CPU
the speed, so the user experience is extremely poor. Therefore, CPU
a three-level high-speed buffer will be added in the design to alleviate CPU
the contradiction with the inconsistency of the memory speed. There is also a buffer mechanism in Nginx
China, the main purpose of which is: ""Used to solve the problem caused by the mismatch of speed between two connections""Nginx
. data to the client. Let's take a look at some configuration items about the buffer:
-
proxy_buffering
: Whether to enable the buffer mechanism, the default ison
off. -
client_body_buffer_size
: Set the memory size for buffering client request data. -
proxy_buffers
: Set the number and size of buffers for each request/connection, default4 4k/8k
. -
proxy_buffer_size
: Sets the size of the buffer used to store response headers. -
proxy_busy_buffers_size
: When the backend data is not fully received, the status bufferNginx
can bebusy
returned to the client. This parameter is used to set the specific sizebusy
of the status , and the default is .buffer
proxy_buffer_size*2
-
proxy_temp_path
: When the memory buffer is full, the data can be temporarily stored to the disk. This parameter is to set the directory for storing the buffered data. -
path
is the path to the temporary directory.-
Syntax:
proxy_temp_path path;
path is the path to the temporary directory
-
-
proxy_temp_file_write_size
: Set the size limit for writing data to the temporary file each time. -
proxy_max_temp_file_size
: Set the maximum capacity allowed to be stored in the temporary buffer directory. -
Non-buffered parameter items:
-
proxy_connect_timeout
: Set the timeout period when establishing a connection with the backend server. -
proxy_read_timeout
: Set the timeout for reading response data from the backend server. -
proxy_send_timeout
: Set the timeout period for transmitting request data to the backend server.
-
The specific nginx.conf
configuration is as follows:
http{
proxy_connect_timeout 10;
proxy_read_timeout 120;
proxy_send_timeout 10;
proxy_buffering on;
client_body_buffer_size 512k;
proxy_buffers 4 64k;
proxy_buffer_size 16k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_temp_path /soft/nginx/temp_buffer;
}
The above buffer parameters are based on the space allocated for each request, not the shared space for all requests. Of course, the specific parameter values need to be determined according to the business, and the memory of the machine and the average data size of each request should be considered comprehensively. Recommended: Java Interview Questions
❝One final note: using buffers can also reduce the bandwidth consumption of immediate transfers.
❞
Seven, Nginx cache mechanism
For performance optimization, caching is a solution that can greatly improve performance, so caching can be seen almost everywhere, such as client caching, proxy caching, server caching, etc., and caching is a part of proxy caching Nginx
. kind. For the whole system, the advantages brought by adding cache are extra obvious:
-
Reduced bandwidth consumption for re-requesting resources to the backend or file server.
-
It reduces the access pressure of downstream servers and improves the overall throughput of the system.
-
Response times are reduced, loading speeds are improved, and pages open faster.
So in Nginx
, how to configure the proxy cache? Let's take a look at the cache-related configuration items first:
"proxy_cache_path" : The path of the proxy cache.
grammar:
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Yes, you read that right, it is so long..., explain the meaning of each parameter item:
-
path
: The path address of the cache. -
levels
: Hierarchical structure of cache storage, up to three levels of directories are allowed. -
use_temp_path
: Whether to use a temporary directory. -
keys_zone
: Designate a shared memory space to store hotspot keys (1M can store 8000 keys). -
inactive
: Set how long the cache will be deleted after it has not been accessed (default is ten minutes). -
max_size
: The maximum storage space allowed for the cache. After the cache is exceeded, the cache will be removed based on the LRU algorithm. Nginx will create a Cache manager process to remove the data, or it can be purge. -
manager_files
: The manager process removes the upper limit of the number of cache files each time. -
manager_sleep
: The upper limit of the time for the manager process to remove cache files each time. -
manager_threshold
: The interval between each time the manager process removes the cache. -
loader_files
: When restarting Nginx to load the cache, the number of loads each time, the default is 100. -
loader_sleep
: The maximum allowed time limit for each loading, the default is 200ms. -
loader_threshold
: After loading once, the pause time interval, the default is 50ms. -
purger
: Whether to enable the purge method to remove data. -
purger_files
: Amount each time cache files are removed. -
purger_sleep
: The maximum time allowed to be consumed each time it is removed. -
purger_threshold
: The interval of pause after each removal.
"proxy_cache" : Turn on or off the proxy cache, and you need to specify a shared memory area when turning it on.
grammar:
proxy_cache zone | off;
zone is the name of the memory area, which is the name set by keys_zone above.
"proxy_cache_key" : defines how to generate the cache key.
grammar:
proxy_cache_key string;
string is the rule for generating Key, eg $scheme$proxy_host$request_uri
.
"proxy_cache_valid" : The status code and expiration time of the effective cache.
grammar:
proxy_cache_valid [code ...] time;
code is the status code, and time is the effective time. Different cache times can be set according to the status code.
For example:proxy_cache_valid 200 302 30m;
"proxy_cache_min_uses" : Set how many times a resource is requested before being cached.
grammar:
proxy_cache_min_uses number;
number is the number of times, the default is 1.
"proxy_cache_use_stale" : When an exception occurs in the backend, whether to allow Nginx to return the cache as a response.
grammar:
proxy_cache_use_stale error;
error is the error type and can be configured timeout|invalid_header|updating|http_500...
.
"proxy_cache_lock" : For the same request, whether to enable the lock mechanism, only one request is allowed to be sent to the backend.
grammar:
proxy_cache_lock on | off;
"proxy_cache_lock_timeout" : Configure the lock timeout mechanism, and the request will be released after the specified time is exceeded.
proxy_cache_lock_timeout time;
"proxy_cache_methods" : Set for which HTTP methods to enable caching.
grammar:
proxy_cache_methods method;
method is the request method type, such as GET, HEAD, etc.
"proxy_no_cache" : Defines the conditions for not storing the cache, and will not be saved when it is met.
grammar:
proxy_no_cache string...;
string is the condition, for example$cookie_nocache $arg_nocache $arg_comment;
"proxy_cache_bypass" : Defines the conditions for not reading the cache, and will not read from the cache when it is met.
grammar:
proxy_cache_bypass string...;
Similar to the above proxy_no_cache
configuration method.
"add_header" : Add field information to the response header.
grammar:
add_header fieldName fieldValue;
"$upstream_cache_status" : records whether the cache is hit, there are many situations:
-
MISS
: The request misses the cache. -
HIT
: The request hits the cache. -
EXPIRED
: The request hit the cache but the cache has expired. -
STALE
: The request hit a stale cache. -
REVALIDDATED
: Nginx verifies that stale caches are still valid. -
UPDATING
: The hit's cache content is stale, but the cache is being updated. -
BYPASS
: The response result is fetched from the origin server.
❝PS: This is different from the previous ones. The previous ones are all parameter items. This one is an Nginx built-in variable.
❞
OK~, Nginx
after getting a general understanding of the cache configuration items in , let’s configure Nginx
the proxy cache:
http{
# 设置缓存的目录,并且内存中缓存区名为hot_cache,大小为128m,
# 三天未被访问过的缓存自动清楚,磁盘中缓存的最大容量为2GB。
proxy_cache_path /soft/nginx/cache levels=1:2 keys_zone=hot_cache:128m inactive=3d max_size=2g;
server{
location / {
# 使用名为nginx_cache的缓存空间
proxy_cache hot_cache;
# 对于200、206、304、301、302状态码的数据缓存1天
proxy_cache_valid 200 206 304 301 302 1d;
# 对于其他状态的数据缓存30分钟
proxy_cache_valid any 30m;
# 定义生成缓存键的规则(请求的url+参数作为key)
proxy_cache_key $host$uri$is_args$args;
# 资源至少被重复访问三次后再加入缓存
proxy_cache_min_uses 3;
# 出现重复请求时,只让一个去后端读数据,其他的从缓存中读取
proxy_cache_lock on;
# 上面的锁超时时间为3s,超过3s未获取数据,其他请求直接去后端
proxy_cache_lock_timeout 3s;
# 对于请求参数或cookie中声明了不缓存的数据,不再加入缓存
proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;
# 在响应头中添加一个缓存是否命中的状态(便于调试)
add_header Cache-status $upstream_cache_status;
}
}
}
Then look at the effect, as follows:
When accessing for the first time, because the resource has not been requested yet, there is no data in the cache, so the cache is not hit. For the second and third times, the cache is still not hit, and the hit is not displayed until the fourth time. Why is this? Because in the previous cache configuration, we configured the minimum condition for joining the cache as: "" Resources must be requested at least three times before they are added to the cache." This can avoid a lot of space occupied by invalid caches.
cache cleaning
When there are too many caches, if they are not cleaned up in time, the disk space will be "eaten up". Therefore, we need a complete cache cleaning mechanism to delete the cache. There are related options in the previous parameters, which can help us automatically clean up after proxy_cache_path
opening purger
Cache, but unfortunately: ** purger
series parameters can only be used in the commercial version NginxPlus
, so you need to pay to use them. **
But there is no way out, we can ngx_cache_purge
replace it with a powerful third-party module, let’s install the plugin first: ① First go to the Nginx
installation directory and create a cache_purge
directory:
[root@localhost]# mkdir cache_purge && cd cache_purge
② Pull the compressed file of the installation package wget
from above through the command and decompress it:github
[root@localhost]# wget https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.tar.gz
[root@localhost]# tar -xvzf 2.3.tar.gz
③ Go to the previous Nginx
decompression directory again:
[root@localhost]# cd /soft/nginx/nginx1.21.6
④ Rebuild once Nginx
, and --add-module
add the third-party module just passed the instruction:
[root@localhost]# ./configure --prefix=/soft/nginx/ --add-module=/soft/nginx/cache_purge/ngx_cache_purge-2.3/
⑤ Compile again according to what you just built Nginx
, "but remember not to make install
" :
[root@localhost]# make
⑥Delete the previous Nginx
startup file, and move it to another location if you are worried:
[root@localhost]# rm -rf /soft/nginx/sbin/nginx
⑦ From the generated objs
directory, re-copy a Nginx
startup file to the original location:
[root@localhost]# cp objs/nginx /soft/nginx/sbin/nginx
At this point, ngx_cache_purge
the installation of the third-party cache clearing module is complete. Next, modify nginx.conf
the configuration slightly and add a location
rule:
location ~ /purge(/.*) {
# 配置可以执行清除操作的IP(线上可以配置成内网机器)
# allow 127.0.0.1; # 代表本机
allow all; # 代表允许任意IP清除缓存
proxy_cache_purge $host$1$is_args$args;
}
Then restart Nginx
, and then you can http://xxx/purge/xx
clear the cache by the following method.
Eight, Nginx implements IP black and white list
Sometimes there are often some requirements, and some interfaces may only be open to corresponding partners, or API
partners who purchase/access, then it is necessary to implement IP
a function similar to a whitelist at this time. And sometimes some malicious attackers or crawler programs need to be prohibited from accessing the website again after being identified, so a IP
blacklist also needs to be implemented. Then these functions do not need to be implemented by the backend, but can Nginx
be processed directly in .
Nginx
The black and white list mechanism is mainly allow、deny
realized through configuration items:
allow xxx.xxx.xxx.xxx; # 允许指定的IP访问,可以用于实现白名单。
deny xxx.xxx.xxx.xxx; # 禁止指定的IP访问,可以用于实现黑名单。
When you want to block/open multiple IP
accesses at the same time, if all of IP
them are written in nginx.conf
the file, they will not be displayed. This method is redundant, so you can create two new files BlocksIP.conf、WhiteIP.conf
:
# --------黑名单:BlocksIP.conf---------
deny 192.177.12.222; # 屏蔽192.177.12.222访问
deny 192.177.44.201; # 屏蔽192.177.44.201访问
deny 127.0.0.0/8; # 屏蔽127.0.0.1到127.255.255.254网段中的所有IP访问
# --------白名单:WhiteIP.conf---------
allow 192.177.12.222; # 允许192.177.12.222访问
allow 192.177.44.201; # 允许192.177.44.201访问
allow 127.45.0.0/16; # 允许127.45.0.1到127.45.255.254网段中的所有IP访问
deny all; # 除开上述IP外,其他IP全部禁止访问
After adding the ones to be banned/opened IP
to the corresponding files, you can nginx.conf
import these two files in:
http{
# 屏蔽该文件中的所有IP
include /soft/nginx/IP/BlocksIP.conf;
server{
location xxx {
# 某一系列接口只开放给白名单中的IP
include /soft/nginx/IP/blockip.conf;
}
}
}
As for where to import the file, this is not arbitrary. If you want to block/open the entire site, http
import it in . If you only need to block/open under a domain name sever
, import it in . open IP
, then location
import it in.
❝Of course, the above is just the simplest
❞IP
black/white list implementation method, and it can also bengx_http_geo_module、ngx_http_geo_module
implemented through a third-party library (this method can be blocked by region and country, andIP
a library is provided).
Nine, Nginx cross-domain configuration
The cross-domain problem is actually a relatively rare problem in the previous single-architecture development, unless it needs to be connected to a third party SDK
, this problem needs to be dealt with. However, with the popularity of separation of front and back ends and distributed architecture, cross-domain issues have become a problem that every Java developer must know how to solve.
Causes of cross-domain problems
The main reason for cross-domain problems is the "same-origin policy" . In order to ensure the security of user information and prevent malicious websites from stealing data, the same-origin policy is necessary, otherwise cookie
it can be shared. Since http
stateless protocols are usually used cookie
to achieve stateful information records, such as user identity/password, etc., once cookie
shared, the user's identity information will be stolen.
The same-origin policy mainly refers to the same three points. Two requests with the same "protocol + domain name + port" can be regarded as the same source, but if any point is different, it means that they are from two different sources. The same-origin policy restricts resource interaction between different origins.
Nginx solves cross-domain problems
After figuring out the cause of the cross-domain problem, Nginx
how can we solve the cross-domain problem next? In fact, it is relatively simple, nginx.conf
just add a little configuration in :
location / {
# 允许跨域的请求,可以自定义变量$http_origin,*表示所有
add_header 'Access-Control-Allow-Origin' *;
# 允许携带cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
# 允许跨域请求的方法:GET,POST,OPTIONS,PUT
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT';
# 允许请求时携带的头部信息,*表示所有
add_header 'Access-Control-Allow-Headers' *;
# 允许发送按段获取资源的请求
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
# 一定要有!!!否则Post请求无法进行跨域!
# 在发送Post跨域请求前,会以Options方式发送预检请求,服务器接受时才会正式请求
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
# 对于Options方式的请求返回204,表示接受跨域请求
return 204;
}
}
After nginx.conf
the above configuration is added to the file, the cross-domain request will take effect.
❝❞
HandlerInterceptorAdapter
But if the backend is developed using a distributed architecture, sometimes RPC calls also need to solve cross-domain problems, otherwise there will also be exceptions that cannot be cross-domain requests, so you can inherit classes in your backend projects.WebMvcConfigurer
Interfaces and annotations@CrossOrgin
are used to implement cross-domain configuration between interfaces.
10. Nginx anti-leech design
First understand what hotlinking is: ""hotlinking refers to the external display of resources imported from the current website by external websites"" , let's give a simple example to understand:
❝Just like the wallpaper website
❞X
Zhan,Y
Zhan,X
Zhan is a way to buy copyrights and sign authors little by little, thus accumulating a large amount of wallpaper materials, butY
due to various reasons such as funds, Zhan directly<img src="X站/xxx.jpg" />
copiedX
all the wallpapers of Zhan through this method Resources, and then provided to users for downloading.
So if we are from this X
site Boss
, we must be unhappy, so how can we shield such problems at this time? Then the ""anti-leech"" to be described next is here!
Nginx
The implementation of the anti-leech mechanism is Referer
related to a header field: This field mainly describes where the current request is sent from, then Nginx
you can get this value in , and then judge whether it is a resource reference request of this site, if not then Access not allowed. Nginx
There is a configuration item in valid_referers
, which can meet the previous requirements. The syntax is as follows:
valid_referers none | blocked | server_names | string ...;
-
none
: Indicates that request access withoutReferer
fields is accepted.HTTP
-
blocked
: Indicates that access is permittedhttp://
orhttps//
otherwise requested. -
server_names
: The white list of resources, here you can specify the domain names that are allowed to be accessed. -
string
: You can customize the string, control wildcards, and regular expressions.
After a brief understanding of the syntax, the next implementation is as follows:
# 在动静分离的location中开启防盗链机制
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){
# 最后面的值在上线前可配置为允许的域名地址
valid_referers blocked 192.168.12.129;
if ($invalid_referer) {
# 可以配置成返回一张禁止盗取的图片
# rewrite ^/ http://xx.xx.com/NO.jpg;
# 也可直接返回403
return 403;
}
root /soft/nginx/static_resources;
expires 7d;
}
After configuring according to the above content, Nginx
the most basic anti-leeching mechanism has been realized, and finally only need to restart it again! Of course, for the implementation of the anti-leech mechanism, there are also special third-party modules ngx_http_accesskey_module
to achieve a more complete design, and interested friends can go and see by themselves.
❝PS: The anti-leeching mechanism cannot solve the crawler's forged
❞referers
information grabbing data in this way.
Eleven, Nginx large file transfer configuration
In some business scenarios, some large files need to be transferred, but there will often be some problems when transferring large files Bug
, such as file exceeding the limit, request timeout during file transfer, etc., then you can Nginx
do some configuration at this time, let’s understand first Some configuration items that may be used when transferring large files:
When transferring large files, the four parameter values of client_max_body_size
, client_header_timeout
, proxy_read_timeout
, proxy_send_timeout
can be configured according to the actual situation of your project.
❝The above configuration is only required as a proxy layer, because the final client transfers files or directly interacts with the backend. Here, the
❞Nginx
configuration as a gateway layer is only adjusted to a level that can "accommodate large files" transfer. Of course,Nginx
it can also be used as a file server, but it needs to use a special third-party modulenginx-upload-module
. If there are not many functions for file upload in the project, it is recommended toNginx
build it. After all, it can save a file server resource. However, if the file upload/download is more frequent, it is recommended to set up an additional file server and hand over the upload/download function to the backend for processing.
12. Nginx configures SLL certificate
As more and more websites are connected HTTPS
, it is not enough Nginx
to configure only in the middle HTTP
, and it is often necessary to listen to 443
the port request HTTPS
. In order to ensure communication security, the server needs to configure the corresponding digital certificate. When the project is used Nginx
as a gateway, then the certificate It also needs to be configured in Nginx
, and then briefly talk about SSL
the certificate configuration process:
① First go to the CA organization or apply for the corresponding SSL
certificate from the cloud console, and download Nginx
the version certificate after passing the review.
② After downloading the digital certificate, there are a total of three complete files: .crt、.key、.pem
:
-
.crt
: Digital certificate file,.crt
which is.pem
an extended file, so some people may not have it after downloading. -
.key
: The server's private key file and the asymmetrically encrypted private key are used to decrypt the data transmitted by the public key. -
.pem
:Base64-encoded
The text file of the source certificate in encoded format, and the extension name can be modified according to the needs.
③Create a Nginx
new certificate
directory under the directory, and upload the downloaded certificate/private key and other files to the directory.
④ Finally, modify nginx.conf
the file, as follows:
# ----------HTTPS配置-----------
server {
# 监听HTTPS默认的443端口
listen 443;
# 配置自己项目的域名
server_name www.xxx.com;
# 打开SSL加密传输
ssl on;
# 输入域名后,首页文件所在的目录
root html;
# 配置首页的文件名
index index.html index.htm index.jsp index.ftl;
# 配置自己下载的数字证书
ssl_certificate certificate/xxx.pem;
# 配置自己下载的服务器私钥
ssl_certificate_key certificate/xxx.key;
# 停止通信时,加密会话的有效期,在该时间段内不需要重新交换密钥
ssl_session_timeout 5m;
# TLS握手时,服务器采用的密码套件
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
# 服务器支持的TLS版本
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 开启由服务器决定采用的密码套件
ssl_prefer_server_ciphers on;
location / {
....
}
}
# ---------HTTP请求转HTTPS-------------
server {
# 监听HTTP默认的80端口
listen 80;
# 如果80端口出现访问该域名的请求
server_name www.xxx.com;
# 将请求改写为HTTPS(这里写你配置了HTTPS的域名)
rewrite ^(.*)$ https://www.xxx.com;
}
OK~, according to the above configuration Nginx
, your website can https://
be accessed through the method, and when the client uses http://
the method to access, it will be automatically rewritten as HTTPS
a request. Recommended: Java Interview Questions
Thirteen, Nginx high availability
If a single node is deployed online Nginx
, natural disasters and man-made disasters will inevitably occur, such as system abnormalities, program downtime, server power outages, computer room explosions, and the destruction of the earth... Hahaha, exaggerated. However, there are indeed hidden dangers in the actual production environment. As Nginx
the gateway layer of the entire system accesses external traffic, once it Nginx
goes down, the entire system will eventually become unavailable. This is undoubtedly extremely bad for the user experience, so it is also Nginx
High availability must be guaranteed .
❝Next, the mechanism will be adopted to achieve
❞keepalived
high availability. It doesn't mean only members, but means , that is, virtual .VIP
Nginx
VIP
Virtual IP
IP
keepalived
In the previous development of the single-node architecture, it was a relatively frequently used high-availability technology. For example, the mechanism provided MySQL、Redis、MQ、Proxy、Tomcat
by etc. will be used to achieve high availability of single-node applications.keepalived
VIP
Keepalived + restart script + dual-machine hot standby construction
① First create a corresponding directory and download it keepalived
to Linux
and unzip it:
[root@localhost]# mkdir /soft/keepalived && cd /soft/keepalived
[root@localhost]# wget https://www.keepalived.org/software/keepalived-2.2.4.tar.gz
[root@localhost]# tar -zxvf keepalived-2.2.4.tar.gz
②Enter the decompressed keepalived
directory and build the installation environment, then compile and install:
[root@localhost]# cd keepalived-2.2.4
[root@localhost]# ./configure --prefix=/soft/keepalived/
[root@localhost]# make && make install
③Enter the installation directory /soft/keepalived/etc/keepalived/
and edit the configuration file:
[root@localhost]# cd /soft/keepalived/etc/keepalived/
[root@localhost]# vi keepalived.conf
④ Edit keepalived.conf
the core configuration file of the host, as follows:
global_defs {
# 自带的邮件提醒服务,建议用独立的监控或第三方SMTP,也可选择配置邮件发送。
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
# 高可用集群主机身份标识(集群中主机身份标识名称不能重复,建议配置成本机IP)
router_id 192.168.12.129
}
# 定时运行的脚本文件配置
vrrp_script check_nginx_pid_restart {
# 之前编写的nginx重启脚本的所在位置
script "/soft/scripts/keepalived/check_nginx_pid_restart.sh"
# 每间隔3秒执行一次
interval 3
# 如果脚本中的条件成立,重启一次则权重-20
weight -20
}
# 定义虚拟路由,VI_1为虚拟路由的标示符(可自定义名称)
vrrp_instance VI_1 {
# 当前节点的身份标识:用来决定主从(MASTER为主机,BACKUP为从机)
state MASTER
# 绑定虚拟IP的网络接口,根据自己的机器的网卡配置
interface ens33
# 虚拟路由的ID号,主从两个节点设置必须一样
virtual_router_id 121
# 填写本机IP
mcast_src_ip 192.168.12.129
# 节点权重优先级,主节点要比从节点优先级高
priority 100
# 优先级高的设置nopreempt,解决异常恢复后再次抢占造成的脑裂问题
nopreempt
# 组播信息发送间隔,两个节点设置必须一样,默认1s(类似于心跳检测)
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
# 将track_script块加入instance配置块
track_script {
# 执行Nginx监控的脚本
check_nginx_pid_restart
}
virtual_ipaddress {
# 虚拟IP(VIP),也可扩展,可配置多个。
192.168.12.111
}
}
⑤ Clone a previous virtual machine as the slave (standby) machine, and edit keepalived.conf
the files of the slave machine as follows:
global_defs {
# 自带的邮件提醒服务,建议用独立的监控或第三方SMTP,也可选择配置邮件发送。
notification_email {
root@localhost
}
notification_email_from root@localhost
smtp_server localhost
smtp_connect_timeout 30
# 高可用集群主机身份标识(集群中主机身份标识名称不能重复,建议配置成本机IP)
router_id 192.168.12.130
}
# 定时运行的脚本文件配置
vrrp_script check_nginx_pid_restart {
# 之前编写的nginx重启脚本的所在位置
script "/soft/scripts/keepalived/check_nginx_pid_restart.sh"
# 每间隔3秒执行一次
interval 3
# 如果脚本中的条件成立,重启一次则权重-20
weight -20
}
# 定义虚拟路由,VI_1为虚拟路由的标示符(可自定义名称)
vrrp_instance VI_1 {
# 当前节点的身份标识:用来决定主从(MASTER为主机,BACKUP为从机)
state BACKUP
# 绑定虚拟IP的网络接口,根据自己的机器的网卡配置
interface ens33
# 虚拟路由的ID号,主从两个节点设置必须一样
virtual_router_id 121
# 填写本机IP
mcast_src_ip 192.168.12.130
# 节点权重优先级,主节点要比从节点优先级高
priority 90
# 优先级高的设置nopreempt,解决异常恢复后再次抢占造成的脑裂问题
nopreempt
# 组播信息发送间隔,两个节点设置必须一样,默认1s(类似于心跳检测)
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
# 将track_script块加入instance配置块
track_script {
# 执行Nginx监控的脚本
check_nginx_pid_restart
}
virtual_ipaddress {
# 虚拟IP(VIP),也可扩展,可配置多个。
192.168.12.111
}
}
⑥Create a new scripts
directory and write Nginx
a restart script check_nginx_pid_restart.sh
:
[root@localhost]# mkdir /soft/scripts /soft/scripts/keepalived
[root@localhost]# touch /soft/scripts/keepalived/check_nginx_pid_restart.sh
[root@localhost]# vi /soft/scripts/keepalived/check_nginx_pid_restart.sh
#!/bin/sh
# 通过ps指令查询后台的nginx进程数,并将其保存在变量nginx_number中
nginx_number=`ps -C nginx --no-header | wc -l`
# 判断后台是否还有Nginx进程在运行
if [ $nginx_number -eq 0 ];then
# 如果后台查询不到`Nginx`进程存在,则执行重启指令
/soft/nginx/sbin/nginx -c /soft/nginx/conf/nginx.conf
# 重启后等待1s后,再次查询后台进程数
sleep 1
# 如果重启后依旧无法查询到nginx进程
if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
# 将keepalived主机下线,将虚拟IP漂移给从机,从机上线接管Nginx服务
systemctl stop keepalived.service
fi
fi
⑦The script file written needs to change the encoding format and grant execution permission, otherwise the execution may fail:
[root@localhost]# vi /soft/scripts/keepalived/check_nginx_pid_restart.sh
:set fileformat=unix # 在vi命令里面执行,修改编码格式
:set ff # 查看修改后的编码格式
[root@localhost]# chmod +x /soft/scripts/keepalived/check_nginx_pid_restart.sh
⑧Since the installation keepalived
is a custom installation location, some files need to be copied to the system directory:
[root@localhost]# mkdir /etc/keepalived/
[root@localhost]# cp /soft/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
[root@localhost]# cp /soft/keepalived/keepalived-2.2.4/keepalived/etc/init.d/keepalived /etc/init.d/
[root@localhost]# cp /soft/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
⑨Add keepalived
the system service and set to enable self-start, and then test whether the startup is normal:
[root@localhost]# chkconfig keepalived on
[root@localhost]# systemctl daemon-reload
[root@localhost]# systemctl enable keepalived.service
[root@localhost]# systemctl start keepalived.service
Other commands:
systemctl disable keepalived.service # 禁止开机自动启动
systemctl restart keepalived.service # 重启keepalived
systemctl stop keepalived.service # 停止keepalived
tail -f /var/log/messages # 查看keepalived运行时日志
⑩Finally, test VIP
whether it takes effect, by checking whether the virtual machine is successfully mounted IP
:
[root@localhost]# ip addr
Virtual IP-VIP
❝From the figure above, it can be clearly seen that the virtual machine has been successfully mounted, but the virtual machine will not be mounted on
❞IP
another machine . Only when the main machine goes offline, the slave machine will go online and take over . Finally, test whether the external network can communicate normally, that is, directly in :192.168.12.130
IP
192.168.12.130
VIP
VIP
Windows
ping VIP
Ping-VIP
When the external VIP
communication is passed, it can also Ping
be communicated normally, which means that the virtual IP
configuration is successful. Recommended: Java Interview Questions
Nginx High Availability Test
After the above steps, keepalived
the VIP
mechanism has been successfully built. In the last stage, several things were mainly done:
-
1.
Nginx
Mounted for the deployed machineVIP
. -
Second, through
keepalived
the establishment of a master-slave dual-machine hot backup. -
Third, through
keepalived
the realization ofNginx
downtime restart.
Because there is no domain name in front, the initial server_name
configuration is the current machine IP
, so nginx.conf
the configuration needs to be changed slightly:
sever{
listen 80;
# 这里从机器的本地IP改为虚拟IP
server_name 192.168.12.111;
# 如果这里配置的是域名,那么则将域名的映射配置改为虚拟IP
}
Finally, let's experiment with the effect:
Nginx down
❝In the above process, first start
❞keepalived、nginx
the services respectively, and thennginx
simulateNginx
the downtime situation by manually stopping. After a while, check the background process again, and we will find thatnginx
it is still alive.
From this process, it is not difficult to find that the function of automatic restart after downtime keepalived
has been realized for us Nginx
, so let's simulate the situation when the server fails:
server failure
❝In the above process, we manually closed
❞keepalived
the service to simulate the power failure of the machine, hardware damage, etc. (because the power failure of the machine = thekeepalived
process in the host disappears), and then checkedIP
the information of the machine again, it is obvious that we can seeVIP
Disappeared!
Now switch to another machine: 192.168.12.130
take a look at the situation:
IP status of 130
❝At this moment, we will find that
❞192.168.12.129
after the host goes down, the VIP automatically drifts from the host to the slave192.168.12.130
, and at this time the client's request will eventually come to130
this machineNginx
.
"In the end, after Keepalived
using Nginx
the master-slave hot backup, whether it encounters various failures such as online downtime or power failure in the computer room, it can ensure that the application system can provide users with 7x24
hourly services."
Fourteen, Nginx performance optimization
The length of the article here is quite long. Finally, let’s talk about Nginx
the performance optimization. The main thing is to briefly talk about the optimization items with the highest income. I won’t expand the description here. After all, there are many reasons for affecting performance. For example, the network, server hardware, operating system, back-end services, the program itself, database services, etc.
Optimization 1: Open the long connection configuration
Usually Nginx acts as a proxy service and is responsible for distributing client requests, so it is recommended to enable HTTP
long connections so that users can reduce the number of handshakes and reduce server loss, as follows:
upstream xxx {
# 长连接数
keepalive 32;
# 每个长连接提供的最大请求数
keepalived_requests 100;
# 每个长连接没有新的请求时,保持的最长时间
keepalive_timeout 60s;
}
Optimization 2. Enable zero-copy technology
The concept of zero copy appears in most middleware with relatively good performance, such as Kafka、Netty
etc., and Nginx
the data zero copy technology can also be configured in the middleware, as follows:
sendfile on; # 开启零拷贝机制
The difference between the zero-copy read mechanism and the traditional resource read mechanism:
-
"Traditional way:" hardware --> kernel --> user space --> program space --> program kernel space --> network socket
-
"Zero copy method:" hardware --> kernel --> program kernel space --> network socket
From the comparison of the above process, it is easy to see the performance difference between the two.
Optimization 3. Open the no-delay or multi-packet co-delivery mechanism
Nginx
There are two key performance parameters in , that is , tcp_nodelay、tcp_nopush
the opening method is as follows:
tcp_nodelay on;
tcp_nopush on;
TCP/IP
The protocol uses the Nagle algorithm by default, that is, in the process of network data transmission, each data packet will not be sent out immediately, but will wait for a period of time, and combine the following data packets into a datagram However, although this algorithm improves the network throughput, the real-time performance is reduced.
❝Therefore, your project is a highly interactive application, so you can manually enable
❞tcp_nodelay
the configuration, so that every data packet submitted by the application to the kernel will be sent out immediately. But this will generate a large number ofTCP
packet headers and increase the network overhead.
On the contrary, the business of some projects does not require high real-time data, but pursues higher throughput. Then you can enable the tcp_nopush
configuration item. This configuration is similar to the meaning of "plug". First, plug the connection so that The data will not be sent out yet, and will be sent out after the plug is removed. After setting this option, the kernel will try to splice small data packets into one large data packet (one MTU
) and send it out.
❝Of course, if after a certain period of time (usually
❞200ms
), the kernel still has not accumulated aMTU
certain amount, it must also send the existing data, otherwise it will always be blocked.
tcp_nodelay、tcp_nopush
The two parameters are "mutually exclusive". If the application pursues response speed, it is recommended to enable tcp_nodelay
the parameter, such as IM
, financial and other types of projects. For applications that pursue throughput, it is recommended to enable tcp_nopush
parameters, such as scheduling system, reporting system, etc.
❝Note: ①
❞tcp_nodelay
Generally, it should be established and used when the long connection mode is turned on. ②tcp_nopush
The parameters must be enabledsendfile
before they can be used.
Optimization 4. Adjust Worker Work Process
Nginx
After startup, only one Worker
worker process will be opened by default to handle client requests, and we can start the corresponding number of worker processes according to the number of CPU cores of the machine, so as to improve the overall concurrency support, as follows:
# 自动根据CPU核心数调整Worker进程数量
worker_processes auto;
❝❞
8
It is OK if the maximum number of working processes is 1, and8
there will be no further performance improvement after 1.
At the same time, you can also slightly adjust the number of file handles that each worker process can open:
# 每个Worker能打开的文件描述符,最少调整至1W以上,负荷较高建议2-3W
worker_rlimit_nofile 20000;
❝The operating system kernel (
❞kernel
) uses file descriptors to access files. Whether it is opening, creating, reading, or writing files, it is necessary to use file descriptors to specify the file to be operated. Therefore, the larger the value, it represents a The more files the process can operate (but it cannot exceed the kernel limit, the3.8W
upper limit is recommended at most).
Optimization 5. Turn on the CPU affinity mechanism
Friends who are familiar with concurrent programming know that the number of processes/threads often far exceeds the number of CPU cores in the system, because the principle of operating system execution is essentially to use the time slice switching mechanism, that is, one CPU core will be in multiple processes. Frequent switching between them causes a large performance loss.
The CPU affinity mechanism refers to Nginx
binding each working process to a fixed CPU core, thereby reducing the time overhead and resource consumption caused by CPU switching. The opening method is as follows:
worker_cpu_affinity auto;
Optimization 6. Open the epoll model and adjust the number of concurrent connections
It was mentioned at the very beginning: Nginx、Redis
all programs are implemented based on the multiplexing model, but the original multiplexing model select/poll
can only monitor 1024
a maximum of a connection, and epoll
it belongs to select/poll
the enhanced version of the interface, so using this model can Improve individual Worker
performance to a great extent , as follows:
events {
# 使用epoll网络模型
use epoll;
# 调整每个Worker能够处理的连接数上限
worker_connections 10240;
}
❝❞
select/poll/epoll
The model will not be elaborated here , and will be analyzed in detail in the following IO model articles.
Fifteen, put it at the end
So far, Nginx
most of the content has been explained. Regarding the performance optimization content of the last section, in fact, the dynamic and static separation, allocation buffer, resource cache, anti-leeching, resource compression, etc. mentioned earlier can also be summarized as A solution for performance optimization.