Nginx-2 详解处理 Http 请求

Nginx 作为当今最流行的开源 Web 服务器之一,以其高性能、高稳定性和丰富的功能而闻名。在处理 HTTP请求 的过程中,Nginx 采用了模块化的设计,将整个请求处理流程划分为若干个阶段,每个阶段都可以由特定的模块来处理。这种设计不仅使得 Nginx 具有极高的灵活性和可扩展性,而且也方便了开发者对 Nginx 进行定制和优化。

Nginx 在与客户端建立连接(三次握手)后通过事件驱动模块获取 Http 请求,解析 header 头部并进行处理,接下来的处理可以大致分为以下 11 阶段,每个阶段都会有一些模块和配置项进行处理,需要关注的是每个模块可以发挥什么作用,有哪些配置项。

image-20250613114549375

而每一个阶段中的也可能有多个模块可以对其发挥作用,这些模块之间也是有顺序的

image-20250613114728929

具体的处理顺序可以去 nginx-1.28.0/objs/ngx_modules.c 中查看,该文件中 ngx_module_names 字段标识了模块的处理顺序,正常为由下向上执行,某些特殊指令可以跳转到其他模块

char *ngx_module_names[] = {"ngx_core_module","ngx_errlog_module","ngx_conf_module","ngx_regex_module","ngx_events_module","ngx_event_core_module","ngx_epoll_module","ngx_http_module","ngx_http_core_module","ngx_http_log_module","ngx_http_upstream_module","ngx_http_static_module","ngx_http_autoindex_module","ngx_http_index_module","ngx_http_mirror_module","ngx_http_try_files_module","ngx_http_auth_basic_module","ngx_http_access_module","ngx_http_limit_conn_module","ngx_http_limit_req_module","ngx_http_realip_module","ngx_http_geo_module","ngx_http_map_module","ngx_http_split_clients_module","ngx_http_referer_module","ngx_http_rewrite_module","ngx_http_proxy_module","ngx_http_fastcgi_module","ngx_http_uwsgi_module",......
}

1、POST_READ

该阶段为接受到完整的 HTTP 头部后,读取请求内容阶段,nginx 读取并解析完请求头之后就立即开始执行

该阶段经常用到 realip 模块,可以获取到一些原始的值,用于做日志分析、限流等使用

我们知道一个请求从发出到 nginx 接收,中间可能经过了多台服务器,为了获取到这个原始 IP,通常会使用两个特定的HTTP头部字段:X-Forwarded-ForX-Real-IP

  • X-Forwarded-For:用于传递客户端请求经过的所有代理服务器的 IP 地址。这个头部通常包含一个或多个 IP地址,它们按照请求经过代理的顺序排列。如果请求直接发送到服务器,则此头部可能不存在或只包含客户端的 IP 地址。
  • X-Real-IP:记录客户端的真实 IP 地址,它只包含一个 IP 地址。这个头部字段由第一个代理服务器设置,并且在请求穿越后续代理时不会被更改,因此它代表了客户端的原始 IP 地址。

realip 模块

  • 默认不会编译,需要编译时使用 --with-http_realip_module 加入
  • 配置项
    • set_real_ip_from:此指令用于定义信任的代理服务器。只有来自这些服务器的 X-Real-IPX-Forwarded-For 头部字段才会被 Nginx 接受和处理。
    • real_ip_header:通过这个指令,可以指定 Nginx 应该使用 X-Real-IP 还是 X-Forwarded-For 头部来确定客户端的真实 IP 地址。
    • realip_recursive:默认关闭,指示 realip 模块是否已经递归地处理了 X-Forwarded-For 头部字段。
  • 重要变量
    • http_x_real_ip:包含X-Real-IP头部的值,即客户端的真实IP地址。如果该头部不存在,则变量为空
    • remote_addr:默认情况下,这个变量包含服务器接收到的客户端 IP 地址。当realip模块启用并正确配置后,它会被设置为客户端的真实 IP 地址。
    • http_x_forwarded_for:包含X-Forwarded-For头部的值,这是一个 IP 地址列表,记录了客户端以及所有中间代理服务器的IP。

实战:

server {listen 9090;location / {proxy_pass http://127.0.0.1:9091;  # 将请求转发到 server 2proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 本机 IP 加入proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-Proto $scheme;}
}server {listen 9091;# 在 server 2 中配置 realip 模块set_real_ip_from 127.0.0.1;        # 允许来自本地的 IP 地址作为反向代理real_ip_header X-Forwarded-For;    # 使用 X-Forwarded-For 头部获取真实 IPreal_ip_recursive on;              # 如果有多个代理,递归获取真实 IPlocation / {access_log /home/nginx/nginx/logs/access_realip.log;# 测试输出真实 IPreturn 200 "\nClient real ip: $remote_addr, X-Forwarded-For: $http_x_forwarded_for\n";}
}

简单解释一下:

在本机 nginx 启动两个端口 9090 和 9091,9090 在收到请求后会模拟代理服务器转发给 9091,9091 认为本机 ip 是可信的(可以这么理解:如果这个 ip 是可信的,它给我说它收到了一个来自 ** 的请求我才相信,否则我就认为和我三次握手的那个 ip 才是真正的请求 ip )

测试:

[root@VM-16-11-centos ~]# curl -H 'X-Forwarded-For: 1.1.1.1, 2.2.2.2' 123.207.214.107:9090Client real ip: 123.207.214.107, X-Forwarded-For: 1.1.1.1, 2.2.2.2, 123.207.214.107

修改 set_real_ip_from 的值为 127.0.0.2 再测试

[root@VM-16-11-centos ~]# curl -H 'X-Forwarded-For: 1.1.1.1, 2.2.2.2' 123.207.214.107:9090Client real ip: 127.0.0.1, X-Forwarded-For: 1.1.1.1, 2.2.2.2, 123.207.214.107

原因是: 127.0.0.1 被认为不可信,所以虽然 X-Forwarded-For 中最后一个 ip 是 123.207.214.107,但 9091 发现与自己通信的其实是本机的 9090,认为真实 ip 就是 127.0.0.1

2、SERVER_REWRITE

在 uri 与 location 匹配之前修改请求的 URI(重定向),在 server 块中的请求地址重写阶段

由于该阶段在 rewrite 阶段前,所以如果这里出现 return 指令,就不会返回 location 中的 return 了

【1】测试 server 下的重写

server {listen 9092;root html/;# 测试 server 下的重写 404 但是返回 403 界面error_page 404 /403.html;}
[root@VM-16-11-centos nginx]# cat html/403.html
This is 403!
[root@VM-16-11-centos ~]# curl 123.207.214.107:9092/test.txt
This is 403!

【2】server 下的重写与 location 中的 return 相比,return 生效

server {listen 9092;root html/;# 测试 server 下的 error_page 和 location 下的 return 生效情况:location 生效error_page 404 /403.html;location / {return 404 "find nothing location!\n";}}
[root@VM-16-11-centos ~]# curl 123.207.214.107:9092/test.txt
find nothing location!

【2】server 下的 return 先于 location 中的 return 返回

server {listen 9092;root html/;# 测试 server 下的 error_page 和 location 下的 return 生效情况:location 生效error_page 404 /403.html;location / {return 404 "find nothing location!\n";}# 测试 server 下的 return 和 location 下的 return 生效: server 中生效return 404 "find nothing server!\n";}
[root@VM-16-11-centos ~]# curl 123.207.214.107:9092/test.txt
find nothing server!

3、FIND_CONFIG

配置查找阶段,根据请求 uri 匹配 location 表达式,这个阶段不支持 nginx 模块注册处理程序,而是由ngx_http_core_module 模块来完成当前请求与 location 配置快之间的配对工作

location 的匹配规则是仅匹配 URI,忽略参数,有下面三种大的情况:

  • 前缀字符串
    • 常规匹配
    • =:精确匹配
    • ^~:匹配上后则不再进行正则表达式匹配
  • 正则表达式
    • ~:大小写敏感的正则匹配
    • ~*:大小写不敏感
  • 用户内部跳转的命名 location ,可以通过 error_pagetry_files 等指令进行内部跳转。
    • @

建议不同业务使用不同的前缀,原因是 location 支持严格匹配、正则、前缀匹配等多种匹配方式,需要考虑匹配的优先级,相比与熟知匹配优先级,各个业务使用不同前缀更加易读

image-20250613140346755

4、REWRITE

location 块中的请求地址重写阶段,当 rewrite 指令用于 location 中时即运行

语法为:rewrite regex replacement [flag]

作用为将 regex 对应指定的 URL 替换成 replacement

其中 flag 字段有以下可选项:

  • last:用 replacement 这个 URL 进行新的 location 匹配
  • break:break 指令停止当前脚本指令的执行,等价于独立的 break 指令
  • redirect:返回 302 临时重定向
  • permanent:返回 301 永久重定向(永久重定向会被浏览器缓存)

新建一个这样的目录结构

[root@VM-16-11-centos nginx]# tree html/test/
html/test/
|-- first
|   `-- 1.txt
|-- second
|   `-- 2.txt
|-- third`-- 3.txt

配置文件:

server {listen 9093;rewrite_log on;root html/test;location /first {rewrite /first(.*) /second$1 last;return 200 'first!\n';}location /second {rewrite /second(.*) /third$1;return 200 'second!\n';}location /third {return 200 'third!\n';}}
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/first/1.txt
second!
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/first/2.txt
second![root@VM-16-11-centos ~]# curl 123.207.214.107:9093/second/3.txt
second!
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/second/2.txt
second!

出现上述响应的原因是 flag 标志的设置,访问 /first/ 时被重写为了 /second 并按照 last 这个 flag 的规则进行了重新匹配,而 /second 虽然进行了重写,但未配置标志位,所以直接返回了 second 请求下的 200 响应

server {listen 9093;rewrite_log on;root html/test;location /first {rewrite /first(.*) /second$1 last;return 200 'first!\n';}location /second {rewrite /second(.*) /third$1 break;return 200 'second!\n';}location /third {return 200 'third!\n';}}
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/first/3.txt
3.txt
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/third/3.txt
third![root@VM-16-11-centos ~]# curl 123.207.214.107:9093/first/3
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.28.0</center>
</body>
</html>
[root@VM-16-11-centos ~]# curl 123.207.214.107:9093/third/3
third!

当 /second 对应的 flag 被设置为 break 后,url 重写后不再进行 location 匹配,而是真正的去找对应的 /third/3

5、POST_REWRITE

请求地址重写提交阶段,防止递归修改 uri 造成死循环,(一个请求执行10次就会被 nginx 认定为死循环)该阶段只由 ngx_http_core_module 模块实现,无外部模块

配置文件

    server {listen 9094;# 开启日志,便于调试access_log logs/access_post_rewrite.log;error_log logs/post_rewrite_error.log debug;  # 启用调试日志# 重写规则location /loop {rewrite ^/loop(.*)$ /loop_rewritten\$1 last;return 200 "No loop detected\n";}# 默认返回location / {return 200 "Request processed successfully\n";}}

测试

[root@localhost nginx]# curl 123.207.214.107:9094/loop/1
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.28.0</center>
</body>
</html>

查看日志:

2025/06/13 15:55:34 [notice] 32345#0: *4474 rewritten data: "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", args: "", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 "^/loop(.*)$" matches "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 rewritten data: "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", args: "", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 "^/loop(.*)$" matches "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 rewritten data: "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", args: "", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 "^/loop(.*)$" matches "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [notice] 32345#0: *4474 rewritten data: "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", args: "", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"
2025/06/13 15:55:34 [error] 32345#0: *4474 rewrite or internal redirection cycle while processing "/loop_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\_rewritten\/1", client: 218.58.62.117, server: , request: "GET /loop/1 HTTP/1.1", host: "123.207.214.107:9094"

最后会出现: rewrite or internal redirection cycle while processing 的错误,即一直在循环

6、PREACCESS

访问权限检查准备阶段,http 模块介入处理阶段,模块 ngx_limit_conn 和 ngx_limit_req 就运行在此阶段

ngx_limit_conn 顾名思义是限制连接个数的,而 ngx_limit_req 是限制请求数的,conn 即 tcp 连接,在一个 keepalive 周期内,所有的req 可以共用一个 conn

ngx_limit_conn

# 定义一个空间 名为 addr,存放二进制 ip 地址,大小为 10m
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {listen 9097;root html/;location / {limit_conn_status 500;		# 如果有多的连接返回 500 错误limit_conn_log_level  warn;limit_rate 50;				# 每秒返回 50Blimit_conn addr 1;			# 同时只能有 1 个连接}
}

开两个终端测试

[root@VM-16-11-centos zwj]# curl localhost:9097/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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@VM-16-11-centos zwj]# curl localhost:9097/
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.28.0</center>
</body>
</html>

也可以查看 access.log

127.0.0.1 - - [15/Jun/2025:13:59:40 +0800] "GET / HTTP/1.1" 500 177 "-" "curl/7.29.0"
127.0.0.1 - - [15/Jun/2025:13:59:49 +0800] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0"

ngx_limit_req

# 定义一个空间 名为 addr_req,存放二进制 ip 地址,大小为 10m,每分钟最多处理 3 个请求
limit_req_zone $binary_remote_addr zone=addr_req:10m rate=3r/m;# limit_req 这里注意 burst 和 nodelay 选项
# burst 桶大小 缓存请求
# nodelay 超出桶大小后是否直接返回,nodelay 就是不延时,直接返回定义的错误信息
limit_req zone=addr_req burst=3 nodelay;
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=addr_req:10m rate=3r/m;server {listen 9097;root html/;location / {limit_conn_status 500;limit_conn_log_level  warn;limit_rate 50;limit_conn addr 1;#limit_req zone=one burst=3 nodelay;limit_req zone=addr_req;limit_req_status 503;}
}

也可以查看 error.log

2025/06/15 14:13:33 [error] 26915#0: *5530 limiting requests, excess: 0.882 by zone "addr_req", client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "localhost:9097"
"logs/error.log" 175L, 21036C

7、ACCESS

访问权限检查阶段,标准模块 ngx_access,第三方模块 nginx_auth_request 以及第三方模块 ngx_lua 的 access_by_lua 指令运行在此阶段,配置指令多是执行访问控制性质的任务,比如检查用户的访问权限,检查用户的来源 IP 地址是否合法

最常用的其实是 allow deny 指令,比如在系统开发完成给远程客户使用阶段,可以指定允许访问的 IP 块

location / { deny 192.168.1.1; allow 192.168.1.0/24; allow 10.1.1.0/16; allow 2001:0db8::/32; deny all; 
}

这些指令是顺序匹配,满足其中一条后就不会继续了

除此之外常用的还有 auth_basic 和 auth_request ,但这些模块需要生成密码文件来配置使用,有点麻烦这里就不再验证了~

8、POST_ACCESS

在请求通过访问控制之后,Nginx 执行这个阶段的处理。这可以用于执行一些在访问控制之后需要进行的操作。

9、TRY_FILES

如果 http 请求访问静态文件资源,try_files 配置项可以使这个请求顺序地访问多个静态文件资源,直到某个静态文件资源符合选取条件,重要部分为:try files 处理 和 mirrors

try files 允许我们在请求访问静态文件时,顺序地尝试访问多个文件,直到找到一个符合条件的文件。如果没有符合条件的文件,Nginx 会执行指定的备用操作。

目录结构:

html/
|-- 403.html
|-- 50x.html
|-- index.html
|-- file
|   |-- assets
|   |   |-- 1.css
|   |   |-- 2.css
|   |   `-- default.css
|   `-- images
|       |-- 1.txt
|       |-- 2.txt
|       `-- default.txt

配置

    server {listen 9096;root html/file;  # 网站根目录# 处理静态文件location / {try_files $uri $uri/ /index.html;  # 依次尝试 $uri、$uri/、index.html}# 针对特定路径处理,比如 /images 目录下的静态文件location /images/ {try_files $uri $uri/ /images/default.txt;  # 尝试访问图片目录下的文件,如果文件不存在,使用默认}# 其他配置location /assets/ {try_files $uri /assets/default.css;  # 访问 assets 目录下的 CSS 文件,若不存在,使用默认样式}}
[root@VM-16-11-centos nginx]# curl localhost:9096/
index
[root@VM-16-11-centos nginx]# curl localhost:9096/3.html
index[root@VM-16-11-centos nginx]# curl localhost:9096/images/111.txt
default
[root@VM-16-11-centos nginx]# curl localhost:9096/images/1.txt
1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt1111.txt

mirror 处理请求时,生成子请求访问其他服务,对子请求的返回值不做处理

10、CONTENT

内容产生阶段,大部分HTTP模块会介入该阶段,是所有请求处理阶段中最重要的阶段,因为这个阶段的指令通常是用来生成HTTP响应内容的

这里比较重要的部分包括:root/alias 的使用,index 和 autoindex 的使用

root 和 alias 的区别主要在于匹配到 location 后,最终的那个文件到底是加上 location 对应的前缀还是不加

[root@VM-16-11-centos nginx]# tree html/
html/
|-- 403.html
|-- 50x.html
|-- index.html
|-- root
|   `-- index.html

配置文件

server {listen       9095;location /root {root   html;}location /alias {alias   html;}}
[root@VM-16-11-centos nginx]# curl localhost:9095/alias/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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@VM-16-11-centos nginx]# curl localhost:9095/root/index.html
root/html[root@VM-16-11-centos nginx]# curl localhost:9095/alias/root/index.html
root/html

root 会将请求 url 完整的追加在其值的后面,而 alias 则会从请求 url 中先去除 location 匹配的部分再追加

index 指定 / 结尾的目录访问时,返回 index 文件内容

配置

server {listen       9095;charset utf-8;  # 编码格式,不配置的话中文可能乱码#access_log  logs/host.access.log  main;location / {root   html;index index.html index.htm;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}
}

image-20250613162550363

autoindex

    server {listen       9095;charset utf-8;	# 编码格式,不配置的话中文可能乱码#access_log  logs/host.access.log  main;location / {root   myHtml;autoindex on;                # 启用目录列表显示autoindex_exact_size on;     # 可选:禁用文件大小显示(以字节为单位)autoindex_localtime on;      # 可选:显示本地时间}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}

image-20250613161823337

注意:index 模块在 autoindex 之前,所以使用 autoindex 请务必关闭 index 或指定一个不存在的文件

11、LOG

日志模块处理阶段,记录日志,正常会在 logs/access.log 中记录 http 请求的日志信息

默认格式:

log_format combined '$remote_addr - $remote_user [$time_local] ' 
'"$request" $status $body_bytes_sent ' '"$http_referer" 
"$http_user_agent"';

可以根据需要自行修改,同时也会有日志压缩和日志缓存的可配置项

日志格式

access_log path [format=name [buffer=size] [gzip[=level]] [flush=time] [if=condition]];access_log off;

  • path:日志文件的路径,可以包含变量。
  • format:指定日志格式的名称。
  • buffer:设置日志写入的缓冲区大小。
  • gzip:启用日志文件的压缩,并可选地设置压缩级别。
  • flush:设置日志刷新的频率。
  • if:通过条件判断来控制是否记录日志。

日志缓存 日志缓存功能可以减少磁盘 I/O 操作,通过批量写入日志来提高性能。

写入磁盘的条件

  • 待写入磁盘的日志大小超出缓存大小。
  • 达到 flush 指定的时间。
  • worker 进程执行 reopen 命令,或者正在关闭。

我只能说学到这里我大概知道 nginx 的每个阶段可以做什么,具体的指令如果不是经常配置应该还是会忘记~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/85003.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/85003.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/85003.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

40-Oracle 23 ai Bigfile~Smallfile-Basicfile~Securefile矩阵对比

小伙伴们是不是在文件选择上还默认给建文件4G/个么&#xff0c;在oracle每个版本上系统默认属性是什么&#xff0c;选择困难症了没&#xff0c;一起一次性文件存储和默认属性看透。 基于Oracle历代在存储架构的技术演进分析&#xff0c;结合版本升级和23ai新特性&#xff0c;一…

【一】零基础--分层强化学习概览

分层强化学习&#xff08;Hierarchical Reinforcement Learning, HRL&#xff09;最早一般视为1993 年封建强化学习的提出. 一、HL的基础理论 1.1 MDP MDP&#xff08;马尔可夫决策过程&#xff09;&#xff1a;MDP是一种用于建模序列决策问题的框架&#xff0c;包含状态&am…

Java延时

在 Java 中实现延时操作主要有以下几种方式&#xff0c;根据使用场景选择合适的方法&#xff1a; 1. Thread.sleep()&#xff08;最常用&#xff09; java 复制 下载 try {// 延时 1000 毫秒&#xff08;1秒&#xff09;Thread.sleep(1000); } catch (InterruptedExcepti…

电阻篇---下拉电阻的取值

下拉电阻的取值需要综合考虑电路驱动能力、功耗、信号完整性、噪声容限等多方面因素。以下是详细的取值分析及方法&#xff1a; 一、下拉电阻的核心影响因素 1. 驱动能力与电流限制 单片机 IO 口驱动能力&#xff1a;如 STM32 的 IO 口在输入模式下的漏电流通常很小&#xf…

NY271NY274美光科技固态NY278NY284

美光科技NY系列固态硬盘深度剖析&#xff1a;技术、市场与未来 技术前沿&#xff1a;232层NAND架构与性能突破 在存储技术的赛道上&#xff0c;美光科技&#xff08;Micron&#xff09;始终是行业领跑者。其NY系列固态硬盘&#xff08;SSD&#xff09;凭借232层NAND闪存架构的…

微信开发者工具 插件未授权使用,user uni can not visit app

参考&#xff1a;https://www.jingpinma.cn/archives/159.html 问题描述 我下载了一个别人的小程序&#xff0c;想运行看看效果&#xff0c;结果报错信息如下 原因 其实就是插件没有安装&#xff0c;需要到小程序平台安装插件。处理办法如下 在 app.json 里&#xff0c;声…

UE5 读取配置文件

使用免费的Varest插件&#xff0c;可以读取本地的json数据 获取配置文件路径&#xff1a;当前配置文件在工程根目录&#xff0c;打包后在 Windows/项目名称 下 读取json 打包后需要手动复制配置文件到Windows/项目名称 下

【kdump专栏】KEXEC机制中SME(安全内存加密)

【kdump专栏】KEXEC机制中SME&#xff08;安全内存加密&#xff09; 原始代码&#xff1a; /* Ensure that these pages are decrypted if SME is enabled. */ 533 if (pages) 534 arch_kexec_post_alloc_pages(page_address(pages), 1 << order, 0);&#x1f4cc…

C# vs2022 找不到指定的 SDK“Microsof.NET.Sdk

找不到指定的 SDK"Microsof.NET.Sdk 第一查 看 系统盘目录 C:\Program Files\dotnet第二 命令行输入 dotnet --version第三 检查环境变量总结 只要执行dotnet --version 正常返回版本号此问题即解决 第一查 看 系统盘目录 C:\Program Files\dotnet 有2种方式 去检查 是否…

Pytest断言全解析:掌握测试验证的核心艺术

Pytest断言全解析&#xff1a;掌握测试验证的核心艺术 一、断言的本质与重要性 什么是断言&#xff1f; 断言是自动化测试中的验证检查点&#xff0c;用于确认代码行为是否符合预期。在Pytest中&#xff0c;断言直接使用Python原生assert语句&#xff0c;当条件不满足时抛出…

【编译原理】题目合集(一)

未经许可,禁止转载。 文章目录 选择填空综合选择 将编译程序分成若干个“遍”是为了 (D.利用有限的机器内存,但降低了执行效率) A.提高程序的执行效率 B.使程序的结构更加清晰 C.利用有限的机器内存并提高执行效率 D.利用有限的机器内存,但降低了执行效率 词法分析…

uni-app项目实战笔记13--全屏页面的absolute定位布局和fit-content自适应内容宽度

本篇主要实现全屏页面的布局&#xff0c;其中还涉及内容自适应宽度。 创建一个preview.vue页面用于图片预览&#xff0c;写入以下代码&#xff1a; <template><view class"preview"><swiper circular><swiper-item v-for"item in 5&quo…

OVS Faucet Tutorial笔记(下)

官方文档&#xff1a; OVS Faucet Tutorial 5、Routing Faucet Router 通过控制器模拟三层网关&#xff0c;提供 ARP 应答、路由转发功能。 5.1 控制器配置 5.1.1 编辑控制器yaml文件&#xff0c;增加router配置 rootserver1:~/faucet/inst# vi faucet.yaml dps:switch-1:d…

PCB设计教程【大师篇】stm32开发板PCB布线(信号部分)

前言 本教程基于B站Expert电子实验室的PCB设计教学的整理&#xff0c;为个人学习记录&#xff0c;旨在帮助PCB设计新手入门。所有内容仅作学习交流使用&#xff0c;无任何商业目的。若涉及侵权&#xff0c;请随时联系&#xff0c;将会立即处理 1. 布线优先级与原则 - 遵循“重…

Phthon3 学习记录-0613

List&#xff08;列表&#xff09;、Tuple&#xff08;元组&#xff09;、Set&#xff08;集合&#xff09;和 Dictionary&#xff08;字典&#xff09; 在接口自动化测试中&#xff0c;List&#xff08;列表&#xff09;、Tuple&#xff08;元组&#xff09;、Set&#xff08…

UVa12298 3KP-BASH Project

UVa12298 3KP-BASH Project 题目链接题意输入格式输出格式 分析AC 代码 题目链接 UVa12298 3KP-BASH Project 题意 摘自 《算法竞赛入门经典&#xff1a;训练指南》刘汝佳&#xff0c;陈锋著。有删改。 你的任务是为一个假想的 3KP 操作系统编写一个简单的 Bash 模拟器。由于操…

云打包生成的ipa上传构建版本经验分享

在上架ios应用&#xff0c;在苹果开发者中心操作的时候&#xff0c;需要提供一个构建版本&#xff0c;如下图所示&#xff1a; 点击蓝色加号&#xff0c;添加构建版本&#xff0c;但是点击蓝色加号后&#xff0c;并没有构建版本可以选。 原因是需要下载下面它推荐的工具来上传…

ESP32的spi通讯(Arduino)

目录 一.基本配置 1.esp32-wroom-32引脚图 2.接线方式 3.Arduino芯片选择和库文件 3.1Arduino配置&#xff08;2.0.11&#xff09; 3.2 下载ESP32SPISlave库&#xff08;0.6.8&#xff09;文件 二、代码编写 1.主机代码 2.从机代码 3.注意事项 三、运行效果 一.基本…

Spring-rabbit重试消费源码分析

在集成RabbitMQ与Spring Boot 3.1.x时&#xff0c;RetryOperationsInterceptor 是实现消息重试机制的关键组件。这里将深入分析 RetryOperationsInterceptor 的工作原理&#xff0c;尤其是在消费者消费失败时的行为&#xff0c;并结合底层源码进行详解。 一、配置解析 首先&a…

如何使用JacksonTypeHandler处理mysql json字符串转List对象的问题

在使用mysql5.7或更高版本时&#xff0c;json类型字段应用场景越来越多&#xff0c;对于普通的对象或者List<Integer>、List<String>这些基础类型&#xff0c;jacksonTypeHandler都能很好的处理&#xff0c;如下&#xff1a; 1、定义一个person对象 import com.f…