看多了 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/v8
,go get
就知道去 github 官網去找,可是對於 golang.design 的庫那就不知道怎麼找了,因此它會嘗試訪問 https://golang.design/x/pkg/foo?go-get=1
來獲取相關信息,因而 /x
handler 就在 header 裏返回 meta 信息,告訴 go get
去 github 找。docker
當 go get 收到上圖的 HTTP 響應,會根據第一個紅框的提示去 https://github.com/golang-design/verbose 這裏找對應的包;而若是是瀏覽器過來的請求,則會重定向到 pkg.go.dev 查看包的詳細信息。前者實際就是和 go get 交互的協議,具體的能夠在這裏看到。瀏覽器
有了短網址跳轉,天然就想知道訪問每一個短網址的 uv/pv 狀況,若是訪問路徑 /s
後不接任何字符,那就返回短網址的彙總信息:架構
瞭解清楚了功能,咱們來看看如何用代碼實現。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/,大功告成:
整體來看,項目的邏輯是比較簡單清晰的,但涉及到東西其實也很多,麻雀雖小,五臟俱全。從實現到部署到運維,都須要瞭解。若是把整個都走通了,仍是頗有收穫的。
在「玩弄」 redir 的過程當中,修了一下 Makefile 文件,增長了一個 stats 頁面的排序,也所以成爲 redir 的從 Contributor,nice!