yz-bijini-cosplay企业应用案例:ACG内容工作室批量生成Cosplay角色图方案

核心内容摘要

避坑指南:Visual Studio调试Docker容器时最常见的7个报错解决方案
韩国国民搜索 NAVER:使用 JuiceFS 打通 Hadoop 与 Kubernetes 存储实践

毕业设计美食探店系统效率提升实战:从单体架构到高并发优化

恶意用户黑客、爬虫、DDoS攻击者可能会频繁请求服务器资源导致资源占用过高我们可以通过IP封禁拉进黑名单手段阻止恶意或可疑用户减少攻击风险。

自主实现动态 IP 黑名单的考虑要点

IP黑名单存储在哪里

如何便捷地动态修改 IP 黑名单?

黑白名单的判断逻辑应在哪里处理?

使用何种数据结构保存黑名单如何快速匹配用户请求的 IP 是否在黑名单中?1IP 黑名单存储在哪里?最简单的方式就是存储在内存中但一般IP 黑名单是动态增加的、需要持久化保存。

常见的持久化方式包括数据库、配置文件或分布式存储系统(如 Redis)可以根据需要选择。

2如何便捷地动态修改I 黑名单?为了方便动态修改 IP 黑名单通常会提供一个管理页面供管理员进行增删改查操作。

许多企业会将配置统一放入 配置中心通过配置中心的管理页面开发人员可以便捷地动态修改黑名单规则。

Java项目中常用的配置中心是 Nacos。

3黑白名单的判断逻辑应在哪里处理?黑白名单逻辑通常部署在高性能的网关或 CDN 上能够更早地拦截非法请求减轻后端压力。

在小型项目中也可以直接在应用程序的过滤器中处理。

4使用何种结构保存黑名单如何快速匹配?为了高效判断每个用户请求的IP 是否在黑名单中首先建议将 IP 黑名单从持久化存储同步到本地缓存中避免频繁查询远程数据源。

对于黑名单数据较小的场景可以使用简单的 set 数据结构存储。

而对于大规模黑名单推荐使用 布隆过滤器或 DFA 来存储和过滤黑名单可以节约内存空间、提高检测效率。

总结一下最终方案:1使用 Nacos 配置中心存储和管理 IP 黑名单2后端服务利用 Web 过滤器判断每个用户请求的 IP3后端服务利用布降过滤器过滤 IP 黑名单布隆过滤器Bloom Filter 是一种高效的、基于概率的数据结构用于判断一个元素是否存在于集合中。

原理是利用多个哈希函数将元素映射到固定的点位上(位数组中)因此面对海量数据它占据的空间也非常小。

例如某个 key 通过 hash-1 和 hash-2 两个哈希函数定位到数组中的值都为 1则说明它存在。

如果布隆过滤器判断一个元素不存在集合中那么这个元素一定不在集合中如果判断元素存在集合中则不一定是真的因为哈希可能会存在冲突。

因此布降过滤器 有误判的概率。

而且它不好删除元素只能新增如果想要删除只能重建。

它的主要特点包括:

空间效率高相比于传统的数据结构(如哈希表)Bloom Filter 能用较少的空间存储大量的数据。

时间复杂度低查询操作非常快速通常是常数时间复杂度 0(

允许误判Bloom Filter 允许假阳性即有时候会错误地判断某个元素在集合中而实际该元素并不在集合中。

不过它不允许假阴性也就是说如果 Bloom Filter 判断某个元素不存在那么它一定是不存在的。

比如对于我们的需求Bloom Filter 可能错误地判断一个不在黑名单中的元素为在黑名单中导致误封。

Bloom Filter 的误判率与以下因素有关:位数组的大小:位数组越大误判率越低但空间开销会增大。

(值会更离散)。

哈希函数的个数:哈希函数越多误判率越低但计算成本会增加。

(Hash 一次冲突那我就多 Hash 几次减少冲突概率)元素数量:存入的元素越多误判率会增加。

通过 合理设计位数组的大小和哈希函数的个数可以控制 Bloom Filter 的误判率在一个可接受的范围内。

例如在很多实际场景中可以将误判率控制在 1%或更低。

假设场景 1:存储 1000 个元素位数组大小为 10000 位哈希函数数量为 7。

误判率大约为

8%。

假设场景 2:存储 100000 个元素位数组大小为 1,000,000 位哈希函数数量为 7。

误判率大约为 1%。

如果误判的代价较高但仍想使用 Bloom Filter可以采取一些补救措施

双层验证:在 Bloom filter 判断元素在黑名单中后进一步查验实际的黑名单(例如查数据库中的黑名单详细记录)。

结合其他数据结构:可以使用 Bloom filter 进行初步筛选如果 Bloom filter 判断为在黑名单中再用哈希表等精确的数据结构进行最终确认。

但这两种方式都无法处理攻击 IP 的大量请求个人也不建议采用。

因此布降过滤器适用于对准确性要求不高的、大规模数据量匹配的场景比如垃圾邮件过滤、爬虫 URL 去重。

缓存穿透防护等。

配置中心为什么需要配置中心在分布式系统中应用的配置管理变得越来越复杂特别是当系统规模和组件数量增加时。

传统的手动配置(写固定配置文件)往往难以应对这些复杂的需求。

而配置中心的出现就是为了实现分布式系统中配置的 **集中化管理**还提供动态更新、配置分组、版本控制、灰度发布、安全管理简化了多环境和多实例的配置运维确保系统的灵活性和稳定性。

一句话专业的技术做专业的事。

配置中心支持的功能1集中化配置管理:所有服务的配置可以在一个地方集中管理运维人员和开发人员可以通过统一的接口修改和获取配置避免了在每个实例中重复配置。

2动态配置:配置中心允许在不重启应用的情况下动态更新配置应用可以实时收到配置的修改进行运行时的调整。

3多环境配置管理:配置中心可以为不同的环境配置不同的配置集按需加载相应的环境配置文件避免了环境间配置的混淆和出错。

4配置的版本控制:配置中心一般都会提供版本管理功能可以查看和回滚到之前的配置版本这提高了系统的容错性和可恢复性。

5配置的安全管理:配置中心一般会提供加密存储和权限控制功能可以对敏感信息(如数据库密码、API密钥等)进行加密处理并限制访问权限确保敏感配置信息的安全性。

常见的配置中心1Spring Cloud Configspring Cloud 提供的配置中心解决方案支持 Git 等版本管理系统存储配置适合与 Spring Cloud 系统集成使用。

2Nacos阿里巴巴开源的服务注册中心和配置中心支持动态配置、服务治理适合微服务架构和 Dubbo、Spring Cloud 的深度集成。

3Apollo由携程开源的配置中心支持多环境、多集群的配置管理配置实时生效且具有权限控制适合大规模分布式系统。

4Consul由 Hashicorp 提供的服务注册与配置中心具有强一致性和健康检查功能适用于服务网格和容器化应用。

一般业务上我们会选择使用 Nacos 或 Apolo 来作为配置中心因为这两个提供了比较丰富的控制台管理页面便于我们修改维护配置。

本项目采用Nacos作为配置中心的实现。

什么是NacosNacos 是 Dynamic Naming and Configuration Service 的首字母简称一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

它提供了一组简单易用的特性集帮助我们快速实现动态服务发现、服务配置、服务元数据及流量管理。

实际上Nacos 不仅支持配置管理它还支持服务发现(作为注册中心)。

Nacos 配置管理的核心概念

Namespace(命名空间)命名空间用于隔离不同的配置集。

它允许在同一个 Nacos 集群中将不同的环境(如开发、测试、生产)或者不同的业务线的配置进行隔离。

(默认提供了一个 public 命名空间)使用场景:在多租户系统中或者需要区分不同的环境时可以使用命名空间。

例如开发环境的配置和生产环境的配置完全隔离可以通过不同的命名空间来管理。

Group(组)配置组是用于将多个相关的配置项进行分类管理的逻辑分组机制。

每个配置项可以属于不同的组以便于配置管理。

使用场景:当一个应用有多个模块且不同模块之间共享部分配置时可以用组来对这些模块的配置进行分类和管理。

例如一个系统中的“支付服务”和“订单服务可能需要用不同的组来存储各自的配置。

Data lDData ID 是一个唯一的配置标识符通常与具体的应用程序相关。

通过 DataIDNacos 知道如何获取特定应用的某个具体配置。

使用场景:每个应用的配置都会有一个独特的 DataID。

例如一个支付系统可能有一个配置文件叫 com.payment.pay-service.yaml 这就是它的 Data lD。

Config Listener(配置监听器)配置监听器用于让客户端实时监听 Nacos 配置中心中的配置变化可以自动感知配置的更新并做出相应的处理。

使用场景:在需要动态调整配置的场景下使用例如调整缓存大小、切换不同的服务端点等应用可以通过监听器及时感知这些变化并应用新的配置。

后端开发基于Nacos实现动态IP黑名单过滤在官方中下载Nacos Server对应版本的应用包此处使用和Sentinel兼容的

2.

0版本不要用别的版本不然出现不兼容不好解决。

下载压缩包后进行解压然后在解压后的文件的bin目录下cmd输入startup.cmd -m standalone命令来启动Nacos Serverstandalone代表单机模式运行非集群模式。

如果报找不到Java那就去配jdk8环境变量、JAVA_HOME。

启动后就可以去访问nacos控制台了http://

127.

0.

1:8848/nacos默认用户名和密码都是nacos。

我们可以通过控制台创建配置填写Ddata IDzhimianguanGroup有默认的也可以自行修改配置格式推荐YAML格式配置内容填写黑名单如下blackIpList:-

1.

1.

1-

2.

2.

2然后点击发布即可。

接着给我们的项目引入Nacos依赖dependency groupIdcom.alibaba.boot/groupId artifactIdnacos-config-spring-boot-starter/artifactId version

0.

12/version /dependency在application.yml文件中添加nacos server地址等配置# nacos配置中心 nacos: config: server-addr:

127.

0.

1:8848 # nacos 地址 bootstrap: enable: true # 预加载 >可以用 Hutool 或 Guava 库自带的 bloomfilter参考文章如果是分布式还可以考虑 Redisson。

此处由于项目已经使用了 Hutool 工具库就用其自带的 BitMapBloomfilter 即可。

下面我们来在项目中创建黑名单过滤的工具类首先新建一个blackfilter包然后在包下创建一个BlackIpUtils类代码如下/** * 黑名单过滤工具类 */ Slf4j public class BlackIpUtils { private static BitMapBloomFilter bloomFilter; // 判断 ip 是否在黑名单内 public static boolean isBlackIp(String ip) { return bloomFilter.contains(ip); } // 重建 ip 黑名单 public static void rebuildBlackIp(String configInfo) { if (StrUtil.isBlank(configInfo)) { configInfo {}; } // 解析 yaml 文件 Yaml yaml new Yaml(); Map map yaml.loadAs(configInfo, Map.class); // 获取 ip 黑名单 ListString blackIpList (ListString) map.get(blackIpList); // 加锁防止并发 synchronized (BlackIpUtils.class) { if (CollectionUtil.isNotEmpty(blackIpList)) { // 注意构造参数的设置 BitMapBloomFilter bitMapBloomFilter new BitMapBloomFilter(

; for (String ip : blackIpList) { bitMapBloomFilter.add(ip); } bloomFilter bitMapBloomFilter; } else { bloomFilter new BitMapBloomFilter(

; } } } }注意因为 Nacos 配置文件的监听的粒度比较粗只能知晓配置有变更无法知晓是新增、删除还是修改因此不论是选择布降过滤器还是 Hashset 最方便的处理逻辑就是重建。

接着来写一个Nacos监听类在blackfilter包下新建一个NacosListener类代码如下/** * nacos 监听器 */ Slf4j Component public class NacosListener implements InitializingBean { NacosInjected private ConfigService configService; Value(${nacos.config.data-id}) private String dataId; Value(${nacos.config.group}) private String group; Override public void afterPropertiesSet() throws Exception { log.info(nacos 监听器启动); String config configService.getConfigAndSignListener(dataId, group, 3000L, new Listener() { final ThreadFactory threadFactory new ThreadFactory() { private final AtomicInteger poolNumber new AtomicInteger(

; Override public Thread newThread(NotNull Runnable r) { Thread thread new Thread(r); thread.setName(refresh-ThreadPool poolNumber.getAndIncrement()); return thread; } }; final ExecutorService executorService Executors.newFixedThreadPool(1, threadFactory); // 通过线程池异步处理黑名单变化的逻辑 Override public Executor getExecutor() { return executorService; } // 监听后续黑名单变化 Override public void receiveConfigInfo(String configInfo) { log.info(监听到配置信息变化{}, configInfo); BlackIpUtils.rebuildBlackIp(configInfo); } }); // 初始化黑名单 BlackIpUtils.rebuildBlackIp(config); } }然后在blackfilter包下新建一个黑名单过滤过滤器BlackIpFilter类代码如下/** * 黑名单过滤器 */ WebFilter(urlPatterns /*, filterName blackIpFilter) public class BlackIpFilter implements Filter { Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { String ipAddress NetUtils.getIpAddress((HttpServletRequest) servletRequest); if (BlackIpUtils.isBlackIp(ipAddress)) { servletResponse.setContentType(text/json;charsetUTF-

; servletResponse.getWriter().write({\errorCode\:\-1\,\errorMsg\:\黑名单IP禁止访问\}); return; } filterChain.doFilter(servletRequest, servletResponse); } }黑名单应该对所有请求生效(不止是Controller 的接口)所以基于 Webfilter 实现而不是 AOP 切面。

Webfilter的优先级高于 Aspect 切面因为它在整个 Web 请求生命周期中更早进行处理。

请求进入时的顺序WebFilter首先WebFilter 拦截 HTTP 请求并可以根据逻辑决定是否继续执行请求。

Spring AOP 切面(Aspect):如果请求经过过滤器并进入 Spring 管理的 Bean(例如 Controller 层)此时切面生效对匹配的 Bean 方法进行拦截。

Controller 层:如果 Aspect 没有阻止执行最终请求到达 Controller 或 RestController 的方法。

然后我们需要在启动类上添加ServletComponentScan注解才能让过滤器被扫描到。

最后我们启动项目后可以进行测试在nacos控制台修改ip配置本地测试的话加入本机的ip后如下blackIpList:-

1.

1.

1-

2.

2.

2- 0:0:0:0:0:0:0:1然后我们通过swagger接口文档随便发个请求都会显示黑名单IP禁止访问。

注意如果你关机了每次本地启动项目前都要先通过命令启动nacos在nacos的bin目录下输入startup.cmd -m standalone来启动。

夜深人不静免费看高清-夜深人不静免费看高清应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123