专栏首页码农桃花源喜提 redir contributor

喜提 redir contributor

看多了 Go 源代码,看一看应用,尤其是比较短小且有趣的应用代码,感觉很有意思,而且举重若轻。

如果顺带修一下小的错误[1],成为 Contributor,那就更多了一种成就感。就像杨文前几天成为 Go Contributor 那样[2],从小处开始,慢慢提升技术含量,总有一天,慢慢成为真正的 Contributor,像曹大那样[3]

某天欧神和杨文不知道怎么鼓捣出了一个 golang.design[4] 网站,前一阵子欧神又发布了一个 redir[5] 项目。它其实是一个跳转,比如,欧神分享的 Gophercon 2020 的 PPT 链接:https://golang.design/s/gophercon2020,其实最后会跳转到一个 dropbox 的一个文件分享页面。但是用 “/s/gophercon2020” 就会显得非常的优雅和高级。类似的,还有一些欧神做的分享,如 https://golang.design/s/go2generics 等,都会通过 /s/ 跳转到实际的地址去。至于为什么是 /s/ 路径,其实这个项目最初的名字是 short,也就是短网址的意思。

所以,我今天要介绍的就是 redir 的实现原理以及部署。

首先来看一下 redir 的两个核心功能:短网址跳转(/s);处理 go get 请求(/x)。前者很好理解,我访问短网址 https://golang.design/s/go2generics,redir 给我重定向到真实的 google slice 的地址;后者则不那么好理解,它处理的是我们在项目中 import 了一个 golang.design 下面的某个包,例如:import "golang.design/x/verbose",那么 go get 来获取这个包的时候会去 github 上 golang.design 相应目录下找,但这一切并不是自然发生的,需要通过返回的 header 告知 go get 一些信息。

对于比较知名的,如 github,我这样写:import github.com/go-redis/redis/v8go get 就知道去 github 官网去找,但是对于 golang.design 的库那就不知道怎么找了,所以它会尝试访问 https://golang.design/x/pkg/foo?go-get=1 来获取相关信息,于是 /x handler 就在 header 里返回 meta 信息,告诉 go get 去 github 找。

与 go get 交互

当 go get 收到上图的 HTTP 响应,会根据第一个红框的提示去 https://github.com/golang-design/verbose 这里找对应的包;而如果是浏览器过来的请求,则会重定向到 pkg.go.dev 查看包的详细信息。前者实际就是和 go get 交互的协议,具体的可以在这里[6]看到。

有了短网址跳转,自然就想知道访问每个短网址的 uv/pv 情况,如果访问路径 /s 后不接任何字符,那就返回短网址的汇总信息:

uv/pv

了解清楚了功能,我们来看看如何用代码实现。

main 函数会首先会根据传入的命令行参数 *daemon 来决定是开启一个 server,还是执行增加 alias(短链接和长链接对)、更新 alias 的命令。前者持续运行,后者则只执行一次,程序就会结束。

如果是启动一个 server,会首先连接 redis,初始化一个本地的 cache,用于加快响应速度;同时会启动两个异步协程:counting 和 backup,前者用于计数 uv/pv,后者则用于备份 redis 中的数据。

接着会注册 /.info/s/x 三个 handler,/.info 用来看一下程序相关的版本信息(内部会通过 nginx 屏蔽,外部无法访问);/s 用来处理短链接;/x 则用于执行包相关的请求。

/s 的处理逻辑是先从本地 cache 拿和短链相对应的实际链接,如果没有拿到,则从 redis 拿,最后调用 http.Redirect(w, r, url, http.StatusTemporaryRedirect) 重定向到实际链接地址。

最后,启动一个异步协程把访问信息(ip)添加到一个 channel 中去,用于计算 pv/uv。

关于 /s handler 还有一类特殊的请求,即短链接为空,直接访问 https://golang.design/s/,那就会返回所有的短链接并且展示相应的 uv/pv 信息。

完成上述这些,最后开始监听端口,处理请求。

另外一个流程就是根据命令行参数执行 alias 的增删改查,是一次性的行为。

整体的架构图:

架构图

最后我们来看下如何部署到自己的云主机上,我会修改成自己的域名:qcrao.com。当然,redir 还会向 Google Analytics 发送追踪数据,需要将 id 改成自己的。

首先要安装 docker 和 docker-compose,这个就不细说,对着命令敲就好了。

然后编译 redir.app:

make all

启动 redir 和 redis 容器:

make up

添加一个新的 alias:

./redir.app -a ck-s -l https://changkun.de/s/

访问 https://www.qcrao.com/s/,大功告成:

qcrao.com/s/

总体来看,项目的逻辑是比较简单清晰的,但涉及到东西其实也不少,麻雀虽小,五脏俱全。从实现到部署到运维,都需要了解。如果把整个都走通了,还是很有收获的。

在“玩弄” redir 的过程中,修了一下 Makefile 文件,增加了一个 stats 页面的排序,也因此成为 redir 的从 contributor,nice!

参考资料

[1]

错误: https://github.com/golang-design/redir/pull/3

[2]

那样: https://go-review.googlesource.com/c/tools/+/269397

[3]

那样: https://go-review.googlesource.com/c/go/+/263277

[4]

golang.design: https://golang.design/

[5]

redir: https://github.com/golang-design/redir

[6]

这里: https://golang.org/cmd/go/#hdr-Remote_import_paths

本文分享自微信公众号 - 码农桃花源(CoderPark),作者:欧神小跟班

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-11-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 深度解密Go语言之pprof

    相信很多人都听过“雷神 3”关于性能优化的故事。在一个 3D 游戏引擎的源码里,John Carmack 将 1/sqrt(x) 这个函数的执行效率优化到了极致...

    梦醒人间
  • Go Modules 的智障版本选择

    之前 go mod 用的比较少,而且一直听社区有各种抱怨,所以也兴趣寥寥。新公司的项目直接使用了 go mod,本来觉得无非是个简单的工具,不需要学习,结果在一...

    梦醒人间
  • 聊聊 g0

    很多时候,当我们跟着源码去理解某种事物时,基本上可以认为是以时间顺序展开,这是编年体的逻辑。还有另一种逻辑,纪传体,它以人物为中心编排史事,使得读者更聚焦于某个...

    梦醒人间
  • 厌倦了枯燥的CRUD,是时候寻找下一个突破点了

    最近这几年,断断续续有人给我留言,连亲戚都托我妈给我带话,问我他家孩子数学成绩不好,以后能当程序员吗?我通常都告诉他:没问题,大胆干!做编程开发用不着多么高深的...

    程序猿DD
  • Php-Laravel输入站点地图(sitemap)

    站点地图可以帮助搜索引擎更好的收录我们的站点,所以我们建站、建博客都最好有站点地图。

    无道
  • CRM WebClient UI和Hybris里工作中心跳转的url生成逻辑

    把Work center的navigation target在client side不可见:在Chrome development tool里看不到,而是点击了...

    Jerry Wang
  • 【postman测试上传】

    用户5640963
  • python 进程监控告警脚本

    监控进程是否存在,如果检测时不存在则发送告警短信,如果连续10次检测都不存在则发送告警电话。

    葫芦
  • 设置时间laydate 结束时间大于开始时间

    Erwin
  • Kafka快速入门系列(3) | Kafka常用脚本介绍及简单的shell操作

      至于怎样查看脚本,我们可以查看Kafka/bin目录,下图标记即为常用的脚本

    不温卜火

扫码关注云+社区

领取腾讯云代金券