從零到部署:基于Go和Docker的全棧短鏈接服務實戰(含源碼)

摘要:本文將手把手帶你使用Go語言,并遵循依賴倒置、分層架構等最佳實踐,構建一個高性能、高可用的全棧短鏈接生成器。項目采用Echo框架、GORM、Redis、MySQL,并通過Docker和Docker Compose實現一鍵式容器化部署到阿里云服務器。文章將深入探討設計思路、核心功能實現、部署流程以及排障經驗,附帶完整的GitHub源碼和在線演示地址。

前言 (Introduction)

大家好,我是Joker。在日常開發和分享中,我們經常會遇到URL過長不便分享的問題,一個簡潔的短鏈接服務便顯得尤為重要。最近,我基于Go語言從零構建并部署了一個功能完備的短鏈接生成器,整個過程涵蓋了現代后端開發的諸多最佳實踐。

寫這篇博客的目的,是希望將整個項目的設計思路、技術選型、核心功能實現、容器化部署流程以及過程中遇到的各種“坑”與大家分享。無論你是Go語言的初學者,還是希望尋找一個完整項目實踐的開發者,相信都能從中有所收獲。

  • 🚀 在線演示地址: http://116.62.241.55

  • 📦 GitHub源碼地址: https://github.com/Joker-0111-G/shortlink-go

一、 設計思路與架構 (Architecture & Design)

在編碼之前,清晰的頂層設計是項目成功的關鍵。本項目嚴格遵循了以下原則:

  1. 分層架構 (Layered Architecture):我們采用了經典的 Controller -> Service -> Repository 三層架構,確保各層職責單一、清晰。

    • Controller層:負責接收和解析HTTP請求,對參數進行基礎校驗,然后調用Service層處理業務,最后將結果以JSON格式返回給前端。

    • Service層:核心業務邏輯層。它編排一個或多個Repository的操作,處理復雜的業務規則,如鏈接的創建、刷新、復用和清理等。

    • Repository層:數據持久層,負責與數據庫和緩存(MySQL、Redis)直接交互,提供原子化的數據操作接口。

  2. 依賴倒置原則 (DIP):這是我們項目“高內聚、低耦合”的核心。通過定義interface(接口),我們讓上層完全不依賴下層的具體實現。

    • Controller 依賴 Service 的接口。

    • Service 依賴 Repository 的接口。

    • 好處:未來如果想把MySQL換成PostgreSQL,只需重新實現一個Repository接口,Service層和Controller層的代碼一行都不用改!這也極大地便利了單元測試。

  3. 數據庫設計:除了基礎字段,我們特別設計了expires_atdeleted_at字段,以支持鏈接有效期和“軟刪除”功能。軟刪除是生產環境的最佳實踐,它避免了數據物理刪除帶來的風險,并為鏈接碼的“回收復用”提供了基礎。

  4. 無狀態服務 (Stateless):我們的Go應用本身是無狀態的,不存儲任何會話信息。這使得它可以輕松地進行水平擴展,以應對未來的高并發需求。

二、 技術棧詳解 (Technology Stack)

本項目采用了一套現代化且高效的技術棧:

核心后端 (Core Backend)

  • Go (Golang): 項目的主要編程語言,用于構建高性能的后端服務。

  • Echo v4: 一個高性能、可擴展、極簡的Go語言Web框架,用于處理HTTP請求、路由和中間件。

  • GORM: Go語言中最流行的ORM(對象關系映射)庫,用于以類型安全的方式操作數據庫,并內置了連接池和防SQL注入等功能。

  • go-redis/v9: 用于在Go程序中與Redis進行交互的高性能官方客戶端庫。

  • Viper: 一個強大的Go配置庫,用于管理config.yaml文件,實現代碼與配置的分離。

前端 (Frontend)

  • HTML5: 構建網頁的基本結構。

  • CSS3: 為網頁提供樣式,使其美觀。

  • JavaScript (ES6+): 實現前端的動態邏輯,特別是:

    • Fetch API: 用于向后端異步發送HTTP請求(創建和獲取鏈接列表)。

    • DOM 操作: 動態地將后端返回的數據渲染到頁面上,實現歷史記錄的展示和實時更新。

數據庫與緩存 (Database & Caching)

  • MySQL 8.0: 作為主數據庫,用于持久化存儲鏈接的映射關系、有效期等核心數據。

  • Redis 7.0: 作為高性能的內存緩存,用于緩存熱點數據(短鏈接到原始鏈接的映射),極大地減輕數據庫壓力并提高訪問速度。

架構與設計原則 (Architecture & Design Principles)

  • 分層架構: 采用了經典的Controller -> Service -> Repository分層設計,使得各層職責清晰,易于維護和測試。

  • 依賴倒置原則 (DIP): 通過定義interface(接口),實現了層與層之間的高層模塊不依賴低層模塊,兩者都依賴于抽象,是項目可擴展、可重構的核心。

  • RESTful API: 后端接口遵循REST風格設計,使用HTTP動詞(GET, POST)和清晰的URL結構來表達操作。

  • JSON: 作為前端和后端之間數據交換的標準格式。

  • 軟刪除 (Soft Deletion): 數據庫設計最佳實踐,通過deleted_at字段來標記數據為“已銷毀”而不是物理刪除,為數據恢復和鏈接碼復用提供了基礎。

  • 后臺任務 (Background Job): 使用Go的Goroutine和time.Ticker實現了一個后臺定時任務,用于自動清理過期的鏈接。

容器化與部署 (Containerization & Deployment)

  • Docker: 用于將Go應用、MySQL和Redis分別打包成獨立的、環境一致的容器。

  • Docker Compose: 用于編排和管理多個Docker容器(應用、數據庫、緩存),通過一個docker-compose.yml文件實現一鍵構建、啟動和聯網。

  • Dockerfile: 用于定義如何將我們的Go源代碼、配置文件和前端文件打包成一個標準化的Docker鏡像。

  • 阿里云 ECS (Elastic Compute Service): 作為項目的生產環境云服務器,提供了公網IP和穩定的運行環境。

  • 安全組 (Security Group): 阿里云提供的云端防火墻,用于控制服務器哪些端口可以被外部訪問。

開發與協作工具 (Development & Collaboration Tools)

  • WSL2 (Windows Subsystem for Linux 2): 在Windows上提供了完整的Linux開發環境,用于本地開發和測試。

  • Visual Studio Code (VS Code): 項目的主要代碼編輯器。

  • Git: 用于項目代碼的版本控制。

  • GitHub : 作為遠程代碼倉庫,用于代碼托管、協作以及從云服務器上拉取代碼。

底層協議與標準 (Underlying Protocols & Standards)

  • HTTP/1.1: Web應用通信的基礎協議。

  • SSH (Secure Shell): 用于安全地遠程登錄和管理阿里云服務器,我們配置了更安全的密鑰對認證

  • TCP/IP: 所有網絡通信的基礎協議棧,我們在排查端口問題時曾涉及。

三、 核心功能實現亮點

項目中包含了一些有趣且實用的功能實現:

  1. 鏈接的創建、刷新與復用邏輯 當用戶請求創建一個短鏈接時,CreateShortLink服務會執行一個帶事務的復雜邏輯:

    • Step 1: 檢查是否存在:首先根據長鏈接查詢數據庫,看是否存在一個完全相同且未過期的短鏈接。如果存在,則直接刷新其有效期并返回,實現“刷新”功能。

    • Step 2: 優先復用:如果不存在,則嘗試在數據庫中尋找一個**最舊的、已被“軟刪除”**的記錄。如果找到,就用新的長鏈接和有效期“復活”這條記錄,并返回它原有的短鏈接碼。這實現了短鏈接碼的回收和循環利用。

    • Step 3: 創建全新:如果連可復用的記錄也找不到,最后才會創建一條全新的記錄,并生成新的短鏈接碼。

    • 數據庫鎖:在“查找復用記錄”的步驟中,我們使用了FOR UPDATE行鎖,確保在高并發下,兩個請求不會同時搶到同一個可復用的記錄,保證了數據的一致性。

  2. 自動銷毀后臺任務 為了實現鏈接到期后自動“銷毀”(軟刪除),我們在main.go中啟動了一個后臺Goroutine。它使用time.Ticker,每分鐘觸發一次,調用CleanupExpiredLinks服務,該服務會執行一條SQL語句,將所有expires_at早于當前時間的鏈接標記為“已刪除”。

  3. 前端實時倒計時 在前端的歷史記錄表格中,我們使用setInterval定時器,每秒鐘調用一次JavaScript函數來重新計算并渲染每個鏈接的“剩余時間”,實現了動態倒計時的效果,提升了用戶體驗。

四、 容器化與部署流程

容器化是本項目的一大亮點,它使得復雜的部署流程變得異常簡單。

  1. 多階段構建 Dockerfile: 我們為Go應用編寫了一個多階段構建的Dockerfile。第一階段使用完整的golang鏡像進行編譯,第二階段則只將編譯好的二進制文件復制到一個極小的alpine鏡像中。這使得我們的最終鏡像體積僅有十幾MB,非常輕量。

  2. docker-compose.yml 編排: 我們用一個文件定義了app, mysql_db, redis_cache三個服務,并配置了它們之間的依賴關系(depends_on)和網絡。在Docker的內部網絡中,Go應用可以通過服務名(如mysql_db)直接訪問數據庫,無需關心IP地址。

  3. 一鍵部署: 在阿里云服務器上配好環境后,整個部署流程濃縮為幾步:

    # 1. 克隆代碼
    git clone <your-repo-url>
    cd shortlink-go# 2. 創建生產環境配置文件 configs/config.yaml
    # (填入域名、數據庫密碼,并將數據庫主機改為服務名 mysql_db)# 3. 一鍵構建并啟動所有服務
    docker compose up --build -d
    

五、 踩坑與總結 (Troubleshooting)

在整個開發和部署過程中,我們也遇到了一些經典問題,這里分享一下:

  • 端口沖突:在本地和服務器上,反復遇到port is already in use的錯誤。最終發現,除了程序本身,Windows防火墻、第三方安全軟件(如火絨)、阿里云安全組,都是需要檢查和配置的地方。

  • WSL2與Windows的網絡迷局:深刻理解了WSL2的網絡模型。從外部設備訪問WSL2中的服務,請求必須先經過Windows主機的網絡堆棧和防火墻,這是解決跨設備訪問問題的關鍵。

  • Docker構建問題:遇到了Go版本不匹配、國內服務器訪問proxy.golang.org超時等問題。通過修改Dockerfile中的FROM鏡像版本和添加國內GOPROXY代理配置,順利解決。

結語 (Conclusion)

????????從一個想法到完成云端部署,這個短鏈接項目讓我們完整地體驗了現代Web服務的開發全流程。通過擁抱Go語言的高性能、Docker的便捷部署以及分層解耦的架構設計,我們構建了一個雖小但“五臟俱全”的可靠服務。希望這篇文章能對你有所啟發。如果你對項目有任何疑問或建議,歡迎在下方評論區交流,或者直接在GitHub上提Issue!

????????感謝閱讀!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91157.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91157.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91157.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MyBatis_3

上一篇文章&#xff0c;我們學習了使用XML實現MyBatis進行增、刪、查、改等操作&#xff0c;本篇文章&#xff0c;我們將學習#{ }和${ }獲取方法參數的區別和使用MyBatisXML實現動態SQL語句。 #{ }和${ }的區別 在之前的文章中我們都是使用#{ }進行賦值&#xff0c;但實際上M…

智能圖書館管理系統開發實戰系列(一):項目架構設計與技術選型

項目背景 智能圖書館管理系統&#xff08;ILMS&#xff09;是一個現代化的桌面應用程序&#xff0c;采用前后端分離架構&#xff0c;結合了Web技術的靈活性和桌面應用的用戶體驗。本項目從高保真原型設計開始&#xff0c;經過完整的軟件開發生命周期&#xff0c;最終實現為一個…

應急前端“黃金3分鐘”設計:極端場景下的操作界面極速搭建技術

摘要**地震突發&#xff0c;應急指揮系統的操作界面卻因加載緩慢無法及時調取數據&#xff1b;火災現場&#xff0c;消防員手持終端的操作步驟繁瑣&#xff0c;延誤救援時機。在分秒必爭的極端場景中&#xff0c;傳統前端操作界面為何頻頻 “掉鏈子”&#xff1f;怎樣才能在 “…

【Android】三種彈窗 Fragment彈窗管理

三三要成為安卓糕手 零&#xff1a;布局轉換 在很多工程當中用的都是LinearLayout和relativelayout&#xff0c;這兩者都可以轉化為Constrainlayout 注&#xff1a;這種用法并不能精確轉換&#xff0c;具體還是要根據自己的需求來做布局約束一&#xff1a;snackbar顯示彈窗 ((2…

【AI繪畫】Stable Diffusion webUI 與 ComfyUI 全解析:安裝、模型、插件及功能對比

一、Stable Diffusion 與 UI 工具概述 Stable Diffusion 是當前最主流的開源 AI 繪畫模型&#xff0c;通過文本描述生成高質量圖像。為降低使用門檻&#xff0c;開發者推出了多種圖形界面&#xff08;UI&#xff09;工具&#xff0c;其中AUTOMATIC1111 webUI&#xff08;簡稱 …

ABP VNext + GraphQL Federation:跨微服務聯合 Schema 分層

ABP VNext GraphQL Federation&#xff1a;跨微服務聯合 Schema 分層 &#x1f680; 在微服務架構下&#xff0c;服務之間往往需要相互通信&#xff0c;而 GraphQL Federation 提供了一個有效的解決方案&#xff0c;幫助我們將多個微服務的 GraphQL API 聚合成一個統一的入口…

小程序組件的生命周期,以及在小程序中進行接口請求的方法設置

微信小程序組件生命周期與接口請求方法詳解一、小程序組件生命周期微信小程序組件的生命周期指的是組件在不同階段自動觸發的函數&#xff0c;開發者可以利用這些鉤子函數在特定時機執行相應操作。小程序組件的生命周期主要分為兩類&#xff1a;組件自身生命周期和組件所在頁面…

在線游戲玩家與物品交互處理

玩家與物品接觸后的判定if (hit ! null && hit.CompareTag("Item")){Debug.Log("撿東西");var worldItem hit.gameObject.GetComponent<WorldItem>();if (worldItem ! null){var inventory GetComponent<PlayerInventory>();if (inv…

深入解析Java Stream 構建:AbstractPipeline

Java Stream 宏觀介紹見&#xff1a;深入解析 Java Stream 設計&#xff1a;從四幕劇看流水線設計與執行機制-CSDN博客 PipelineHelper PipelineHelper 是 Java Stream API 內部一個至關重要的輔助類。正如其名&#xff0c;它是一個“管道助手”。可以把它想象成一個執行上下文…

《林景媚與命運回響》

《林景媚與命運回響》——當數據庫開始回響命運&#xff0c;現實是否還能被信任&#xff1f;《林景媚數據庫宇宙》系列第九部第一章&#xff1a;命運的漣漪公元 2089 年&#xff0c;數據庫神諭的運行已趨于穩定&#xff0c;PostgreSQL Quantum Engine&#xff08;PQE&#xff0…

圖神經網絡入門:從GNN開始01圖卷積網絡GCN節點分類 02圖注意力網絡GAT 03圖自編碼器GAE 04 門控圖神經網絡GGNN

目錄 一.基礎1-[圖論、圖算法、CNN] 二.基礎2-[圖卷積神經網絡GCN] 三.torch-geometric.nn工具包安裝&#xff08;包含各種算法和數據集&#xff09; 四.GCN任務[節點分類-Cora 數據集] 五.圖注意力網絡&#xff08;GAT&#xff09; 六.圖自編碼器&#xff08;GAE&#x…

001 Configuration結構體構造

目錄DramSys 代碼分析1 Configuration結構體構造1.1 from_path 函數詳解1.2 構造過程總結這種設計的好處2 Simulator 例化過程2.1 instantiateInitiatorDramSys 代碼分析 1 Configuration結構體構造 好的&#xff0c;我們來詳細解釋一下 DRAMSysConfiguration.cpp 文件中 fro…

以太坊十年:智能合約與去中心化的崛起

以太坊10周年&#xff0c;敬開發者&#xff0c;敬構建者&#xff0c;敬還在鏈上的我們 以太坊即將迎來十周年紀念,作為一名在這個生態中深耕了8到9年的見證者&#xff0c;我親歷了它從一紙白皮書的構想到成長為全球領先去中心化平臺的全過程。這十年間&#xff0c;以太坊經歷了…

kafka 3.9.1版本: kraft + sasl+ standlone 模式完整可行安裝步驟

Kafka 3.9.1 Kraft 單機模式安裝 安裝 OpenJDK 11 CentOS/RHEL yum install -y java-11-openjdk-develUbuntu/Debian apt install -y openjdk-11-jdk下載安裝包 wget https://mirrors.aliyun.com/apache/kafka/3.9.1/kafka_2.12-3.9.1.tgz tar -zxvf kafka_2.12-3.9.1.tgz -C /…

Gitee DevOps平臺深度評測:本土化優勢與功能特性全面解析

Gitee DevOps平臺深度評測&#xff1a;本土化優勢與功能特性全面解析 在數字化轉型浪潮下&#xff0c;企業軟件開發流程的自動化與協作效率成為核心競爭力。作為國內領先的代碼托管與DevOps平臺&#xff0c;Gitee&#xff08;碼云&#xff09;憑借其本土化服務與全流程支持能力…

從零開始本地化部署Dify:開源大模型應用平臺搭建全指南

在AI應用開發的浪潮中&#xff0c;Dify作為一款開源的大語言模型(LLM)應用開發平臺&#xff0c;正逐漸成為開發者和企業的首選工具。它巧妙地融合了后端即服務&#xff08;BaaS&#xff09;和LLMOps的理念&#xff0c;讓開發者能夠快速搭建生產級的生成式AI應用。無論是構建智能…

Qt 多媒體開發:音頻與視頻處理

Qt 多媒體模塊提供了一套完整的 API&#xff0c;用于開發音頻和視頻處理應用。從簡單的媒體播放到復雜的音視頻編輯&#xff0c;Qt 都提供了相應的工具和組件。本文將從基礎到高級全面解析 Qt 多媒體開發。 一、Qt 多媒體模塊概述 1. 主要組件 Qt 多媒體模塊包含以下核心組件&a…

Mac 專業圖像處理 Pixelmator Pro

原文地址&#xff1a;Pixelmator Pro Mac 專業圖像處理 Pixelmator Pro&#xff0c;是一款非常強大、美觀且易于使用的圖像編輯器&#xff0c;專為 Mac 設計。 采用單窗口界面、基于機器學習的智能圖像編輯、自動水平檢測&#xff0c;智能快速選擇及更好的修復工具等功能優點…

iptables和IPVS比較

iptables 和 IPVS (IP Virtual Server) 都是 Linux 系統上用于處理網絡流量的強大工具&#xff0c;但它們的設計目標、工作原理和適用場景有顯著區別&#xff1a; 核心區別&#xff1a;主要目的&#xff1a; iptables&#xff1a; 核心是一個包過濾防火墻和網絡地址轉換工具。它…

語音識別指標計算 WER

目錄 CER&#xff08;Character Error Rate&#xff09; WER Word Error Rate&#xff08;詞錯誤率&#xff09; &#x1f9ee; WER 計算方式 &#x1f4cc; 示例 ? 理解要點 CER&#xff08;Character Error Rate&#xff09; 語音識別中的 CER&#xff08;Character …