如果你曾经想过“应该有一个实现这种功能的应用”,并憧憬有谁能够为你开发一个就好了,现在我们有一个好消息,那个人找到了,就是你自己。
Web应用可以是非常强大、高效和易扩展的,但却不应该是复杂的。简单就是Web应用的一大优势。你可以利用这种优势来搭建自己的解决方案,实现自己的创意。一旦了解所有模块是如何搭建到一起的,你就能开发出想要的应用了。
本书是一本实用教程,将会演示一种无服务器的方案来搭建Web应用。使用这个方案,大部分运维方面的问题就不需要你自己操心了,而且也省去运行服务器的费用。你能集中时间和精力开发想要的应用,而让其他人去考虑业务发展带来的应用上线、配置、升级、扩展服务器等问题。使用多层Web框架、自动生成的代码或者拷贝模板,这些方法并不会带来这样的好处。等我们一起学完本书,你就会知道如何通过移除部分代码和消除中间层来交付更好的应用。
为了能够快速演示开发过程,我们将使用一个预设好的工作空间,里面加载了搭建完整Web应用必需的所有模块。首先,我们会完成一个单页应用,用JavaScript、HTML和CSS代码来实现原来在服务器端实现的逻辑。我们将根据Web标准,深入挖掘单页Web应用的必要功能,从零开始搭建,从而了解它们的运行机制,保证这种设计能符合我们应用的要求。当仅凭Web标准不能完全实现需求时,我们会使用jQuery来填补差距。最后,我们会使用测试优先的方法来渐进式开发,以保证单页应用的可测试性。
为了降低中间层成本并确保我们的应用能供上百万的用户使用,我们使用Amazon Web Services(AWS)作为无服应用的后端。你将看到如何使用高可用、高可扩展、更便宜、更易维护的云服务来替换掉传统Web应用的服务器、数据库和负载均衡器。我们将讨论在开发此类应用时会碰到的一些安全性问题,并会介绍随着应用业务的扩展可能会用到的其他技术和工具。
我希望能够让你看到新的可能性。以前非常费时费钱的应用开发或许能变成一个人在一两天内就可以完成的事情。随着技术进步和个人能力的提升,更多的梦想将会实现。一旦理解了这些技术的发展,你就会发现从前因为太难而几乎无法实现的目标,现在可以借由新途径来达成。读完本书,你将学会将创意变成真实应用所需的技能。
无服Web应用
在传统Web应用中,服务器是系统不可缺少的组成部分。尽管有时候服务器的前面还有负载均衡器或者专用Web服务器,但完成大部分工作的还是应用服务器。它完成一个应用所有的必要功能,包括存储用户数据、进行安全认证、控制流程等。应用的页面大部分仅仅只是为后端提供界面而已,尽管也会涉及一些控制导航的功能。使用这种许多人称之为多层架构的传统方式,系统一般会由浏览器、应用服务器和多个后端服务构成(见下图)。
使用无服的方式,可以移除所有这些层次架构,达到更直接的实现。与其仅仅把网页客户端当作应用服务器的界面展示,不如构建一个单页Web应用在浏览器中实现应用逻辑。这意味着你只需要一个简单的静态网页服务器,所有的交互都只不过是应用内容的传输而已,浏览器就像是一个应用容器。这样,最终的设计就是移除传统Web应用架构中所有的中间层次,允许浏览器直接连接到它所需要的服务上。
使用Facebook、Google和Twitter之类的OAuth 2.0身份认证服务商提供的服务,无须保存用户密码就可以创建用户身份。如果要存储数据,你可以在浏览器端直接使用Amazon DynamoDB之类的服务。在浏览器中无法执行的函数都可以使用Amazon Lambda微服务或者其他专门的Web服务来处理。除了能够简化架构,这种切换到Web服务作为后端的方式,还能让应用获得这些服务与生俱来的可用性和可扩展性优势。
你可能会好奇到底发生了什么,使这种方式成为可能。为什么现在在一个Web应用中,中间层的应用服务器变得可有可无呢?答案是,自从2015年以来,类似Amazon这样的云服务提供商开始对外提供服务的API,这使得无服务器的方式成为可能,Amazon本身也为如何使用他们的工具和基础设施提供了最好的示范。
基于Web标准搭建一个单页Web应用,而不是使用服务器端Web框架来完成,我们可以快速应用一些新兴技术。例如,我们不再需要将应用的数据模型绑定到任何一个对象层级或者数据同步机制上,因而能更方便地集成不同服务。既然我们所有的工作都倚赖于Web,就不必拘泥于以前搭建Web应用的成见,可以用目前最新的技术来搭建应用(见下图)。
无服设计的好处
如果你在寻找一种快速搭建低成本Web应用的方法,无服Web应用很可能就是一个解决方案。不需要花费时间和精力了解传统Web应用技术栈的各个层级,采用这种方式你能更专注于实现业务功能,有人会为你操心运行维护和可扩展性的问题。接下来让我们深入探讨无服设计的好处,帮助你在考虑下一个项目中是否使用这种方式时做出更明智的决定。
零服务器
无服设计最明显的好处就是不需要维护服务器(不管是物理的还是虚拟的)。你不需要担心打安全补丁、监控CPU和内存使用情况、回滚日志、磁盘空间不足或者其他在维护自有服务器时经常碰到的运维问题。和大多数平台即服务(PaaS)方式一样,无服设计能让你专注于应用开发,而无须担心基础设施的问题。
易扩展
这种设计方式的另一大好处是,你可以依靠云服务供应商来扩展自己的应用。在做水平扩容时,不需要忙不颠地在几个负载均衡应用服务器之间保持数据的一致性,你可以直接连接Web服务,而它们已经解决了数据一致性的问题。这意味着不管你的应用有几个用户、几百个用户,还是几十万个用户,只需要修改Amazon Web Services控制台的一些设置就可以保证完美的运行。
高可用
另外,使用这种设计能轻松实现高可用性。你不必为了升级而关闭应用服务器,或者为了实现“热”部署而扩建基础设施。不再会有服务的重启或者部署包在服务器间的拷贝。最妙的是,Amazon有一群训练有素的员工7×24小时守护着你的基础设施,一旦发现问题随时能够响应。
低成本
这些服务的成本可以非常低。使用无服的方式以及利用Amazon的免费套餐(Free Tier),一个月支付几美分就可以运行你的应用。一旦超过了免费额度,其费用经常也是随着你的用户量线性增长的(考虑费用最高的情况)。我们在这本书里构建的应用就算扩展到100万的用户,一天也只需要花费一杯咖啡的钱。
(微)服务友好
这种方式可以轻松适应微服务或者其他的面向服务架构。你可以在系统中引入特定的服务以实现自定义身份认证、验证或者异步数据处理。如果有必要,你甚至可以重新引入应用服务器,渐进式地重构应用。反之,如果一开始就使用一个中间层来控制所有的安全证书,就很难切换到需要认证的Web服务上。这些应用服务器没办法像无服应用一样,在应用层管理身份信息。
代码更少
在传统Web应用里,一些操作(比如导航)在Web客户端和服务器端都需要执行,造成了代码的重复。有时候,这种重复工作并不明显,尤其当服务器代码是用不同的语言写时。而在无服应用中,应用逻辑都移到了客户端,很容易保证应用内不再有重复的代码。将应用逻辑代码放在一个位置(以及用一种语言实现)帮助我们解决了这个问题。
此外,无服的方式更便于构建和排错,因为系统的组成部分变得更少了。Web应用天生就是分布式的,也就是说,正如CAP理论所述 ,它们在同一个网络的节点间传递消息(一般是以请求和响应的形式),限制它们的是实现方式。
有些应用会比其他应用更分散(more distributed)。一个系统越分散,就越难排错。移除应用中的中间层能减少其分散的程度。在我们这个简单的应用中,如果一个客户端需要从一个数据库中获取数据,就会直接连接数据库,而不是通过中间层连接。这就意味着系统中的网络节点更少,也意味着如果出现问题,需要定位的地方更少。
如上所述,构建一个无服应用的理由有很多。学完本书,你就会明白为什么这种方式如此强大。了解了无服应用的这些优点,我们再来看看它有哪些限制。
无服设计的限制
尽管无服架构有许多优点,但它也不是适用于所有类型的应用。为了享受这种设计带来的益处,你必须接受一系列的限制。如果你的应用不能适应这些限制,那么它很可能不是最合适的构建方式。所以在搭建应用之前,让我们一起看看这些限制。
供应商锁定
首先最大的限制就是你使用的Web服务必须支持第三方身份认证服务商,这样在云服务提供商的选择上就受到了限制。所以如果使用无服的方式,你就会依赖于第三方服务,供应商锁定也就成了一个问题。构建一个基于其他公司服务的系统,意味着这个应用的命运和供应商公司的命运绑在了一起。如果供应商公司被收购、破产或者改变商业模式,你的应用不下大力气修改就很难在其他地方运行。所以,评估服务提供商的业务目标和长期稳定性与技术选型是同样重要的。
奇怪的日志
所有运维关注的事情,比如应用日志,在你使用无服设计之后会呈现新的形态。当你把所有请求都通过一台服务器路由时,记录下所有信息以查看用户正在做什么是非常简单的事情。没有了这种中心化设计,日志的记录必须由每个支撑应用的不同Web服务来实现。这些日志格式跟大部分应用服务器日志都不同,记录的数据也很可能是你不熟悉的。我们在后面第8章的“分析S3日志”会深入探讨Web服务日志的分析。
不一样的安全模型
对于无服应用,有些常见的安全隐患不复存在,但你将会遇到一些不熟悉的新问题。比如,为了安全而验证用户数据,结果不能在浏览器中安全地实现。你需要假设有些恶意用户可能会在浏览器中劫持证书而使用该证书授权的Web服务。使用无服的方式,意味着你不能把浏览器中的应用验证逻辑和安全验证逻辑放在一起,必须分开实现。
Amazon提供的许多Web服务都能验证请求。你可以参考第5章的“数据访问和验证”一节内容利用DynamoDB来实现。然而,对于有些应用来说,很难只用Web服务提供的工具来实现充分的有效性约束。比如,在浏览器中直接编写文本时,你不可能放心地将写入的数据编码后存到数据库中,保证不会有跨站脚本攻击发生。因为攻击者不使用应用就能直接将这个数据添加到数据库。
这种情况下,你有(至少)两个选择。第一,可以假设某些用户可编辑的表可能包含未经验证的数据,然后针对性地设计系统的其他部分。比如,用户只能写入他们自己可读取的数据,这是可行的方式。第二,可以将某些写操作委托给自定义Web服务,比如可以使用Lambda函数来进行验证,并且以一种安全的方式写入数据。我们将会在第6章的“使用Lambda构建微服务”中详细介绍。
不一样的身份模型
外部身份管理是我们这本书构建的应用中的一个独特功能。使用Web服务来管理身份信息有很多好处,但对你来说这种机制可能有点陌生。与将用户信息和其他数据保存在一起的传统方式不同,这些用户资料会保存在一个独立访问的数据存储服务中。如果使用这种方式构建无服应用,一些在数据库中处理用户数据的方法(比如用一个ID关联一张User表)就没办法实现。
失去控制
此外,将所有请求路由到统一的中间层可以实现某种程度的控制,这在某些情况下是非常有用的。比如,拒绝访问攻击和其他一些攻击有时候可以在应用服务器上进行阻截。对你而言,放弃对身份认证的直接控制可能想一想都觉得可怕。我们后面在第7章会用一整章来专门探讨这些安全问题。
规模与成本的关系
最后,你需要了解这些服务的开销。虽然能够自动扩展应用这一点非常厉害,但易于扩展同时也意味着花钱更容易。你需要了解这些服务的定价策略以及当用户增加时这些价格的变化。我们后面会在第8章中深入讨论应用的成本。
既然你已经了解了无服Web应用的代价,我们可以开启这本教程,探索一下无服Web应用是如何实现的。在教程中,你可能会发现这种设计方式为你开发的Web应用带来的其他好处和限制。一旦知晓了无服应用的全貌,就可以判断下一个项目是否适合这种方式了。
使用自己的工作空间
为了学习无服Web应用的知识,我们将在本书中搭建一个JavaScript编程解题应用作为示例,名字叫LearnJS。它会向用户展示一些简单的编程题,然后让他们用JavaScript作答,并按下按钮检查答案是否正确。这个应用的样子如下图所示。
我们将会从后往前搭建这个应用。本章我们将会部署它,然后测试,再加入一些应用逻辑。在那之后,我们再来思考架构设计。
如果你对现代开发者们拥护的这种迭代增量式开发风格不熟悉(我本来想把它叫作敏捷开发,但是它和敏捷的涵义还有所不同),这套流程看起来是完全错误的。还没有构建好应用我们怎么部署呢?还不知道要让应用做什么,怎么先写自动化测试呢?还有,我们是不是应该在动手之前先考虑一下架构设计呢?
如果你对此有疑问,没关系,我们将会一步步实现这个流程。一旦完成之后,你将会理解,甚至是赞同这种方式。不仅因为它是学习新技术的绝佳途径,而且也是构建软件的有效方法:前进一小步,评估当前状态,不断重复此过程,直到客户满意。
使用Git进行代码管理
-
Git是一个代码管理系统。与其他系统一样,Git能帮你跟踪代码的变动,保证代码安全,以及与他人共享。如果你对它不熟悉,可以看看下面的介绍。
-
Fork一个项目意味着创建一个自有的副本。如果你在Github.com上创建一个账号,再查看你的工作空间项目 ,应该可以在页面右上角看到一个“Fork”按钮。单击按钮,过几秒后,Github就会为你创建这个项目的副本。现在你需要把它复制到本地电脑上,这个过程称为克隆(clone)。使用一个Git客户端,你能将整个工作空间都克隆到自己电脑的本地目录上。一旦完成,就万事俱备了。
想要了解更多如何使用Git和Github的内容,参见Github Guides。
一开始,你需要fork一个在Github上准备好的工作空间 。使用这个工作空间能让你专注于构建应用和学习相关知识,而不是把时间花在搭建必要但不相关的基础设施上。在进行下一步操作之前,使用以下命令克隆被fork的工作空间(填入你的Github用户名):
$ git clone git@github.com:/learnjs.git
要理解接下来会做什么,首先需要理解现有的代码。刚才克隆的工作空间中有一个public文件夹,里面包含了一个空应用。这个应用没有任何功能,它的标记(markup)也很快就会被替换,但它包含了所有我们需要的基本工具。
在构建应用时,我们主要会修改public文件夹下的三个文件:index.html、app.js和app_spec.js。我们会在index.html中添加应用的标记。这就是我们单页Web应用中的“单页”。使用自己顺手的文本编辑器,打开这个文件,查看一下内容。在元素中,你将会看到这个预备好的工作空间里我们必须使用的一些库。
-
<meta charset="utf-8"><title>Learn JS!</title><link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Raleway:400,300,600"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.2/normalize.min.css"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css"><script src="https://code.jquery.com/jquery-2.1.4.min.js"></script><script src="/vendor.js"></script><script src="/app.js"></script><style type="text/css" media="all">
-
body { margin-top: 30px; }
-
</style>
应用里第一个库是标准化CSS基准库,它保证了我们的基本样式在所有浏览器中都是一致的。后面我们会引入Skeleton,一个响应式CSS样板库。Skeleton提供了响应式网格和一些小的CSS组件,可以用于样式和布局。我们还引入了Skeleton的默认字体Raleway,托管在Google字体库 。还有一个引入的库是jQuery 2。我们用jQuery来做许多事情,比如搭建应用视图、视觉动画和监听事件。
第二个文件vendor.js包含的库要么是我们应用自定义的,要么是不够流行而没有放在CDN上的类。迄今为止,这个文件包含的唯一东西是一个AWS (版本号为2.2.4)JavaScript开发库的自定义子集,包含了以下几个服务类库:
- CognitoIdentity
- CognitoSync
- DynamoDB
- Lambda
- STS
元素里的另一个脚本为app.js。到目前为止,这个文件是空的。这里就是我们添加用JavaScript编写的应用逻辑的地方。它不仅会包含应用的领域特定逻辑,而且包含像路由器、模板函数和数据绑定代码这样的基础设施。
元素里的最后一项是一个
-
learnjs/1000/public/index.html
-
<body>
-
<div class='container'>
-
<h1>It works!</h1>
-
<div>
-
<span>You're ready to start!</span>
-
<span>Skeleton 2, jQuery 2, and AWS libraries are included.</span>
-
</div>
-
</div>
-
</body>
工作空间内还包括一个名叫Jasmine的测试框架。空间内的public/tests文件夹包含了一个测试执行器和一个空的测试组件(public/tests/app_spec.js)。当我们编写测试用例来保证应用的功能时,就把它们添加到这里。
本地执行
既然了解了目前的进度,就把应用启动起来,然后把自己设想成用户来看一看。接着我们可以对其进行评估,做一些小修改,部署我们的第一个版本。要做这些事,需要一台在本地运行的Web服务器来为应用提供服务。
预先准备好的工作空间提供了一个叫作sspa的包装器脚本。对这个脚本的使用将贯穿全书,它将实现包括配置AWS服务、构建代码包和部署应用等简单任务。这个脚本代码非常易读,如果想知道它是怎么工作的,尽管打开看一看。为了在本地启动一个包含public文件夹下的内容的开发服务器,在预设的工作空间主目录下执行以下命令:
learnjs $ ./sspa server
sspa脚本的server指令会启动一个简单的Python Web服务器提供静态内容。当然,你也可以使用自己的Web服务器。只需让预备的工作空间来提供public文件夹下的内容,一切搞定。我们在书中所做的事情都不会涉及特定的Web应用开发工具。不管你喜欢使用什么工具,都可以在你最舒服的工作环境中应用本书中的所有技术。
一旦搭建好Web服务器并运行起来,看一下我们的应用。如果你是用预备工作空间中自带的服务器,可以打开习惯的浏览器,访问http://localhost:9292。你应该可以看到以下内容:
这就是我们的应用。目前还没有什么内容。尽管可以试着为应用规划一长串的功能,但因为还不知道究竟我们想要些什么,超前规划似乎会变成徒劳。相反,我们会给应用添加一个标题页面,然后决定接下来做什么。
创建着陆页
当用户第一次加载我们的应用时,我们想展示给他们一个页面,既能快速解释我们的应用是什么又能提供清晰的入门指南。这个页面通常被叫作着陆页(landing page),我们的应用中也会添加一个这样的页面。
LiveReload和LivePage
-
不管你使用哪种Web服务器,我都非常推荐在实际项目中使用某种自动刷新页面的工具。有很多现成的选择。有一个与我们的预备工作空间配合使用的好工具是Google Chrome 中的LivePage插件。它安装和使用起来很容易,只要你修改了代码,它都会运行测试脚本并重新加载应用。这样的工具建立了一个快速反馈闭环,你可以用来检验样式和布局变动或者执行一些客户端测试。
-
另外一个选择是名为LiveReload的工具。LiveReload既可以用作一个单独的Web服务器,也可以在开发中用作自动重载Web应用的协议。无论什么时候服务器检测到硬盘文件的改动,都会及时通知客户端的JavaScript库(或者浏览器插件)。LiveReload有多种形式,有LiverReload应用 和像LiveReloadX 这样的命令行工具。如果你希望在Node.js中运行,live-server 或者grunt-livereload 可能更适合你的需求。
为了构建着陆页,我们用Skeleton网格创建了一个简单的布局。这个页面会包含一些标题文本、一张图片和一个经常用于号召行动的按钮。用户将单击这个按钮来启动我们的应用。
如果你之前不熟悉Skeleton,现在是一个熟悉它的好时机 。当然,它里面其实并没有很多东西(所以才叫这个名字)。它的文档非常规范,而且有许多案例,所以很容易学习。花5分钟时间过一遍,就能理解它能做什么以及是怎么实现的。
为了展示这个网格,我们将厚着脸皮从Skeleton着陆页的案例中“偷”些代码。使用你的文本编辑器,打开index.html,将这些标记添加到应用页的中:
-
learnjs/1100/public/index.html
-
<body>
-
<div class='container'>
-
<div class='row'>
-
<div class='one-half column'>
-
<h3>Learn JavaScript, one puzzle at a time.</h3>
-
<a href='' class='button button-primary'>Start Now!</a>
-
</div>
-
<div class='one-half column'>
-
<img src='/images/HeroImage.jpg'/>
-
</div>
-
</div>
-
</div>
-
</body>
在你的浏览器中,应该能看到我们的着陆页,而不是之前的文本了(见下图)。单击按钮并不会触发任何操作,但这并不是错误。
既然我们已经添加了一个着陆页,就有东西可以去部署了。虽然不是很丰富,但也足够用来走部署流程,足够我们在为应用添加更多功能之前把一切理顺。
部署到Amazon S3
当启动新项目时,经常会碰到很多未知的风险。那些问题可能根本不在预料之中,会让你浪费很多时间。如果能识别并避免这些风险,可以少一些挫败感、头疼和痛苦。
有一个很容易避免的风险就是部署问题。我们不想等开发完成之后再部署。我们关于应用如何运行的假设有可能是错误的。如果基于这些错误的假设构建应用,风险和潜在痛点会增加。因为我们是在个人电脑上开发应用然后部署在服务器上的,Web应用经常面临一堆问题。这两种环境很可能完全不一样,等你理解了它们所有的不同点,就会发现自己是在白费力气。
通过提前部署,我们就知道自己的部署流程是否做了正确的配置。我们可以检测生产环境是否可行,确保没有任何权限之类的问题。最重要的是,我们解决了所有必要的任务,证明我们可以把应用从头到尾完成。在你的应用交付给用户使用之前,从他们的角度,你就是没完成任何东西,不管你已经写了多少代码。
我们没有运行自己的Web服务器(例如Apache或者Nginx),而是将应用部署到Amazon的Simple Storage Service(S3)上。它的一大用途是作为静态站点服务器。虽然不如其他服务器功能全,但它很便宜(一个月只需要几美分)而且便于扩展。既然我们一直在尝试避免在服务器基础设施上投入时间和金钱,那么S3完美满足了需求。
搭建AWS命令行接口
在本书中,我们需要和AWS交互来创建和配置应用所需的服务。一个好方法是使用AWS命令行接口,简称AWS CLI。我们会先用这个工具创建我们的S3存储桶(bucket),在后面构建应用的过程中它会有大用处。
如果你还没安装AWS CLI,那就赶快安装,并且配置好管理员权限。Amazon推荐使用pip,一个Python包管理器,来安装AWS CLI。如果没有pip,也可以使用easy_install,它也是一个Python包管理器。你需要使用Python 2.7以上版本。根据你安装的管理器,执行以下对应的命令:
-
$ sudo easy_install pip
-
$ sudo pip install awscli
在Debian/Ubuntu系统上,你可以用apt来安装pip:
$ sudo apt-get install python-pip
在OS X 10.11上安装AWS CLI
如果在OS X 10.11(El Capitan)上用pip安装AWS CLI出现问题,你可以在install命令 后面添加--upgrade和--ignore-installed six参数。
为了使用这个工具,你需要配置它。首先,要在AWS账号上创建一个带管理员权限的用户。
创建一个带访问密钥的AWS用户
授权你访问其他所有AWS的那个AWS称为身份认证和访问管理服务(Identity and Access Management,IAM)。你可以用这个服务创建一个能访问你账户下某些服务的独立用户。显然,这对于团队协作很有帮助,但还能用它根据角色或者任务创建不同用户。类似这样的分组访问方法可以限制密钥泄露导致的漏洞,防止测试数据直接进入生产数据库,或者防止一个应用意外影响到另一个应用。
你可能想为应用创建很多用户,我们这里先创建第一个带管理员权限的用户。该用户有你账户里所有服务的访问权限,所以一定要小心使用。按照以下操作步骤创建用户:
1.打开AWS控制台 ,如果有必要,注册一个账号。
2.进入“Security & Identity”下面的“Identity & Access Management”服务。
3.在左边侧边栏,点击“Users”。
4.点击“Create New Users”创建一个新用户。我们将会使用这个用户账号来部署应用。
5.为用户挑选一个名字(比如learnjs),填在第一行。
6.勾选上“Generate an access key for each user”(为每个用户分配访问密钥)复选框,点击“Create”。
7.按照提示下载证书。
证书由两个密钥组成:访问密钥(access key)和私钥(secret key)。这两个密钥都在你下载的CSV文件里,也可以直接在网站上看到。Amazon只给你一次操作机会,所以马上下载下来,否则你只能重新创建密钥了。
不需要为这个用户提供密码。
一旦拿到这些密钥,就可以完成AWS CLI的设置。用管理员用户运行aws configure命令,然后按照提示输入密钥信息。如果它要求你设置默认区域,输入us-east-1。
-
$ aws configure --profile admin
-
AWS Access Key ID [None]: JFAKEKEYSRRETDMAAKIA
-
AWS Secret Access Key [None]: 2Jdw+ThI5iSafAKeKeY4ExamPLEsHAONXn32Af/sm
-
Default region name [None]: us-east-1
-
Default output format [None]:
Joe问:
如果我想用其他区域呢?
-
如果你对AWS比较熟悉,很可能在一个非us-east-1的区域有几个已经配置好的服务了。当然你也可以在管理员界面中修改区域配置,但注意并不是所有的服务都适用于所有的区域。另外,在其他区域sspa脚本可能没法正确处理URL请求和其他资源名。
-
如果你用了非us-east-1的其他区域,需要验证一下你所使用的服务在那个区域是否可用。另外,你可能需要修改下sspa脚本以适配你的区域名。
既然AWS CLI已经配置好了,在主目录下应该能发现一个新文件~/.aws/credentials。这个文件的内容如下所示(当然密钥是不一样的):
-
[admin]
-
aws_access_key_id = JFAKEKEYSRRETDMAAKIA
-
aws_secret_access_key = 2Jdw+ThI5iSafAKeKeY4ExamPLEsHAONXn32Af/sm
在创建用户并且保存证书之后,你需要通过创建访问策略来授予该用户访问的权限。回到AWS控制台的用户列表页,你应该可以看到最近创建的用户。点击该用户,进入用户概要页。它应该看起来如下图所示。
接下来,你需要创建一个策略,规定该用户能访问哪些服务。找到用户概要页的“Permission”模块,点击添加新托管策略的链接。你将会看到一系列如下图所示的策略信息。
勾选上“AdministratorAccess”旁边的复选框,然后单击“Attach Policy”按钮,就大功告成了。现在你可以创建一个S3存储桶(bucket)。然后,就可以部署应用了!
创建一个S3存储桶
基于已有的管理员用户,你可以创建一个S3存储桶。预备工作空间中的sspa脚本包装了一些AWS CLI的命令,不仅能够创建存储桶,而且能够把它配置成服务于我们应用的静态文件Web服务器。如果你还有一个想指向这个应用的域名,这里必须将它输入成存储桶的名字(比如learnjs.benrady.com);如果没有,那么你想用什么名字都行。只需要输入create_bucket调用sspa脚本,以新的存储桶名当作参数即可。
-
learnjs $ ./sspa create_bucket learnjs.benrady.com
-
make_bucket: s3://learnjs.benrady.com/
-
Website endpoint is: \
-
http://learnjs.benrady.com.s3-website-us-east-1.amazonaws.com
Amazon S3存储桶的名字是全局的,所以不能用别人用过的名字。
如果命令成功执行,一个新的存储桶就被创建了。你可能想换一个存储桶名再运行一次命令,为应用创建一个测试或者演示环境。退出命令后,在终端中应该看到sspa脚本返回了一个存储桶网站访问端点的URL。记下来这个URL地址,再执行以下命令部署应用:
$ ./sspa deploy_bucket learnjs.benrady.com
好了!现在把sspa脚本刚才显示的网站访问端点输入到浏览器中,就可以看到我们的应用了。它上线了!如果没看到,可以仔细检查AWS控制台中Amazon S3的网站端点地址。如果为AWS CLI配置的区域不是us-east-1,有可能sspa脚本显示的地址是不对的。
一旦确认应用已经成功部署,就可以给应用起一个域名来简化URL访问链接。你需要把域名映射到这个S3存储桶。你可以通过在DNS服务商的网站上,创建一个CNAME项,把端点URL当作记录的值,来实现映射。更多有关如何实现的详细信息,参见附录B的内容。一旦做完这些,部署工作就全部完成了,我们就可以继续下一步的工作。
首次部署
你已经把应用成功部署到生产环境中了。有了这一次的经验,后面再修改应用,你应该有信心完成部署了。这种方式将帮助你小步前进,专注于怎么让应用变得更好以及怎么把它推向潜在用户。
下一步
至此,你已经知道怎么把应用部署到Amazon S3。下面是一些你可能会感兴趣的延伸话题。
AWS区域
所有的AWS服务都运行在遍布于全球各地的数据中心,也就是前文所说的“区域”(region)。让应用在不同的区域并行运行是一个确保高可用性的好办法,即使在面对灾难性故障或者自然灾害的时候。
在选择区域的时候,首先保证你需要的服务在那个区域是可用的。另外还必须考虑你的用户在什么区域,其他非AWS的支撑服务器在什么区域(比如邮件服务器)等等。
创建测试环境
我们在本章中刚接触它,但是随着本书的内容一点点深入,后面会搭建一个完整的测试环境,其配置和生产环境一致。你可能认为这么做没有什么意义,但走完整个过程,你会了解到两套环境下会面临的一些配置问题。是现在就解决还是暂时搁置这些问题,由你自己决定。
IAM锁定
我们在这个应用中创建的管理员用户可以访问账号里的所有服务。等你对需要的服务更熟悉之后,更好的方式将是移除这个用户的所有管理员策略,添加一些细粒度策略,只允许它访问真正需要的服务。
至此,我们已经为接下来的工作做好了准备。在下一章中,我们将会添加一个客户端路由到应用中,支持不同的应用视图,以及解决一些按钮不管用的问题!