Category: 大咖专栏


基于Amazon EC2 Container Service构建安全高可用的Docker私有库

1. 背景

Docker hub作为docker官方镜像仓库,提供了大量Docker镜像的托管服务。但使用它来托管企业私有Docker镜像存在一些问题,比如:

(1)Docker hub托管私有镜像的服务目前只面对收费账户;

(2)使用Docker hub托管私有镜像并不适合一些特殊场景,比如工作环境网络是内网,不允许访问外网,那就更不可能到Docker hub去下载镜像。

在这种情况下,如果能构建一个安全可靠的Docker私有库,将会是一个更好的选择。本文将介绍在Amazon EC2 Container Service基础上结合AWS Elastic LoadBalancer、AWS Autoscaling Group、AWS S3及Docker官方提供的registry镜像构建安全、高可用的Docker私有库的方案,帮助您轻构实现这一需求。

2. 方案详解

我们会使用AWS CloudFormation服务,使用自定义的模板脚本声明所需的资源,实现自动化构建。接下来结合我们的模板脚本对本方案进行详细介绍。

注意:以下内容与代码相关部分只贴出主要代码,部分代码用…表示省略;红字部分请替换成您自己账号相关的信息。

完整模板代码地址:https://s3-us-west-2.amazonaws.com/blog.leonli.org/registry.yml

         或者点击按钮直接在控制台中运行:

2.1 架构图

根据以上架构图,基本数据传输过程为:

(1)Docker客户端向镜像仓库发送的pull/push等命令事实上都是通过docker daemon转换成restful请求的形式再发送给镜像仓库的。在本架构中,我们利用AWS Elastic LoadBalancer(简称ELB)接收客户端发来的请求,作为整个架构的接入层。由于我们要求数据是通过TLS加密传输的,所以我们需要使用AWS IAM中的server certificate(由AWS IAM账户上传的TLS证书)与ELB关联,实现对客户端发来的请求进行加密。

(2)ELB会将请求反向代理给后端分布在不同可用区的两台Container Instance(安装了Docker运行环境的EC2实例),Container Instance中运行了Docker registry服务。当请求到达registry时,我们需要首先使用内置在registry中的用户认证文件(比如本架构中使用apache htpasswd创建的基本用户名密码保护文件),进行用户认证,认证不通过,则驳回请求,认证通过,才可以读写数据。

(3)我们将数据统一存储在一个只供创建者使用的S3 Bucket中。

2.2 基于AWS ECS运行Docker Registry服务

Amazon EC2 Container Service (ECS) 是一项高度可扩展的高性能容器管理服务,它让您能够在托管的 Amazon EC2 实例群集上轻松运行Docker应用程序。 Amazon ECS主要有以下几个组件:ECS Cluster、 Container Instance、Task , ECS Service。这里我们基于ECS运行了Docker registry服务,架构如下:

(1)首先我们在模板中定义了一个ECS Cluster,用来管理相关的Container Instance。ECS提供了ECS-Optimize AMI来创建EC2实例作为Container Instance,ECS-Optimize AMI已经内置Docker运行环境和Container Agent代理,可以为我们节省安装这些环境所需的时间。Container Instance在启动时可以由Container Agent根据配置文件/etc/ecs/ecs.config中的ClusterName属性的值知道需要将实例注册到哪个ECS Cluster上。

因为我们要使用Auto Scaling服务实现对EC2实例的伸缩控制。所以我们使用Auto Scaling的Launch Config组件声明我们的Container Instance。并通过UserData传入Shell脚本,此脚本主要完成以下三件事:

– 调用 echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config ,将Container Instance注册到我们的ECS Cluster中。

– 创建/docker-registry/certs目录和/docker-registry/auth目录,并调用aws s3 copy命令从指定的S3 Bucket中复制TLS证书文件和htpasswd用户认证文件。这些文件将在运行Docker Registry时使用到。

– 调用cfn-signal命令,通知AutoScaling Group资源EC2实例已经启动完毕。

Container Instance相关的主要模板代码如下:

(2)然后我们定义了一个TaskDefinition来声明我们要运行的容器及其相关配置。这里我们运行的是Docker registry镜像的容器,它是官方提供的用于构建镜像仓库服务的镜像文件。

ContainerInstances:

    Type: AWS::AutoScaling::LaunchConfiguration

Properties:

      …

      UserData:

Fn::Base64: !Sub |

          #!/bin/bash -xe

          echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config

  yum install -y aws-cfn-bootstrap

          yum install -y aws-cli

          sudo rm -rf /docker-registry

          sudo mkdir -p /docker-registry/certs

          sudo chmod 777 /docker-registry/certs

          sudo mkdir -p /docker-registry/auth

          sudo chmod 777 /docker-registry/auth

          aws s3 cp s3://${SSLCertificateFileBucket}/${SSLCertificateFileName} /docker-registry/certs/domain.crt

          aws s3 cp s3://${SSLCertificateFileBucket}/${SSLKeyFileName} /docker-registry/certs/domain.key

          aws s3 cp s3://${SSLCertificateFileBucket}/${HtpasswdFileName} /docker-registry/auth/htpasswd

          /opt/aws/bin/cfn-signal -e $? –stack ${AWS::StackId} –resource ECSAutoScalingGroup –region ${AWS::Region}

– 配置环境变量REGISTRY_AUTH、REGISTRY_AUTH_HTPASSWD_REALM、REGISTRY_AUTH_HTPASSWD_PATH指定宿主机目录/auth/htpasswd文件作为Basic Authentication基础用户认证文件,从而实现用户授权认证。

    – 配置环境变量REGISTRY_HTTP_TLS_CERTIFICATE、REGISTRY_HTTP_TLS_KEY指定宿主机目录/certs/中存放的domain.crt作为TLS证书文件,domain.key作为TLS秘钥,从而实现TLS传输加密。

    – 通过配置环境变量REGISTRY_STORAGE指定registry的存储驱动为AWS S3,配置REGISTRY_STORAGE_S3_REGION为存储的S3所在Region,配置REGISTRY_STORAGE_S3_BUCKET为存储的Bucket。从而实现将镜像文件存储到AWS S3指定的Bucket中。

关于构建私有库的更多细节和更多配置可以通过Docker官方文档进行了解:Deploy a registry server

TaskDefinition相关的主要模板代码如下:

RegistryTaskDefinition:

    Type: AWS::ECS::TaskDefinition

Properties:

      NetworkMode: bridge

      ContainerDefinitions:

       – Name: RegistryContainer

          Image: registry:2

          …

PortMappings:

            – ContainerPort: 443

              HostPort: 443

          Environment:

            – Name: REGISTRY_AUTH

              Value: htpasswd

            – Name: REGISTRY_AUTH_HTPASSWD_REALM

              Value: “Registry Realm”

           – Name: REGISTRY_AUTH_HTPASSWD_PATH

             Value: /auth/htpasswd

            – Name: REGISTRY_HTTP_TLS_CERTIFICATE

              Value: /certs/domain.crt

            – Name: REGISTRY_HTTP_TLS_KEY

              Value: /certs/domain.key

            – Name: REGISTRY_HTTP_ADDR

              Value: 0.0.0.0:443

             – Name: REGISTRY_STORAGE

              Value: s3

            – Name: REGISTRY_STORAGE_S3_REGION

              Value: !Ref AWS::Region

            – Name: REGISTRY_STORAGE_S3_BUCKET

              Value: !GetAtt StorageBucket.DomainName

          …

(3)最后我们定义了一个ECS Service,指定TaskDefinition、Cluster和所需运行的任务个数DesiredCount。这样,我们就构建了一个运行着docker registry镜像的ECS服务了。

2.2 如何实现高可用性

(1) 跨可用区部署服务

– 首先,我们在模板中声明了一个VPC和两个私有子网PrivateSubnet1和PrivateSubnet2,这两个子网是分别部署在不同可用区的。

– 其次,我们的ECS服务是通过Elastic Load Balancing(ELB)来平衡多个容器的负载,ELB是高可用且自动伸缩的。我们在模板中定义了一个命名为RegistryELB的ELB组件,指定它是internet-facing模式可供外网访问、并且是跨可用区的。ELB接收外网的请求,并且将请求代理给Container Instance中的容器。

– 最后,我们在模板中声明了一个Auto Scaling Group,指定VPCZoneIdentifier为跨可用区的两个子网PublicSubnet1和PublicSubnet2,由RegistryELB代理请求,从而实现跨可用区部署服务。

(2) 利用Auto Scaling保障可用实例数量

当服务遇到一些突发或者预期的高流量时,或者您的服务出现某些异常时,可以利用Auto Scaling服务保障可用实例数量。比如某台Container Instance宕机了,那么可以利用Auto Scaling自动启动相同配置的另一台Container Instance代理宕机的实例继续提供服务。

大部分情况下,企业Docker私有库承受的流量负载不会太大,所以本方案不介绍Auto Scaling的扩展策略,当然您也可以根据自己的业务需要修改模板代码,实现此功能。本方案使用Auto Scaling主要是为了保障可用实例数量一直维持在DesiredCapacity,这个参数是我们通过模板的参数传入的。

Auto Scaling Group相关的主要模板代码如下:

ECSAutoScalingGroup:

    Type: AWS::AutoScaling::AutoScalingGroup

    Properties:

    …

LaunchConfigurationName: !Ref ‘ContainerInstances’

      MinSize: !Ref MinSize

      MaxSize: !Ref MaxSize

     DesiredCapacity: !Ref DesiredCapacity

    …

(3) 利用s3确保数据完整性

Amazon Simple Storage Service (Amazon S3) 是AWS提供的对象存储服务,它可用于在 Web 上的任何位置存储和检索任意数量的数据,能够提供 99.999999999% 的持久性,使用S3来存储Docker私有库的镜像文件,可以确保数据完整。Docker registry镜像支持使用S3作为存储驱动,只需传入存储所在Bucket和所在Region即可。我们在模板中声明了一个Bucket用来存储镜像数据。并且这个Bucket只能由创建者进行控制。

2.3 如何实现安全性

(1) 利用TLS加密传输

Docker官方建议与私有库通信的所有数据传输皆使用TLS加密,我们通过上传IAM server certificate证书并将其与ELB关联,ELB的Listener使用SSL安全监听443端口,并将请求代理给实例的443端口,实例上也需要安装TLS证书。从而实现全链路的安全传输。

(2)利用apache htpasswd实现基本用户认证

如果我们创建的私有库没有用户认证机制,那么无论是谁只要知道私有库链接,就可以肆无忌惮地访问和操作我们托管在私有库的文件,这显然不是我们想要看到的。所以需要实现用户认证,只有通过认证的用户,才有权进行相关操作。

这里,我们使用apache htpasswd实现基本用户认证。这也是Docker registry镜像默认支持的认证方式。

3. 构建过程

3.1 准备工作

(1) 域名

您必须拥有一个用来指向registry的域名,这样您才可以通过域名访问您的私有库。

(2)TLS证书

yourcertificate.crt intermediate-certificates.pem > yourcertificate.crt

Docker官方建议私有库数据传输基于TLS,这样您还需要为您的域名申请CA认证,得到TLS证书和秘钥文件。有以下两种方式:

向CA供应商购买。

利用Let’s Encrypt生成免费的证书,具体操作参考letsencrypt官网。

另外,如果您的证书供应商还提供给你intermedia证书,那么您需要将它与你的证书进行合并,运行如下命令可以进行合并

aws iam upload-server-certificate —server-certificate-name YourCertName —certificate-body file:///path/to/certificate.pem —certificate-chain file:///path/to/chained.pem —private-key file:///path/to/private_key.pem

(3)上传IAM Server Certificate

{

    “ServerCertificateMetadata”: {

        “Path”: “/”,

        “ServerCertificateName”: “MyRegistryCert”,

        “ServerCertificateId”: “ASCAJHAWE3QRHEHH3L6KM”,

         “Arn”: “arn:aws:iam::xxxxxxxxx:server-certificate/YourCertName”,

“UploadDate”: “2017-07-01T16:16:45.125Z”,

        “Expiration”: “2017-09-26T12:15:00Z”

     }

}

 

openssl x509 -inform DER -in Certificate.der -outform PEM -out Certificate.pem

当Docker客户端向我们的ELB发送请求时,出于安全考虑,需要对传输加密,这时可以利用IAM Server Certificate,将我们的TLS证书、秘钥以及证书链文件上传,IAM会帮我们自动生成一个Server Certificate,再将它与ELB绑定即可。

可以使用AWS CLI按照以下命令上传:

openssl rsa -in PrivateKey.pem -out PrivateKey.pem

上传完成后,您会得到类似以下响应信息,将红字部分ARN记录下来,后面构建时需要它作为参数传入模板中。

注意:

– TLS证书、秘钥及证书链必须都是PEM格式,如果不是,可以使用以下命令进行转换:

– AWS IAM 要求证书秘钥是不加密的,所以当您的秘钥是加密时,需要使用以下命令转换

– 如果您在上传Server Certificate过程中遇到问题,可参考AWS官网指南:

Working with Server Certificate

(4)htpasswd用户认证文件

使用apache htpasswd来做基本认证,首先需要安装httpd,安装完后运行以下命令可以生成一个包含 一条用户名和密码记录的htpasswd文件

htpasswd -c username password > htpasswdfile

后面如果需要加入更多条记录,只需将 -c 参数去除,运行上面相同的命令即可。

(5) 将证书、秘钥和认证文件上传到S3

我们需要将前面几步生成好的TLS证书、秘钥、htpasswd文件上传到S3中,Container Instance启动后会从S3中将这些文件拷贝下来,通过映射到容器中供registry容器使用。

创建一个S3 Bucket, 将这几个相关文件上传。

3.2 自动化构建

接下来,我们在AWS Management Console中使用CloudFormation指定我们的模板文件创建一个Stack。如何使用CloudFormation创建Stack,请参考AWS CloudFormation用户指南:CloudFormation入门

Stack构建成功后,在输出栏会有输出值 RegistryELBDns,它是我们创建的ELB的DNS域名。我们需要将我们之前TLS证书签发的域名DNS解析(CName解析)转发到这个ELB的DNS域名。这样就可以使用我们自己的域名访问我们的私有库了。

3.3 开始使用

构建完Docker私有库后,现在可以开始使用了。

首先,在Docker客户端,我们可以从Docker Hub上拉取一个ubuntu镜像。

docker pull ubuntu:16.04

然后tag这个镜像到我们自己的域名下

docker tag ubuntu:16.04 myregistrydomain.com/my-ubuntu

登录我们的私有库

docker login myregistrydomain.com

输入用户名,密码后,调用push命令将镜像上传

docker push myregistrydomain.com/my-ubuntu

上传完后,可以调用pull命令拉取镜像

docker pull myregistrydomain.com/my-ubuntu

4. 总结

本文介绍了如何利用AWS ECS及其他AWS服务构建一个高可用、安全可靠的docker私有库,通过本方案的详细介绍和构建实践,相信您对于docker registry以及AWS Elastic LoadBalancer、AWS Autoscaling Group、AWS S3及AWS CloudFormation有了更进一步的认识。接下来,您可以利用AWS ECS容器管理服务及Docker容器技术,更加轻松地构建和管理您的应用程序,发挥更大的效益。

作者介绍

李磊,AWS解决方案架构师,负责基于AWS的云计算方案的架构设计,同时致力于AWS云服务在国内和全球的应用和推广。在大规模并发后台架构,电商系统,社交网络平台、互联网领域应用,DevOps以及Serverless无服务器架构等领域有着广泛的设计与实践经验。在加入AWS之前超过十年的开发和架构设计经验, 带领团队攻克各种技术挑战,总是希望站在技术的最前沿。

白皮书:Amazon EC2 Container Service(ECS)上的微服务架构(下篇)

ECS上构建微服务架构

在构建微服务架构时面临的一个主要问题就是,如果减轻运行、维护、扩展和管理微服务架构所需大规模分布式集群资源的工作量和复杂性。目前主流的解决此问题的方案之一就是通过容器化部署和运行服务,降低运维和部署的复杂性。Amazon EC2 Container Service(ECS)是AWS提供的一个容器管理服务,能够应对和解决微服务架构的部署和运维中面临的种种挑战。

本章节首先介绍Amazon ECS及其架构和工作原理,然后介绍利用Amazon ECS及其他相关AWS服务分层构建的一个高可用、高可扩展性、容错的微服务,并讨论该方案中涉及的分布式系统监控、服务发现、异步通信等问题。

Amazon ECS 简介

什么是Amazon ECS

Amazon ECS是一个高度可扩展伸缩、高性能容器管理服务,支持Docker容器[vi]并能够让你轻构地在EC2实例构建的集群中运行应用程序。

Amazon ECS能够让你轻松地进行安装、操作和扩展你的集群资源。使用简单的API调用,你就可以启动和停止基于Docker的应用程序、查询你的集群状态、还可以使用其他熟悉的服务,诸如安全组、ELB、EBS卷和AWS IAM角色。

Amazon ECS的特点
  • 与Docker完美兼容:支持 Docker 并使您能够在 Amazon EC2 实例的集群间运行和管理 Docker 容器。Amazon ECS 所管理的集群中的每个 EC2 实例都运行有 Docker 守护程序,所以无论您将何应用程序打包为本地容器,它都将部署和运行在 Amazon ECS 上,无需进行任何配置更改。
  • 内置集群托管:管理自己的容器管理基础设施通常涉及安装、操作、扩展自己的集群管理软件、配置管理系统和监控解决方案。这些系统的可用性和可扩展性架构和管理很难。Amazon ECS 消除了容器管理工作的复杂性。使用 Amazon ECS,您只需要启动容器实例集群并指定想要运行的任务即可,所有集群管理工作将由 Amazon ECS 完成。
  • 编程控制:Amazon ECS 为您提供一组简单的 API,方便您集成和扩展服务。使用 API,您可以创建和删除集群、注册和取消注册任务、启动和终止 Docker 容器,并能提供集群及其实例的状态相关详细信息。您还可以使用 AWS CloudFormation[vii] 预置 Amazon ECS 集群、注册任务定义和安排容器。
  • 任务调度:Amazon ECS  包含许多任务调度程序和内置的Placement Engine,可以根据您的资源需求(例如 CPU 或 RAM)和可用性要求在集群中放置容器。通过使用可用的任务调度程序,您可以安排长期运行的应用程序和服务以及批量作业。Amazon ECS API 还能提供完整的集群状态信息,允许您编写自己的任务调度程序或集成现有的第三方调度程序(例如 Marathon)。Amazon ECS 是共享状态的乐观并发系统,可以将集群的完整状态呈现给所有的计划程序。通过使用 Amazon ECS API 或 Blox (一个用于容器管理和编排的开源对象集合),您可以开发自己的任务调度程序或集成第三方调度程序。
  • 负载均衡:Amazon ECS 已与 Application Load Balancing (ALB) 集成,支持您在多个容器之间分配流量。您只需指定任务定义和要使用的 ALB,Amazon ECS 服务计划程序将自动添加和删除 ALB 中的容器。您可以在任务定义中指定动态端口,这可为安排在 EC2 实例上的容器提供未使用的端口。您还可以使用基于路径的路由与多个服务共享 ALB。
  • 监控:Amazon ECS 为您的容器和集群提供了监控功能。您可以监控正在运行的任务的 CPU 和内存使用率及总和,这些任务通过 Amazon CloudWatch 按任务定义、服务或集群进行分组。您还可以设置 CloudWatch 警报,在您的容器或集群需要扩大或缩小规模时提醒您。
  • 日志记录:您可以将各个容器实例的 ECS 代理日志和 Docker 容器日志发送到 Amazon CloudWatch 日志,以简化问题诊断。借助 AWS CloudTrail,您还可以记录所有的 Amazon ECS API 调用并将日志文件发送给您。记录的信息包括 API 调用者的身份、API 调用的时间、API 调用者的源 IP 地址、请求参数以及 Amazon ECS 返回的响应元素。
  • 安全性:Amazon ECS支持您为每项 ECS 任务指定一个 IAM 角色。如此一来,ECS 容器实例将获得遵循“最低权限”访问策略的最小角色,允许您分别管理实例角色和任务角色。您还可以查看哪项任务使用哪个角色,这些信息均记录在 CloudTrail 日志中。
Amazon ECS的架构及工作原理
 
ECS的架构

ECS由以下主要组件构成:

  • Task Scheduler:任务调度器负责将task和service以task definition文件描述的形式按照一定的调度策略,放置到相应的Container Instance上进行运行。
  • Resource Manager:Resource Manager负责对宿主机进行通信,申请、释放并管理任务运行时所需资源。
  • ECS Cluster:ECS集群是一组EC2实例的集合,由运行Docker容器的Container Instance(容器实例)组成,构成了ECS运行的整体资源。当运行任务时,ECS会根据task definition的信息从ECR或者任何其他Docker镜像仓库中拉取对应的镜像文件,并在集群中运行。
  • Container Agent:Container Agent负责Container Instance与集群的心跳通信,负责访问Container Instance、健康检查、发送命令等等。默认Container Agent是内置在 Amazon ECS-optimized AMI中的,当您创建Container Instance就已经自动安装了Container Agent。
  • Container Instance:Container Instance就是安装了Container Agent并在ECS集群上进行了注册的EC2实例。当您运行ECS任务时,ECS会根据任务调度策略将任务放置到特定的Container Instance上运行。

图3:ECS的架构
跨AZ保证高可用性

Amazon ECS通过跨可用区(AZ)运行应用程序容器来保证高可用性。您需要在VPC中创建您的ECS集群,通过task definition(任务说明)和task service(服务说明)定义好Docker容器镜像文件,并其运行在您的ECS集群上。此外,您还可以通过Amazon ECR,Docker Hub或任何私有镜像仓库来存储和管理您的Docker容器镜像文件。

图4:跨分区运行ECS集群
灵活的任务调度

Amazon ECS将运行在容器中的作业分为两种类型:task(任务)和service(服务)。

一个task通常指的是一次性的作业,比如定时触发器、批量数据处理等,task 需要由一个task definition文件定义其所需的资源和处理过程,并将它运行在您的集群上。您可以指定运行在您的ECS集群上的task个数。

一个service服务指的是永久运行在后台的作业,您同样需要在task definition文件中对其进行定义。Amazon ECS允许您定义一定数量(由desired count参数指定)的任务进程来支持一个service,当某个任务进程失败或者不健康,ECS会自动启动新的任务进程,以保证该服务的任务数量达到desired count。

那么如何将这些任务放到特定的容器实例上呢?Amazon ECS提供的Task Placement Engine支持多种容器任务调度策略:

  • Binpacking:最少资源利用(根据CPU或者内存)的实例会优先被放置,这种策略会先将任务放到可用资源最少的实例上,减少了启动过多的实例,提高了资源利用率。
  • Spread:根据某个特定值进行平衡放置,这个特定值可以是一个键值对,也可以是instanceId或者host。一般可使用这种策略实现跨AZ的任务放置。
  • Affinity:组合条件的放置策略,比如两个符合条件的task不能同时放到某个实例中,或者两个符合条件的task必须同时放到某个实例中。
  • Distinct Instance:将每项任务放置在不同的容器实例中。

图5:任务调度策略

此外,您可以任意组合多种调度策略,或者通过BLOX项目自定义您的任务调度策略。关于BLOX,详见https://blox.github.io/

分层构建微服务方案

本节我们通过分布式应用中经典的CDN层、API层、应用层以及数据持久层分层介绍使用AWS ECS及其他AWS服务构建一个高性能、高可用的微服务。

图6:分层构建微服务
CDN层

CDN层的意义在于加速静态和动态资源的传输,并潜在地减轻后端服务器的压力。

使用CDN,可以让您的微服务应用客户端从最近的端点或者代理服务器、缓存服务器上获取资源,或者可以让您通往原数据服务器的链路得到优化,从而降低延时, 加快您网站及应用上的图片、视频、脚本等数据的传输。

API层

API层是所有请求的入口,它可以隐藏应用程序的业务逻辑细节,通过诸如HTTP REST API接受外部请求。API层一般还需要对所接收的请求进行流量管理、请求过滤、缓存及访问授权和控制。您可以使用Application Load Balancer(ALB)来实现您的API层。ALB是 Amazon Elastic Load Balancing(ELB) 服务的一个负载均衡选项,支持您在运行于一个或多个 EC2实例上的多个服务或容器之间基于内容定义路由规则。它可以做到:

  • 基于主机的路由:您可以基于 HTTP 标头的“主机”字段路由客户端请求,以便您从同一个负载均衡器路由到多个域。
  • 基于路径的路由:您可以基于 HTTP 标头的 URL 路径路由客户端请求。

ALB提供了对容器化应用程序的支持,您可以对应用程序负载均衡器进行配置,以在单个 EC2 实例的多个端口之间对容器进行负载均衡。借助 Amazon EC2 Container Service (ECS),您可以在 ECS 任务定义中指定一个动态端口,以便在将容器安排到 EC2 实例上时为其提供一个未使用的端口。ECS 计划程序会自动使用该端口将任务添加到 ALB Target Group。

如下图所示:您可以将ALB作为API层的入口,接收外部API调用请求,可以对请求进行过滤和访问控制,并根据一定的分发策略将请求分发给其代理的ECS集群,从而起来负载均衡的作用。关于更多ALB的介绍,请参考:http://docs.amazonaws.cn/elasticloadbalancing/latest/application/introduction.html

图7:使用ALB实现API层作为服务调用入口
应用层

应用层实现了具体的应用程序业务逻辑。AWS提供了多种方式来运行应用程序,您可以将程序直接部署到EC2上、或者使用Elastic Beanstalk服务快速构建运行环境,或者使用无服务器服务AWS Lambda、当然也可以使用容器管理服务ECS。这里介绍ECS利用容器技术运行应用层的好处。

  • 一致性:容器镜像文件具有一致性,无论您将同一个容器镜像部署到开发者的笔记本还是测试环境,抑或是生产环境,容器都会保持一致的工作。
  • 灵活性:容器技术将应用程序划分为各个独立的、松耦合的服务,这一点跟微服务架构思想是完美融合的。容器可以使微服务架构的灵活性得到更好的表现。
  • 高资源利用率:容器允许您预先定义需要使用的资源数据(比如CPU和内存),可以在多个下层宿主机构成的集群上共享资源,达到比虚拟机技术更好的资源利用率。
  • 高工作效率:容器具有一致性、版本公开性、松耦合和可轻松回滚等特性的可以重复使用的工作集。您不需要重复“造轮子”,无论从开发和运维上都可以提高您的工作效率。
数据持久层

数据持久层负责将业务中使用到的数据进行存储和管理。将数据管理和持久化单独封装一层,可以让应用层实现无状态化,从而便于应用层进行水平伸缩扩展和实现容错机制。

静态数据一般可以存储在AWS Simple Storage Service(S3)服务上,并通过AWS CloudFront进行分发。关于S3,可以参考 https://www.amazonaws.cn/s3/

会话数据和常用的数据,可以存储在数据缓存中间件中,比如Memcached或者Redis。AWS提供了ElasticCache服务管理这两种缓存服务。关于ElasticCache,可以参考 https://www.amazonaws.cn/elasticache/

对一致性要求较高的业务数据可以存储在关系型数据库中,AWS Relational Database Service(RDS)服务可以管理六大常见关系型数据库引擎(Microsoft SQL Serve,Oracle,MySQL,MariaDB,PostgreSQL, Amazon Aurora)。关于RDS,可以参考 https://www.amazonaws.cn/rds/

关系型数据库不利于伸缩和业务扩展,利用NoSQL数据库得到了更好的可扩展性、可用性和性能。您可以使用Amazon DynamoDB创建可以存储任意数据、应对大量访问的数据库表。DynamoDB可以将表中数据分布到足够多的服务器上,以满足高性能、大数据量、大访问量的存储要求。关于DynamoDB,可以参考https://www.amazonaws.cn/dynamodb/

解决微服务架构中的常见问题

在讨论如何分层构建微服务后,通过ECS和AWS相关服务,我们已经很大程序上减轻了架构和运维微服务应用所需的工作量。本节我们将讨微服务架构中另外几个常见的问题,并结合AWS提供的相关服务对这些问题进行分析和处理。

服务发现

如何让服务发现彼此并进行交互,这是微服务架构必须解决的问题。服务发现包括检查服务的健康状态以及自动发现新服务上线。在AWS中提供了几种方式来实现服务发现:

1. 基于 Application Load Balancer实现的服务发现

ALB具有健康检查和服务上线注册下线注销的功能,将这些功能与DNS解析服务相结合,可以低成本地轻松解决服务发现问题。

您可以给每个微服务设置自定义的域名,然后通过一个CNAME入口,将这些服务绑定到某个Elastic Load Balancer的DNS下。这些服务的DNS名将会被发布给所有需要访问服务的应用程序, 同时结合ALB基于路径路由的功能,能够利用Target Group和Path的结合分发给不同的微服务,节省资源和成本。

图8:基于Elastic Load Balancer的服务发现

2. 基于Key-Value对存储的服务发现

您还可以使用Key-Value键值对存储的形式来实现服务发现,虽然这种方式实现起来需要您花费比其他方式更多的时间,但是它能提供更好的灵活性和扩展性,并且不用担心DNS缓存问题。这种方式天生与客户端负载均衡技术相吻合,客户端负载均衡可以解决性能瓶颈并简化流量管理。

图9展示的是一个利用Amazon DynamoDB作为Key-Value键值存储,并结合DynamoDB Stream以生产者消费者模式来实现服务状态更改通知的架构。


图9:基于Key-Value对存储的服务发现

3. 基于第三方开源组件的服务发现

您还可以使用开源社区中的服务发现组件来构建服务发现,例如Hadoop的子项目ZooKeeper或者Hashicorp公司的Consul[vii], 这种方式的好处在于合理利用了已有的开源社区中的优秀框架来提供基于Key-Value的特定服务,并且这些开源社区的组件对AWS的集成也非常对友好,能够非常快速的搭建服务发现的方案。下图10展示了Consul与ECS的协同工作, 宿主机将会首先利用Registrator[ix]的Agent在Docker启动时将Consul Agent注册到Consul Server,由于Consul基于消息订阅的模型设计,所以其他服务很快收到订阅知道新的组件上线并且能够通过其API了解到其他服务的状态.


图10:基于Consul服务发现

 

数据一致性

单体型架构的应用一般都是将数据存储在一个数据库中,应用程序中所有模块统一使用一致的数据模型。微服务则不能使用这些中心数据库,因为这与微服务去中心化、要求独立型的原则不符。每一个微服务组件都可以拥有自己的一套数据持久化方案。那么如何在服务通信过程中,保持数据的一致性呢?

通常情况下,微服务中状态的变化将会影响整个系统数据的一致性。在这种情况下,事件驱动模型被实践证明可以用于实现数据的最终一致性。事件驱动模型的核心就是将应用程序每一次状态变化当作一个事件记录下来,与持久化数据状态不同,数据是通过一连串事件流存储起来的。数据库事务日志和版本控制就是应用事件驱动模型最出名的两个例子。

在微服务场景中,事件驱动模型以“订阅者-消费者”形式进行应用程序各服务间的解耦,在各个应用不同数据系统的微服务组件之间共享事件流数据,事件驱动模型还可用于读写分离场景,提升读和写的性能。

下图展示如何利用AWS Kinesis Stream作为中心事件流,捕获各个服务的数据变化作为事件,并将事件流记录在S3上。图中各个微服务组件由ALB、ECS和RDS组成,如图所示,微服务组件Microservice 1由于某个状态改变,向Kinesis发布事件,Kinesis将事件持久化到S3中(客户可以使用Redshift服务对这些事件流进行分析),其他微服务组件如Microservice 2和3订阅了这个事件,会拉取并过滤事件,并在本服务组件中进行相应的处理。通过这种机制,可以实现不同数据系统间数据的最终一致。

图11:Kinesis实现事件驱动
异步通信

在单体型架构的应用中,各个模块间的通信是非常简单的,可以是简单的方法调用或者通过内部事件发布机制。而当使用微服务架构时,服务间的通信必须通过网络远程调用。

常用的微服务通信机器除了HTTP REST API进行API调用外,对于一些对实时性要求不高,又耗时较长的通信场景,经常需要使用到消息队列实现异步通信。Amazon Simple Queue Service(SQS)和Amazon Simple Notification Service(SNS)都是AWS提供的用于异步通信、通知推送的服务。

服务监控与日志记录

在微服务架构中,您需要对各个服务进行监控,以判断服务是否健康,是否可用。您还需要对服务的API调用记录、访问记录等日志进行记录,以实现问题发现和追踪。

您可以使用Amazon CloudWatch来收集系统指标,集中管理和监控日志文件,设置预警并自动适应您的运行环境中发生的变化。Amazon CloudWatch可以监控的AWS资源包括EC2实例、DynamoDB表和RDS DB实例,也可以监控任何您的应用和服务生成的自定义指标和日志文件。

1. 监控

利用Amazon CloudWatch,您可以轻松地对微服务组件进行监控,可以监控整个系统的资源利用率、应用程序的性能和服务的健康状态。CloudWatch非常简单,只要进行一些简单的设置,您就可以拥有一套可靠、可伸缩、灵活的监控方案。您不再需要自己去维护一个复杂的监控系统。在微服务架构中运用CloudWatch的另一个好处就是,CloudWatch提供的自定义收集指标可以让开发人员针对特定服务定制特定指标。另外,基于收集到的自定义指标,自动伸缩也可以得到轻松地实现。

2. 记录日志

持续记录日志对于排查和发现问题起到非常重要的作用。微服务让产生的更新发布频率比以往传统架构更多,并鼓励工程师团队更多地尝试新的功能和特性。了解用户的影响对整个应用的逐步提升起来决定性的作用。
为了更好地调试和总览整个分布式系统的状况,我们必需将日志存储在一个统一的中心。在AWS中,您可以使用Amazon CloudWatch Logs来监控、存储和访问您EC2实例上、CloudTrail或者其他资源上的日志文件。

3. 集中管理日志

您可以有很多不同的选择来集中管理日志文件。大部分AWS服务已经“开箱即用”地集中了日志文件。在AWS中,首要的存放日志文件的地方就是Amazon S3和Amazon CloudWatch Logs。图13展示的是一些AWS服务的日志记录能力。日志文件对于每个系统来说都是重要的部分,基本每一个系统操作都会生成一条日志记录。中心化的日志管理方案就是将所有日志文件放在一个统一的中心位置,这样便于日志的访问、查询和分析。

图12:AWS部分服务的日志记录能力

4. Correlation IDs(关联ID)

在很多场景中,一个请求需要由多个微服务共同合作进行处理。想象一下,一个由数十个微服务组成的复杂的系统,当服务链中某个服务出现一个错误时的对整个服务链所造成的影响有多大。即使每一个微服务都有进行很好的日志记录,并集中化日志管理,要追踪出现的错误,需要将所有这些跟这个错误关联的日志都找出来,这是非常困难的。

关联ID的中心思想就是,当负责面向用户的服务收到请求时创建一个特定的ID。这个ID可以放在HTTP头(比如,使用类似“x-correlation-id”这个的头字段)然后在服务链中传递到其他服务中去。这个ID就可以在各个服务独立的日志中记录,这样针对特定请求,就可以根据这个关联ID将所有关联的日志记录都找出来了。

为了得到日志文件中正确的服务调用顺序,可以在HTTP头中传递一个计数器,每经过一个服务就累加一次。

审计

在微服务架构中需要处理的另一个挑战,就是潜在的数百个分布式服务如何既确保所有用户操作的可见性,又能够在组织层面获得良好的整体感观。为了加强安全管理,对资源访问和引起系统变化的操作进行审计就显得非常重要。对系统的更改无论在独个服务中,还是在跨服务的整个系统层面,都必须进行严格追踪记录。在微服务架构中,更改是经常需要发生的,这也就让对更改的审计变得更加重要。

1. 审计追踪

AWS CloudTrail是一个非常有用的在微服务中追踪更改的工具,因为它能将所有在AWS平台上的API调用进行记录,并实时传送到CloudWatch Logs或者几分钟内传送到Amazon S3中。它可以记录从AWS Management Console、AWS CLI、SDK发起或者直接调用的记录。

所有用户的行为和自动化运行的系统行为都变成可以查询和分析的。CloudTrail记录的信息包括用户账号、时间戳、调用的目标服务、调用者的IP地址、请求参数和返回响应元素。

2. 事件和实时操作

整个系统结构中有一些系统状态的变化是必须对其进行快速响应的,必须快速进行修复或者必须及时跟进处理这些变化。Amazon CloudWatch Events实现了一个近实时的事件系统。它可以声明一些适配某些系统状态变化的规则,并定义好自动响应这些变化的措施。

Amazon CloudWatch Events与CloudTrail结合,可以为所有AWS服务上的所有API调用生成事件。它还支持自定义事件或者根据某个特定的调度策略生成事件(比如定时事件)。当一个事件发生并且符合您系统中定义的规则时,CloudWatch Events将立即通知您预先定义好的系统中的某个角色或人物,以便他们及时做出响应措施。更好的做法是,当事件触发时,您可以定义自动化处理的工作流或者调用一个自定义的Lambda function。

图13展示的是使用CloudTrail和CloudWatch Events处理在一个微服务架构系统中进行审计和系统修复的需求。所有的微服务都由CloudTrail进行追踪、审计并将审计信息存储在S3 bucket中。当一个对您系统的更改发生时,CloudWatch Events能在CloudTrail基础上触发事件警告,及时通知系统管理员。您还可以对所有这些日志信息使用Elasticsearch等搜索引擎技术进行日志查询。

图13:审计追踪和系统修复

总结

微服务架构可以突破传统单体型架构遇到的种种限制,它是松耦合的,去中心化的,黑盒的,多语种的,在可用性、可靠性、可伸缩性、可扩展性、安全性、性能和工作效率上更加优秀。但微服务架构也面临着像资源管理、服务发现、消息通信、数据一致性等诸多问题和挑战,利用AWS提供的ECS及其他相关服务,可以解决微服务架构面临的挑战和难题,轻松架构微服务应用,更好地拥抱微服务带来的种种便利。

客户案例

Remind

(https://aws.amazon.com/cn/solutions/case-studies/remind/)

Remind 是一款 Web 和移动应用程序,教师可以使用该应用程序向学生发送短信并与家长保持联系。Remind 在自己的平台上拥有 2500 万名用户和 150 多万名教师,该应用程序每月可发送 1.5 亿条消息。

“迁移到 Amazon ECS 后,我们服务的性能得到了显著提升。我们将服务响应时间的第 99 个百分位降低了 50%。” – Jason Fischl 工程师副总裁

Coursera

(https://aws.amazon.com/cn/solutions/case-studies/coursera-ecs/)

Coursera 是一家教育技术公司,致力于在全球范围内提供世界上最好的课程。该公司与世界各地的顶尖大学和机构合作,为所有人免费提供各种在线课程。Coursera 拥有来自 190 个国家/地区的 1300 多万用户,提供来自 119 个机构的 1000 多个课程,涵盖从 Python 编程到作曲的各个主题。

“借助 Amazon ECS,Coursera 可以集中精力发布新软件,无需花时间管理群集。” – Frank Chen软件工程师

Shippable

(https://aws.amazon.com/cn/solutions/case-studies/shippable/)

Shippable 是一个提供托管式持续集成、测试和使用 GitHub 和 Bitbucket 等存储库进行部署的平台。该公司在从应用程序创建一直到向最终用户交付软件的整个过程中为开发人员和运营团队提供帮助,并在整个过程中实现完全的自动化和完全的控制。Shippable 的平台有助于消除实现重复性持续集成/持续交付和工作流中的阻碍和难题,这样,开发人员便能够专注于交付高质量代码。

“借助 Amazon ECS,我们的开发人员几乎不用花时间在运营相关工作上。过去,我们的高级开发人员需要将 80% 的时间花费在后端基础设施管理功能方面,而现在则将 80% 的时间投入在客户功能上。” – Avi Cavale首席执行官兼联合创始人

Segment

(https://aws.amazon.com/cn/solutions/case-studies/segment/)

Segment 为企业提供一种可从枢纽中心收集客户数据,以备日后用于分析、市场营销和其他用途的服务。该公司的总部位于旧金山,拥有广泛的客户群,从初创公司到大型企业,其中包括 Nokia、Angie’s List、Conde Nast、The Motley Fool 和 Salesforce Foundation 等。

“转而使用 Amazon ECS 大大简化了服务的运行,无需担心预配置或可用性。”- Calvin French-Owen联合创始人兼首席技术官

mytaxi

(https://aws.amazon.com/cn/solutions/case-studies/mytaxi/)

mytaxi 基于 AWS 设计了一款采用速度快且可轻松扩展的 Docker 容器的微服务架构,以应对新年除夕等特别日子的需求高峰。该公司运行着欧洲领先的出租车应用程序,此应用程序在 40 个城市中将 1000 万用户与 45000 辆出租车联系起来。整个基础设施都构建在 AWS 之上,其中的 Amazon EC2 和 Amazon ECS 等服务可为 mytaxi 的 Docker 容器提供支持。

“2015 年 11 月,我们将 Docker 容器架构移动到了 Amazon ECS,而在 12 月,我们有史以来第一次能够庆祝新年,因为我们的系统可以处理大量请求,并且没有发生任何崩溃或中断,我们对这项成就感到极为自豪。”- Sebastian Herzberg系统工程师

 

Burda Studios

(https://aws.amazon.com/cn/solutions/case-studies/burda-studio/)

BurdaStudios 是全球媒体集团 Hubert Burda Media 的一个部门,拥有近 10000 名员工和 500 多个品牌,包括家庭和生活方式类杂志以及企业间出版物。BurdaStudios 专门从事影视制作和数字出版。该公司的旗舰网站是 Bunte.de,一个在德语欧洲国家/地区 (德国、瑞士和奥地利) 处于领先地位的名人八卦门户。该网站是了解好莱坞演员、体育明星和皇室成员最新新闻的首选网站。它吸引了 600 万独立用户,月访问量高达 3000 – 3500 万次 (其独立用户的数量比最大竞争对手高出约 20%),通过展示、视频和本地广告盈利。

“我们通过 AWS 和微服务架构所做的事情正是数字出版业的未来。”- Hansjörg Posch BurdaStudios 首席技术官

Airtime

(https://aws.amazon.com/cn/solutions/case-studies/airtime/)

使用 AWS 服务重新设计其应用程序之后,Airtime 能够以更加快速可靠的方式为客户提供社交体验,而且不会产生任何延迟。Airtime 是一家社交媒体公司,也是一款移动应用程序,可让用户在 iOS 和 Android 设备上实时分享自己喜爱的音乐、视频,并进行消息收发。该公司通过使用 Amazon EC2、Amazon Route 53 和 Amazon S3 等基本服务开始了采用 AWS 的过程,然后重新设计了自己的平台,以便能在采用 Amazon EC2 Container Service (Amazon ECS) 和 Docker 容器的微服务架构上运行。除了改善客户体验之外,Airtime 还通过滚动部署简化了内部流程,而且可以利用 Elastic Load Balancing Connection Draining 等较新的 AWS 功能。

Abema TV

(https://aws.amazon.com/cn/solutions/case-studies/abema-tv/)

AbemaTV 是一家互联网媒体服务公司,运营着日本领先的流媒体平台之一 – FRESH!by AbemaTV。目前, FRESH! by AbemaTV 可提供大约 1400 个频道和将近 37000 个节目:从广播电台的流媒体服务到由 CyberAgent (AbemaTV 的母公司) 开发的原版影视剧,应有尽有。AbemaTV 使用 Amazon Aurora 数据存储来执行其写入密集型微服务 (例如时间表和聊天),并利用 Amazon Relational Database Service (Amazon RDS) 上的 MySQL 数据库来处理剩余的微服务 API。所有 API 都通过 Amazon CloudFront 和 Amazon API Gateway 进行管理。对于可能会影响 API 响应时间的流程,AbemaTV 实施了一套可通过 Amazon Simple Queue Service (Amazon SQS) 队列接收任务的工作程序。

“Amazon EC2 Container Service 对于我们构建具有高可用性、稳定性的微服务,以及受益于各种 AWS 服务而言至关重要。”- Akinori Yamada 工程团队

Linden Lab

(https://aws.amazon.com/cn/solutions/case-studies/linden-lab/)

Linden Lab 是一家总部位于旧金山的互联网公司,因推出 Second Life 虚拟世界而广为人知。Second Life 为用户提供了一个可生成 3D 内容并与之进行互动的平台。用户可通过 Linden Lab 的客户端程序或通过可选的第三方查看器访问 Second Life 虚拟世界。该公司的其他产品包括 Blocksworld,它让用户可以构建虚拟 3D 块并使用这些 3D 块进行游戏;还包括“Project Sansar”,这是计划于 2016 年发布的用于提供虚拟体验的新平台代码名称。

“使用 Amazon EC2 Container Service,我们可以切实地提高开发速度,从而将构建和部署时间缩短 50% 或更高。借助 Amazon ECS,我们拥有了一个非常稳定的平台,这让我们可以大幅扩展产品规模。” – Landon McDowell 运营副总裁

CyberAgent

(https://aws.amazon.com/cn/solutions/case-studies/cyberagent/)

CyberAgent 是一家互联网媒体服务公司,运营着日本领先的流媒体平台之一 – FRESH!。目前,FRESH! 可提供大约 1400 个频道和将近 37000 个节目,从广播电台的流媒体服务到原版影视剧,应有尽有。CyberAgent 使用 Amazon Aurora 数据存储来执行其写入密集型微服务 (例如时间安排和对话),并利用 Amazon Relational Database Service (Amazon RDS) 上的 MySQL 数据库来处理其余的微服务 API。所有 API 都通过 Amazon CloudFront 和 Amazon API Gateway 进行管理。对于可能会影响 API 响应时间的流程,CyberAgent 实施了一套可通过 Amazon Simple Queue Service (Amazon SQS) 队列接收任务的工作程序。

“Amazon EC2 Container Service 对于我们构建具有高可用性、稳定性的微服务,以及受益于各种 AWS 服务而言至关重要。” – Akinori Yamada 工程团队

Meteor Development Group

(https://aws.amazon.com/cn/solutions/case-studies/meteor-development-group/)

Meteor Development Group 是一款开源的跨平台 JavaScript 应用程序平台,开发人员可以使用它为 Web、Android 和 iOS 应用程序编写代码。Meteor 由总部位于旧金山的 Meteor Development Group 创建,使用分布式数据协议和发布-订阅模式自动将更改传送给客户,无需开发人员编写同步代码。Meteor 是 GitHub 上领先的 Web 应用程序框架,每天有数以千计的公司要依靠该平台构建现代化应用程序。

“AWS 的稳定性大家有目共睹。我们面临的难题是:‘我们能够扩展运行所有客户应用程序所需的计算资源数量吗?’以及,“我们能够扩展协调所有这些资源的机制吗?”使用 AWS,我们可以对这两个问题回答‘能’。” – Matt DeBergalis 联合创始人兼产品副总裁

引用

[vi] https://www.docker.com

[vii] https://aws.amazon.com/cloudformation/

[viii] https://www.consul.io/

[ix]http://gliderlabs.github.io/registrator/latest/

白皮书:Amazon EC2 Container Service(ECS) 上的微服务架构(上篇)

更多白皮书:https://aws.amazon.com/cn/whitepapers/

观看在线研讨会视频-运行在Amazon ECS上的微服务架构及实践

 

作者介绍

李磊,AWS解决方案架构师,负责基于AWS的云计算方案的架构设计,同时致力于AWS云服务在国内和全球的应用和推广。在大规模并发后台架构,电商系统,社交网络平台、互联网领域应用,DevOps以及Serverless无服务器架构等领域有着广泛的设计与实践经验。在加入AWS之前超过十年的开发和架构设计经验, 带领团队攻克各种技术挑战,总是希望站在技术的最前沿。

白皮书:Amazon EC2 Container Service(ECS) 上的微服务架构(上篇)

简介

微服务是一种软件开发的组织和架构方法,它可以加快软件交付周期、增强创新和自主性,提高软件的可维护性和可伸缩、可扩展性,同时也提高了企业开发和发布软件服务的能力。使用微服务架构,软件产品将由多个独立的、可通过API进行交互的服务组成。这些服务将由各个小团队独自负责。

通过本白皮书,我们将首先总结一下微服务架构的特性,讨论构建微服务架构面临的挑战和难题,然后介绍AWS的ECS容器集群服务,以及如何利用ECS结合其他AWS提供的服务解决微服务架构中遇到的难题。

什么是微服务架构

微服务架构的特性

近些年,微服务架构的概念变得越来越火[i],事实上微服务并非某项具体的技术或框架,它也不是软件工程学中新的概念,而是一些成功的,经过实践论证的概念的组合,比如面向对象方法论、敏捷开发、面向服务架构、API-first设计、以及持续集成。

“微服务”这个名词是一个概括性的术语,很难对其进行精确的定义。但是所有微服务架构方法都具有以下共同特性:

  • 去中心化:微服务架构是由去中心化数据管理的分布式系统组成。它不依赖中心数据库上统一的数据库模式。每一个服务都有自己独立的数据模型。去中心化的另一个含义是,每个服务在开发、部署、管理和维护过程中也是相互独立的,不依赖某个中心系统。
  • 独立:微服务架构中各个服务组件都可以独立进行更改、升级和替换,而不会影响其他服务组件的正常功能。同样,负责各个服务组件的团队之间也都是相互独立的,互不干扰的。
  • 专注做好一件事:每个服务组件都是专注于某个问题域的功能集合,一旦某个服务复杂度到达一定程度,则应该考虑将其进行服务切分或对其进行再次微服务架构。
  • 多语种:微服务并不是“一体通用”的方法,它允许各个团队根据自己的喜好选择最适合自己问题域的开发语言、开发工具。因此,微服务无论在操作系统、开发语言、数据存储还是工具,都是兼容的。也就是说,微服务是“多语种”的。
  • 黑盒子:微服务中的服务都是按照“黑盒”设计的,也就是说,它们将内部逻辑对外隐藏进来,各个服务间通过定义良好的API进行通信,避免了暗含的相互依赖。
  • 谁构建,谁运行:通常情况下,在生产环境中,构建了某个服务的团队负责该服务的运行和维护。这条规则也称之为DevOps[ii]。DevOps除了能让各个团队按照自己的安排独立工作外,还可以让开发人员更贴近软件产品的真正使用者,能帮助他们更好地了解用户的需求。微服务对于企业组织架构上的影响也是不容忽视的,正如康威定律所言,系统架构是公司组织架构的反映[iii]。

图1:微服务架构的特征

单体型架构 vs. SOA vs. 微服务架构

技术为业务而生,架构也为业务而出现,无论传统单体型架构、SOA和微服务都是因为业务的发展而出现。出现SOA以及微服务框架与业务的发展、平台的壮大密不可分。

单体型架构

当网站或者应用流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本,简化开发流程,适合于个人开发或者小团队开发一些功能单一的小产品使用。这是最传统的架构模式,一般整个系统都是有一个统一的数据中心,各个功能模块显式进行相互依赖(比如直接调用模块公开的方法)。当网站流量随着业务发展不断变大时,这种架构的应用在可扩展性、容错性(一旦某个功能模块被流量击溃,整个系统瘫痪)上存在致命性的缺陷。

SOA

当网站或者应用流量变大,单体型架构无法招架之时,可以采取面向服务架构方式,将应用根据系统维度、功能维度、读写维度或者模块维度进行划分成各个独立的服务组件,服务组件间通过某个约定的方式(比如Web Service或者HTTP REST API)进行通信。当服务越来越多,容量的难以准确评估,小服务导致资源浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率,这种架构一般仍然存在一个统一的数据中心或者调度中心。整个系统的可维护性、可扩展性相对于单体型架构得到提高,但在服务细粒度、隔度性、去中心化方面仍与微服务有差,另外就是SOA架构常常依赖于总线结构,利用可热插拔的中间件以及消息队列来完成服务与服务之间的解耦,对于总线结构的依赖也使得服务的独立性并没有被完全剥离。

微服务架构

在微服务架构中,每个服务都要去中心化,不存在单点故障问题。每个服务都要实现高可用、高负载,不会因为一个服务不可用而影响整套业务流。每个服务细粒度,专注于自己的问题域,与别的服务采用更好的Restful或者良好定义的API进行通信。服务都要高度通用化,即多种终端都可调用,不分语言和平台服务部署或升级简单,不会消耗大量人力并且部署过程不易出现人为错误,同时还具有快速注册与自动服务发现功能。

微服务的益处

许多AWS客户选择微服务架构来解决传统单体型架构中存在的敏捷性和可扩展性限制的问题。让我们来看看选择微服务架构能够带来哪些方面的益处吧。

敏捷

使用微服务的组织由多个负责运维独立服务的小团队组成。各个团队都是在界限明确的小范围内独立、快速地工作,从而起到减小迭代时间的效果。各个小团队效率的提升将使整个企业组织工作效率进行很大程序地提高。

图2标示由多个小团队组成的企业组织架构与由一个大团队组成的企业组织架构,在发布部署一个应用时的工作效率区别。

图2:部署微服务
创新

小团队可以独立自主地针对自己负责的问题域选择相关的技术、框架和工具,这就是创新的体现。职责与义务,让团队产生对自己的服务的责任感。

DevOps通过将开发与运维人员结合到一个团队中,让他们能更早地、更好地沟通,解决了开发部署过程中没必要的摩擦和矛盾。当应用程序部署时,敏捷的处理流程可以让开发和运维工作不再需要暂停下来,相反,整个软件交付周期,从提交代码到发布版本,整个流程将变成自动化的。测试一个新的想法,或者当新功能出现问题时及时回滚,将变得更加轻松。因为失败成本的降低,团队将更加乐于更改和创新。

质量

使用微服务架构您的应用程序,将一定程度上提高代码质量。这跟面向对象设计中提出的分模块开发有同样的效果:提高代码的可重用性、封装性和可维护性。

伸缩性

细粒度解耦的微服务架构另一个好处就是,它非常适合构建大规模系统。它允许针对不同的服务选择最适合的技术,这也是性能优化的体现。每个服务都可以使用最合适的开发语言和框架来实现,利用最优的数据持久化解决方案,并通过各自独立的服务配置进行调优。

合理解耦的微服务架构,可以独立地进行水平伸缩扩展。这相对于传统架构中使用的垂直伸缩有很大的优势。垂直伸缩指的是当业务量、流量增大时,升级硬件资源,将应用部署到“更大的机器”上,这会导致“机器硬件资源上限”和伸缩时宕机的问题。水平伸缩,通过将更多的服务部署到服务池(多个机器组成的集群)中,可以动态地适配流量,并且不会陷入单个机器资源上限问题。整个水平伸缩的过程将会是自动化的。另外,应用程序的可靠性将得到增加,因为出现问题的服务可以自动地被健康的服务替换掉,而不影响整个应用的运行。

可用性

微服务架构可以轻松实现故障隔离。通过健康检查、缓存、隔离仓、断路器等技术,可以减小当某个组件出现故障时的影响,从而保证应用的高可用性。

微服务架构面临的挑战

尽管拥有前面提到的那么多优点,但是微服务架构和所有其他架构一样,都不是解决所有问题的“银弹”。使用微服务架构也会面临一些挑战和难题。比如:

  • 微服务架构都是分布式的,也就会存在所有“分布式计算误区”中提到的问题[iv]。
  • 从单体型架构迁移至微服务架构,需要您准确地划分好各个服务间的界限,并且从应用层到数据库层松耦合代码依赖。
  • 除此之外,在组织管理方面还存在着一些挑战,比如如何组建一个高效的团队,如何将团队转变成DevOps的生产模式,如何合理化开发团队与运维团队的沟通等。

本白皮书主要关注的是架构和运维方面遇到的挑战,如果想了解更多关于AWS如何运用DevOps的知识,请访问https://aws.amazon.com/devops[v]

架构复杂度

在传统单体型架构中,所有的复杂度和依赖都存在项目的代码库中。而对于微服务架构而言,复杂度变成了各个服务间的交互。

在架构上面临的挑战有处理异步通信、连锁故障、数据一致性问题、服务发现和授权认证等问题。

运维复杂度

运用微服务架构,你不再只是运行一个服务,而是数十个,甚至数百个服务。这也就带来了以下问题:

  • 如何以可伸缩、低成本的方式配置好所需要的资源?
  • 如何避免不同的团队重复“造轮子”,重复处理同一个问题,或重复安装配置相同的软件工具?
  • 如何跟踪并管理好上百个代码流的部署过程和它们之间的相互依赖(不同服务可以单独部署)?
  • 如何监控整个系统的健康并提前感知潜在的热点和流量高峰?
  • 如何在整个系统各个服务间追踪和调试问题?
  • 如何分析一个快速增长并超出预期需求的分布式系统的海量日志数据?
  • 如何处理不同技术栈、开发环境间缺少统一标准的问题?
  • 如何受益于不同技术带来的开发效率,而不受困于维护升级这些技术带来的困难?

微服务与云平台

微服务近些年的崛起与诸如AWS这样的公有云平台的发展密切相关。AWS提供了可以直接解决微服务架构面临的挑战的服务。

  • 按需资源调配:资源可以快速根据资源进行配备。相对于传统的基础设施,云平台几乎可以说在资源上是没有上限的。运行于不同环境、不同版本的服务可以临时或永久地共存。不同需要进行困难的资源预测和评估。按需资源调配解决了如何以可伸缩、低成本的方式配置好所需要的资源的问题。
  • 低成本低风险地进行尝试:你只需为你使用的资源付费,从一定程序上降低了你尝试新想法的成本。新功能或者新服务可以快速地发布,并且当尝试失败时,可以快速关闭这些服务和其所需的资源。降低尝试新想法所需的成本和风险,将大力推动更多的创新。这也是跟微服务架构提倡的高度敏捷相符合。
  • 可编程性:AWS服务自带API、命令行工具(CLI)和针对不同语言的SDK。服务器甚至整个架构都可以通过编码的方式进行克隆、关闭、扩展、监控并且在发生故障时实现自动恢复。标准化和自动化是构建速度、一致性、重复性和可伸缩的关键。你可以通过编码的方式统一管理你所需的资源,减少运维微服务架构所需的精力。
  • 基础设施即代码:除了可以编写脚本来配置和管理你的资源,AWS还支持你将基础设施代码化,像应用程序的代码一样放置到版本管理工具中进行管理。因此,各个版本的基础设施都可以随时进行重新部署。你可以保证基础设施代码与应用程序代码一样的质量和性能。回滚不再只与代码相关,也包含整个基础设施。可编程性和基础设施即代码可以解决运行、维护、扩展微服务架构时面临的问题。
  • 持续交付:云平台的可编程性推动了配置和部署流程的自动化。开发阶段的持续集成概念也因此可以扩展到运维阶段(因为运维也是可编码的了),从而形成持续集成与交付的概念。持续交付解决了如何同时管理多个代码流并行部署交付的问题。
  • 自我管理的服务:云平台最出色的优点就是服务都是自我管理的。你不再需要进行繁重的配置虚拟机、安装配置优化软件、处理资源伸缩扩展、管理备份等运维工作。诸如监控、安全、记录日志、伸缩和保持可用性等系统操作和特性都在云平台服务中内置好了。自我管理的服务从一定程度上缓解了运行微服务架构的复杂度和工作量。
  • 面向服务:AWS本身就是微服务架构的。每一个AWS服务都是针对某个特定问题域的,并且都是通过API进行相互通信。你可以将这些服务像乐高积木一样组合成复杂的结构,用来解决特定的问题。这样就解决了重复“造轮子”的问题。
  • 多语种:AWS提供了多种存储得数据库技术供你选择。AWS Marketplace上有许多可以运行在EC2上的操作系统供你使用。AWS的SDK支持各种各样主流开发语言。这可以让你根据特定问题选择最合适的技术方案,从而避免重复“造轮子”问题。

引用

[i] https://www.google.com/trend/explore#q=Microservices
[ii] https://en.wikipedia.org/wiki/DevOps
[iii] https://en.wikipedia.org/wiki/Conway%27s_law
[iv] https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing
[v] https://aws.amazon.com/devops/

白皮书:Amazon EC2 Container Service(ECS) 上的微服务架构(下篇)

更多白皮书:https://aws.amazon.com/cn/whitepapers/

观看在线研讨会视频-运行在Amazon ECS上的微服务架构及实践

作者介绍

李磊,AWS解决方案架构师,负责基于AWS的云计算方案的架构设计,同时致力于AWS云服务在国内和全球的应用和推广。在大规模并发后台架构,电商系统,社交网络平台、互联网领域应用,DevOps以及Serverless无服务器架构等领域有着广泛的设计与实践经验。在加入AWS之前超过十年的开发和架构设计经验, 带领团队攻克各种技术挑战,总是希望站在技术的最前沿。

Amazon EC2 Container Service打造容器化的SaaS应用

概述

在SaaS化应用的改造中,容器技术的应用越来越广泛。相对于传统的虚拟机模式,容器化模式的隔离技术“更轻量”,“ 更快速”,“ 更便捷”. 目前业界越来越广的使用“容器”技术用于应用的微服务化改造,将自己产品的一些服务“微服务”化,构建基于云平台的SaaS化应用。

容器技术改造的难点

1. 技术的复杂性

容器技术应用的难点在于生产环境的实施及部署, 一般需要解决

  • 容器资源编排调度
  • 服务的自动发现及注册
  • 容器的监控及报警
  • 容器的扩展及收缩

这只是解决的部分问题,用户还必须去解决生产环境部署中怎样实现高可用部署及与公有云平台的集成问题。这使得Docker的生产化部署变得困难。

2. Docker编排框架的选型

许多人认为容器技术的价值在编排层,目前在容器的编排框架上主要的流派正在上演 “三国演义”包括,Google Kubernetes、Apache Mesos、Docker  DockerSwarm. Kubernetes,Mesos是目前市场上比较成熟的解决方案,占有较大的市场份额。DockerSwarm的优点是与Docker平台中的许多功能的集成,因为它平滑地内置于Docker平台中。上述三个编排框架都开放源代码,用户只需为技术支持服务付费。除了这些标准外还有许多初创公司也推出了自有的编排框架, 如Rancher使用Java语言开发了Cattle,它是Rancher实现的自有的一套基于Docker的编排引擎。众多的开源或自有的编排框架在不断发展,演进。这给客户的技术平台选型也带来极大的挑战。

Amazon EC2 Container Service(ECS)

为了降低容器平台生产部署的复杂性,Amazon ECS提供了一个平台来管理Docker容器。Amazon ECS是一项高度可扩展的高性能容器管理服务,您将不再需要安装、运维、扩展自己的群集管理基础设施。只需进行简单的 API 调用,您便可以启动和停止支持 Docker 应用程序,查询群集的完整状态,使用各种熟悉的功能,包括安全组、Elastic Load Balancing、EBS 卷和 IAM 角色。您可以使用 Amazon ECS 根据您的资源需求和可用性要求在您的群集中安排容器的置放。您还可以集成自己的或第三方的计划程序,以满足业务或应用程序的特定要求。Amazon EC2 Container Service 没有任何附加费用。您只需为您创建的用于存储和运行应用程序的 AWS 资源 (例如 EC2 实例或 EBS 卷) 付费。Amazon ECS的介绍,请参阅:https://aws.amazon.com/cn/documentation/ecs/

让我们来先看一个简单的Docker应用场景

客户有多套应用系统部署在云端,采用虚拟机隔离的方式,每套系统独占虚拟机资源,造成资源利用率不高。希望通过微服务化改造来提高云资源的利用效率及应用部署的敏捷性。改造的方法是从系统架构上分离应用层,使用Docker来封装应用层工作负载。采用Docker封装是微服务化改造最便捷的一种方式,因为对原有系统的代码修改少。降低了改造,迁移的成本。

将WEB,APP层直接封装成Docker容器运行。前端通过负载均衡传入流量,并负载均衡到Docker集群上。 需要实现服务的自动发现及注册,两级(Docker, EC2)自动扩展/收缩及容器的监控及报警。

下面我们就来介绍一下基于Amazon ECS的实现方法。

1. 应用层的封装

ECS提供了ECR(存储库),具有与Docker HUB一样的镜像存储管理功能.我们准备一个镜像来演示我们的应用层封装,这是一个Apache服务器的镜像,Dockerfile定义如下:

为了模拟三个不同的应用,我们对Apache服务器的配置做小小的更改:

在配置文件中新加了两个目录: app1, app2.并更改目录的初始页面的标题为目录名,这样当访问

提交更改

将镜像Push到ECR存储库,就得到了我们封装的应用层镜像

2. 创建服务

ECS有几个比较重要的概念。 任务服务集群

  • 任务就是您的应用程序的蓝图,是一个最基本的功能单元,包括构成应用程序的一个或多个容器,比如我们的案例中,封装的Apache镜像就是一个任务只包含了一个容器,但在实际案例中任务可能会有一个或多个容器,比如WEB容器,APP容器,它们共同组成一个任务。
  • 多个在一个容器实例或跨主机容器实例运行的任务就构成了服务,服务更像是一个应用的集群,ECS可以与ALB集成实现服务的自动注册及发现。通过使用动态端口映射选项,我们可以简单地注册一个服务到负载均衡器,而 ECS透明地管理Docker容器的注册和注销。我们还得到了传统负载平衡器的所有特性,如健康检查、连接保持和访问日志等。
  • 集群是EC2 实例的逻辑分组。Amazon ECS 从您指定的注册表中下载容器映像,并在集群内的容器实例上运行这些映像。

我们首先创建任务:

由于我们通过不同的URL路径来区分不同的应用,这里只需要创建一个任务定义

任务定义名称: taskweb

任务角色:

网络模式:        桥接

约束:

容器定义:

容器名称: dockerweb

映像: 772041933387.dkr.ecr.us-east-1.amazonaws.com/web-app:v1

内存限制:512M

端口映射:    主机端口:0  容器端口:80  协议:tcp

命令:    /usr/sbin/apache2,-D,FOREGROUND

然后创建集群:

集群名称: erp

实例配置:

预配置模型: 按需实例

EC2 实例类型: m4.large

实例的数量: 4

EC2 Ami Id: amzn-ami-2016.09.g-amazon-ecs-optimized [ami-275ffe31]

EBS 存储: 22

密钥对: martin

联网:

VPC: martin

子网: Pub1

Pub2

安全组: ECSSG

容器实例IAM 角色: ecsInstanceRole

创建负载均衡的ALB

名称: albdocker

模式: 面向internet

IP 地址类型: ipv4

侦听器: http:80

可用区

VPC: martin

AZ: pub1

pub2

分配安全组: ecssg
目标组名称: targetweb

协议: HTTP

端口: 80

运行状况检查

协议: HTTP

路径: /index.php
目标组名称: targetapp1

协议: HTTP

端口: 80

运行状况检查

协议: HTTP

路径: /index.php
目标组名称: targetapp2

协议: HTTP

端口: 80

运行状况检查

协议: HTTP

路径: /index.php

在集群中创建代表不同应用的服务:

服务名称:srvweb

任务定义: taskweb:8

集群: erp

任务数: 2

任务放置模板: AZ均衡放置

可选配置: Elastic Load Balancing

ELB 名称: albdocker

目标组名称: targetweb

路径模式: /

运行状况检查路径: /index.php
服务名称:srvapp1

任务定义: taskweb:8

集群: erp

任务数: 2

任务放置模板: AZ均衡放置

可选配置: Elastic Load Balancing

ELB 名称: albdocker

目标组名称: targetapp1

路径模式: /

运行状况检查路径: /index.php
服务名称: srvapp2

任务定义: taskweb:8

集群: erp

任务数: 2

任务放置模板: AZ均衡放置

可选配置: Elastic Load Balancing

ELB 名称: albdocker

目标组名称: targetapp1

路径模式: /

运行状况检查路径: /index.php

创建完服务后,srvapp1, srvapp1, srvweb已经自动完成在ALB的注册

实现了如下的架构:

集群的状态如下:

现在我们已经实现了微服务化的改造,通过不同的URL就可以访问运行在Docker集群上不同的应用程序。

3. 自动扩展/收缩及监控,报警

还有两级(Docker,EC2)自动扩展/收缩及容器的监控及报警的功能怎么实现呢?  ECS集成了Auto Scaling, Cloudwatch。在集群和服务中都有Autoscaling组,只需要简单配置就可以了,如下图:

看看是不是很简单呢?除了我们可以通过Portal来实现外,ECS还提供了API接口。那还等什么,赶紧去试试吧!

 

作者介绍

杨历,AWS解决方案架构师负责AWS中国合作伙伴生态系统的技术支持工作,致力于为合作伙伴提供AWS云计算方案架构的咨询和设计,上云迁移, 应用优化,培训等服务。在高可用,灾备解决方案,大规模并发应用架构,自动化运维,RDBMS,数据仓库,数据集成等方面有着广泛的设计和实践经验。在加入AWS之前曾在Oracle研发中心,Oracle中国,微软中国担任研发工程师,资深技术顾问等工作。

API Gateway 的Android SDK

1.  背景介绍

Amazon API Gateway 是一种完全托管的服务,可以帮助开发者轻松创建、发布、维护、监控和保护任意规模的 API。作为无服务器架构中的一个重要组成部分,已经有越来越多的用户熟悉并使用Amazon API Gateway。为了让大家更轻松地调用生成的API,Amazon API Gateway还提供了生成客户端SDK的功能,目前支持的客户端语言包括Java、JavaScript、iOS(Object-C)、iOS(Swift) 和 Android。

今天,我们通过一个具体的例子演示一下Android SDK,帮助大家快速上手,更方便轻松地使用Amazon API Gateway。

2.  配置部署 API

我们参考官方文档中的宠物店这个例子,配置一套代理HTTP接口的API。我们简化接口定义,以便突出Android SDK的使用,只做2个接口:

/pets

方法: GET

参数:

type String 宠物类型

page int 页码

/pets/{id}

方法: GET

参数: 无

2.1 创建 Model

我们的 API代理的后端接口还是这个宠物店的接口

http://petstore-demo-endpoint.execute-api.com/petstore/pets

我们先根据其返回结果创建相关的结果数据模型。

我们以Oregon区域为例,打开Amazon API Gateway管理控制台

https://us-west-2.console.aws.amazon.com/apigateway/home?region=us-west-2

点击 Create API

保持New API选中不变。

API name 填写petstore。

Description 填写A demo API for Android SDK.。点击 Create API按钮。

这时左侧导航链接会显示成 APIs > petstore> Resources。点击导航链接中的APIs > petstore> Models。这里已经显示有2个默认创建出来的Model。我们点击Create按钮再来创建一个。

2.1.1 Pets: 宠物列表的 Model

Model name* 填写 Pets

Content type* 填写 application/json

Model description 填写 A list of pets。

我们使用https://jsonschema.net/ 这个在线工具来生成Model schema。

Root ID 填写 pets。

我们直接访问 http://petstore-demo-endpoint.execute-api.com/petstore/pets

[
     {
         "id": 1,
         "type": "dog",
         "price": 249.99
     },
     {
         "id": 2,
         "type": "cat",
         "price": 124.99
     },
     {
         "id": 3,
         "type": "fish",
         "price": 0.99
     }
]

帖到 JSON 栏中,其它选项保持不变,点击Generate Schema按钮,结果生成在右侧的窗格中。

复制出来,粘贴到Model schema 格中即可。点击Creat Model按钮保存完成。

2.1.2 Pet: 宠物详情接口的 Model

点击Create按钮再来创建一个。

Model name* 填写 Pet。

Content type* 填写 application/json。

Model description 填写 A pet。

我们再使用https://jsonschema.net/ 这个在线工具来生成Model schema。

Root ID 填写 pet。

我们直接访问http://petstore-demo-endpoint.execute-api.com/petstore/pets/1

把得到的返回结果

{
    "id": 1,
    "type":
    "dog",
    "price":249.99
}

帖到 JSON 栏中,其它选项保持不变,点击Generate Schema按钮,结果生成在右侧的窗格中。复制出来,粘贴到Model schema 格中。点击Creat Model按钮保存完成。

2.2 配置API

2.2.1 宠物列表接口

左侧导航链接点击 APIs > petstore> Resources。保持最顶层的 / 为选中状态时,点击 Actions 下拉菜单,选择Create Resource。

Resource Name* 填写pets

Resource Path 自动填写了 pets。然后点击Create Resource按钮。

这时刚刚创建的/pets应该是选中状态,再点击Actions 下拉菜单,选择Create Method,在当时出现的方法菜单里选择GET,然后点后面的对号符确定。

然后在/pets – GET – Setup 页,Integration type 选HTTP。

Endpoint URL填写 http://petstore-demo-endpoint.execute-api.com/petstore/pets。

其它保持默认,点击Save按钮。

创建成功后,点击 Method Request 链接,在 Method Request配置页,点击URL Query String Parameters 展开之。

点击 Add query string 增加一个参数 type ,点击 Add query string 增加第二个参数 page。其它项保持默认。

点击Method Execution 链接返回,点击Method Response链接。在Method Response配置页,点击 200 左边的三角形,展开响应详情。在Response Body for 200下点击铅笔图标编辑之,把Model菜单下选择Pets,然后点击对勾图标保存。

点击Method Execution 链接返回,点击TEST链接,我们来测试一下。Query Strings 下面 type输入dog,page输入1,然后点击 Test按钮。右侧会显示出形如如下结果,表示这个API已经配置成功。

Request: /pets?type=dog&page=1

Status: 200

Latency: 271 ms

Response Body

[
     {
         "id": 1,
         "type": "dog",
         "price": 249.99
     },
     {
         "id": 2,
         "type": "dog",
         "price": 124.99
     },
     {
         "id": 3,
         "type": "dog",
         "price": 0.99
     }
]

2.2.2 宠物详情接口

左侧导航链接点击 APIs > petstore> Resources。保持最顶层的 /pets 为选中状态时,点击 Actions 下拉菜单,选择Create Resource。

Resource Name* 填写{petId}

Resource Path 自动填写了 –petid-,把它删掉,改成{petId}。然后点击Create Resource按钮。

这时刚刚创建的/{petId}应该是选中状态,再点击Actions 下拉菜单,选择Create Method,在当时出现的方法菜单里选择GET,然后点后面的对号符确定。

然后在/pets/{petId} – GET – Setup 页,Integration type 选HTTP。

Endpoint URL填写 http://petstore-demo-endpoint.execute-api.com/petstore/pets/{petId}。

其它保持默认,点击Save按钮。

创建成功后,点击 Method Request 链接,在 Method Request配置页,点击Request Paths展开之,确认这里已经有一条petId了。如果没有,请返回Create Resource 步骤检查。

点击Method Execution 链接返回,点击Method Response链接。在Method Response配置页,点击 200 左边的三角形,展开响应详情。在Response Body for 200下点击铅笔图标编辑之,把Model菜单下选择Pet,然后点击对勾图标保存。

点击Method Execution 链接返回,点击TEST链接,我们来测试一下。Query Strings 下面{petId}输入1,然后点击 Test按钮。右侧会显示出如下结果,表示这个API已经配置成功。

Request: /pets/1

Status: 200

Latency: 357 ms

Response
Body

{
     "id": 1,
     "type": "dog",
     "price": 249.99
}
2.3 部署API并生成SDK

2.3.1 部署API

左侧导航链接点击 APIs > petstore> Resources,Action 菜单点击 Deploy API,在弹出层里

Deployment stage 菜单下拉选 [New Stage]。

Stage name*填写 test。

Stage description 填写 test stage。

Deployment description 填写 first deploy。

点击 Deploy 按钮。部署成功后会跳转到test Stage Editor。可以看到

Invoke URL: 形如 https://abcde12345.execute-api.us-west-2.amazonaws.com/test

我们把这个 URL 后面接上前述配置过的API路径,再来测试一下。因为我们配置的没有AUTH难,所以可以简单的使用游览器直接访问,比如

https://abcde12345.execute-api.us-west-2.amazonaws.com/test/pets

可以得到宠物列表的JSON结果就表示部署成功了。同理可以再测试一下

https://abcde12345.execute-api.us-west-2.amazonaws.com/test/pets/1

2.3.1 生成SDK

在test Stage Editor页点击SDK Generation选项卡,Platform* 选Android。下面展开的内容,都和我们即将开发的Android App 包名有关,我们先定好包名为 com.example.petstore。相应的这里几项这样填写:

Group ID 填写com.example

Invoker package 填写完整包名com.example.petstore

Artifact ID 填写petstore

Artifact version 填写自己编排的版本号,比如1.0.0

然后点击Generate SDK按钮,弹出下载文件对话框,保存到本机即可。

这是一个ZIP压缩包,解压可以得到以下目录和文件。

│  build.gradle

│  LICENSE.txt

│  NOTICE.txt

│  pom.xml

│  README.md

└─src

└─main

└─java

└─com

└─example

└─petstore

│    PetstoreClient.java

└─model

Pet.java

Pets.java

PetsItem.java

先放在这备用。下面我们用 Android Studio 开始做 App 项目。

3.  Android 开发整合SDK

3.1 创建一个新的Android项目

我们打开Android Studio,新建一个项目,Application name 填写 Petstore,Company domain 填写 example.com,从而 Package name 成为com.example.petstore,和我们前面生成 SDK 时使用的包名保持一致。

然后一路点击Next ,使用默认配置(Empty Activity, Activity Name是MainActivity,Layout Name 是activity_main)创建一个项目。

3.2 整合API Gateway生成的Android SDK

使用 API Gateway生成的SDK其实有官方文档:

http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/how-to-generate-sdk-android.html

但是我们今天用更简便的方法,直接用build.gradle管理包,不需要按官方文档那样安装Maven再编译等。

项目创建起来后,我们在Project面板启用Project视图。

打开app/build.gradle,在 dependencies段添加以下几行,其实就是AWS SDK 的核心包,API Gateway的包以及用于解析JSON的gson包。

compile 'com.amazonaws:aws-android-sdk-core:2.4.+'
compile "com.amazonaws:aws-android-sdk-apigateway-core:2.4+"
compile 'com.google.code.gson:gson:2.8.0'

然后按提示点击Sync now同步项目。这时会下载上述3个依赖库,视网络状态可能需要一些时间。我们可以不用等待,继续后面的配置。

添加访问互联网权限, 打开/app/src/main/AndroidManifest.xml,在 <application 节点前面加上一行:

<uses-permission android:name="android.permission.INTERNET" />

我们打开之前下载的SDK压缩包解压的目录 src/main/java/com/example/petstore,把下面的文件和目录

│    PetstoreClient.java

└─model

Pet.java

Pets.java

PetsItem.java

复制到 Android项目中 com.example.petstore下面。完成的样子如下图所示:

3.3 编写代码用SDK实现调用API

我们使用Cognito进行验证,所以需要先创建一个Cognito 的 Federated identity pool,有关方法请参阅相关文档,这里不再赘述。

http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/identity-pools.html

在Android Studio里打开 MainActivity.java。先定义2个常量

然后我们定义一个testPet() 方法。

最后在onCreate()方法里加上如下代码,新开线程做HTTP请求,就可以了。

到这里例子已经完成,我们运行一个App,顺利地话可以看到如下的日志输出,我们已经可以顺利得到API接口的响应结果了。

这是在模拟器上运行的弹出层效果的截图。

例子的源码在下面 git 库的 Petstore 目录,供大家参考。

https://github.com/xfsnow/android

使用时请记得把MainActivity.java里的COGNITO_POOL_ID 换成你自己真实的值,以及new CognitoCachingCredentialsProvider 时要使用你的COGNITO_POOL_ID所在的region 值。

4.  小结

Amazon API Gateway生成的客户端SDK主要功能包括以下几点:

  • 根据我们为各个接口定义的Model批量创建好相应的Model类。
  • 通过 AWS 核心SDK实现HTTP请求的验证。
  • 封装HTTP请求和响应。
  • 把响应结果通过Gson库转换成方便Android Java使用的Model类。

这个简单的例子也体现出生成的客户端SDK便利了客户端应用程序的开发。

 

作者介绍:

薛峰,亚马逊AWS解决方案架构师,AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内和全球的应用和推广,在大规模并发应用架构、移动应用以及无服务器架构等方面有丰富的实践经验。在加入AWS之前曾长期从事互联网应用开发,先后在新浪、唯品会等公司担任架构师、技术总监等职位。对跨平台多终端的互联网应用架构和方案有深入的研究。

云计算转型成熟度模型: 为您的上云行动制定有效策略的指南

云计算转型成熟度模型为帮助企业制定自己的上云之旅提供了指南。该模型定义了确定成熟阶段的特征,在进入下一阶段前必须完成的每个阶段的转型活动,以及在组织成熟度的四个阶段(包括项目,基础,迁移和优化)中实现的结果。

想了解您的企业目前处于云计算转型之旅的什么位置吗?下表可以帮您确定您的企业目前处于哪个阶段:

一旦您确定了目前处于哪个阶段,就可以遵循 AWS 入云框架(AWS CAF) 的指导开始您的下一步旅程了。CAF 可以为企业的入云之旅提供一个经济且高效的计划 。AWS CAF将复杂的迁移计划过程分解为可管理的重点领域, 无论您是需要帮助定义组织的云计算路线图,做应用程序开发的转型或大规模部署任务关键型工作负载,我们都可以按照AWS Cloud Adoption Framework的原则提供规范性的指导。

来自全面入云客户的建议

除了AWS CAF,我们也想分享来自不同行业的客户的建议,这些客户都已经决定将所有系统都迁移到AWS云平台之上(all-in on the AWS Cloud)。

 

“我们在入云之旅的沿途学到的一件事就是文化变革,文化变革可以将人们团结起来坚定地沿着这个旅程走下去,并且真正完成组织转型,不仅要说服人们我们选择的是正确的技术,重要的是要赢得民心,这样才能圆满地完成如云之旅。”

迈克·查普尔,IT服务交付高级主管,Notre Dame


“我们选取了一些系统部署在AWS上,因为可以在Amazon内部进行快速配置, 这些系统运行得更快。 这是一个巨大的成功。 这种成功使我们对取得更多类似的成功产生了浓厚的兴趣。 所以在开始使用POC验证了AWS功能后,我们立即开始扩展到其他系统,直到完全迁移到AWS 。”

埃里克·盖革,IT的副总裁行动,芝加哥联邦住房贷款银行


“对我们来说,最重要的一件事就是,AWS的确能满足我们业务增长的需要。这不仅需要从能力角度来看,还要从区域扩张的角度来看。 这可以帮助我们把我们的业务模式推广到整个地区,最终跨越全球。”

马尔切洛·韦瑟尔勒,CEO,新加坡邮政

 

原文链接:https://aws.amazon.com/cn/blogs/publicsector/cloud-adoption-maturity-model-guidelines-to-develop-effective-strategies-for-your-cloud-adoption-journey/

译者:刘育新

AWS云架构高级咨询顾问,获得AWS解决方案架构师专业级认证和DevOps工程师专业级认证,专注于云迁移解决方案。目前已为多家跨国公司及本土公司、合作伙伴提供上云迁移的咨询设计和实施服务,在加入AWS之前有近20年的IT架构设计和项目管理经验。

使用Apache Kylin和Amazon EMR进行云上大数据OLAP分析

作者:史少锋 Kyligence资深架构师,Apache Kylin committer & PMC

 

公司简介

上海跬智信息技术有限公司 (Kyligence) 是由Apache Kylin (首个来自中国的 Apache 软件基金会顶级开源项目) 核心团队组建,专注于大数据分析领域创新的数据科技公司。Apache Kylin是近两年迅速崛起的开源分布式大数据分析引擎,它充分利用Hadoop MapReduce,HBase,Spark等成熟技术,对超大数据集进行预计算(构建Cube),从而当在线查询请求到来时,通过检索Cube以亚秒级低延迟返回结果,实现真正的大数据上的交互式分析。对于用户来说,Kylin屏蔽了底层平台的技术细节,用户只需要掌握多维模型、数据仓库、SQL等知识,就可以通过Kylin的Web界面进行建模,Kylin将自动生成任务对数据进行计算。计算完成后用户即可通过各类可视化工具连入Kylin进行分析,易用性非常高。今天,Apache Kylin已经在众多企业得到广泛应用,如今日头条等。

解决方案

Kyligence为各行各业的客户提供基于AWS公有云平台的Hadoop数据仓库解决方案。Elastic MapReduce (Amazon EMR) 是AWS推出的云上Hadoop方案,这一方案使得Hadoop的部署、监控、扩容变的非常灵活方便。Amazon EMR将计算和存储分离,可以使用S3做数据存储,用户可随需启停Hadoop而不用担心数据丢失,用户只需为运行时使用的资源付费,从而大大减少运维成本。以最近发布的Apache Kylin v2.0和Amazon EMR 5.5(海外版)为例,在AWS云上使用Kylin是非常简单快速的。

1. 启动EMR集群

如果您已经有在运行的,包含了HBase 1.x服务的EMR集群,那么这一步可以跳过,您可以使用现有集群进行此实验。

EMR的启动非常简单,登录AWS控制台,选择Amazon EMR服务,点击“Create Cluster”,选择最新的5.5版本,类型为HBase:

这里您可以选择合适的硬件配置;默认是m3.xlarge 3个节点,其中1个节点为master,另外两个为core节点。选择合适的EC2 key pair,随后点击“Create cluster”,AWS便会开始自动安装和配置Hadoop/HBase集群。

大约20分钟后,集群状态显示为“Waiting Cluster ready”,这意味着集群准备就绪可以使用了。

 

2. 安装Apache Kylin 2.0

Apache Kylin以Hadoop client的方式运行,使用标准协议/API与集群交互。您可以将它安装在集群的任意节点上,通常建议安装在一个单独的client节点上。在这里我们为了简单,就把Kylin安装在master节点上。

在AWS控制台上,您可以获取SSH到Amazon EMR的方法;点击“Master public DNS”旁边的SSH链接,即可获得,如下图所示:

SSH登录到master节点后,创建一个Kylin安装目录,下载并解压Apache Kylin 2.0的二进制包:

sudo mkdir /usr/local/kylin

sudo chown hadoop /usr/local/kylin

cd /usr/local/kylin

wget http://www-us.apache.org/dist/kylin/apache-kylin-2.0.0/apache-kylin-2.0.0-bin-hbase1x.tar.gz 

tar –zxvf apache-kylin-2.0.0-bin-hbase1x.tar.gz

如果下载速度较慢,可以至Kylin官网寻找并使用更接近的下载镜像。

由于一个已知的问题KYLIN-2587,您需要手动在Kylin里设置一个参数:用编辑器打开/etc/hbase/conf/hbase-site.xml,在其中寻找到“hbase.zookeeper.quorum”这个参数,然后将它以及它的值,拷贝到Kylin目录下的conf/kylin_job_conf.xml文件中。如下所示:

<property>
  <name>hbase.zookeeper.quorum</name>
  <value>ip-nn-nn-nn-nn.ap-northeast-2.compute.internal</value>
</property>

(注意请使用在您环境中真实获得的zookeeper地址)

3. 创建sample cube并启动Kylin

Kylin自带了一个小的数据集以及定义好的cube,只需要运行bin/sample.sh就可以将数据导入到Hive和HBase中:

export KYLIN_HOME=/usr/local/kylin/apache-kylin-2.0.0-bin

$KYLIN_HOME/bin/sample.sh

随后,就可以启动Kylin了:

$KYLIN_HOME/bin/kylin.sh start

大约若干秒以后,Kylin服务就会完成启动,在7070端口等待用户请求。

4. 修改安全组以允许访问Kylin

Amazon EMR默认创建了两个安全组,分别给Amazon EMR master和Amazon EMR core,要想从外网访问Kylin,需要设置相应规则;这里我们是将Kylin部署到了master节点,所以需要编辑master的安全组:

添加规则,允许7070端口从外面地址访问,为安全起见,建议只开放给最小的IP群,例如仅自己的地址:

接下来,在浏览器中输入http://<master-public-address>:7070/kylin,就会显示Kylin的登录页,使用默认账号ADMIN加密码KYLIN完成登录:

5. 构建Sample Cube

登录Kylin后,选择“learn_kylin”的项目,就会看到“kylin_sales”的样例Cube。此Cube模拟一个电商对其销售记录从多维度进行分析的场景,维度包括了时间(天,周,年)、区域、卖家、买家、商品分类等。

此时Cube只有定义,还没有加载数据,状态是“disabled”,需要触发一次Build。点击“Actions”,“Build”,然后选择一个时间范围,Kylin会以此条件从Hive加载数据进行一系列计算(样例数据已经导入到Hive):

所有的MapReduce, Spark, HBase操作,Kylin会自动生成并依次执行。大约七八分钟后,任务进度到100%构建完成,接下来此Cube就可以使用了:

6. 查询Cube

Cube构建完成后状态变更为“Ready”,可以使用SQL对其进行查询。虽然Kylin将原始数据构建成了多维Cube,但是对外的查询接口依旧是标准SQL,且表名、字段名依然是用原始的名称。这意味着用户一方面可以不用学习新的工具和语法,另一方面以前在Hive中执行的查询语句,基本上可以直接在Kylin中执行。

在Kylin主页点击“Insight”,切换到查询视图。此时页面的左导航处显示可以通过Cube进行查询的表和列。这里您可以尝试手写一条SQL,如下面的这条语句,按年计算交易总金额和记录数:

select YEAR_BEG_DT, sum(price), count(*) from kylin_sales inner join kylin_cal_dt on part_dt = cal_dt group by YEAR_BEG_DT;

点击“Submit”,Kylin随即执行并显示结果,如下图所示:

至此您已经完成了在AWS上运行Hadoop + Kylin的任务!从上图可以看出,Kylin的执行只耗费了0.61秒,接下来您使用可视化工具如Tableau, Excel, Saiku, Zeppelin, SmartBI等通过Kylin的ODBC/JDBC驱动连接Kylin server,体验交互式OLAP分析。

使用完以后,记得关闭Amazon EMR集群以节省费用。

成功案例

Strikingly基于AWS公有云和Kylin搭建了大数据解决方案。Strikingly (https://strikingly.com/)是一个简单、易用、美观的Web建站平台,产品中有一个面向用户的 Web Analytics Dashboard,它从各个维度以及不同时间尺度上展现了用户网站包括 Unique View, Geo Distribution 等数据,如下图所示。

用户数据查询的类型主要集中于对于各个维度数据的 group by 和 count distinct,都是比较耗时的查询操作。随着数据规模不断增长,以往的解决办法面临性能瓶颈。研究之后,Strikingly采用了Kylin + Amazon EMR的方案:每隔5分钟将原始数据备份到指定的S3 bucket上。通过预先定义好的Lambda函数对原始数据进行处理,转换成Kylin + Amazon EMR可以处理的数据格式,然后交由Kylin + Amazon EMR计算。通过引入Kylin,成功将数据查询的延迟从5~10秒降低到了1秒以内。当数据量增加的时候,可以通过Amazon EMR控制台动态添加core machine横向扩展服务,提高吞吐能力,这保证了可以对未来一段时间内可以预见的数据规模增加提供足够的技术支撑。

总结

借助于独有的分布式预计算技术,Apache Kylin比其它各类OLAP引擎能提供更高的查询性能和并发能力,并且随着数据量增加,查询延迟依旧可以保持在亚秒级(参考Kylin的SSB测试:https://github.com/Kyligence/ssb-kylin)。近些年云计算技术日趋成熟,越来越多的企业正在将大数据分析迁移到云上,AWS无疑是很热门的选择,而在选择大数据OLAP方案时,低延迟、高并发、可扩展是重要的考虑因素,Kylin结合Amazon EMR可以使云上的大数据分析变得简单而强大。
想要了解Apache Kylin的更多信息,您可以参考Apache Kylin官网(https://kylin.apache.org);如需要了解具体解决方案、商业版及专业服务,请联系Kyligence。

 

作者介绍

史少锋,Kyligence 技术合伙人&资深架构师。高级软件架构师,Apache Kylin核心开发者和项目管理委员会成员(PMC),专注于大数据分析和云计算技术。曾任eBay全球分析基础架构部大数据高级工程师,IBM云计算部门软件架构师;曾是IBM公有云Bluemix dev&ops团队核心成员,负责平台的规划、开发和运营。

如何使用Apache Mahout在 Amazon Elastic Mapreduce上构建推荐系统

本篇博文首先简单介绍了机器学习,并给出了Apache Mahout项目的背景情况以及推荐系统中需要注意的一些细节,然后我们会构建一个电影推荐系统并写一个简单的web服务来提供给客户端查询结果。最后我们会列出学习和参与到Mahout社区中的一些方法。

机器学习

机器学习植根于人工智能,这意味着机器学习工具具有对数据问题的认知和自动决策能力,但是目前的机器学习算法并不包含真正意义上的计算思想。尽管如此,机器学习经常采用某种类型的自动化决策,并采用迭代的方式来最大化或最小化与模型性能相关的特征值。

机器学习领域包含许多主题和方法,通常有分类、聚类以及推荐等。

分类是基于其他已知(独立)变量的组合来预测未知(从属)变量的过程,例如预测银行的客户流失或某项音乐服务的订阅者数量。在这两种情况下,我们使用关于客户的已知变量来预测他们停止使用相关服务的趋势。 下表列出了几个可能的已知变量:

变量类型 例子
用户信息 城市、州、年龄、性别
行为方式 银行客户消费习惯、用户播放特定艺术家音乐的频率
环境因素 银行客户的费用评估、用户播放音乐时遭遇缓冲的频率

在进行分类工作时,我们通常针对包含从属变量真实取值的数据进行训练,然后通过比较留存测试数据的预测值和真实值的差距来评估模型的性能。

聚类是寻找事物集合和分组的过程。在几何学中,我们经常讨论N维空间中的聚类向量。举个例子,下面图中在二维空间中展示了四对由向量代表的人,每一个维度是一种支出类别,在本例中是娱乐支出和杂项支出。

左上角图中显示两人的支出数量是相近的,但是消费习惯则完全指向了不同的方向,所以这两人是不相似的。基于同样的原因,左下图中的两人就拥有相近的消费习惯。当然通常我们在分类时引入的维度是多于两个的,甚至是成千上万的维度,并且从数学上可以推广到任意有限的维度空间。

聚类的关键在于我们用来定义相似性的距离度量或者测量方法。一些常用的方法如欧几里德距离、余弦相似度(相似向量间的夹角的余弦值接近0,反之则接近1)以及Tanimoto系数(两个向量相同点占两个向量所有点的比例)。

推荐系统通常接收数据输入,通常是基于行为的数据,然后预测用户最终会倾向于哪个选项。过去十年推荐系统的流行很大程度上得益于Netflix Prize的推广,它在2006年到2009年间奖励给那些击败Netflix现有推荐系统的人。

推荐系统的性能以预测值和真实值之间的比较来得出,在生产系统中通常还结合A/B测试来进行优化。

Apache Mahout

大多数的Hadoop发行版本都包含了Apache Mahout,这其中就有Apache Bigtop和EMR。本质上Apache Mahout是一个机器学习的算法库,包含分类、聚类以及推荐等多种工具,可以被用于计算相似性和生成用户推荐等目的。Mahout使用Hadoop的Mapreduce框架来执行具体的计算过程,现在也支持新的计算框架,比如UC Berkeley’s AMPLab的Spark。

Mahout第一次bug修复发生在2008年1月,直到本篇博文写就之时,总共有1700个Jira tickets,其中54个依然是open状态。时至今日,社区中的贡献者和用户仍然在不停地针对代码和文档进行优化工作。

推荐系统

大多数人感觉到推荐系统的存在是从网页开始的,后台推荐系统会将结果显示在用户浏览网页的某一部分之上。这些包含推荐结果的网页帮助用户找到想买的商品、想听的音乐、想看的电影、想雇佣的人,甚至是约会的对象。

GroupLens研究团队于上个世纪90年代早期构建了USENET文章推荐系统,自此推荐系统技术开始了快速发展。随着时间的推移,推荐对象本身也发生了变化,除了新的文章,还有大量的在线行为值得分析,比如用户在网页上的点击链接行为;点赞和档案浏览;购物行为以及听音乐和看电影。

这些发展提供了基于用户行为进行推荐的可能性,能够帮助我们进一步改进推荐系统。 在USENET示例中,用户扫描作者和主题的文章列表,点击,阅读和关闭文章。 在线零售网站,购物者搜索产品,浏览产品页面,点击照片放大,阅读评论,并将产品添加到购物车。 在流媒体音乐网站上,音乐消费者搜索艺术家或专辑,播放曲目,通过曲目快速播放,并将艺术家添加到收藏夹,流媒体视频网站的工作方式类似。 在专业或个人联系的社交网站上,用户搜索并与其他人互动。 每个示例包括用户以某种方式与某些类型的项目进行交互的用户。

构建推荐系统

为了说明如何在EMR上通过Mahout建立分析型作业,我们决定构建一个电影推荐系统。我们会使用用户打分的电影评分数据,这些数据由GroupLens团队提供。推荐系统最终会为每一位用户推荐自己最感兴趣的电影。

1.  登录AWS账户

2.  配置EMR ruby客户端

3.  启动EMR集群

./elastic-mapreduce --create --alive --name mahout-tutorial --num-instances 4
--master-instance-type m1.xlarge --slave-instance-type m2.2xlarge --ami-version 3.1 --ssh

4.  获取电影评分数据

wget http://files.grouplens.org/datasets/movielens/ml-1m.zip

unzip ml-1m.zip

处理rating.dat文件,用”,”替换”::”,取出每一行的前3列

cat ml-1m/ratings.dat | sed 's/::/,/g' | cut -f1-3 -d, > ratings.csv

上传处理后的评分数据到HDFS

hadoop fs -put ratings.csv /ratings.csv

5.  启动推荐作业

mahout recommenditembased --input /ratings.csv --output recommendations --numRecommendations 10
--outputPathForSimilarityMatrix similarity-matrix --similarityClassname SIMILARITY_COSINE

6.  查看结果数据

hadoop fs -ls recommendations

hadoop fs -cat recommendations/part-r-00000 | head

你应该看到类似下面文件的输出结果

User ID           (Movie ID : Recommendation Strength) Tuples

35        [ 2067:5.0, 17:5.0, 1041:5.0, 2068:5.0, 2087:5.0, 1036:5.0, 900:5.0, 1:5.0, 2081:5.0, 3135:5.0 ]

70        [ 1682:5.0, 551:5.0, 1676:5.0, 1678:5.0, 2797:5.0, 17:5.0, 1:5.0, 1673:5.0, 2791:5.0, 2804:5.0 ]

105     [ 21:5.0, 3147:5.0, 6:5.0, 1019:5.0, 2100:5.0, 2105:5.0, 50:5.0, 1:5.0, 10:5.0, 32:5.0 ]

140     [ 3134:5.0, 1066:5.0, 2080:5.0, 1028:5.0, 21:5.0, 2100:5.0, 318:5.0, 1:5.0, 1035:5.0, 28:5.0 ]

175     [ 1916:5.0, 1921:5.0, 1912:5.0, 1914:5.0, 10:5.0, 11:5.0, 1200:5.0, 2:5.0, 6:5.0, 16:5.0 ]

210     [ 19:5.0, 22:5.0, 2:5.0, 16:5.0, 20:5.0, 21:5.0, 50:5.0, 1:5.0, 6:5.0, 25:5.0 ]

245    [ 2797:5.0, 3359:5.0, 1674:5.0, 2791:5.0, 1127:5.0, 1129:5.0, 356:5.0, 1:5.0, 1676:5.0, 3361:5.0 ]

280     [ 562:5.0, 1127:5.0, 1673:5.0, 1663:5.0, 551:5.0, 2797:5.0, 223:5.0, 1:5.0, 1674:5.0, 2243:5.0 ]

每一行的第一个数字是用户ID,后面的键值对是每一部电影的ID以及它的推荐得分。本例中推荐得分是5分制,从结果集(10个推荐结果)可以看出针对每位用户的推荐电影都是满分,所以我们应该进一步计算超过10个推荐结果的情况。

构建推荐服务

接下来我们要通过一个web服务来查看特定用户的推荐结果

1.  安装Twisted,Klein和Redis的Python模块

sudo easy_install twisted

sudo easy_install klein

sudo easy_install redis

2.  安装Redis并启动服务

wget http://download.redis.io/releases/redis-2.8.7.tar.gz

tar xzf redis-2.8.7.tar.gz

cd redis-2.8.7

make

./src/redis-server &

3.  构建一个web服务负责加载推荐结果数据到Redis并响应查询需求

把下面的代码放入一个文件内,如“hello.py”

from klein import run, route

import redis

import os

 

# Start up a Redis instance

r = redis.StrictRedis(host='localhost', port=6379, db=0)

 

# Pull out all the recommendations from HDFS

p = os.popen("hadoop fs -cat recommendations/part*")

 

# Load the recommendations into Redis

for i in p:

 

# Split recommendations into key of user id

# and value of recommendations

# E.g., 35^I[2067:5.0,17:5.0,1041:5.0,2068:5.0,2087:5.0,

#       1036:5.0,900:5.0,1:5.0,081:5.0,3135:5.0]$

k,v = i.split('t')

 

# Put key, value into Redis

r.set(k,v)

 

# Establish an endpoint that takes in user id in the path

@route('/<string:id>')

 

def recs(request, id):

# Get recommendations for this user

v = r.get(id)

return 'The recommendations for user '+id+' are '+v

 

 

# Make a default endpoint

@route('/')

 

def home(request):

return 'Please add a user id to the URL, e.g. http://localhost:8080/1234n'

 

# Start up a listener on port 8080

run("localhost", 8080)

4.  启动web服务

twistd -noy hello.py &

5.  使用用户ID 37测试服务

curl localhost:8080/37

6.  你应该看到如下的类似输出

针对37号用户的推荐结果是

[7:5.0,2088:5.0,2080:5.0,1043:5.0,3107:5.0,2087:5.0,2078:5.0,3108:5.0,1042:5.0,1028:5.0]

7.  当你完成所有操作时,别忘了关闭EMR集群

./elastic-mapreduce --list

 

j-UNIQUEJOBID      WAITING        ec2-AA-BB-CC-DD.compute-1.amazonaws.com         mahout-tutorial

 

./elastic-mapreduce --terminate j-UNIQUEJOBID

8.  确认是否关闭

./elastic-mapreduce --list

 

j-UNIQUEJOBID     SHUTTING_DOWN     ec2-AA-BB-CC-DD.compute-1.amazonaws.com         mahout-tutorial

几分钟之后

./elastic-mapreduce --list

 

j-UNIQUEJOBID     TERMINATED     ec2-AA-BB-CC-DD.compute-1.amazonaws.com         mahout-tutorial

总结

恭喜!你已经构建了一个简单的推荐系统,其中包含了开发更复杂推荐系统的关键模块:

  • 采集原始数据
  • 进行数据预处理
  • 运行分析作业
  • 分析结果数据
  • 通过web服务发布结果数据

你可以从以下几个途径进一步探索本示例,比如替换SIMILARITY_COSINE为VectorSimilarityMeasure中的另外一个度量,以此来通过不同的距离度量而不是余弦相似性来判断两个用户是否喜欢同一类型的电影。当然你还可以让推荐结果变得更容易解读,将电影ID和电影名字以及介绍关联在一起返回给查询请求是一个不错的主意。

Mahout还包含了其他的推荐算法,其中还包括和Netflix奖相关的算法:交替最小二乘法(ALS)。该项目还包含了用于分类和聚类的算法,这些算法被封装为一个个的工具,从命令行就能访问和使用。

Mahout社区倡导积极与用户和开发人员合作。 您可以通过在EMR上尝试使用Mahout,或者通过下载自己的副本并在本地或在自己的集群上运行Mahout。 您可以提交有关如何使用工具的问题,并向用户邮件列表中提出可能的错误,您还可以在这里讨论开发人员邮件列表中的问题,从而为开发做出贡献。 如果您遇到要更正的错误或者新的功能要更新到项目中,请您在项目Jira页面上提供故障单并说明具体问题。如果您想要在页面顶部看到创建问题按钮,请确保创建一个帐户。

 

作者介绍

刘磊,曾供职于中国银联电子支付研究院,期间获得上海市科技进步一等奖,并申请7项国家发明专利。现任职于AWS中国专业服务团队,致力于为客户提供基于AWS服务的专业大数据解决方案、项目实施工作以及咨询服务。

AWS WAF – Web 应用程序防火墙初体验

1. 背景介绍

AWS WAF ,全称是Web Application Firewall ,即Web 应用程序防火墙,可以帮助用户保护Web 应用程序免受常见的Web漏洞攻击。通常这些攻击会损害Web应用的安全性,影响可用性,消耗过多的资源,增加成本,还降低响应速度和用户体验。

WAF可以让用户创建定制规则进行流量筛选,阻隔恶意访问,保障正常请求。比如,可以根据 IP 地址、HTTP 标头、HTTP 正文或 URI 字符串来筛选 Web 请求,这样便能阻止诸如 SQL 注入或跨站点脚本等常见攻击模式。

和其它诸多 AWS 服务一样,WAF 的所有功能也可以通过AWS管理控制台或API进行配置。这便利了用户团队的不同角色,不论是开发人员、DevOps工程师还是安全审查专家都可以方便使用,从开发到部署的全过程系统地管理Web应用的安全。

WAF 和AWS的Web相关服务紧密结合,目前支持CloudFront和Application Load Balancer。AWS WAF 让您能够创建集中化的规则集合,而后部署到多个网站上。用户通常有多个网站和 Web 应用程序,使用WAF可以只定义一组规则并复用于多个应用程序上。WAF也是AWS全托管的服务,用户无需担心其扩展和可用性。只需在正确的资源上启用WAF,无需部署任何额外软件即可完成部署。并且只需要部署一次,即可以全球的边缘节点全部生效。

作为防火墙,WAF当然也少不了监控和报警。WAF 可以让用户设置条件来监视哪些请求。提供准实时地 Web 流量监测报告,并以此信息来创建新的规则或使用 Amazon CloudWatch 的进行报警。

今天,我们以WAF实现防盗图这个常见应用场景,帮助大家快速上手,体验其强大和便捷。

2. 部署与配置WAF

现在主流的Web应用都使用了无cookie域名来加速静态内容,我们这里也进行类似的部署,如网站域名是 example.com,图片服务使用另一个域名 example_img.com。禁止盗图的效果可以从下表来概述。

调用图片的域名 响应效果
*.example.com 200 OK
其它非法域名 403 Forbidden

WAF目前支持CloudFront和Application Load Balancer,我们这个例子中防盗图要保护的是图片服务器,这里我们所使用的就是CloudFront提供的CDN。我们用一个现成的CloudFront分发来作演示,使用AWS 的DNS服务Route 53 配置了域名 imgtest.simg.cf。为了演示效果,我们还使用EC2配合搭建了一个简单的Web服务器,也使用Route 53 配置了域名allow.snowpeak.cf。有关EC2、ClourFront和Route 53的使用这里不再赘述,请参见各自相关文档。

现在已有了具体的2个域名,我们要实现前述的禁止盗图效果,把规则具体化为以下控制流程:

  • Referer请求头包含“://allow.snowpeak.cf/”(不写具体的协议更简单,可以同时支持HTTP和HTTPS请求)则允许访问。
  • 其它情况下禁止访问。

登录AWS WAF管理控制台

https://console.aws.amazon.com/waf/home

在左侧导航菜单中点击AWS WAF > Web ACLs,来到Web ACLs页,点击Create Web ACL按钮会前进到Set up a web access control list (web ACL)向导。

如果前进到Concepts overview页,直接点击右下角Next按钮,前进到Step 1: Name web ACL页。

2.1 创建 Web ACL

1.  Web ACL name 输入ImgAntiHotLink。

2.  CloudWatch metric name 会自动填上ImgAntiHotLink。

3.  Region保持默认的Global (CloudFront)不变。

4.  AWS resource to associate 点击下拉,选择我们已有的CloudFront分发。

5.  点击Next按钮。

2.2 创建字符串匹配条件

在Step 2: Create conditions页,下拉到页面最底部,找到String match conditions,点击其右边的Create condition 按钮创建字符串匹配条件。

在弹出的Create string match condition层中:

1.  Name栏填写referer_domain。

2.  Region保持默认的Global (CloudFront)不变。

3.  Filter settings 部分,Part of the request to filter on 在菜单中选择Header,在随后出现的 Header 栏选择Referer。

4.  Match type选Contains。Transformation选Convert to lowercase。

5.  Value to match填写://allow.snowpeak.cf/。

6.  点击 Add filter按钮,最后点击右下角Create按钮完成创建。

创建完成后弹层关闭,回到Step 2: Create conditions页,点击右下角Next按钮。

2.3 创建规则

在Step 3: Create rules页,Add rules to a web ACL 下点击右边的Create Rule按钮,在弹出层Create Rule 里如下填写:

1.  在 Name 中填写AntiHotlink,CloudWatch metric name 会自动填写上相同的值。

2.  Region保持默认的Global (CloudFront)不变即可。

3.  在 Add Conditions 下,When a request 下的3个菜单依次选择

  • does
  • match at least one of the filters in the string match condition
  • referer_domain

4.  点击“Add condition”,最后点击右下角 Create 按钮,完成创建。

创建完成后,弹层关闭,回到Step 3: Create rules页。

把 AntiHotLink 这条规则的Action 选 Allow。

Default action 选Allow all requests that don’t match any rules

点击右下角的Review and create 按钮。

最后来到Step 4: Review and create页,点击右下角Confirm and create 按钮完成创建。

3.4 查看配置结果

这时我们可以到 AWS WAF 下各个分项去看一下配置的结果,看看上述向导帮我们在Web ACLs、Rules、和 String matching下分别建立了记录并且做了关联。
在左侧导航菜单中点击AWS WAF > Web ACLs,来到Web ACLs页。如果你从其它区分region 的服务管理页来到AWS WAF页,可能出发现这里没有记录,提示“You don’t have any web ACLs in XXX region. Choose Create web ACL to get started.”,不用惊慌,是因为上面的Filter菜单默认选中了你常用的region。我们刚刚创建的WAF是不区分region的,所以在这里点选“Global (Cloudfront)”,然后我们创建的记录就可以显示出来了。

再依次点击AWS WAF > Rules和Conditions > String matching,查看到各有一条记录。

前述的向导已经帮我们创建了这些具体的分项,一方面方便我们可以逐个分别调整,另一方面,也方便我把把条件和规则复用到不同的站点上。

WAF 配置完毕后立刻生效,不用像 CloudFront 分发那样还需要等待一段时间。这一点在发生Web攻击时用于及时应对是很有意义的。

3. 效果验证

我们做一个简单的 HTML 页面,里面引用我们的图片文件,然后把它部署到我们在EC2上的Web站点上。当我们使用正常的域名访问时,比如https://allow.snowpeak.cf/imgtest.htm,图片都可以正常加载出来。下图是带 Firebug请求详情的截图。

我们再使用EC2原始的域名来访问,http://ec2-xxxx.compute.amazonaws.com 就可以模拟非法域名引用我们的图片。可以看到图片都没有显示出来。下图是带 Firebug请求详情的截图。

4. 监控

WAF提供方便的常用监控,在WAF管理页面就可以查看,还可集成到CloudWatch,使用更丰富的指标和图表。在左侧导航菜单中点击AWS WAF > Web ACLs,来到Web ACLs页,在这里点击咱们已创建的这条记录ImgAntiHotLink,页面右侧就会显示出监控详情。这个请求的数据归集有几分钟延迟,新建的ACL稍等一会可以看到结果。

首先是请求次数的图表。

右下方是请求的详情。

这里点击“View the graph in CloudWatch”,还可以跳转到CloudWatch 去看更多详细的日志和图表。

更为强大的是,可以结合CloudWatch Alarm创建报警,比如当拦截的非法请求数高于一定阈值时通知我们,方便我们再人工干预。操作方法和其它Alarm一样,具体可参考Alarm的相关文档,这里不再赘述。

5. 小结

今天我们只是通过一条规则实现了一个常见场景的配置。实际的防盗图还要考虑到更多因素,比如允许移动端App访问,允许特定搜索引擎访问图片以便收录。我们可以灵活使用String matching和Rule,配置出各种丰富的规则和效果,满足各种访问控制的需求。

在Web应用开发领域,防盗图是只个常见的小需求,在自建数据中心如果要实现防盗图,需要在所有CDN节点上逐个配置,开发和运维都很繁琐。在AWS上我们使用WAF可以非常方便的进行配置,还能享受其天然的高可用。对于各种Web攻击的防御,WAF更是得心应手的工具,为我们Web应用保驾护航。

 

作者介绍:

薛峰,AWS解决方案架构师,AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内和全球的应用和推广,在大规模并发应用架构、移动应用以及无服务器架构等方面有丰富的实践经验。在加入AWS之前曾长期从事互联网应用开发,先后在新浪、唯品会等公司担任架构师、技术总监等职位。对跨平台多终端的互联网应用架构和方案有深入的研究。

 

通过AWS Config 管理AWS服务配置

在之前的一篇安全相关的文章《从永恒之蓝开始,安全防范没有结束》中,提到通过AWS Config自动规范AWS服务的安全、合规方面的配置。

为更好遵从各行业的合规要求,构建安全的IT环境,企业的安全团队一般都会在明确安全/管理边界的前提下,选择相关安全框架,用对应的风险评估方法梳理出符合自身业务特点的安全模型。根据安全模型,通常也会用各种文档标准化抽象为各种管理策略,例如可能包含以下常见的内容:

  • 用户权限策略
  • 访问控制策略
  • 服务器安全策略
  • 应用接入策略
  • 网络分区策略
  • 数据传输策略
  • 数据存储策略
  • 备份归档策略
  • 日志记录策略
  • 审计管理策略

……….

在实际的应用场景中,标准策略可能会因为业务的变化或管理方式的变化动态调整,如何持续评估和审核在AWS云端的资源配置的合规性是否与企业规划一致?如何帮助用户在云端更好的实现变更管理,安全分析甚至自动修正不合规的配置 ?这种场景下,可以考虑用AWS Config 服务来帮忙。

一、AWS config 是什么

AWS Config 是一项托管服务,借助 Config您可以盘点AWS 资源、查看配置更改以及 AWS 资源之间的关系并深入探究详细的资源配置历史记录。使用 Config,还能通过自定义规则来定义所需的资源配置、内部最佳实践和指南,并依据这些规则评估您记录的配置。

AWS Config的主要应用功能:

  • 评估您 AWS 资源配置是否具备所需设置。
  • 获得与您的 AWS 账户关联的受支持资源的当前配置快照。
  • 检索您的账户中的一个或多个资源配置。
  • 检索一个或多个资源的历史配置。
  • 在资源被创建、修改或删除时接收通知。
  • 查看不同资源之间的关系。例如,您可能想要找到使用特定安全组的所有资源

AWS Config工作原理

更多AWS Config的信息可以参考https://aws.amazon.com/cn/config/

二、 AWS config 配置测试

为了更好了解AWS Config的工作过程,以下 将以AWS安全组的配置监控为例做一个简短测试 。

1. 测试场景:

  • 一个为web服务器配置的安全组,该安全组策略只允许对Internet开放HTTP和HTTPS两个端口;
  • 配置AWS Config 规则,当该安全组配置规则中添加了其他端口时,AWS Config 自动记录,并触发修复机制自动删除新加入的不合规的配置。

2. 配置过程

a. 权限准备。为成功配置AWS Config 规则,需要创建IAM 角色,授予 AWS Config 权限,使其可以访问Amazon S3 存储桶、Amazon SNS 主题,获取受支持的 AWS 资源的配置详细信息。IAM内置了一个AWSConfigRole的托管策略 。

新建一个IAM Role 命名为awsconfigrole, 可以直接附加该策略:

另外,测试过程中将使用lambda自动对安全组执行安全组操作,cloudwatch log操作,也需要建立好对应的IAM role并编辑策略赋予对应的权限,在测试中该IAM role为:awsoncifgec2security

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Effect": "Allow",

            "Action": [

                "logs:CreateLogGroup",

                "logs:CreateLogStream",

                "logs:PutLogEvents"

            ],

            "Resource": "arn:aws:logs:*:*:*"

        },

        {

            "Effect": "Allow",

            "Action": [

                "config:PutEvaluations",

                "ec2:DescribeSecurityGroups",

                "ec2:AuthorizeSecurityGroupIngress",

                "ec2:RevokeSecurityGroupIngress"

            ],

            "Resource": "*"

        }

    ]

}

b. 配置AWS Config Setting。在AWS 控制台,打开 AWS Config ,具体过程可以参考:http://docs.aws.amazon.com/zh_cn/config/latest/developerguide/gs-console.html

在本测试过程中,我们选择资源类型为SecurityGroup:

在配置过程中,指定一个存储桶保存日志,并指定预先为AWS Config 的IAM Role ,当然也可以在这个步骤选择新建角色:

在上述页面中,可以选择是否通过SNS 启用通知将信息流式传输到 Amazon SNS 主题,发送配置历史记录传输、配置快照传输和合规性等通知。

在Resources页面中验证一下,评估的对象是否能正常的筛选出来,本例中我们是对测试的安全组进行查找:

c. AWS Config 规则配置。AWS Config提供一些内置的规则,也支持自定义规则创建。在前文中提及测试的背景中需要通过自动机制保证安全组规则符合设定的合规配置,我们将通过lambda完成该步骤。在创建规则的过程中,按向导设置规则名称,点击新建lambda功能按钮:

在lambda创建过程中,选择blank blueprint 并为函数指定runtime为python2.7 ,将准备好的代码保存在s3(可以在github中找到相关代码参考,比如https://github.com/awslabs/aws-config-rules )并上传。

Lambda函数主要完成以下工作:

  • lambda函数中按照要求只开启tcp 80 和tcp 443端口;
  • 如果有其他端口添加到配置规则中将被删除,最终保证安全组的配置规则条目中只有tcp80和tcp443相关的配置;
  • 相关的操作将记录在cloudwath logs中。

在创建过程中,为lambda指定对应的IAM Role.

lambda创建完成后,需要在AWS Config 规则页面中指定Lambda ARN,  配置触发器。本例中,当安全组配置发生变化时即触发对安全组的评估,也可以配置按照时间周期的评估对象。 另外,为了详细记录评估信息,为规则启用debug级别的记录。

 

AWS config  规则后,当前的安全组配置将自动被评估。

d. 验证。为触发AWS Config 对安全组的评估, 我们在对应的安全组规则中除tcp 80 和tpc443,额外新添加tcp445 端口。在cloudwathc logs中创建了logs group,可以进行相关日志查看:

在日志中可以清楚看到对安全组有revoking的行为,操作的端口正是额外添加的tcp445 , 并且最终将安全组只开启tcp80 和tcp443 端口。

三、进一步讨论

在上述测试过程中,大致可以了解AWS Config的工作机制和配置流程,下面进一步对一些场景的应用场景做进一步说明。

资产发现

AWS Config 不仅会发现账户中的资源、记录其当前配置并捕获对这些配置所做的任何更改,Config 还会保留已删除资源的详细配置信息。所有资源及其配置属性的完全快照在您的账户中提供完整的资源库。

持续安全分析

AWS Config 提供的数据可使您持续监控您的资源配置情况,并评估这些配置是否具有潜在的安全弱点。对您的资源配置进行更改,将触发系统发送 Amazon Simple Notification Service (SNS) 通知,这些通知可发送给您的安全团队,以便他们查看通知并采取相应措施。发生潜在的安全事件后,您可以使用 Config 查看资源的配置历史记录并检查您的安全状况。

正如测试过程中展示,企业IT团队只需明确制定相关的策略,配置AWS Config规则,AWS Config提供了托管规则和自定义规则,能满足各种就能持续监控相关的安全标准是否合规。借助 AWS Config,利用 AWS Lambda 中的自定义规则将合规性要求编制成代码,这些代码会定义资源配置内部最佳实践和指南。您可以使用 Config 自动评估您的资源配置和资源更改,从而确保整个 AWS 基础设施实现持续合规性和自主监管。通过这个机制,为企业的安全自动化提供了一个可行选项。

变更管理

在创建、更新或删除资源时,AWS Config 会将这些配置更改流式传输到 Amazon Simple Notification Service (SNS),如此便会收到所有配置更改通知。根据通知机制也可以考虑引入基于事件触发的机制,进一步集成各个管理环节。

在AWS Config按照既定规则完成评估后,可以在规则的详细信息中查看到具体的变更事件记录:

审计

AWS CloudTrail 将记录账户上的用户 API 活动,将保存有关 API 操作的完整详细信息,如发起人的身份、该 API 调用的时间、请求参数和 AWS 服务返 。AWS Config 与AWS CloudTrail 集成 ,回答“谁进行了修改此资源的 API 调用?”例如下图, 使用集成的 AWS CloudTrail 信息,可以发现是哪个用户错误配置了安全组。

综合上述讨论,企业内部资产管理团队可以清楚明确当前在AWS云端的数字资产,安全团队可以将严格制定的安全体系持续的在云端自动化运行,任何相关的变更和配置管理都能详尽的记录,方便后续的审计。

更多关于AWS Config的一些常见问题可参考:https://aws.amazon.com/cn/config/faq/

作者介绍

李艺明

AWS解决方案架构师,负责基于AWS的云计算方案架构规划和咨询。在企业数字化转型,物联网和大规模并发场景有广泛的规划和实践经验。拥有超过10年的IT从业经验,为各种规模的企业客户提供IT项目实施和顾问服务。在加入AWS之前,服务于微软担任解决方案工程师,负责Windows Azure方案和架构设计,在此之前负责企业私有云和企业协同应用系统的架构规划和设计。