基于go-zero的短鏈生成系統

go-zero框架

gozero(又稱go-zero)是一款由知名開發者kevwan設計的Golang微服務框架,專注于高性能、低延遲和易用性。其核心目標是簡化分布式系統的開發,提供開箱即用的工具鏈,涵蓋API網關、RPC服務、緩存管理、數據庫操作等模塊。

項目目錄結構

zero_remake/
├── common/
│   ├── init_gorm.go
│   └── init_redis.go
├── shorturl_api/
│   ├── etc/
│   │   └── shorturl.yaml
│   ├── internal/
│   │   ├── config/
│   │   │   └── config.go
│   │   ├── handler/
│   │   │   ├── redirecthandler.go
│   │   │   └── ...
│   │   ├── logic/
│   │   │   ├── redirectlogic.go
│   │   │   └── ...
│   │   ├── svc/
│   │   │   └── servicecontext.go
│   │   └── types/
│   │       └── ...
│   └── main.go
├── shorturl_rpc/
│   ├── etc/
│   │   └── shorturl.yaml
│   ├── internal/
│   │   ├── config/
│   │   │   └── config.go
│   │   ├── logic/
│   │   │   └── ...
│   │   ├── svc/
│   │   │   └── servicecontext.go
│   │   └── types/
│   │       └── ...
│   └── main.go
└── go.mod
  • common/:公共初始化、工具等代碼
  • shorturl_api/:API 網關服務
  • shorturl_rpc/:RPC 服務
  • 各自有?etc/?配置、internal/?業務代碼、main.go?啟動入口

配置文件(yaml)

Name: shorturl.rpc
ListenOn: 0.0.0.0:8888
Etcd:Hosts:- 127.0.0.1:2379Key: shorturl.rpcMysql:DbUser: rootDbPort: "3306"DbPass: wwy040609DbName: shorturlDbHost: localhostBizRedis:RedisHost: 127.0.0.1RedisPort: "6379"RedisPass: ""RedisDB: 0

Etcd用于定位RPC服務端口

Mysql用于永久存儲

Redis用于緩存熱點數據

接口文檔

雪花算法

雪花算法的實現原理:

雪花算法是一種隨時間變化的分布式全局唯一ID算法,其生成的ID可以看做是一個64位的正整數,除了最高位,將剩余的63位分別分為41位的時間戳,10位的機器ID以及12位的自增序列號。

我們不采用MySQL的主鍵自增ID和redsi的incr的自增ID,而是使用本地雪花算法的形式直接生成ID,這樣性能更高。

Redis

將數據存儲在內存上,查詢速度極快,可以存放熱點數據,減少數據庫查詢次數
redis的github地址https://github.com/redis/redis
redis-go的github地址https://github.com/redis/go-redis

Redis的幾種數據結構

  1. 字符串:可以存儲文本、序列化的對象等。例如,可以將用戶的登錄令牌存儲為字符串,方便快速驗證用戶身份。
  2. 哈希:適合存儲對象的多個屬性。例如,可以存儲用戶信息,以用戶 ID 為鍵,用戶的各種屬性(如姓名、年齡、地址等)作為哈希中的字段和值,方便快速查詢和更新用戶的單個屬性。
  3. 列表:可用于實現消息隊列、任務隊列等應用場景。例如,將待處理的任務依次加入列表,多個消費者可以從列表中取出任務進行處理。
  4. 集合:存儲不重復元素,可用于實現標簽系統、好友列表、共同關注等功能。例如,將用戶的關注用戶列表存儲為集合,方便進行集合運算,如求交集、并集等,以找出共同關注的用戶。
  5. 有序集合:存儲元素及其分數,可用于排行榜系統,根據分數對元素進行排序。例如,存儲游戲玩家的分數,按分數對玩家進行排名。

本次項目中的Redis

  1. 本次Redis中的鍵值對都是以字符串形式進行存儲的
  2. 本次Redis第一次可以自己設定時間,當Redis中的數據因為expiration設置到期而消失時,如果繼續從數據庫中可以獲取時間,那么自動將其添加到緩存中從新設置為24h
if err := l.svcCtx.Redis.Rdb.Set(l.svcCtx.Redis.Ctx, shortCode, in.Url, expireDuration).Err(); err != nil {return &shortUrl.GenerateShortUrlResponse{Code:      errmsg.ERROR_FAILED_SAVE_TO_REDIS,Shortcode: "",}, errors.New("Fail to save to redis")}

布隆過濾器

Bloom Filter:short-url/zero_remake/shorturl_rpc/internal/logic/repository/BoomFilter.go

作用

  1. 布隆過濾過濾器通過hash存儲可以快速判斷數據是否已經存在
  2. 如果出現緩存和數據庫中都沒有的數據,那么可以通過布隆過濾器快速判斷數據不存在,減少數據庫查詢次數(緩存穿透)

hash 算法

布隆過濾器的hash算法

布隆過濾器的優缺點

優點
  1. 時間復雜度低,增加和查詢元素的時間復雜為O(N),(N為哈希函數的個數,通常情況比較小)
  2. 保密性強,布隆過濾器不存儲元素本身
  3. 存儲空間小,如果允許存在一定的誤判,布隆過濾器是非常節省空間的(相比其他數據結構如Set、Map集合)
缺點
  1. 有點一定的誤判率,但是可以通過調整參數來降低
  2. 無法獲取元素本身
  3. 很難刪除元素

short-url\server\server.go 服務層

GenerateShortURL(發送長鏈接并生成短鏈接)

工作流程
  1. 檢查URL是否為空:如果URL為空,返回錯誤。
  2. 檢查布隆過濾器和數據庫:先用布隆過濾器快速檢查URL是否已存在,若可能存在則進一步查詢數據庫確認。
  3. 生成短鏈:使用MD5哈希和Base64編碼生成短鏈。
  4. 解析過期時間:如果提供了過期時間,則解析并驗證其格式。
  5. 存儲短鏈信息:將短鏈信息存儲到MySQL,并將短鏈和原始URL存儲到Redis中,同時設置過期時間。
  6. 更新布隆過濾器:將原始URL添加到布隆過濾器。

HandlerURL(獲取短鏈接并跳轉)

工作流程
  1. 清除超時數據:調用 DeleteWithTime() 函數清除Redis中過期的數據。
  2. 查找原始URL : * 首先從Redis中查找短鏈接對應的原始URL。 * 如果Redis中不存在,則去數據庫中查找。
  3. 處理結果: 1. 如果在Redis或數據庫中找到原始URL,返回成功并重定向到原始URL。 2. 如果未找到或出現錯誤,返回相應的錯誤碼。?

特殊的

對于存在超過一個月的數據,會自動在數據庫中刪除

func (l *HandleShortLogic) DeleteWithTime() error {err := l.svcCtx.DB.Where("created_at < ?", time.Now().Add(-time.Hour*24*30)).Delete(&models.Shorturl{}).Errorif err != nil {return err}return nil
}

server中的InDb函數

這個函數其實可以不用寫的,因為每次重啟程序布隆過濾器會重置,所以會重復查詢添加,如果后端一直開著就不會出現這種問題

func InDb(url string) bool {var shortURL model.Shorturlif err := model.Db.Where("url =?", url).First(&shortURL).Error; err == nil {// 已經生成過,直接返回短鏈return true}return false
}
if Bloom.MightContain(url) {// 可能已經生成過,進行精確檢查var shortURL model.Shorturlif err := model.Db.Where("url =?", url).First(&shortURL).Error; err == nil {// 已經生成過,直接返回短鏈log.Println("已經生成過,直接返回短鏈")return errmsg.SUCCESS, shortURL.Shorturl}}

你會發現布隆過濾器的判斷和這個函數如出一轍

例子:?https://www.google.com/search?q=%E7%89%9B%E5%AE%A2%E8%B0%83%E6%95%B4%E7%AE%80%E5%8E%86%E5%90%84%E4%B8%AA%E6%A8%A1%E5%9D%97%E7%9A%84%E9%A1%BA%E5%BA%8F

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

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

相關文章

Linux-修改線上MariaDB服務端口號

準備工作&#xff08;很重要&#xff01;&#xff01;&#xff01;&#xff09;&#xff1a; 提前做好Linux服務器快照 提前做好數據庫數據備份 1. 修改配置文件 首先&#xff0c;我們需要找到MariaDB的配置文件。通常情況下&#xff0c;這個文件位于以下位置&#xff1a;…

Spring Cloud 微服務(負載均衡策略深度解析)

&#x1f4cc; 摘要 在微服務架構中&#xff0c;負載均衡是實現高可用、高性能服務調用的關鍵機制之一。Spring Cloud 提供了基于客戶端的負載均衡組件 Ribbon&#xff0c;結合 Feign 和 OpenFeign&#xff0c;實現了服務間的智能路由與流量分配。 本文將深入講解 Spring Clo…

HTML/CSS基礎

1.html:超文本標記語言。它是一種標識性的語言&#xff0c;非編程語言&#xff0c;不能使用邏輯運算。通過標簽將網絡上的文本格式進行統一&#xff0c;使用分散網絡資源鏈接為一個邏輯整體&#xff0c;屬于標記語言。 超文本&#xff1a;就是指頁面內可以包含圖片&#xff0…

C# 事件驅動編程的核心:深度解析發布者_訂閱者模式

適用場景&#xff1a;GUI交互、消息隊列、微服務通信等需要解耦事件生產與消費的系統 &#x1f9e9; 模式核心組件解析 發布者&#xff08;Publisher&#xff09; 作用&#xff1a;定義事件并管理訂閱者列表關鍵行為&#xff1a; 提供和-運算符注冊/注銷訂閱者通過Invoke()方…

華為云Flexus+DeepSeek征文 | 從零開始搭建Dify-LLM應用開發平臺:華為云全流程單機部署實戰教程

華為云FlexusDeepSeek征文 | 從零開始搭建Dify-LLM應用開發平臺&#xff1a;華為云全流程單機部署實戰教程 前言一、華為云Dify-LLM平臺介紹1. Dify-LLM解決方案簡介2. Dify-LLM解決方案地址3. Dify-LLM單機架構介紹4. 預估成本說明 二、華為云Maas平臺介紹1. 華為云ModelArts …

oracle集合三嵌套表(Nested Table)學習

嵌套表 嵌套表(Nested Table)是Oracle中的一種集合數據類型&#xff0c;它允許在表中存儲多值屬性&#xff0c;類似于在表中嵌套另一個表。 嵌套表具有以下特點&#xff1a; 是Oracle對象關系特性的一部分 可以看作是一維數組&#xff0c;沒有最大元素數量限制 存儲在單獨…

Python學習之——單例模式

Python學習之——單例模式 參考1 利用__metaclass__實現單例super的用法class Singleton(type)元類 2 重載__new__方法實現單例模式3 利用裝飾器實現單例考慮一個類如果繼承一個單例類的問題 參考 python之metaclasssingleton&#xff08;一&#xff09; python之metaclasssin…

【Linux】U-boot常用命令總結

U-Boot 是嵌入式系統中常用的引導加載程序&#xff08;bootloader&#xff09;&#xff0c;它提供了一套命令行接口&#xff0c;用于調試、加載操作系統鏡像以及進行硬件測試等操作。 1、變量操作命令 這些命令用于管理 U-Boot 的環境變量。 命令功能說明setenv name value設…

【Linux】不小心又創建了一個root權限賬戶,怎么將它刪除?!

一.前言 今天在學習linux提權的時候&#xff0c;把新建的一個普通賬戶權限提升成了root&#xff0c; 當我練習完提權&#xff0c;想要把這個賬戶刪掉的時候。 發現… 好家伙&#xff0c;這個根本刪不掉 隨后試了各種各樣的方法&#xff0c;都不行&#xff0c;后來突然想到是否…

數據結構:數組(Array)

目錄 什么是數組&#xff08;Array&#xff09;&#xff1f; &#x1f50d;為什么數組的下標要從 0 開始&#xff1f; 一、內存地址與偏移量的關系&#xff1a;從 0 開始是最自然的映射 二、指針的起點就是第 0 個元素的地址 三、歷史原因&#xff1a;BCPL → B → C → …

視頻內存太大怎么壓縮變小一點?視頻壓縮的常用方法

視頻傳生活或者工作中很常見&#xff0c;如發送視頻郵件、在線視頻播放、視頻上傳下載等。未壓縮的大內存視頻文件傳輸時&#xff0c;不僅會消耗大量的網絡帶寬資源&#xff0c;還會使傳輸時間大幅增加。在網速有限的情況下&#xff0c;發送一個幾 GB 的未壓縮視頻可能需要數小…

性能測試包括哪些方面?要掌握哪些知識

性能測試是軟件測試中的一個重要方面&#xff0c;它主要關注軟件在不同條件下的穩定性、可靠性和性能表現。性能測試包括多個方面&#xff0c;需要掌握的知識也相對廣泛。以下是對性能測試包括的方面以及需要掌握的知識分析&#xff1a; 一、性能測試包括的方面 響應時間&…

windows的vscode無法通過ssh連接ubuntu的解決辦法

現象&#xff1a; 最近在windows本地通過vscode登錄ssh時發現不得勁&#xff0c;總是報錯無法與”192.168.1.129“建立連接&#xff0c;如下圖&#xff1a; 但是這種報錯以及在輸出端的信息并沒有提供具體錯誤原因&#xff0c;于是換poweshell來登錄&#xff0c;報錯如下圖&am…

第2章,[標簽 Win32] :Windows 的字符串函數

專欄導航 上一篇&#xff1a;第2章 &#xff1a;兼容 ASCII 字符與寬字符的 Windows 函數調用 回到目錄 下一篇&#xff1a;無 本節前言 在下面的文章鏈接里面&#xff0c;我們談到過&#xff0c;使用兼容版的字符串處理函數的知識。 第2章 &#xff1a;編寫兼容多字節字…

Java的SpringAI+Deepseek大模型實戰-會話記憶【三】

文章目錄 背景項目環境實現步驟第一步、定義會話存儲方式方式一、定義記憶存儲ChatMemory方式二、注入記憶存儲ChatMemory 第二步、配置會話記憶方式一、老版本實現方式二、新版本實現 第三步、添加會話ID 異常處理1、InMemoryChatMemory 無法解析 背景 前兩期搭建起大模型對話…

Python3完全新手小白的學習手冊 10 文件和異常

文章目錄 讀取文件讀取文件的全部內容 相對路徑和絕對路徑訪問文件中的各行使用文件的內容包含100萬位的大型文件圓周率值中包含你的生日嗎&#xff1f; 寫入文件寫入一行寫入多行 異常處理ZeroDivisionError異常使用try-except代碼塊else代碼塊處理FileNotFoundError異常分析文…

VC Spyglass:工具簡介

相關閱讀 VC Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828932.html?spm1001.2014.3001.5482 傳統上&#xff0c;基于仿真的動態驗證技術一直是功能驗證的核心方式。隨著現代SoC設計日益復雜&#xff0c;靜態驗證技術的引入變得愈發重要。 Synopsys的 VC Sp…

AWS RDS Aurora全局數據庫轉區域數據庫實戰指南:無縫遷移零停機

Aurora全局數據庫是AWS提供的跨區域高可用解決方案,但在某些場景下,我們需要將其轉換為普通區域數據庫。本文將詳細介紹這一轉換過程,并分享關鍵技術要點和實戰經驗。 一、全局數據庫與區域數據庫概述 AWS RDS Aurora全局數據庫是一種跨區域部署的數據庫架構,主要用于災備…

C++之路:函數重載與運算符重載

目錄 函數重載運算符重載C運算符重載范圍對照表注意事項 運算符重載語法全局運算符重載類內運算符重載下面以一個一元運算符為例&#xff0c;介紹特性1&#xff1a;下面介紹特性3&#xff1a;&#xff08;必須類內重載的運算符?&#xff09; 函數重載 函數重載是指同一個作用域…

七、SpringCloud 項目遷移至 K8s

七、SpringCloud 項目遷移至 K8s 文章目錄 七、SpringCloud 項目遷移至 K8s1、環境準備1.1 集群規劃1.2 SpringCloud 項目架構及遷移需求分析 2、遷移 Eureka 集群2.1 構建及容器化2.2 部署至 K8s2.3 創建通信Service 3、遷移網關服務3.1 構建及容器化3.2 部署至 K8s3.3 創建Se…