2.1 從App業務邏輯中提煉API接口
業務邏輯思維導圖
功能-業務邏輯思維導圖
基本功能模塊關系
功能模塊接口UML(設計出API)
在設計稿標注API
編寫API文檔
2.2 設計API的要點
根據對象設計API
API的命名
API的安全性
API所返回的數據:禁止返回Null值
圖片的處理:圖片數據庫保存原圖,在App客戶端本地緩存圖片不存在時,按圖片尺寸向服務端請求動態生成。
返回的提示信息:給用戶看的提示和給程序員看的提示。
在線API測試文檔:使用Swagger-UI搭建,按TDD(測試驅動開發)原則進行開發。
在App客戶端啟動時調用一個API獲取必要的初始化信息:比如App版本
關于API的版本升級問題:V2版本的API的Controller必須要繼承V1版本的Controller,V2版本的API只重寫需要改動的API。
2.3 如何選擇合適的數據庫產品
2.3.1 Redis、MongoDB、MySQL讀寫數據的區別
Redis的數據是存放在服務器的內存,當內存用滿了后需要擴容,就只能使用Redis的分布式方案。為了防止斷電或Redis程序重啟造成內容數據的丟失,可調整Redis配置文件,按照一定的策略把數據持久化傳到硬盤。
MongoDB同時使用了硬盤和內存,其使用了操作系統提供的MMAP(內存文件映射)機制進行數據文件的讀寫,MMAP可以把文件直接映射到進程的內存空間中,這樣文件就會在內存中有對應的地址,這時對文件的讀寫是能通過操作內存進行的,而不需要使用傳統的如fread、fwrite文件操作方式。
MySQL的數據是放在硬盤中的。雖然MySQL也有緩存,但MySQL緩存的是查詢的結果,而不是緩存數據。
2.3.2 Redis、MongoDB、MySQL查找數據的區別
Redis的數據是基于“鍵值對”存儲。Redis查找數據,每次都是直奔目標,讀寫速度當然快。
MongoDB和MySQL中查找數據,有兩種模式:知道id或索引,不知道id或索引。前者直奔目標,效率高;后者逐個查找,效率低。
2.3.3 Redis、MongoDB、MySQL適用場景
Redis適用場景:讀寫頻率高的數據、熱點數據。
MongoDB適用場景:網站數據(實時的插入、更新與查詢),大尺寸、低價值的數據,高伸縮性的場景(數十或者數百臺服務器組成的數據庫),存儲地理坐標的數據;不適合高度事務性的系統、傳統的商業智能應用及需要復雜SQL的問題。
MySQL適用場景:事務性的系統(涉及金錢),需要復雜SQL的問題。
2.4 如何選擇消息隊列軟件
2.4.1 為什么使用消息隊列
將一些需要花比較多的時間,而且遲點完成不影響整個任務的完成進度的小任務,放到消息隊列中,可加快后臺請求的響應時間;比如發送郵件、發送短信、推送消息等任務就非常適合放到消息隊列中。同時消息隊列也能把大量的并發請求變成串行的請求,減輕服務器的負擔。
2.4.2 消息隊列的工作流程
App后臺(隊列生產者)把消息推入到消息隊列;
守護進程(隊列消費者)不斷地檢測消息隊列中有沒有新的消息,沒有消息就休息一會兒再檢測消息隊列中有沒有新的消息(這樣做能避免消息隊列占據過多的服務器資源),有消息的話就從消息隊列取出消息,用新的線程處理相關的業務,在主線程中繼續檢測消息隊列是否有新消息。
2.4.3 常見的一些消息隊列產品
RabbitMQ:重量級的消息隊列,適合企業級的開發,其支持大量的協議,比如AMQP、XMPP、SMTP、STOMP;同時RabbitMQ自帶了一個Web監控界面,可方便監控隊列的情況。
Redis:雖然是一個key-value系統,但其也支持隊列這種數據格式,可看作是一個輕量級的消息隊列。在App后臺架構中Redis被廣泛使用,如果把其作為消息隊列,能減少項目中的運維成本。
ZeroMQ:號稱最快的消息隊列,尤其針對大吞吐量的需求場景。
ActiveMQ
2.5 使用分布式服務實現業務的復用
隨著業務不斷增加,后臺系統由一個單一的應用慢慢膨脹為一個巨無霸系統,它聚合了大量的應用和服務,各個模塊之間由很多功能重復實現,造成了開發、運維、部署的麻煩。
2.5.1 巨無霸系統的危害
維護上的麻煩
代碼管理上的不方便
數據庫連接資源的耗盡
2.5.2 遠程服務的優點
把重復實現的模塊獨立部署為遠程服務,新增的業務調用遠程服務所提供的功能實現相關的業務,不依賴于里面具體的代碼實現。當遠程服務里面的業務需要發生變化時,只要接口的傳入參數和返回值保持不變,就不會影響到調用這些遠程服務的業務。
2.5.3 遠程服務的實現
REST
REST(Representational State Transfer),即表述性狀態傳遞,它是一組架構約束條件和原則。滿足這些約束條件的原則的應用程序或設計就是RESTful。
REST架構的特點:每一個URI代表一種資源;客戶端和App后臺之間,傳遞這種資源的某種表述;客戶端通過GET、POST、PUT、DELETE等HTTP動詞,對App后臺資源進行操作,實現“表述性狀態傳遞”。
REST設計原則中最重要的是請求是無狀態的。
RPC
RPC(Remote Procedure Call),即遠程過程調用,它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通信程序之間攜帶信息數據。在OSI網絡通信模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分布式多程序在內的應用程序更加容易。
開源的RPC庫
阿里巴巴開源Dubbo,其是一個分布式服務框架,致力于提供高性能和透明化的RPC遠程調用服務和SOA服務治理方案。
當當網在Dubbo的基礎上實現了如下的新功能,并將其命名為Dubbox。
支持REST風格遠程調用(HTTP+JSON/XML)。
支持基于Kryo和FST的Java高效序列化實現。
支持基于嵌入式Tomcat的HTTP remoting體系。
將Dubbo中Spring由2.x升級到目前常用的3.x版本。
將Dubbo中的Zookeeper客戶端升級到最新的版本,以修正老版本中包含的bug。
2.6 搜索技術入門
常見的開源搜索軟件介紹
復制代碼
<?xml version="1.0" encoding=www.venkeng.com/ "utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
</configSections>
<unity>
<typeAliases>
<typeAlias alias="IEarPhone" type="Xu.UnityDemo.Interface.IEarPhone,Xu.UnityDemo" />
<typeAlias alias="IPhone" type=www.qwert888.com"Xu.UnityDemo.Interface.IPhone,Xu.UnityDemo" />
<typeAlias alias="NubiaPhone" type="Xu.UnityDemo.Model.NubiaPhone,Xu.UnityDemo" />
<typeAlias alias="MiPhone" type="Xu.UnityDemo.Model.MiPhone,Xu.UnityDemo" />
<typeAlias alias="NubiaEarPhone" type="Xu.UnityDemo.Model.NubiaEarPhone,Xu.UnityDemo" />
<typeAlias alias="MiEarPhone" type="Xu.UnityDemo.Model.MiEarPhone,Xu.UnityDemo" />
</typeAliases>
<containers>
<container name="IOCcontainer">
<type type="IPhone" mapTo="MiPhone" name="Mi"></type >
<type type="IPhone" mapTo="NubiaPhone"></type >
<type type="IEarPhone" mapTo="NubiaEarPhone"></type >
</container>
</containers>
</unity>
</configuration>
復制代碼
主要用到兩個節點<typeAlias>和<type>。<typeAlias>節點的alias是別名在<type>節點中的type使用,type是“命名空間+對象名,所在程序集名稱”。<type>節點的type是“需要映射的對象”mapTo是“映射的目標對象”name是“標識名”在多個類繼承同個接口的時候區分使用。其余的節點如圖Unity配置文件節點圖。
代碼如下:
復制代碼
ExeConfigurationFileMap fileMap =www.yunshengyule178.com new ExeConfigurationFileMap();
fileMap.ExeConfigFilename www.fengshen157.com/= Directory.GetCurrentDirectory() + "/Config/UnityIocConfig.xml";
Configuration configuration =www.bais7.com ConfigurationManager.www.mhylpt.com/ OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
//獲取特定配置節下已命名的配置節<container name="IOCcontainer">下的配置信息
section.Configure(_container, "IOCcontainer");
復制代碼
五、三種依賴注入
1、構造函數注入
構造函數注入是最常用的一種注入方式,如下:
復制代碼
private IPhone _iPhone;
private IUnityContainer _container;
public ValuesController(www.yisengyule.com IUnityContainer container, IPhone iPhone)
{
_container = container;
_iPhone = iPhone;
Lucene
Solr
ElasticSearch
Sphinx
CoreSeek
2.7 定時任務
Linux定時任務Crontab
Java定時任務框架Quartz