Java NIO服务端IP黑名单过滤应在OP_ACCEPT或首次读取时获取远程地址并检查,命中则关闭通道;推荐使用ConcurrentHashMap<String, Boolean>实现线程安全的O(1)查询。

在 Java NIO 服务端(如基于 Selector + ServerSocketChannel + SocketChannel 实现的自定义服务器)中实现基于 IP 的黑名单过滤,核心思路是:在客户端连接建立(OP_ACCEPT)或首次读取数据时,获取其远程地址,检查是否在黑名单中;若命中,则直接关闭通道,不分配缓冲区、不注册读事件、不进入后续业务处理流程。
1. 黑名单数据结构选型与线程安全
黑名单需支持快速查询(O(1) 或 O(log n)),且可能被多个 IO 线程(如单 Selector 多线程模型下)并发访问。推荐:
-
使用
ConcurrentHashMap<String, Boolean>:IP 字符串为 key(如"192.168.1.100"),value 可固定为Boolean.TRUE,仅作存在性判断;插入/删除/查询均为线程安全,性能好; - 避免用
HashSet+synchronized:锁粒度大,影响高并发吞吐; - 若黑名单极小(Collections.unmodifiableSet(new HashSet(...)) 配合定期重建,但不推荐动态场景。
2. 在 accept 阶段拦截非法 IP
这是最高效的位置——连接刚建立、尚未分配资源(如 ByteBuffer、业务上下文),立即拒绝可节省内存和 CPU。
示例关键代码片段:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
// 在处理 OP_ACCEPT 事件时
if ((key.readyOps() & SelectionKey.OP_ACCEPT) != 0) {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel clientChannel = serverChannel.accept();
clientChannel.configureBlocking(false);
// ✅ 获取客户端 IP(注意:IPv6 地址需规范化,如转为无缩写形式)
String remoteIp = clientChannel.getRemoteAddress()
.getAddress().getHostAddress();
// ✅ 检查黑名单
if (blacklistMap.containsKey(remoteIp)) {
clientChannel.close(); // 直接关闭,不注册任何事件
continue;
}
// 合法 IP:注册 OP_READ,绑定附件等
clientChannel.register(selector, SelectionKey.OP_READ, new ConnectionContext());
}
3. 支持动态增删与持久化(可选增强)
生产环境通常需要运行时管理黑名单(如通过 HTTP 接口、配置中心或本地文件监听):
- 提供线程安全的增删方法:
addBlacklistedIp(String ip)/removeBlacklistedIp(String ip),内部调用blacklistMap.put(ip, true)/blacklistMap.remove(ip); - 若需重启不丢失,可将黑名单存于本地文件(如 JSON 或每行一个 IP),启动时加载,配合
WatchService监听文件变更并热更新; - 注意:IP 格式统一(如 IPv4 不带端口、IPv6 去掉方括号、标准化压缩写法),建议封装工具方法预处理再存入 map。
4. 补充说明:为何不在 read 阶段做?
虽然可在首次 OP_READ 时检查 IP,但此时已分配堆外/堆内缓冲区、触发了至少一次系统调用,且可能已排队等待处理。尤其在遭受扫描或 CC 攻击时,accept 阶段拦截能显著降低无效连接带来的资源开销和上下文切换压力。除非业务要求根据请求内容(如 HTTP Header 中的 X-Forwarded-For)做更复杂判断,否则应优先在 accept 拦截。
不复杂但容易忽略的是 IP 地址的标准化处理和并发安全——只要这两点做好,NIO 层的黑名单机制就非常轻量且可靠。

















