首页 > 代码库 > 企业自建的苹果通知推送系统的架构演进与探索

企业自建的苹果通知推送系统的架构演进与探索

企业的APP开发中,对于苹果设备有个独特的通知推送功能要解决,尤其是在做移动IM时,对APNS(Apple Push Notification Service)的要求比较高,虽然有专门的第三方提供此类服务,但出于安全的考滤,有能力的公司宁愿自建推送服务系统。本人结合工作中的开发经验,在这探讨一下其架构的演进与探索,希望能使此类系统更加完美。

IM系统自建苹果通知推送服务系统的层级关系如下:

                                                                图1层级关系

首先说明一下在我工作中APNS的使用场景:


对于最初的解决方案是我入项目组时就已经定好的,具体的应对方案如下:

                                                                        图3  原始设计方案

虽然这个方法实现了功能,但对于APP的推广后的大量的用户使用,系统的承受能力和扩展能力很明显就不足,虽然推送系统已经根据用户的设置信息,从最大程度上减少了压力,但对于IM软件来说仍然不够,而且对于IM类的APP来说还有两个特殊的要求:角标和消息顺序。

出于众多的考滤,历时两个多月,我对推送系统做了如下的改进,首先从架构上:

                                                                      4    单个证书解决方案

我利用了RabbitMQ的路由功能做系统的负载均衡支持,因为苹果设备的设备号是固定64位长度,而且具有唯一性,所以的就用了用户的设备号来做Hash(散列),具体的算法如下:

public abstract class RouteKeyUtil {
    
    private static Properties prop = ConfigUtil.getApnsConfig();
    
    private static Map<Integer, String> map;
    
    static {
        String list = prop.getProperty("queues");
        String[] queues = list.split(",");
        map = new HashMap<Integer, String>();
        int ii = 1;
        for (String q : queues) {
            if(StringUtils.isNotEmpty(q)){
                map.put(Integer.valueOf(ii++), q);
            }
        }
    }

    public static String genarateRouteKey(String token) {
        if (token == null || token.isEmpty()) {
            throw new IllegalArgumentException("token is empty");
        }
        int random = token.charAt(0) * token.charAt(1);
        int index = random % map.size() + 1;
        return map.get(Integer.valueOf(index));
    }
    
    public static Map<Integer, String> getAllQueues(){
        return map;
    }
}

由于苹果的证书分为企业证书和开发者证书,而且两个证书的调用接口地址不一样,如果调错的话Apple Server会返回发送失败错误。所以对于两个证书我们在一个系统里做了区别,但两者架构相同,如下:

                                                                                        5  双证书解决方案

但是利用MQ做负载均衡有一个致使命的缺点,就是不能相互感知,一但监听服务器宕机,消息就会在MQ中积压,为了解决此问题,我利用Zookeeper提供的订阅功能做了一个监控方案,Zookeeper用于存放配置,健康检测系统用于监听服务状态和动态修改配置,这样可以简单实现失效转移(failover)功能,具体设计如下:

                                                                               6 系统监控

此系统设计方案还有很多缺点,在此提出希望大家能给点宝贵的建议。


企业自建的苹果通知推送系统的架构演进与探索