移動App服務端架構設計


我從事手機app服務端開發現在已經是3個年頭,自己也整理出了一套相對好用的服務架構,寫出來,跟大家一起分享。如有不足,還請多指教。

一:基礎流程圖。

image

其實有一點還需要加上,就是對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:   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后,還需要加密,這個看你對數據的安全性如何看待。如支付寶用的RSACryptoServiceProvider加密,如asp.net的ViewState用的base64編碼。其實用什么編碼無所謂,你只需要定制屬於你自己的碼表。

接下來到重點了。你反序列化時可以使用Newtonsoft.json隨便得到了rt字段的類型。一般同學就開始這樣寫了:

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

這樣寫沒錯,但是如果你的rt類型比較多了以后就會出現很長很長的流水代碼。所以這個地方我更加建議動態,避免大串大串if else if。接下來就是具體的業務邏輯處理、數據處理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM