海豚浏览器于2010年2月正式发布Android版本,在正式发布的近一年之后从一个纯客户端的产品开始迭代式地进化,逐渐加入各种云端服务的功能,海豚浏览器的云端之路也因此而启程。在创业之初,因为资源、人手的各种紧缺,自然而然的云端服务的部署也就成为首选。当时在国外的创业型小公司中,亚马逊云平台(Amazon AWS)备受青睐,因此我们也毫不犹豫的选择了AWS做为服务商,并且在海豚阅读(Dolphin Webzine)的第一次发布里做了大规模的尝试,随后又相继推出了海豚同步,海豚声纳等云服务。
起初接触云平台其实更多地仍然是把云平台当成普通的IDC主机租用服务在用,体验到的优势是相对于物理主机而言,云主机(instance)上线/下线都比较方便。而且不像国内很多主机服务是预充值或者预付款的消费模式,AWS平台的付款直接与信用卡挂钩,用多少就付多少,非常灵活。随着时间的推移,对云平台认识的浅显和不充分,导致我们吃了不少的苦头,当然也积累了不少经验教训。到现在,整个AWS云平台(见图1)的大部分服务我们都有实际使用的经验。
图1:AWS服务栈
云平台上的扩展性
说到云平台的使用就不得不先说说水平扩展(scale out)。之前我们的做法是在服务正式对外发布之前,部署多套同角色的机器(比如前端机器和应用服务器),就为了保证能够应对突发的流量增长。这些备用机器的部署和使用在云平台上其实是没有多大必要的。在AWS上完全可以通过ELB这样的一个弹性负载均衡器来自动实现服务的水平扩展,ELB支持多种协议,并且可以自定义水平扩展的条件,对于服务的开发者来说,这省了不少开发的活,而且对于普通的负载均衡应用场景来说,它完全可以替代Nginx或者HAProxy。
对于垂直扩展(scale up)来说,有两点比较重要,一是对云主机升降级时类型的选择,二是了解云主机的生命周期。EC2上的云主机有固定的好几种类型,首选一般都是64位机器,这样方便内存扩容,如果对于CPU消耗比较高(比如HTTPS连接),那么优先选High-CPU型的,如果是对内存要求比较大(比如MongoDB),那么优先选High-Memory型的。海豚的大多数机器选型集中在micro/small用作监控和前端,small/medium部署应用服务、消息队列,medium/large做数据库和离线计算。xlarge再往上用得很少,基本上都靠水平扩展解决了。对于云主机的生命周期来说,restart和stop/start是有区别的,升降级的时候必须要stop云主机,升降级完毕再启动的时候,机器的内部IP会发生变化(IP通过DHCP分配的),这一点经常会给依赖IP的服务配置造成问题。解决的办法有两个,一个是通过VPC来自己控制IP地址分配,另外一个就是使用Elastic IP这样的静态地址。
云平台上的存储
和计算资源一样,存储资源是一个云平台的核心要素之一。云平台上的存储按照使用场景分为三大类型:
·临时存储。AWS的instance storage就是临时存储的一种,主要用来存放缓存和一些中间结果等内容。要注意的是临时存储的内容在云主机stop以后就会被清空,因为通过df命令往往看不出来这一点,所以之前有过把instance storage当成持久化存储的经历,损失就很惨重。
·持久化存储。持久化存储最常指的就是物理硬盘,在AWS平台上,EBS就是这样的一个可以以任意大小被挂载的“硬盘”,实际上它的实现是一个网络文件系统,因此它的访问速率受限于网络带宽,而且不是那么稳定。通常可以通过在EBS标准的volume上做RAID或者使用最新推出的Provisioned IOPS volume来解决I/O速率问题。另外尽管EBS是持久化存储,并不意味着它就不会发生数据的丢失,EBS的年化不良率有0.1%-0.5%,因此对于单存储节点来说需要定期的去做EBS的镜像和备份,以防止意外的发生。
·大规模冗余存储。S3就是这种存储类型的样例。S3不是一个文件系统的架构,I/O速率和延迟也不及EBS,但它的好处在于一方面可以在一个比较低的价格(和EBS差不多)提供99.999999999%的可靠性,另外一方面可以存取非常大规模,比如PB级别的数据,这些数据可以在不限于AWS的任何地方使用。海豚就用S3存储了几乎所有的镜像、数据备份和各种日志。除此之外,S3和CloudFront(AWS的CDN解决方案)集成程度很高,因此海豚也通常使用S3作为APK等内容分发的渠道。