導語

本文通過結合實際的業務痛點,闡述瞭如何進行服務重構與性能優化,介紹了諸多實際落地方案。

背景

隨着租房業務的快速發展,業務系統開發人員在忙於業務系統快速迭代的過程中往往會忽視了系統本身的優化,需求不斷的累積,導致冗餘邏輯越來越多,代碼耦合度越來越高,開發迭代效率也變的大不如前。一個同樣的功能,集成在不同頁面,有時候需要寫多套同樣的邏輯代碼。在APP端尤其明顯,嚴重影響了用戶體驗和迭代效率,因此需要對業務系統做一次升級優化。

業務現狀

租房業務系統在2017年經歷過一次服務化改造和重構,解耦了核心的業務和服務,抽離出了幾個公共應用服務層,對於性能和開發效率都有一定的提升,然而隨着業務的快速迭代、變更,我們的業務系統也需要隨之升級。我們之前的業務系統是爲房產所有類目如租房、二手房、商業地產等而設計的,業務系統重點關注的是不同類目不同場景下,相同類型頁面的通用性以及擴展性。而2019年集團戰略調整,我們只專注於租房業務即可。這就需要我們在優化設計系統時重點對租房業務的快速發展以及未來的業務可能變化提前做好準備,避免以後系統反覆重構,浪費資源。當然也要考慮到避免過度設計,否則會帶來更高的維護成本和線上排查問題的難度。

問題&設計方案

1、開發效率方面  1.1、問題

  • 業務代碼長時間積累,可讀性差。

  • 單一接口,模塊衆多邏輯耦合,需求改動互相影響,不利於業務系統穩定性。

  • 相同模塊的擴展性,複用性差,影響迭代速度。

  • 各個系統職責模糊,流程不規範,不利於新人介入。

目前影響開發效率最主要的原因是由於業務調整業務層系統架構設計的擴展性和複用性差,不同頁面系統的相同模塊有產品邏輯迭代需要更改多個頁面系統。那麼如何更改系統架構提升系統的開發效率呢?
1.2、方案
1)拆分通用模塊系統
對現有的業務系統進行全局分析,分析出哪些通用模塊可以拆出單獨的系統,既需要考慮的業務的擴展性,又需要考慮的業務的差異性以及對於各個版本的兼容性。最後我們從原有的系統之上又拆分出了四個業務子系統,分別是推薦系統、列表系統、微聊電話系統、房東信息系統。

老系統結構圖VS新系統結構圖

2)子模塊不同頁面體驗一致:
統一交互&視覺規範,接口協議字段對齊且增加區分場景標識,保證各個頁面場景上的相同模塊業務邏輯保持一致。
3)統一系統流程規範
統一開發規範,統一各個系統職責規範,保證系統的單一職責性。
4) 通用模塊系統平滑遷移
由於新的公共模塊協議系統返回協議格式適配了所有APP迭代的版本,業務遷移的話成本還是比較低的。

  • 遷移方式採用內部系統互相調用的方式平移遷移,對上下游頁面系統無感知。

  • 採取灰度配置策略,保留老代碼邏輯增加灰度配置開關,實時監控,保證有問題隨時回滾。按照流量10%、20%、50%、100%逐步灰度放量直至全量。

1. 3.效果

  • 需求層面:支持單個系統快速迭代,以及多個系統互相組合適配出新的頁面,伸縮性強,支持業務場景最小成本的快速試錯。

  • 開發層面:各個系統模塊獨立開發,代碼解耦,維護成本低,職責更清晰。

  • 運維層面:各個系統獨立部署,單獨擴容,互不影響。

  • 實際效果:例如以下頁面都是根據拆分後的系統快速互相組合適配出的新頁面,以前開發週期至少2人/日,而現在基本上只需要幾個小時就能適配出來,大大提升了我們的開發效率,如下圖線上複用配置模塊:

2、用戶體驗方面  2.1、問題

  • 接口加載速度慢?

  • 用戶感知卡頓?

  • 接口拆分不合理?

  • 請求合併沒做到位?

2. 2、

解決方案

1)對接口異步拆分模塊數據緩存

a)根據實際功能頁面模塊拆分

b)首屏數據在沒有數據依賴的情況下儘量拆分成單獨接口

c)非首屏數據拆分異步接口實現

d)數據分級,根據級別設置緩存和數據超時時間

2)併發請求數據

a)數據之間有依賴無法併發去請求數據?例如租房詳情頁需要展示房源數據和小區數據,小區數據是根據房源數據裏返回的小區id獲取的,這就導致了這兩塊數據無法併發獲取,針對於這種情況我們可以對上游頁面做下分析,在不影響上游頁面性能的基礎上可把參數傳遞過來,達到併發效果。

b)併發如何實現?由於現有業務系統採用nginx+php-fpm架構,對於單個接口裏依賴的多個數據都是依次順序獲取,延時隨着需求迭代不斷的累加,又由於租房業務系統基本都是io密集型的場景,綜合考慮最終我們運用了nginx+swoole+php架構模式,利用swoole的協程進行請求合併。

3)核心數據內置

APP內置變化頻率較低的地域數據,地鐵數據,篩選項數據,以及一些通用配置數據,已達到更順暢的用戶體驗的效果。內置的數據支持主動和被動的更新機制,引入了數據版本概念在數據源切換時用戶能夠無感知平滑切換。

a)內置數據特點:變化頻率較低,使用頻率高,用戶體驗提升明顯。

例如地域、商圈、地鐵、學校等篩選項數據,以及一些通用配置數據。

b)通過和客戶端端約定規則,使內置的數據支持主動更新。

例如有時候會受一些政府政策影響,需要屏蔽一些區域或者商圈,並且需要馬上生效,我們通過現有的技術策略能根據服務端下發新的數據主動實時更新生效。

c)數據源切換時用戶無感知平滑切換。在底層數據源有切換時服務端根據數據版本的概念,針對於不同的版本用不同的邏輯去處理,例如租房的地鐵數據從a切到了b,如果服務端還用a的處理邏輯就有問題了,服務端會先上線a和b不同版本號的處理邏輯,之後在進行底層數據源切換。

在數據源進行切換時如下圖所示:

4)預加載&數據前置

預加載數據前置,就是把有依賴的數據在上一步預先準備好,怎麼做好前置數據依賴取決於你對上下游頁面邏輯的瞭解,以及上下游頁面系統技術棧的瞭解。

a)在不影響上游頁面性能前提下,把上游頁面與下游頁面重疊的數據直接帶到下游頁面,以達到預先加載數據的效果。

b)上游頁面與下游頁面重疊數據要提前規劃好,保證獲取數據邏輯的一致性。

c)預加載後的數據根據數據和業務場景特點決定是否進行數據覆蓋。

3、具體實例

1)APP租房大類頁

對於首屏的金剛位,先顯示後更新,接入配置平臺,數據緩存,異步更新。其餘模塊拆分接口異步加載。

2)APP列表頁

對地域、地鐵、學校等數據內置,預拉取篩選項本地選中高亮實時交互,列表頁接口拆分成篩選項接口、列表數據接口,非核心模塊數據、引流位數據超時拋棄上報。

3)APP詳情頁

首屏數據預加載列表頁帶入預加載數據, 接口拆分主房源接口+房東/經紀人模塊接口+小區模塊接口+推薦附近/同價位模塊接口,各個模塊基礎數據緩存,數據併發請求。

4、效果

主要場景

首屏渲染avg時間 服務接口avg耗時

優化前後對比

優化前後對比

APP大類頁 下降60% 下降65%
APP列表頁 下降55% 下降60%
APP詳情頁 下降72% 下降80%

團隊介紹

58租房技術部,負責58和安居客雙平臺的租房業務研發,業務上致力於提高租客和房東在房屋出租上的用戶體驗和效率,技術上我們採用PHP和JAVA的雙語言技術棧,業務流量、數據量、複雜度都比較高,在系統的性能、穩定性、研發的效率提升方面有豐富的技術積累,團隊技術氛圍濃厚。

作者簡介

果海濤,房產租房技術部。16年加入58同城先後負責從0到1的PHP技術棧的服務化重構、租客端業務,專注於業務系統架構和性能提升等工作。

相關文章