Spring Boot 实现网络限速:让流量“收放自如”

news2026/4/1 2:36:19
Spring Boot 实现网络限速让流量“收放自如”一、为啥要网络限速在当今这个数字化时代网络服务就像我们生活中的水电一样不可或缺而网络限速则是保障这些服务稳定、高效运行的关键一环。它能确保在各种复杂的网络环境下服务的性能不会受到太大影响为用户提供稳定的体验。先来讲讲抵御恶意攻击。在互联网这个广阔的世界里并非所有的访问都是善意的。恶意爬虫就像不请自来的小偷在未经授权的情况下大量抓取网站数据不仅会消耗大量的网络带宽还可能导致服务器资源被耗尽使正常用户无法访问。还有 CCChallenge Collapsar攻击攻击者通过控制大量傀儡机向目标服务器发送海量的请求试图耗尽服务器的资源使其瘫痪。这就好比一群人在疯狂地挤一扇门让真正有需要进门的人被挡在外面。而通过网络限速我们可以对单位时间内的请求数量或流量进行限制当检测到某个 IP 或用户的访问频率异常高时直接拦截这些非法请求就像在门口设置了一个保安拦住那些不怀好意的人从而有效保护服务器的安全。再谈谈应对流量峰值。现在的电商平台经常会举办各种促销活动像 “双 11”“618” 这样的购物狂欢节大量用户会在同一时间涌入平台进行抢购。这就好比一场洪水突然来袭如果服务器没有任何防护措施很容易就会被这突如其来的巨大流量冲垮。网络限速就像是一个坚固的堤坝通过削峰填谷的方式将瞬间的高峰流量进行合理分配让流量平稳地进入服务系统。比如限制每个用户每秒只能发起一定数量的请求或者限制整个系统每秒的总请求数这样可以避免服务器因为瞬间承受过多压力而崩溃确保所有用户都能有机会参与活动享受服务。最后看看保护核心资源。很多服务都依赖于数据库、缓存、第三方接口等核心资源。当大量高频请求穿透到这些下游组件时就像无数人同时去争夺有限的资源很容易导致这些组件不堪重负引发级联故障。比如一个电商系统的订单查询接口如果没有限速可能会有大量用户同时请求导致数据库负载过高不仅订单查询功能无法正常使用还可能影响到其他依赖数据库的功能如商品展示、库存更新等。通过网络限速我们可以限制对这些核心资源的访问频率保护它们不被过度使用就像给资源加上了一把锁只有在允许的情况下才能访问从而保证整个服务系统的稳定运行。二、常见限速策略大盘点为了实现网络限速业内有很多行之有效的策略每种都有其独特的优势和适用场景接下来我就给大家介绍 4 种常见的限速策略。固定窗口计数器固定窗口计数器算法是一种简单直观的限流方法。在这种算法中我们会设定一个固定的时间窗口比如 1 秒然后在这个窗口内对请求进行计数。每来一个请求计数器就加 1 当计数器达到设定的阈值时后续的请求就会被拒绝直到这个时间窗口结束计数器才会清零开始下一轮计数。假设我们设置一个接口 1 秒内最多允许 100 次请求。一开始计数器 count 为 0每收到一个请求count 就加 1。在这 1 秒内如果 count 小于等于 100请求可以正常访问一旦 count 超过 100后续的请求就会被拒绝。当这 1 秒过去后count 重置为 0重新开始计数。这种算法的优点是实现起来非常简单容易理解和部署。但它有一个明显的缺陷就是在窗口切换的瞬间可能会出现突发流量问题。比如说在 1 秒的时间窗口内前 100 毫秒就来了 100 个请求满足阈值条件都被处理了那么在接下来的 900 毫秒内即使系统很空闲再有请求也会被拒绝。更糟糕的是在窗口切换时如果上一个窗口最后 100 毫秒来了 100 个请求而下一个窗口的前 100 毫秒又来 100 个请求那么在这 200 毫秒内系统就需要处理 200 个请求远远超出了我们预期的每秒 100 次的限制这就是所谓的 “突刺现象” 和 “临界问题”很可能导致系统负载过高甚至崩溃。滑动窗口计数器为了解决固定窗口计数器算法的 “突刺现象” 和 “临界问题”滑动窗口计数器算法应运而生。这种算法的核心思想是将固定的大时间窗口拆分成多个小窗口随着时间的推移这些小窗口不断地滑动统计也在持续变化。比如说我们把 1 秒的大窗口拆分成 10 个 100 毫秒的小窗口每个小窗口都有自己独立的计数器。当请求到达时我们不仅要统计当前小窗口内的请求数还要统计当前窗口及之前若干个小窗口的请求总数以此来判断是否超过限流阈值。随着时间每过 100 毫秒窗口就向右滑动一格最老的那个小窗口的计数就会被丢弃同时纳入最新的小窗口的计数。这样做的好处是显而易见的它使得流量统计更加平滑能够有效减少请求的突发性避免在窗口切换时出现流量突增的情况。但由于它需要维护多个小窗口的计数器并且在每次请求时都要进行更复杂的统计计算所以实现起来相对复杂一些对系统资源的消耗也会多一些 。不过为了系统的稳定性这些代价通常是值得的在对限流精度要求较高的场景中滑动窗口计数器算法被广泛应用。漏桶算法漏桶算法的原理就像我们日常生活中的漏斗一样。请求就像水一样可以任意速率流入到一个桶中而桶则以固定的速率将请求 “漏出” 进行处理。如果请求流入的速度太快导致桶被装满了那么多余的请求就会像溢出的水一样被直接丢弃或者排队等待处理。比如说一个漏桶的容量设定为 100 个请求漏出的速率是每秒 10 个请求。当请求以每秒 20 个的速度涌入时桶会在 5 秒后被装满之后新来的请求就会被拒绝。只有当桶中的请求被不断处理有了空闲空间后新的请求才有可能进入桶中等待处理。漏桶算法的最大优点就是能够非常平滑地处理流量无论外界的请求流量如何波动它都能保证请求以固定的速率被处理就像漏斗里的水总是以稳定的速度流出一样这对于保护下游系统免受突发流量的冲击非常有效。但它也有明显的缺点那就是无法应对短暂的突发流量。即使系统在某个时刻非常空闲请求也只能按照固定的速率慢慢排队处理这在一些对响应时间要求较高的场景比如秒杀活动中可能会导致用户体验很差因为用户的请求可能需要长时间等待才能被处理。令牌桶算法令牌桶算法是目前互联网中应用最为广泛的限流算法它巧妙地在 “限制流量” 和 “允许突发” 之间找到了平衡。在这个算法中系统会以一个恒定的速率往桶里生成令牌每个令牌都可以看作是一个允许请求通过的 “许可证”。桶有一个固定的容量当令牌生成的数量达到桶的容量时新生成的令牌就会被丢弃。当请求到达时它必须先从桶中获取一个令牌如果桶中有足够的令牌请求就可以立即被处理如果桶中没有令牌了请求就会被拒绝或者等待直到有新的令牌生成。假设我们设定令牌桶的容量为 100 个令牌生成令牌的速率是每秒 10 个。如果在前 5 秒内没有请求到来那么桶中就会积攒 50 个令牌。这时突然来了 80 个请求由于桶中有足够的令牌这 80 个请求都可以立即被处理充分体现了它允许突发流量的特性。同时从长期来看因为令牌的生成速率是固定的所以它又能很好地限制平均流量防止系统被持续的高流量压垮。与漏桶算法相比令牌桶算法更加灵活它允许系统在有令牌储备的情况下快速处理突发的大量请求避免了像漏桶算法那样即使系统空闲也只能慢慢处理请求的尴尬非常适合大多数需要限制流量同时又要应对突发情况的业务场景比如 API 网关、电商平台的抢购接口等。在实际应用中Google 的 Guava 工具包为我们提供了成熟的令牌桶算法实现。通过使用 Guava 的 RateLimiter 类我们可以轻松地创建一个令牌桶实例并设置每秒生成的令牌数。例如RateLimiter limiter RateLimiter.create(10.0)表示创建一个每秒生成 10 个令牌的令牌桶。在处理请求时我们可以使用limiter.acquire()方法来尝试获取令牌如果获取成功则表示请求可以继续处理否则请求可能需要等待或者被拒绝这种简单易用的方式大大提高了我们在项目中实现限流功能的效率 。三、Spring Boot 实现网络限速全攻略一核心思路大揭秘在 Spring Boot 项目中实现网络限速我们可以借助 Spring AOP面向切面编程的强大能力结合令牌桶算法来达成目标。这就好比在一条高速公路上设置了多个收费站AOP 切面每个收费站都可以对过往的车辆请求进行检查看它们是否有足够的 “通行证”令牌以此来控制车辆的通行速度请求频率。具体来说我们会自定义一个注解比如RateLimit它就像是一个特殊的标识被添加到需要限速的接口方法上。当请求到达这些被标记的接口时Spring AOP 就会像一个敏锐的观察者立即捕获到这个请求并触发我们预先定义好的限速逻辑。而这个限速逻辑的核心就是基于令牌桶算法实现的。令牌桶算法就像是一个神奇的桶系统会以一个固定的速率往桶里放入令牌每个令牌代表着一次请求的许可。当请求到来时它必须从桶中获取一个令牌才能继续前进。如果桶里没有令牌了请求就会被拒绝或者等待直到有新的令牌被生成。通过这种方式我们可以有效地控制接口在单位时间内能够处理的请求数量从而实现网络限速的目的。二实现步骤详细拆解接下来我将详细介绍基于 Spring Boot AOP 思想使用令牌桶算法结合自定义注解实现网络限速的具体步骤每一步都配有相应的代码示例方便大家理解和实践。引入核心依赖首先在你的 Spring Boot 项目的pom.xml文件中引入以下核心依赖dependencies!-- Spring Boot Web核心依赖 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- AOP依赖用于拦截注解 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId/dependency!-- Lombok依赖简化代码如自动生成getter、setter、构造函数等 --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependency/dependenciesSpring Boot Web 依赖提供了构建 Web 应用所需的基本组件让我们能够轻松创建和管理 HTTP 接口。AOP 依赖则是实现注解拦截的关键它允许我们在不修改原有业务代码的基础上在方法执行前后、异常处理等阶段插入自定义逻辑。Lombok 依赖可以大大简化我们的代码编写工作减少样板代码的冗余提高开发效率。自定义限速注解在项目中创建一个新的注解类用于标记需要限速的接口方法。例如我们创建一个RateLimit注解packagecom.example.ratelimit.annotation;importjava.lang.annotation.*;/** * 网络限速注解添加在接口方法上即可实现限速 */Target({ElementType.METHOD})// 仅作用于方法Retention(RetentionPolicy.RUNTIME)// 运行时生效允许AOP反射获取注解信息Documented// 生成JavaDoc时包含该注解publicinterfaceRateLimit{/** * 每秒允许的请求数限速阈值默认10 */doublepermitsPerSecond()default10.0;/** * 限流后的提示信息默认“请求过于频繁请稍后再试” */Stringmessage()default请求过于频繁请稍后再试;/** * 限速唯一标识可选默认取请求接口的路径如/api/test支持SpEL表达式 * 示例#request.ip 按IP限速#user.id 按用户ID限速 */Stringkey()default;}这个注解包含了三个主要参数permitsPerSecond用于设置每秒允许的请求数也就是限速阈值默认值为 10message用于设置当请求被限流时返回给客户端的提示信息默认是 “请求过于频繁请稍后再试” key是一个可选参数用于指定限速的唯一标识默认情况下会取请求接口的路径。通过 SpEL 表达式我们可以实现更加灵活的限速策略比如按 IP 地址、用户 ID 等进行限速。实现令牌桶算法创建一个线程安全的令牌桶工具类用于管理令牌的生成和获取。下面是一个简单的实现示例packagecom.example.ratelimit.util;importlombok.extern.slf4j.Slf4j;importjava.util.concurrent.ConcurrentHashMap;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.atomic.AtomicLong;/** * 令牌桶工具类线程安全支持多标识独立限速 */Slf4jpublicclassTokenBucketUtil{/** * 存储不同标识对应的令牌桶key限速标识value令牌桶 */privatestaticfinalConcurrentHashMapString,TokenBucketTOKEN_BUCKET_MAPnewConcurrentHashMap();/** * 获取令牌非阻塞获取不到直接返回false * param key 限速标识 * param permitsPerSecond 每秒允许的请求数令牌生成速率 * return true获取令牌成功false限流 */publicstaticbooleantryAcquire(Stringkey,doublepermitsPerSecond){TokenBuckettokenBucketTOKEN_BUCKET_MAP.computeIfAbsent(key,k-newTokenBucket(permitsPerSecond));returntokenBucket.tryAcquire();}/** * 令牌桶内部类 */privatestaticclassTokenBucket{// 令牌桶的容量这里设置为100可根据实际情况调整privatestaticfinalintCAPACITY100;// 每秒生成的令牌数privatefinaldoublerate;// 当前可用的令牌数使用AtomicLong保证线程安全privatefinalAtomicLongtokensnewAtomicLong(CAPACITY);// 上次更新令牌的时间戳privatelonglastRefillTimeSystem.nanoTime();publicTokenBucket(doublerate){this.raterate;}publicbooleantryAcquire(){refill();returntokens.decrementAndGet()0;}privatevoidrefill(){longnowSystem.nanoTime();// 计算距离上次更新令牌的时间间隔单位为秒doubleelapsedTime(now-lastRefillTime)/1e9;// 根据时间间隔和生成速率计算新生成的令牌数doublenewTokenselapsedTime*rate;// 更新当前可用的令牌数确保不超过桶的容量tokens.addAndGet((long)Math.min(CAPACITY-tokens.get(),newTokens));// 更新上次更新令牌的时间戳lastRefillTimenow;}}}在这个工具类中我们使用了一个ConcurrentHashMap来存储不同标识对应的令牌桶这样可以支持多个接口或不同条件下的独立限速。TokenBucket内部类负责具体的令牌管理逻辑包括令牌的生成refill方法和获取tryAcquire方法。refill方法会根据当前时间和上次更新时间的差值计算出这段时间内应该生成的令牌数量并更新当前可用的令牌数。tryAcquire方法则会先调用refill方法补充令牌然后尝试获取一个令牌如果获取成功则返回true否则返回false表示请求被限流。AOP 拦截实现限速创建一个 AOP 切面类用于拦截添加了RateLimit注解的接口方法并进行限速判断。示例代码如下packagecom.example.ratelimit.aspect;importcom.example.ratelimit.annotation.RateLimit;importcom.example.ratelimit.util.TokenBucketUtil;importlombok.extern.slf4j.Slf4j;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.springframework.stereotype.Component;importorg.springframework.web.context.request.RequestContextHolder;importorg.springframework.web.context.request.ServletRequestAttributes;importjavax.servlet.http.HttpServletRequest;AspectComponentSlf4jpublicclassRateLimitAspect{Around(annotation(rateLimit))publicObjectcheckRateLimit(ProceedingJoinPointjoinPoint,RateLimitrateLimit)throwsThrowable{// 获取当前请求对象ServletRequestAttributesattributes(ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();HttpServletRequestrequestattributes.getRequest();// 获取限速标识如果未设置则使用请求接口路径StringkeyrateLimit.key().isEmpty()?request.getRequestURI():rateLimit.key();// 从令牌桶中获取令牌判断是否超过限速if(!TokenBucketUtil.tryAcquire(key,rateLimit.permitsPerSecond())){log.warn(请求被限流接口: {}, 提示信息: {},request.getRequestURI(),rateLimit.message());returnrateLimit.message();}// 如果获取令牌成功继续执行接口方法returnjoinPoint.proceed();}}在这个切面类中我们使用Around注解定义了一个环绕通知它会拦截所有添加了RateLimit注解的方法。在通知方法中首先获取当前的 HTTP 请求对象然后根据注解中设置的key值或请求接口路径作为限速标识从令牌桶工具类中尝试获取令牌。如果获取令牌失败说明请求超过了限速阈值记录一条警告日志并返回预先设置的限流提示信息给客户端如果获取令牌成功则调用joinPoint.proceed()方法继续执行被拦截的接口方法让请求正常通过。四、配置说明与参数调整在使用RateLimit注解进行网络限速时合理配置注解中的参数以及调整令牌桶的相关参数至关重要这直接关系到限速策略是否能够精准地满足业务需求。注解参数配置permitsPerSecond限速阈值这个参数设置了每秒允许通过的请求数量它是限速的核心指标。在实际应用中需要根据接口的业务特性和服务器的承载能力来精确设定。比如对于一个简单的查询接口假设服务器每秒能够轻松处理 100 次请求且该接口的使用频率相对稳定没有明显的突发流量那么可以将permitsPerSecond设置为 100 。但如果是一个涉及复杂业务逻辑和数据库操作的接口或者服务器资源有限可能就需要将这个值设置得低一些比如 20 - 50以防止过多请求导致服务器负载过高。message限流提示信息当请求被限流时这个参数定义了返回给客户端的提示信息。清晰、友好的提示信息能够帮助用户理解为什么请求失败并引导他们采取正确的操作。例如“您的请求过于频繁请稍后再试。给您带来不便敬请谅解” 这样的信息既明确告知用户请求被限流又表达了对用户的歉意有助于提升用户体验。在国际化的项目中还可以考虑根据不同的语言环境返回不同的提示信息以满足全球用户的需求。key限速唯一标识此参数用于指定限速的唯一标识默认情况下会使用请求接口的路径。通过使用 SpEL 表达式我们可以实现更加灵活的限速策略。如果想要按 IP 地址对请求进行限速可以将key设置为#request.remoteAddr。这样来自不同 IP 的请求就会被独立统计和限速防止某个恶意 IP 通过大量请求耗尽服务器资源。如果是一个多用户的系统希望按用户 ID 进行限速以保证每个用户的公平访问可以将key设置为#user.id其中#user是 Spring 上下文里的用户对象。在一些复杂的业务场景中还可以结合多个因素来生成唯一标识比如#request.remoteAddr _ #user.id实现按 IP 和用户 ID 双重维度的限速。令牌桶参数调整桶容量capacity在我们之前实现的令牌桶工具类中桶容量被硬编码为 100 但在实际应用中这是一个需要根据业务场景灵活调整的重要参数。桶容量决定了系统能够承受的突发流量大小。如果一个电商平台举办限时秒杀活动在活动开始的瞬间可能会有大量用户同时发起请求这时就需要一个较大的桶容量来应对突发流量。假设我们预计活动开始时每秒的请求峰值可能达到 500为了保证在短时间内大部分请求能够被正常处理就可以将桶容量设置为 500 或更高。相反如果是一个对稳定性要求极高不希望出现任何突发流量冲击的系统比如银行的核心交易系统桶容量就可以设置得相对较小以确保流量始终保持平稳。令牌生成速率rate这个参数与RateLimit注解中的permitsPerSecond相对应它决定了令牌桶中令牌的生成速度也就是系统允许的平均请求处理速率。如果一个视频直播平台为了保证所有用户都能流畅观看直播需要限制每个用户对直播流接口的请求频率防止个别用户占用过多带宽。假设平台规定每个用户每秒最多只能请求直播流数据 5 次那么令牌生成速率就可以设置为 5 。在实际调整时还需要考虑系统的资源利用率和业务的实时性要求。如果将令牌生成速率设置得过低虽然能够有效限制流量但可能会导致用户请求处理不及时影响用户体验而设置得过高则可能无法达到限流的目的使系统面临过载的风险。调整策略在系统运行过程中业务场景可能会发生变化比如电商平台在不同的促销活动期间用户的访问量和行为模式会有很大差异或者随着业务的增长系统的负载能力也会发生变化。因此需要建立一套动态调整令牌桶参数的机制。可以通过监控系统实时收集接口的请求数据包括请求频率、响应时间、服务器资源利用率等指标。当发现接口的请求频率持续超过设定的限速阈值且服务器资源利用率过高时说明当前的限速策略可能过于宽松需要适当降低令牌生成速率或减小桶容量反之如果接口的请求频率远低于限速阈值且服务器资源有大量空闲就可以考虑提高令牌生成速率或增大桶容量以充分利用系统资源提升服务的吞吐量。还可以结合机器学习算法根据历史数据和实时监控信息自动预测业务流量的变化趋势从而更加智能地调整令牌桶参数 。五、测试验证与效果展示为了验证我们在 Spring Boot 中实现的网络限速功能是否有效接下来将使用 Postman 工具进行详细的测试并直观地展示测试结果。测试准备启动 Spring Boot 应用确保按照前面步骤实现的 Spring Boot 项目已经成功启动监听的端口为默认的 8080如果有修改请根据实际情况调整。配置测试接口在控制器类中添加一个简单的测试接口并使用RateLimit注解进行限速配置。例如importcom.example.ratelimit.annotation.RateLimit;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;RestControllerpublicclassTestController{RateLimit(permitsPerSecond5,message请求过于频繁请稍后再试,key#request.remoteAddr)GetMapping(/test)publicStringtest(){return测试接口访问成功;}}这里将/test接口的限速阈值设置为每秒 5 次限流提示信息为 “请求过于频繁请稍后再试”并按请求的 IP 地址进行限速以确保不同 IP 的访问相互独立。测试过程正常请求测试打开 Postman发送 GET 请求到http://localhost:8080/test。在短时间内连续发送 5 次请求可以观察到每次请求都能正常返回 “测试接口访问成功”说明在限速阈值范围内请求能够顺利通过。限速测试紧接着快速连续发送超过 5 次请求例如发送 10 次。从第 6 次请求开始Postman 返回的响应内容为 “请求过于频繁请稍后再试”这表明当请求频率超过每秒 5 次的限速阈值时限速功能生效后续请求被成功拦截并返回了预先设置的限流提示信息。多 IP 测试验证按 IP 限速使用不同的 IP 地址可以通过修改本地代理或者在不同网络环境下测试分别对/test接口进行请求。可以发现每个 IP 都有独立的限速计数互不影响。例如IP1 在短时间内发送超过 5 次请求后被限速但 IP2 仍然可以正常发送请求直到其自身的请求次数也超过限速阈值进一步验证了按 IP 地址限速的有效性。测试结果展示正常请求响应{响应状态码:200,响应内容:测试接口访问成功}限速响应{响应状态码:200,响应内容:请求过于频繁请稍后再试}通过以上测试过程和结果展示可以清晰地看到我们基于 Spring Boot AOP 令牌桶算法实现的网络限速功能运行正常能够准确地按照设定的限速策略对接口请求进行限制有效保护系统免受过高流量的冲击 确保了系统在高并发场景下的稳定性和可靠性。在实际应用中你可以根据业务需求灵活调整限速注解的参数以适应不同接口和场景的限速要求。六、总结与拓展在今天的分享中我们深入探讨了 Spring Boot 中实现网络限速的重要性、常见策略以及基于 AOP 和令牌桶算法的具体实现方案。通过合理配置注解参数和调整令牌桶参数我们能够精准地控制接口的访问频率有效抵御恶意攻击、应对流量峰值并保护核心资源。测试结果也充分验证了该方案的有效性和可靠性。在未来的拓展方向上我们可以进一步优化令牌桶算法的实现提高其性能和效率。可以考虑引入分布式缓存如 Redis来存储令牌桶的状态实现分布式环境下的统一限速管理以适应微服务架构和大规模集群的需求。还可以结合实时监控和动态调整机制根据系统的实时负载和业务需求自动调整限速策略使系统能够更加智能、灵活地应对各种复杂的网络情况。希望本文能为大家在 Spring Boot 项目中实现网络限速提供有益的参考和帮助。如果你们在实践过程中有任何问题或想法欢迎在留言区分享交流让我们共同进步打造更加稳定、高效的网络服务 。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…