如何用Go實現一款類似滴滴優步的網路約車軟體(含源碼)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

導讀:我們經常使用打車軟體出行,也經常思考其架構設計。本文作者在所在國家也負責開發一款打車軟體,並且開源了其中大部分代碼,可以協助我們更好瞭解網路約車軟體的架構體系。本文由高可用架構翻譯。



各位讀者好,本文將給大家分享我們如何通過記憶體儲存實現地圖動畫車效果。 我們公司也運營了一個類似 Uber 的軟體 Namba Taxi,我們需要在用戶端主畫面上顯示動畫車。 這篇文章是關於功能如何完整實現的文章,主要目的不是介紹 Go 語言。


開始


這個故事始於2015年,我們的移動開發人員開發一款軟體,工作主題是為出租車司機提供打車服務。 在應用程式中,動畫汽車看起來像下面的圖中動畫那樣 [1] 。




我們的第一個挑戰是缺乏地圖跟蹤資料。我們每 15 秒擷取一次位置資料。 我們不能簡單減小上報間隔,因為當司機端程式上行資料時候,同時需要擷取當前訂單,下一個訂單,以及一些警報功能(一個SOS按鈕, 當司機按下它,其他司機就可以協助他)。當我們減少更新間隔時,系統流量更大。 我們不確認我們是否能夠扛住如此大的重新整理。


實現的第一步


我們第一次的嘗試比較簡單:


  1. 處理請求並儲存座標。

  2. 建立另一個請求並為汽車設定動畫。


顯而易見,這樣做存在一些問題,如大家在一些打車軟體所見,我們不能正確地繪製汽車路線,汽車可能跑在田野,森林,湖泊和公寓上,用這種方法後效果看起來是這樣的 [2]。



作為問題的解決方案,我們使用 OpenStreetMap Routeing Machine(OSRM)來規劃線路並改進我們的演算法,並使用相同的逾時設定。


  1. 發起請求。

  2. 擷取座標。

  3. 將儲存的座標發送到伺服器。

  4. 通過 OSRM 構建路線。

  5. 返回資料到用戶端。


通過線路規劃體系,現在似乎可以工作了,但我們又面臨單向道路的問題



例如,司機停留在紅點的十字路口。 但他的裝置位置準確性有問題,導致資料標記在十字路口的對面。 在用戶端,我們擷取這些座標,儲存並發送到後端,OSRM 建立一個合法的路線,並返回給應用程式。因為用戶端移動得非常快,所以這種情況路線規劃很可笑。

我們以一種樸素的方式解決了這個問題。 我們檢查兩點之間的最短距離,並且不建立距離小於 20 米的路線。 使用該演算法經過幾天的測試後,我們決定發布我們的應用程式並希望擷取一些反饋。

儘管如此,我們的版本還存在一些問題,所以我們決定進行第二次迭代。


  1. 第一是車費計算機,計算是在司機端(用戶端)完成,這樣避免發送無用的請求,可以節約很多服務端資源。 另一方面,為了安全等方面考慮,我們需要在伺服器端複製資料並儲存它。

  2. 此外,我們意識到每 15 秒一次上報太少,因為使用者在螢幕開啟後,15秒後才會看到車在移動。

  3. 此外,我們在司機端的 GPS 模組有很多問題,這個可能跟司機的手機裝置相關。

  4. 最後,我們想要在主畫面上渲染動畫車。


還需要解決的問題


  1. 從司機收集更多的資料

  2. 在主畫面上顯示動畫車

  3. 在伺服器端儲存行車過程中計費資料

  4. 節約移動流量

  5. 每秒收集一次資料


我想談一談有關節約移動流量頻寬的問題。在我們國家,出租車收費非常便宜,我們像使用公用交通那樣使用出租車。 例如,從城市的一邊跑到另一邊可能只需要 2 歐元,這就跟在巴黎坐地鐵價格差不多。但另外一方面移動頻寬成本還也很高,如果我們每秒節約 100 位元組,那麼我們將給為公司節省差不多 2000 美元。


資料追蹤


  1. 司機位置(緯度,經度)

  2. 司機當前的 session 資訊,在登入時我們會給司機端提供 session id

  3. 訂單資訊(訂單 ID 和車費)


我們決定每一次資料上報應小於 100 位元組。 我們尋找傳輸協議來解決這個問題

正如你可以看到,我們審視了以下幾個協議:


  1. HTTP

  2. WebSockets

  3. TCP

  4. UDP


對我們來說理想的選擇是 UDP,因為:


  1. 我們只發送資料報

  2. 我們不需要保證送達

  3. 極簡主義

  4. 儲存大量資料

  5. 只有 20 位元組開銷

  6. 在我們的國家的移動網路沒有被阻止


至於資料序列化,我們考察了:


  1. JSON

  2. MsgPack

  3. Protobuf


我們選擇 ProtoBuf,因為它對小資料非常有效。



以看到最近的競爭者是 PB 的三倍。(小編:可以參考 TimYang 的一條微博 [3] )


每次上報總共的資料


  1. 42 位元組的業務資料

  2. 加上 20 位元組的 IP 前序

  3. 得到每次上報 62 位元組資料


當我們獲得資料時,我們考慮如何儲存。


資料存放區


我們需要儲存這些資料:


  1. 標識司機的會話資訊 session id

  2. 車牌號

  3. 訂單 ID 和計費資訊

  4. 執行搜尋的最後位置

  5. N 次最後位置以規劃路線


使用的儲存


  1. 使用 Percona 儲存所有資料。 我們儲存司機,訂單,計費等。

  2. Redis 作為用於緩衝。

  3. Elasticsearch 用於地理編碼


如上所述,當有大量線上司機時候,使用這些儲存來儲存資料並不方便。 所以我們需要地理索引。

我們評估了兩個地理索引:


  1. KD 樹

  2. R 樹。


我們對地理索引的要求:


  1. 搜尋 N 個最近的點。

  2. 我們需要一個平衡樹,以在最糟糕的情況下提供最好的搜尋


KD 樹

KD 樹並不適合我們的需要,因為它是不平衡的,只能搜尋一個最近的點。 我們可以在 kd-tree 上實現 k-nearest 鄰居,但是沒必要重造輪子,因為 R-tree 已經解決了這個問題。


R-樹



它看起來像這樣。 我們可以執行搜尋 N 個最近點,並且它是平衡樹。 我們選擇了這個。

您可以得到它的 Go 語言實現源碼 [5]。


另外,我們需要一個到期機制,因為我們需要使司機的逾時機制,比如司機端 900 秒沒有響應則在伺服器刪除會話。 所以我們需要 LRU 資料結構來儲存最後的位置。 同時因為我們只儲存 N 個位置。 如果我們嘗試添加資料時候,佇列儲存體已滿,我們則刪除最少使用的那個條目。 


下面是我們的儲存架構。


  1. 我們將所有資料存放區在記憶體中。

  2. 我們使用 R-tree 執行搜尋最近的司機

  3. 此外,我們使用兩個檢索圖,可以並按車牌號或session執行搜尋


我們打車軟體最終演算法


這裡是後端的最終演算法:


  1. 使用 UDP 傳輸資料

  2. 嘗試從儲存擷取司機

  3. 如果儲存不存在 - 則從 Redis 擷取司機

  4. 檢查並驗證資料

  5. 將司機儲存到儲存

  6. 如果不存在 - 初始化 LRU

  7. 更新 r-tree


HTTP 介面


我們實現了這些介面:


  1. 返回最近的司機;

  2. 從儲存中刪除司機(通過車牌號或session id)

  3. 擷取行程資訊

  4. 擷取司機資訊


結論


最後,我想給出我們在後端系統中總結的經驗:


  1. UDP + Protobuf 以節省資料

  2. 記憶體儲存

  3. R 樹擷取最近的司機

  4. LRU 緩衝用於儲存最後的 n 個位置

  5. OSRM 用於地圖匹配和定製路線




您可以在 github [5] 上查看上面整個過程的原始碼。現在功能還比較簡單,但實現了文章中描述的許多功能。


參考資源

  • GIF 動畫下載
  • http://weibo.com/10503/24F1QpDmL
  • https://github.com/dhconnelly/rtreego
  • https://github.com/maddevsio/openfreecabs
  • 本文英文原文

推薦閱讀


  • Uber容錯設計與多機房容災方案

  • 為什麼Uber宣布從Postgres切換到MySQL?

  • 滴滴passport設計之道:帳號體系高可用的7條經驗(含PPT)


本文由高可用架構翻譯,轉載請註明出處,技術原創及架構實踐文章,歡迎通過公眾號菜單「聯絡我們」進行投稿。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.