來自公眾號:****51CTO技術棧
“
經(jīng)濟高速發(fā)展的今天,我們處于信息大爆炸的時代彰亥。隨著經(jīng)濟發(fā)展咧七,信息借助互聯(lián)網(wǎng)的力量在全球自由地流動,于是就催生了各種各樣的服務平臺和軟件系統(tǒng)任斋。
由于業(yè)務的多樣性继阻,這些平臺和系統(tǒng)也變得異常的復雜。如何對其進行監(jiān)控和維護是我們 IT 人需要面對的重要問題废酷。就在這樣一個紛繁復雜地環(huán)境下瘟檩,監(jiān)控系統(tǒng)粉墨登場了。
今天澈蟆,我們會對 IT 監(jiān)控系統(tǒng)進行介紹墨辛,包括其功能,分類丰介,分層背蟆;同時也會介紹幾款流行的監(jiān)控平臺。
監(jiān)控系統(tǒng)的功能
在 IT 運維過程中哮幢,常遇到這樣的情況:
某個業(yè)務模塊出現(xiàn)問題,運維人員并不知道志珍,發(fā)現(xiàn)的時候問題已經(jīng)很嚴重了橙垢。
系統(tǒng)出現(xiàn)瓶頸了,CPU 占用持續(xù)升高伦糯,內(nèi)存不足柜某,磁盤被寫滿;網(wǎng)絡請求突增敛纲,超出網(wǎng)關承受的壓力喂击。
以上這些問題一旦發(fā)生,會對我們的業(yè)務產(chǎn)生巨大的影響淤翔。因此翰绊,每個公司或者 IT 團隊都會針對此類情況建立自己的 IT 監(jiān)控系統(tǒng)。
監(jiān)控系統(tǒng)工作流程圖
其功能包括:
對服務旁壮,系統(tǒng)监嗜,平臺的運行狀態(tài)實時監(jiān)控。
收集服務抡谐,系統(tǒng)裁奇,平臺的運行信息。
通過收集信息的分析結(jié)果麦撵,預知存在的故障風險刽肠,并采取行動溃肪。
根據(jù)對風險的評估,進行故障預警音五。
一旦發(fā)生故障惫撰,第一時間發(fā)出告警信息。
通過監(jiān)控數(shù)據(jù)放仗,定位故障润绎,協(xié)助生成解決方案。
最終保證系統(tǒng)持續(xù)诞挨、穩(wěn)定莉撇、安全運行。
監(jiān)控數(shù)據(jù)可視化惶傻,便于統(tǒng)計棍郎,按照一定周期導出、歸檔银室,用于數(shù)據(jù)分析和問題復盤涂佃。
監(jiān)控系統(tǒng)的分類
既然監(jiān)控系統(tǒng)對我們意義重大,針對不同場景把監(jiān)控系統(tǒng)分為三類蜈敢,分別是:
日志類
調(diào)用鏈類
度量類
日志類
通常我們在系統(tǒng)和業(yè)務級別上加入一些日志代碼辜荠,記錄一些日志信息,方便我們在發(fā)現(xiàn)問題的時候查找抓狭。
這些信息會與事件做相關伯病,例如:用戶登錄,下訂單否过,用戶瀏覽某件商品午笛,一小時以內(nèi)的網(wǎng)關流量,用戶平均響應時間等等苗桂。
這類以日志的記錄和查詢的解決方案比較多药磺。比如 ELK 方案(Elasticsearch+Logstash+Kibana),使用ELK(Elasticsearch煤伟、Logstash癌佩、Kibana)+Kafka/Redis/RabbitMQ 來搭建一個日志系統(tǒng)。
ELK 結(jié)合 Redis/Kafka/RabbitMQ 實現(xiàn)日志類監(jiān)控程序內(nèi)部通過 Spring AOP 記錄日志持偏,Beats 收集日志文件驼卖,然后用 Kafka/Redis/RabbitMQ 將其發(fā)送給 Logstash,Logstash 再將日志寫入 Elasticsearch鸿秆。最后酌畜,使用 Kibana 將存放在 Elasticsearch 中的日志數(shù)據(jù)顯示出來,形式可以是實時數(shù)據(jù)圖表卿叽。
調(diào)用鏈類
對于服務較多的系統(tǒng)桥胞,特別是微服務系統(tǒng)恳守。一次服務的調(diào)用有可能涉及到多個服務。A 調(diào)用 B贩虾,B 又要調(diào)用 C催烘,好像一個鏈條一樣,形成了服務調(diào)用鏈缎罢。調(diào)用鏈就是記錄一個請求經(jīng)過所有服務的過程伊群。請求從開始進入服務,經(jīng)過不同的服務節(jié)點后策精,再返回給客戶端舰始,通過調(diào)用鏈參數(shù)來追蹤全鏈路行為。從而知道請求在哪個環(huán)節(jié)出了故障咽袜,系統(tǒng)的瓶頸在哪兒丸卷。調(diào)用鏈監(jiān)控的實現(xiàn)原理如下:
①Java 探針,字節(jié)碼增強
Java 代碼運行原理圖在介紹這種方式之前询刹,我們先來復習一下 Java 代碼運行的原理谜嫉。通常我們會把 Java 源代碼,通過“Java 編譯器”編譯成 Class 文件凹联。再把這個 Class 的字節(jié)碼文件裝載到“類裝載器”中進行字節(jié)碼的驗證沐兰。最后,把驗證過后的字節(jié)碼發(fā)送到“Java 解釋器”和“及時編譯器”交給“Java 運行系統(tǒng)”運行蔽挠。Java 探針僧鲁,字節(jié)碼增強的方式就是利用 Java 代理,這個代理是運行方法之前的攔截器象泵。在 JVM 加載 Class 二進制文件的時候,利用 ASM 動態(tài)的修改加載的 Class 文件斟叼,在監(jiān)控的方法前后添加需要監(jiān)控的內(nèi)容偶惠。例如:添加計時語句,用于記錄方法耗時朗涩。將方法耗時存入處理器忽孽,利用棧先特性(先進后出)處理方法調(diào)用順序。每當請求處理結(jié)束后谢床,將耗時方法和入?yún)?map 輸出到文件中兄一,然后根據(jù) map 中相應參數(shù),區(qū)分出耗時業(yè)務识腿。
最后將相應耗時文件取下來出革,轉(zhuǎn)化為 xml 格式并進行解析,通過瀏覽器將代碼分層結(jié)構展示出來渡讼。
Java 探針工具原理圖備注:ASM 是一個 Java 字節(jié)碼操縱框架骂束,它可以動態(tài)生成類或者增強既有類的功能耳璧。ASM 可以直接產(chǎn)生二進制 Class 文件,可以在類被載入 Java 虛擬機之前改變類行為展箱。Java Class 被存儲在 .class文件里旨枯,文件擁有元數(shù)據(jù)來解析類中的元素:類名稱、方法混驰、屬性以及 Java 字節(jié)碼(指令)攀隔。ASM 從類文件中讀入信息后,能夠改變類行為栖榨,分析類信息昆汹,甚至能夠生成新類。②攔截請求獲取每次請求服務中的信息來實現(xiàn)跟蹤的治泥。這里以 Zipkin+Slueth 為例說明其原理筹煮。
Sleuth 提供鏈路追蹤。由于一個請求會涉及到多個服務的互相調(diào)用居夹,而這種調(diào)用往往成鏈式結(jié)構败潦,經(jīng)過多次層層調(diào)用以后請求才會返回。常常使用 Sleuth 追蹤整個調(diào)用過程准脂,方便理清服務間的調(diào)用關系劫扒。
Sleuth 服務調(diào)用追蹤圖例每次請求都會生成一個 Trace ID,如上圖所示這個 Trace ID 在整個 Request 和 Response 過程中都會保持一致狸膏,不論經(jīng)過了多少個服務沟饥。這是為了方便記錄一次調(diào)用的整個生命周期。再看每次請求的時候都會有一個 Span ID湾戳,這里的 Span 是 Sleuth 服務跟蹤的最小單元贤旷,每經(jīng)過一個服務,每次 Request 和 Response 這個值都會有所不同砾脑,這是為了區(qū)分不同的調(diào)用動作幼驶。針對每個調(diào)用的動作,Sleuth 都做了標示如下:
Server Received 是服務器接受韧衣,也就是服務端接受到請求的意思盅藻。
Client Sent 是客戶端發(fā)送,也就是這個服務本身不提供響應畅铭,需要調(diào)用其他的服務提供該響應氏淑,所以這個時候是作為客戶端發(fā)起請求的。
Server Sent 是服務端發(fā)送硕噩,看上圖SERVICE 3 收到請求后假残,由于他是最終的服務提供者,所以作為服務端榴徐,他需要把請求發(fā)送給調(diào)用者守问。
Client Received 是客戶端接受匀归,作為發(fā)起調(diào)用的客戶端接受到服務端返回的請求。
實際上 Sleuth 就是通過上述方式把每次請求記錄一個統(tǒng)一的 Trace ID耗帕,每個請求的詳細步驟記作 Span ID穆端。
每次發(fā)起請求或者接受請求的狀態(tài)分別記錄成 Server Received,Client Sent仿便,Server Sent体啰,Client Received 四種狀態(tài)來完成這個服務調(diào)用鏈路的跟蹤的。
Sleuth 服務調(diào)用追蹤圖例在調(diào)用服務的鏈路上每個被調(diào)用的服務節(jié)點都會通過 Parent ID 來記錄發(fā)起調(diào)用服務的 Span ID嗽仪,由于 Span ID 是唯一確認最小服務單元的荒勇,所以知道了 Parent 的 Span ID 也就知道了誰調(diào)用自己了。
度量類
實現(xiàn)了時序數(shù)據(jù)庫(TimeSeriesData闻坚,TSD)的監(jiān)控方案沽翔。實際上就是記錄一串以時間為維度的數(shù)據(jù),然后再通過聚合運算窿凤,查看指標數(shù)據(jù)和指標趨勢仅偎。說白了,就是描述某個被測主體在一段時間內(nèi)的測量值變化(度量)雳殊。由于 IT 基礎設施橘沥,運維監(jiān)控和互聯(lián)網(wǎng)監(jiān)控的特性,這種方式被廣泛應用夯秃。一般對時序數(shù)據(jù)進行建模分為三個部分座咆,分別是:主體,時間點和測量值仓洼。通過這個例子來看一下介陶,時序數(shù)據(jù)庫的數(shù)學模型,例如:需要監(jiān)控服務器的 In/Out 平均流量:
整個監(jiān)控的數(shù)據(jù)庫稱為“Metric”色建,它包含了所有監(jiān)控的數(shù)據(jù)斤蔓。類似關系型數(shù)據(jù)庫中的 Table。
每條監(jiān)控數(shù)據(jù)镀岛,稱為“Point”,類似于關系型數(shù)據(jù)庫中的 Row 的概念友驮。
每個“Point”都會定義一個時間戳“Timestamp”漂羊,將其作為索引,表明數(shù)據(jù)采集的時間卸留。
“Tag”作為維度列走越,表示監(jiān)控數(shù)據(jù)的屬性。
“Field”作為指標列耻瑟,作為測量值旨指,也就是測量的結(jié)果赏酥。
時序數(shù)據(jù)庫數(shù)據(jù)模型圖例時序數(shù)據(jù)庫的存儲原理,關系型數(shù)據(jù)庫存儲采用的是 B tree谆构,雖然降低了數(shù)據(jù)查詢的磁盤尋道時間裸扶,但是無法解決大量數(shù)據(jù)寫入時的磁盤效率。由于監(jiān)控系統(tǒng)的應用場景搬素,經(jīng)常會遇到大批量的數(shù)據(jù)寫入呵晨,所以我們會選擇 LSMtree(Log Structured Merge Tree)存儲時序數(shù)據(jù)庫。LSMtree(Log Structured Merge Tree)熬尺,從字面意義上理解摸屠,記錄的數(shù)據(jù)按照日志結(jié)構(Log Structured)追加到系統(tǒng)中,然后通過合并樹(Merge Tree)的方式將其合并粱哼。來看一個 LevelDB 的例子季二,方便我們理解,LSM-tree 被分成三種文件:
接收寫入請求的 memtable 文件(內(nèi)存中)
不可修改的 immutable memtable 文件(內(nèi)存中)
磁盤上的 SStable文件(Sorted String Table)揭措,有序字符串表胯舷,這個有序的字符串就是數(shù)據(jù)的key。SStable 一共有七層(L0 到 L6)蜂筹。下一層的總大小限制是上一層的 10 倍需纳。
LSMtree LevelDB 存儲示意圖LSMtree 寫入流程:
將數(shù)據(jù)追加到日志 WAL(Write Ahead Log)中,寫入日志的目的是為了防止內(nèi)存數(shù)據(jù)丟失艺挪,可以及時恢復不翩。
把數(shù)據(jù)寫到 memtable 中。
當 memtable 滿了(超過一定閥值)麻裳,就將這個 memtable 轉(zhuǎn)入 immutable memtable 中口蝠,用新的 memtable 接收新的數(shù)據(jù)請求。
-
immutablememtable 一旦寫滿了津坑, 就寫入磁盤妙蔗。并且先存儲 L0 層的 SSTable 磁盤文件,此時還不需要做文件的合并疆瑰。
每層的所有文件總大小是有限制的(8MB眉反,10MB,100MB… 1TB)穆役。從 L1 層往后寸五,每下一層容量增大十倍。
-
某一層的數(shù)據(jù)文件總量超過閾值耿币,就在這一層中選擇一個文件和下一層的文件進行合并梳杏。
如此這般上層的數(shù)據(jù)都是較新的數(shù)據(jù),查詢可以從上層開始查找,依次往下十性,并且這些數(shù)據(jù)都是按照時間序列存放的叛溢。
監(jiān)控系統(tǒng)的分層
談完了監(jiān)控系統(tǒng)的分類,再來聊聊監(jiān)控系統(tǒng)的分層劲适。用戶請求到數(shù)據(jù)返回楷掉,經(jīng)歷系統(tǒng)中的層層關卡。
監(jiān)控系統(tǒng)分層示意圖
一般我們將監(jiān)控系統(tǒng)分為五層來考慮减响,當然也有人分成三層靖诗,大致的意思都差不多,僅供參考:
客戶端監(jiān)控支示,用戶行為信息刊橘,業(yè)務返回碼,客戶端性能颂鸿,運營商促绵,版本,操作系統(tǒng)等嘴纺。
業(yè)務層監(jiān)控败晴,核心業(yè)務的監(jiān)控,例如:登錄栽渴,注冊尖坤,下單,支付等等闲擦。
應用層監(jiān)控慢味,相關的技術參數(shù),例如:URL 請求次數(shù)墅冷,Service 請求數(shù)量纯路,SQL 執(zhí)行的結(jié)果,Cache 的利用率寞忿,QPS 等等钾军。
系統(tǒng)層監(jiān)控驾讲,物理主機精拟,虛擬主機以及操作系統(tǒng)的參數(shù)世曾。例如:CPU 利用率,內(nèi)存利用率霹抛,磁盤空間情況宵溅。
網(wǎng)絡層監(jiān)控,網(wǎng)絡情況參數(shù)上炎。例如:網(wǎng)關流量情況,丟包率,錯包率藕施,連接數(shù)等等寇损。
流行的監(jiān)控系統(tǒng)
前面講了監(jiān)控系統(tǒng)的功能,分類裳食,分層矛市,相信大家對 IT 監(jiān)控系統(tǒng)都有一定的了解了。接下來诲祸,我們來看看有哪些優(yōu)秀實踐浊吏。這里介紹兩個比較流行的監(jiān)控系統(tǒng):
Zabbix
Prometheus
Zabbix
Zabbix 是一款企業(yè)級的分布式開源監(jiān)控方案。它由 Alexei Vladishev 創(chuàng)建救氯,由 Zabbix SIA 在持續(xù)開發(fā)和支持找田。Zabbix 能夠監(jiān)控網(wǎng)絡參數(shù),服務器健康和軟件完整性着憨。它提供通知機制墩衙,允許用戶配置告警,從而快速反饋問題甲抖∑岣模基于存儲的數(shù)據(jù),Zabbix 提供報表和數(shù)據(jù)可視化准谚,并且支持主動輪詢和被動捕獲挫剑。它的所有報告、統(tǒng)計信息和配置參數(shù)都可以通過 Web 頁面訪問柱衔。Zabbix 的 API 功能樊破,完善度很高,大部分操作都提供了 API 接口秀存,方便和現(xiàn)有系統(tǒng)整合捶码。例如:通過歷史數(shù)據(jù)查詢 API,獲取線上服務器使用情況或链,生成報表惫恼;設置條件,對問題服務器和問題業(yè)務進行篩選澳盐,加入告警祈纯。利用 Zabbix graph 的 API,生成關鍵指標趨勢圖叼耙,方便運維人員實時了解系統(tǒng)情況腕窥。利用告警添加 API,讓監(jiān)控系統(tǒng)和部署系統(tǒng)聯(lián)動筛婉。比如新部署了一個新實例簇爆,那么自動添加所需要的監(jiān)控策略癞松;反之,下線一個實例入蛆,就刪除關聯(lián)的監(jiān)控策略响蓉。Zabbix 由 Server,Agent哨毁,Proxy(可選項)組成:
Agent 負責收集數(shù)據(jù)枫甲,并且傳輸給 Server。
Server 負責接受 Agent 的數(shù)據(jù)扼褪,進行保存或者告警想幻。
Proxy 負責代理 Server 收集 Agent 傳輸?shù)臄?shù)據(jù),并且轉(zhuǎn)發(fā)給 Server话浇。Proxy 是安裝在被監(jiān)控的服務器上的脏毯,用來和 Server 端進行通信,從而傳輸數(shù)據(jù)凳枝。
Zabbix 的部署模式Zabbix 的數(shù)據(jù)采集抄沮,主要有兩種模式:Server 主動拉取數(shù)據(jù)和 Agent 主動上報數(shù)據(jù)。以 Server 拉取數(shù)據(jù)為例岖瑰,用戶在 Web-portal 中叛买,設置需要監(jiān)控的機器,配置監(jiān)控項蹋订,告警策略率挣。Zabbix-Server 會根據(jù)策略主動獲取 Agent 的數(shù)據(jù),然后存儲到 MySQL 中露戒。同時根據(jù)用戶配置的策略椒功,判定是否需要告警。用戶可以在 Web 端智什,以圖表的形式动漾,查看各種指標的歷史趨勢。在 Zabbix 中荠锭,將 Server 主動拉取數(shù)據(jù)的方式稱之為 Active Check旱眯。這種方式配置起來較為方便,但是會對 Zabbix-Server 的性能存在影響证九。所以在生產(chǎn)環(huán)境中删豺,一般會選擇主動推送數(shù)據(jù)到 Zabbix-Server 的方式,稱之為 Trapper愧怜。即用戶可以定時生成數(shù)據(jù)呀页,再按照 Zabbix 定義的數(shù)據(jù)格式,批量發(fā)送給 Zabbix-Server拥坛,這樣可以大大提高 Server 的處理能力蓬蝶。Proxy尘分,作為可選項,起到收集 Agent 數(shù)據(jù)并且轉(zhuǎn)發(fā)到 Server 的作用丸氛。當 Server 和 Agent 不在一個網(wǎng)絡內(nèi)音诫,就需要使用 Proxy 做遠程監(jiān)控,特別是遠程網(wǎng)絡有防火墻的時候雪位。同時它也可以分擔 Server 的壓力,降低 Server 處理連接數(shù)的開銷梨撞。
Prometheus(普羅米修斯)
隨著這幾年云環(huán)境的發(fā)展雹洗,Prometheus 被廣泛地認可。它的本質(zhì)是時間序列數(shù)據(jù)庫卧波,而 Zabbix 采用 MySQL 進行數(shù)據(jù)存儲时肿。從上面我們對時間序列數(shù)據(jù)庫的分析來看,Prometheus 能夠很好地支持大量數(shù)據(jù)的寫入港粱。它采用拉的模式(Pull)從應用中拉取數(shù)據(jù)螃成,并通過 Alert 模塊實現(xiàn)監(jiān)控預警。據(jù)說單機可以消費百萬級時間序列查坪。一起來看看 Prometheus 的幾大組件:
Prometheus Server寸宏,用于收集和存儲時間序列數(shù)據(jù),負責監(jiān)控數(shù)據(jù)的獲取偿曙,存儲以及查詢氮凝。
監(jiān)控目標配置,Prometheus Server 可以通過靜態(tài)配置管理監(jiān)控目標望忆,也可以配合 Service Discovery(K8s罩阵,DNS,Consul)實現(xiàn)動態(tài)管理監(jiān)控目標启摄。
監(jiān)控目標存儲稿壁,Prometheus Server 本身就是一個時序數(shù)據(jù)庫,將采集到的監(jiān)控數(shù)據(jù)按照時間序列存儲在本地磁盤中歉备。
監(jiān)控數(shù)據(jù)查詢傅是,Prometheus Server 對外提供了自定義的 PromQL 語言,實現(xiàn)對數(shù)據(jù)的查詢以及分析威创。
-
Client Library落午,客戶端庫。為需要監(jiān)控的服務生成相應的 Metrics 并暴露給 Prometheus Server肚豺。
當 Prometheus Server 來 Pull 時溃斋,直接返回實時狀態(tài)的 Metrics。通常會和 Job 一起合作吸申。
Push Gateway梗劫,主要用于短期的 Jobs享甸。由于這類 Jobs 存在時間較短,可能在 Prometheus 來 Pull 之前就消失了梳侨。為此蛉威,這些 Jobs 可以直接向 Prometheus Server 端推送它們的 Metrics。
-
Exporters走哺,第三方服務接口蚯嫌。將 Metrics(數(shù)據(jù)集合)發(fā)送給 Prometheus。
Exporter 將監(jiān)控數(shù)據(jù)采集的端點丙躏,通過 HTTP 的形式暴露給 Prometheus Server择示,使其通過 Endpoint 端點獲取監(jiān)控數(shù)據(jù)。
Alertmanager晒旅,從 Prometheus Server 端接收到 Alerts 后栅盲,會對數(shù)據(jù)進行處理。例如:去重废恋,分組谈秫,然后根據(jù)規(guī)則,發(fā)出報警鱼鼓。
Web UI拟烫,Prometheus Server 內(nèi)置的 Express Browser UI,通過 PromQL 實現(xiàn)數(shù)據(jù)的查詢以及可視化蚓哩。
Prometheus 架構圖說完了 Prometheus 的組件构灸,再來看看 Prometheus 的架構:
Prometheus Server 定期從 Jobs/Exporters 中拉 Metrics。同時也可以接收來自 Pushgateway 發(fā)過來的 Metrics岸梨。
Prometheus Server 將接受到的數(shù)據(jù)存儲在本地時序數(shù)據(jù)庫喜颁,并運行已定義好的 alert.rules(告警規(guī)則),一旦滿足告警規(guī)則就會向 Alertmanager 推送警報曹阔。
Alertmanager 根據(jù)配置文件半开,對接收到的警報進行處理,例如:發(fā)出郵件告警赃份,或者借助第三方組件進行告警寂拆。
WebUI/Grafana/APIclients,可以借助 PromQL 對監(jiān)控數(shù)據(jù)進行查詢抓韩。
最后將兩個工具進行比較如下:
Zabbix 和 Prometheus 比較圖從上面的比較可以看出:
Zabbix 的成熟度更高纠永,上手更快。高集成度導致靈活性較差谒拴,在監(jiān)控復雜度增加后尝江,定制難度會升高。而且使用的關系型數(shù)據(jù)庫英上,對于大規(guī)模的監(jiān)控數(shù)據(jù)插入和查詢是個問題炭序。
Prometheus 上手難度大啤覆,定制靈活度高,有較多數(shù)據(jù)聚合的可能惭聂,而且有時序數(shù)據(jù)庫的加持窗声。
對于監(jiān)控物理機或者監(jiān)控環(huán)境相對穩(wěn)定的情況,Zabbix 有明顯優(yōu)勢辜纲。如果監(jiān)控場景多是云環(huán)境的話笨觅,推薦使用 Prometheus。
總結(jié)
監(jiān)控系統(tǒng)思維導圖監(jiān)控系統(tǒng)對 IT 系統(tǒng)運維意義重大耕腾,從狀態(tài)監(jiān)控到收集/分析數(shù)據(jù)屋摇,到故障報警,以及問題解決幽邓,最后歸檔報表,協(xié)助運維復盤火脉。監(jiān)控系統(tǒng)分為三大類牵舵,日志類,調(diào)用鏈類倦挂,度量類畸颅,他們有各自的特點,且應用場景各不相同方援。因為要對整個 IT 系統(tǒng)進行監(jiān)控没炒,所以將其分為五層,分別是犯戏,客戶端送火,業(yè)務層,應用層先匪,系統(tǒng)層种吸,網(wǎng)絡層。Zabbix 和 Prometheus 是當下流行的監(jiān)控系統(tǒng)呀非,可以根據(jù)他們的特點選擇使用坚俗。
作者:崔皓
簡介:十六年開發(fā)和架構經(jīng)驗,曾擔任過惠普武漢交付中心技術專家岸裙,需求分析師猖败,項目經(jīng)理,后在創(chuàng)業(yè)公司擔任技術/產(chǎn)品經(jīng)理降允。善于學習恩闻,樂于分享。目前專注于技術架構與研發(fā)管理拟糕。
編輯:陶家龍判呕、孫淑娟