← 回所有專案

獨立開發 ‧ 房仲業 · 2022

加盟房仲平台

獨立開發集團旗下所有加盟房仲品牌的網站平台。架構與主力平台相同——由買屋中台等資料中台提供查詢、背後以 Elasticsearch 支撐關鍵字與 GEO 搜尋——差別在於資料來源:透過 RabbitMQ 即時接收主力平台的物件事件,挑出加盟物件同步進加盟專用的索引。是公司第一個完全容器化的對外網站,也是第一個採用 Elasticsearch 的專案。

C#ASP.NET CoreAngularExpressRabbitMQElasticsearchElasticsearch GEOMSSQLDocker
加盟房仲平台

專案概述

集團除了直營的主力品牌之外,旗下還有多個加盟房仲品牌,每個品牌都有自己的 對外網站。這個專案由我獨立設計並開發,負責所有加盟品牌網站背後的平台:從 資料同步、資料中台、搜尋,到各品牌的前端網站。

加盟品牌的物件資料,原本就是由各加盟店在集團的主力平台上建檔、維護,加盟網站要 做的是把屬於加盟品牌的物件即時拿過來,再依品牌呈現在各自的網站上。所以整體 架構和主力平台很像,最大的差別在於資料來源:

主力平台加盟平台
資料來源直接來自 MSSQL 原始資料接收主力平台發布的物件事件
資料範圍直營物件只挑出加盟品牌的物件
查詢方式買屋中台等資料中台 + Elasticsearch買屋中台等資料中台 + Elasticsearch
對外網站一個品牌多個加盟品牌網站

這也是公司第一個完全容器化的對外網站,以及第一個正式採用 Elasticsearch 的專案。

系統架構

加盟房仲平台架構圖:集團主力平台發布物件異動事件到 RabbitMQ,同步消費者只挑出加盟物件並轉成加盟用的資料格式,寫入 MSSQL 持久化、寫入 Elasticsearch 供查詢;加盟物件資料中台以 ASP.NET Core Web API 查詢 Elasticsearch,提供買屋搜尋、GEO 鄰近推薦與四大區推薦排序給各加盟品牌網站

整個平台分成三層:

  • 資料同步:透過 RabbitMQ 接收主力平台的物件事件,挑出加盟物件後,同時寫入 加盟專用的 MSSQL(持久化)與 Elasticsearch(查詢)
  • 資料中台:以 ASP.NET Core Web API 實作的加盟物件資料中台,包含買屋中台 等服務,所有查詢都走 Elasticsearch
  • 品牌網站:各加盟品牌的前端網站,透過中台取得資料,只呈現屬於自己品牌的物件

資料同步:從主力平台接收物件事件

加盟物件在主力平台上建檔之後,加盟網站要「馬上」看得到;物件改價、下架,加盟網 站也要同步反映。如果用排程定期去主力平台的資料庫撈資料,不只會有時間差,也會讓 加盟平台和主力平台的資料庫綁死在一起。

所以改成事件驅動:主力平台在物件新增、修改、下架時發布事件到 RabbitMQ,加 盟平台訂閱這些事件:

  1. 過濾:收到事件後,先判斷這筆物件是否屬於加盟品牌,不是就直接略過
  2. 轉換:把主力平台的物件格式,轉成加盟平台需要的資料結構,並標上所屬的 加盟品牌
  3. 寫入:同時寫入加盟專用的 MSSQL 與 Elasticsearch;下架事件則把物件從索引中 移除

這樣的好處是兩個平台只透過事件溝通:主力平台不需要知道有哪些系統在接收它 的事件,加盟平台也不需要讀主力平台的資料庫。日後主力平台內部怎麼改,只要事件 格式不變,加盟平台都不受影響。

加盟物件資料中台

和主力平台一樣,加盟平台也把查詢收斂到資料中台,前端網站不直接碰資料庫。 中台以 ASP.NET Core Web API 實作,包含買屋中台等服務,背後全部查詢加盟專用 的 Elasticsearch。

所有加盟品牌共用同一套中台,查詢時帶上品牌條件,每個品牌網站就只會拿到自 己的物件。新增一個加盟品牌時,不需要再複製一套後端,只要加上品牌的設定即可。

物件搜尋

  • 關鍵字搜尋:可以用區域、路名、社區名稱、捷運站等關鍵字找物件
  • 多條件篩選:總價、坪數、房數、屋齡、物件類型等條件組合查詢
  • GEO 鄰近物件推薦:每筆物件建立索引時就把經緯度存成 geo_point,物件詳細頁 以目前物件為中心,用 geo_distance 找出附近的其他物件並依距離排序

四大區推薦排序

首頁與推薦區塊的物件,依台灣北、中、南、東四大區計算並排序:使用者所在或正 在瀏覽的區域,優先推薦同區的物件,再依序帶出其他區域。加盟店遍布全台,這樣能讓 各地的使用者先看到離自己近、真正有機會去看屋的物件,而不是被單一區域的大量物件 洗版。

前端:Angular + Express

房仲網站非常依賴搜尋引擎流量,物件頁一定要能被 Google 正確收錄。原本的做法 是 Angular 搭配 ASP.NET Core MVC 來處理 SEO,前後端技術混在一起,部署和維護都 比較麻煩。

這次把前端改成 Angular + Express:由 Express 負責在伺服器端渲染頁面,搜尋 引擎拿到的是完整的 HTML,使用者進到頁面後再由 Angular 接手互動。前端與後端 API 各自獨立,也各自打包成容器部署。

各加盟品牌的網站共用同一套前端架構,依品牌設定切換配色、Logo 與版型,品牌 之間的差異集中在設定裡,不需要為每個品牌各維護一份程式碼。

容器化

這是公司第一個完全容器化的對外網站:前端(Angular + Express)、資料中台 (ASP.NET Core)、同步消費者都各自打包成 Docker 映像部署。

當時公司其他網站都還跑在 IIS 上,並且依賴大量的記憶體快取撐住查詢流量,每 個站台都吃掉大量記憶體。加盟平台因為查詢全部改走 Elasticsearch,不需要在應 用程式裡放記憶體快取,服務本身是無狀態的,也才能順利容器化、隨流量增減實例。

成果

  • 一套平台支撐集團所有加盟品牌網站,新增品牌只需要加上設定
  • 加盟物件透過事件即時同步,主力平台上架、改價、下架,加盟網站同步反映
  • 公司第一個完全獨立開發、對外的容器化專案
  • 公司第一個移除記憶體快取、解決 IIS 浪費大量記憶體資源問題的專案
  • 公司第一個正式採用 Elasticsearch 的專案

使用技術

  • 後端:C#、ASP.NET Core Web API
  • 前端:Angular、Express(伺服器端渲染)
  • 資料:Elasticsearch(geo_point、geo_distance)、MSSQL
  • 訊息:RabbitMQ
  • 部署:Docker