当前位置: 首页 > 科技观察

框架组件要不要自研?

时间:2023-03-22 00:49:12 科技观察

很多朋友问我:需要自己开发框架组件吗?是否需要自建技术体系?2015年加入58到家后,框架/组件/基础服务/技术平台恰好属于我的职责范围,所以想谈谈我的想法。为什么前期不推荐自研?前期研发人员少,公司不确定能走多远。业务相对简单,业务以“快速迭代”为最高优先级。类型:研发语言:熟悉PHP就选PHP,熟悉Java就选Java数据库:熟悉MySQL就选MySQL,熟悉SQL-server就选SQL-server框架组件:ROR熟悉RubyonRails就选ThinkPHP熟悉ThinkPHP就选ThinkPHP熟悉ThinkPHP就选Springboot...这个时候不要纠结选机型,选择适合自己的业务熟悉、快速迭代是重中之重,公司首先要生存下来。还有一点,这个时候对技术伙伴的技术眼光有一定的要求。如果前期方向错了,公司发展几年后,并发数据量会增加很多倍,成本和未来的技术响应可能会很麻烦。58同城前期选择了微软技术体系。后来数据量越来越大,并发量越来越大,机器数据库也越来越多。性能和成本都撑不住(猜猜一个SQL-serverlicense一年多少钱)钱?),后来CTO带领大家转战开源阵营。虽然痛苦了1-2年,但从长远来看绝对是正确的决定。现在,如果你重新创业,选择cloud、LAMP或者Spring,估计就不会走太多弯路了。随着规模的扩大,为什么还要把控技术栈?随着业务越来越复杂,研发人员越来越多,如果每个领导都选择一个自己擅长的框架,就会出现这样的情况:站点框架,A组使用SSH,B组使用Spring+SpringMVC+Mybatis;服务框架,C队使用REST,D队使用dubbo,E队使用thrift;数据库访问,X队使用mybatis,Y队使用DAO,Z队使用jdbc;...总体而言,跨部门调用越来越麻烦,重复的轮子越来越多,技术效率会逐渐降低,研发+测试+运维成本越来越高。第一种观点:即使不自己开发,也请尽量统一技术栈。统一了技术栈之后,为什么建议再封装一层?统一技术栈后,如果不封装,redis官方Java客户端Jedis可能会有这样的接口:StringMemcache::get(Stringkey)StringMemcache::set(Stringkey,Stringvalue)StringMemcache::del(Stringkey)浅封装会变成这样:String58DaojiaKV::get(Stringkey){Stringresult=Memcache::get(key);returnresult;}String58DaojiaKV::set(Stringkey,Stringvalue){Stringresult=Memcache::set(key,value);returnresult;}String58DaojiaKV::del(Stringkey){Stringresult=Memcache::del(key);returnresult;}这样做有什么好处?(1)屏蔽upstream底层实现细节,调用者无需关注缓存是memcache还是redis,调用者只关注58DaojiaKV;(2)当底层发生变化时,对上游是透明的。当memcache不能满足要求,需要切换到redis时,所有调用者不需要做大的改动,升级到最新的58DaojiaKV即可,58DaojiaKV的接口不变,实现变为:String58DaojiaKV::get(Stringkey){Stringresult=Jedis::get(key);returnresult;}String58DaojiaKV::set(Stringkey,Stringvalue){Stringresult=Jedis::set(key,value);returnresult;}String58DaojiaKV::del(Stringkey){Stringresult=Jedis::del(key);returnresult;}(3)一些通用功能的统一实现,只是不需要每个upstream都升级。比如实现一个缓存访问时间统计功能,所有调用者不需要大改动,升级到最新的58DaojiaKV即可:String58DaojiaKV::get(Stringkey){LongstartTime=now();Stringresult=Jedis::get(key);LongendTime=now();reportKVTime(startTime-endTime);returnresult;}String58DaojiaKV::set(Stringkey,Stringvalue){LongstartTime=now();Stringresult=Jedis::set(key,value);LongendTime=now();reportKVTime(startTime-endTime);returnresult;}String58DaojiaKV::del(Stringkey){LongstartTime=now();Stringresult=Jedis::del(key);LongendTime=now();reportKVTime(startTime-endTime);returnresult;}同样,如果要实现统一告警、调用链跟踪、SQL执行时间,也可以使用类似的方法。第二种观点:第三方库,不仅要统一,还可以浅封装一层,预留以后的扩展性。随着规模的进一步扩大,为什么还要适当造一些轮子呢?业务进一步发展,研发团队进一步壮大。虽然采用了统一的技术栈,但不同研发团队的痛点非常相似:有站点,监控服务可用性,处理时间监控需求;报警要求;自动发布、自动运维需求;服务治理、服务自动发现需求;调用链跟踪要求;SQL监控需求;系统级数据收集和可视化要求;……此时,开源框架可能无法满足需求:开源框架/组件太重,我们需要的可能只是一个轻量级的框架/组件;开源框架/组件只能满足我们的部分需求;不明白开源框架/组件的设计理念,需要更高的二次开发成本(维护dubboX和数据库中间件Atlas的同学可以出来说几句);一些通用需求与业务紧密结合,开源的框架/组件可能还不够;……这时候,如果技术实力足够,可以统一开发一些框架和组件,解决所有技术团队的共同痛点,满足所有技术团队的共同需求。第三个观点:适当造一些轮子。总结框架组件,需要自研吗?初步建议:不要自研,用熟悉的,业务快速迭代优先,需要一定的技术眼光。长期建议:统一技术栈;浅封装一层;适当地造轮子;【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文