使用Go语言开发一个短链接服务:二、架构设计
章节
源码:https://gitee.com/alxps/short_link
在上一篇中,我们介绍了短链接服务的应用场景、基本原理以及Go的基本代码实现。在这一篇,我们将讨论服务的技术选型和架构设计。
后端Web框架
就无脑用Go最流行的Web框架Gin。
数据库
备选方案包括MySQL、PostgreSQL、MongoDB。我们这里的数据存储,基本围绕短链接code和长链接url对应关系的保存和读取。这里我们选择MongoDB,理由有:
1、我们不需要用到关系型数据库的事务(MongoDB4.0后也支持事务,惊不惊喜、意不意外)、join查询等特性。绝大多数读写场景是围绕单条数据,短链接code和长链接url两个字段。
2、MongoDB支持分布式、横向扩展。有朝一日,当我们的短链接服务火得一塌糊涂时,数据量级指数增长,数据库读写性能出现瓶颈、磁盘空间不足,可以直接通过加机器节点解决,无需分库分表
3、在读取方面,MongoDB相对于MySQL、PostgreSQL具有更高的性能。主要因为MongoDB使用了面向文档的存储方式,可以将相关数据存储在一个文档中,从而减少了数据查询时的磁盘IO。
4、在适量级的内存的MongoDB的性能非常迅速的,它将热数据存储在物理内存中,热数据的读写十分快。
5、我们基本是单条数据读取,MongoDB索引(b树)b数相比Mysql索引(b+数)性能更高
Go的MongoDB驱动我们使用MongoDB官方维护的go.mongodb.org/mongo-driver/mongo 。
缓存
鲁迅说:“诸多策略,缓存为王。”
备选方案包括Redis、Memcached。我们的服务使用缓存需求,主要为保存和读取短链接code(作为key)和长链接url(作为value)。根据需求,Memcached可能是一个更好选择,但是我还是选择Redis。
应该选Memchached的理由:
1、不需要用到Redis丰富的数据类型、数据持久化、事务等特性,只需要简单的单key保存和读取
2、根据本人以往的认知,100k以上的数据中,Memcached性能要高于Redis
应该选择Redis的理由:
1、在新版的Redis 6.x版本中,支持多线程处理io,优化了过期算法和过期处理逻辑。上面说的,以往100k以上的数据中Memcached性能要高于Redis认知,如今不一定成立
2、更多人熟悉的是Redis
3、我不会Memcached
Go的Redis驱动我们使用MongoDB官方维护的github.com/redis/go-redis/v9 。
架构图
上一篇中,我们提到了短链接服务的基本原理是,服务维护了短链接和长链接一对一关系,客户端输入短链接,服务端获取到短链接code,到缓存、数据库获取对应的长链接,并http跳转到对应的长链接。
基本架构

流程图

总结
架构基本就设计如此,目前涉及到的组件版本信息如下:
1、Golang 1.22.0
2、Gin github.com/gin-gonic/gin v1.9.1
3、MongoDB 7.0.6; go.mongodb.org/mongo-driver/mongo v1.14
4、Redis 7.2.4;github.com/redis/go-redis/v9
下一篇我们将开始项目代码编写。
使用Go语言开发一个短链接服务:二、架构设计的更多相关文章
- 百度 谷歌 Twitter,这么多短链接服务(Short Url)究竟哪家强?
一.短链接是什么 url=HPqdQ5VR3vA39x7ZWoWyNzwWnsDhTbh66BTpdzsJLroBDzFRm4JV-G818Zc027uZrwe7zxtxnD4H2FUahftpUK& ...
- 用PHP和Python生成短链接服务的字符串ID
假设你想做一个像微博短链接那样的短链接服务,短链接服务生成的URL都非常短例如: http://t.cn/E70Piib, 我们应该都能想到链接中的E70Piib对应的就是存储长链接地址的数据记录的I ...
- Knative 实战:三步走!基于 Knative Serverless 技术实现一个短网址服务
短网址顾名思义就是使用比较短的网址代替很长的网址.维基百科上面的解释是这样的: 短网址又称网址缩短.缩短网址.URL 缩短等,指的是一种互联网上的技术与服务,此服务可以提供一个非常短小的 URL 以代 ...
- Java 网址短链接服务原理及解决方案
一.背景 现在在各种圈的产品各种推广地址,由于URL地址过长,不美观.不方便收藏.发布.传播以及各种发文字数限制等问题,微信.微博都在使用短链接技术.最近由于使用的三方的生成.解析短链接服务开始限制使 ...
- 短链接服务Octopus的实现与源码开放
前提 半年前(2020-06)左右,疫情触底反弹,公司的业务量不断提升,运营部门为了方便短信.模板消息推送等渠道的投放,提出了一个把长链接压缩为短链接的功能需求.当时为了快速推广,使用了一些比较知名的 ...
- 最近做了一个短网址服务 di81.com
最近做了一个短网址服务: di81.com 项目中有一处需求,需要把长网址缩为短网址,把结果通过短信.微信等渠道推送给客户.刚开始直接使用网上现成的开放服务,然后在某个周末突然手痒想自己动手实现一 ...
- 从服务端架构设计角度,深入理解大型APP架构升级
随着智能设备普及和移动互联网发展,移动端应用逐渐成为用户新入口,重要性越来越突出.但企业一般是先有PC端应用,再推APP,APP 1.0版的功能大多从现有PC应用平移过来,没有针对移动自身特点考虑AP ...
- 使用plv8+hashids生成短链接服务
有写过一个集成npm plv8 以及shortid生成短链接id服务,实际上我们可以集成触发器自动生成url对应的短链接地址,hashids也是一个不错的选择. 以下是一个别人写的一个博客实现可以参考 ...
- 使用go语言开发一个后端gin框架的web项目
用liteide来开发go的后端项目,需要注意的是环境变量要配置正确了 主要是GOROOT, GOPATH, GOBIN, PATH这几个, GOPATH主要用来存放要安的包,主要使用go get 来 ...
- 用 Go 快速开发一个 RESTful API 服务
何时使用单体 RESTful 服务 对于很多初创公司来说,业务的早期我们更应该关注于业务价值的交付,而单体服务具有架构简单,部署简单,开发成本低等优点,可以帮助我们快速实现产品需求.我们在使用单体服务 ...
随机推荐
- NC17247 H、Diff-prime Pairs
题目链接 题目 题目描述 Eddy has solved lots of problem involving calculating the number of coprime pairs withi ...
- 【Lua】xLua逻辑热更新
1 前言 Lua基础语法 中系统介绍了 Lua 的语法体系,ToLua逻辑热更新 中介绍了 ToLua 的应用,本文将进一步介绍 Unity3D 中基于 xLua 实现逻辑热更新. 逻辑热更新 ...
- Context与Reducer
Context与Reducer Context是React提供的一种跨组件的通信方案,useContext与useReducer是在React 16.8之后提供的Hooks API,我们可以通过use ...
- Oracle本地管理对比数据字典管理表空间
Locally vs. Dictionary Managed Tablespaces 整理自:http://www.orafaq.com/node/3. When Oracleallocates sp ...
- 使用Java线程同步工具类CountDownLatch
java.util.concurrent.CountDownLatch是Java并发并发编程中的线程同步工具类,基于AQS(java.util.concurrent.locks.AbstractQue ...
- click模块解析命令行参数
click模块解析命令行参数 安装 pip install click 操作步骤 1)使用@click.command()装饰一个函数,使之成为命令行接口 2)使用@click.option()等装饰 ...
- 01、NATS基础介绍
01.NATS基础介绍 项目中使用到了 NATS,但是之前并没有接触过,所以特意去学习了下,网上找了些资料,相对来说,都不是很全的介绍,所以特意记录下笔记,方便自己掌握,也希望可以帮助到其他小伙伴. ...
- CentOS系统下,配制nginx代理
1.安装: yum install nginx 2.证书文件位置: a. 创建https证书文件夹:/etc/nginx/ssl b. 上传两个证书文件到/etc/nginx/ssl 3.在/etc/ ...
- Docker:Failed to copy files, no space left on device
主页 个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/ 问题描述 在Mac上进行docker构建时,偶尔会遇到以下问题 Fai ...
- obsidian 日记本倒序汇总 获取标题显示 插件dataviewjs list
obsidian 日记本倒序汇总 获取标题显示 插件dataviewjs list // dataviewjs function removeDuplicate(arr) { return arr.f ...