引子
云服务的热度越来越高,IaaS、PaaS、SaaS开始逐渐为大家所知,论坛时期的那些草根站长也开始不自己购买服务器转而使用云主机了,大环境在慢慢变好,特别是对创业人员来说。
不过所谓的云服务三个层次发展并不均衡,IaaS是真正做起来了,特别是aws,早就是一个很重要的收入源了,国内来讲,比较有名的就是阿里云、 UCloud、青云了,应该也开始盈利了,可喜可贺。但是PaaS并没有做起来,GAE、SAE、BAE、JAE应该没有一个称得上成功。至于SaaS,在笔者的认知里,无非就是提供给大众用的一个网站,有账号体系,不同账号有自己的数据,不做评价。
本文主要是想聊一下在当前大环境下,我们应该如何做开发,行业应该如何发展。哇,话题好大,口气不小,每个人都有自己的理解,仁者见仁智者见智,笔者也只是碎碎念,可能观点一无是处,错得离谱,读者一笑置之,不要扔砖头,砸到花花草草也是不好~
IaaS服务概述
首先,我们回顾一下现在IaaS厂商提供了什么
*云主机
这是必须的,否则就不是IaaS厂商了,至于用的Xen还是KVM,那咱们不关心,总之对用户来讲,拿到手的是一个指定CPU核数、指定内存大小、指定磁盘大小和类型、指定网络带宽的机器。
如此一来,开发者无需去花费几千甚至几万块购买物理服务器了,初期买个配置低的云主机还是比较省钱,而且不用关心操作系统、yum源、机架、网络、交换机、网线、机房租赁费用等等问题,着实省心不少。
*周边服务
一个服务要想跑起来,光有服务器和操作系统是不够的,我们通常还要依赖一些周边服务,比如数据库、Cache、Redis、MQ、存储、LB等等,如果只有云主机,那我们需要自己在云主机上搭建并维护这些服务。对于一些资深栈溢出工程师那肯定是没问题的,但是大部分人都是各有所长,一个好的开发并不一定是个好的DBA。
这些IaaS厂商也意识到这个问题,他们会把这些周边服务统一管理、运维,然后卖给开发者,其实这是个好事,IaaS厂商雇用专业的人士来打磨这些服务,通常都要比我们在云主机上手工搭建的要稳定、高效、安全、可用。而IaaS厂商统一处理这些周边服务之后很容易形成规模效应,成本可以做得更低,稳定性也更好,双赢。
通常的IaaS厂商就是提供这些服务了,当然,像AWS走在行业前面的巨头,会提供更多其他的服务,我们姑且不谈。
IaaS下的开发
上节咱们简单介绍了IaaS提供的服务、产品,那么在这样的环境下,开发人员是怎么利用IaaS快速实现他们的产品原型的呢?
通常一个典型的产品可能包含三个与用户交互的部分:web端、iOS手机端、Android手机端。而后端通常是有一个nginx前端,有业务逻辑部分,比如tomcat中跑的Java code、php-fpm驱动的php code、gunicorn驱动的Python code,会用到数据库来做持久化,用到Cache来提高查询速度,如果后端有些比较重量级的计算任务可能还会有个rpc服务。
哪部分需要自己搞,哪部分需要IaaS厂商来搞?
- 业务逻辑相关的代码肯定是dev来开发的
- nginx前面通常需要有个四层的负载均衡,也就是大家熟知的ELB了,这个是IaaS厂商提供
- nginx、php语言环境、php-fpm(以PHP程序举例)肯定是sre来搭建并运维了,当然,如果这个小公司只有一个技术人员,说不得就要通吃dev、qa、sre、fe、ui、ue的所有工作了
- 数据库、Cache应该由IaaS厂商提供,他们负责维护、备份、扩容,只要提供给用户一个连接地址即可
嗯,看起来IaaS厂商还是帮了我们一些忙的,一些系统、网络、DBA运维相关的事情用户是不用操心的。
接下来这个创业公司的唯一的技术人员开始着手码代码了。虽然IaaS厂商已经帮忙解决一部分问题了,接下来这个哥们还会遇到哪些问题呢?脑洞打开……
#p#
IaaS之后,缺失的云服务
说缺失可能并不准确,因为有些服务已经有些公司在做了,只是目前并没有与IaaS很好的结合起来
Code托管
代码放在哪里?这是个问题。使用Github?不太好,因为这是个创业项目,原因如下:
- Github是个用代码交流的开发者社区,开源代码很适合放在上面,但这不代表私有项目也适合放在上面,而且Github私有repo是收费的,虽然不贵,创业嘛,能省则省,特别是有替代服务的情况下
- Github在国外,网络状况不是很好,经常要连vpn才能使用,麻烦
- Github不方便与内部其他平台(比如编译平台)整合,其实这个归根结底还是网络惹的祸,万恶的那个啥啊
所以,国内出了个gitcafe、出了个git.oschina.net、出了个coding.net,稍大一些的公司直接就自己搭建svn服务器或者gitlab服务器
这是一块蛋糕,亲爱的读者,如果你是做IaaS的,可以尝试与这些代码托管服务商合作一下,毕竟,代码是一切的开始。
Build平台
编译平台、产品库,这些名词对于devops来说再熟悉不过了。这一节我们就来聊聊这部分话题:
代码已经托管起来了,那下一步是什么呢?编译打包!没错,如果你使用的解释型语言,比如PHP、Ruby体会可能不深,但如果是编译型的,比如Java、Go、C++,估计就深有感触了。code写好了,要去测试、上线,首先要做的是编译并打包。
最终的期望是:打成的包自包含Runtime,部署到线上任何一台机器上都能跑起来,当然了,前提是这些机器都是相同的操作系统,相同的字长。为啥说要自包含呢?因为线上机器环境千差万别,操作系统版本可能不同、Python版本可能不同、可能连wget命令都没有,千万不能依赖线上环境。
做这个平台的关键是指定合理的规范
最终的发布包要是什么格式,包内的文件是怎么个组织方式,meta信息应该放在哪里,启动脚本应该放在哪里,打好的发布包放在哪里,应该是一个整包还是散文件,平台去哪里拉取用户的打包产物……发布包最终是拿来部署的,故而规范的制定要考虑与部署系统的结合。
Runtime要提前准备好以提高编配速度
我们刚才说最终的期望是打好的包要做到自包含Runtime,所以Java的项目需要包含JDK、Tomcat(或者Resin、Jetty之类的),Python的项目要包含Python的语言环境,还要准备好Nginx之类的,这些常用软件不能在编译的时候去外网下载,应该提前放到内网或者编译机上。
Docker Image & Docker Registry
Docker最近比较火,我们可以把 Docker Image看做是一种发布包,Docker Registry看做是一种产品库。因为Docker Image就是一个自包含的可以在任何部署了Docker的机器上跑起来。而Dockerfile可以看作是一种打包规范,类似Heroku和 CloudFoundry中的buildpack
这一块IaaS厂商并没有提供,笔者觉得这也是一个可以做的方向,不知道有没有创业公司已经看到商机在这块发力了。
Deploy工具
我们说Code已经托管好了,又有编译平台负责打好包了,接下来就是部署了。作为CI的最后一公里,Deploy工具起到了很重要的作用,往QA环境部署、往沙盒环境部署、往小流量环境部署、线上全量部署都要用到。
说到底,部署就是一个按照某种并发策略去一批机器上批量执行部署脚本的过程
嗯,笔者自认为这句话总结得还算精辟,哈哈,只是不知道有多少人会赞同~
对于单个项目只有几十台机器而言,有针对性得写一个部署脚本,批量ssh到对应机器上跑一下完成部署是没有问题的。但是这不够规范,个人搞个人的,也难以形成业内标准,推进软件开发的步伐,对于几百台机器的大项目,ssh就很难完成了,批量建立信任关系也是一个比较麻烦的事情。
这个时候一个强悍的Deploy工具就派上用场了,这个工具要:
- 具备批量去各个机器执行脚本的能力,而且要保证每个脚本不能多执行了,不能少执行了,每个机器上可能要部署一个agent来支持
- 并发策略要可调控,比如一个一个来做?还是每次做2个?5个?因为不同的服务可承受的同时重启的实例数目不一样,所以这个并发策略要可配置
- 有既定规范流程,这个流程是指在单机执行的一些步骤,先干什么,再干什么,最后干什么等等,我们要去分析抽象出一个通用流程,能够满足大部分项目部署需求
- 单机部署流程可定制,虽然我们已经抽象了一个比较好的通用流程,但是总有一些特例是没法用默认方式满足的,故而这个流程要可定制,插入用户自己的特殊逻辑
最后达到的效果就是:用户要发起部署,只要简单的指定一些meta信息即可完成。meta信息可能包括:发布包地址、机器列表、进程启动账号、部署目录等等
aws有提供一个叫Deploy的服务,不知道是否就是干这个事情的。
Config Center
我们在做Build平台和Deploy工具的时候,必然要处理配置问题,因为不同的项目配置是不一样的,甚至同一个项目,部署在不同的机器上配置都是不同的。但是对于一个项目而言,我们期望一次release动作用到的发布包都是相同的,不会因为配置不同做成多个发布包。这个不知道大家有没有感触,测试环境、沙盒环境、线上环境通常有自己的配置,所以有些人就为测试环境打一个包、为沙盒环境打一个包、为线上环境打一个包。这种做法在笔者看来是很不好的。因为QA测试的那个包竟然不是线上用的包!那如何保证不出问题?!
我们推荐做成一个包,那就要屏蔽差异,把不同的配置信息抽出来。外部搭建一个Config Center就是一个方案。
配置信息通常不大,好多人可能很容易想到用Zookeeper实现一个。不过这篇文章中我们不谈具体实现,淘宝有个开源项目叫Diamond也是做类似事情的,大家如果有兴趣可以参考一下,如果没记错的话,Google的Borg系统中也是有一个配置中心的。
云主机and服务监控
上面提到的几点主要是针对code和deploy的,接下来咱们聊一下监控。提到监控这个词,你想到了对什么的监控?cpu、内存、io、网络、磁盘,嗯,没错,机器基础监控必须要有;进程存活监控、端口监控、域名监控,嗯,针对服务存活性的监控,也必须要有。通常提供云监控的IaaS厂商都会提供以上两类监控,够了么?还有其他需求么?
你是否想过http 500次数的监控?url响应时间过长的监控?api调用次数过多的监控?log中Error字样或Exception字样过多的监控?嗯,这些就属于是一些业务自定义监控了。能提供这种监控的IaaS就不多见了。而实际上,这是很有需求的,就像我刚才举的这几个例子,你是dev的话你肯定也想知道吧?
但是这些监控每个服务都不一样,作为IaaS平台方,应该从哪里拉取这些监控数据呢?显然,没地方!应该让app方告诉平台方pull的接口是什么,或者平台方直接提供一个push接口,让app自己去收集数据然后push。不管是哪种方式,平台方都要制定数据格式规范,比如什么样的接口才可以被拉取,拉取到的数据应该是什么格式,或者什么样的数据才能push,push的方式是什么样的,诸如此类。
如此一来,我们开发产品的这些苦逼码农不但可以了解到我们使用的云主机的运行情况,服务的存活情况,也可以了解到服务的性能情况,稳定情况,是不是不错?
LB接口化
IaaS厂商刚刚起步的时候,第一个要做的显然是云主机;云主机搞定之后呢?显然是RDS;RDS搞定之后呢?大部分厂商都会选择去做LB,因为域名后面直接配置七层server还是有很大的问题,那就是七层server宕机之后无法及时从域名中摘掉,因为dns是有比较久的生效时间的嘛~于是 LVS之类的四层负载均衡设备就派上用场了,也就是aws中所谓的ELB。
通常IaaS厂商都会提供LB,但是并不是所有厂商都提供api让用户去修改vip对应的rs,而这点在笔者看来是一个非常重要的功能,最好尽快提供。它有什么用呢?LB已经可以自动摘掉宕机的七层实例了,还不够?这个api主要是用于做自动迁移的,即:新扩容的rs可以及时加进来,宕机的rs可以及时摘掉。这个加进来和摘掉的动作要自动化!故而LB要接口化。
All in Automation
之前我们已经提到需要一个Deploy工具,让用户方便得部署他们的服务,快速迭代,持续集成。但是在部署的过程中用户仍然要指定很多信息,比如要部署的机器列表,run应用的Linux账号,部署完成之后还要手工修改ELB的配置,修改vip对应的rs(别怕,通常是不用修改的,只有个别情况比如扩容的时候才需要)。整个过程比较复杂。特别是分配机器列表,如果模块比较多,我们为了更好的资源利用通常会选择混部,比如io密集型的与cpu密集型的部署到一台机器上,这样一来我们要花心思去分配,能不能让平台自动化去调度完成?
比较好的用户使用方式可能是这样的:
用户提供发布包,提供所有可用的机器列表,告诉平台要部署的服务是io密集型的还是cpu密集型的,告诉平台这个服务要注册的ELB vip是什么以及这个服务的服务端口是什么,然后平台自动去调度部署。
平台可能的做法:
通过监控系统收集到该用户各个云主机的资源利用情况,按照比较好的混部策略,找到比较适合部署这个服务的云主机,部署少量几个app实例,把这几个实例注册到对应的vip上去(LB接口化很重要吧,嘿)提供服务,然后监控这些实例是否挂掉,如果挂掉了自动拉起,如果实例所在的机器都挂了,自动将实例迁移到其他好的云主机上去,同时修改vip对应的rs配置,然后监控这个vip的流量,如果流量太高,自动扩容,找新的云主机部署新实例,将新的rs加到该vip下。
目前先想到这么多,这是笔者脑袋中的一个不甚成熟的蓝图,诸位看官有补充的欢迎留言。如果看完之后碰撞出了你脑袋中的思维火花,可以选择打赏我包烟钱,我不会介意的,嗯?不知道我的支付宝?哦,就是我的手机号,嗯?不知道我的手机号?打电话问嘛……