• 移动App服务端架构设计


    来源:http://www.cnblogs.com/YamatAmain/archive/2013/06/09/3129452.html

    我从事手机app服务端开发现在已经是3个年头,自己也整理出了一套相对好用的服务架构,写出来,跟大家一起分享。如有不足,还请多指教。

    一:基础流程图。

    image

    其实有一点还需要加上,就是对json的压缩和加密,一来给用户节约流量,二来防止请求被截取破解我们的参数。具体先压缩后加密还是先加密后压缩这个问题看需求。

    看到这个架构设计时,你们可能会说如果程序入口挂了,所有的服务都不可以用了。

    所以这个架构的弱点在程序入口处,因此要有一(多)台机器做负载,负载的工具可以是HaProxy(软件)或者F5(硬件)的负载。F5比较昂贵,我没用过,haproxy的配置我就不贴了,谷歌一大把。

    二:Json参数设计

    手机App的灵魂是用户数,有了用户数才有一切。据我得到的数据,目前一款app从开始制作到推广到注册到充值的费用是14.6元(内部数据)。所以一款App的成功大部分取决于渠道推广。而一款手机的mac.imsi等数据是唯一标识一个手机用户的标准。可能某个用户换了一款手机,但是还想用以前的账号登录,所以userID也是必不可少的字段。但是会出现一个问题,两个mac.imsi,userID,但是他是一个用户,所以对用户信息的更新是至关重要的。但是用户数据的更新不可能放在客户端,当你界面提供了上传imsi.mac.phonenumber等字段到服务端时,用户会义无反顾的选择否。如果你偷偷上传用户的隐私数据到数据库,这是国内通用做法。不排除被用户控告的可能性。所以我们要想一起两全其美的办法。每一次都把这些信息上传上去,美其名曰:唯一标识用户。至于其它的数据,那是运营哥需要的数据,可以在数据中加上。

    {  
    "context": {  
    "userID": "1",  
    "pwd": "fuckGfw",  
    "imei": "353641012835017",  
    "imsi": "460000000000000"  
    },  
    "reqType": {  
    "rt": "xxx"  
    }  
    }

    每次把context中的参数进行更新,保持你所拥有的用户数据是真实值钱的。其中的rt字段为每次请求的目的(请求类型),它用来区分每次请求上来 我们需要调用那一台服务器的服务来处理请求。 

    服务架构和数据已经准备OK,我们接下来coding.

    1:请求入口的承载类型选取

    你是选择传统的.aspx页面为入口还是ashx还是wcf/wcfRest/WebApi 这个自由度很大,具体在项目中的选择主要看心情。我心情不好,所以选择.aspx页面。

    主入口为Default.aspx页面,代码如下

       1:   protected void Page_Load(object sender, EventArgs e)
       2:   {
       3:      if(!IsPostBack)
       4:      {
       5:          try
       6:          {
       7:          }
       8:          catch (Exception exc)
       9:          {
      10:          }
      11:      }
      12:   }

    在主入口处加一个大范围的catch,而在catch中输出系统忙。嗯,美其名曰:用户体验。

    对json的压缩我使用了GZip,代码如下:

       1:      public static class CompressionHelper
       2:      {
       3:          /// <summary> 
       4:          /// Compress the byte[] 
       5:          /// </summary> 
       6:          /// <param name="input"></param> 
       7:          /// <returns></returns> 
       8:          public static byte[] Compress(byte[] input)
       9:          {
      10:              byte[] output;
      11:              using (MemoryStream ms = new MemoryStream())
      12:              {
      13:                  using (GZipStream gs = new GZipStream(ms, CompressionMode.Compress))
      14:                  {
      15:                      gs.Write(input, 0, input.Length);
      16:                      gs.Close();
      17:                      output = ms.ToArray();
      18:                  }
      19:                  ms.Close();
      20:              }
      21:              return output;
      22:          }
      23:   
      24:          /// <summary> 
      25:          /// Decompress the byte[] 
      26:          /// </summary> 
      27:          /// <param name="input"></param> 
      28:          /// <returns></returns> 
      29:          public static byte[] Decompress(byte[] input)
      30:          {
      31:              List<byte> output = new List<byte>();
      32:              using (MemoryStream ms = new MemoryStream(input))
      33:              {
      34:                  using (GZipStream gs = new GZipStream(ms, CompressionMode.Decompress))
      35:                  {
      36:                      int readByte = gs.ReadByte();
      37:                      while (readByte != -1)
      38:                      {
      39:                          output.Add((byte)readByte);
      40:                          readByte = gs.ReadByte();
      41:                      }
      42:                      gs.Close();
      43:                  }
      44:                  ms.Close();
      45:              }
      46:              return output.ToArray();
      47:          }
      48:      } 

    压缩完json后,还需要加密,别脑残的说MD5,小心我抽你。这个看你对数据的安全性如何看待。如支付宝用的RSACryptoServiceProvider加密,如asp.net的ViewState用的base64编码。其实用什么编码无所谓,你只需要定制属于你自己的码表。代码我就不贴了,我怕把我1个月100块的保密费弄成10000的律师费。。。

    接下来到重点了。你反序列化时可以使用Linq to Json或者Newtonsoft.json随便得到了rt字段的类型。一般同学就开始这样写了:

       1:              switch (rt)
       2:              {
       3:                  case"":
       4:                      break;
       5:                  default:
       6:                      break;
       7:              }

    这样写没错,但是如果你的rt类型比较多了以后就会出现很长很长的流水代码。所以这个地方我更加建议使用依赖注入。接下来就是具体的业务逻辑处理、数据处理。

    整片写完,仔细看看这架构,有什么难度?有什么难点?有什么值钱的地方?值得商榷。

  • 相关阅读:
    python 并发编程 多线程 event
    python 并发编程 多线程 定时器
    python 并发编程 多线程 信号量
    linux top 查看CPU命令
    python 并发编程 多线程 GIL与多线程
    python 并发编程 多线程 死锁现象与递归锁
    python 并发编程 多线程 GIL与Lock
    python GIL全局解释器锁与互斥锁 目录
    python 并发编程 多线程 GIL全局解释器锁基本概念
    执行python程序 出现三部曲
  • 原文地址:https://www.cnblogs.com/sunminmin/p/4230200.html
Copyright © 2020-2023  润新知