设计通过外部网关发送短信的批评

时间:2012-05-17 12:27:17

标签: java multithreading postgresql sms

我们有一个基于客户端 - 服务器的应用程序,它使用外部网关发送和接收SMS。 我正在考虑重新设计/修改现有架构以提高效率和性能。 欢迎各地的想法和建议。请注意,在高峰期 小时约每小时从客户端 - 服务器 - 网关发送3000条SMS。 每天发送的SMS总量可能在8000到10,000之间

现有架构

发送短信

  1. 客户端向服务器发送SMS,等待来自服务器的唯一smsid(由db生成)(打开连接)
  2. 服务器将短信存储在数据库中,将短信发送到网关。
  3. 网关将短信发送到手机,将唯一的收据返回给服务器。
  4. 服务器在数据库中存储唯一的收据
  5. 服务器将唯一的smsid(在步骤2中生成)返回给客户端
  6. 步骤1-5是一个请求 - 响应周期。

    确认短信

    1. 网关向服务器发送消息状态
    2. 服务器更新数据库中的消息状态,从发送到已发送/失败/未知等。
    3. 客户端定期轮询服务器,以使用先前收到的smsid接收消息的状态。
    4. 客户端更新客户端状态。
    5. 数据库设计

      所有短信都存储在数据库中的1个单个短信表中。最初我们有数据,约会 回到2006年左右,单表中约有500万条记录。我们现在已经归档了数据并且只有 表中当前年份的数据。

      缺点   - 客户端长时间等待导致连接有时超时错误,导致向服务器重新发送相同的消息。    由于服务器无法检测到这是重复的消息,它会将消息重新发送到网关,    导致客户重复短信。   - 每秒在sms表上执行多次SELECT,UPDATE查询,有时会给db带来相当大的负担    并且系统失败了。也没有归档数据的机制。

      新架构

      发送短信

      1. 客户端向服务器发送SMS,等待来自服务器的唯一smsid(由db生成)(打开连接)
      2. 服务器将sms存储在数据库中,将唯一的smsid返回给客户端。
      3. 步骤1-2是一个请求 - 响应周期。

        1. 使用cron分离进程以定期轮询数据库表以检索短信 并发送到网关或可以使用java多线程???
        2. 网关将短信发送到手机,将唯一的收据返回给服务器。
        3. 服务器在数据库中存储唯一的收据
        4. 确认短信保持与上述相同

          数据库设计

          1. 根据继承或使用Postgresql时间/范围分区根据收到的日期对数据进行分区
          2. 单独的脚本每天将数据从table1移动到table2。使用union查询连接表以报告和检索数据。
          3. 什么是基于db性能的更好方法?

1 个答案:

答案 0 :(得分:0)

首先,我不相信需要将其分解为多个表格。您没有进行批量操作,这可能会使小型表上的检查键比大型表更容易。在你的情况下,更有可能是有用的是部分索引的概念。在这种情况下,您只能索引当前的每日记录。

在这方面,您可能每天只为当前日期的记录创建一个新索引并删除上一个索引。如果这样做,您可能还想索引日期,以便快速创建此部分索引。

一旦我有机会进行测试,我会在稍后编辑一些性能注释。

更新

经过测试,它看起来像一个普通的日期索引是不够的。我认为你需要做的就是添加一个附加的current_index bool值,默认值为true。然后你可以索引WHERE current_index = true,并在一天结束时将它们设置为false,从而将它们从索引中删除。

这将使您的查询保持快速,防止每天向表添加新索引,同时您可以获得更小索引的好处。这应该可以让你在两个方面表现最佳。

也是这样:使用cron分离进程定期轮询数据库表以检索短信并发送到网关或者可以使用java多线程???

在Postgres文档中查看LISTEN和NOTIFY。不要轮询db表。只是对通知进行投票。这将为您节省可观的开销。不要依赖NOTIFY来获取有效负载,因为这不安全。只需将其用作应用程序的“触发器”即可知道它应该进行轮询。

基本上它的作用是向服务器发送一个非常轻量级的异步通知(你可以在btw的触发器中执行此操作),然后你的应用程序会知道轮询可能是一个好主意。在通知事务提交时发送通知。