当前位置: 首页 > news >正文

Nginx-2 详解处理 Http 请求

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 的每个阶段可以做什么,具体的指令如果不是经常配置应该还是会忘记~

相关文章:

  • 【MFC】树控件的使用详解
  • Vue 组合式 API 与 选项式 API 全面对比教程
  • Proteus8.17-安装说明
  • nodejs中Express框架的基本使用
  • Proteus8.17-LCD12864液晶屏幕仿真模型
  • 【QT系统相关】QT网络
  • Google DeepMind研究:大语言模型(LLMs) 思维链解码(CoT-decoding)方法解析
  • Django构建简易视频编辑管理系统
  • 【Qt 中的元对象系统(Meta-Object System)】
  • 多模态大语言模型arxiv论文略读(123)
  • java 设计模式_行为型_20中介者模式
  • [蓝桥杯 2025 国 B] 斐波那契字符串一一题解
  • 快速上手文本向量模型 Sentence-Transformers
  • 基于YOLOv8+Deepface的人脸检测与识别系统
  • 【Docker管理工具】安装Docker磁盘使用仪表板Doku
  • 139. 单词拆分
  • 鸿蒙运动开发实战:打造专属运动视频播放器
  • 【2】Redis 缓存击穿原理和解决方案
  • 制作微PE U盘后电脑多出300M盘符(EFI分区)无法隐藏的解决过程
  • [VSCode] VSCode 设置 python 的编译器
  • 网站建设费用IP/深圳博惠seo
  • 统一用户管理系统/绍兴seo网站推广
  • 重庆一般建一个网站需要多少钱/网络营销推广流程
  • 怎么做二维码转到网站/seo搜索引擎优化实训
  • 网站建设新发展/百度商店应用市场
  • 上海小程序开发设计/萌新seo