如何用Golang開發一個短鏈接服務 使用map內存存儲實現

golangmap實現短鏈接服務的核心是通過兩個map維護長短鏈雙向映射,配合自增id生成base62短串,并通過http接口提供生成和跳轉功能。1. 使用shorttolong和longtoshort兩個map實現雙向映射,避免重復生成相同短鏈;2. 通過自增id結合base62編碼生成唯一短標識符;3. 利用net/http庫創建shorten接口接收長鏈接生成短鏈、redirect接口根據短鏈跳轉原鏈接;4. 數據存儲于內存適合原型開發,但需注意重啟丟失、并發安全及沖突風險。

如何用Golang開發一個短鏈接服務 使用map內存存儲實現

短鏈接服務的核心是將一個長 URL 映射成一個簡短的字符串,用戶訪問這個短串就能跳轉到原始地址。如果你只是想快速實現一個基礎版本,用 golang 的 map 做內存存儲是一個簡單又直接的辦法。

如何用Golang開發一個短鏈接服務 使用map內存存儲實現

下面我們就來看看怎么一步步用 Golang + map 實現一個最簡單的短鏈接服務。

如何用Golang開發一個短鏈接服務 使用map內存存儲實現


1. 設計數據結構和映射關系

我們使用兩個 map 來保存長短鏈接之間的雙向映射:

立即學習go語言免費學習筆記(深入)”;

  • 一個用于短鏈 → 長鏈(供跳轉時查找)
  • 一個用于長鏈 → 短鏈(避免重復生成)
var shortToLong = make(map[string]string) var longToShort = make(map[string]string)

這樣設計的好處是,當用戶提交相同的長鏈接時,我們可以直接返回之前生成的短鏈接,而不是每次都生成新的。

如何用Golang開發一個短鏈接服務 使用map內存存儲實現


2. 生成短鏈接標識符

短鏈接的關鍵在于生成一個唯一的、較短的字符串作為標識。常見做法是使用 Base62 編碼(0-9a-zA-Z),也可以結合遞增 ID 或隨機生成。

這里我們采用一個簡單的自增 ID 方式,每次生成后轉換為 Base62:

func generateShortKey(id int) string {     const base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"     result := ""     for id > 0 {         id--         result = string(base62[id%62]) + result         id /= 62     }     return result }

比如 ID=1 會生成 “a”,ID=10000 會生成 “27g”,足夠簡潔且不易沖突。


3. 處理請求邏輯

我們使用 Go 的標準庫 net/http 搭建一個簡單的 HTTP 服務,包含兩個接口:

  • /shorten:接收長鏈接,返回短鏈接
  • /{key}:根據短鏈接 key 跳轉到原鏈接

接口一:生成短鏈接

var counter = 1  func shortenHandler(w http.ResponseWriter, r *http.Request) {     longURL := r.URL.Query().Get("url")     if longURL == "" {         http.Error(w, "Missing 'url' parameter", http.StatusBadRequest)         return     }      if short, exists := longToShort[longURL]; exists {         fmt.Fprintf(w, "Short URL: http://localhost:8080/%sn", short)         return     }      short := generateShortKey(counter)     counter++      shortToLong[short] = longURL     longToShort[longURL] = short      fmt.Fprintf(w, "Short URL: http://localhost:8080/%sn", short) }

接口二:跳轉處理

func redirectHandler(w http.ResponseWriter, r *http.Request) {     parts := strings.Split(r.URL.Path, "/")     if len(parts) < 2 || parts[1] == "" {         http.Error(w, "Invalid short URL", http.StatusBadRequest)         return     }      key := parts[1]     if longURL, exists := shortToLong[key]; exists {         http.Redirect(w, r, longURL, http.StatusFound)     } else {         http.NotFound(w, r)     } }

然后注冊路由并啟動服務:

func main() {     http.HandleFunc("/shorten", shortenHandler)     http.HandleFunc("/", redirectHandler)      fmt.Println("Starting server at :8080")     if err := http.ListenAndServe(":8080", nil); err != nil {         log.Fatal(err)     } }

4. 測試一下

你可以通過瀏覽器或者 cURL 來測試:

  • 生成短鏈接:

    curl "http://localhost:8080/shorten?url=https://example.com/really-long-path?query=abc"
  • 訪問短鏈接跳轉:

    curl -v http://localhost:8080/a

注意事項和優化空間

雖然上面的方法已經能跑起來,但還是有些需要注意的地方:

  • 重啟數據丟失:因為數據存在內存里,程序重啟就會清空。如果要持久化,可以考慮加個文件或數據庫寫入。
  • 并發安全問題:多個請求同時操作 map 可能會有競態條件??梢杂?sync.Mutex 或者換成 sync.Map。
  • 短鏈沖突風險:如果使用隨機生成而不是自增 ID,需要檢查是否已存在該 key。
  • 性能限制:內存存儲適合小規模使用,如果數據量大了就需要上 redis 這樣的緩存系統。

基本上就這些。用 map 實現短鏈接服務雖然簡單,但很適合練手或做原型開發。等你熟悉流程后,再擴展功能、換存儲方式都不難。

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享