65.9K
CodeProject 正在变化。 阅读更多。
Home

围绕 Amazon Web Services 构建想法的 7 个简单步骤

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (11投票s)

2006年10月18日

CPOL

11分钟阅读

viewsIcon

63556

downloadIcon

402

本文是一个简单的分步指南,适合那些有想法并希望快速实现它们的人。我们将使用代码演示在 Amazon S3 上构建应用程序是多么容易。我们还将重点介绍您在发布应用程序之前可能提出的问题。

引言

本文将使用代码演示在 Amazon S3 上构建应用程序是多么容易。我们还将重点介绍您在发布应用程序之前可能提出的问题。为了说明目的,斜体字代表一个正在构建应用程序(此处为 S3Whois)的开发人员(此处为我)的思考过程。

第 1 步:从你的绝佳想法开始

每个企业都始于一个绝佳的想法。你要么已经有一个想法,要么有一个需要解决的问题。从小处着手,但要放眼大局。只需问几个简单的问题来检验你的想法:

  • 是否已经有人做过了?我的想法是否独特?
  • 是否有赚钱的潜力(商业模式)?
  • 它解决了什么问题?

相信自己和你的想法,并始终与“经验丰富的人”进行验证。

我有一个简单的想法。我觉得当鼠标悬停在任何网页上出现的电子邮件地址上时,显示一个小工具提示框会很酷。我们可以非常有创意地决定在工具提示框中显示什么。一开始,我想我会简单地显示该个人的所有“名片”信息,并附上一张小照片。大概是这样的:

我认为这个想法很棒,因为它赋予了电子邮件一个面孔,并帮助我将电子邮件地址与真实的身份/人物关联起来。

第 2 步:白板勾画你的想法

整个系统将如何工作?当你需要倾泻思绪时,请始终使用白板。会有很多“想法的衍生”,这些衍生又会产生更多的“想法的衍生”,让你无法专注于主要想法。为了快速实现目标,重要的是要专注于你的主要成功场景。白板通常有助于转录你的想法。你需要问的问题是:

  • 整个系统将如何工作?
  • 拼图的主要部分是什么?它是否有提供网页的 Web 服务器?是否有客户端?
  • 不同部分将如何相互交互?
  • 系统的外观和感觉会是怎样的?

我试图让它适用于互联网上的每个网页的想法表明,我需要开发一个浏览器插件或工具栏。该插件将解析用户访问的每个页面,并将所有 mailto: href 链接替换为注入的 JavaScript 代码。当触发鼠标悬停事件时,它将渲染一个小的 div 层(名片大小)。

然后,工具提示框将使用电子邮件作为输入参数查询 Web 服务器和数据存储,然后获取与该电子邮件相关联的数据。最初,数据可以是图片(照片)和一些额外信息,如姓名、电子邮件地址、兴趣和邮政编码。

我该如何获取数据呢?我需要一个 Web 表单,用户可以使用它将数据插入到数据存储中。

最初,我的白板图看起来像:

我的拼图的主要部分是:

  1. 浏览器插件/工具栏/脚本将作为客户端。
  2. Web 服务器将有两个页面。一个页面从数据存储中获取数据,另一个页面通过 HTML 表单将数据插入到数据存储中。
  3. 需要一个数据存储来存储我的最终用户数据。

系统的外观和感觉会是怎样的?

  • Get 页面看起来应该像一张带照片的名片。
  • Put 表单需要一个 HTML 表单。我可以用免费的网站模板(或 Microsoft VS.NET 2005 模板)嵌入表单。

总的来说,我觉得我需要以下几点:

  • 直观的用户界面:工具提示框应在用户访问互联网上的任何网页时可用。
  • 可扩展、可靠、快速的存储:我的钱不多。存储应经济实惠。存储检索应可靠且快速。
  • 快速开发:学习曲线小。

鉴于整体要求:

  • 重用:尽可能重用。不要重复造轮子。
  • 易于开发:开发和集成应易于进行。我不想陷入数据库 SQL 查询编写的困境而失去对实际想法的关注。

第 3 步:获取合适的工具

所以你有一个绝佳的想法。你也对整个系统如何工作以及不同部分如何相互交互有了很好的感觉。现在,我们想深入一点,问以下问题:

  1. 我应该使用什么技术平台?
  2. 我可以使用哪些开源/第三方实用工具?
  3. 如果我出名了怎么办?它会增长到多大?
  4. 我将在哪里托管我的应用程序?

快速到达那里很重要,因此拥有合适的设备/装备来到达那里也很重要。人们要么选择他们已经熟悉的东西,要么利用这个机会学习新的产品或技术。

我选择了后者。 考虑到以上几点,并以快速开发(在一个周末内)为目标,我考虑了以下几点:

为了解决上面的 #1 问题,我觉得使用像 GreaseMonkey 这样的东西并安装一个小用户脚本(可能已经由某个天才开发者开发,我只需要注意它——积极思考)在 脚本库中会很酷。这样,用户(我的客户)只需安装一个很酷的小脚本即可完成所有魔力。一个注意事项:Greasemonkey 仅适用于 Firefox,但也有类似的引擎,如适用于 IE 的 greasemonkIEturnabout。其他选择是:开发 BHO/ActiveX IE 插件或 Firefox 插件。

为了解决 #2 问题,我决定使用 VS.NET 2005,它内置了 IIS 服务器。我认为这是一个学习微软新产品的绝佳机会。

为了解决 #3 问题,我认为最快最简单的开发方式是使用一个已有的 Web Service。而不是创建数据库并编写老套的 CRUD 数据库 SQL 逻辑,我将简单地使用某种 Web Service 来存储所有客户的配置文件。

因此,我决定使用新的 Amazon S3 Web Service,主要有三个原因:

  • 它很可靠。
  • 它非常便宜(存储数据 15 美分/GB,传输 20 美分/GB-月),并且
  • 它具有可扩展性——我不用担心我的应用程序一夜成名( aha!)。我不用担心基础设施,因为所有这些都来自亚马逊,而且是按需付费的服务。它使用按使用付费的模式——就像我点播的直播电视服务一样,我只为我喜欢的电影付费。

很棒,不是吗?

新的白板图

获取合适的工具/代码生成器

我为 Firefox 安装了 Greasemonkey 插件,并修改了他们用户脚本库中可用的一个用户脚本(功劳归于 Walter Zorn,他提供了很棒的 JavaScript 工具提示)。 我已经配置好了 IIS 和 VS2005.NET。

创建 AWS 账户

我访问了 http://aws.amazon.com,创建了一个账户,并获取了 Access Key ID 和 Secret Access Key。我还通过点击 http://aws.amazon.com/s3 上的“Sign up for Web Service”按钮并提供我的信用卡详细信息,注册了 Amazon S3。.

下载辅助类

  • 亚马逊提供了多种语言的入门套件,如 Java 和 PHP,支持 REST 和 SOAP 接口。我从 Amazon S3 代码示例中获取了 C# REST 和 SOAP API。.
  • 阅读了资源中心的 技术文档

第 4 步:开始编码!

强烈建议深入代码。这类似于我们学习游泳的方法。跳进去!你会扑腾、挣扎、溅水,并努力在几分钟内生存下来;然而,一段时间后,你会发现你的恐惧已经转变成了信心。同样,只有当你真正投入代码时,你才会意识到将 Amazon S3 集成到你的应用程序是多么容易。你应该在此处问的问题是:

  • 我应该从哪里开始?哪个入门包最能帮助我接近我需要的东西?
  • AWS 资源中心是否有匹配我需求的现有代码示例?还是我需要从头开始构建一个原型?
  • 我如何调用 Web Service?我需要哪些引导代码?

我在 VS.NET 2005 中创建了一个新的网站,并添加了从资源中心的“代码示例”部分下载的现有文件。我拥有了创建第一个“Happy-path”用例所需的所有代码。我的解决方案资源管理器看起来像这样:

我创建了一个名为 getprofile.aspx 的新文件并插入了以下代码:

  <asp:Panel ID="profilePanel" runat="server">
    <table>
       <tr>
        <td rowspan="4">
            <form action="" runat="server">
               <asp:Image ID="s3WhoisImage" runat="server" Height="150px" Width="100px"/>
            </form>
        </td>
        <td>
         <table>
           <tr> <td>
            <asp:Label ID="s3WhoisName" runat="server" Text="Label"></asp:Label></td>
        </tr>
        <tr><td>
            <asp:Label ID="s3WhoisEmail" runat="server" Text="Label"></asp:Label></td>
        </tr>
         <tr><td>
            <asp:Label ID="s3WhoisInterests" runat="server" Text="Label"></asp:Label></td>
        </tr>
         </table>
        </td>
        </tr>
    </table>
  </asp:Panel>

为了支持这个 HTML,我的代码(getprofile.aspx.cs)中有以下内容:

//amazon aws credentials : you can get these from creating one at http://aws.amazon.com
//I am reading from web.config
string accessKey = system.Configuration.ConfigurationManager.AppSettings.Get("AccessKey");
string secretKey = System.Configuration.ConfigurationManager.AppSettings.Get("SecretKey");
  
//use your bucketname from web.config
bucketName = System.Configuration.ConfigurationManager.AppSettings.Get("bucketname");

//using REST get the URL of the image. Let the browser make the fetch call
//tricky to do this in SOAP as ASP.NET does not have 
//ImageControl that takes in byte Array/bitmap
//QueryStringAuthGenerator simply generates
//the URL that we can use to make the REST call
QueryStringAuthGenerator generator = 
   new QueryStringAuthGenerator(accessKey, secretKey, true);
generator.ExpiresIn = 60 * 1000;
string url = generator.get(bucketName, s3WhoisId, null);
s3WhoisImage.ImageUrl = url;

// *******************************************************
//  REST example to get metadata of S3 object
// *******************************************************
RESTConnection restS3 = new RESTConnection(accessKey, secretKey);
GetResponse resp = restS3.getHead(bucketName, s3WhoisId, null);
SortedList metadata =  resp.Object.Metadata;

//populating the html fields from the metadata
s3WhoisEmail.Text = (string)metadata["s3WhoisEmail".ToLower()];
s3WhoisName.Text = (string)metadata["s3WhoisName".ToLower()];                
s3WhoisInterests.Text = (string)metadata["s3WhoisInterests".ToLower()];

我发现我也可以使用 SOAP 做同样的事情:

// *******************************************************
//  SOAP example to get metadata of S3 object
// *******************************************************
SOAPConnection s3 = new SOAPConnection(accessKey, secretKey);
GetObjectResult objResult = s3.get(bucketName, s3WhoisId, true);
s3WhoisEmail.Text = GetMetadataValue(objResult.Metadata, "s3WhoisEmail");
s3WhoisName.Text = GetMetadataValue(objResult.Metadata, "s3WhoisName");
s3WhoisInterests.Text = GetMetadataValue(objResult.Metadata, "s3WhoisInterests");

GetProfile.aspx 看起来像这样:

好的。现在我了解了如何使用 SOAP 和 REST 从 S3“获取”对象。我需要弄清楚如何将对象“放置”到 Amazon S3 中。PUT 对象稍微有点棘手,因为我发现有多种设计选择:

  1. 我可以在 Amazon S3 中将图片存储为一个具有“image”内容的 contet-type 对象,并将所有其他配置文件数据“附加”为该对象的元数据。.
  2. 我可以在 Amazon S3 中将图片存储为一个具有“image”内容的 contet-type 对象,并将配置文件数据也作为文本内容的 contet-type 对象。.
  3. 我可以在 Amazon S3 中将图片存储为一个对象,并附带一个存储所有配置文件数据的附加文本文件对象。.

正如你所见,Amazon S3 给了我选择最适合我的方案的灵活性。#1 在我的情况下似乎是最可行的选项,因为我可以在一个请求中获取对象及其所有元数据,从而减少了请求的数量。此外,它的可扩展性也更强,因为我只需添加一两行代码即可添加新的元数据对象。

这就是我的 putprofile.aspx 的样子:

我的代码隐藏 putprofile.aspx.cs:

public partial class PutProfile : System.Web.UI.Page
{
    private string bucketName = "";
    private SOAPConnection s3;
    private RESTConnection restS3;
    protected void Page_Load(object sender, EventArgs e)
    {
        //amazon aws credentials : you can get these
        //from creating one at http://aws.amazon.com
        string accessKey =
          System.Configuration.ConfigurationManager.AppSettings.Get("AccessKey");
        string secretKey =
          System.Configuration.ConfigurationManager.AppSettings.Get("SecretKey");
        //use your bucketname
        bucketName = 
          System.Configuration.ConfigurationManager.AppSettings.Get("bucketname");
        //we will demostrate both SOAP and REST. so lets instantiate the connection
        s3 = new SOAPConnection(accessKey, secretKey);
        restS3 = new RESTConnection(accessKey, secretKey, true);
        string id = Request.QueryString["id"];
        if (id != "" && id != null)
        {
            s3WhoisId.Enabled = false;
            s3WhoisId.Text = id;
        }
        else
            s3WhoisId.Enabled = true;
    }
    protected void cmdSend_Click(object sender, EventArgs e)
    {
        // Check to see if image file was uploaded
        if (filMyFile.PostedFile != null)
        {
            // Get a reference to PostedFile object
            HttpPostedFile myFile = filMyFile.PostedFile;
            // Get size of uploaded file
            int nFileLen = myFile.ContentLength;
            // make sure the size of the file is > 0}
            if (nFileLen > 0)
            {
                // Allocate a buffer for reading of the file
                byte[] myData = new byte[nFileLen];
                // Read uploaded file from the Stream
                myFile.InputStream.Read(myData, 0, nFileLen);
                // Create a name for the file to store
                string strFilename = Path.GetFileName(myFile.FileName);
              // *******************************************************
              // using REST to put a file in S3
              // *******************************************************
                SortedList metadata = new SortedList();
                metadata.Add("s3WhoisName", s3WhoisName.Text);
                metadata.Add("s3WhoisEmail", s3WhoisEmail.Text);
                metadata.Add("s3WhoisInterests", s3WhoisInterests.Text);
                SortedList headers = new SortedList();
                headers.Add("Content-Type", "image/jpeg");
                //prepare the object
                S3Object obj = new S3Object(myData, metadata);
                //make the call
                Response res = restS3.put(bucketName, s3WhoisId.Text, obj, null);
                //check the response message
                if (res.Status == System.Net.HttpStatusCode.OK)
                message.Text = "Profile Stored";
            }
        }
    }

我还发现我也可以使用 SOAP 做同样的事情:

// *******************************************************
// using SOAP to put a file in S3
// *******************************************************
PutObjectResult objS3PutObjectResult;
MetadataEntry objMetaDataEntry;
MetadataEntry[] aobjMetaDataEntries = new MetadataEntry[3];

// adding some metadata entries to the object data
objMetaDataEntry = new MetadataEntry();
objMetaDataEntry.Name = "s3WhoisName";
objMetaDataEntry.Value = s3WhoisName.Text;
aobjMetaDataEntries[0] = objMetaDataEntry;
objMetaDataEntry = new MetadataEntry();
objMetaDataEntry.Name = "s3WhoisEmail";
objMetaDataEntry.Value = s3WhoisEmail.Text;
aobjMetaDataEntries[1] = objMetaDataEntry;
objMetaDataEntry = new MetadataEntry();
objMetaDataEntry.Name = "s3WhoisInterests";
objMetaDataEntry.Value = s3WhoisInterests.Text;
aobjMetaDataEntries[2] = objMetaDataEntry;

// make the remote call
objS3PutObjectResult = s3.put(bucketName, s3WhoisId.Text, 
                       myData, aobjMetaDataEntries, null);
if (objS3PutObjectResult != null)
message.Text = "Profile Stored";

最终效果是这样的:

总而言之,此应用程序利用了以下内容:

  • Visual Studio 2005 IDE (.NET 2.0 framework)
  • Amazon S3 C# 库
  • Greasemonkey 引擎(免费)
  • Greasemonkey 用户脚本

GetProfile.aspx 使用唯一的标识符从 S3 获取存储的图片/配置文件及其元数据。该唯一标识符作为 S3 对象在 S3 中的“键”存储。PutProfile.aspx 是一个 ASP.NET 网页表单,它从网页获取图片、姓名、电子邮件地址等信息,并将信息以对象的形式存储在 S3 中。所有图片都作为“对象”存储在“S3whois”存储桶中,其他信息作为该对象的元数据存储。Greasemonkey 脚本解析 HTML 页面,并在遇到 mailto: 链接时注入鼠标悬停 JavaScript 代码。鼠标悬停时会显示 getprofile.aspx 页面。

第 5 步:发布你的“Happy Path” Beta 版

任何应用程序总会有一些边缘情况/例外情况。一些可能有用的技巧:

  • 记录下你所有的边缘情况。
  • 分析已实现的用例,看看它们是否会打开任何安全漏洞。
  • 保护好你的 AWS 凭据。确保在分发和打包应用程序时,清除这些字段。
  • 通过将你的应用程序发送给同事、朋友/家人来测试它,当然,也发送给 Amazon Web Services。他们总是想知道你在做什么。

一旦我的“Happy Path”奏效,我就将我的应用程序托管在本地 Web 服务器上,以便其他人可以开始使用它并提供更多反馈。我记录了主要成功场景,并创建了一个单页“用户手册”。

第 6 步:宣传/写博客/记录并让世界知道

与他人分享你的应用程序非常重要。让世界知道你。让世界写关于你的博客。

我做了几件事来营销和宣传我的应用程序:

  • AWS 的 资源中心 总是提供很棒的内容。我发现“解决方案目录”是一个很受欢迎的地方,所有开发人员都在那里列出他们的应用程序。我填写了一个简单的表格,并将我的应用程序信息添加到解决方案目录中。我还发现其他开发人员正在使用 Amazon S3 构建什么。
  • 我使用了 开发者论坛 来提出我的问题。
  • 我还发送了一封电子邮件到 awseditor@amazon.com 并告知他们我的应用程序。
  • 我在我个人的博客网站上写了关于它的博客。

第 7 步:不断改进和添加新功能以保持领先地位

持续跟踪功能,以便你可以添加和改进。一种已被证明成功的方法是维护一个 wiki 页面,让其他人可以为你的应用程序添加内容(功能/评论)。

我选择创建一个 Excel 表格,帮助我跟踪/排序我添加的每个新功能的的状态。每当出现新的有趣功能时,我都会持续维护和更新该 Excel 工作表。

资源

© . All rights reserved.