框架組件,究竟要不要自研?究竟要不要建設自研技術體系。
15年加盟58到家後,框架/組件/基礎服務/技術平臺,正好也是本身負責範圍的一部分,故談一談本身的想法。
早期研發人數較少,公司也不肯定能走多遠,業務相對簡單,業務以「快速迭代」爲最高優先級,此時通常會選擇「本身熟悉的技術」做爲選型:
(1)研發語言:熟PHP選PHP,熟Java選Java
(2)數據庫:熟MySQL選MySQL,熟SQL-server選SQL-server
(3)框架組件:熟Ruby on Rails選ROR,熟ThinkPHP選ThinkPHP,熟Spring boot才選
此時千萬不要糾結選型,選本身熟悉的,業務以快速迭代爲最優先,公司得先生存下來。
多說一句,此時對於技術合夥人的技術視野就有必定要求,若是早期方向不對,等公司發展若干年,數據量併發量上漲不少倍,成本以及將來的技術應對恐怕會有麻煩。
58同城早期選型是微軟技術體系,後來數據量增大,併發量增大,機器數據庫愈來愈多,性能扛不住,成本也扛不住(你猜一個SQL-server的licence一年多少錢?),後來CTO帶領你們轉型開源陣營,雖然陣痛了1-2年,但長遠來講,絕對是正確的決策。
現在,若是你再創業,選雲,選LAMP或者Spring,八成不會走太大的彎路。
隨着業務愈來愈複雜,研發人數愈來愈多,若是每一個leader都選擇本身擅長的框架,就會出現這樣的狀況:
(1)站點框架,team A用着
SSH
,team B用着
Spring+SpringMVC+Mybatis;
(2)服務框架,team C用着
REST
,team D用着
dubbo
,team E用着
thrift
;
(3)數據庫訪問,team X用着
mybatis
,team Y用着
DAO
,team Z用着
jdbc
;
對於總體而言,跨部門的調用愈來愈麻煩,重複造的輪子愈來愈多,技術效率會逐步下降,研發+測試+運維成本都愈來愈高。
統一了技術棧之後,若是不封裝,redis官方Java客戶端Jedis可能有這樣一些接口:
String Memcache::get(String key)redis
String Memcache::set(String key, String value)數據庫
String Memcache::del(String key)緩存
String 58DaojiaKV::get(String key) {微信
String result = Memcache::get(key);mybatis
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)對上游屏蔽底層實現的細節,調用方不用關注緩存是memcache仍是redis,調用方只關注58DaojiaKV;
(2)底層變化的時候,對上游透明,當memcache不能知足需求,要切換爲redis時,全部調用方不須要大的變化,升級一個最新的58DaojiaKV便可,58DaojiaKV的接口不變,實現變爲:
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)統一實現一些通用的功能,就不須要每個上游升級了,例如,要實現一個緩存訪問時間統計的功能,全部調用方不須要大的變化,升級一個最新的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;
}
同理,若是要實現統一的告警,調用鏈跟蹤,SQL執行時間,也能夠用相似的方法。
第二個觀點:第三方庫,不但要統一,還能夠淺淺的封裝一層,預留將來的擴展性。
業務進一步發展,研發團隊進一步擴張,雖然使用了統一的技術棧,但不一樣研發團隊的痛點是極其相似的:
(1)有站點,監控服務的可用性,處理時間監控需求;
(1)開源框架/組件過重了,咱們須要的可能只是一個輕量級的框架/組件;
(3)不瞭解開源框架/組件的設計理念,要二次開發成本更高(維護dubboX的同窗,維護數據庫中間件Atlas的同窗能夠出來講兩句);
(4)有些通用的需求是和業務緊密結合的,開源框架/組件可能知足不了;
此時,若是技術實力具有,能夠統一研發一些框架和組件,解決全部技術團隊的通用痛點,知足全部技術團隊的通用需求。
初期建議:不自研,用熟悉的,業務快速迭代爲優先,須要必定技術視野。
(1)你猜一個SQL-server的licence一年多少錢?