从零开始搭建微服务: 阿里云不完全攻略(1)

本文是新系列“从零开始搭建微服务”的开篇,该系列将围绕微服务展开,重点在于动手搭建

一个典型的微服务架构(转自 [Introduction to Microservices](https://www.nginx.com/blog/introduction-to-microservices/))

微服务是个很大的话题,关于微服务单体服务的优缺点众说纷纭。但不可否认的是:微服务对产品的快速迭代,小步快跑有着巨大的作用。移动互联的时代,更要拥抱变化。因此,从我司的实际出发,如何基于有限的研发人手,落地微服务,这是从创业之初,就摆在我们面前的问题。
工欲善其事 必先利其器要搭建服务,首先要有服务器,最好还有各类开箱即用的基础服务。有限的人手,让我们没有多做犹豫就确定了“一切都放到云上”的决策。
《Netty 内存管理探险: PoolArena 分配之谜》中曾经提到过,我司重度使用阿里云。是的,最终我们选择的云供应商是阿里云。阿里云中各种五花八门的产品和其购买选项会让很多初识者眼花缭乱,无从下手。本文就来谈谈这方面的一点心得。

一. 阿里云的正确打开方式

打开链接 www.aliyun.com,首先我们得注册一个阿里云账号。对企业用户来说,应尽快申报企业实名认证。只有企业实名认证账号才能进行对公账号转账充值,开具增值税发票等企业专用功能。实名认证入口位于“账号管理”中:

阿里云企业实名认证

接下来,得根据产品的目标人群选定一个主要的产品地域。几乎所有的阿里云产品都会要求用户选择所在地域,这也很好理解,云产品也实际落地在阿里云维护的某个物理机房中,就会有地域属性。同一个地域内的阿里云产品的互通可以近似理解为内网访问,而跨地域的阿里云产品互通就得通过互联网进行公网通信,其可靠性和实时性都会受到影响。另外,通过公网互通,一般来说,除产品本身的费用外,阿里云还会收取相应的公网出站流量费用。
由于阿里云目前尚不支持在产品购买后,迁移地域,因此,除非目的明确(例如异地互备),建议从属于同一系统的阿里云产品都购买在相同地域中。目前,阿里云地域有:
阿里云的产品地域

如果面向目标人群主要为国内用户,可选择的地域包括:华北1/2、华东1/2和华南1。根据笔者实测,这五个区域的国内南北互通和运营商互通没有太大差异。而华东1的物理位置就在阿里云的大本营: 杭州,不少阿里云的新产品也会第一时间在华东1试运营,因此,建议优先选择。

二. 云服务器: ECS

一般来说,首先需要采购的是云服务器(ECS)。在阿里云的ECS购买界面中,用户可根据CPU类型,CPU核数和内存的配比,公网带宽,ECS绑定的云盘大小灵活组合,但这样的灵活性也带来了令人眼花缭乱的定价。我们来一一分析:

2.1 CPU 类型及内存配比

目前阿里云 ECS 的实例类型分为:系列I、系列II和系列III三大类,这三个系列的差异主要表现在CPU类型(支持指令集等)、对应采用的内存型号和是否I/O优化,用户可根据实际运行应用的特性(IO密集型计算密集型)来选择。从笔者的实践来看,即便是采用最低配置的系列I,也足以在 CentOS 6.5 / 7 上,基于 JDK8,运行常规的IO密集型 JVM 应用服务。在采用了微服务架构,单个服务的业务逻辑在基于异步IO异步接口模式充分优化后,由复杂度的不同,单组后端服务能轻松支撑 1K~ 5K 甚至更高的并发。摘录说明如下:

  • 系列 II 较系列 I 进行了硬件升级,采用 Haswell CPU、DDR4 内存,并默认为 I/O 优化实例,同时增加了一些新的指令集,使整数和浮点运算的性能翻倍,整体计算能力更强。
  • 系列 III 相对系列 I 和系列 II 进行了硬件升级,采用 Intel Broadwell CPU、DDR4 内存,并默认为 I/O 优化实例,高主频和中主频两种 CPU 配合多种内存配比,可以提供给用户更好的性能以及更多的选择。

而是否I/O优化的差异主要和挂载的云盘IOPS相关,具体为:

  • 支持 I/O 优化的实例
    挂载 SSD云盘或高效云盘时能够获得云盘的全部存储性能,因为 I/O 优化为实例与云盘之间提供更好的网络能力,可保证云盘存储性能的发挥。
  • 不支持 I/O 优化的实例
    挂载 SSD云盘时,通常最高可获得 1000 左右的 IOPS 性能;挂载高效云盘时,通常最高可获得数百的 IOPS 性能

在实例的选择界面,根据不同系列,CPU核数和内存大小有若干固定搭配提供。CPU核数和内存的配比有四种:1:1(1核配1G内存)、1:2(1核配2G内存)和1:4(1核配4G内存)和1:8(1核配8G内存)。在上述的三个系列中,最低配置都有1核1G,而目前最高配置,竟然能选择到56核224G【注1】。如对实例有特殊需求(需要更多CPU核数或是更大的内存),则可如下截图所示填写工单,提交阿里云后台,由人工进行处理。

购买非标准实例 需要提交工单申请

申请非标准实例的工单样例

如前文所述,后端服务大多数是IO密集型的,特别地,对于 JVM 应用而言,出现 OutOfMemory 异常的场景比起CPU居高不下要多得多(大多数系统负载异常升高也都直接或间接由于 OutOfMemory 引起的)。因此,我们在实践中以选择 2核16G 的内存型实例为主,下面以该配置为例,并固定几个因素来比较三个系列实例的采购成本:

  • 计费方式均为“按量付费”
  • 带宽计费模式为“固定带宽”,并设置为0Mps;此时ECS只有内网IP,没有公网IP,后文会提到此类内网ECS的优缺点和使用场景
  • 只有一块默认的40G系统盘,没有额外的数据盘,且都采用该区域允许的最低配类型云盘

如下表列出了在2核16G配置下,不同系列,不同区域实例的每小时费用:

实例类型 华东1 华东2 华北1 华北2 华南1
系列I(2核16G) ¥1.707/时 ¥1.71/时 N/A ¥1.71/时 ¥1.71/时
系列II(2核16G) ¥1.75/时 ¥1.75/时 ¥1.75/时 ¥1.75/时 ¥1.75/时
系列III(2核16G) ¥1.83/时 ¥1.83/时 ¥1.83/时 ¥1.83/时 ¥1.83/时

ECS不同系列成本对比

表中数据均为本文成文时(2017.2)的数据,仅供参考

从上表可以看到,如我们所预期的,在内核个数和内存大小相同的前提下,系列III的成本最高,系列I的成本最低,而相同系列几乎不存在地域差异。唯一的异常是在华东1中,系列I的每小时费用相比其它三个地域便宜0.003元,这是由于在华东1地域,系列I的存储只能选择普通云盘,而其它区域的系列I只能选择高效云盘或性能更高也更贵的SSD云盘

注1:

  • 按量计费方式下的实例最高配置目前为:4核16G
  • 包年包月计费方式下的实例最高配置目前可达惊人的:56核224G;当然费用也惊人的贵
2.2 计费方式:按量付费 vs 包年包月

阿里云所有产品都支持的计费方式是:按量付费,这也是云服务相比于传统IDC的根本优势之一。所谓打开水龙头就用,那当然是用了多少资源付多少钱,这一计费方式对用户来说最容易理解。另一方面,对于包括ECS在内的几个核心产品,阿里云还提供了包年包月的计费方式来锁定长期用户。具体来说,用户可以一次性为今后一段时间的资源使用预先付费。相比于每小时结算一次的按量计费,如果使用时长相同,这笔预付费用会便宜不少。让我们来具体算算有多划算。以系列I的2核16G的配置为例,地域为华东2,都按照使用时长为1年,不同计费方式下的1年成本对比如下:

系列I(2核16G) 按量 包月 包1年 包2年 包3年
计费单价 ¥1.71/时 ¥500.00/月 ¥5100/年 ¥8400/2年 ¥9000/3年
计费周期数 × 24 × 365 × 12 × 1 ÷ 2 ÷ 3
总费用(元) 14979.60 6000 5100 4200 3000

一比吓一跳啊!包月使用1年的费用仅仅是按量使用1年的40%。更不用提,目前阿里云在大力做促销的包2年、包3年的打折力度了。当然,包年包月的优惠付出的代价是锁定了使用期限。
需要注意,包年包月ECS有5天内无理由退款的选项:在购买包年包月ECS后,发现配置有误,或是地域选择错误,或者任何其它原因,如距离购买生效时还未超过5天的,可以进行退款。但请注意,截止目前为止,该规定细则仍然是:每个用户累积只有1次ECS 5天内无理由退款的机会,也就是只要该阿里云账号已经进行过一次成功的ECS退款操作,就不能再次退款了。因此,下单要慎重啊!

阿里云 [5天无理由退款规则](https://www.aliyun.com/support/jpfw?spm=5176.7740684.2.1.bZeFbu)

综上,我们对选择何种计费方式,可以归纳如下:

  • 试用、临时使用为目的的ECS购买,无论是测试配置,测试地域,最好采用按量付费方式,最少只需要掏1小时的费用,只要记得试用完成后,立刻通过控制台释放实例即可(不足一小时按照一小时计费)
  • 长期使用为目的,在ECS的配置和地域都已经完全明确的前提下,能包多长时间包多长时间,享受超值的打折优惠
2.3 网络和安全组

在购买ECS时,我们可以选择使用何种网络类型,阿里云提供了“经典网络”和“专用网络”两种:

  • 经典网络:内网IP地址由阿里云统一分配,且不可更改,可方便的与用户购买的其它实例或阿里云产品进行同地域的内网互访,适合对网络自定义及自主性管理要求适中的用户
  • 专用网络:是指逻辑隔离的私有网络,用户可以自定义网络拓扑和 IP 地址,支持通过专线连接,网络可扩展性强。适合于对网络有个性化定制及高级定制需求的客户

简言之,“专用网络”给了有能力且有需求使用“虚拟交换机/路由器”来规划定义私有网络用户这样一种可能性:在阿里云的基础网络内建立一个可以自定义的专有隔离网络,自定义这个专有网络的网络拓扑IP 地址。两种网络类型的功能对比如下表:

功能点 经典网络 专有网络
二层逻辑隔离 不支持 支持
自定义私网网段 不支持用户自定义 用户自定义
私网 IP 规划 经典网络内唯一 专有网络内唯一,专有网络间可重复
自建 VPN 不支持 支持
私网互通 账号内相同地域内互通 专有网络内互通,专有网络间隔离
自建 NAT 网关 不支持 支持

经典网络 vs 专有网络

“专用网络”的一种应用场景是搭配高速通道组建混合云,如下图所示:

混合云示意图

使用“专用网络”(VPC)、ECS和其它云产品搭建云上业务系统,而出于数据保密性考虑,核心数据放置在云下用户的自建数据中心(IDC),使用高速通道专线接入,实现云上云下数据互通,形成混合云使用环境。

专用网络还有其它使用场景,参见文后所附参考资料(阿里云:VPC专用网络常用应用场景),这里不再赘述。
对于大多数用户而言,“经典网络”已经足够使用。而使用“安全组”防火墙可做到三层网络访问控制,所以,如果要在经典网络中,进行简单的访问隔离,可使用创建多个“安全组”来实现,具体说明参见文后所附参考资料安全组使用FAQ。在小规模使用中,"偷懒"一点,全局使用一个默认安全组,通常也足够了。

2.4 ECS绑定的存储

无论选择何种实例类型,小到1核1G,大到56核224G,ECS默认的系统盘大小均为40G,用户可以调整系统盘最大到500G,或是购买额外的数据盘。增大系统盘或另购数据盘都会增加ECS的采购成本。从笔者的实践来看,如果只是安装后端服务,以及临时保存运行日志,默认的40G系统盘在安装完系统后的剩余空间已完全足够。

  • 问题1:要用云盘长期保存文件(用户上传的图片、音视频)怎么办,而且文件的数量估计还挺多?
    如业务中需要长期保存文件,则建议单独采购阿里云的OSS产品,使用其SDK二次开发来完成功能。从安全性、数据完整性以及结合使用阿里云CDN的方便性看,OSS都提供了远超云盘文件系统的能力。本系列后续文章中会再做详细介绍。
  • 问题2:系统产生的运行日志中有很多有用信息,想长期保存,以后估计还得做个分析,40G空间不够咋办?
    后端服务运行产生的日志类文件,如需要长期保存,建议结合使用阿里云日志服务OSS表格存储MaxCompute等存储类服务,并配合 E-MapReduce、MaxCompute 进行离线日志分析。

另外,如确需购买额外云盘,也建议采购独立型云盘。其购买入口位于“云服务器ECS”-"磁盘"下,如截图所示:

独立云盘购买入口

独立型云盘可以在不同的时间,挂载到相同地域的不同ECS实例上,这种云盘的使用方式更为灵活和经济。

2.5 带宽方式

ECS在带宽计费方式上也提供了两种选择 —— “按固定带宽” 和 “按使用流量”:

  • 按固定带宽的方式:
    需指定公网出站的带宽的大小,如 10Mbps,适用于业务场景对于网络带宽要求比较稳定的客户,费用较低
  • 按使用流量的方式:
    是按公网出站的实际发生的网络流量进行收费,适用于业务场景对网络带宽需求变化较大的场景,如平时带宽使用较低但间歇性的出现网络访问高峰的场景;为了防止突然爆发的流量产生较高的费用,可以指定容许的最大网络带宽进行限制

对于如何选定带宽方式,我们可以从接入架构考虑。从我司的实践来看,一个相对合理的生产系统接入架构是:将阿里云负载均衡(SLB)前置于业务系统前。此时,由前端APP或WEB与后端服务交互产生的入站和出站公网流量,均在SLB上计费。一般情况下,SLB和后端ECS属于同一地域,因此两者通信走的是内网流量,不产生费用。

SLB 前置示意图

该方式的优势是巨大的,显而易见,如果SLB后端对接多个运行相同功能服务的ECS,可满足高可用和吞吐量水平扩容的要求。同时,由于ECS不直接暴露在公网,可避免一系列由ECS操作系统漏洞带来的安全性问题。此时,作为后端服务的ECS甚至无需公网IP,也就可以配置为前文提及的“内网ECS”模式——将固定带宽直接配置为 0Mbps。关于 SLB 的使用方式,在本系列的下一篇文章,还会详细介绍。

是否可将所有ECS都配置为无公网IP的内网ECS呢?

从实际操作情况看,往往做不到,有如下几个原因:

  • 除使用阿里云提供的ECS控制台外,一般还需要登录到ECS上,通过图形界面或命令行进行操作。即便是在全Linux组成的系统中,还是至少需要一台能通过公网访问的服务器,来作为登录跳板机,使用 ssh 或类似方式,手动登录到组内的任何一台ECS上
  • 公网带宽为0Mbps的ECS,除了公网不能直接到达外(不能直接入站),它本身也不能直接访问公网(不能直接出站)。这一限制,通常不会带来问题,因为所有的阿里云产品,包括 RDS、OSS、云数据库 Redis,消息队列等在内,都有内网地址,均能通过内网访问或仅支持内网访问。但如ECS上运行的后端服务需要访问非阿里云产品的公网服务,例如:第三方短信平台、百度系开放平台、腾讯系开放平台,则ECS必须能够有公网的访问能力。

综上,如ECS仅作为运维跳板机使用,可确定带宽计费方式必然是选择“按使用流量”划算,大致估算运维操作中,可能的最大下载(对ECS来说是出站带宽)需求,即可确定最大网络带宽的数值。若是后端服务需要对公网进行访问的,如果访问操作较为均匀,建议采用“固定带宽”方式;若访问操作时机及所需带宽随机性较大,则还是采用“按使用流量”计费为妥。
另外,如需搭建内容下载型业务,从带宽成本和体验考虑,应优先考虑使用阿里云CDN,而非直接通过ECS或SLB提供下载服务。

2.6 延伸问题:单台ECS运行多少服务实例合适

在微服务架构中,一个基本的事实是:相比于大单体,会存在多得多的独立服务进程,或称之为“服务实例”。那么,到底该如何将这些服务实例分配到服务器中去:是尽量在低配ECS上运行单实例,还是将更多的实例纳入到CPU核数和内存都更多的高配ECS中去运行?为后面行文方便,我们将这一概念称为:ECS/实例 配比策略,前者定义为:1:1配比,后者定义为:1:N配比
让我们来简单测算下分别采用两种不同的ECS/实例 配比策略的成本开销。由于目前阿里云中ECS的最低配实例就是1核1G内存的,我们假定单服务实例使用1G内存,一共有12个这样的服务实例需要运行,在该假设情况下,成本对比为:

ECS/实例 配比策略 低配ECS运行单实例(1:1) 高配ECS运行多实例(1:N)
单实例内存资源消耗 1G 1G
整系统所需实例数 12 12
单台ECS配置 1核1G 2核16G
所需ECS数量 12 1
单ECS成本【注2】 ¥459.00/年 ¥5079.60/年
购买ECS总成本(元) ¥5508 ¥5079.60

ECS/实例配比策略比较(1)

从上表看,1:1配比相对于1:N配比策略,每年就要多花费428.4元。更进一步,由于微服务架构更鼓励单服务实例专注于实现单个业务功能,因此,将单服务实例基于异步IO和异步接口模式充分优化后,内存消耗能降到更低。在 《Netty 内存管理探险: PoolArena 分配之谜》 一文中,就引用了我司在生产系统中的实际案例:xharbor (API 网关)可配置为 128M堆内存(Heap)加上 96M堆外直接内存(Direct)总计 使用 224M系统内存来运行。
目前,我司生产系统的不同类型服务实体已经多达30+,按照30种服务类型算,为确保高可用性,每种服务实体都至少运行两个实例,因此总计有60个同时运行的实例,按照单个实例消耗 250M 内存来再次测算整个后端系统运行1年时间的所需的ECS成本,两种配比策略对比如下:

ECS/实例 配比策略 低配ECS运行单实例(1:1) 高配ECS运行多实例(1:N)
单实例内存资源消耗 250M 250M
整系统所需实例数 60 60
单台ECS配置 1核1G 2核16G
所需ECS数量 60 2【注3】
单ECS成本【注2】 ¥459.00/年 ¥5079.60/年
购买ECS总成本(元) ¥27540 ¥10159.2

ECS/实例配比策略比较(2)

此时,1:N配比策略的成本仅为 1:1 配比成本的37%。很明显,这是由于在1:1配比策略下,大量的系统内存资源被浪费了。在上面的两次测算中,细心的读者应该已经注意到,我们忽略了CPU资源的占用差异,在第二次测算的1:N配比策略下,每个服务实例只能分摊到 1/15 核的CPU资源。但大多数情况下,后端服务由于是IO密集型服务,所占用的CPU资源较低,一般不会成为系统瓶颈。另一方面,阿里云及其合作伙伴提供了相当多的标准计算密集型服务,包括:图像裁剪、识别,语音识别,视频转换,大数据分析等,其投入/产出成本相比于自行搭建更为低廉。如业务中用到上述功能,建议优先考虑花钱购买标准服务来解决问题。
相对于显性的采购成本,隐性的ECS运维成本,往往更容易被决策者所忽略。更多的ECS数量意味着更多的运维行为和更多的系统级监控,也就意味着更多的人力成本投入。运维系统的自动化程度越高,运维上的人力成本投入会越低,但这也同时带来了较多的基础研发投入。哪怕是有着阿里云强大的产品控制台和OpenAPI作为基础,从我司的实践来看,这里也是一个需要精兵强将投入的“艰巨战场”。

当然1:N配比策略也有需要谨慎处理的不足之处

  • 由于计算资源没有被隔离,存在由单个服务实例负载异常造成整台ECS缓慢的问题,这就需要更为实时和灵敏的业务监控系统来及时发现此类问题,给短期的手工解决赢得时间,给长期的自动化处理找到线索;
  • 由于网络资源没有隔离,多个服务实例的接入端口必须分离,最好是由操作系统自动分配(对于Socket编程来说,就是将绑定的端口值设置为0)。因此,即便是物理位置相同的服务实例,它的每次运行,服务端口都会不同,这也是微服务架构中需要解决的核心问题之一:服务发现。
  • 同样由于系统/网络资源没有隔离,单个服务实例的网络入站或出站流量过大,也会影响同ECS上的其它实例正常提供服务,还有诸如TCP连接数占用过多,系统文件句柄占用过多等问题。这就需要在微服务的统一开发框架中提前埋入相关监控点,并配合业务指标监控系统及时排查、准确定位发生异常的业务模块。

综上,借用《人月神话》中的一句名言:“No Silver Bullet 没有银弹”。在实践中,我们往往根据微服务中不同功能实例的特性,混合使用1:1和1:N这两种配比策略:对于业务负载较小的服务实例,在确保高可用性的前提下(相同功能服务的多个实例部署在不同ECS上),尽量合用单台高配ECS;而对于业务负载繁重或是业务负载变化较大的服务实例,可以部署在单台匹配负载需求的ECS上,确保其承载能力,同时也隔离其负载的剧烈变化。
说句题外话,让技术人员能根据系统的“个性特点”来调整部署方式,用较小的投入,获得最大的产出,这不正是研发团队应该追求的技术成就感吗?

注2:ECS采用系列I,非I/O优化实例,且带宽配置为 0Mbps
注3:同类型服务的两个实例各自运行在不同的ECS上,互为热备,来确保高可用性;此时,每个高配ECS运行30个实例,共计需要 0.25G × 30 = 7.5G 内存,除保留给操作系统2G的运行内存外,实际还有6.5G的内存资源可运行更多的服务实例

2.7 最后一个问题:ECS购买后的配置变更

给各位耐心读到此处的读者吃个定心丸。ECS购买后,还可以有限的变更配置。参照阿里云相关文档总结如下:

  1. 按量付费ECS不支持变更配置。这个能理解,如果配置不合适,直接释放,重新购买即可;
  1. 包年包月支持有限度的配置变更,具体如下:
    • 独享型实例外,对实例规格可随时进行升级,包括 CPU、内存、基础带宽进行升级。升级实例规格后需要在控制台重启实例
    • 不能随时降配,但可以续费降配。降配后的新配置会在新的续费周期内生效。当前剩余服务期限内配置不会发生改变;
    • 提交续费降配操作后,当前剩余服务期限内将不再支持升级和降配功能;
    • 升降配的时候,实例规格族不能互换,只能选择同一规格族中的相关规格;
    • 升降配前后,公网和内网的 IP 地址不会改变。
好吧,最后还有一个小问题

操作系统镜像:我们理所当然 强烈推荐 Unix Like 系的:CentOS、CoreOS、FreeBSD ... 啥都行,只要你熟悉。


总结
在本文中,我们结合架构(主要是微服务架构),重点探讨分析了阿里云ECS的选型和购买的细节,但也挖了不少坑,包括 SLB、OSS、CDN 等相关产品。下一篇文章,将会一并填坑。(TO BE CONTINUED... I WILL BE BACK)

不多解释了 :)

参考资料:
阿里云产品文档:安全组使用FAQ
阿里云产品文档:VPC专用网络常用应用场景
阿里云产品文档:负载均衡
阿里云产品文档:对象存储 OSS
阿里云产品文档:内容分发网络 CDN

推荐阅读更多精彩内容