深度解析:Nginx模块架构与工作机制的奥秘

ops/2024/11/29 20:20:29/

文章目录

  • 前言
    • Nginx是什么?
    • Ngnix特点:
  • 一、Nginx模块与工作原理
    • 1.Nginx的模块
      • 1.1 Nginx模块常规的HTTP请求和响应的流程图:
      • 1.2 Nginx的模块从结构上分为如下三类:
      • 1.3 Nginx的模块从功能上分为如下三类:
    • 2.Nginx的进程模型
      • 2.1 Nginx进程结构
      • 2.2 nginx进程管理
    • 3.多进程I/O模型
      • 3.1 nginx的多进程模型
      • 3.2 nginx支持的事件模型
  • 二、Nginx的适用场景
    • 2.1 HTTP服务器
    • 2.2 反向代理/负载均衡
    • 2.3 虚拟主机
    • 2.4 Nginx三大功能总结
  • 三、nginx和其他web服务的对比
    • 3.1 nginx对比httpd
    • 3.2 Nginx对比HProxy 、LVS

前言

Nginx是什么?

Nginx是由俄罗斯的程序设计师伊戈尔·西索夫(Igor Sysoev)所开发,一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。
官方测试nginx 能够支支撑 5 万并发链接,并且 cpu、内存等资源消耗却非常低,运行非常稳定其特点是占有内存少,并发能力强。
事实上nginx的并发能力在同类型的网页服务器中表现较好,国内使用Nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

Ngnix特点:

  1. 高并发:单机支持10万以上的并发连接;
  2. 高性能:低内存消耗:一般1万个非活跃的 HTTP Keep-Alive 连接在 Nginx 中仅消耗2.5MB内存;
  3. 高可靠性:可以在服务器上持续不间断运行数年;
  4. 高拓展性:主要体现在它的模块化设计,模块化设计非常的稳定使得nginx的第三方模块生态圈非常的丰富,丰富的生态圈为我们nginx丰富的功能提供了保证;
  5. 热部署:master 管理进程与 worker工作进程的分离设计,使得 Nginx 能够支持热部署;
  6. 开源协议:使用 BSD 许可协议,免费使用,且可修改源码。

一、Nginx模块与工作原理

1.Nginx的模块

1.1 Nginx模块常规的HTTP请求和响应的流程图:

在这里插入图片描述

1.2 Nginx的模块从结构上分为如下三类:

核心模块:HTTP模块、EVENT模块和MAIL模块
基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块,
第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。
用户可根据自己的需要开发的模块都属于第三方模块。

1.3 Nginx的模块从功能上分为如下三类:

Handlers(处理器模块) 此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。
Filters (过滤器模块) 此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。
Proxies (代理类模块) 此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。

2.Nginx的进程模型

2.1 Nginx进程结构

在这里插入图片描述

nginx_29">2.2 nginx进程管理

在这里插入图片描述
2.2.1 Master进程
核心功能: 管理进程
master进程主要用来管理worker进程,具体包括如下4个主要功能:

  1. 接收来自外界的信号。
  2. 向各worker进程发送信号。
  3. 监控woker进程的运行状态。
  4. 当woker进程退出后(异常情况下),会自动重新启动新的woker进程。

用户交互接口:master进程充当整个进程组与用户的交互接口,同时对进程进行监护。它不需要处理网络事件,不负责业务的执行,只会通过管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。

重启work进程:我们要控制nginx,只需要通过kill向master进程发送信号就行了。比如kill -HUP pid,则是告诉nginx,从容地重启nginx,我们一般用这个信号来重启nginx,或重新加载配置,因为是从容地重启,因此服务是不中断的。

master进程在接收到HUP信号后是怎么做的呢?

  1. 首先master进程在接到信号后,会先重新加载配置文件,然后再启动新的worker进程,并向所有老的worker进程发送信号,告诉他们可以光荣退休了。

  2. 新的worker在启动后,就开始接收新的请求,而老的worker在收到来自master的信号后,就不再接收新的请求,并且在当前进程中的所有未处理完的请求处理完成后,再退出。

直接给master进程发送信号,这是比较传统的操作方式,nginx在0.8版本之后,引入了一系列命令行参数,来方便我们管理。比如,./nginx -s reload,就是来重启nginx,./nginx -s stop,就是来停止nginx的运行。如何做到的呢?我们还是拿reload来说,我们看到,执行命令时,我们是启动一个新的nginx进程,而新的nginx进程在解析到reload参数后,就知道我们的目的是控制nginx来重新加载配置文件了,它会向master进程发送信号,然后接下来的动作,就和我们直接向master进程发送信号一样了。

2.2.2 worker进程
核心功能:处理请求
基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。

worker进程之间是平等的,每个进程,处理请求的机会也是一样的。当我们提供80端口的http服务时,一个连接请求过来,每个进程都有可能处理这个连接,怎么做到的呢?

Nginx采用异步非阻塞的方式来处理网络事件,类似于Libevent,具体过程如下:

  1. 接收请求:首先,每个worker进程都是从master进程fork过来,在master进程建立好需要listen的socket(listenfd)之后,然后再fork出多个worker进程。所有worker进程的listenfd会在新连接到来时变得可读,每个work进程都可以去accept这个socket(listenfd)。当一个client连接到来时,所有accept的work进程都会受到通知,但只有一个进程可以accept成功,其它的则会accept失败。为保证只有一个进程处理该连接,Nginx提供了一把共享锁accept_mutex来保证同一时刻只有一个work进程在accept连接。所有worker进程在注册listenfd读事件前抢accept_mutex,抢到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该连接。
  2. 处理请求:当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。
    我们可以看到,一个请求,完全由worker进程来处理,而且只在一个worker进程中处理。worker进程之间是平等的,每个进程,处理请求的机会也是一样的。

3.多进程I/O模型

nginx_63">3.1 nginx的多进程模型

优势:
首先,对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。

其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快启动新的worker进程。当然,worker进程的异常退出,肯定是程序有bug了,异常退出,会导致当前worker上的所有请求失败,不过不会影响到所有请求,所以降低了风险。

虽然nginx采用多worker的方式来处理请求,每个worker里面只有一个主线程,那能够处理的并发数很有限啊,多少个worker就能处理多少个并发,何来高并发呢?非也,这就是nginx的高明之处,nginx采用了异步非阻塞的方式来处理请求,也就是说,nginx是可以同时处理成千上万个请求的。一个worker进程可以同时处理的请求数只受限于内存大小,而且在架构设计上,不同的worker进程之间处理并发请求时几乎没有同步锁的限制,worker进程通常不会进入睡眠状态,因此,当Nginx上的进程数与CPU核心数相等时(最好每一个worker进程都绑定特定的CPU核心),进程间切换的代价是最小的。

而apache的常用工作方式(apache也有异步非阻塞版本,但因其与自带某些模块冲突,所以不常用),每个进程在一个时刻只处理一个请求,因此,当并发数上到几千时,就同时有几千的进程在处理请求了。这对操作系统来说,是个不小的挑战,进程带来的内存占用非常大,进程的上下文切换带来的cpu开销很大,自然性能就上不去了,而这些开销完全是没有意义的。

在这里插入图片描述

nginx_74">3.2 nginx支持的事件模型

Nginx支持如下处理连接的方法(I/O复用方法),这些方法可以通过use指令指定。

select– 标准方法 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-select_module 和 –without-select_module 来启用或禁用这个模块。

poll– 标准方法 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-poll_module 和 –without-poll_module 来启用或禁用这个模块。
3.2.3 kqueue– 高效的方法,使用于 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。

epoll – 高效的方法,使用于Linux内核2.6版本及以后的系统。在某些发行版本中,如SuSE 8.2, 有让2.4版本的内核支持epoll的补丁。

rtsig – 可执行的实时信号,使用于Linux内核版本2.2.19以后的系统。默认情况下整个系统中不能出现大于1024个POSIX实时(排队)信号。这种情况 对于高负载的服务器来说是低效的;所以有必要通过调节内核参数 /proc/sys/kernel/rtsig-max 来增加队列的大小。可是从Linux内核版本2.6.6-mm2开始, 这个参数就不再使用了,并且对于每个进程有一个独立的信号队列,这个队列的大小可以用 RLIMIT_SIGPENDING 参数调节。当这个队列过于拥塞,nginx就放弃它并且开始使用 poll 方法来处理连接直到恢复正常。
/dev/poll – 高效的方法,使用于 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+.
3.2.6 eventport – 高效的方法,使用于 Solaris 10. 为了防止出现内核崩溃的问题, 有必要安装这个 安全补丁。

在linux下面,只有epoll是高效的方法

二、Nginx的适用场景

2.1 HTTP服务器

Nginx作为HTTP服务器:是指在web项目开发时,总是将项目部署在tomcat jetty等应用服务器上,而服务端所需要的资源,文本数据和静态资源路径自然存放在数据库中,而静态资源实体(如图片、音视频等)既不能放在数据库中,又不能放在应用服务器的相关目录下,这个时候我们需要一种用来存放项目所需静态资源的服务器(只要在数据库的字段中存储好静态资源的路径即可),这就是http服务器——Nginx。
通常我们使用nginx处理静态资源请求,例如 图片、css、js、html等请求,动态请求交由后端服务(java程序,php程序,python程序等)去处理。这种方式也可称为动静分离。
静态请求和动态请求最直接的区别是是否连接数据库进行数据交互。

一个网页的js请求如下图所示:
在这里插入图片描述
配置Nginx——修改Nginx安装目录nginx.conf

server {listen       81; # 监听的端口server_name  localhost; # 域名或IPlocation / {      # 访问路径配置root   /var/www/html; # 根目录index  index.html index.htm; # 默认首页}error_page   500 502 503 504  /50x.html;      # 错误页面location = /50x.html {root   /var/www/errpage;}
} 

现在对这段代码解释,实际上,对于Nginx做服务器,和其他服务器一样,只要搞清“ ip:port、页面、后台目录”三个东西:
指定ip:port是localhost:81,我们直接在Linux计算机的浏览器上输入localhost:81,显示的是index.html/index.htm界面,对应后台目录是Nginx安装目录/index目录(如usr/local/nginx/index);我们直接在Linux计算机的浏览器上输入localhost:81/50x.html,对应后台目录是Nginx安装目录/html目录(如usr/local/nginx/html).
关于匹配关系,上面的配置中/表示可以匹配所有,/50x.html表示可以匹配50x.html,优先级关系是优先匹配长的,如localhost:81/50x.html同时满足/和/50x.html,由于优先匹配长的,所以要导向到html目录。如localhost:81/xxx.html仅满足于/,所以导向到index目录。
关于页面优先关系, index、index.html、index.htm;优先关系是从左到右,有index.html就显示index.html,没有就显示index.htm。

对于上面的理解如下图:
在这里插入图片描述

2.2 反向代理/负载均衡

Nginx反向代理:Nginx作为服务端代理,代表实际应用服务器与客户端交流,将网络请求分发给后台实际服务器。
Nginx负载均衡:Nginx作为服务端代理,根据weight权重将网络请求分发给后台实际服务器。
负载均衡和反向代理的关系:负载均衡是通过反向代理来实现的,负载均衡=反向代理+weight权重。

2.2.1 正向代理与反向代理
正向代理:是指客户端的代理,代表客户端向服务端发出网络请求,如图:
在这里插入图片描述
反向代理:是指服务端的代理,代表服务端向客户端发出响应结果,如图:
在这里插入图片描述
正向代理+反向代理,由客户端代理服务器代表Client客户机向服务端发出网络请求,由服务端代理服务器代表Server服务机向客户端发出响应结果。如图:
在这里插入图片描述
最简单的理解,正向代理和反向代理这个知识是计算机网络中的一个知识,由于当前使用的http网络请求时基于请求-响应模式,服务端开启后被动等待(websocket协议服务端也可以发送消息给客户端),由客户端主动发起网络请求(get请求、post请求),服务端提供结果响应,然后客户端再一次主动发起网络请求,服务端再一次提供结果响应

客户端局域网LAN1中的代理服务器代表客户端主机,我们称之为正向代理,正向代理隐藏了客户端,其存在的意义在于 客户端无法直接访问到服务端,但是 代理服务器可以访问到服务端,所以客户端通过代理服务器来访问到服务端。
2.2.2 Nginx实现反向代理
Nginx是如何实现反向代理的,我们一步步来分析。两个Tomcat服务通过Nginx反向代理,本例子使用三台虚拟机进行测试。
Nginx服务器:192.168.1.2
tomcat1服务器:192.168.1.100
tomcat2服务器:192.168.1.101

客户端访问流程如下:
在这里插入图片描述
这里的配置是基于域名实现的反向代理。
配置一个代理即tomcat1服务器

upstream tomcat_server1 {server 192.168.1.100:8080;}

配置一个代理即tomcat2服务器

upstream tomcat_server2 {server 192.168.1.101:8080;}

配置一个虚拟主机

 server {listen 80;server_name aaa.com;location / {#域名aaa.com的请求全部转发到tomcat_server1即tomcat1服务上proxy_pass http://tomcat_server1;#欢迎页面,按照从左到右的顺序查找页面index index.jsp index.html index.htm;}}
server {listen 80;server_name bbb.com;location / {#域名bbb.com的请求全部转发到tomcat_server2即tomcat2服务上proxy_pass http://tomcat_server2;index index.jsp index.html index.htm;}
}

2.2.3 nginx的负载均衡算法
对于负载均衡,它的最重要的 upstream 参数,还有就是nginx的默认的负载均衡算法和常用的负载均衡算法。
wrr:英文全称weighted round-robin,就是权重(就是上面的weight)轮询,这是默认负载均衡方式.
ip_hash:IP的哈希结果固定选择一个真实服务器,每个请求只访问tomcat,解决跨节点session共享问题,分布式登录的时候用到。
leas_conn:该负载均衡方案同时考虑连接数和权重两个因素,连接数越小且权重越大,则优先,如果上一次刚刚分配,本次不分配。

2.2.4 同源策略
所谓同源,是否同源由URL决定,URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。
同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略禁止这种跨域请求。后端分离已经是web应用最常见的架构。但由于浏览器的同源策略导致web应用访问不同域的资源不得不面临跨域访问问题。
配置方法:
add_header Access-Control-Allow-Origin; //允许所有域名跨域访问代理地址,表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求
add_header Access-Control-Allow-Headers XXX XXX XXX; 表明服务器允许请求中携带字段
add_header Access-Control-Allow-Methods; //跨域请求访问请求方式,
在这里插入图片描述

2.3 虚拟主机

2.3.1 虚机主机简介
Nginx虚拟主机:Nginx部署在一个物理服务器上,却通过IP、端口、域名对外实现多个访问入口,让客户端以为是多个服务器,这就是虚拟主机。
虚拟主机技术,使一个IP,通过port可以对应多个域名。
虚拟主机和负载均衡的区别又是什么?
Nginx做虚拟主机,将一个服务器当做多个服务器用,通过文件目录来虚拟服务器(主机),虚拟主机指的是Nginx自己作为服务器存储文件;
Nginx做负载均衡,Nginx作为服务端代理服务器,将网络请求分发到具体的应用服务器(Tomcat或Jetty),根据不同的应用服务器(Tomcat Jetty)的性能,设置weight权重,Nginx本身不作为服务器存储文件。

2.3.2 在nginx中的配置格式

 ......
events {
.......
}
http{
.......
server{
.......
}
server{
.......
}} 

Nginx的/conf/nginx.conf配置中,每个server标签就是一个虚拟主机。 实际上,就是同一机器,用不同的目录虚拟成不同的访问入口。
其中,因IP不同形成的不同的访问入口称为“基于IP的虚拟主机”,因端口不同形成的不同的访问入口称为“基于端口的虚拟主机”,因域名不同形成的不同的访问入口称为“基于域名的虚拟主机”。

2.3.3 Nginx三种虚拟主机方式——基于IP的虚拟主机配置
客户端访问流程如下:
在这里插入图片描述
一台Nginx服务器绑定三个IP:192.168.1.2、192.168.1.3、192.168.1.4,访问不同的IP请求不同的html目录,即:访问http://192.168.1.2将访问“html2”目录下的html网页,访问http://192.168.1.3将访问“html3”目录下的html网页,访问http://192.168.1.4将访问“html4”目录下的html网页,如图:

#配置虚拟主机192.168.1.2
server {listen       80;server_name  192.168.1.2;location / {root   /usr/local/nginx/html2;index  index.html index.htm;}}} 
#配置虚拟主机192.168.1.3
server {listen       80;server_name  192.168.1.3;location / {root   /usr/local/nginx/html3;index  index.html index.htm;}}} 
#配置虚拟主机192.168.1.4
server {listen       80;server_name  192.168.1.4;location / {root   /usr/local/nginx/html4;index  index.html index.htm;}}} 

2.3.4 Nginx三种虚拟主机方式——基于端口的虚拟主机配置
客户端访流程问如下:
在这里插入图片描述
一个物理服务器,提供一个IP地址三个端口,分别是192.168.1.2:81、192.168.1.2:82、192.168.1.2:83,在外界客户端开来,好像有三个服务器,都可以独立网络请求,因为它们后台是不同的文件目录,分别是/usr/local/nginx/html2、/usr/local/nginx/html3和/usr/local/nginx/html4,不会产生任何数据文件干扰。

#配置虚拟主机端口81
server {listen       81;server_name  192.168.1.2;location / {root   /usr/local/nginx/html2;index  index.html index.htm;}}
#配置虚拟主机端口82
server {listen       82;server_name  192.168.1.2;location / {root   /usr/local/nginx/html3;index  index.html index.htm;}}#配置虚拟主机端口83
server {listen       83;server_name  192.168.1.2;location / {root   /usr/local/nginx/html3;index  index.html index.htm;}}

2.3.5 Nginx三种虚拟主机方式——基于域名的虚拟主机配置
客户端访流程问如下:
在这里插入图片描述
一个物理服务器,提供三个域名地址,分别是aaa.com、bbb.com和ccc.com,在外界客户端开来,好像有三个服务器,都可以独立网络请求,因为它们后台是不同的文件目录,/usr/local/nginx/html2、/usr/local/nginx/html3和/usr/local/nginx/html4,不会产生任何数据文件干扰。
客户端测试访问时候需要绑定本地hosts文件解析域名指向nginx服务器IP地址。

2.3.6 小结

  1. 对于基于IP的虚拟主机:由于IP地址本来就稀缺,一个物理服务器配两个IP是不合实际的(毕竟,一个IP比一个服务器贵),所以,基于IP的虚拟主机不常用到,了解即可;

  2. 对于基于端口的虚拟主机:端口倒是不稀缺0-65535(一共65536个,默认是80端口),但是想让用户在浏览器上输入端口是非常不切实际的,所以,基于IP的虚拟主机也不常用到,了解即可;

  3. 对于基于域名的虚拟主机:一个物理服务器/服务器群(一个IP)配置多个域名,是可行的,因为:
    (1) 成本低,域名平均价格比IP便宜的多;
    (2) 客户端可以容易的记得域名,然后在浏览器中输入域名。

2.4 Nginx三大功能总结

http服务器+虚拟主机+负载均衡
在这里插入图片描述

nginxweb_330">三、nginx和其他web服务的对比

nginxhttpd_331">3.1 nginx对比httpd

服务进程模型配置文件性能对比部署方面社区情况
Nginx异步、非阻塞事件驱动配置简洁轻量级支持高并发安装启动简单,支持热启动活跃
httpd进程模型稍复杂重量级不支持高并发安装启动简单,不支持热启动活跃

总结:
Nginx除了可以作为HTTP服务器使用,其强大的反向代理功能还被广泛地用作负载均衡前端服务器,逐渐取代了基于硬件的负载均衡器。在Nginx中可以配置若干个后端服务器,Nginx在收到HTTP请求之后按照一定规则(轮询,IP哈希,优先随机)等将请求转发给后端服务器,实现负载在多台服务器上的平均或加权分配。
同时作为负载均衡的前端还能缓存后端返回的数据,缓解后端服务器的压力。前端采用Nginx做负载均衡限制每个服务器的连接数,后端服务器运行Apache的模式也并不少见。

3.2 Nginx对比HProxy 、LVS

从Nginx、LVS和HProxy 3种负载均衡软件的优缺点、适用性和量级等角度进行详细的对比

项目NginxHAProxyLVS
简介高可用、负载均衡基于TCP和HTTP应用的代理,支持高并发,多集群反向代理高性能http和反向代理服务器、支持高并发、经量级Web,低系统资源消耗Linux虚拟机、VS/DR VS/TUN,VS/NAT,三种模式负载均衡
优点1、正则规则更为强大和灵活
2、Nginx对网络稳定性的依赖非常小
3、可以承担高负载且稳定
4、Nginx可以通过端口检测到服务器内部的故障
1、抗负载能力强、负载均衡速度快
2、支持Session的保持,Cookie的引导,同时支持通过获取指定的url来检测后端服务器的状态
3、HAProxy支持TCP协议的负载均衡转发
1、抗负载能力强、工作在四层,只负责分发作用,
2、配置简单
3、无流量产生,只负责分发请求
4、适应范围广
缺点1、Nginx仅能支持http、https和Email协议
2、对后端服务器的健康检查,只支持通过端口来检测,不支持通过url来检测
1、不支持POP/SMTP、SPDY、协议,不支持HTTP cache功能
2、重载配置的功能需要重启进程
3、多进程模式支持不够好
1、不支持正规表达式,不能做动静分离
2、如果是网站应用比较庞大,LVS/DR+Keepalived相比前两者实施较为复杂
四层支持支持支持
七层支持支持不支持
支持算法支持轮循
带权轮循
IP哈希算法
支持轮循
带权轮循
原地址保持
RI请求URL rdp-cookie
支持轮循
带权轮循
最小连接数
权重最小连接

http://www.ppmy.cn/ops/137733.html

相关文章

Django+Nginx+uwsgi网站Channels+redis+daphne多人在线聊天实现粘贴上传图片

在DjangoNginxuwsgi网站Channelsredisdaphne多人在线的基础上(详见DjangoNginxuwsgi网站使用Channelsredisdaphne实现简单的多人在线聊天及消息存储功能-CSDN博客),实现在输入框粘贴或打开本地图片,上传到网站后返回图片路径&…

【H2O2|全栈】Node.js(1)

目录 前言 开篇语 准备工作 ES6导入导出 导入 有名导出 匿名导出 Node概念 Node导入导出 导入 有名导出 匿名导出 Node常用模块 path模块 和路径有关的全局变量 常见方法 导入方法 fs模块 常见方法 导入方法 结束语 前言 开篇语 本系列博客主要分享Java…

AI在线免费视频工具4:AI视频编辑ai-video-composer

1、ai-video-composer 使用自然语言从您的资产组成新的视频。添加视频、图像和音频资源,让 Qwen 2.5-Coder 为您生成一个新的视频(使用 FFMPEG) https://huggingface.co/spaces/huggingface-projects/ai-video-composer

【C/C++】深入解析 Stack 与 Queue 数据结构(详解):实现原理、应用场景与性能优化

文章目录 引言栈(Stack)数据结构详解1. 栈的基本概念2. 栈的实现原理3. C中的栈实现4. 栈的应用场景5. 栈的性能分析6. 实战示例:括号匹配 队列(Queue)数据结构详解1. 队列的基本概念2. 队列的实现原理3. C中的队列实现…

Rust vtable(Rust虚表、Rust虚函数表)动态绑定、Rust多态调用、通过类型引用创建trait对象(自动实例化)

文章目录 Rust vtable原理深度解析1. 什么是 vtable?1.1 Trait 对象和 vtableTrait对象指针结构- 一个指向数据的指针(指向具体类型实例的数据)- 一个指向 vtable 的指针,vtable 存储了该类型所有 trait 方法的函数指针 示例&…

架构第十一章:zabbix

监控体系 1.监控知识概述 (1)对系统不间断的实时监控 (2)实时反馈系统和服务状态 (3)保证系统和服务可靠、安全 (4)保证业务持续稳定运行 实时 反馈 可靠 安全 2.怎么进行监控&…

跨平台应用开发框架(1)----Qt(组件篇)

目录 1.Qt 1.Qt 的主要特点 2.Qt的使用场景 3.Qt的版本 2.QtSDK 1.Qt SDK 的组成部分 2.安装 Qt SDK 3.Qt SDK 的优势 3.Qt初识 1.快速上手 widget.cpp mian.cpp widget.h Helloworld.pro 2.对象树 3.坐标系 4.信号和槽 1. 信号和槽的基本概念 2. 信号和槽的…

[蓝桥杯 2021 省 AB2] 小平方

题目描述 小蓝发现,对于一个正整数 nn 和一个小于 nn 的正整数 vv,将 vv 平方后对 nn 取余可能小于 nn 的一半,也可能大于等于 nn 的一半。 请问,在 11 到 n−1n−1 中, 有多少个数平方后除以 nn 的余数小于 nn 的一半。 例如&…