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

news2025/1/12 19:52:38

文章目录

  • 前言
    • 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; # 域名或IP
    location / {      # 访问路径配置
        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
支持轮循
带权轮循
最小连接数
权重最小连接

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

抖音SEO矩阵系统:开发技术分享

市场环境剖析 短视频SEO矩阵系统是一种策略,旨在通过不同平台上的多个账号建立联系,整合同一品牌下的各平台粉丝流量。该系统通过遵循每个平台的规则和内容要求,输出企业和品牌形象,以矩阵形式增强粉丝基础并提升商业价值。抖音作…

面试经典 150 题:205,55

205. 同构字符串 【解题思路】 来自大佬Krahets 【参考代码】 class Solution { public:bool isIsomorphic(string s, string t) {map<char, char> Smap, Tmap;for(int i0; i<s.size(); i){char a s[i], b t[i];//map容器存在该字符&#xff0c;且不等于之前映射…

STM32 Keil5 attribute 关键字的用法

这篇文章记录一下STM32中attribute的用法。之前做项目的时候产品需要支持远程升级&#xff0c;要求版本只能向上迭代&#xff0c;不支持回退。当时想到的方案是把版本号放到bin文件的头部&#xff0c;设备端收到bin文件的首包部数据后判断是否满足升级要求&#xff0c;这里就可…

【Redis 缓存策略】更新、穿透、雪崩、击穿、布隆过滤

目录 缓存简单介绍 缓存更新策略 缓存更新需求 数据库缓存不一致解决方案 先操作缓存还是先操作数据库&#xff1f; 先删除缓存&#xff0c;再操作数据库 先操作数据库&#xff0c;再删除缓存 总结 删除缓存还是更新缓存&#xff1f; 保证缓存与数据库的操作的同时成功或失败 …

利用c语言详细介绍下栈的实现

数据结构中&#xff0c;栈是一种线性结构&#xff0c;数据元素遵循后进先出的原则。栈的一端为栈顶&#xff0c;一端为栈底或栈尾&#xff0c;数据只在栈顶端进行操作。新插入数据称为入栈或者压栈&#xff0c;删除数据叫做出栈或者退栈。 一、图文介绍 我们通过建立一个stack…

5.5 W5500 TCP服务端与客户端

文章目录 1、TCP介绍2、W5500简介2.1 关键函数socketlistensendgetSn_RX_RSRrecv自动心跳包检测getSn_SR 1、TCP介绍 TCP 服务端&#xff1a; 创建套接字[socket]&#xff1a;服务器首先创建一个套接字&#xff0c;这是网络通信的端点。绑定套接字[bind]&#xff1a;服务器将…

Transformer详解及衍生模型GPT|T5|LLaMa

简介 Transformer 是一种革命性的神经网络架构&#xff0c;首次出现在2017年的论文《Attention Is All You Need》中&#xff0c;由Google的研究团队提出。与传统的RNN和LSTM模型不同&#xff0c;Transformer完全依赖于自注意力&#xff08;Self-Attention&#xff09;机制来捕…

计算机网络基础全攻略:探秘网络构建块(1/10)

一、计算机网络基础概念 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路和通信设备连接起来&#xff0c;在网络操作系统&#xff0c;网络管理软件及网络通信协议的管理和协调下&#xff0c;实现资源共享和信息传递的计算机系统…

Android 应用测试的各种环境问题记录(Instrumentation测试)

报错记录 failed to configure packages targetSdkVersion&#xff08;未解决&#xff09; failed to configure com.demo.test.SettingsActivityTest.testOnCreate_withNullSavedInstanceState: Package targetSdkVersion34 > maxSdkVersion32 java.lang.IllegalArgumentE…

Python 爬虫从入门到(不)入狱学习笔记

爬虫的流程&#xff1a;从入门到入狱 1 获取网页内容1.1 发送 HTTP 请求1.2 Python 的 Requests 库1.2 实战&#xff1a;豆瓣电影 scrape_douban.py 2 解析网页内容2.1 HTML 网页结构2.2 Python 的 Beautiful Soup 库 3 存储或分析数据&#xff08;略&#xff09; 一般爬虫的基…

周志华深度森林deep forest(deep-forest)最新可安装教程,仅需在pycharm中完成,超简单安装教程

1、打开pycharm 没有pycharm的&#xff0c;在站内搜索安装教程即可。 2、点击“文件”“新建项目” 3、创建项目&#xff0c;Python版本中选择Python39。如果没有该版本&#xff0c;选择下面的Python 3.9下载并安装。 4、打开软件包&#xff0c;搜索“deep-forest”软件包&am…

用python将一个扫描pdf文件改成二值图片组成的pdf文件

使用墨水屏读书现在似乎越来越流行&#xff0c;这确实有一定的好处&#xff0c;例如基本不发热&#xff0c;电池续航时间超长&#xff0c;基本不能游戏所以有利于沉浸式阅读&#xff0c;还有不知道是不是真的有用的所谓防蓝光伤害。但是&#xff0c;如果阅读的书籍是扫描图片组…

前端---HTML(一)

HTML_网络的三大基石和html普通文本标签 1.我们要访问网络&#xff0c;需不需要知道&#xff0c;网络上的东西在哪&#xff1f; 为什么我们写&#xff0c;www.baidu.com就能找到百度了呢&#xff1f; 我一拼ping www.baidu.com 就拼到了ip地址&#xff1a; [119.75.218.70]…

电影风格城市夜景旅拍Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 电影风格城市夜景旅拍通过 Lightroom 调色&#xff0c;将城市夜晚的景色打造出如同电影画面般的质感和氛围。以独特的色彩和光影处理&#xff0c;展现出城市夜景的魅力与神秘。 预设信息 调色风格&#xff1a;电影风格预设适合类型&#xff1a;人像&#xff0c;街拍…

【多模态】Flamingo模型技术学习

Flamingo模型技术学习 前言Flamingo——支持上下文学习的多模态模型模型架构模型架构——Resampler模型架构——插入到LLM的cross-attention层 代码查看——masked cross-attentionnote 前言 最近多模态模型特别火&#xff0c;从头开始学习&#xff01;在前面写的几篇里面学习了…

C 语言学习-06【指针】

1、目标单元与简介存取 直接访问和间接访问 #include <stdio.h>int main(void) {int a 3, *p;p &a;printf("a %d, *p %d\n", a, *p);*p 10;printf("a %d, *p %d\n", a, *p);printf("Enter a: ");scanf("%d", &a)…

ctfshow单身杯2024wp

文章目录 ctfshow单身杯2024wp签到好玩的PHPezzz_sstiez_inject ctfshow单身杯2024wp 签到好玩的PHP 考点&#xff1a;序列化反序列化 <?phperror_reporting(0);highlight_file(__FILE__);class ctfshow {private $d ;private $s ;private $b ;private $ctf ;public …

超高流量多级缓存架构设计!

文章内容已经收录在《面试进阶之路》&#xff0c;从原理出发&#xff0c;直击面试难点&#xff0c;实现更高维度的降维打击&#xff01; 文章目录 电商-多级缓存架构设计多级缓存架构介绍多级缓存请求流程负载均衡算法的选择轮询负载均衡一致性哈希负载均衡算法选择 应用层 Ngi…

【Mybatis】@Param注解 resultMap手动映射

文章目录 一、映射文件参数二、查询映射2-1 一对一2-2 一对多2-3 总结 一、映射文件参数 Param 注解官方文档解释 1、单个参数&#xff08;对象&#xff09;不使用注解 public int save(User user);<!-- 添加用户 --> <insert id"save" parameterType&quo…

Unreal从入门到精通之如何绘制用于VR的3DUI交互的手柄射线

文章目录 前言实现方式MenuLaser实现步骤1.Laser和Cursor2.移植函数3.启动逻辑4.检测射线和UI的碰撞5.激活手柄射线6.更新手柄射线位置7.隐藏手柄射线8.添加手柄的Trigger监听完整节点如下:效果图前言 之前我写过一篇文章《Unreal5从入门到精通之如何在VR中使用3DUI》,其中讲…