博客
关于我
Netty学习总结(3)——Netty百万级推送服务
阅读量:789 次
发布时间:2023-02-14

本文共 1909 字,大约阅读时间需要 6 分钟。

Netty推送服务设计与优化

背景

近年来,移动互联网和物联网开发的同学纷纷向我咨询推送服务相关问题,这些问题主要集中在以下几个方面:Netty是否适合作为推送服务器、一个Netty服务器最多能支撑多少个客户端、以及Netty在推送服务中遇到的各种技术问题等。

通过分析这些问题,我希望通过本文的案例分析和对推送服务设计要点的总结,帮助大家在实际工作中少走弯路。

推送服务概述

在移动互联网时代,推送服务已成为App应用不可或缺的一部分。推送服务通过向用户发送通知、广告等消息,显著提升了用户的活跃度和留存率。随着物联网的普及,智能家居设备的接入数量呈快速增长,这使得推送服务面临着更大的挑战。

推送服务的特点

  • 网络不稳定:移动网络信号波动大,容易出现网络闪断等问题。
  • 高并发和长连接:海量客户端接入,长连接维持时间长,资源消耗大。
  • 协议限制:Android的长连接需要由各应用自行维护,导致消息推送和心跳检查带来巨大的流量和电量消耗。
  • 不稳定性:消息丢失、重复推送、延迟传输等问题时有发生。
  • 垃圾消息:缺乏统一的服务治理能力,导致信件风暴问题。
  • 针对这些问题,部分企业提出了自己的解决方案,比如京东云推出的推送服务,通过多应用单服务单连接模式和定时心跳优化解决了电量和流量问题。

    智能家居领域的案例

    问题描述

    智能家居的MQTT消息服务中间件服务器需要维持10万用户的在线长连接,每天处理2万个并发消息请求。随着时间推移,程序出现内存泄露现象,怀疑Netty的Bug是导致问题的原因之一。

    服务器配置为16G内存、8核心CPU,Netty中boss线程池设置为1个,worker线程池为6个,其余资源留给业务使用。后来将worker线程池调整为11个,问题依旧。

    Netty版本为4.0.8.Final。

    问题定位

    通过内存堆栈dump和对象关系分析,发现Netty的ScheduledFutureTask实例数量激增,达到10W个左右。进一步调查发现,IdleStateHandler用于处理链路空闲状态时设置的超时时间过长(15分钟),导致大量定时任务被创建并存活,占用大量内存。

    每个长连接都持有一个ScheduledFutureTask,且这些任务保存有业务成员变量。尽管持久代设置较大,但这些定时任务未被及时回收,最终导致内存泄露。

    问题解决

    重新设计IdleStateHandler的超时时间为45秒后发现内存问题得到有效解决。分析表明,100个长连接即便有长周期定时任务,也不会导致内存泄露问题,因为新生代通过minor GC即可回收内存。

    Netty海量推送服务设计要点

    作为高性能的NIO框架,Netty确实适合开发高效的推送服务,但要实现稳定性和性能的平衡,需要在设计阶段针对推送服务特点进行优化。

    最大句柄数修改

    在Linux系统中,文件句柄数默认限制较低(如1024),直接导致Netty服务器接收客户端连接时遇到“too many open files”错误。通过修改内核参数和调整用户限制,可以将句柄数提升到1000000级。

    ulimit -acore_file_size unlimitedulimit -nofile 1000000

    CLOSE_WAIT问题

    在百万级推送服务中,服务端需要处理频繁的网络异常和客户端断连。以下是优化建议:

  • 合理设置客户端重连间隔,避免连接过于频繁。
  • 实施客户端重复登录拒绝机制。
  • 正确处理I/O异常和解码异常,防止句柄泄露。
  • 定期清理处于CLOSE_WAIT状态的连接,避免积压过多。
  • 合理心跳周期设置

    移动无线网络的特点决定了推送服务的心跳周期需要谨慎设计。合理的周期设置可以平衡客户端链路的稳定性和网络资源消耗。

    • 移动网络特性:移动设备连接互联网时,其实是通过运营商的内网IP进行NAT转换,链路容易因无信号或NAT映射表清除而断开。
    • 心跳周期建议:180秒左右是一个合理的选择,既能维持链路稳定性,又不会导致过多的网络负担。

    内存池优化

    对于海量长连接的推送服务,内存池能够显著减少内存泄漏和GC压力。通过使用PooledByteBufAllocator,可以实现缓冲区的动态管理,避免内存浪费。

    TCP参数优化

    合理设置TCP接收和发送缓冲区大小(如32K),优化软中断分配,提升网络通信性能。

    JVM参数优化

    合理配置JVM参数,避免Full GC,确保内存管理的高效性。

    结语

    通过Netty的优化配置和合理设计,可以实现高性能的百万级推送服务。关键在于充分了解Netty的特点,合理设置心跳周期、优化内存管理、配置合适的TCP参数等。

    转载地址:http://rjcfk.baihongyu.com/

    你可能感兴趣的文章
    mysql的cast函数
    查看>>
    mysql的grant用法
    查看>>
    mysql的InnoDB引擎索引为什么使用B+Tree
    查看>>
    mysql的logrotate脚本
    查看>>
    MySQL的on duplicate key update 的使用
    查看>>
    MySQL的Replace用法详解
    查看>>
    mysql的root用户无法建库的问题
    查看>>
    MySQL的sql_mode模式说明及设置
    查看>>
    mysql的sql执行计划详解
    查看>>
    mysql的sql语句基本练习
    查看>>
    Mysql的timestamp(时间戳)详解以及2038问题的解决方案
    查看>>
    mysql的临时表简介
    查看>>
    mysql的函数操作
    查看>>
    mysql的分页查询limit关键字
    查看>>
    MySql的创建数据表、约束、外键约束的创建修改删除、级联操作
    查看>>
    MySQL的基本命令
    查看>>
    MySQL的常见命令
    查看>>
    MySQL的操作:
    查看>>
    mysql的数据类型有哪些?
    查看>>
    mysql的语法规范
    查看>>