喜提 redir contributor

看多了 Go 源代碼,看一看應用,尤爲是比較短小且有趣的應用代碼,感受頗有意思,並且舉重若輕。nginx

若是順帶修一下小的錯誤,成爲 Contributor,那就更多了一種成就感。就像楊文前幾天成爲 Go Contributor 那樣,從小處開始,慢慢提高技術含量,總有一天,慢慢成爲真正的 Contributor,像曹大那樣git

某天歐神和楊文不知道怎麼鼓搗出了一個 golang.design 網站,前一陣子歐神又發佈了一個 redir 項目。它實際上是一個跳轉,好比,歐神分享的 Gophercon 2020 的 PPT 連接:https://golang.design/s/gophercon2020,其實最後會跳轉到一個 dropbox 的一個文件分享頁面。可是用 「/s/gophercon2020」 就會顯得很是的優雅和高級。相似的,還有一些歐神作的分享,如 https://golang.design/s/go2generics 等,都會經過 /s/ 跳轉到實際的地址去。至於爲何是 /s/ 路徑,其實這個項目最初的名字是 short,也就是短網址的意思。github

因此,我今天要介紹的就是 redir 的實現原理以及部署。golang

首先來看一下 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 一些信息。redis

對於比較知名的,如 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 找。docker

與 go get 交互

當 go get 收到上圖的 HTTP 響應,會根據第一個紅框的提示去 https://github.com/golang-design/verbose 這裏找對應的包;而若是是瀏覽器過來的請求,則會重定向到 pkg.go.dev 查看包的詳細信息。前者實際就是和 go get 交互的協議,具體的能夠在這裏看到。瀏覽器

有了短網址跳轉,天然就想知道訪問每一個短網址的 uv/pv 狀況,若是訪問路徑 /s 後不接任何字符,那就返回短網址的彙總信息:架構

uv/pv

瞭解清楚了功能,咱們來看看如何用代碼實現。app

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!

相關文章
相關標籤/搜索