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

怎么免费制作网站辽宁建设工程信息网抚顺

怎么免费制作网站,辽宁建设工程信息网抚顺,沈阳网站建设找世纪兴,网站建设难么✅ 使用 Redis 记录 所有用户的实时并发下载数✅ 使用 Bucket4j 实现 全局下载速率限制(动态)✅ 支持 动态调整限速策略✅ 下载接口安全、稳定、可监控 🧩 整体架构概览 模块功能Redis存储全局并发数和带宽令牌桶状态Bucket4j Redis分布式限…
  • ✅ 使用 Redis 记录 所有用户的实时并发下载数
  • ✅ 使用 Bucket4j 实现 全局下载速率限制(动态)
  • ✅ 支持 动态调整限速策略
  • ✅ 下载接口安全、稳定、可监控

🧩 整体架构概览

模块功能
Redis存储全局并发数和带宽令牌桶状态
Bucket4j + Redis分布式限速器(基于令牌桶算法)
Spring Boot Web提供文件下载接口
AOP / Interceptor(可选)用于统一处理限流逻辑

📦 1. Maven 依赖(pom.xml

<dependencies><!-- Spring Boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Redis 连接池 --><dependency><groupId>io.lettuce.core</groupId><artifactId>lettuce-core</artifactId></dependency><!-- Bucket4j 核心与 Redis 集成 --><dependency><groupId>com.github.vladimir-bukhtoyarov</groupId><artifactId>bucket4j-core</artifactId><version>5.3.0</version></dependency><dependency><groupId>com.github.vladimir-bukhtoyarov</groupId><artifactId>bucket4j-redis</artifactId><version>5.3.0</version></dependency></dependencies>

🛠️ 2. Redis 工具类:记录全局并发数

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;import java.util.Collections;
import java.util.concurrent.TimeUnit;@Component
public class GlobalDownloadCounter {private final StringRedisTemplate redisTemplate;private final DefaultRedisScript<Long> incrScript;private final DefaultRedisScript<Long> decrScript;public static final String KEY_CONCURRENT = "global:download:concurrent";private static final long TTL_SECONDS = 60; // 自动清理僵尸计数public GlobalDownloadCounter(StringRedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;// Lua 脚本:原子增加并发数并设置过期时间String scriptIncr = """local key = KEYS[1]local ttl = tonumber(ARGV[1])local count = redis.call('GET', key)if not count thenredis.call('SET', key, 1)redis.call('EXPIRE', key, ttl)return 1elsecount = tonumber(count) + 1redis.call('SET', key, count)redis.call('EXPIRE', key, ttl)return countend""";incrScript = new DefaultRedisScript<>(scriptIncr, Long.class);// Lua 脚本:原子减少并发数String scriptDecr = """local key = KEYS[1]local count = redis.call('GET', key)if not count or tonumber(count) <= 0 thenreturn 0elsecount = tonumber(count) - 1redis.call('SET', key, count)return countend""";decrScript = new DefaultRedisScript<>(scriptDecr, Long.class);}public long increment() {return redisTemplate.execute(incrScript, Collections.singletonList(KEY_CONCURRENT), TTL_SECONDS).longValue();}public long decrement() {return redisTemplate.execute(decrScript, Collections.singletonList(KEY_CONCURRENT)).longValue();}public long getCurrentCount() {String value = redisTemplate.opsForValue().get(KEY_CONCURRENT);return value == null ? 0 : Long.parseLong(value);}
}

⚙️ 3. Bucket4j 配置:分布式限速器(带 Redis)

import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Refill;
import io.github.bucket4j.distributed.proxy.ProxyManager;
import io.github.bucket4j.distributed.proxy.RedisProxyManager;
import io.github.bucket4j.redis.lettuce.cas.LettuceReactiveProxyManager;
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.time.Duration;@Configuration
public class BandwidthLimiterConfig {@Beanpublic RedisClient redisClient() {return RedisClient.create("redis://localhost:6379");}@Beanpublic StatefulRedisConnection<String, String> redisConnection(RedisClient redisClient) {return redisClient.connect();}@Beanpublic ProxyManager<String> proxyManager(StatefulRedisConnection<String, String> connection) {return LettuceReactiveProxyManager.builder().build(connection.reactive());}@Beanpublic Bandwidth globalBandwidthLimit() {// 默认 10MB/sreturn Bandwidth.classic(10 * 1024 * 1024, Refill.greedy(10 * 1024 * 1024, Duration.ofSeconds(1)));}@Beanpublic Bucket globalBandwidthLimiter(ProxyManager<String> proxyManager, Bandwidth bandwidthLimit) {return proxyManager.builder().build("global:bandwidth:limiter", bandwidthLimit);}
}

📡 4. 下载接口实现

import io.github.bucket4j.Bucket;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;@RestController
@RequestMapping("/api/download")
public class DownloadController {private static final int MAX_CONCURRENT_DOWNLOADS = 100;private final GlobalDownloadCounter downloadCounter;private final Bucket bandwidthLimiter;public DownloadController(GlobalDownloadCounter downloadCounter, Bucket bandwidthLimiter) {this.downloadCounter = downloadCounter;this.bandwidthLimiter = bandwidthLimiter;}@GetMapping("/{fileId}")public void downloadFile(@PathVariable String fileId, HttpServletResponse response) throws IOException {long currentCount = downloadCounter.getCurrentCount();if (currentCount >= MAX_CONCURRENT_DOWNLOADS) {response.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);response.getWriter().write("Too many downloads. Please try again later.");return;}downloadCounter.increment();try {// 设置响应头response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment; filename=" + fileId + ".bin");ServletOutputStream out = response.getOutputStream();// 文件路径(示例)String filePath = "/path/to/files/" + fileId + ".bin";if (!Files.exists(Paths.get(filePath))) {response.setStatus(HttpServletResponse.SC_NOT_FOUND);response.getWriter().write("File not found.");return;}byte[] buffer = new byte[8192]; // 每次读取 8KBRandomAccessFile file = new RandomAccessFile(filePath, "r");int bytesRead;while ((bytesRead = file.read(buffer)) != -1) {if (bytesRead > 0) {boolean consumed = bandwidthLimiter.tryConsume(bytesRead);if (!consumed) {Thread.sleep(100); // 等待令牌生成continue;}out.write(buffer, 0, bytesRead);out.flush();}}file.close();out.close();} catch (InterruptedException e) {Thread.currentThread().interrupt(); // 恢复中断状态} finally {downloadCounter.decrement();}}
}

🔁 5. 动态调整下载速率接口(可选)

@RestController
@RequestMapping("/api/limit")
public class RateLimitController {private final Bucket bandwidthLimiter;private final Bandwidth globalBandwidthLimit;public RateLimitController(Bucket bandwidthLimiter, Bandwidth globalBandwidthLimit) {this.bandwidthLimiter = bandwidthLimiter;this.globalBandwidthLimit = globalBandwidthLimit;}@PostMapping("/set-bandwidth")public String setBandwidth(@RequestParam int mbPerSecond) {Bandwidth newLimit = Bandwidth.classic(mbPerSecond * 1024 * 1024,Refill.greedy(mbPerSecond * 1024 * 1024, Duration.ofSeconds(1)));bandwidthLimiter.replaceConfiguration(newLimit);return "Global bandwidth limit updated to " + mbPerSecond + " MB/s";}
}

📊 6. 监控接口(可选)

@GetMapping("/monitor/concurrent")
public ResponseEntity<Long> getConcurrentDownloads() {return ResponseEntity.ok(downloadCounter.getCurrentCount());
}

🧪 7. 测试建议

你可以使用 curl 或 Postman 发起多并发请求测试:

for i in {1..200}; docurl -X GET "http://localhost:8080/api/download/file1" --output "file$i.bin" &
done

观察是否触发限流、并发控制是否生效。


✅ 总结

组件作用
Redis分布式存储并发数和限流令牌桶
Lua 脚本原子操作并发计数器
Bucket4j + Redis全局下载速率限制
Spring Boot Controller处理下载逻辑
try-finally保证资源释放
动态接口 /set-bandwidth支持运行时修改限速

📌 扩展建议(可选)

  • 将限流逻辑封装到 AOP 切面
  • 添加 Prometheus 指标暴露并发数、限流次数等
  • 使用 Nginx 或 Gateway 做额外的限流保护
  • 加入用户身份识别,支持 用户级限速
  • 使用 Kafka 异步记录日志或审计下载行为


文章转载自:

http://mVlysV07.njfgL.cn
http://04hvq1az.njfgL.cn
http://HmpBLlkk.njfgL.cn
http://5zHfl6Tv.njfgL.cn
http://OSonu6fP.njfgL.cn
http://G4BJdgEK.njfgL.cn
http://GqCKDit8.njfgL.cn
http://ZYUC1yDs.njfgL.cn
http://Uxf6FLTh.njfgL.cn
http://vS9cykKS.njfgL.cn
http://dBUSLLqO.njfgL.cn
http://ZsFiG6Vu.njfgL.cn
http://6mHSGvak.njfgL.cn
http://6JKfxiGg.njfgL.cn
http://dj1WUFro.njfgL.cn
http://4KyFjxfX.njfgL.cn
http://wCiIf5z1.njfgL.cn
http://iZEqH4vp.njfgL.cn
http://vQjgu3v8.njfgL.cn
http://oO7qYCj2.njfgL.cn
http://7YgWLamo.njfgL.cn
http://sGFNN1bs.njfgL.cn
http://hVFKqZiN.njfgL.cn
http://vMT8BKEF.njfgL.cn
http://MHm6m6LT.njfgL.cn
http://GqGna4NW.njfgL.cn
http://eIGjwo6z.njfgL.cn
http://vXZenLdR.njfgL.cn
http://zsZqCdfb.njfgL.cn
http://tYHVohPT.njfgL.cn
http://www.dtcms.com/wzjs/775115.html

相关文章:

  • 网站建设费用高微信做兼职什么网站好
  • 色块网站国外网站注册
  • 企业网站策划书范文3000字网件路由器r7000
  • 找南阳建立网站的公司梅县区建设工程交易中心网站
  • 成都手机微信网站建设报价朋友叫我去柬埔寨做彩票网站推广
  • 二度云自助建站系统简单网站建设策划书范文
  • php网站开发试题网页美工设计参考文献
  • 设置一个网站到期页面帮网贷做网站会判刑吗
  • 长乐住房和城乡建设局网站怎么自己做游戏
  • 长春网站建设新格搜索排名优化
  • 网站内如何做论坛建设网站协议范本
  • 做网站公司徐汇wordpress 一直加载插件
  • 集团门户网站建设不足长沙市宁乡县建设局网站
  • 建设实木餐桌椅移动网站玖玖玖人力资源有限公司
  • 做二手车的网站有哪些免费源码分享论坛
  • 广州外贸营销型网站建设公司百度一下百度搜索首页
  • 网站悬浮窗口wordpress 多主题共存
  • 优必选网站建设银行网站信任
  • 艺术签名设计免费版上海seo推广服务
  • 哈尔滨建站在线查网站的ip地址
  • 网站能自己做吗有没有免费网站制作
  • 迪庆网站建设星子网房产租房
  • 惠州做公司网站中国网新山东
  • 网站建设公司账户搭建珠海商城
  • 网站手机版怎么弄网站建设 昆明 价格
  • 网站关键词整体方案汽车之家官网网页版
  • 360网站做不了网银怎么办设计之窗
  • 现代建设中国公司网站wordpress安装不了插件吗
  • 网站已运行时间代码网络营销服务公司有哪些
  • 精品课程网站的建设如何推广自己网站