作者: 邓明轩
推送细节分析
了解基 本的 M DS 推送 知识 是不足 于编 写一 个可 靠的 数据推 送程 序的 ,要 保证 数据推 送 的可靠 性, 必须 了解 整个 推送过 程的 每一 个细 节。 本章节 先从 整体 上描 述了 整个数 据推 送的 调用时 序, 然后 从不 同的 关键点 详细 讲解 数据 推送 的细节 。
M DS 推送的整体时序
如上图所示,数据 推送主 要是应用服务器、 MD S 服 务器、网络服务、 手机端 几个组件
之间的 交互 。 在网络 服务 这一块 我们 可以 假定 这一 层是稳 定的 , 不做考虑 , 对于网 络无 法提 供服务 等情 况我 们可 以通 过手持 设备 端关 闭无 线电 , 或者是 将手 持设 备放 入无 线屏蔽 区等 方 式模拟 。所 以我 们要 考虑 是应用 服务 器, MDS /BE S 服务器 ,手 持设 备这 三部 分。
数据推 送由 应用 服务 器发 生, 向 MDS /BE S 服务 器发 出 HT TP P o s t 请求。 第 一个 需要考 虑 的是 该 HT TP P o s t 请求是否 能到 达 MDS /BE S 服务 器。 这一点 在 “ 推送 请求 是否 到达 MDS / BE S 服务器 ”小 节中 有详 细讨 论。
MDS /BE S 服 务器 在接 收到 HT TP P o s t 请求后 会对 请求 的格式 进行 判断 ,如 果格 式错误 , 如指定 目标 不存 在等 ,则 MDS /BE S 服 务器 会返 回 40 0 错 误。 所以 第二 点要考 虑是的 如何 保 证所有 到达 MDS /BE S 服务 器的请 求都 是合 法的 ,有 关这一 点在 “推 送请 求检 查”小 节中 有
详细描 述。
MDS /BE S 服 务器 发现 推送 数据格 式正 确以后 , 还 需要 判断服 务器 上的 队列 是否 有足够 的 空间保 存该 数据 , 如果没 有发现 空闲 队列 则丢 弃该 数据并 向应 用服 务器返 回 5 0 3 错误 。 因此 第三点 要考 虑的 是什 么情 况会导 致服 务器 推送 队列 占满, 如何 尽量 避免 这种 情况。 有关 这一 点在“ MDS /BE S 中的 推送 队列” 中有 详细 描述 。
MDS /BE S 服 务器 将数 据推 送到客 户端 以后 , 由 客户 端程序 将数 据提 取, 交由 相应的 应用 逻辑进 行处 理。 然后, 客户 端应用 在提 取数 据的 时候 并不一 定能 及时 地将 所有 推送到 的数 据 获取。 所以 第四 点要 考虑 的是手 持设 备端 是否 也存 在队列 , 如 何保 证客 户端 程序将 所有 数据 都提取 出来 。有 关这 一点 在“手 持设 备端 对消 息的 处理” 小节 中有 详细 描述 。
手持设 备在 接收 推送 数据 后会通 知 MDS / BE S 服 务器 , MDS /BE S 服务 器则 向应 用服务 器 发送异 步的 确认 消息 , 通过 返回数 值 20 0 或 者是 4 0 0 通知应 用服 务器 推送 数据 是推送 成功 还 是推送 失败 。 异 步确 认消 息对于 应用 开发 者有 特别 的意义 , 通 过它 可以 确定 数据是 否到 达客
户端, 从而 决定 是否 再次 推送数 据。 然后, 很多 开发 商都发 现, 异步 确认 消息 的返回 的 “ 2 0 0 ” 和“ 40 0 ” 并不能 准备 地反 映数据 的接 收情况 。所以 ,如何 使用 异步确 认消息 ,在不 同的 场 景下异 步消 息会 包含 什么 不同值 , 对于 应用开 发者 而言非 常重要 。 有关 这一 点在小 节 “异 步 确认消 息” 有详 细描 述。
推送请求是否 到达 M DS/BE S 服 务 器
有关推 送请 求是 否到 达 M DS /BE S 服 务器, 很 多开发 人员都 会忽 略, 认为 推送 请求是 否 到达 MDS / BE S 服 务器 是由 代码是 否编 写正 确决 定的 ,一定 会在 代码 测试 阶段 体现也 来, 也 必须在 代码 编写 阶段 解决 这个问题 。 然 而在 生产 环境 确实有 一些 因素 会导 致应 用服务 器发 送 的推送 请求 无法到 达 MDS / BE S 服务 器, 从而 导致推 送数据 丢失 的问 题。
推送请 求无 法到 达 MDS /BE S 服务器 的一 个可 能的直 接原因 是指 定的 服务 器名 不正确 或 者是指 定的 端口 号不 正确 , 原因 可能 是 BE S 管理员 修改 了 BE S 服务 器的 服务 器名、 IP 地址 或 者是推 送监 听端 口。
这种问 题比 较容 易发 现, 一方面 是因 为所有 的 Bla ck Berr y 用 户此 时都 无法 接收 到推送 数 据,另 一方 面也 因为 应用 服务器 端会 报网 络连 接的 异常。 以 ja v a 代 码为 例, 当指定 的服 务 器名或 者是 端口 号不 正确 的情况 下, 应用 服务 器端 的推送 程序 会报 以下 异常 :
java.net.ConnectException : Connection refused 或者是 报域 名无 法解 析等 网络连 接级 别的 异常 。 发现这种情况只需 要检 查代码中指定的服务 器名 和端口号是否和生产 环境 相同就可以
解决问 题。
推送请 求无 法到 达 MDS /BE S 服务器 的一 个潜 在可能 性是推 送请 求的 并发 数量 太大导 致
MDS /BE S 服 务器 无法 及时 接收所 有请 求。 这种问 题比 较难 于发 现, 因为部 分用 户仍 然可 以收 到推送 数据 , 只 有部 分用 户的部 分数
据丢失了 。 同 时, 这种问 题在功 能性 测试 场景 下不 容易发生 , 只 有在大 压力 测试或 者是 存在 大量用 户的 生产 环境 中才 容易出 现。
产 生这 种问 题的根 源是 M DS /BE S 服务器 的并 发接 收限 制。 MD S 服 务器其 实是运 行在
T om ca t 服务器上 一个 服务, T om ca t 服务 器作 为应用 容器处 理了 低层 的网 络请 求。 而 T om ca t
服务器 在底 层有 并发 网络 请求的 限制 , 当 网络 连接 达到服 务器 限制 时, 新的 推送连 接会 处理 等待状 态, 如果 在网 络超 时前仍 无法 建立 连接 ,则 会出现 网络 超时 异常 :
java.net.ConnectException : Connection timed out: connect
根据测 试的 结果 , 不同版 本的 BE S 服 务器 在低 层并 发网络 请求 的数 量上 有差 异。 以 2 0 0 个并发 限制 为例 ,就 是说 同一时 间点 只能 有 2 0 0 个 连接可 以向 MDS /BE S 服务 器发送 推送 请 求。 第 20 1 个请 求以 后有所有 请求 都将进 入等 待状态, 如果 在 T CP /IP 超 时限制 到达 之前 MDS /BE S 服 务器 仍无 法释 放前 20 0 个 请求 ,则 等待 状态的 请求 会因 为网 络超 时而中 断。
当应用 服务 器采 用多 线程 机制处 理推 送请 求的 情况 下有可 能出 现以 上情况 。 如 果因为 业 务原因 在短 时间 内出 现大 量等待 推送 的数 据, 应用服 务器则 有可 能启 动多 于 20 0 个 的线 程发 送推送 请求 。 如果需 要推 送的数 据太大 , 或者 是推 送线程 需要 动态 对数 据进 行计算 , 就有 可 能导致 线程所 启动 的连接 在短时 间内没 有关 闭。当 多于 20 0 个线 程处 于这种 状态的 时候 , MDS /BE S 服 务器 就无 法继 续接收 推送 请求了 。 这 种问 题的一 个现 象就 是应 用服 务器端 报网 络 超时异 常或 者是 连接 被拒 绝的异 常。
总的而 言, 要保 证数 据推 送的成 功, 第一 步需 要保 证推送 数据 到达 MDS /BE S 服务器 , 发现推 送数 据没 有到 达 M DS /BE S 服务 器的 情况 时应 该对应 用服 务器 的日 志进 行检查 ,进 一 步确定 问题 的原 因。
推送请求检查
在 MDS /BE S 服务 器接 收到 推送请 求后 , MDS / BE S 服 务器会 对请 求进 行检 查, 只有符 合 推送格 式的 请求才 被 MDS / BE S 服务 器所 接收 。 当 MD S /BE S 服务 器接 收推 送时 , 会返回 值为
2 0 0 的 HT TP 答复 , 告 知应 用服务 器已 经接 收该 请求 。 当 M DS /BE S 服 务器 拒绝 推送请 求时 会
根据拒 绝的 原因 返回 相应 的错误码 ,可 能返 回的错 误码包 括 4 0 0 , 4 03 , 5 0 3 等。 下面对 不同 的 情况进 行描 述。
第一种 请求 被拒 绝的 原因 是推送 请求 的格 式不 对, 包括 U R L 格 式不 正确 和 H TTP 头不 正 确两种 情况 ,两 种情 况 M DS /BE S 服 务器 都会返 回 4 0 0 消息 表示 拒绝 。 U R L 格 式不正 确包 括 U RL 中不包含“ DES TINA TI ON ”参数,或者是不包含 “ P OR T ”参数等。 HTTP 头不正确包括 PUS H ID 不唯 一等。 因为推 送请求中 的 HTTP 头属 性都 有缺省 值, 所以 使用 错误 的 HTTP 头属 性并不 会引 发错误 , MDS / BE S 服务 器只 是忽 略该参 数。 如 HTTP 头 “ X -RI M -PUS H -ID ” 被误 写 为“ X -RIMP US HID ” , MDS / BE S 服务器 并不会 拒绝该 请求,只 是使用“ X -RIM -PUS H -ID ”的缺 省值, 就是 服务 器随 机生 成一个 唯一 的 ID 给推 送消 息。
对于 HT TP 协议 而言 , 服务 器返 回 40 0 代 表服 务器一 般性错误 , 所 以返 回消息 会以异 常 形式被 捕获。 以 ja v a 代码 为类, 程序 会捕 获到 以下 网络异 常:
“ java.io.IOException : Se rv er re tu rn ed HT TP re sp on se co de : 40 0 fo r UR L:
http://... ”
第二种 推送 请求 被拒 绝的 情况是 推送 请求 指定 的收 件人不 正确 , 就是 指应 用服 务器发 送
推送请 求时 使用 了正 确的 格式 , 不 过 DES TIN A TIO N 参 数指定 的收 件人 并不 存在 或者是 该收 件 人并不 是 Bla ck B er r y 用户 。此 时 MDS / BE S 服务 器会 返回 40 3 错 误。 读者 需要 注意 BE S 服务
器 3 . 7 之 前的 版本 对于这 种情况 会视 作格 式错 误, 返回 4 0 0 错误 。
同 样 以 j a v a 代码为例 , 收件人不正确 的 情况 下 程序会捕获到以下网络异 常 :
“ java.io.IOException : Se rv er re tu rn ed HT TP re sp on se co de : 40 3 fo r UR L:
http://... ”
第三种 请求 被拒 绝的 情况 是 MDS /BE S 服务 器上 的推 送队列 已满 ,无 法再 接收 更多的 推 送请求 。 此 时会 返回 50 3 错 误, 表 示服 务器 暂时 没有足 够的资 源处 理该 请求 。 这种 情况 下 ja v a 应用程 序会 捕获 到以 下异 常:
“ java.io.IOException : Se rv er re tu rn ed HT TP re sp on se co de : 50 3 fo r UR L:
http://... ”
这种情 况与 推送 请求 是否 正确无 关, 取决 于 MDS / BE S 服务器 运行 情况 。关 于 MDS /BE S
服务器 的推 送队 列, 在下 一节中 我们 才进 行详 细的 讨论。
如果数 据推 送请 求通过 了 MDS /BE S 服 务器 的消 息检 查, 则 MDS /BE S 服务 器会 将该数 据 放入推 送队 列等 待发 送, 同时给 应用 服务 器返 回成 功消 息 2 0 0 。
成功消 息是 以 HT TP 的 R e s po ns eCo de 形 式返 回的 , 开 发人员 可以通 过 HTTP 连接 的相应 方法获取 , 在 ja v a 代码中 获 取 R e s po ns eCo de 的函数是 “ g et R e s po ns eCo d e ” 。只有确认 MDS /BE S 服 务器 返回 的 R e s po ns eCo de 是 2 00 , 才能 确定推 送数 据已经 由 MDS / BE S 接收。 对 于其它 的异 常情 况都 需要 由程序 进行 判断 ,确 定如 何调整 请求 继续 重试 推送 过程。
有一点 非常 重要 的是 MDS / BE S 接收 该推 送数 据并不 意味着 该数 据就 一定 能到 达手持 设 备端, 还有 很多 因素 会导 致手持 设备 端的 应用 接收 不到该 数据 。
BlackBerry SDK下载
相关链接:
BES服务器推送机制分析(一)
BES服务器推送机制分析(二)
BES服务器推送机制分析(三)