前言
说到后台技术栈,脑海中是不是浮现的是这样一幅图?
有点眼晕,以下只是我们会用到的一些语言的合集,而且只是语言层面的一部分,就整个后台技术栈来说,这只是一个开始,从语言开始,还有很多很多的内容。今天要说的后台是大后台的概念,放在服务器上的东西都属于后台的东西,比如使用的框架,语言,数据库,服务,操作系统等等。
整个后台技术栈我的理解包括4个层面的内容:
语言:用了哪些开发语言,如:C++/Java/Go/PHP/Python/Ruby等等;
组件:用了哪些组件,如:MQ组件,数据库组件等等;
流程:怎样的流程和规范,如:开发流程,项目流程,发布流程,监控告警流程,代码规范等等;
系统:系统化建设,上面的流程需要有系统来保证,如:规范发布流程的发布系统,代码管理系统等等;
结合以上的的4个层面的内容,整个后台技术栈的结构如图2所示:
图2后台技术栈结构
以上的这些内容都需要我们从零开始搭建,在创业公司,没有大公司那些完善的基础设施,需要我们从开源界,从云服务商甚至有些需要自己去组合,去拼装,去开发一个适合自己的组件或系统以达成我们的目标。咱们一个个系统和组件的做选型,最终形成我们的后台技术栈。
各系统组件选型
1、项目管理/Bug管理/问题管理
项目管理软件是整个业务的需求,问题,流程等等的集中地,大家的跨部门沟通协同大多依赖于项目管理工具。有一些SaaS的项目管理服务可以使用,但是很多时间不满足需求,此时我们可以选择一些开源的项目,这些项目本身有一定的定制能力,有丰富的插件可以使用,一般的创业公司需求基本上都能得到满足,常用的项目如下:
Redmine:用Ruby开发的,有较多的插件可以使用,能自定义字段,集成了项目管理,Bug问题跟踪,WIKI等功能,不过好多插件N年没有更新了;
Phabricator:用PHP开发的,Facebook之前的内部工具,开发这工具的哥们离职后自己搞了一个公司专门做这个软件,集成了代码托管,CodeReview,任务管理,文档管理,问题跟踪等功能,强烈推荐较敏捷的团队使用;
Jira:用Java开发的,有用户故事,task拆分,燃尽图等等,可以做项目管理,也可以应用于跨部门沟通场景,较强大;
悟空CRM:这个不是项目管理,这个是客户管理,之所以在这里提出来,是因为在ToB的创业公司里面,往往是以客户为核心来做事情的,可以将项目管理和问题跟进的在悟空CRM上面来做,他的开源版本已经基本实现了CR的核心功能,还带有一个任务管理功能,用于问题跟进,不过用这个的话,还是需要另一个项目管理的软件协助,顺便说一嘴,这个系统的代码写得很难维护,只能适用于客户规模小(1万以内)时。
2、DNS
DNS是一个很通用的服务,创业公司基本上选择一个合适的云厂商就行了,国内主要是两家:
阿里万网:阿里年收购了万网,整合了其域名服务,最终形成了现在的阿里万网,其中就包含DNS这块的服务;
腾讯DNSPod:腾讯年以万收购DNSPod%股份,主要提供域名解析和一些防护功能;
如果你的业务是在国内,主要就是这两家,选一个就好,像今日头条这样的企业用的也是DNSPod的服务,除非一些特殊的原因才需要自建,比如一些CDN厂商,或者对区域有特殊限制的。要实惠一点用阿里最便宜的基础版就好了,要成功率高一些,还是用DNSPod的贵的那种。
在国外还是选择亚马逊吧,阿里的DNS服务只有在日本和美国有节点,东南亚最近才开始部点,DNSPod也只有美国和日本,像一些出海的企业,其选择的云服务基本都是亚马逊。
如果是线上产品,DNS强烈建议用付费版,阿里的那几十块钱的付费版基本可以满足需求。如果还需要一些按省份或按区域调试的逻辑,则需要加钱,一年也就几百块,省钱省力。
如果是国外,优先选择亚马逊,如果需要国内外互通并且有自己的APP的话,建议还是自己实现一些容灾逻辑或者智能调度,因为没有一个现成的DNS服务能同时较好的满足国内外场景,或者用多个域名,不同的域名走不同的DNS。
3、LB(负载均衡)
LB(负载均衡)是一个通用服务,一般云厂商的LB服务基本都会如下功能:
支持四层协议请求(包括TCP、UDP协议);
支持七层协议请求(包括HTTP、HTTPS协议);
集中化的证书管理系统支持HTTPS协议;
健康检查;
如果你线上的服务机器都是用的云服务,并且是在同一个云服务商的话,可以直接使用云服务商提供的LB服务,如阿里云的SLB,腾讯云的CLB,亚马逊的ELB等等。如果是自建机房基本都是LVS+Nginx。
4、CDN
CDN现在已经是一个很红很红的市场,基本上只能挣一些辛苦钱,都是贴着成本在卖。国内以网宿为龙头,他们家占据整个国内市场份额的40%以上,后面就是腾讯,阿里。网宿有很大一部分是因为直播的兴起而崛起。
国外,Amazon和Akamai合起来占比大概在50%,曾经的国际市场老大Akamai拥有全球超一半的份额,在AmazonCDN入局后,份额跌去了将近20%,众多中小企业都转向后者,Akamai也是无能为力。
国内出海的CDN厂商,更多的是为国内的出海企业服务,三家大一点的CDN服务商里面也就网宿的节点多一些,但是也多不了多少。阿里和腾讯还处于前期阶段,仅少部分国家有节点。
就创业公司来说,CDN用腾讯云或阿里云即可,其相关系统较完善,能轻松接入,网宿在系统支持层面相对较弱一些,而且还贵一些。并且,当流量上来后,CDN不能只用一家,需要用多家,不同的CDN在全国的节点覆盖不一样,而且针对不同的客户云厂商内部有些区分客户集群,并不是全节点覆盖(但有些云厂商说自己是全网节点),除了节点覆盖的问题,多CDN也在一定程度上起到容灾的作用。
5、RPC框架
维基百科对RPC的定义是:远程过程调用(RemoteProcedureCall,RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。
通俗来讲,一个完整的RPC调用过程,就是Server端实现了一个函数,客户端使用RPC框架提供的接口,调用这个函数的实现,并获取返回值的过程。
业界RPC框架大致分为两大流派,一种侧重跨语言调用,另一种是偏重服务治理。
跨语言调用型的RPC框架有Thrift、gRPC、Hessian、Hprose等。这类RPC框架侧重于服务的跨语言调用,能够支持大部分的语言进行语言无关的调用,非常适合多语言调用场景。但这类框架没有服务发现相关机制,实际使用时需要代理层进行请求转发和负载均衡策略控制。
其中,gRPC是Google开发的高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(ProtocolBuffers)序列化协议开发,且支持众多开发语言。本身它不是分布式的,所以要实现框架的功能需要进一步的开发。
Hprose(HighPerformanceRemoteObjectServiceEngine)是一个MIT开源许可的新型轻量级跨语言跨平台的面向对象的高性能远程动态通讯中间件。
服务治理型的RPC框架的特点是功能丰富,提供高性能的远程调用、服务发现及服务治理能力,适用于大型服务的服务解耦及服务治理,对于特定语言(Java)的项目可以实现透明化接入。缺点是语言耦合度较高,跨语言支持难度较大。国内常见的冶理型RPC框架如下:
Dubbo:Dubbo是阿里巴巴公司开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring框架无缝集成。当年在淘宝内部,Dubbo由于跟淘宝另一个类似的框架HSF有竞争关系,导致Dubbo团队解散,最近又活过来了,有专职同学投入。
DubboX:DubboX是由当当在基于Dubbo框架扩展的一个RPC框架,支持REST风格的远程调用、Kryo/FST序列化,增加了一些新的feature。Motan:Motan是新浪微博开源的一个Java框架。它诞生的比较晚,起于年,年5月开源。Motan在微博平台中已经广泛应用,每天为数百个服务完成近千亿次的调用。
rpcx:rpcx是一个类似阿里巴巴Dubbo和微博Motan的分布式的RPC服务框架,基于Golangnet/rpc实现。但是rpcx基本只有一个人在维护,没有完善的社区,使用前要慎重,之前做Golang的RPC选型时也有考虑这个,最终还是放弃了,选择了gRPC,如果想自己自研一个RPC框架,可以参考学习一下。
6、名字发现/服务发现
名字发现和服务发现分为两种模式,一个是客户端发现模式,一种是服务端发现模式。
框架中常用的服务发现是客户端发现模式。
所谓服务端发现模式是指客户端通过一个负载均衡器向服务发送请求,负载均衡器查询服务注册表并把请求路由到一台可用的服务实例上。现在常用的负载均衡器都是此类模式,常用于微服务中。
所有的名字发现和服务发现都要依赖于一个可用性非常高的服务注册表,业界常用的服务注册表有如下三个:
etcd,一个高可用、分布式、一致性、key-value方式的存储,被用在分享配置和服务发现中。两个著名的项目使用了它:Kubernetes和CloudFoundry。
Consul,一个发现和配置服务的工具,为客户端注册和发现服务提供了API,Consul还可以通过执行健康检查决定服务的可用性。
ApacheZooKeeper,是一个广泛使用、高性能的针对分布式应用的协调服务。ApacheZooKeeper本来是Hadoop的子工程,现在已经是顶级工程了。
除此之外也可以自己实现服务实现,或者用Redis也行,只是需要自己实现高可用性。
7、关系数据库
关系数据库分为两种,一种是传统关系数据,如Oracle,MySQL,Maria,DB2,PostgreSQL等等,另一种是NewSQL,即至少要满足以下五点的新型关系数据库:
完整地支持SQL,支持JOIN/GROUPBY/子查询等复杂SQL查询。
支持传统数据标配的ACID事务,支持强隔离级别。
具有弹性伸缩的能力,扩容缩容对于业务层完全透明。
真正的高可用,异地多活、故障恢复的过程不需要人为的接入,系统能够自动地容灾和进行强一致的数据恢复。
具备一定的大数据分析能力。
传统关系数据库用得最多的是MySQL,成熟,稳定,一些基本的需求都能满足,在一定数据量级之前基本单机传统数据库都可以搞定,而且现在较多的开源系统都是基于MySQL,开箱即用,再加上主从同步和前端缓存,百万pv的应用都可以搞定了。不过CentOS7已经放弃了MySQL,而改使用MariaDB。MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可。开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将MySQL闭源的潜在风险,因此社区采用分支的方式来避开这个风险。
在Google发布了F1:ADistributedSQLDatabaseThatScales和Spanner:Google’sGlobally-DistributedDatabasa之后,业界开始流行起NewSQL。于是有了CockroachDB,于是有了奇叔公司的TiDB。国内已经有比较多的公司使用TiDB,之前在创业公司时在大数据分析时已经开始应用TiDB,当时应用的主要原因是MySQL要使用分库分表,逻辑开发比较复杂,扩展性不够。
8、NoSQL
NoSQL顾名思义就是Not-OnlySQL,也有人说是No–SQL,个人偏向于Not-OnlySQL,它并不是用来替代关系库,而是作为关系型数据库的补充而存在。
常见NoSQL有4个类型:
键值,适用于内容缓存,适合混合工作负载并发高扩展要求大的数据集,其优点是简单,查询速度快,缺点是缺少结构化数据,常见的有Redis,Memcache,BerkeleyDB和Voldemort等等;
列式,以列簇式存储,将同一列数据存在一起,常见于分布式的文件系统,其中以Hbase,Cassandra为代表。Cassandra多用于写多读少的场景,国内用得比较多的有,大概台机器的集群,国外大规模使用的公司比较多,如eBay,Instagram,Apple和沃尔玛等等;
文档,数据存储方案非常适用承载大量不相关且结构差别很大的复杂信息。性能介于kv和关系数据库之间,它的灵感来于lotusnotes,常见的有MongoDB,CouchDB等等;
图形,图形数据库擅长处理任何涉及关系的状况。社交网络,推荐系统等。专注于构建关系图谱,需要对整个图做计算才能得出结果,不容易做分布式的集群方案,常见的有Neo4J,InfoGrid等。
除了以上4种类型,还有一些特种的数据库,如对象数据库,XML数据库,这些都有针对性对某些存储类型做了优化的数据库。
在实际应用场景中,何时使用关系数据库,何时使用NoSQL,使用哪种类型的数据库,这是我们在做架构选型时一个非常重要的考量,甚至会影响整个架构的方案。
9、消息中间件
消息中间件在后台系统中是必不可少的一个组件,一般我们会在以下场景中使用消息中间件:
异步处理:异步处理是使用消息中间件的一个主要原因,在工作中最常见的异步场景有用户注册成功后需要发送注册成功邮件、缓存过期时先返回老的数据,然后异步更新缓存、异步写日志等等;通过异步处理,可以减少主流程的等待响应时间,让非主流程或者非重要业务通过消息中间件做集中的异步处理。
系统解耦:比如在电商系统中,当用户成功支付完成订单后,需要将支付结果给通知ERP系统、发票系统、WMS、推荐系统、搜索系统、风控系统等进行业务处理;这些业务处理不需要实时处理、不需要强一致,只需要最终一致性即可,因此可以通过消息中间件进行系统解耦。通过这种系统解耦还可以应对未来不明确的系统需求。
削峰填谷:当系统遇到大流量时,监控图上会看到一个一个的山峰样的流量图,通过使用消息中间件将大流量的请求放入队列,通过消费者程序将队列中的处理请求慢慢消化,达到消峰填谷的效果。最典型的场景是秒杀系统,在电商的秒杀系统中下单服务往往会是系统的瓶颈,因为下单需要对库存等做数据库操作,需要保证强一致性,此时使用消息中间件进行下单排队和流控,让下单服务慢慢把队列中的单处理完,保护下单服务,以达到削峰填谷的作用。
业界消息中间件是一个非常通用的东西,大家在做选型时有使用开源的,也有自己造轮子的,甚至有直接用MySQL或Redis做队列的,关键看是否满足你的需求,如果是使用开源的项目,以下的表格在选型时可以参考:
图3
以上图的纬度为:名字、成熟度、所属社区/公司、文档、授权方式、开发语言、支持的协议、客户端支持的语言、性能、持久化、事务、集群、负载均衡、管理界面、部署方式、评价。
10、代码管理
代码是互联网创业公司的命脉之一,代码管理很重要,常见的考量点包括两块:
安全和权限管理,将代码放到内网并且对于关系公司命脉的核心代码做严格的代码控制和机器的物理隔离;
代码管理工具,Git作为代码管理的不二之选,你值得拥有。GitLab是当今最火的开源Git托管服务端,没有之一,虽然有企业版,但是其社区版基本能满足我们大部分需求,结合Gerrit做Codereview,基本就完美了。当然GitLab也有代码对比,但没Gerrit直观。Gerrit比GitLab提供了更好的代码检查界面与主线管理体验,更适合在对代码质量有高要求的文化下使用。
11、持续集成
持续集成简,称CI(continuousintegration),是一种软件开发实践,即团队开发成员经常集成他们的工作,每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。持续集成为研发流程提供了代码分支管理/比对、编译、检查、发布物输出等基础工作,为测试的覆盖率版本编译、生成等提供统一支持。
业界免费的持续集成工具中系统我们有如下一些选择:
Jenkins:Java写的有强大的插件机制,MIT协议开源(免费,定制化程度高,它可以在多台机器上进行分布式地构建和负载测试)。Jenkins可以算是无所不能,基本没有Jenkins做不了的,无论从小型团队到大型团队Jenkins都可以搞定。不过如果要大规模使用,还是需要有人力来学习和维护。
TeamCity:TeamCity与Jenkins相比使用更加友好,也是一个高度可定制化的平台。但是用的人多了,TeamCity就要收费了。
Strider:Strider是一个开源的持续集成和部署平台,使用Node.js实现,存储使用的是MongoDB,BSD许可证,概念上类似Travis和Jenkins。
GitLabCI:从GitLab8.0开始,GitLabCI就已经集成在GitLab,我们只要在项目中添加一个.gitlab-ci.yml文件,然后添加一个Runner,即可进行持续集成。并且GitLab与Docker有着非常好的相互协作的能力。免费版与付费版本不同可以参见这里: