框架組件,究竟要不要自研?究竟要不要建設(shè)自研技術(shù)體系。15年加盟58到家后,框架/組件/基礎(chǔ)服務(wù)/技術(shù)平臺(tái),正好也是自己負(fù)責(zé)范圍的一部分,故談一談自己的想法。早期研發(fā)人數(shù)較少,公司也不確定能走多遠(yuǎn),業(yè)務(wù)相對(duì)簡(jiǎn)單,業(yè)務(wù)以“快速迭代”為最高優(yōu)先級(jí),此時(shí)一般會(huì)選擇“自己熟悉的技術(shù)”作為選型:(1)研發(fā)語(yǔ)言:熟PHP選PHP,熟Java選Java(2)數(shù)據(jù)庫(kù):熟MySQL選MySQL,熟SQL-server選SQL-server(3)框架組件:熟Ruby on Rails選ROR,熟ThinkPHP選ThinkPHP,熟Spring boot才選此時(shí)千萬(wàn)不要糾結(jié)選型,選自己熟悉的,業(yè)務(wù)以快速迭代為最優(yōu)先,公司得先生存下來(lái)。多說(shuō)一句,此時(shí)對(duì)于技術(shù)合伙人的技術(shù)視野就有一定要求,如果早期方向不對(duì),等公司發(fā)展若干年,數(shù)據(jù)量并發(fā)量上漲很多倍,成本以及未來(lái)的技術(shù)應(yīng)對(duì)恐怕會(huì)有麻煩。58同城早期選型是微軟技術(shù)體系,后來(lái)數(shù)據(jù)量增大,并發(fā)量增大,機(jī)器數(shù)據(jù)庫(kù)越來(lái)越多,性能扛不住,成本也扛不住(你猜一個(gè)SQL-server的licence一年多少錢(qián)?),后來(lái)CTO帶領(lǐng)大家轉(zhuǎn)型開(kāi)源陣營(yíng),雖然陣痛了1-2年,但長(zhǎng)遠(yuǎn)來(lái)說(shuō),絕對(duì)是正確的決策。如今,如果你再創(chuàng)業(yè),選云,選LAMP或者Spring,八成不會(huì)走太大的彎路。隨著規(guī)模的擴(kuò)大,為什么要控制技術(shù)棧?隨著業(yè)務(wù)越來(lái)越復(fù)雜,研發(fā)人數(shù)越來(lái)越多,如果每個(gè)leader都選擇自己擅長(zhǎng)的框架,就會(huì)出現(xiàn)這樣的情況:(1)站點(diǎn)框架,team A用著SSH,team B用著Spring+SpringMVC+Mybatis;(2)服務(wù)框架,team C用著REST,team D用著dubbo,team E用著thrift;(3)數(shù)據(jù)庫(kù)訪問(wèn),team X用著mybatis,team Y用著DAO,team Z用著jdbc;對(duì)于整體而言,跨部門(mén)的調(diào)用越來(lái)越麻煩,重復(fù)造的輪子越來(lái)越多,技術(shù)效率會(huì)逐步降低,研發(fā)+測(cè)試+運(yùn)維成本都越來(lái)越高。第一個(gè)觀點(diǎn):即使不自研,技術(shù)棧也請(qǐng)盡量統(tǒng)一。統(tǒng)一了技術(shù)棧,為什么建議淺淺的封裝一層?統(tǒng)一了技術(shù)棧以后,如果不封裝,redis官方Java客戶(hù)端Jedis可能有這樣一些接口:String Memcache::get(String key)
String Memcache::set(String key, String value)
String Memcache::del(String key)
String 58DaojiaKV::get(String key) {
???????? String result = Memcache::get(key);
???????? return result;
}
String 58DaojiaKV::set(String key, String value) {
???????? String result = Memcache::set(key, value);
???????? return result;
}
String 58DaojiaKV::del(String key) {
???????? String result = Memcache::del(key);
???????? return result;
}
(1)對(duì)上游屏蔽底層實(shí)現(xiàn)的細(xì)節(jié),調(diào)用方不用關(guān)注緩存是memcache還是redis,調(diào)用方只關(guān)注58DaojiaKV;(2)底層變化的時(shí)候,對(duì)上游透明,當(dāng)memcache不能滿(mǎn)足需求,要切換為redis時(shí),所有調(diào)用方不需要大的變化,升級(jí)一個(gè)最新的58DaojiaKV即可,58DaojiaKV的接口不變,實(shí)現(xiàn)變?yōu)?/span>:String 58DaojiaKV::get(String key) {
???????? String result = Jedis::get(key);
???????? return result;
}
String 58DaojiaKV::set(String key, String value) {
???????? String result = Jedis::set(key, value);
???????? return result;
}
String 58DaojiaKV::del(String key) {
???????? String result = Jedis::del(key);
???????? return result;
}
(3)統(tǒng)一實(shí)現(xiàn)一些通用的功能,就不需要每一個(gè)上游升級(jí)了,例如,要實(shí)現(xiàn)一個(gè)緩存訪問(wèn)時(shí)間統(tǒng)計(jì)的功能,所有調(diào)用方不需要大的變化,升級(jí)一個(gè)最新的58DaojiaKV即可:String 58DaojiaKV::get(String key) {
???????? Long startTime = now();
???????? String result = Jedis::get(key);
???????? Long endTime = now();
???????? reportKVTime(startTime- endTime);
???????? return result;
}
String 58DaojiaKV::set(String key, String value) {
???????? Long startTime = now();
???????? String result = Jedis::set(key, value);
???????? Long endTime = now();
???????? reportKVTime(startTime- endTime);
???????? return result;
}
String 58DaojiaKV::del(String key) {
???????? Long startTime = now();
???????? String result = Jedis::del(key);
???????? Long endTime = now();
???????? reportKVTime(startTime- endTime);
???????? return result;
}
同理,如果要實(shí)現(xiàn)統(tǒng)一的告警,調(diào)用鏈跟蹤,SQL執(zhí)行時(shí)間,也可以用類(lèi)似的方法。第二個(gè)觀點(diǎn):第三方庫(kù),不但要統(tǒng)一,還可以淺淺的封裝一層,預(yù)留未來(lái)的擴(kuò)展性。隨著規(guī)模的進(jìn)一步擴(kuò)大,為什么需要適當(dāng)?shù)脑煲恍┹喿樱?/strong>業(yè)務(wù)進(jìn)一步發(fā)展,研發(fā)團(tuán)隊(duì)進(jìn)一步擴(kuò)張,雖然使用了統(tǒng)一的技術(shù)棧,但不同研發(fā)團(tuán)隊(duì)的痛點(diǎn)是極其類(lèi)似的:(1)有站點(diǎn),監(jiān)控服務(wù)的可用性,處理時(shí)間監(jiān)控需求;(3)有自動(dòng)化發(fā)布,自動(dòng)化運(yùn)維需求;(4)有服務(wù)治理,服務(wù)自動(dòng)發(fā)現(xiàn)需求;(7)有系統(tǒng)層面數(shù)據(jù)收集與可視化展現(xiàn)的需求;此時(shí),開(kāi)源的框架可能滿(mǎn)足不了需求了:(1)開(kāi)源框架/組件太重了,我們需要的可能只是一個(gè)輕量級(jí)的框架/組件;(2)開(kāi)源框架/組件,只能滿(mǎn)足我們的一部分需求;(3)不了解開(kāi)源框架/組件的設(shè)計(jì)理念,要二次開(kāi)發(fā)成本更高(維護(hù)dubboX的同學(xué),維護(hù)數(shù)據(jù)庫(kù)中間件Atlas的同學(xué)可以出來(lái)說(shuō)兩句);(4)有些通用的需求是和業(yè)務(wù)緊密結(jié)合的,開(kāi)源框架/組件可能滿(mǎn)足不了;此時(shí),如果技術(shù)實(shí)力具備,可以統(tǒng)一研發(fā)一些框架和組件,解決所有技術(shù)團(tuán)隊(duì)的通用痛點(diǎn),滿(mǎn)足所有技術(shù)團(tuán)隊(duì)的通用需求。第三個(gè)觀點(diǎn):適當(dāng)造一些輪子。初期建議:不自研,用熟悉的,業(yè)務(wù)快速迭代為優(yōu)先,需要一定技術(shù)視野。(1)你猜一個(gè)SQL-server的licence一年多少錢(qián)?(2)你對(duì)技術(shù)老大的選型滿(mǎn)意么?