「lbs服務(wù)」從0開始做一個LBS服務(wù)(lbs系統(tǒng)是什么意思)

服務(wù) 做一個 lbs LBS| 2022-12-06 hwszkj

如果說移動互聯(lián)網(wǎng)時代區(qū)別與主機(jī)互聯(lián)網(wǎng)時代最大的革命是什么?大部分人都會認(rèn)為是LBS服務(wù),眾所周知的我們一款社交應(yīng)用,當(dāng)年就是靠著搖一搖跟查看附近的人,一發(fā)不可收,徹底掀起了移動互聯(lián)網(wǎng)的革命。今天我們介紹一下如何實(shí)現(xiàn)一個簡單的位置服務(wù)功能的架構(gòu)是什么樣子呢?

我們先從業(yè)務(wù)場景入手吧,之前我們團(tuán)隊(duì)是做共享充電寶的,我們經(jīng)常會遇到這樣的場景,尋找最近的共享充電寶在哪里。一開始,我們這個東西是這么實(shí)現(xiàn)的,對于每個共享充電寶站,都會存經(jīng)緯度坐標(biāo)在數(shù)據(jù)庫里面。每次用戶過來查詢身邊的充電寶,前端會把用戶的經(jīng)緯度坐標(biāo)帶上來,然后后臺從數(shù)據(jù)庫里面撈出所有的坐標(biāo),通過經(jīng)緯度計(jì)算距離,然后找出最小距離的共享充電寶倉庫出來。

慢慢的隨著業(yè)務(wù)的擴(kuò)展,充電寶倉庫越來越多,性能問題就顯現(xiàn)了,畢竟每次拿出全國門店的充電寶來比較,的確性能很差。即便我們把數(shù)據(jù)都緩存了,但依然改變不了很多無所謂的計(jì)算。

一個簡單的優(yōu)化是我們按照城市或者區(qū)域去分區(qū),然后每次只檢查同個區(qū)域的數(shù)據(jù),按照城市分區(qū)是一個比較簡單的方案,因?yàn)榫W(wǎng)上有很多API可以根據(jù)經(jīng)緯度而獲取到對應(yīng)的區(qū)號。這一個看似行之有效的優(yōu)化,卻引來了不少投訴。舉個例子,假如我們以城市分區(qū),那么有些在城市交界的服務(wù)點(diǎn),就會搜索不到。例如在廣州佛山的交接有個門店,卻在分區(qū)上歸屬與佛山,這個時候在廣州的邊界就會搜索不到,即便距離很短。

這便引出了我們今天的主角,GeoHash,將經(jīng)緯度編碼成字符串,可以起到一個降維的作用。如下圖,一般來說,兩個編碼前面相同的子字符串越多,說明他們越接近。具體的算法大家感興趣可以深入學(xué)習(xí)。

還好開源世界已經(jīng)幫我們提供了一個很好用的GeoHash庫了,那便是使用Redis。Redis將位置的數(shù)據(jù)存放在zset里面。并對我們提供了一些API,下面我們簡單的介紹一下。

1.我們從業(yè)務(wù)場景出發(fā),我們每新增一個共享充電寶的服務(wù)站,就需要插入這個服務(wù)站的坐標(biāo)信息,我們使用redis命令geoadd。

2.用戶查詢以自己為中心,附近的充電寶,我們可以使用redis命令georadius

3.后臺可能要拉去所有的門店列表,可以使用redis命令geodist