Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 395|回复: 0

[默认分类] 移动App服务端架构设计

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-12 17:21:11 | 显示全部楼层 |阅读模式
    我从事手机app服务端开发现在已经是3个年头,自己也整理出了一套相对好用的服务架构,写出来,跟大家一起分享。如有不足,还请多指教。
    一:基础流程图。

    其实有一点还需要加上,就是对json的压缩和加密,一来给用户节约流量,二来防止请求被截取破解我们的参数。具体先压缩后加密还是先加密后压缩这个问题看需求。
    看到这个架构设计时,你们可能会说如果程序入口挂了,所有的服务都不可以用了。
    所以这个架构的弱点在程序入口处,因此要有一(多)台机器做负载,负载的工具可以是HaProxy(软件)或者F5(硬件)的负载。F5比较昂贵,我没用过,haproxy的配置我就不贴了,谷歌一大把。
    二:Json参数设计
    手机App的灵魂是用户数,有了用户数才有一切。据我得到的数据,一款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.    1:   protected void Page_Load(object sender, EventArgs e)
    复制代码
    1.    2:   {
    复制代码
    1.    3:      if(!IsPostBack)
    复制代码
    1.    4:      {
    复制代码
    1.    5:          try
    复制代码
    1.    6:          {
    复制代码
    1.    7:          }
    复制代码
    1.    8:          catch (Exception exc)
    复制代码
    1.    9:          {
    复制代码
    1.   10:          }
    复制代码
    1.   11:      }
    复制代码
    1.   12:   }
    复制代码



    在主入口处加一个大范围的catch,而在catch中输出系统忙。嗯,美其名曰:用户体验。
    对json的压缩我使用了GZip,代码如下:

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


    压缩完json后,还需要加密,这个看你对数据的安全性如何看待。如支付宝用的RSACryptoServiceProvider加密,如asp.net的ViewState用的base64编码。其实用什么编码无所谓,你只需要定制属于你自己的码表。
    接下来到重点了。你反序列化时可以使用Linq to Json或者Newtonsoft.json随便得到了rt字段的类型。一般同学就开始这样写了:

    1.    1:              switch (rt)
    复制代码
    1.    2:              {
    复制代码
    1.    3:                  case"":
    复制代码
    1.    4:                      break;
    复制代码
    1.    5:                  default:
    复制代码
    1.    6:                      break;
    复制代码
    1.    7:              }
    复制代码


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

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-25 08:08 , Processed in 0.347226 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表