不到 150 行 Go 代码!从 0 打造你的高性能短链接服务(含源码)

117 阅读3分钟

在日常开发中,我们经常会遇到分享长链接、管理短链、统计点击量的需求。你也许已经习惯使用 bit.ly、t.cn 这类短链接服务,但你是否想过:

👉 自己写一个短链接生成器,其实只需要不到 150 行 Go 代码!

本文带你揭开短链接服务的神秘面纱,构建一个极简但结构清晰的短链接服务。你不仅能学会如何处理路由、表单、随机短链生成和跳转,还能将它继续扩展为可持久化、可统计、可容器化的完整系统。

出于极简风考虑今天选用了echo框架。


🚀为什么选择 Go 来写短链接?

短链接服务的特点是:

  • 高频请求
  • 高性能要求
  • 架构简单但扩展性强

而 Go 正好具备:

  • 高并发、高性能的原生优势
  • 简单易读的语法
  • 强大且完善的标准库
  • 易部署、易容器化

一个轻量级的短链接服务,用 Go 来写再合适不过。


⭐功能概述

我们将构建的短链接服务包含:

  • 输入任意 URL,自动生成短链
  • 访问短链 → 301 跳转原始链接
  • 首页展示所有短链
  • 基于 Echo 框架快速构建

结构清晰,扩展友好。


🧩架构设计

整个系统由 3 个核心 Handler 组成:

IndexHandler      → 首页:输入框 + 链接列表  
SubmitHandler     → 创建短链  
RedirectHandler   → 访问短链并跳转  

底层使用内存 Map 存储,可轻松替换为 Redis/PostgreSQL。


📁项目目录结构建议

采用轻量但可扩展的目录结构:

url-shortener/
├── main.go
├── handler/
│   ├── index.go
│   ├── submit.go
│   └── redirect.go
├── storage/
│   └── memory.go
└── util/
    └── random.go

比常见的“一个文件写到底”更适合后续扩展。


🧑‍💻 核心代码


🔧随机短链生成

func GenerateRandomString(n int) string {
	seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
	var result []byte
	for i := 0; i < n; i++ {
		index := seededRand.Intn(len(charset))
		result = append(result, charset[index])
	}
	return string(result)
}

采用 Base62 字符集,短链随机分布更均匀。


📝创建短链(SubmitHandler)

func SubmitHandler(c echo.Context) error {
	url := c.FormValue("url")
	if url == "" {
		return c.String(http.StatusBadRequest, "url is required")
	}

	// 自动补全协议
	if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
		url = "https://" + url
	}

	// 生成短链 ID
	id := util.GenerateRandomString(8)

	// 保存
	storage.LinkMap[id] = &storage.Link{
		Id:  id,
		Url: url,
	}

	return c.Redirect(http.StatusSeeOther, "/")
}

要点:

  • 自动补全 https://
  • 生成随机短链 ID
  • 写入存储
  • 使用 303 重定向回首页

🔀短链跳转(RedirectHandler)

func RedirectHandler(c echo.Context) error {
	id := c.Param("id")

	link, ok := storage.LinkMap[id]
	if !ok {
		return c.String(http.StatusNotFound, "short link not found")
	}

	return c.Redirect(http.StatusMovedPermanently, link.Url)
}

采用 301 永久重定向,利于浏览器与 CDN 缓存。


🏠首页展示(IndexHandler)

func IndexHandler(c echo.Context) error {
	html := `
		<h1>Go 短链接服务</h1>
		<form method="POST" action="/submit">
			<input name="url" placeholder="请输入一个 URL" style="width: 300px;" />
			<button type="submit">生成短链</button>
		</form>
		<hr>
		<h3>已生成的短链:</h3>
		<ul>
	`

	for _, link := range storage.LinkMap {
		html += fmt.Sprintf("<li><a href='/%s'>/%s</a> → %s</li>",
			link.Id, link.Id, link.Url)
	}

	html += "</ul>"

	return c.HTML(http.StatusOK, html)
}

轻量级 HTML,可替换为模板引擎。

image.png


🔮扩展方向

如果你想将其做大做强,你可以无限的发挥自己的想象,无限的扩展。

1. 持久化:Redis/PostgreSQL

解决重启后数据丢失。

2. 点击统计与分析(日志管理,运营分析)

记录 PV/UV、来源、地理位置等。

3. 自定义短链(slug)

例如 /go-best-practice

4. Docker 化部署

轻松上线,镜像可做到 10MB 级。

一个原型项目,也能持续成长为生产级服务,只要你肯想,就没有代码做不到的,程序员动起手来,没有什么不可能。


📥示例源码(可直接运行)

已准备可运行示例项目: