微服務稅和更簡單的 grpc mock

現在稍微有一點規模的公司基本都上微服務了,後端工程師在大小公司打雜的話都會碰到因爲是微服務,所以在做開發的時候:

各種各樣奇形怪狀的問題,每一個痛點都會涉及到不少相關的解決方案,比如環境問題,之前我分享過 https://tilt.dev/;穩定性問題,我們直接去看 Google 三步曲 https://sre.google/books/;上下游用隊列解耦之後,上游的不穩定業務事件導致下游故障,有 data validation 平臺和 schema registry 來緩解。

我們這裏還只是舉了幾個簡單的例子,每一個問題都需要額外的努力來規避,對於那些正在遷移到微服務的公司來說,這些不過是一大堆問題裏的九牛一毛。

對於想要使用微服務的公司來說,需要了解微服務稅的概念:

It is the cost you pay to reap the substantial benefits of distributed application architecture.

K8s,可觀測性基礎設施,監控和基礎的框架,都是在研發成本以外,需要額外付出的成本,好在現在有 CNCF,有一些微服務稅我們不用交了,直接使用現成的基礎設施即可 (儘管這個所謂的 free lunch,也並沒有多好喫。

在一大堆問題裏最重要的還是框架問題,對於 Go 語言的生態來說,目前依然沒有最像 java 生態的 spring cloud 那樣大家都認可的解法。

框架在微服務技術架構中是承上啓下的作用:

需要負責對接公司內的基礎設施,儘量將這些基礎設施的差異性對業務方屏蔽,業務研發只要寫邏輯就可以了,其它問題一律不用關心。

另一方面,框架本身也應該協助業務降低重複代碼的編寫次數,比如根據協議 IDL 來生成協議 / 控制層代碼,根據用戶預定義好的 SQL 生成相關的訪問函數代碼,都是大家熟知的例子。

看起來好像沒什麼技術含量,但是爲什麼現在市面上的框架都是災難一樣的使用體驗呢?哪怕那些大公司開源的框架,裏面一樣充斥的垃圾代碼和 bug?

這個問題我和同事們認真地分析過,主要有下面一些原因:

第一點比較好理解,大多數寫框架的人可能一行業務代碼都沒寫過,沒有動過手,自然很難去體會到業務到底苦在哪,沒有共情,做出來的東西也很難對路。如果連用戶調研都不願意做,那結果就是自 high 了。

第二點,中大型公司的考覈體系,對於框架組很多時候是考覈規模和性能數據指標,比如:框架覆蓋度,框架和其它業界同類方案的優勢,以及看起來比較先進的技術點 (看你怎麼吹),不會考覈框架本身的用戶體驗。

你可以關注一下你們公司裏會不會針對公司內的框架收集 nps 調查問卷,如果沒有,那大概率就是不會考覈。之前某個國內的巨頭公司,因爲框架研發組的老闆級別很高,大家不敢在內網吐槽,還要跑到脈脈去講。

第三點,也是因爲第二點衍生出來的,公司考覈的就是這些性能指標,如果性能指標出問題了,對於框架的研發人員的績效和考覈來說是非常不利的,所以有些數據在內部測完之後不會放出來,也就是刻意對用戶進行了隱瞞。這個其實也不難理解,比如有些 hack 的性能優化,是要結合業務場景嚴謹地分析才能知道是否合適的,研發人員在公司內爲了不出問題,一般也會這麼做,但在對外宣傳的時候,他們會把這些優化的限制刻意隱瞞掉,導致公司外部的人被相應的宣傳所誤導,後續走彎路。

所以這也是我建議在使用那些大公司開源的技術方案時,應該自己多做一些性能測試的原因。

好像扯了一些有的沒的,我們還是要講一點乾貨的。

最近被之前螞蟻的質量同事教育,瞭解了做域內自動化測試時,對於服務的外部依賴的 mock 需求:

如上圖,自動化測試腳本對被測服務發起測試,希望看被測服務是否能夠處理各種外部依賴的正常 / 異常流程,這時候希望能夠在不侵入被測代碼的前提下,能夠改變被測服務依賴的外部服務 (即這裏的 serv_a,serv_b,serv_c) 的返回結果,在 java 中有 jvm-sandbox 這種能夠比較方便地對測試進行隔離,並且動態修改 class 實現的神器,但是在 Go 裏,這個需求不太好實現。

正好目前公司內在大規模落地 go-zero,所以我們和 go-zero 社區的同學合作,想了一些辦法來解決這個問題,下面是社區同學提出的方案:

因爲想要在不改被測服務的前提下來修改外部服務的行爲,這讓我們想到了日常工作中用到的一些代理服務,所以我們在中間加一個 proxy。

這個 proxy 可以和自動化測試腳本交互,由腳本來設定相應的服務、請求和響應匹配規則,可以做到 case by case 的請求響應匹配 / 隔離,也就是可以動態地對 serv_a,serv_b,serv_c 這樣的服務做 mock。

因爲公司內默認使用的是 grpc,目前市面上所有 mock 都需要用戶提供 pb 才能進行,並且沒有辦法動態設置。而對 grpc 比較熟悉的同學則知道在 grpcurl 這個工具中,給我們提供了 describe 功能,我們可以使用 grpc desc 來查看服務的定義,當然,前提是服務開啓了 reflection。

通過 reflection 能夠拿到服務定義的話,我們無需再去要求用戶提供原始的 pb 定義。

這樣,一個簡單的,能夠實現動態 mock 的 proxy 就完成了,後續這套方案做完了 go-zero 社區的同學也會開源出來,敬請期待。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/G3wDiC_sgesmnea0JNDZLw