1

喜提 redir contributor

 3 years ago
source link: https://qcrao.com/2020/11/16/become-contributor-of-redir/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

喜提 redir contributor

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

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

某天欧神和杨文不知道怎么鼓捣出了一个 golang.design 网站,前一阵子欧神又发布了一个 redir 项目。它其实是一个跳转,比如,欧神分享的 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 交互

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

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

uv/pv
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:

1
make all

启动 redir 和 redis 容器:

1
make up

添加一个新的 alias:

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

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

qcrao.com/s/
qcrao.com/s/

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK