一探B站后台架构, 他山之石, 何以攻玉? -- 仅从一个一线Golang开发者的角度谈B站4.22代码
4月22日, B站部分后臺源代碼因為某憤怒的員工, 被上傳至Github. 本文我們不討論安全, 法律, 去惡意攻擊或者獲利是違法的! 我們工作時也要注意代碼安全), 我僅從開發者的角度談談, 這份代碼我們能學到什么? B站Golang生態建設, 代碼規范, 工具建設, 技術棧選擇, 對于Go在部門或公司的推廣又有哪些值得借鑒?
首先必須得說, B站這份代碼整體還是不錯的, 不是說組件或者基礎庫多么的厲害, 而是從整體目錄分布, 業務代碼分布, API易用性, 業務代碼風格, 工具的統一, 上手難度上來評價.
這里是一個小小的總結.
可以看出B站有一定的技術建設能力, 能夠基于開源技術棧做封裝和改進, 所選技術棧適合中小型公司業務. 技術總監毛劍水平的確挺不錯, 下面會給出兩篇B站在Gopher China上的分享.
詳細請看下文
PS: 學習完代碼已刪除, 不要問我要代碼哈.
[TOC]
嗶哩嗶哩的Go微服務實戰
文章上: https://mp.weixin.qq.com/s/bPFUGQDZCnt2aeIf7JI2cQ (主要講B站從PHP, Java轉為Go微服務之路)
文章下: https://mp.weixin.qq.com/s/4uA6iE7HC_SAfdIATAdrrA (主要講B站中間件建設情況)
視頻: https://www.bilibili.com/video/av29079011
以上兩篇(上面后兩篇)是B站公開分享的Go微服務實戰, 上文講B站的微服務演進, 下文講B站的中間件建設.
本文中很多情況的確和本文中一致. 詳細可參考這兩篇文章.
目錄結構及整體情況
通過main.go啟動文件統計, 整體約329個Go服務. 有170人左右貢獻過Go代碼.
整體目錄結構
admin是管理后臺的服務, service是提供RPC內部服務, job是處理消息隊列的服務, interface目錄是對外http的服務.
其中admin目錄下54個, infra目錄下5個基礎組件服務, interface下77個, job目錄下80個, service目錄下113個.
整理目錄結構
可以看出來B站Go后臺代碼管理使用的是一個大倉庫的方式(從源碼目錄整齊度以及大倉庫的README來看, 應該是這樣的, 當然還有個東西叫git. 這種方式有好處也有壞處.
我在前公司也有這種情況, 前人把大概某20個服務放在一個倉庫中, 后續的git log簡直沒法看. 幸好后面大家沒這么做了.
服務目錄結構
服務目錄結構
cmd: 放main.go和配置文件, 作為啟動入口 conf: 放配置文件對應的golang struct, 使用的是toml model: 放結構體, 比如Http參數轉換用的struct, DB存儲對應的struct, 各層之間傳遞用的struct dao: data access object, 數據庫訪問方法, redis, memcache訪問方法, 還有一些RPC調用也放在這里面 http: 提供http服務, 主要是提供協議轉換, 聚合. 邏輯還是再service層做. service: 對于后端服務來說, 該目錄提供服務的實現, 對于http服務, 該目錄提供http服務的實現.目錄規范性
所有的服務均遵守該目錄結構. model層放VO, DO等, dao層用于數據層封裝, 隔離本服務的領域邏輯與外部數據. http層提供協議轉換. service實現具體邏輯.
比較像Java開發的模式, 可能在公司很多人不是很喜歡這樣復雜的目錄, 喜歡什么都放在一個目錄下.
不過這樣的分目錄是一種比較好的實踐. 各層分的清清楚楚, 一個服務從1個接口到10個接口, 都比較清晰. 對于服務改動來說,也比較好聚焦于某一層.
生成工具的重要性
目錄做到規范性, 服務維護, 其他人接手也容易多了. 然而大家都是有各自習慣, 每個人都喜歡偷懶, 靠規范, 靠說教來使得程序員保持目錄規范, 實踐證明是不可能的. 所以得靠生成工具.你給程序員生成好的代碼目錄和模式, 99%的人是不會去改的…能把業務邏輯實現了, 還管其他的干啥?
此份代碼的300多個服務, 目錄都是一致的, 不管是http服務, 還是接收消息隊列的服務, 還是后臺service. 同時service包下, http包下的代碼流程都基本一致, rpc調用方式一致, 都是靠生成工具來實現.
B站Golang技術棧分析
| RPC | 基于grpc封裝的warden框架, 已開源 | https://github.com/bilibili/kratos |
| HTTP框架 | 基于gin封裝的blade master框架, 已開源 | 同上 |
| 服務注冊與發現 | 初期為zk, 后面逐步改為參考Spring Cloud體系Eureka自研的discovery | 已開源 https://github.com/bilibili/discovery |
| 存儲 | DB, redis, memcache, hbase存儲一些用戶kv信息和歷史流水, 已封裝好庫 library/database/ | client庫已開源 https://github.com/bilibili/kratos |
| 搜索 | B站視頻, 用戶, 歷史記錄等使用es搜索, 客戶端已封裝在基礎庫中 library/database/elastic | |
| 小文件存儲 | 毛劍個人研發的bfs, 已開源. | https://www.toutiao.com/i6272104949560115714/ https://github.com/Terry-Mao/bfs |
| 消息隊列 | 基于kafka封裝的databus | |
| log | 基于uber的zap封裝的日志框架 | |
| 配置及配置中心 | 支持從環境變量讀取配置, 從toml中解析配置, 支持遠程配置中心(自研,?mysql存儲, 本地落地,http協議, long poll, 客戶端有更新事件, 類似于攜程開源的Apollo) | |
| 監控 | 使用開源的prometheus, 框架和庫(sql, redis, hbase等)中已預埋計數點和時間統計點, 同時也可以在業務邏輯中打點. library/stat/stat.go | |
| trace | trace似乎是基于agent的方式, 使用unix?domain socket進行傳送, 框架和庫已預埋點. library/net/trace.go | |
| 研發流程管理 | TAPD, 哈哈, 有相關的tapd struct信息 |
其中RPC, HTTP框架, 數據訪問的一些庫封裝, 包括生成工具, 均以kratos項目在github開源了( https://github.com/bilibili/kratos Kratos是bilibili開源的一套Go微服務框架,包含大量微服務相關框架及工具)
B站目前使用及封裝的中間件的詳細介紹在Gopher China 2017 B站的分享有提到原理和使用情況.
https://mp.weixin.qq.com/s/4uA6iE7HC_SAfdIATAdrrA
bfs介紹
https://www.jianshu.com/p/923917220d23
B站運維體系發展
https://myslide.cn/slides/3840
總結
簡單分析了下B站的代碼風格和后臺架構, 目錄規范性, 工具建設均做的不錯, 其中代碼生成工具做的很好, http服務, 后臺grpc服務,均可通過proto生成(目前now也是這樣做的), 也有使用go ast進行生成的工具(大家可以參考一下).
中間件方面, 技術選型大部分為一些目前業界比較實用和流行的開源組件, 進行了一些封裝, 比較適合員工上手. 同時像配置中心, 小文件存儲, 為自研. 全套解決方案比較關鍵路徑均開源.
可以看出B站有一定的技術建設能力. 技術選型比較符合中小型公司的實際情況.
對于我們而言, 可以借鑒一下, 完善生成工具, 提高API的易用性, 降低入門門檻, 根據業務選用適合組件.
總結
以上是生活随笔為你收集整理的一探B站后台架构, 他山之石, 何以攻玉? -- 仅从一个一线Golang开发者的角度谈B站4.22代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逆向微信Mac客户端:微信情话助手初版
- 下一篇: 整数n分解成素数乘积c语言,C程序实现整