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