Nginx: 配置项之http模块connection和request的用法以及limit_conn和limit_req模块

news2024/11/15 18:41:29

connection和request

  • connection 就是一个连接, TCP连接
    • 客户端和服务器想要进行通信的话,有很多种方式
    • 比如说, TCP的形式或者是UDP形式的
    • 通常很多应用都是建立在这个TCP之上的
    • 所以, 客户端和服务器通信,使用了TCP协议的话,必然涉及建立TCP连接
    • 也就是通常所说的三次握手
  • TCP协议它是一个有状态的一个协议,它是有一个完整的状态机的
    • 通过那个状态位的不同变化来判断分析的
  • 如果先建立了这个TCP连接之后,接下来就可以发送应用层的数据信息
    • 比如 HTTP 请求,这就是一个 request
    • 这个 request 它是必须建立在 我们的connection之上的
    • HTTP协议, 它又是一个无状态的协议
  • 所以说connection和request他们连个基本的关系是
    • 首先要建立 connection 之后才需要去发送 request
    • 这个 connection 和 request 之间对应的关系并非一对一的
    • 在打开长连接的过程中,可能在一个 connection 中会发送很多的HTTP的requests请求
  • 请求示意图
  • 我的客户端想要跟服务器通信去获取服务器上某一些网站的信息
  • 就简单以浏览网页这种形式来说,送一个请求
  • 也就是在浏览器中去刷新一个URL, 它会发生哪些事呢?
    • 第一个肯定需要去建立一个connection,也就发起一个TCP的一个连接
    • 客户端首先会给服务器发送一个带有SYN的一个数据包
    • 服务器收到这个数据包之后就知道客户端是想发起一个TCP连接
    • 它会回应客户端发送的SYN包,并且也发送一个ACK同时它也有一个SYN的标志
    • 客户端收到以后给服务器发送一个ACK
    • 至此,三次握手就完成了,建立了一个TCP连接
    • 那TCP连建立完成之后,这个客户端就可以去发送具体的一个HTTP请求
  • 比如我们在 www.baidu.com 中访问
    • 这个时候, 请求的是提供的web服务器上的某一个或多个文件
    • 默认是80端口,对应我们服务器上的一个外部应用
    • 这个时候网站首页中可能包含了很多信息,会发起多个 request 请求
    • 这个时候在一个TCP连接之中,可能会对应多个 request 的请求
    • 开启了这个长连接的情形下,它为了加速效率
    • 会允许你一个connection连接中发送很多个 request
    • 同时服务器回应很多 response 报文
  • request请求都是要建立在connection之上

limit_conn 模块


1 )基本功能

  • 用于限制客户端并发连接数
  • 默认编译进 nginx, 通过 --without-http_limit_conn_module 禁用
  • 使用共享内存,对所有worker子进程生效
    • 如果需要对客户端的并发连接进行限制的话
    • 对于一个特定的客户端来说,他第一次发起一个HTTP的请求
    • 这个请求被某一个worker子进程所处理
    • 假如, 他下一次再发起的这个HTTP请求, 有可能受会到另外一个 worker 子进程
    • 因此, 想要对所有客户端连接进行一个统一的控制
    • 不同的worker子进程之间必须知道某一个客户端发送过来的连接有几个
    • 必须要有一块共享内存, 在共享内存中,我们需要去维护这样一个数据结构
    • 这个数据结构中能够保存特定客户端所发送过来的已经建立的这个连接数
    • 因此,即使某一次请求被录入到不同的work子进程之后
    • 我们的worker子进程也能够去这样一个共享内存中去取出这块数据结构中
    • 已经存储的客户端所建立的连接数,从而对客户端的一个连接数进行限制

2 )常用指令

  • limit_conn_zone, 其实这个zone指令就是用来定义共享内存的
  • limit_conn_status, 主要是用来定义限制行为发生的时候,返回给客户端的一个状态
  • limit_conn_log_level,限制行为发生的时在日志中所记录的这个日志等级
  • limit_con,这个才是真正去定义客户端的限制的一个并发连接数

那我们来逐个的看每一个指令,它的一个具体用法

2.1 ) limit_conn_zone

  • 语法: limit_conn_zone key zone=name:size
    • 这是一个固定写法,后面空格会跟一个key
    • 这个 key 是一个唯一性的标识,用来标识客户端的唯一性的
    • 比如说, 可以根据客户端的一个IP来做客户端的唯一性标识
    • 通常情况下,我们会使用一个变量叫一个 $remote_addr 这样一个变量
    • 这个是在Nginx 中所内置的一个变量
    • 也就是说,当我们部署好Nginx, 你的客户端发送一个请求过来以后
    • 在请求中会带上这个 $remote_addr, Nginx会将客户端的IP赋值给 $remote_addr
    • 因此用来识别客户端的一个键,可以根据客户端唯一性标识这个IP来对客户端进行限制
    • 当然还有很多一些其他的限制,比如说我们可以根据客户端建立的时候
    • 有很多token信息来进行一个唯一的token信息来进行一个限速
    • 当然不同的形式,需要根据自己的应用场景去定义
    • 在实际的应用场景,通常用的最多的都是这个 $remote_addr
    • 那在很多情形下,如果存在反向代理的情形,可能通过反向代理中
    • 加一个指定的 real_ip 的指令,获取到 real_ip 对 real_ip 进行限速
    • 总之,key就是用来定义所限速客户端那个唯一性标识
    • 之后 zone=name:size 是一个固定写法,这个name是任意名称都行
    • 后面跟一个冒号 和 size,这个size是定义共享内存的空间,以M为单位
  • 默认值: 无
  • 上下文: http (只能定义在 http 段中,即在http的全局配置信息中定义)
  • 示例: limit_conn_zone $binary_remote_addr zone=addr:10m
    • $binary_remote_addr 和 $remote_addr 都是标记客户端ip信息的
    • $binary_remote_addr 好处是只使用4个字节的空间,提升处理效率
    • $remote_addr 会占用 7 - 15 个字节
    • 这里 10m 一般足够使用

2.2 )limit_conn_status

  • 语法:limit_conn_status code
    • code 是状态码,比如:201, 302,404,…
  • 默认值: limit_conn_status 503;
  • 上下文:http、server、location

2.3 ) limit_conn_log_level

  • 语法: limit_conn_log_level info | notice | warn | error;
    • 比如说当我们这个限制行为发生的时候,根据客户的IP来限速
    • 我们把它限速为一个并发连接,超过一个并发连接的时候, 不处理,返回503状态码
    • 同样,在对应的 log 中进行记录
  • 默认值:limit_conn_log_level error;
  • 上下文:http、server、location

2.4 ) limit_conn

  • 语法:limit_conn zone number;
    • 前面的 limit_conn_zone 已经定义了某一个名称的一个共享内存,指定了大小空间
    • 这个时候可以直接使用, 这个 zone 其实是要引用前面定义的addr的名称的那个定义
    • 之后number就是限速多少
  • 默认值: 无
  • 上下文:http、server、location

3 ) 配置示例

  • 我们想要根据 $binary_remote_addr 也就是客户端的IP去限速
  • 并且把每一个客户端IP限速为2,只要超过2个链接,就给它限制住
  • 超过2个链接,就直接给他返回 503

示例

http {
	limit_conn_zone   $binary_remote_addr zone=limit_addr:10m # 这个只能在 http 段中
	
	server {
		listen      	           80;
		server_name     localhost;
		
		location / {
			root     html;
			index   index.html  index.htm;
			
			limit_status 503;
			limit_conn_log_level warn;
			limit_conn limit_addr 2;
			limit_rate  50;
		}
	}
}

重启

  • $ /opt/nginx/sbin/nginx -s reload
  • 开启 多个 curl 终端 进行 curl localhost,前2个窗口有结果,后面就会 503

limit_req 模块


1 ) 基本功能

  • 用于限制客户端处理请求的平均速率

  • 默认编译进 nginx, 通过 --without-http_limit_req_module 禁用

  • 使用共享内存, 对所有 woker 子进程生效

  • 限流算法: leaky_bucket

上图是算法思想思路

  • 它所使用的一个限流算法是一个 leaky_bucket 的算法,limit_req 模块本身类似于一个限流的模块
  • 有一些很经典的一些限流算法:比如说像 leaky_bucket 算法,计算器算法(固定窗口),令排桶算法等等
  • 这些都是在高并发系统中经常使用的一个限流的一个算法
  • 在 Bursty data 图表中,横坐标是一个时间轴,纵坐标是一个流量的轴
  • 假如说,随着时间的推移,流量是不均匀的,前两秒钟,它的流量达到了 12 Mbps
  • 之后第2秒到第7秒中间没有任何流量, 之后第7秒到第10秒之间, 又平均是2 Mbps的一个流量
  • 在这十秒钟,它一共有 12 * 2 + 2 * 3 = 30M 的流量,但是分布很不均匀
  • 前2秒突发比较大,2 - 7 s 没有流量, 7 - 10 s 流量较少
  • 这个 lkeybucket 算法就是实现了将流量削平来进行限流的动作
  • 它把这些突发的流量,包括中间没有的流量给强行的限制到某一个速率上来进行处理
  • 也就是 30 / 10 = 3Mbps 的速率,它类似于一个水龙头,使用这样一个漏斗来进行处理
  • 从水龙头滴出来的水类似于我们的流量,水龙头的开关大小都用来模拟流量的一个大小
  • 对于在这漏斗下面出水的一个速率,它是一个恒定的
  • 这个漏桶算法最重要的功能就是实现一个削平流量
  • 将突发的流量和不均匀的流量来进行一个强行恒定到某一个数据上来进行处理
  • 上面有一个 Bursty flow, Bursty的参数类似于用来定义这样一个桶的大小
  • 现在以 3Mbps 的速率来消费这些流量,但是这个流量峰值可能远远超过了3M这样一个流量
  • 只要我这个桶没有满的情形下,这个服务是不会被拒绝的
  • 只有说这个漏斗中的水完全满了之后,流量完全超过了这个桶的大小之后的才会被拒绝

2 )常见指令

2.1 limit_req_zone

  • 用于定义共享内存
  • 语法:limit_req_zone key zone=name:size rate=rate
  • 默认值: 无
  • 上下文:http
  • 示例: limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m
    • rate=2r/m 每分钟2个请求
    • 它会平均处理,比如30s之后再处理第二个

2.2 limit_req_status

  • 语法:limit_req_status code;
  • 默认值:limit_req_status 503;
  • 上下文: http、server、location

2.3 limit_req_log_level

  • 语法: limit_req_log_level info | notice | warn | error;
  • 默认值: limit_req_log_level error;
  • 上下文: http、server、location

2.4 limit_req

  • 语法:limit_req zone=name [burst=number] [nodelay | delay=number];
    • 这里 burst 就是用来定义桶的大小
    • 想要它立即返回的话,必须加个 nodelay 选项
  • 默认值: 无
  • 上下文: http、server、location
  • 示例
    • limit_req zone=one;
    • limit_conn zone=one burst=5 nodelay;

3 ) 配置示例

http {
	# 注意下面的定义
	limit_req_zone $binary_remote_addr zone=limit_req:15m rate=2r/m; # 这里rate设置的很小,用于演示
	
	server {
		listen      	           80;
		server_name     localhost;
		
		location / {
			root          html;
			index         index.html  index.htm;
			error_log     logs/limit_req_error.log       info; # 这个配置是特意加上的,用于查看错误输出
			
			# 注意下面的定义
			limit_req_status 504;
			limit_req_log_level notice;
			limit_req zone=limit_req; # 0s - 30s 内第一次,30s - 1m内 第二次,如果在0s-30s收到第二次请求则返回504
			# limit_req zone=limit_req burst=7 nodelay; # 定义 burst 选项,30s之内会继续返回,不会504, 直到 7次之后

		}
	}
}

啊,我们后面在环境中给大家做实际的演示,让大家看它们两者之间有什么具体的区别啊,它的默认值是没有的啊,适用的上下文也在defDPserver和location中。
比如说我们现在四厘一这种,我们这个时候就直接后面不写这样一个铜的定义大小。
我们直接写limitIQ我们直接用一个name的用法,这也写错了啊,我们来给大家改一下啊,这就是肉啊,就这么东西。
哇,这个也是中文等位啊,也是room等于这样一个模块啊。
ok那接下来我们给大家演示一下啊,呃我们还接着上一节的我们这个配置文件,我们直接给大家做展示啊,户下的con零x,还是我们先在这儿去定义我们这个root是吧?
定义我们limitrequest这样一个room,一个共享内存。limit,我们来REQ若这样一个指令,后面我们引用的k还是我们的客户端IP是吧?
根据不同的客户端IP去限定我们的客户端的平均速率啊之后呢,我们还是要分一个room等于多少。
比如说我们起一个名字limit,我们就有REQ吧之后,比如说我们给它定义成一个十五兆的共享内存,好不好?
之后我们知道还有一个rate,对吧?我们限定速率是多少呢?限定这个服务器处理客户端请求的一个平均速率是多少呢?
比如说我们这个时候把它限定成一个两次请求吧。我们就现在大一点啊,两次请求每分钟注意啊,大家我把这个色的请处理请求量很小,是因为我为了便于给大家演示这个效果啊。
假如说我设定成一分钟处理两个请求。那也就意味着我在三十秒内只能处理一个请求,大家一定要理解这个关系啊,它是一个消频的关系。
比如说我们在这儿,至于去引用的limitIQ我们都知道我们的IQ定义status,我们上面是返回的这个五零三,我们在这以示区别,我们让它返回五零四,好吧,继续我们的limitREQ还有什么呀?
loglevel,我们把它定义成notice吧,好吧,inthenotice这样一个选项一会儿我们可以在具体的日志中去给大家看一下。
那第三个是一个limit什么呀?直接引用我们的limitIQ这样一个对吧?
后面直接使用room,我们来引用我们前面所定义的样共享内存的名称是什么呀?
limitIQ那好,我们现在就写一个,我们再给大家写一个啊。那这个这样一个我直接引用的时候没有去写那个birth,也就是说定义我们那个桶的整体的大小,也就是我们请求的一个大小是吧?
我们IQ比如说我们在这再定义一个zone等于limitIQ这是我们定义一个birth啊,比如说birth等于七,我给大家定一首对,你是no类的denothis是什么意思?
也就是意味。比如说我现在每分钟处理两个请求,也就是意味着我三十秒只处理一个请求。
那我第一次请求之后,我在三十秒内再去请求。第二次的时候肯定是给我返回这样一个五零四的。
但是如果我要定义birars的选项之后的话,它就不会给我返回一个五零四啊,他会直接给我返回一个正确的结果,并且我们这使用是nodelte的话,就非延迟处理,它会立即给我返回结果啊。
那我们现在现在先把这个给钉先给注释掉啊,好吧,那么这个时候先用我们这样一个指令,先检查一下语法,语法没问题是吧?
我们用杠sreload指令。好,这个时候我们现在来尝试一下去访问我们用靠指令logohost啊,这样吧,我先去把上面那个给注销啊,因为我们需要这个也会影响我们做测试啊,我们先把这个做注销了,先给先把这个给注释掉。
好,那们直接这样,我们用call命令啊,这个时候我们就是用call命令,这就是我第一次请求,对吧?
我定的一个每分钟能处理两个请求,那一三十秒处理一个。第一次大家看他肯定返回一个NEX我要看朵尼x。
这个时候假如我请求第二次的时候,大家看它会直接给我返回一个五零四,也就是限速行为。
这个时候已经发生了,这时候候下我再请求,他肯定还是没有返回结果的,再请求,再请求还是不行,直到等到距离。
第一次你请求返回结果之后,距离三十秒之内三十秒后才会再给你返回结果啊。
大家看那么三十秒到了,它会又返回一个结果。那这就是我们这个啊那这样吧,我们把它给定义小一点吧。
比如说我们把它定义成一个,为了大家去看这个效果,我们把它定义成每分钟处理十二个吧,每分钟处理十二个请求,也就意味着我五秒钟处理一个啊,这样我们演示起来会好好看一些时间间隔短一点。
比如说我们第一次请求大家看返回结果了,对吧?
第二次肯定没有第三秒还没有第四秒也没有第五秒,大家看是不是大概相隔间隔五秒有结果了呀。
book大家看还有没有两秒,三秒四秒五秒。
大家看对不对?先间隔五秒又返回来一个结果。所以说我们在这儿所给大家说的这个结果,它一定是大家一定要能理解这个每分钟处理多少些请求啊,所以说我们的这个limitrequest模块,它本身是限制我们客户端的一个平均处理速率的。
他并不是说比如说我要限制每分钟十二个请求啊。
他并不是说在每分钟之内,你连续给他发十二个请求,他都会给你处理的。
并不是这样的啊,他会严格的去按照给你换算成每秒能处理的一个请求个数来进行一个处理啊。
ok那我们接下来来看一下啊,我们这个来看一下,我们都知道我们使用那个loglevel来记录我们这个日志了。
那这个时候我们来看一下OBE亚的NGX有一个nox的errorlog,大家看在这儿,它是不是?
比如说我这个limitrequest模块限制行为发生的时候,大家看它这里的是不是记了一些notice呀?
哦,大家记住是ever啊,我看看error模块啊,我们来看一下啊,这个时候我们来监控一下这样一个模块,我们再去访问一下这样一个地址ofvingcalllocalhost,对吧?
第一次没关系,第二次肯定哎,我们在这没有记录进去,我们的这个啊嗯不对,这个时候我们在来给它啊,因为我们在这没定义我们的日志啊,我们再来引用一个日志吧。
比如说我们在这引用一个日志啊,比如说我们在这定义一个llogerrolog我们来看一下errorlog的一个用法吧啊,应该是这样写的啊,airlog这样airlog,我们后面直接跟我们具体的日志。
比如说我就写到logs下面的这limit杠IQ杠error二有点老的。好吧,我这个时候比如说我就记录info级别的,因为我们这个notice级别要比这个info级别要高一些。
所以我们一定要记住的低一些,才能够把它给显示出来。
好,那个时候再用OBDNDX视频下的NI杠sreload指令。
好,这个时候我们再来监控一下,我们看OBD下的NDXlogs下的limit,我们来监控一下这样一个日志啊。
这个时候比如说我这个时候开始访问,第一次有结果是吧?
第二次返回错误。第三次也返回收,大家看我这个日志中,大家看他是不是记录了很多行为啊,第一次大家看它是不是limitrequest,对吧?
限制行为发生了是吧?限制是是哪个客户端啊,幺二七零零零点幺,因为我就是本机发起的HTP请求对吧?
大家看它又有这个限制行为发生了限制行为发生了等等。
这个时候你再去请求,如果有的话,他还会继续限制啊,大家看这个日志中都会给大家记录到这样一些限制行为发生OK那这节课呢我们就给大家讲了一个这个我们的limitrequest模块啊,能够限制我们处理客户数据的一个平均速率啊。
ok那我们本节课呢就给大家讲到这里啊。

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

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

相关文章

一分钟告诉你毕业季大学都在用在线版招生简章是如何制作?

毕业季临近,各大高校纷纷进入招生宣传的关键时期。在数字化时代背景下,在线版招生简章成为了高校之间竞争的焦点。一分钟带你了解,这些吸引眼球的在线版招生简章是如何制作出来的。 1. 准备好制作工具:FLBOOK在线制作电子杂志平台…

【论文分享】Graviton: Trusted Execution Environments on GPUs 2018’OSDI

目录 AbstractIntroductioncontributions BackgroundGPUSoftware stackHardwareContext and channel managementCommand submissionProgramming modelInitializationMemory allocationHost-GPU transfersKernel dispatch Sharing Intel SGX Threat ModelOverviewGraviton Archi…

World of Warcraft [CLASSIC] Engineering 335-420

World of Warcraft [CLASSIC] Engineering 工程学冲技能点 335 - 420 [冰霜冲击雷管] 335-345 [冰霜手雷] 346-358 这部分知道可以不看了 在地狱火半岛,萨尔玛,找70级工程学大师学习新的技能,用来充技能都不划算 回【达拉然】找80级工程…

【电子数据取证】提升案件分析准确性的去重技术

前言 紧随《AES解密侵犯隐私案件数据》一文的讨论,本文将深入探讨数据解密后的处理工作。解密只是数据恢复的第一步,确保数据的准确性和分析的有效性同样重要。本文将重点介绍数据去重技术,阐述在解密数据后如何细致地进行去重处理&#xff…

wx.choosemedia 无反应 不生效 不弹出图片视频

调整开发者工具基础版本:打开微信开发者工具 > 右上方点击详情 > 本地设置 >调试基础库(更换版本) 这里我试了几个,发现 3 开头的版本都不行。。最后选了 2.30.4版本,官方文档给的答案是 2.10.0 开始支持 。…

特殊管道资源采购

管道资源物料是从管道(如输油管)或其它线管(如输电线)中直接进入生产流程的物料。与寄售物料不同的是,管道资源物料不必一定经过“采购”获得。管道库存不是在仓库中实际可用的库存。管道中的物料始终可用,…

Datawhale X 李宏毅苹果书 AI夏令营-深度学习入门班-task1

机器学习就是去拟合一种函数,它可能在高维上,十分抽象,但是却可以有丰富的语义含义,从而完成一系列任务 回归任务是预测一个准确的值,例如拟合一条直线的时候,我们希望每一个点的值都能对应上 分类任务则…

JAVA-抽象类和抽象方法

目录 一、抽象类的概念 二、抽象类语法 三、抽象类特性规则 四、抽象类的作用 一、抽象类的概念 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果 一个类中没有包含足够…

宠物空气净化器是否是智商税?性价比高的宠物空气净化器十大排名

我开着一家猫咪咖啡馆,我们店貌美小猫可没少给我带来回头客~先给大家看看我的招财猫们 我的猫咪咖啡馆已经运营了三年了,直到最近才迎来了盈利的曙光。初期,面对种种困难与挑战,特别是频繁的投诉,几乎让我陷入了经营困…

IO进程线程8月23日

1&#xff0c;思维导图 2&#xff0c;创建子父 #include<myhead.h> int main(int argc, const char *argv[]) {pid_t pid;pidfork();if(pid>0){int fp3open("./3.txt",O_RDONLY);int fp4open("./4.txt",O_CREAT|O_TRUNC|O_WRONLY,0664);char str…

gin快速入门

gin 项目地址晓智科技晓智科技晓智文档晓智文档文档源码文档源码 快速体验 func HandlerPong(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "pong",}) }func main() {r : gin.Default()r.GET("/ping", HandlerPong)_ r.Run(&qu…

JUnit 5和Mockito进行单元测试!

1. JUnit 5 基础 JUnit 5是最新的JUnit版本&#xff0c;它引入了许多新特性&#xff0c;包括更灵活的测试实例生命周期、参数化测试、更丰富的断言和假设等。 1.1 基本注解 Test&#xff1a;标记一个方法为测试方法。 BeforeEach&#xff1a;在每个测试方法之前执行。 AfterEac…

69 H3C SecPath F1000 (系统模块介绍-2)

28-IRF 特性简介 IRF&#xff08;Intelligent Resilient Framework&#xff0c;智能弹性架构&#xff09;是一种软件虚拟化技术。它的核心思想是将多台设备连接在一起&#xff0c;进行必要的配置后&#xff0c;虚拟化成一台设备。使用这种虚拟化技术可以集合多台设备的硬件资源…

54. 螺旋矩阵【 力扣(LeetCode) 】

一、题目描述 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 二、测试用例 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入…

软件测试——自动化测试selenium

自动化测试 测试人员编写自动化测试脚本&#xff0c;维护并解决自动化脚本问题 自动化的主要目的就是用来进行回归测试 回归测试 常见面试题 ⾃动化测试能够取代人工测试吗&#xff1f; ⾃动化测试不⼀定⽐人工测试更能保障系统的可靠性&#xff0c;⾃动化测试是测试⼈员手…

图论 最短路

文章目录 单源最短路朴素Dijkstra代码 堆优化Dijkstra代码 Bellman-ford代码 spfaspfa求最短路代码 spfa判断负环代码 多源最短路Floyd代码 单源最短路 朴素Dijkstra 给定一个 n n n 个点 m m m 条边的有向图&#xff0c;图中可能存在重边和自环&#xff0c;所有边权均为正…

vscode 阅读linux内核(vscode+clangd)

此插件曾在vim里用过&#xff0c;非常好用。 首先先在vscode 里下载clangd插件 这只是客户端&#xff0c;还需下载个服务器&#xff08;这在coc插件里也有说明&#xff09; sudo apt install clangd 下载完后可以 clangd --version 查看版本信息&#xff0c;如果能查看&#x…

回归预测|基于灰狼GWO优化BP神经网络多输入多输出的数据回归预测Matlab程序GWO-BP 含预测新数据程序

回归预测|基于灰狼GWO优化BP神经网络多输入多输出的数据回归预测Matlab程序GWO-BP 含预测新数据程序 文章目录 前言回归预测|基于灰狼GWO优化BP神经网络多输入多输出的数据回归预测Matlab程序GWO-BP 含预测新数据程序 一、GWO-BP多输出模型1. 原理2. GWO-BP模型流程步骤1: 初始…

jenkins最佳实践(一):jenkins安装与部署

各位小伙伴们大家好呀&#xff0c;我是小金&#xff0c;下面我将记录学习jenkins的系列文章与心得&#xff0c;一方面用于博主的自我记录&#xff0c;一方面如果能帮助到正在浏览这篇文章的小伙伴&#xff0c;那更好不过了&#xff0c;本篇文章主要讲述jenkins的安装以及安装je…

已经30岁了,想转行从头开始现实吗?什么样的工作算好工作?

我是29岁那年&#xff0c;完成从转行裸辞副业的职业转型。 如果你把职业生涯看成是从现在开始30岁&#xff0c;到你退休那年&#xff0c;中间这么漫长的30年&#xff0c;那么30岁转行完全来得及&#xff1b; 如果你觉得必须在什么年纪&#xff0c;什么时间内必须完成赚到几十…