首頁 >後端開發 >Golang >在 Go 中建立具有速率限制和 Redis 的 URL 縮短器

在 Go 中建立具有速率限制和 Redis 的 URL 縮短器

Linda Hamilton
Linda Hamilton原創
2024-11-05 13:54:02587瀏覽

像 Bitly 或 TinyURL 這樣的 URL 縮短器是非常流行的工具,但您有沒有想過如何建立一個工具?在這篇部落格中,我們將深入探討如何在 Go 中建立具有速率限制的自訂 URL 縮短器以及用於資料儲存和 IP 追蹤的 Redis 資料庫。我們將介紹核心功能、技術堆疊以及我在過程中遇到的挑戰。

項目概況

此 URL 縮短器應用程式接受用戶的長 URL,產生更短的唯一鏈接,並允許用戶根據需要自訂縮短的別名。伺服器會將所有使用縮短 URL 的訪客重新導向到原始長 URL。

以下是主要組件的快速概述:

  • WebServer:使用 Fiber 框架處理路由和請求。
  • 速率限制器:管理使用者請求以防止濫用,限制 IP 在給定時間範圍內可以發出的請求數量。
  • URL 驗證器:確保 URL 的格式有效並準備好儲存。
  • URL 產生器:為每個長 URL 產生唯一的短連結或使用使用者提供的自訂別名。
  • Redis 資料庫:儲存 URL 對映和 IP 速率限制。

考慮到這些功能,讓我們分解實現。

Building a URL Shortener with Rate Limiting and Redis in Go

技術堆疊

  • Go:快速且高效,Go 是建立高效能 URL 縮短器的理想選擇。
  • Fiber:Go 中的 Web 框架,因其輕量級效能和簡單性而被選取。
  • Redis:記憶體資料庫,用於儲存 URL 映射和 IP 配額,為我們提供速度和持久性。
  • Docker:容器使 Redis 的設定變得簡單,並確保應用程式可移植和可擴展。

專案結構

核心文件和資料夾的組織方式如下:

.
├── main.go               # Entry point for the application
├── routes/
│   ├── shorten.go        # Handles URL shortening and redirects
├── database/
│   ├── redis.go          # Database connection logic
├── helpers/
│   ├── helper.go         # Utility functions for URL validation
├── .env                  # Environment variables
├── docker-compose.yml    # Docker setup for Redis

設定應用程式

1. 主伺服器邏輯(main.go)

我們的主應用程式檔案設定用於縮短和解析 URL 的路由。這是程式碼片段:

package main

import (
    "log"
    "os"

    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/fiber/v2/middleware/logger"
    "github.com/joho/godotenv"

    "github.com/ravikisha/url-shortener/routes"
)

func setupRoutes(app *fiber.App) {
    app.Get("/:url", routes.ResolveURL)
    app.Post("/api/v1", routes.ShortenURL)
}

func main() {
    err := godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }

    app := fiber.New()
    app.Use(logger.New())

    setupRoutes(app)

    log.Fatal(app.Listen(os.Getenv("APP_PORT")))
}

2. 速率限制和 URL 縮短 (shorten.go)

為了防止濫用,我們使用 Redis 來追蹤每個 IP 位址並限制允許的請求數量。流程如下:

  1. 檢查速率限制:當發出請求時,速率限制器會檢查 Redis 以查看該 IP 發出了多少請求。
  2. 處理 URL:如果未超過速率限制,伺服器將驗證 URL 並縮短它。
  3. 產生或使用別名:如果使用者提供自訂別名,我們會儲存它。否則,我們會產生一個唯一的 ID。
.
├── main.go               # Entry point for the application
├── routes/
│   ├── shorten.go        # Handles URL shortening and redirects
├── database/
│   ├── redis.go          # Database connection logic
├── helpers/
│   ├── helper.go         # Utility functions for URL validation
├── .env                  # Environment variables
├── docker-compose.yml    # Docker setup for Redis

3.Redis資料庫設定(redis.go)

在 redis.go 中,我們定義了一個輔助函數來連接到 Redis。此連線用於跨不同元件儲存短 URL 並實施速率限制。以下是如何設定 Redis 的簡單範例:

package main

import (
    "log"
    "os"

    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/fiber/v2/middleware/logger"
    "github.com/joho/godotenv"

    "github.com/ravikisha/url-shortener/routes"
)

func setupRoutes(app *fiber.App) {
    app.Get("/:url", routes.ResolveURL)
    app.Post("/api/v1", routes.ShortenURL)
}

func main() {
    err := godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }

    app := fiber.New()
    app.Use(logger.New())

    setupRoutes(app)

    log.Fatal(app.Listen(os.Getenv("APP_PORT")))
}

Docker 設定

為了簡化 Redis 的設置,我使用了 Docker。這使得應用程式可移植且易於部署。

package routes

import (
    "os"
    "strconv"
    "time"

    "github.com/asaskevich/govalidator"
    "github.com/go-redis/redis/v8"
    "github.com/gofiber/fiber/v2"

    "github.com/ravikisha/url-shortener/database"
    "github.com/ravikisha/url-shortener/helpers"
)

// Define structs for the request and response data
type request struct {
    URL         string        `json:"url"`
    CustomShort string        `json:"short"`
    Expiry      time.Duration `json:"expiry"`
}

type response struct {
    URL             string        `json:"url"`
    CustomShort     string        `json:"short"`
    Expiry          time.Duration `json:"expiry"`
    XRateRemaining  int           `json:"x-rate-remaining"`
    XRateLimitReset time.Duration `json:"x-rate-limit-reset"`
}

運行應用程式

  1. 從 GitHub 複製儲存庫:URLShortener
  2. 運行 Redis 的 Docker 容器:

    package database
    
    import (
        "context"
        "github.com/go-redis/redis/v8"
    )
    
    var Ctx = context.Background()
    
    func NewClient(dbNum int) *redis.Client {
        rdb := redis.NewClient(&redis.Options{
            Addr:     "localhost:6379",
            Password: "",
            DB:       dbNum,
        })
        return rdb
    }
    
  3. 在.env中設定環境變數:

    version: '3'
    services:
      redis:
        image: "redis:alpine"
        ports:
          - "6379:6379"
    
  4. 運行 Go 應用程式:

    docker-compose up -d
    

現在,應用程式已上線,您可以開始縮短網址!

測試 URL 縮短器

縮短網址

使用以下 JSON 負載向 /api/v1 發送 POST 請求:

DB_ADDR="localhost:6379"
DB_PASSWORD=""
APP_PORT=":6767"
DOMAIN="localhost:6767"
APP_QUOTA=10

存取縮短的 URL

使用產生的短 URL,例如 http://localhost:6767/exmpl,重定向到 https://example.com。

主要經驗教訓

  1. 使用 Redis 進行速率限制:Redis 的速度非常快,並且使用它進行 URL 儲存和速率限制非常有效率且有效。
  2. 使用 Fiber 建立 REST API:Fiber 的簡單性和效能非常適合在 Go 中建立 API。
  3. 錯誤處理和驗證:確保強大的錯誤處理和 URL 驗證對於提供使用者友善的體驗至關重要。

未來的改進

我想在將來添加一些功能和最佳化:

  • 管理儀表板:用於追蹤 URL 使用情況和監控統計資料的 UI。
  • 詳細分析:追蹤點擊次數、引薦來源網址和使用者人口統計資料。
  • 可擴充性:將應用程式部署在雲端提供者上,並使用分散式Redis來處理更廣泛的資料。

結論

建立這個 URL 縮短器是一次有益的體驗,也是探索 Go、Fiber 和 Redis 的好方法。無論您是學習後端開發還是探索 Go 在 Web 服務中的潛力,該專案都提供了堅實的基礎。

如果您想查看實際程式碼,請在此處查看 GitHub 儲存庫。讓我知道您的想法或您對改進專案有什麼建議!

以上是在 Go 中建立具有速率限制和 Redis 的 URL 縮短器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn