You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Golang+Redis+MongoDB的短链接服务数据库连接问题求助

共享Redis/MongoDB连接的实现方案

1. 新建db包统一管理连接

在项目根目录下创建db包,专门负责初始化、维护数据库连接,让routes下的shorten.go和resolve.go等文件可以直接复用。

Redis连接实现

// db/redis.go
package db

import (
	"context"
	"github.com/redis/go-redis/v9"
	"your-project/config" // 替换为实际config包路径
)

var RedisClient *redis.Client

// InitRedis 初始化Redis连接
func InitRedis() error {
	cfg := config.GetRedisConfig() // 从配置包读取Redis参数
	RedisClient = redis.NewClient(&redis.Options{
		Addr:     cfg.Addr,
		Password: cfg.Password,
		DB:       cfg.DB,
	})

	// 测试连接可用性
	_, err := RedisClient.Ping(context.Background()).Result()
	return err
}

MongoDB连接实现

// db/mongo.go
package db

import (
	"context"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"your-project/config"
)

var MongoClient *mongo.Client
var ShortLinkCollection *mongo.Collection // 预初始化常用集合

// InitMongo 初始化MongoDB连接
func InitMongo() error {
	cfg := config.GetMongoConfig()
	clientOpts := options.Client().ApplyURI(cfg.URI)
	var err error
	MongoClient, err = mongo.Connect(context.Background(), clientOpts)
	if err != nil {
		return err
	}

	// 验证连接
	err = MongoClient.Ping(context.Background(), nil)
	if err != nil {
		return err
	}

	// 初始化短链接集合
	ShortLinkCollection = MongoClient.Database(cfg.DBName).Collection("short_links")
	return nil
}

2. 项目入口初始化连接

在main.go中先完成数据库连接初始化,再启动路由:

// main.go
package main

import (
	"log"
	"your-project/db"
	"your-project/routes"
)

func main() {
	// 初始化Redis
	if err := db.InitRedis(); err != nil {
		log.Fatalf("Redis初始化失败: %v", err)
	}

	// 初始化MongoDB
	if err := db.InitMongo(); err != nil {
		log.Fatalf("MongoDB初始化失败: %v", err)
	}

	// 注册并启动路由
	routes.SetupRoutes()
}

3. 在routes包中复用连接

不管是shorten.go还是resolve.go,直接引用db包的全局客户端即可:

shorten.go中插入Redis示例

// routes/shorten.go
package routes

import (
	"context"
	"net/http"
	"your-project/db"
	"your-project/response"
)

func Shorten(w http.ResponseWriter, r *http.Request) {
	// 省略URL校验、base62编码逻辑...

	shortCode := "生成的短码"
	originalURL := "用户输入的原始URL"

	// 写入Redis
	err := db.RedisClient.Set(context.Background(), shortCode, originalURL, 0).Err()
	if err != nil {
		response.Error(w, http.StatusInternalServerError, "Redis存储失败")
		return
	}

	// 可选:写入MongoDB持久化
	// _, err = db.ShortLinkCollection.InsertOne(context.Background(), models.ShortLink{...})
	// if err != nil { ... }

	response.Success(w, http.StatusOK, map[string]string{"short_code": shortCode})
}

resolve.go中查询Redis示例

// routes/resolve.go
package routes

import (
	"context"
	"net/http"
	"github.com/redis/go-redis/v9"
	"your-project/db"
	"your-project/response"
)

func Resolve(w http.ResponseWriter, r *http.Request) {
	shortCode := r.PathValue("shortCode") // 从URL路径获取短码

	// 从Redis查询原始URL
	originalURL, err := db.RedisClient.Get(context.Background(), shortCode).Result()
	if err != nil {
		if err == redis.Nil {
			response.Error(w, http.StatusNotFound, "短码不存在")
		} else {
			response.Error(w, http.StatusInternalServerError, "Redis查询失败")
		}
		return
	}

	// 重定向到原始URL
	http.Redirect(w, r, originalURL, http.StatusFound)
}

4. 注意事项

  • 确保config包能正确读取Redis/MongoDB的配置参数(地址、密码、库名等)
  • 全局连接变量仅初始化一次,避免重复创建连接池
  • 程序退出时可添加连接关闭逻辑:db.RedisClient.Close()、db.MongoClient.Disconnect(context.Background())

内容的提问来源于stack exchange,提问作者Arnob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:01:07