邮箱创建时间打标与自动删除功能设计思路

简介: 设计邮箱创建时间打标与自动删除功能,通过记录邮箱首次出现时间,结合定时清理机制,自动批量删除超期(如24小时)邮箱,避免内存泄漏。采用ConcurrentHashMap保障线程安全,异步删除服务器邮件提升性能,并提供监控统计与日志追踪,确保系统稳定高效运行。

邮箱创建时间打标与自动删除功能设计思路

🎯 问题背景

在邮件处理系统中,收件人邮箱数量会随时间无限增长,导致内存泄漏和性能下降。需要设计一个自动管理机制来解决这个问题。

🏗️ 设计方案

核心数据结构

// 邮箱创建时间映射表
private final Map<String, Long> emailCreationTimestamps = new ConcurrentHashMap<>();

// 收件人邮箱映射表  
private final Map<String, List<EmailMessage>> recipientEmailMap = new ConcurrentHashMap<>();

// 保留时间配置
private static final long EMAIL_RETENTION_TIME = 24 * 60 * 60 * 1000; // 1天

设计思路

  1. 创建时间打标:新邮箱首次出现时记录时间戳
  2. 自动清理:每次处理邮件后检查过期邮箱
  3. 批量删除:一次性删除所有过期邮箱
  4. 异步处理:服务器删除操作异步执行

🔧 核心实现

1. 邮箱创建时间打标

private void processEmailGrouping(List<EmailMessage> newEmails) {
   
    long currentTime = System.currentTimeMillis();
    recipientEmailGroupMap.forEach((recipientEmail, emails) -> {
   
        // 检查是否是新邮箱
        if (!recipientEmailMap.containsKey(recipientEmail)) {
   
            // 记录新邮箱的创建时间
            emailCreationTimestamps.put(recipientEmail, currentTime);
            log.debug("新邮箱 {} 创建时间: {}", recipientEmail, new Date(currentTime));
        }
        recipientEmailMap.computeIfAbsent(recipientEmail, k -> new ArrayList<>())
                .addAll(emails);
    });
}

2. 自动删除过期邮箱

private void cleanupExpiredEmails() {
   
    long currentTime = System.currentTimeMillis();
    Set<String> expiredEmails = findExpiredEmails(currentTime);

    if (!expiredEmails.isEmpty()) {
   
        performEmailCleanup(expiredEmails);
    }
}

private Set<String> findExpiredEmails(long currentTime) {
   
    return emailCreationTimestamps.entrySet().stream()
            .filter(entry -> (currentTime - entry.getValue()) > EMAIL_RETENTION_TIME)
            .map(Map.Entry::getKey)
            .collect(Collectors.toSet());
}

3. 邮箱删除机制

public boolean deleteRecipientEmail(String recipientEmail) {
   
    try {
   
        List<EmailMessage> emailsToDelete = recipientEmailMap.get(recipientEmail);

        if (ObjectUtils.isNotEmpty(emailsToDelete)) {
   
            // 删除邮件ID
            // 取出id
           Set<String> messageIds = emailsToDelete.stream()
                        .map(EmailMessage::getMessageId)
                        .collect(Collectors.toSet());
            processedMessageIds.removeAll(messageIds);

            // 删除内存中的邮箱
            recipientEmailMap.remove(recipientEmail);

            // 删除创建时间
            emailCreationTimestamps.remove(recipientEmail);

            // 异步删除服务器邮件
            deleteEmailsFromServerAsync(recipientEmail);
        }
        return true;
    } catch (Exception e) {
   
        log.error("删除邮箱 {} 时发生错误", recipientEmail, e);
        return false;
    }
}

📊 监控统计

public Map<String, Object> getProcessingStats() {
   
    Map<String, Object> stats = new ConcurrentHashMap<>();
    int totalEmailCount = recipientEmailMap.values().stream()
            .mapToInt(List::size)
            .sum();

    stats.put("processedMessageCount", processedMessageIds.size());
    stats.put("recipientEmailCount", recipientEmailMap.size());
    stats.put("totalEmailCount", totalEmailCount);
    stats.put("emailCreationTimestampCount", emailCreationTimestamps.size());

    return stats;
}

🚀 工作流程设计

1. 新邮箱创建流程

flowchart TD
    A[开始处理邮件] --> B[邮件分组处理]
    B --> C[检查是否新邮箱]
    C --> D{是否为新邮箱?}
    D -->|是| E[记录创建时间]
    D -->|否| F[添加到映射表]
    E --> F
    F --> G[清理过期邮箱]
    G --> H[结束]

    style A fill:#e1f5fe
    style E fill:#c8e6c9
    style G fill:#fff3e0
    style H fill:#f3e5f5

2. 自动清理流程

flowchart TD
    A[开始清理检查] --> B[获取当前时间]
    B --> C[查找过期邮箱]
    C --> D{有过期邮箱?}
    D -->|是| E[批量删除处理]
    D -->|否| F[结束]
    E --> G[记录清理日志]
    G --> F

    style A fill:#e1f5fe
    style E fill:#ffcdd2
    style G fill:#fff3e0
    style F fill:#f3e5f5

3. 邮箱删除详细流程

flowchart TD
    A[开始删除邮箱] --> B[获取邮件列表]
    B --> C{邮件列表为空?}
    C -->|是| D[记录日志]
    C -->|否| E[删除邮件ID]
    E --> F[删除内存中的邮箱]
    F --> G[删除创建时间]
    G --> H[异步删除服务器邮件]
    H --> I[返回成功]
    D --> J[返回成功]

    style A fill:#e1f5fe
    style E fill:#ffcdd2
    style F fill:#ffcdd2
    style G fill:#ffcdd2
    style H fill:#fff3e0
    style I fill:#c8e6c9
    style J fill:#c8e6c9

4. 整体系统工作流程

flowchart TD
    A[系统启动] --> B[定时任务触发]
    B --> C[获取新邮件]
    C --> D{有新邮件?}
    D -->|否| B
    D -->|是| E[邮件分组处理]
    E --> F[检查新邮箱]
    F --> G{发现新邮箱?}
    G -->|是| H[记录创建时间]
    G -->|否| I[添加到映射表]
    H --> I
    I --> J[自动清理检查]
    J --> K{有过期邮箱?}
    K -->|是| L[批量删除过期邮箱]
    K -->|否| M[等待下次任务]
    L --> N[异步删除服务器邮件]
    N --> M
    M --> B

    style A fill:#e1f5fe
    style H fill:#c8e6c9
    style L fill:#ffcdd2
    style N fill:#fff3e0

5. 数据流转关系图

graph LR
    A[新邮件] --> B[邮件分组]
    B --> C[邮箱映射表]
    B --> D[创建时间映射表]
    C --> E[过期检测]
    D --> E
    E --> F[过期邮箱列表]
    F --> G[批量删除]
    G --> H[内存清理]
    G --> I[服务器删除]

    style A fill:#e1f5fe
    style C fill:#c8e6c9
    style D fill:#c8e6c9
    style F fill:#ffcdd2
    style H fill:#ffcdd2
    style I fill:#fff3e0

📝 使用示例

// 获取统计信息
Map<String, Object> stats = defaultEmailMonitorService.getProcessingStats();
System.out.println("邮箱数量: " + stats.get("recipientEmailCount"));

// 获取所有邮箱
List<String> allEmails = defaultEmailMonitorService.getAllRecipientEmails();

// 删除指定邮箱
boolean success = defaultEmailMonitorService.deleteRecipientEmail("user@example.com");
目录
相关文章
|
7月前
|
文字识别 安全 Java
验证码识别
基于Spring Boot与ONNX Runtime的OCR服务,支持D4NEW/D4OLD引擎,提供RESTful API,兼容Base64、URL及文件上传,集成Swagger文档,具备多环境配置、日志管理与跨域支持,易于扩展与部署。
299 5
|
7月前
|
存储 缓存 监控
临时邮箱地址获取服务器邮件工作流程与实现
本系统实现临时邮箱生成与邮件监控功能,支持随机邮箱创建、IMAP增量拉取、并发解析及过期清理。通过内存缓存与连接池提升性能,提供接口用于获取、查询和删除临时邮箱邮件,适用于需临时收信的场景,保障安全与高效。
425 0
|
7月前
|
存储 运维 安全
别再把 Collector 当黑箱:OpenTelemetry Collector 拓展与自定义处理器实战指南
别再把 Collector 当黑箱:OpenTelemetry Collector 拓展与自定义处理器实战指南
426 14
|
7月前
|
消息中间件 Java Spring
RabbitMq-队列交换机绑定关系优化为枚举注册
本项目通过枚举配置简化RabbitMQ队列、交换机及绑定关系的注册流程,实现自动化声明。只需定义队列枚举,即可完成交换机创建、队列声明与绑定,大幅减少重复代码,提升开发效率。支持直连、主题、广播及延迟交换机,配置灵活,易于维护。
156 8
|
7月前
|
算法 索引
双指针技巧秒杀七道数组题目
本文介绍双指针技巧在数组和链表中的应用,涵盖快慢指针与左右指针。通过力扣多道经典题目,如删除重复项、两数之和等,详解如何用快慢指针实现原地修改,提升算法效率。内容覆盖数组与链表去重、链表环检测等常见问题,适合巩固基础算法思维。(239字)
|
7月前
|
JavaScript 前端开发 算法
React框架
React基于虚拟DOM和Diff算法实现高效渲染,通过生命周期管理组件状态。支持JSX、服务端渲染,易于测试与优化。强调单向数据流,可与其他框架集成,广泛用于构建高性能前端应用。(239字)
|
7月前
|
负载均衡 算法 架构师
Ribbon负载均衡
本节深入讲解Ribbon实现客户端负载均衡的原理,解析@LoadBalanced注解的作用机制,剖析其如何通过RestTemplate拦截请求、选择服务实例并重写URL。结合Eureka,详解负载均衡策略配置、自定义规则及饥饿加载优化,帮助读者全面掌握Ribbon核心知识点,并引出后续Nacos等服务端负载均衡实现的对比思考。(238字)
|
人工智能 搜索推荐 数据可视化
用 Python 制作简单小游戏教程:手把手教你开发猜数字游戏
本教程详细讲解了用Python实现经典猜数字游戏的完整流程,涵盖从基础规则到高级功能的全方位开发。内容包括游戏逻辑设计、输入验证与错误处理、猜测次数统计、难度选择、彩色输出等核心功能,并提供完整代码示例。同时,介绍了开发环境搭建及调试方法,帮助初学者快速上手。最后还提出了图形界面、网络对战、成就系统等扩展方向,鼓励读者自主创新,打造个性化游戏版本。适合Python入门者实践与进阶学习。
1467 1
|
人工智能 前端开发 Java
一文彻底明白三极管
三极管,全称半导体三极管,是电子电路的核心元件,具有电流放大和开关功能。它由三个区域组成:基区、发射区和集电区,分为PNP和NPN两种类型。三极管的关键特性包括电流放大倍数(β)、输入和输出特性曲线。根据用途可分为小功率、大功率和高频三极管。其主要应用包括信号放大、开关控制和振荡电路。关注我,一起学习更多电子知识!
2363 0
一文彻底明白三极管
|
监控 Ubuntu 安全
debian或Ubuntu中开启ssh允许root远程ssh登录的方法
在Debian或Ubuntu系统中启用root用户的SSH远程登录需要编辑SSH配置文件、设置root密码并重启SSH服务。虽然这可以在某些情况下提供便利,但必须注意安全性,通过使用强密码、限制IP访问、使用SSH密钥认证等方法来保护服务器的安全。
8214 5