Java案例怎么推送站内消息?

wen java案例 79

本文目录导读:

Java案例怎么推送站内消息?

  1. 📚 目录导读
  2. 什么是站内消息推送?业务场景与价值
  3. Java实现站内消息的核心技术栈
  4. 案例1:基于消息队列的异步推送(RabbitMQ)
  5. 案例2:WebSocket实时推送 + Spring Boot整合
  6. 案例3:配合数据库轮询的离线消息补发
  7. 高频问答集锦(开发者必读)
  8. SEO优化建议 & 总结

📚 目录导读

  1. 什么是站内消息推送?业务场景与价值
  2. Java实现站内消息的核心技术栈
  3. 案例1:基于消息队列的异步推送(RabbitMQ/ Kafka)
  4. 案例2:WebSocket实时推送 + Spring Boot整合
  5. 案例3:配合数据库轮询的离线消息补发
  6. 高频问答集锦(开发者必读)
  7. SEO优化建议 & 总结

什么是站内消息推送?业务场景与价值

站内消息推送,是指用户在登录系统后,在平台内收到的通知、公告、提醒等非邮件/非短信的即时或延迟消息,常见场景包括:

  • 电商:订单状态更新、物流提醒、优惠券到账
  • 社交:点赞评论、好友申请、系统公告
  • 企业系统:审批进度、任务指派、告警通知

价值:提升用户活跃度、降低通知延迟、增强用户体验,Java作为后端主力语言,必须掌握高效推送方案。


Java实现站内消息的核心技术栈

组件 推荐技术 说明
后端框架 Spring Boot + Spring MVC 提供REST API和WebSocket支持
消息中间件 RabbitMQ / Apache Kafka 解耦生产与消费,保证消息不丢
实时通信 WebSocket / SSE 双向实时推送
数据库 MySQL + Redis MySQL存储消息,Redis缓存未读数量
生命周期 生产者→消息队列→消费者→DB→推送

关键设计原则:异步、削峰、可靠、实时。


案例1:基于消息队列的异步推送(RabbitMQ)

场景

当用户完成支付后,系统需向用户推送“订单已支付”通知,若同步推送,高并发下可能阻塞下游服务。

实现步骤

引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

配置队列

@Configuration
public class RabbitConfig {
    @Bean
    public Queue pushQueue() {
        return new Queue("user.push.queue", true);
    }
}

生产者(支付服务)

@Service
public class OrderService {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    public void paySuccess(Long userId, String orderNo) {
        // 业务逻辑 ...
        PushMessage msg = new PushMessage(userId, "您的订单 " + orderNo + " 已支付成功");
        rabbitTemplate.convertAndSend("user.push.queue", msg);
    }
}

消费者(推送服务)

@Component
@RabbitListener(queues = "user.push.queue")
public class PushConsumer {
    public void handlePush(PushMessage msg) {
        // 1. 存储到数据库(MySQL)
        pushMsgRepository.save(msg);
        // 2. 通过WebSocket实时推送
        webSocketService.sendToUser(msg.getUserId(), msg.getContent());
    }
}

优势:解耦、抗压、支持失败重试。


案例2:WebSocket实时推送 + Spring Boot整合

场景

用户在线时,需立刻收到消息,而非HTTP轮询。

实现步骤

WebSocket配置

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(chatHandler(), "/ws/push")
                .setAllowedOrigins("*");
    }
}

处理器逻辑

public class PushWebSocketHandler extends TextWebSocketHandler {
    private static final Map<Long, WebSocketSession> sessions = new ConcurrentHashMap<>();
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        Long userId = extractUserId(session); // 从token获取
        sessions.put(userId, session);
    }
    public void sendToUser(Long userId, String message) {
        WebSocketSession session = sessions.get(userId);
        if (session != null && session.isOpen()) {
            session.sendMessage(new TextMessage(message));
        }
    }
}

前端连接

let ws = new WebSocket("wss://your-domain.com/ws/push?token=xxx");
ws.onmessage = (event) => {
    // 更新通知栏
};

注意:需配合Spring Security拦截器做权限校验。


案例3:配合数据库轮询的离线消息补发

场景

用户离线期间,WebSocket无法推送,需在用户重新上线时,通过数据库轮询补发。

实现方案

  1. 消息表设计

    CREATE TABLE `user_push` (
    `id` bigint PRIMARY KEY,
    `user_id` bigint,
    `content` varchar(500),
    `status` tinyint DEFAULT 0, -- 0未读1已读
    `created_at` datetime
    );
  2. 上线时批量拉取

    @EventListener
    public void onUserOnline(UserOnlineEvent event) {
     List<PushMessage> unread = pushMsgRepository.findByUserIdAndStatus(
         event.getUserId(), 0);
     for (PushMessage msg : unread) {
         webSocketService.sendToUser(msg.getUserId(), msg.getContent());
     }
     // 标记已读
     pushMsgRepository.updateStatusByUserId(event.getUserId(), 1);
    }

优化:使用Redis做未读计数热数据,减轻DB压力。


高频问答集锦(开发者必读)

Q1:什么时候用RabbitMQ,什么时候用Kafka?

A:RabbitMQ适合轻量级、路由灵活、实时性高的站内推送;Kafka适合海量日志、高吞吐、数据持久化需求,小规模团队优先选择RabbitMQ。

Q2:WebSocket断线重连怎么处理?

A:前端监听 onclose,使用指数退避策略重连(如1s→2s→4s...),服务端维护心跳(ping/pong)检测死连接。

Q3:如何保证消息不丢?

A:生产者开启confirm模式,消费者手动ack,未确认消息重新入队列,同时数据库写入作为兜底。

Q4:推送消息体包含敏感信息怎么办?

A:使用AES或HTTPS加密传输,服务端只推送消息ID,前端通过HTTP接口拉取详情并加密展示。

Q5:十万级用户并发推送怎么设计?

A:采用Redis消息队列 + 多消费者组 + WebSocket集群,配合Nginx+Sticky Session路由用户到相同节点。


SEO优化建议 & 总结

SEO关键词布局

  • 核心词:Java站内消息推送Spring Boot WebSocketRabbitMQ推送案例
  • 长尾词:Java实时通知系统架构离线消息补发方案高并发消息队列设计

策略

  • 整理知乎/CSDN/掘金同主题热门文章,提取高频代码片段并注释详细
  • 将本文拆分为3篇系列文章:《基础篇:队列与存储》《进阶篇:WebSocket实战》《高并发篇:集群与离线》

通过本文的三个案例,你可以构建一个完整的站内消息推送系统:

  1. RabbitMQ异步解耦保证高可用
  2. WebSocket实时推送提升即时性
  3. 数据库+Redis轮询确保离线消息不丢失

实际项目中,建议根据用户并发量、团队技术栈灵活组合,初创项目直接用Spring Event + WebSocket即可,百万级用户则需中间件+分片。

📌 代码示例已去掉具体域名,部署时请替换为实际的WebSocket端点地址和MQ连接配置。

抱歉,评论功能暂时关闭!