重新思考边缘负载均衡

本文介绍了Netflix在基于轮询的负载均衡的基础上,集成了包括服务器使用率在内的多因素指标,并对冷启动服务器进行了特殊处理,从而优化了负载均衡逻辑,提升了整体业务性能。原文: Rethinking Netflix’s Edge Load Balancing[1]

我们在介绍开源Zuul 2[2]的文章中简单提到了负载均衡方面的一些改进,本文将更详细介绍这项工作的原因、方式和结果。

目标

Netflix的云网关团队一直致力于帮助系统减少错误,获得更高的可用性,并提高故障恢复能力。因为Netflix每秒有超过一百万次请求,即使是很低的错误率也会影响到会员体验,所以每一点提升都有帮助。

因此,我们向Zuul和其他团队学习,改进负载均衡实现,以进一步减少由服务器过载引起的错误。

背景

Zuul以前用基于轮询的Ribbon负载均衡器[3],并基于某些过滤机制将连接失败率高的服务器列入黑名单。

过去几年里,我们做了一些改进和定制,比如向最近上线的服务器发送较少流量,以避免过载。这些改进已经取得了显著效果,但对于某些问题比较多的原始集群,还是会看到与负载相关的错误率远高于预期。

如果集群中所有服务器都过载,那选择哪一台服务器几乎没有什么区别,不过现实中我们经常看到只有某个服务器子集过载的情况。例如:

  • 服务器冷启动后(在红黑部署和触发自动伸缩期间)。
  • 由于大量动态属性/脚本/数据更新或大型GC事件,服务器暂时变慢/阻塞。
  • 服务器硬件问题。经常会看到某些服务器运行得总是比其他服务器慢,有可能是由于邻居节点占用太多资源,也可能因为硬件不同。
指导原则

在开始一个项目时,需要记住一些原则,从而帮助指导在设计软件时需要做出的大大小小的决定,这个项目基于的原则如下。

在现有负载均衡器框架的约束下工作

我们已经将之前定制的负载均衡器集成到了Zuul代码库中,从而使得无法与Netflix的其他团队共享这些定制。因此,我们决定这次基于约束条件并做出额外投资,从一开始就考虑复用,从而能够直接在其他系统中使用,减少重新发明轮子的代价。

向他人学习

尝试在他人的想法和实现基础上构建,例如之前在Netflix其他IPC栈中试用的"二选一(choice-of-2)"和"试用期(probation)"算法。

避免分布式状态

选择本地决策,避免跨集群协调状态的弹性问题、复杂性和滞后。

避免客户端配置和手动调优

多年来基于Zuul的操作经验表明,将服务配置的部分置于不属于同一团队的客户服务中会导致问题。

一个问题是,客户端配置往往与服务端不断变化的现实不同步,或者在不同团队拥有的服务之间引入耦合的变更管理。

例如,用于服务X的EC2实例类型升级,导致该集群所需节点减少。因此,现在服务Y中的"每台主机最大连接数"客户端配置应该增加,以反映新增加的容量。应该先对客户端进行更改,还是先对服务端进行更改,还是同时对两者进行更改?更有可能的是,完全忘了要改配置,从而导致更多问题。

尽可能不要配置静态阈值,而是采用基于当前流量、性能和环境变化的自适应机制。

当需要静态阈值时,与其让服务团队将阈值配置协调到每个客户端,不如让服务在运行时进行通信,以避免跨团队边界推动更改的问题。

负载均衡方法

主要的想法是,虽然服务器延迟的最佳数据来源是客户端视图,但服务器利用率的最佳数据来源是服务器本身。结合这两种数据源,可以得到最有效的负载均衡。

我们基于一组互补机制,其中大多数已经被其他人开发和使用过,只是以前可能没有以这种方式组合。

  • 用于在服务器之间进行选择的 二选一算法(choice-of-2 algorithm)
  • 基于服务器利用率的 负载均衡器视图进行主负载均衡。
  • 基于服务器利用率的 服务器视图进行二次均衡。
  • 基于 试用期和基于 服务器世代的机制,避免新启动的服务器过载。
  • 随着时间推移,收集的服务器统计数据 衰减为零。

Join-the-Shortest-Queue和服务器报告利用率相结合

我们选择支持常用的Join-the-shortest-queue(JSQ) 算法,并将服务器报告的利用率作为第二算法,以尝试结合两者达到最佳效果。

JSQ的问题

Join-the-shortest-queue对于单个负载均衡器非常有效,但如果跨负载均衡器集群使用,则会出现严重问题。负载均衡器会倾向于在同一时间选择相同的低利用率服务器,从而造成超载,然后转移到下一个利用率最低的服务器并造成超载,以此类推……

通过结合使用JSQ和二选一算法,可以在很大程度上消除羊群问题,除了负载均衡器没有完整的服务器使用信息之外,其他方面都很好。

JSQ通常仅从本地负载均衡器计算到服务器的正在使用的连接数量来实现,但是当有10到100个负载均衡器节点时,本地视图可能会产生误导。

单个负载平衡器的观点可能与实际情况大不相同
单个负载平衡器的观点可能与实际情况大不相同

例如,在上图中,负载均衡器A有一个到服务器X的请求和一个到服务器Z的请求,但没有到服务器Y的请求。所以当它收到新请求时,基于本地数据,选择利用率最小的服务器,会选择服务器Y,但这不是正确的选择。服务器Y实际上负载最重,其他两个负载均衡器目前都有请求发送到服务器Y上,但负载均衡器A没有办法知道。

这说明单个负载均衡器的观点与实际情况完全不同。

在只依赖客户端视图时遇到的另一个问题是,对于大型集群(特别是与低流量相结合时),负载均衡器通常只有几个活跃连接,和集群中的某个子集交互。因此,当它选择哪个服务器负载最少时,通常只是在若干个它认为负载都是0的服务器之间进行选择,而并没有关于所选服务器的利用率的数据,所以只能盲猜。

这个问题的解决方案是与所有其他负载均衡器共享所有活跃连接数状态……但这样就需要解决分布式状态问题。

考虑到获得的好处要大于付出的成本,因此我们通常只将分布式可变状态作为最后手段:

  • 分布式状态增加了部署和金丝雀发布等任务的运维开销和复杂性。
  • 弹性风险与数据损坏的爆炸半径相关(1%负载均衡器上数据损坏让人烦恼,但100%负载均衡器上数据损坏会造成停机)。
  • 在负载均衡器之间实现P2P分布式状态系统的成本,或者运维一个具有处理大量读写流量所需的性能和弹性凭证的单一数据库的成本。

另一种更简单的解决方案(也是我们选择的),是依赖于服务器向每个负载均衡器报告资源使用情况……

服务器报告使用率

服务器主动上报其使用率的好处是可以提供所有使用了该服务器的负载均衡器的完整信息,从而避免JSQ的不完整问题。

对此有两种实现方式:

  1. 运行状况检查端点 主动轮询每个服务器的当前利用率。
  2. 被动跟踪来自服务器的响应,并标注其当前利用率数据。

我们选择第二种方式,其实现简单,可以频繁更新数据,避免了N个负载均衡器每隔几秒钟轮询M个服务器所带来的额外开销。

被动策略的影响是,负载均衡器向一台服务器发送请求的频率越高,获得的该服务器的利用率数据就越新。因此RPS越高,负载均衡的有效性就越高。但反过来,RPS越低,负载均衡的效果就越差。

这对我们来说不是问题,但对于通过特定负载均衡器处理低RPS(同时通过另一个负载均衡器处理高RPS)的服务来说,主动轮询运行状况检查可能更有效。临界点是负载均衡器向每个服务器发送的RPS低于运行状况检查的轮询频率。

服务端实现

我们在服务端通过简单跟踪活跃请求计数来实现,将其转换为该服务器配置的最大百分比,并将其作为HTTP响应报头:

X-Netflix.server.utilization: <current-utilization>[, target=<target-utilization>]

服务器可以指定可选的目标利用率,从而标识预期在正常条件下运行的利用率百分比,负载均衡器基于这一数据进行粗粒度过滤,后面会详细介绍。

我们尝试使用活跃计数以外的指标,例如操作系统报告的cpu利用率和平均负载,但发现它们会引起振荡,原因似乎是因为它们是基于滚动平均值计算的,因此有一定的延迟。所以我们决定现在只用相对简单的实现,即只计算活跃请求。

用二选一算法代替轮询

由于我们希望能够通过比较服务器的统计数据来选择服务器,因此不得不抛弃现有的简单轮询实现。

我们在Ribbon算法中尝试的一个替代方案是JSQ与ServerListSubsetFilter相结合,以减少分布式JSQ的羊群问题。这样可以得到合理的结果,但是结果在目标服务器之间的请求分布仍然过于分散。

因此,我们参考了Netflix另一个团队的早期经验,并实现了"二选一(Choice-of-2)"算法。这样做的优点是实现简单,使负载均衡器的cpu成本较低,并能提供良好的请求分布。

根据综合因素进行选择

为了在服务器之间进行选择,我们比较了3个不同的因素:

  1. 客户端运行状况: 该服务器连接相关错误的滚动百分比。
  2. 服务器利用率: 该服务器的最新利用率数据。
  3. 客户端利用率: 从当前负载均衡器发送到该服务器的活跃请求数。

这3个因素被用来为每个服务器计算分数,然后比较总分数选择获胜者。

像这样使用多个因素确实会使实现更加复杂,但可以避免仅依赖一个因素可能出现的边际问题。

例如,如果一台服务器开始出现故障并拒绝所有请求,那么上报的利用率将会低得多(因为拒绝请求比接受请求开销更小),如果这是唯一考虑的因素,那么所有负载均衡器将开始向那台坏服务器发送更多请求。客户端运行状况因素缓解了这种情况。

过滤

当随机选择2台服务器进行比较时,会过滤掉任何超过安全利用率配置和运行状况阈值的服务器。

每个请求都会进行这种过滤,以避免定期过滤会出现的过时问题。为了避免在负载均衡器上造成较高的cpu负载,我们尽力而为(best-effort) 尝试N次来随机选择一个可用服务器,然后在必要时回退到未筛选的服务器。

当服务器池中有很大一部分存在长期问题时,这样的筛选非常有用。在这种情况下,随机选择2个服务器通常会出现选择了2个坏服务器进行比较的情况。

但缺点是这依赖于静态配置阈值,而这是我们试图避免的。测试结果让我们相信这点依赖是值得的,即使只依赖一些通用(非特定于服务的)阈值。

试用期

对于任何没有发送响应给负载均衡器的服务器,一次只允许一个活跃请求,随后会过滤掉这些试用服务器,直到收到来自它们的响应。

这有助于避免新启动的服务器还没有机会显示使用率数据之前就因大量请求而超载。

基于服务器世代的预热

我们基于服务器世代在服务器启动的前90秒内逐步增加流量。

这是另一种有用的机制,就像试用期一样,可以在微妙的发布后增加一些关于服务器过载的警告。

统计衰变

为确保服务器不会被永久列入黑名单,我们将衰减率应用到所有用于负载均衡的统计数据上(目前是30秒的线性衰减)。例如,如果一个服务器的错误率上升到80%,停止向它发送流量,使用的数据将在30秒内衰减为零,比方说15秒后是会是40%)。

运维影响
差距更大的请求分布

不用轮询进行负载均衡的负面影响是,以前服务器之间的请求分布非常均衡,现在服务器之间的负载差距更大。

"二选一"算法在很大程度上能缓解这种情况(与跨集群中所有服务器或服务器子集的JSQ相比),但不可能完全避免。

因此,在运维方面确实需要考虑这一点,特别是在金丝雀分析中,我们通常比较请求计数、错误率、cpu等的绝对值。

越慢的服务器接收的流量越少

显然这是预期效果,但对于习惯于轮询的团队来说,流量是平等分配的,这对运维方面会产生连锁反应。

由于跨原始服务器的流量分布现在依赖于它们的利用率,如果一些服务器正在运行效率更高或更低的不同构建,那么将接收到更多或更少的流量。所以:

  • 当集群采用红黑部署时,如果新的服务器组性能下降,那么该组的流量比例将小于50%。
  • 同样的效果可以在金丝雀集群中看到,基线组可能会接收到与金丝雀组不同的流量。所以当我们着眼于指标时,最好着眼于RPS和CPU的组合(例如RPS在金丝雀中可能更低,而CPU相同)。
  • 更低效的异常值检测。我们通常会自动监控集群中的异常服务器(通常是由于硬件问题导致启动速度变慢的虚拟机)并终止它们,当由于负载均衡而接收较少流量时,这种检测就更加困难。
滚动动态数据更新

从轮询迁移到新的负载均衡器取得了很好的效果,可以很好的配合动态数据和属性的分阶段更新。

最佳实践是每次在一个区域(数据中心)部署数据更新,以限制意外问题的爆发半径。

即使数据更新本身没有引起任何问题,服务器应用更新的行为也会导致短暂的负载高峰(通常与GC相关)。如果此峰值同时出现在集群中所有服务器上,则可能导致负载下降以及向上游传播大量错误。在这种情况下,因为所有服务器的负载都很高,负载均衡器几乎无法提供帮助。

然而,如果考虑与自适应负载均衡器结合使用,一个解决方案是在集群服务器之间进行滚动数据更新。如果只有一小部分服务器同时应用更新,那么只要还有足够服务器能够承载流量,负载均衡器就可以短暂减少到这些服务器的流量。

合成负载测试结果

在开发、测试和调优负载均衡器时,我们广泛使用了合成负载测试场景,这在使用真实集群和网络验证有效性时非常有用,可以作为单元测试之后的可重复步骤,但还没有使用真实用户流量。

测试的更多细节在后面的附录中列出,现总结要点如下:

  • 与轮询实现相比,启用了所有功能的新负载均衡器在负载下降和连接错误方面降低了几个数量级。
  • 平均和长尾延迟有了实质性改善(与轮询实现相比减少了3倍)。
  • 服务器本身由于添加了特性,显著增加了价值,减少了一个数量级的错误以及大部分延迟。
结果比较
结果比较
对实际生产流量的影响

我们发现,只要服务器能够处理,新负载均衡器就能非常有效的将尽可能多的流量分配到每个服务器。这对于在间歇和持续降级的服务器之间进行路由具有很好的效果,无需任何人工干预,从而避免工程师在半夜被叫醒处理重大生产问题。

很难说明在正常运行时的影响,但在生产事故中甚至在某些服务的正常稳态运行中,可以看到对应的影响。

事故发生时

最近的事故涉及到服务中的错误,该错误导致越来越多的服务器线程随着时间的推移而阻塞。从服务器启动的那一刻起,每小时都会阻塞几个线程,直到最终达到最大负载并造成负载下降。

在下面的服务器RPS图表中,可以看到在凌晨3点之前,服务器负载分布差距较大,这是由于负载均衡器向阻塞线程数量较多的服务器发送较少流量的缘故。然后,在凌晨3点25分之后,自动缩放启动更多服务器,由于这些服务器还没有任何线程阻塞,每个服务器收到的RPS大约是现有服务器的两倍,可以成功处理更多流量。

每服务器RPS
每服务器RPS

现在,如果我们看一下同一时间范围内每台服务器的错误率图表,可以看到,在整个事故过程中,所有服务器的错误分布是相当均匀的,尽管某些服务器的容量比其他服务器小得多。这表明负载均衡器在有效工作,而由于集群整体可用容量太小,因此所有服务器都被推到稍稍超过其有效容量的位置。

然后,当自动缩放启动新服务器时,新服务器处理了尽可能多的流量,以至于出现了与集群其他部分相同的错误。

每服务器每秒错误
每服务器每秒错误

因此,综上所述,负载均衡器在向服务器分配流量方面非常有效,但在这种情况下,没有启动足够的新服务器,从而导致没法将整体错误水平降至零。

稳态

我们还看到,在某些服务中,由于GC事件而出现几秒钟的负载下降,因此稳态噪声显著降低。从这里可以看出,启用新的负载均衡器后,错误大幅减少:

启用新负载均衡器前后数周内与负载相关的错误率
启用新负载均衡器前后数周内与负载相关的错误率
告警中的差距

一个意料之外的影响是突出了我们自动告警中的一些差距。一些基于服务错误率的现有告警,以前会在渐进式问题只影响到集群的一小部分时发出告警,现在因为错误率一直很低,告警会晚得多,或者根本不发出告警。这意味着,有时没法将影响集群的大问题通知给团队。解决方案是增加对利用率指标的偏差而不仅仅是错误指标的额外告警来弥补这些差距。

结论

本文并不是为Zuul做宣传(尽管它是一个伟大的系统),只是为代理/服务网格/负载均衡社区分享和增加了一个有趣的方法。Zuul是测试、实施和改进这些类型负载均衡方案的伟大系统,以Netflix的需求和规模来运行,使我们有能力证明和改进这些方法。

有许多不同方法可以改善负载均衡,而这个方法对我们来说效果很好,大大减少了与负载有关的错误率,并极大改善了真实流量的负载均衡。

然而,对于任何软件系统来说,都应该根据自己组织的限制和目标来做决定,并尽量避免追求完美。


附录--合成负载测试的结果
测试场景

这个负载测试场景重现了这样一种情况: 小型原始集群正在进行红黑部署,而新部署的集群存在冷启动问题或某种性能退化(通过人为在新部署的服务器上为每个请求注入额外延迟和cpu负载来模拟)。

该测试将4000 RPS发送到一个大型Zuul集群(200个节点),该集群反过来代理到一个小型Origin集群(20个实例),几分钟后,启用第二个缓慢的Origin集群(另外20个实例)。

启用所有功能

以下是启用了所有功能的新负载均衡器的指标图表。

启用新负载均衡器所有功能进行负载测试
启用新负载均衡器所有功能进行负载测试

作为参考,看看流量是如何在较快和较慢的服务器组之间分配的,可以看到,负载均衡器把发送到较慢组的比例减少到15%左右(预期50%)。

正常集群和慢速集群之间的流量分布
正常集群和慢速集群之间的流量分布
禁用服务器利用率

还是新负载均衡器,但禁用了服务器利用率功能,因此只有客户端数据被用于均衡。

使用新负载均衡器进行负载测试,但禁用了服务器利用率特性
使用新负载均衡器进行负载测试,但禁用了服务器利用率特性
原始实现

这是最初的轮询负载均衡器与服务器黑名单功能。

使用原始负载均衡器进行负载测试
使用原始负载均衡器进行负载测试

你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。
微信公众号:DeepNoMind

参考资料

[1]

Rethinking Netflix’s Edge Load Balancing: https://netflixtechblog.com/netflix-edge-load-balancing-695308b5548c

[2]

Open Sourcing Zuul 2: https://medium.com/netflix-techblog/open-sourcing-zuul-2-82ea476cb2b3

[3]

Ribbon负载均衡器: https://github.com/Netflix/ribbon

- END -

本文由 mdnice 多平台发布

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

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

相关文章

第十五章 EM期望极大算法及其推广

文章目录 导读符号说明混合模型伯努利混合模型(三硬币模型)问题描述三硬币模型的EM算法1.初值2.E步3.M步初值影响p,q 含义 EM算法另外视角Q 函数BMM的EM算法目标函数LEM算法导出 高斯混合模型GMM的EM算法1. 明确隐变量, 初值2. E步,确定Q函数3. M步4. 停止条件 如何应用GMM在聚…

软测推荐第二期:10本高质量测试书籍

在不断发展的软件开发领域&#xff0c;测试是质量的守护者&#xff0c;确保产品不仅满足功能要求&#xff0c;而且提供无缝的用户体验。随着软件复杂性的增加&#xff0c;对完善的测试方法和见解的需求也随之增加。 上次给大家推荐了五本书&#xff0c;获得了大家的积极反馈&a…

RT-Thread系统使用常见问题处理记录

1.使用telnet连接系统时发送help指令显示不全的问题。 原因&#xff1a;telnet发送缓存太小。 解决办法&#xff1a;更改agile_telnet软件包里Set agile_telnet tx buffer size的大小。 2.使用Paho MQTT软件包过一段时间报错hard fault on thread: mqtt0 解决办法&#xff1…

UE5加载websocket模块为空

今天测试UE 发现工程启动不了&#xff0c;后来看到原来是websocket模块无法加载。 解决的它的方法很简单&#xff0c;这种问题一般会出现在源码版本的引擎或者是停电了&#xff0c;导致UElaunch版本损坏&#xff0c;解决方法是来到源码版本的引擎 这个目录下&#xff1a; D:\…

稳定性测试—fastboot和monkey区别

一、什么是稳定性测试 稳定性测试是指检验程序在一定时间内能否稳定地运行&#xff0c;在不同的场景下能否正常地工作的过程。主要目的是检测崩溃、内存泄漏、堆栈错误等缺陷。 二、Monkey 1.什么是Monkey 是一个命令行工具&#xff0c;通常在adb安卓调试运行&#xff0c;模…

ABAP简单的队列设置QRFC

场景&#xff1a;用job的方式在接口里启用job&#xff0c;如果接口调用比较频繁&#xff0c;存在同一时间启动相同job的情况&#xff0c;会导致锁表锁程序这种情况。 查阅job函数&#xff0c;发现在JOB_CLOSE函数里自带了类似队列的参数&#xff0c;但是因为是接口&#xff0c…

如何卸载干净 IDEA(图文讲解)windows和Mac教程

大家好&#xff0c;我是sun~ 很多小伙伴会问 Windows / Mac 系统上要怎么彻底卸载 IDEA 呢&#xff1f; 本文通过图片文字&#xff0c;详细讲解具体步骤&#xff1a; 如何卸载干净 IDEA&#xff08;图文讲解&#xff09; Windows1、卸载 IDEA 程序2、注册表清理3、残留清理 M…

重生奇迹mu下载后仅仅只是挂机吗?

挂挂机、聊聊天&#xff0c;打打怪&#xff0c;如此简单、轻松的游戏或许有&#xff0c;但绝对不是重生奇迹mu&#xff01;因为重生奇迹mu挂机也不是那么容易&#xff0c;即便是多名高端玩家组队挂机&#xff0c;也有可能是全队惨灭&#xff0c;这样的情况时常发生在游戏中。 …

【入门Flink】- 05Flink运行时架构以及一些核心概念

系统架构 Flink运行时架构Standalone会话模式为例 1&#xff09;作业管理器&#xff08;JobManager&#xff09; JobManager 是一个 Flink 集群中任务管理和调度的核心&#xff0c;是控制应用执行的主进程。每个应用都应该被唯一的 JobManager 所控制执行。 JobManger 又包含…

聚观早报 |盒马参战双11;真我GT5 Pro将压轴登场

【聚观365】11月4日消息 盒马参战双11 真我GT5 Pro将压轴登场 奇瑞汽车10月销量创新高 iQOO 12系列将首发电竞芯片Q1 苹果CEO库克称正改善供需平衡 盒马参战双11 不少消费者反映&#xff0c;今年盒马的双11已悄然开始&#xff1a;10月20日起&#xff0c;盒马APP很多商品页…

【3D图像分割】基于 Pytorch 的 VNet 3D 图像分割3(3D UNet 模型篇)

在本文中&#xff0c;主要是对3D UNet 进行一个学习和梳理。对于3D UNet 网上的资料和GitHub直接获取的代码很多&#xff0c;不需要自己从0开始。那么本文的目的是啥呢&#xff1f; 本文就是想拆解下其中的结构&#xff0c;看看对于一个3D的UNet&#xff0c;和2D的UNet&#x…

python实现MC协议(SLMP 3E帧)的TCP服务端(篇二)

python实现MC协议&#xff08;SLMP 3E帧&#xff09;的TCP服务端是一件稍微麻烦点的事情。它不像modbusTCP那样&#xff0c;可以使用现成的pymodbus模块去实现。但是&#xff0c;我们可以根据协议帧进行组包&#xff0c;自己去实现帧的格式&#xff0c;而这一切可以基于socket模…

Zephyr-7B-β :类GPT的高速推理LLM

Zephyr 是一系列语言模型&#xff0c;经过训练可以充当有用的助手。 Zephyr-7B-β 是该系列中的第二个模型&#xff0c;是 Mistralai/Mistral-7B-v0.1 的微调版本&#xff0c;使用直接偏好优化 (DPO) 在公开可用的合成数据集上进行训练 。 我们发现&#xff0c;删除这些数据集的…

系列五、映射文件xxxMapper.xml

一、概述 mapper映射文件是mybatis中最重要的部分&#xff0c;涉及到的细节也非常多。 1.1、parameterType 表示输入参数的类型。例如&#xff1a; <select id"getUserById" parameterType"integer" resultType"org.star.entity.model.UserDO&…

python自动化测试模板

1:准备html模版 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>接口自动化…

网络协议的基本概念

网络协议的基本概念 随处可见的协议 在计算机网络与信息通信领域里&#xff0c;人们经常提及“协议”一词。互联网中常用的具有代表性的协议有IP、TCP、HTTP等。 “计算机网络体系结构”将这些网络协议进行了系统归纳。TCP/IP就是IP、TCP、HTTP等协议的集合。现在&#xff0…

DI93a HESG440355R3 通过其Achilles级认证提供网络安全

DI93a HESG440355R3 通过其Achilles级认证提供网络安全 施耐德电气宣布推出Modicon M580以太网PAC (ePAC)自动化控制器&#xff0c;该控制器采用开放式以太网标准&#xff0c;通过其Achilles级认证提供网络安全。M580 ePAC使工厂操作员能够设计、实施和运行一个积极利用开放网…

(免费领源码)java#springboot#mysql网上商城系统的设计与实现08789-计算机毕业设计项目选题推荐

摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;采用Java技术建设网上商城系统。 本设…

PCL点云处理(007)-Ransac

随机抽样一致性算法RANSAC(Random sample consensus)是一种迭代的方法来从一系列包含有离异值的数据中计算数学模型参数的方法。 RANSAC算法本质上由两步组成&#xff0c;不断进行循环&#xff1a; 从输入数据中随机选出能组成数学模型的最小数目的元素&#xff0c;使用这些元素…

【C++】红黑树模拟实现STL中的map与set

红黑树里面具体存的是什么类型的元素&#xff0c;是由模板参数 T 来决定&#xff1a; 如果 T 是 Key 那么就是 set。 如果 T 是 pair<const Key, V>&#xff0c;那么就是 map。 1、定义红黑树的节点结构 // 定义红黑颜色 enum Colour {RED,BLACK };template<class …