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

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

文章目录

  • 前言
    • 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进程结构

在这里插入图片描述

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模型

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开销很大,自然性能就上不去了,而这些开销完全是没有意义的。

在这里插入图片描述

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服务器+虚拟主机+负载均衡
在这里插入图片描述

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

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
支持轮循
带权轮循
最小连接数
权重最小连接

相关文章:

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

文章目录 前言Nginx是什么?Ngnix特点: 一、Nginx模块与工作原理1.Nginx的模块1.1 Nginx模块常规的HTTP请求和响应的流程图:1.2 Nginx的模块从结构上分为如下三类:1.3 Nginx的模块从功能上分为如下三类: 2.Nginx的进程模型2.1 Nginx进程结构2.2 nginx进程…...

【git】commit之后,想撤销commit

一、已经commit,想要回退到上一步 保留代码 git reset --soft HEAD^回退到具体的哪一步 HEAD^的意思是上一个版本,也可以写成HEAD~1如果你进行了2次commit,想都撤回,可以使用HEAD~2二、git reflog 查看 sha值 git reflog 回到…...

实现在两台宿主机下的docker container 中实现多机器通讯

基于我的实验背景 上位机:ubuntu 20.04 (docker humble 22.04) 下位机:ubuntu 22.04(docker noetic 20.04) 目标:实现在上位机中的docker container 容器的22.04环境去成功远程访问 非同网段的下位机的20.04的contai…...

Python 网络爬虫操作指南

网络爬虫是自动化获取互联网上信息的一种工具。它广泛应用于数据采集、分析以及实现信息聚合等众多领域。本文将为你提供一个完整的Python网络爬虫操作指南,帮助你从零开始学习并实现简单的网络爬虫。我们将涵盖基本的爬虫概念、Python环境配置、常用库介绍。 上传…...

vue3 uniapp 扫普通链接或二维码打开小程序并获取携带参数

vue3 uniapp 扫普通链接或二维码打开小程序并获取携带参数 微信公众平台添加配置 微信公众平台 > 开发管理 > 开发设置 > 扫普通链接二维码打开小程序 配置链接规则需要下载校验文档给后端存入服务器中,保存配置的时候会校验一次,确定当前的配…...

高标准农田智慧农业系统建设方案

1 项目概述 1.1 建设背景 我国是农业大国,近30年来农田高产量主要依靠农药化肥的大量投入,大部分化肥和水资源没有被有效利用而随地弃置,导致大量养分损失并造成环境污染。我国农业生产仍然以传统生产模式为主,传统耕种只能凭经验施肥灌溉,不仅浪费大量的人力物力,也对环…...

【python图解】数据结构之字典和集合

【python图解】数据结构之字典和集合 在 Python 中,字典和集合是另外的两种重要数据结构,它们分别用于存储键值对和无序的唯一元素集合。下面我们将详细介绍字典和集合的定义、操作方法、使用场景及相关案例。 1. 字典(Dictionary&#xff0…...

vue 预览pdf 【@sunsetglow/vue-pdf-viewer】开箱即用,无需开发

sunsetglow/vue-pdf-viewer 开箱即用的pdf插件sunsetglow/vue-pdf-viewer, vue3 版本 无需多余开发,操作简单,支持大文件 pdf 滚动加载,缩放,左侧导航,下载,页码,打印,文本复制&…...

TCL嵌入式面试题及参考答案

USB2.0 和 USB3.0 的速度区别是什么? USB2.0 和 USB3.0 在速度上有显著的区别。USB2.0 理论上的最高传输速度为 480Mbps,也就是 60MB/s 左右。而 USB3.0 的理论传输速度则可达到 5Gbps,即约 625MB/s ,这比 USB2.0 快了很多倍。 在实际应用中,USB2.0 通常用于一些对速度要求…...

即时通讯服务器被ddos攻击了怎么办?

攻击即时通讯系统的主要手段 击键记录 目前盗取即时通讯工具帐号信息的最主要方法是通过特洛伊木马等恶意软件,例如QQ木马,这类程序能够盗取QQ密码信息,常见的能够盗取最新版本QQ密码的木马程序有十几种之多。几乎所有主要的QQ木马程序都采…...

RTC QoS方法十三.(ReedSolomonFEC简介)

一、FlexFEC恢复的困局 在使用FlexFEC进行冗余的时候,经验值需要冗余5倍的丢包率,才能有比较高的恢复率。 Flex FEC在2D数组异或时能获得比较高的恢复率,但是如上图所示,25个包发送10个FEC包,成本为10/2540%的冗余度。…...

嵌入式开发工程师面试题 - 2024/11/24

原文嵌入式开发工程师面试题 - 2024/11/24 转载请注明来源 1.若有以下定义语句double a[8],*pa;int i5;对数组元素错误的引用是? A *a B a[5] C *(p1) D p[8] 解析: 在 C 或 C 语言中&am…...

《Shader入门精要》透明效果

代码以及实例图可以看github :zaizai77/Shader-Learn: 实现一些书里讲到的shader 在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道(Alpha Channel)​。当开启透明混合后,当一个物体被渲染到屏幕上时&…...

一篇文章了解Linux

目录 一:命令 1 ls命令作用 2 目录切换命令(cd/pwd) (1)cd切换工作目录命令 3 相对路径、绝对路径和特殊路径 (1)相对路径和绝对路径的概念和写法 (2)几种特殊路径的表示符 (3)练习题: 4 创建目录命令&#x…...

创建字典时,键名不能是数字

4. 请问下面创建字典的 8 种方法中,哪几种是正确的。 >>> a {99:"吕布", 90:"关羽", 60:"刘备"}>>> b dict(99:"吕布", 90:"关羽", 60:"刘备")>>> c dict(99"吕布…...

架构-微服务-环境搭建

文章目录 前言一、案例准备1. 技术选型2. 模块设计3. 微服务调用 二、创建父工程三、创建基础模块四、创建用户微服务五、创建商品微服务六、创建订单微服务 前言 ‌微服务环境搭建‌ 使用的电商项目中的商品、订单、用户为案例进行讲解。 一、案例准备 1. 技术选型 maven&a…...

mysql根据日期查询没有的日期也要显示数据

先查询出日期数据(当前日期往前推12个月) select bb.datefrom (select num : num 1,date_format(adddate(date_sub(date_sub(curdate(),interval 12 month),interval 1 month),interval num month), %Y-%m) as datefrom mysql.help_topic,(select num : 0) as twhere addd…...

ArcGIS定义投影与投影的区别(数据和底图不套合的原因和解决办法)

今天介绍一下ArcGIS中定义投影与投影的区别。 给大家解惑一下为什么经常出现自己的数据无法和底图套合的情况。 一 目录 1、ArcGIS定义投影与投影的概念区别 2、ArcGIS定义正确的坐标系 3、ArcGIS动态投影实现套合 4、ArcGIS地理坐标系转投影坐标系(错误做法&am…...

SQL Server数据库日志(ldf文件)清理

随着系统运行时间的推移,数据库日志文件会变得越来越大,这时我们需要对日志文件进行备份或清理。 下面是日常运维中比较常用的日志清理SQL语句 --- 查询数据库log名称 USE testdb SELECT name, physical_name FROM sys.master_files WHERE database_id …...

ubuntu 安装proxychains

在Ubuntu上安装Proxychains,你可以按照以下步骤操作: 1、更新列表 sudo apt-update 2、安装Proxychains sudo apt-get install proxychains 3、安装完成后,你可以通过编辑/etc/proxychains.conf文件来配置代理规则 以下是一个简单的配置示例&…...

Maven学习笔记

Maven功能介绍 提供了一套标准化的项目结构提供了一套标准化的构建流程(编译、测试、打包、发布.....)提供了一套依赖管理机制 依赖管理其实就是管理你项目所依赖的第三方资源(jar包、插件...) ①Maven使用标准的坐标配置来管理…...

.net 支持跨平台(桌面)系列技术汇总

1. 首先微软老大哥的.net core 。 .NET Core 是微软开发的一个跨平台、高性能的开源框架,用于构建云和互联网连接的新型应用。 它允许开发者在 Windows、macOS 和 Linux 上使用喜爱的开发工具进行开发,并支持部署到云或本地环境。 .NET Core 是对 .NET …...

[Golang]传递一个切片(slice)和使用变参(...)语法传递多个参数之间的区别

在 Go 中,传递一个切片(slice)和使用变参(…)语法传递多个参数之间有一些关键区别。让我们详细讨论这两种方式之间的区别: 传递切片(Slice) 传递方式: 传递切片时&…...

【PGCCC】Postgresql BRIN 索引原理

前言 postgresql 提供了块级索引(简称 BRIN),主要适用于类似时序数据之类的,有着天然的顺序,而且都是添加写的场景。相比于 btree 索引,它的体积小得多,非常适用于大数据量的场景。 原理 pos…...

安全加固方案

交换机安全加固 查看是否关闭未使用的接口 25GE1/0/1、25GE1/0/47、25GE1/0/48需要使用,暂不关闭 system-view # interface Eth-Trunk99 shutdown quit interface Eth-Trunk100 shutdown quit interface Eth-Trunk110 shutdown quit interface 25GE1/…...

Adobe Illustrator 2024 安装教程与下载分享

介绍一下 下载直接看文章末尾 Adobe Illustrator 是一款由Adobe Systems开发的矢量图形编辑软件。它广泛应用于创建和编辑矢量图形、插图、徽标、图标、排版和广告等领域。以下是Adobe Illustrator的一些主要特点和功能: 矢量绘图:Illustrator使用矢量…...

WSL安装不同版本ubuntu(已有ubuntu20.04,再装ubuntu18.04)

参考: 如何在 WSL 中删除指定版本的 Ubuntu(以删除 Ubuntu 22.04 为例)_wsl卸载某个-CSDN博客 已有ubuntu20.04,现在再安装一个ubuntu18.04 直接参考下面我写的链接的第四步,前面的步骤都不需要再做了 Win11安装WSL…...

指针测试总结(一)(一维数组)

1.取一维数组的首地址 int main() {int arr[3] {5,8,1}; printf("%d\n",arr);printf("%d\n",&arr);printf("%d\n",&arr[0]);printf("%d\n",&arr0); }输出结果: 1096809108 1096809108 1096809108 1096809108…...

CentOS环境上离线安装python3及相关包

0. 准备操作系统及安装包 准备操作系统环境: 首先安装依赖包,安装相应的编译工具 [rootbigdatahost bin]# yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-d…...

Matlab 深度学习工具箱 案例学习与测试————求二阶微分方程

clc clear% 定义输入变量 x linspace(0,2,10000);% 定义网络的层参数 inputSize 1; layers [featureInputLayer(inputSize,Normalization"none")fullyConnectedLayer(10)sigmoidLayerfullyConnectedLayer(1)sigmoidLayer]; % 创建网络 net dlnetwork(layers);% 训…...

算法笔记:回溯算法

回溯法理论基础 「回溯是递归的副产品,只要有递归就会有回溯」,所以回溯法也经常和二叉树遍历,深度优先搜索混在一起,因为这两种方式都是用了递归。 回溯法就是暴力搜索,并不是什么高效的算法,最多再剪枝一…...

[工具分享] 根据Excel数据根据Word文档模板,批量创建生成Word文档并重命名,方便快速查找打印

前几天交楼的小姐姐要多份Word文档合同打印给客户,那么100份就需要修改100次 上面好多都是模板的制式文件,里面的部分数据都是要根据实际值来变动的, 那么有没有快速的方法来操作呢,还是只能一个个手动的改,又容易出…...

数据库的联合查询

数据库的联合查询 简介为什么要使⽤联合查询多表联合查询时MYSQL内部是如何进⾏计算的构造练习案例数据案例:⼀个完整的联合查询的过程 内连接语法⽰例 外连接语法 ⽰例⾃连接应⽤场景示例表连接练习 ⼦查询语法单⾏⼦查询多⾏⼦查询多列⼦查询在from⼦句中使⽤⼦查…...

DICOM图像深入解析:为何部分DR/CR图像默认显示为反色?

概述 在数字医学影像处理中,CR(Computed Radiography,计算机放射摄影)和DR(Digital Radiography,数字放射摄影)技术广泛应用于医疗影像获取与分析。然而,临床实践中常常遇到这样一个问题:部分CR/DR图像在默认打开时呈现为反色(即负片效果),需手动反色后才能正常阅片…...

C#基础上机练习题

21.计算500-800区间内素数的个数cn,并按所求素数的值从大到小的顺序排列,再计算其间隔加、减之和,即第1个素数-第2个素数第3个素数-第4个素数第5个素数……的值sum。请编写函数实现程序的要求,把结果cn和sum输出。 22.在三位整数…...

UE5 实现组合键触发事件的方法

因为工作原因。 需要用大括号{和}来触发事件 但是在蓝图中搜了一下,发现键盘事件里根本就没有{}这两个键。 花费了一下午,终于找到解决的方法了,也就是增强输入的弦操作 首先创建一个项目 纯蓝图或者C都可行 进入到内容浏览器的默认页面 …...

Linux麦克风录音实战

在 Linux 上使用麦克风进行录音可以通过多种方式实现,包括使用命令行工具、图形界面应用程序以及编程接口。下面我将介绍几种常见的方法,从简单的命令行工具到使用 PortAudio 库进行编程。 一. 使用arecord命令行工具 arecord 是 ALSA(Adva…...

Diving into the STM32 HAL-----Timers笔记

嵌入式设备会按时间执行某些活动。对于真正简单且不准确的延迟,繁忙的循环可以执行任务,但是使用 CPU 内核执行与时间相关的活动从来都不是一个聪明的解决方案。因此,所有微控制器都提供专用的硬件外设:定时器。定时器不仅是时基生…...

RPC学习

一、什么是 RPC RPC(Remote Procedure Call),即远程过程调用,是一种计算机通信协议,它允许运行在一台计算机上的程序调用另一台计算机上的子程序或函数,就好像调用本地程序中的函数一样,无需程序…...

STM32端口模拟编码器输入

文章目录 前言一、正交编码器是什么?二、使用步骤2.1开启时钟2.2配置编码器引脚 TIM3 CH1(PA6) CH2 (PA7)上拉输入2.3.初始化编码器时基2.4 初始化编码器输入2.5 配置编码器接口2.6 开启定时器2.7获取编码器数据 三、参考程序四、测试结果4.1测试方法4.2串口输出结果…...

深入理解 MyBatis 的缓存机制:一级缓存与二级缓存

MyBatis 是目前 Java 开发中常用的一种 ORM(对象关系映射)框架,它不仅简化了 SQL 语句的编写和管理,还提供了强大的缓存机制,用以提高数据库访问的性能。MyBatis 的缓存分为一级缓存和二级缓存,分别应用于不…...

做一个FabricJS.cc的中文文档网站——面向markdown编程

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,用爱发电&#…...

Elasticsearch在部署时,对Linux的设置有哪些优化方法?

大家好,我是锋哥。今天分享关于【Elasticsearch在部署时,对Linux的设置有哪些优化方法?】面试题。希望对大家有帮助; Elasticsearch在部署时,对Linux的设置有哪些优化方法? 1000道 互联网大厂Java工程师 精…...

ThingsBoard规则链节点:Azure IoT Hub 节点详解

目录 引言 1. Azure IoT Hub 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 数据传输 3.2 数据分析 3.3 设备管理 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台,提供了设备…...

SpringBoot线程池的使用

SpringBoot线程池的使用 在现代Web应用开发中,特别是在使用Spring Boot框架时,合理使用线程池可以显著提高应用的性能和响应速度。线程池不仅能够减少线程创建和销毁的开销,还能有效地控制并发任务的数量,避免因线程过多而导致的…...

ubuntu中使用ffmpeg和nginx推流rtmp视频

最近在测试ffmpeg推流rtmp视频,单独安装ffmpeg是无法完成推流的,需要一个流媒体服务器,常用nginx,可以直接在ubuntu虚拟机里面测试一下。 测试过程不涉及编译ffmpeg和nginx,仅使用基本功能: 1 安装ffmpeg …...

如何在CodeIgniter中添加或加载模型

在CodeIgniter框架中,模型(Model)是用于与数据库进行交互的重要组件。模型通常包含数据库查询、业务逻辑以及与数据库表相关的函数。以下是如何在CodeIgniter中添加或加载模型的步骤: 1. 创建模型文件 首先,你需要在…...

加菲工具 - 好用免费的在线工具集合

加菲工具 https://orcc.online AI 工具 加菲工具 集合了目前主流的,免费可用的ai工具 文档处理 加菲工具 pdf转word、office与pdf互转等等工具都有链接 图片图标 加菲工具 统计了好用免费的在线工具 编码解码 加菲工具 base64编码解码、url编码解码、md5计算…...

Centos 8, add repo

Centos repo前言 Centos 8更换在线阿里云创建一键更换repo 自动化脚本 华为Centos 源 , 阿里云Centos 源 华为epel 源 , 阿里云epel 源vim /centos8_repo.sh #!/bin/bash # -*- coding: utf-8 -*- # Author: make.han...

神经网络12-Time-Series Transformer (TST)模型

Time-Series Transformer (TST) 是一种基于 Transformer 架构的深度学习模型,专门用于时序数据的建模和预测。TST 是 Transformer 模型的一个变种,针对传统时序模型(如 RNN、LSTM)在处理长时间依赖、复杂数据关系时的限制而提出的…...