聊聊最近工作中解決的幾個小問題

最近項目組搞衝刺,忙到爆,五月一篇文章也沒寫,眼看六月又將結束,抓住一個週末抽點時間寫寫最近工作中遇到的幾個小問題,希望能給遇到相同問題的同學些許幫助。

 衝刺階段的裝備-紅頭巾)

 

 

問題1:用戶進入微信公衆號菜單時偶現oAuth2.0授權失敗

問題背景:

我們有些功能以微信公衆號的形式提供出去,爲了避免用戶使用時頻繁輸入用戶名密碼,所以藉助微信的oAuth2.0鑑權流程實現了免登錄的效果,但是有個前提是需要用戶提前做一步綁定操作,將我們體系的userid和微信體系中的openid做一個綁定,只要有了openid就可以關聯到用戶。

 

下面看下微信oAuth2.0的接入流程。

 

 

 

就在上圖中4.1調用開放api獲取access_token時會偶現

{"errcode":40163,"errmsg":"code been used”}

排查過程:

什麼情況下會對同一個auth _code發起重複調用呢?

  • 是httpclient(4.1由httpclient發起,所以先懷疑它)的重試嗎?不是,我看了上一次調用的日誌,沒有異常而且響應很快,完全不具備httpclient重試的條件。
  • 是業務代碼的重試嗎?看了代碼並沒有任何重試的痕跡。
  • 有沒有可能是第4步“帶着auth_code,訪問第三方應用指定的地址”重複請求了呢?帶着這種疑問開始找證據,果不其然,從nginx的access log中很快發現了蛛絲馬跡。
grep auth_code access.log

  

第一次請求

第二次請求

 可以看到兩次使用的code是同一個,還有個細節是第一次請求的http狀態碼是499,看下網絡上對nginx 499狀態碼的解釋:

499,客戶端關閉連接,這個狀態碼並不是http協議中定義的status code,而是nginx自己定義的一個狀態碼。由於服務器處理請求較多,客戶端在有效時間內沒有得到答覆,主動關閉了連接。

 

到這兒我大膽的猜測這是微信客戶端加的一種優化策略,如果某個請求超時,那就斷開重試一次,從上面兩次請求的access log可以得出微信認定的超時時間爲20s,正是這種優化才造成了這個問題,怎麼優化呢?

解決方式:

也許有人說這屬於微信的bug啊,作爲一個第三方應用提供方我們怎麼優化呢,其實不然,某種角度來說是我們沒有做好“冪等“才導致這種問題發生,微信客戶端在此時只是一個普通的瀏覽器而已,即使它沒有這種“重試”,誰又能保證後面的環節沒有重試發生呢,比如nginx,所以廢話不多說還是把“冪等”做起來,解決方式很簡單,引入redis對auth_code的查詢結果暫存幾分鐘,如果報“code been used”那就從redis獲取一次。

 

問題2:站點升級https以後導致附件預覽功能失敗

問題背景:

筆者所在的團隊目前負責B端的業務,涉及到附件預覽,其中附件預覽是獨立的服務,當業務中有附件預覽需求時會重定向到預覽服務進行在線預覽。

大體流程如下:

1.用戶在業務方站點發起預覽請求;

2.業務方拼接相關參數重定向到預覽服務;

3.預覽服務通過業務方傳遞的附件鏈接調用業務方接口下載附件到本地;

4.預覽服務將下載的附件轉換成html、圖片、pdf等供用戶在線預覽。

之前一直運行的好好的,但是業務站點由http升級到https以後有部分用戶反映,附件預覽失敗,報錯截圖如下:

 

 第一反應我是有點懵的,預覽服務本身就是個http地址,怎麼還牽扯到證書了,緊接着我讓客戶把瀏覽器地址欄內容複製給我,果然是個https地址,趕快找運營借來測試賬號嘗試復現,結果在我瀏覽器上沒復現出來,在其他同事瀏覽器上覆現了,都是chrome只是版本不一樣,到這裏還是雲裏霧裏的,不知道發生了什麼,猜測可能是瀏覽器做了某些處理導致。

 

解決方式:

緊急將預覽服務也增加了https支持,問題隨之解決,至於原因我一直沒有找到特別確切的答案,所以在此也就不多說了,猜測是一個叫做HSTS的東西作祟,當你發現http被強制重定向爲https的時候希望你可以聯想到它,有興趣的可以看下知乎上ThoughtWorks團隊寫的一篇文章https://zhuanlan.zhihu.com/p/25537440。

 

問題3:git分支亂合併

最近團隊出現過好幾次git分支合併錯的問題,比較致命的是把開發分支合併到某個release分支上,更誇張的是居然運行了一個晚上,還好第二天一大早就有測試發現了問題,緊急回退才避免了事故擴大。

 

下圖是我們團隊的git flow流程,和標準的git flow差別不小,目前我們有固定的迭代週期和發版計劃,所以整體流程和TrunkBased很相似,直接在master開發,到達發版節點以後發佈master代碼,發佈完成以後拉取release分支,用來做歷史版本bug的修復。

 

某天晚上有個小哥修改bug,本意可能是改完了把release合回master,但是手抖居然合反了,導致線上運行着未經測試的代碼,想想我都一頭汗,事後他過來找我。

“哥,幫我回退下代碼,昨天把代碼合錯了”

“嗯”(我咬着後槽牙回答到)

 

 

 

問題雖然解決了,同時也映射出我們的代碼合併流程其實是存在問題的,試圖通過一種口口相傳的方式顯然是不行的,得想辦法藉助工具來解決,通過調研我大概發現有以下兩種辦法:

1.在git服務端設置保護分支,只允許某幾個人的合併,甚至只能通過MR的方式來合併分支,將風險性行爲交給團隊內“德高望重“的人來實施;

2.在git客戶端通過git hook的方式來實施,檢測到某些風險合併時拒絕merge。

 

最終我使用客戶端hook的方式規避這種風險,主要原因是想讓開發者提前意識到這種問題,不要把風險往後傳遞。

實踐方式如下:

1. 在.git\hooks目錄下實現commit-msg這個hook,git已經內置了這個文件只是增加了sample後綴,刪除sample就會啓用這個hook;

2. 編寫檢測腳本,這段引用自互聯網,侵刪。

https://www.cnblogs.com/SteelArm/p/12773485.html

#!/bin/sh

BLACKLIST=("master" "origin/master")
forbid_list=()

if [[ -e .git/MERGE_HEAD ]]; then
  heads=`ls .git/refs/heads`

  for bl in "${BLACKLIST[@]}"; do
    if [[ -n `echo ${heads} | grep -oP "(^| )${bl} "` ]]; then
      forbid_list+=(`cat .git/refs/heads/${bl}`)
    fi
  done

  merge_head=`cat .git/MERGE_HEAD`
  for br in "${forbid_list[@]}"; do
    if [[ ${merge_head} == ${br} ]]; then
      echo -e "\033[41;37m 合併了黑名單中的分支 \033[0m\n\r"
      echo -e "\033[41;37m 請使用 git merge --abort 命令終止合併 \033[0m"
      exit 1
    fi
  done
fi

 

3. 最終效果,如果錯誤合併了會報錯提示;

 

寫在最後

以上是我近期工作中遇到的幾個比較有意思的問題,在這裏分享出來,希望下一次你遇到同樣問題的時候能帶來些許幫助。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章