原文鏈接:https://mp.weixin.qq.com/s/ah9gdutZueCxbqjrWVhiQg
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
本文概括性的介紹gRPC往毡,包括gRPC的起源,核心特性,生態(tài)體系副编,以及一些知名開(kāi)源軟件對(duì)gRPC的使用扣典,最后總結(jié)gRPC與netty妆毕、dubbo等框架的區(qū)別,目的是讓讀者從整體上對(duì)gRPC有一個(gè)相對(duì)全面的認(rèn)知激捏。
1 gRPC起源
十多年來(lái)设塔,Google一直在使用一個(gè)名為Stubby的通用RPC基礎(chǔ)架構(gòu)來(lái)連接在數(shù)據(jù)中心內(nèi)部和跨越數(shù)據(jù)中心運(yùn)行的大量微服務(wù),其內(nèi)部系統(tǒng)長(zhǎng)期以來(lái)一直接受微服務(wù)架構(gòu)的普及远舅。
擁有統(tǒng)一的跨平臺(tái)RPC基礎(chǔ)架構(gòu)闰蛔,可以在整個(gè)系統(tǒng)范圍內(nèi)推廣效率,安全性图柏,可靠性和行為分析序六,這對(duì)于支持Google的驚人增長(zhǎng)至關(guān)重要。我們今天使用的每個(gè)Google服務(wù)背后的RPC骨干都是Stubby蚤吹。
Stubby有許多很棒的功能 - 但是例诀,它不是基于任何標(biāo)準(zhǔn)随抠,而是與Google的內(nèi)部基礎(chǔ)設(shè)施緊密耦合,并不適合公開(kāi)發(fā)布繁涂。
隨著SPDY拱她,HTTP / 2和QUIC的出現(xiàn),許多這些相同的功能已經(jīng)出現(xiàn)在公共標(biāo)準(zhǔn)中扔罪,以及Stubby未提供的其他功能秉沼。很明顯,是時(shí)候重做Stubby以利用這種標(biāo)準(zhǔn)化矿酵,并將其適用范圍擴(kuò)展到分布式計(jì)算的最后一英里唬复,支持移動(dòng)設(shè)備(如安卓)、物聯(lián)網(wǎng)(IOT)全肮、和瀏覽器連接到后端服務(wù)敞咧。
2015年3月,Google決定在公開(kāi)場(chǎng)合構(gòu)建下一版Stubby辜腺,以便與業(yè)界分享經(jīng)驗(yàn)休建,并進(jìn)行相關(guān)合作,為Google內(nèi)部以及外界的微服務(wù)構(gòu)建下一版本的Stubby评疗,也就是本文要介紹的主角gRPC丰包。
2 gRPC介紹
gRPC是一個(gè)現(xiàn)代的開(kāi)源高性能RPC框架,可以在任何環(huán)境中運(yùn)行壤巷。它可以有效地連接數(shù)據(jù)中心內(nèi)和跨數(shù)據(jù)中心的服務(wù)邑彪,并提供可插拔的支持,以實(shí)現(xiàn)負(fù)載平衡(load balancing)胧华,調(diào)用鏈追蹤(tracing)寄症,健康檢查(health checking)和身份驗(yàn)證(authentication)。它還適用于分布式計(jì)算的最后一英里矩动,用于將設(shè)備有巧,移動(dòng)應(yīng)用程序和瀏覽器連接到后端服務(wù)。
gRPC的四個(gè)核心特性悲没,使得其對(duì)開(kāi)發(fā)者有著極大的吸引力:
簡(jiǎn)單的服務(wù)定義
跨平臺(tái)跨語(yǔ)言
基于http/2雙向流傳輸
可插拔的插件機(jī)制
2.1 服務(wù)定義
與許多 RPC 系統(tǒng)類似篮迎,gRPC 也是基于以下理念:定義一個(gè)服務(wù),指定其能夠被遠(yuǎn)程調(diào)用的方法(包含參數(shù)和返回類型)示姿。在服務(wù)端實(shí)現(xiàn)這個(gè)接口甜橱,并運(yùn)行一個(gè) gRPC 服務(wù)器來(lái)處理客戶端調(diào)用。在客戶端擁有一個(gè)存根(Stub)栈戳,它提供與服務(wù)器相同的方法岂傲。客戶端應(yīng)用可以像調(diào)用本地對(duì)象一樣直接調(diào)用另一臺(tái)不同的機(jī)器上服務(wù)端應(yīng)用的方法子檀,其背后會(huì)通過(guò)RPC通信給服務(wù)端發(fā)送請(qǐng)求镊掖,并獲得響應(yīng)乃戈。如下圖:
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
要完成這樣的功能,我們首先要進(jìn)行服務(wù)定義(Service Definition)亩进,一些框架中症虑,將定義服務(wù)的語(yǔ)法稱之為IDL(Interface Definition Language,接口定義語(yǔ)言)归薛。
gRPC 默認(rèn)使用 Protocol Buffer進(jìn)行服務(wù)定義侦讨,這是 Google 開(kāi)源的一套成熟的結(jié)構(gòu)數(shù)據(jù)序列化機(jī)制(當(dāng)然也可以使用其他數(shù)據(jù)格式如 JSON)。
目前Protocol Buffer已經(jīng)發(fā)展到proto3苟翻,相對(duì)于proto2,它擁有輕量簡(jiǎn)化的語(yǔ)法骗污、一些有用的新功能崇猫,并且支持更多新語(yǔ)言。通常建議在 gRPC 里使用 proto3需忿,因?yàn)檫@樣你可以使用 gRPC 支持全部范圍的的語(yǔ)言诅炉,并且能避免 proto2 客戶端與 proto3 服務(wù)端交互時(shí)出現(xiàn)的兼容性問(wèn)題,反之亦然屋厘。
使用Protocol Buffer進(jìn)行服務(wù)定義非常簡(jiǎn)單明了涕烧,我們可以創(chuàng)建一個(gè).proto文件,按照Protocol Buffer語(yǔ)法編寫此文件汗洒,如:
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
說(shuō)明如下:
定義一個(gè)表示請(qǐng)求的HelloRequest议纯,其包含一個(gè)message字段表示請(qǐng)求內(nèi)容
定義一個(gè)表示響應(yīng)的HelloResponse,其包含一個(gè)message字段表示響應(yīng)內(nèi)容
定義服務(wù)HelloService溢谤,其提供一個(gè)hello方法瞻凤,以HelloRequest作為方法參數(shù),并返回HelloResponse
考慮為什么要在一個(gè)文件中進(jìn)行服務(wù)定義世杀?
這主要是為了跨語(yǔ)言阀参。gRPC提供了工具,可以根據(jù)服務(wù)定義文件瞻坝,來(lái)為不同的平臺(tái)和語(yǔ)言生成server端和client端的代碼蛛壳,意味著你的服務(wù)端和客戶端,可以使用不同的語(yǔ)言所刀。例如衙荐,筆者最近開(kāi)發(fā)的一個(gè)服務(wù),服務(wù)端使用go編寫浮创,客戶端需要支持go赫模、python、java蒸矛。此時(shí)筆者就可以根據(jù)這個(gè)配置文件瀑罗,分別生成不同語(yǔ)言的代碼胸嘴。
2.2 跨語(yǔ)言跨平臺(tái)工作
gRPC提供了工具,可以為不同的平臺(tái)斩祭、語(yǔ)言劣像,生成對(duì)應(yīng)的client和server代碼,使得彼此之間可以通過(guò)gRPC進(jìn)行通信摧玫。
通常一個(gè)規(guī)模較大的公司耳奕,技術(shù)棧往往不統(tǒng)一,可能會(huì)使用多種語(yǔ)言诬像。通過(guò)gRPC屋群,服務(wù)端我們可以使用一種語(yǔ)言編寫,而客戶端可以支持多種語(yǔ)言坏挠。
下圖演示了服務(wù)端使用C++芍躏,客戶端使用Java和Ruby的交互案例:
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
截止筆者撰寫此文(2019年6月28日),官方支持10種語(yǔ)言降狠,以及l(fā)inux对竣、mac、windows三種平臺(tái)榜配,具體如下:
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
2.3 插件機(jī)制
grpc提供了可插拔的插件機(jī)制否纬,或者說(shuō)是攔截器機(jī)制,以對(duì)每一次RPC請(qǐng)求進(jìn)行攔截蛋褥×偃迹基于此,我們可以實(shí)現(xiàn)一些RPC通信過(guò)程中的高級(jí)功能烙心。如:
身份驗(yàn)證:
gRPC內(nèi)置了兩種驗(yàn)證機(jī)制谬俄,基于連接層面的SSL/TLS,以及基于Google Token的身份認(rèn)證機(jī)制弃理。如果不滿足需求溃论,你也很容易的進(jìn)行擴(kuò)展自己驗(yàn)證機(jī)制。
負(fù)載均衡:
在微服務(wù)架構(gòu)中痘昌,為了實(shí)現(xiàn)容災(zāi)钥勋、高可用或者水平擴(kuò)展等目的,通常一個(gè)服務(wù)都會(huì)部署多個(gè)節(jié)點(diǎn)辆苔∷憔模客戶端在調(diào)用時(shí),盡量的將請(qǐng)求分散在不同的節(jié)點(diǎn)上驻啤,以實(shí)現(xiàn)負(fù)載均衡菲驴。通常負(fù)載均衡有兩種模式:1)通過(guò)代理,即請(qǐng)求先發(fā)送給一個(gè)中間代理服務(wù)器骑冗,例如nginx赊瞬,由代理按照負(fù)載均衡策略選擇一個(gè)后端節(jié)點(diǎn)進(jìn)行處理先煎;2) 客戶端路由:客戶端按照負(fù)載均衡選擇某個(gè)后端服務(wù)節(jié)點(diǎn),進(jìn)行調(diào)用巧涧。gRPC提供了一套完善的機(jī)制薯蝎,支持客戶端發(fā)現(xiàn)服務(wù)端有哪些節(jié)點(diǎn),以及自定義負(fù)載均衡策略谤绳。
健康檢查:
健康檢查用于探測(cè)服務(wù)端是否可以處理RPC請(qǐng)求占锯。檢查檢查可以由客戶端直接發(fā)起,或者通過(guò)其他系統(tǒng)(如consul)缩筛。服務(wù)端可以選擇回復(fù)”unhealthy"來(lái)表明自己還沒(méi)準(zhǔn)備好處理請(qǐng)求消略,或者服務(wù)端已經(jīng)宕機(jī)∠古祝客戶端根據(jù)服務(wù)端回復(fù)的響應(yīng)信息艺演,或者指定時(shí)間內(nèi)是否收到響應(yīng),來(lái)判斷服務(wù)端是否健康婿失。
2.4 基于HTTP/2雙向流傳輸
gRPC 基于 HTTP/2 標(biāo)準(zhǔn)設(shè)計(jì),帶來(lái)諸如雙向流啄寡、流控豪硅、頭部壓縮、單 TCP 連接上的多復(fù)用請(qǐng)求等特挺物。這些特性使得其在移動(dòng)設(shè)備上表現(xiàn)更好懒浮,更省電和節(jié)省空間占用。
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
gRPC利用HTTP/2進(jìn)行消息傳輸识藤,但是其只是本身定義了HTTP2中的傳輸單元中幀(Frame)的格式砚著。至于HTTP/2協(xié)議本身的解析,gRPC盡量復(fù)用已有的組件痴昧。例如稽穆,在Java中,Netty本身支持HTTP/2協(xié)議協(xié)議赶撰,因此gRPC默認(rèn)是支持與netty進(jìn)行整合的舌镶。又或者,如果你希望移動(dòng)設(shè)備(如安卓)豪娜,可以直接與服務(wù)端進(jìn)行交互餐胀,那么在安卓客戶端,你可以選擇將gRPC與okHttp進(jìn)行整合瘤载。
3 gRPC生態(tài)體系
gRPC有著豐富的生態(tài)系統(tǒng)否灾,這些組件是由不是官方提供。以下介紹部分組件:
grpc-opentracing
grpc-gateway
grpc-prometheus
其他組件
3.1 grpc-opentracing
在RPC調(diào)用過(guò)程中鸣奔,可能會(huì)出現(xiàn)A調(diào)動(dòng)B墨技,B又調(diào)用C等情況惩阶,此時(shí)我們希望對(duì)完整的調(diào)用鏈路進(jìn)行追蹤。
grpc生態(tài)系統(tǒng)中有一個(gè)grpc-opentracing組件健提,我們可以使用其對(duì)接zipkin琳猫,進(jìn)行調(diào)用鏈路展示,查看整個(gè)調(diào)用鏈路中每個(gè)環(huán)節(jié)的耗時(shí)私痹,以發(fā)現(xiàn)系統(tǒng)的瓶頸脐嫂。下
圖來(lái)源自zipkin官網(wǎng),我們可以看到鏈路追蹤的最終展示效果:
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
3.2 grpc-promethus
grpc-prometheus來(lái)對(duì)gRPC服務(wù)進(jìn)行監(jiān)控紊遵,并將監(jiān)控?cái)?shù)據(jù)存儲(chǔ)到prometheus中账千。
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
目前有2種語(yǔ)言的實(shí)現(xiàn):
java-grpc-prometheus
go-grpc-prometheus
監(jiān)控指標(biāo)服務(wù)端與客戶端分別統(tǒng)計(jì),統(tǒng)計(jì)的指標(biāo)包括:發(fā)起了多少個(gè)請(qǐng)求暗膜,接收到了多少個(gè)響應(yīng)匀奏,響應(yīng)延遲等。
3.3 grpc-gateway
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
gRPC已經(jīng)支持了絕大部分主流語(yǔ)言学搜,對(duì)于一些小眾語(yǔ)言可能不支持娃善,此時(shí)你可以使用grpc-gateway來(lái)進(jìn)行反向代理。
grpc-gateway本質(zhì)是一個(gè)protoc插件瑞佩,我們?cè)诰帉慻RPC服務(wù)定義proto文件聚磺,通過(guò)指定一些自定義選項(xiàng),在編譯時(shí)炬丸,在生成gRPC代碼時(shí)瘫寝,額外指定生成grpc-gateway反向代理相關(guān)代碼,其作用是將RESTful JSON API請(qǐng)求轉(zhuǎn)換為gRPC請(qǐng)求稠炬。
之后焕阿,我們對(duì)反向代理代碼進(jìn)行改造,對(duì)于不支持gRPC的語(yǔ)言首启,讓其發(fā)送HTTP RESTful JSON 請(qǐng)求暮屡,通過(guò)反向代理將其轉(zhuǎn)換成grpc請(qǐng)求,下圖演示了其工作原理:
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
3.4 其他支持
上述提到的幾個(gè)組件gRPC生態(tài)體系中的組件毅桃,圍繞著gRPC來(lái)開(kāi)發(fā)的栽惶。一些其他的著名開(kāi)源軟件,如nginx疾嗅、haproxy等外厂,也提供了對(duì)gRPC的支持。
3.4.1 nginx對(duì)gRPC的支持
nginx從1.13.10開(kāi)始提供對(duì)grpc的支持代承,client端和server端都可以使用gRPC實(shí)現(xiàn)汁蝶,通過(guò)nginx進(jìn)行代理,如下圖:
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
nginx使用grpc_pass指令代理流量。下面的nginx代理配置掖棉,演示了在端口80上偵聽(tīng)未加密的gRPC流量并將請(qǐng)求轉(zhuǎn)發(fā)到端口50051上的服務(wù)器墓律。
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
更完整的介紹和配置,點(diǎn)擊這里:
https://www.nginx.com/blog/nginx-1-13-10-grpc/
3.4.2 HAProxy對(duì)gRPC的支持
HAProxy 從1.9.2 添加了對(duì)gRPC的支持幔亥。完整介紹耻讽,點(diǎn)擊以下鏈接:
https://www.haproxy.com/blog/haproxy-1-9-2-adds-grpc-support/
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
4 gRPC使用案例
很多知名公司或者機(jī)構(gòu)目前都使用了gRPC,這些公司對(duì)gRPC的使用帕棉,本身就證明了其強(qiáng)大穩(wěn)定與可靠针肥。官方列出有以下這些:
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
這些公司分別在各自的產(chǎn)品中使用了gRPC,下面介紹etcd和tidb香伴。
4.1 etcd案例
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
etcd是一個(gè)可靠的分布式k/v存儲(chǔ)慰枕,利用Raft一致性算法,用于存儲(chǔ)分布式系統(tǒng)的最關(guān)鍵數(shù)據(jù)即纲,使用Go語(yǔ)言編寫具帮,k8s使用了etcd來(lái)存儲(chǔ)數(shù)據(jù)。
etcd v3 使用 gRPC 作為它的消息協(xié)議低斋。etcd 項(xiàng)目包括基于 gRPC 的 Go client 和 命令行工具 etcdctl蜂厅,通過(guò) gRPC 和 etcd 集群通訊。另外膊畴,對(duì)于gRPC不支持的語(yǔ)言掘猿,etcd v3通過(guò)grpc-gateway(回顧前文)予以支持。
4.2 tidb案例
TiDB 是 PingCAP 公司設(shè)計(jì)的開(kāi)源分布式 HTAP (Hybrid Transactional and Analytical Processing) 數(shù)據(jù)庫(kù)巴比,結(jié)合了傳統(tǒng)的 RDBMS 和 NoSQL 的最佳特性术奖。TiDB 兼容 MySQL礁遵,支持無(wú)限的水平擴(kuò)展轻绞,具備強(qiáng)一致性和高可用性。
TiDB 集群主要包括三個(gè)核心組件:TiDB Server佣耐,**PD Server **和 TiKV Server政勃。此外,還有用于解決用戶復(fù)雜 OLAP 需求的 TiSpark 組件兼砖。這些組件之間也使用gRPC來(lái)交互奸远,如下圖:
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
圖片來(lái)源自網(wǎng)絡(luò)
關(guān)于tidb與gRPC的淵源,參考這里(故事比較曲折):
https://blog.csdn.net/weixin_33919941/article/details/89145274
5 gRPC性能
之所以有這么多廠商使用gRPC讽挟,除了其本身的設(shè)計(jì)懒叛,豐富的生態(tài)體系,與其高性能也有著極大的關(guān)系耽梅。
gRPC專為分布式應(yīng)用的高性能和高生產(chǎn)率設(shè)計(jì)而設(shè)計(jì)薛窥。持續(xù)性能基準(zhǔn)測(cè)試是gRPC開(kāi)發(fā)工作流程的關(guān)鍵部分。目前gRPC會(huì)針對(duì)master分支每小時(shí)運(yùn)行一次多語(yǔ)言性能測(cè)試,并將這些數(shù)字報(bào)告給儀表板以進(jìn)行可視化诅迷。
測(cè)試場(chǎng)景
無(wú)爭(zhēng)用延遲 - 只有1個(gè)客戶端使用StreamingCall一次發(fā)送一條消息時(shí)看到的中位數(shù)和尾部響應(yīng)延遲
QPS - 當(dāng)有2個(gè)客戶端和總共64個(gè)通道時(shí)的消息/秒速率佩番,每個(gè)通道使用StreamingCall一次發(fā)送100個(gè)未完成的消息
可伸縮性(適用于所選語(yǔ)言) - 每個(gè)服務(wù)器核心的消息數(shù)/秒
下圖演示了第二個(gè)測(cè)試場(chǎng)景下的測(cè)試qps:
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "點(diǎn)擊并拖拽以移動(dòng)")
可以看到,使用go和java時(shí)罢杉,qps接近240w/s這個(gè)驚人的數(shù)字趟畏。當(dāng)然,千萬(wàn)不能完全相信這個(gè)數(shù)字滩租,qps受到網(wǎng)絡(luò)赋秀、消息大小尖坤、機(jī)器配置等多種因素的綜合影響芍耘。實(shí)際使用還是需要自行測(cè)試。
6 總結(jié)
本文概括性的介紹gRPC究抓,包括gRPC的起源蜘欲,核心特性益眉,生態(tài)體系,以及一些知名開(kāi)源軟件對(duì)gRPC的使用姥份,目的是讓讀者從整體上對(duì)gRPC有一個(gè)相對(duì)全面的認(rèn)知郭脂。
補(bǔ)充:gRPC與netty、dubbo等框架的區(qū)別
netty本質(zhì)上是一個(gè)高性能的網(wǎng)路通信框架澈歉,且局限于Java語(yǔ)言展鸡。gRPC則不同,則是面向微服務(wù)設(shè)計(jì)的埃难,netty可以作為gRPC的底層通信框架莹弊,gRPC本身還支持很多微服務(wù)中的概念,如前面提到的服務(wù)發(fā)現(xiàn)注冊(cè)涡尘,鏈路追蹤等忍弛。
與其他微服務(wù)框架如dubbo、spring cloud等考抄,gRPC不局限于某一種語(yǔ)言细疚,而是幾乎所有主流語(yǔ)言。
另外一個(gè)很大的不同是川梅,gRPC不是采用私有協(xié)議疯兼,而是基于標(biāo)準(zhǔn)的HTTP/2實(shí)現(xiàn),這意味著可能會(huì)有更多的廠商使用或者支持gRPC贫途,如果前面提到的nginx吧彪、etcd等。這體現(xiàn)了遵循標(biāo)準(zhǔn)的重要性丢早,試想姨裸,如果想要nginx支持dubbo,或者etcd來(lái)使用dubbo,幾乎是不可能的事情啦扬。
設(shè)計(jì)者的思路中狂,直接決定了一門技術(shù)到底能夠有多廣泛的使用場(chǎng)景。
微信公眾號(hào)【程序員黃小斜】作者是前螞蟻金服Java工程師扑毡,專注分享Java技術(shù)干貨和求職成長(zhǎng)心得胃榕,不限于BAT面試,算法瞄摊、計(jì)算機(jī)基礎(chǔ)勋又、數(shù)據(jù)庫(kù)、分布式换帜、spring全家桶楔壤、微服務(wù)、高并發(fā)惯驼、JVM蹲嚣、Docker容器,ELK祟牲、大數(shù)據(jù)等隙畜。關(guān)注后回復(fù)【book】領(lǐng)取精選20本Java面試必備精品電子書。