在Azure上构建一个基于Facebook的营销式应用程序(下)

原创
云计算
当你的Facebook应用程序点击率上升的时候,它如何进行扩展呢?如果你是在Windows Azure上构建的这个应用程序,并且是按横向扩展的思想设计的这个应用程序,那么很高兴地告诉,你可以“高枕无忧”了。

本文承接《在Azure上构建一个基于Facebook的营销式应用程序(上) 》 和《在Azure上构建一个基于Facebook的营销式应用程序(中)》

选择一个商店

如果我们在联系信息窗体中通过了验证,我们接下来就可以让用户选择一个他自己喜欢的商店了。这个应用程序会给用户展示一个包含三个商店的列表(这三个商店都在这个用户的邮政编码所在地方圆50英里之内,是按照从最近到最远的顺序来排序的)。要想让这个窗体快速地显示出来,尽量减少Web角色上的负载,提前计算距离,然后把据距离信息和商店数据整理到Azure Table Storage中是我们首先应该做的事情。要时刻谨记,我们的目标是可扩展性,而不是想当然的可升级性或未来的可预见性——营销式应用程序存在的时间相对较短。

我使用的是公用的来自于1999年人口普查的美国邮政编码列表(具体可以参考:http://www.census.gov/geo/www/tiger/zip1999.html)。这个列表包含每个邮政编码的经度和纬度坐标。然后,因为我没有自己的商店,所以我从这个列表随机地选择了一些邮政编码,然后用这些邮政编码生成了一个包含1000个样例商店的列表。然后,把这个商店列表通过CSV文件(这种文件格式对Azure Azure Storage Explorer比较友好)的形式,上传到我的***个Azure表中,“Store”实体如下所示:

Listing 7

public class Store: TableServiceEntity

{

// partition key is store number

// row key is empty

public Store()

{

this.RowKey = "";

}

public string Name { get; set; }

public string City { get; set; }

public string State { get; set; }

public string Zip { get; set; }

}

接下来,我构建了第二张表,叫作“ZipStore”,对于这个国家中的每个邮政编码来说,它包含0到3行。每行是一个“邮政编码-商店”对,对于每个邮政编码来说,只考虑在这个邮政编码所在地方圆50英里内的三个最近的商店。要构建这样一张表,我必须要遍历邮政编码列表,然后使用一个基于经度和纬度的公式(具体可以参考:http://zips.sourceforge.net/),计算出各个邮政编码所在地到每一个商店的距离,把范围内最近的三个商店保存下来。如果方圆50英里之内根本就没有商店,那么我会放弃这个邮政编码。30分钟的数值分析之后,我得到了一个包含“邮政编码-商店”信息的CSV文件,然后我把这个文件上传到了Azure Table Storage中。“ZipStore”实体是十分简单的。

Listing 8

class ZipStore: TableServiceEntity

{

// partition key is zip code

// row key is distance rank (0 is nearest)

public string StoreNumber { get; set; }

}

“partition key”存储了邮政编码。“row keys”是每个商店的靠近等级。每个“partition”代表一个邮政编码,“partition”中的每一行代表一个商店和这个邮政编码所在地的靠近程度。

现在,我们可以看一看“Store”容器了:

Listing 9

public class StoreRepository : IStoreRepository

{

readonly AzureTable<ZipStore> _zipStore;

readonly AzureTable<Store> _store;

public StoreRepository()

{

var factory = new AzureStorageFactory ();

_zipStore = (AzureTable<ZipStore>)factory.GetTable><ZipStore>();

_store = (AzureTable<Store>)factory.GetTable><Store>();

}

public IEnumerable<Store> GetNearbyStores(string ZipCode)

{

var stores = new List<Store>();

Store store;

var query = _zipStore.Query.Where(zs => zs.PartitionKey == ZipCode);

foreach (ZipStore zs in query)

{

store = _store.Get(s => s.PartitionKey == zs.StoreNumber && s.RowKey == "");

if (store != null)

stores.Add(store);

}

Return stores;

}

}

这里值得一提的是“GetNearbyStores()”方法,控制器使用这个方法来加载可用的商店列表。***个查询只指定了“partition key”(邮政编码),然后返回三个或少于三个商店。因为“row key”是距离等级,所以这个查询会按照距离的顺序来返回各个商店。而对于每个商店来说,我们使用商店号作为“partition key”,从“store”表中获取商店名,城市,国家和邮政编码。

虽然对于这个视图来说,必须要进行四次查询,但是它们都是通过“partition key”和“row key”来进行的,速度非常快。而且,你还可以购买存储空间,通过把全部的“store”实体都直接存储到“ZipStore”表中,尽量减少对单一查询的检查的方式,来获得更好的性能。

#p#

存储和队列

这个叫作“SelectStore”的处理程序用用户选择的商店和注册标记来更新“contact”,然后保存这个“contact”。

Listing 10

[HttpPost]

[CanvasAuthorize]

public ActionResult SelectStore(SelectStoreViewModel model)

{

FacebookApp app = new FacebookApp ();

Contact contact = contactRepository.GetFromFacebookId(app.UserId);

if (ModelState.IsValid)

{

contact.StoreNumber = model.StoreNumber;

contact.Registered = true;

contactRepository.Save(contact);

QueueContact(contact);

return this.CanvasRedirectToAction("SignupComplete");

}

Return View(model);

此外,为了方便Worker角色进行处理,这个控制器会把“contact”排成队列。这是“QueueContact”的完整实现:

Listing 11

private void QueueContact(Contact contact)

{

// queue the contact for the worker role.

ContactQueueMessage message = new ContactQueueMessage();

message.FacebookId = contact.PartitionKey;

contactQueue.AddMessage(message);

}

Windows Azure Toolkit可以让你更方面地使用Azure队列。对于在多个角色(一个可扩展的应用程序是由这些角色组成的)之间进行通信来说,队列是必需的。“ContactQueue”继承于一个Windows Azure Toolkit类型,“ContactQueueMessage”也是如此,它们可以让队列方法的实现变得更加简单。但是,当这个工具包从Worker角色的队列中获取消息的时候,这个工具包会才会真正地大放异彩。接下来我们将会看到这一点。

在Worker角色中Dequeuing

Worker角色做了很多的工作,但是这一切都是在响应队列消息的过程中完成的。使用Windows Azure Toolkit,我们可以在这个角色的“OnStart()”方法中创建一个队列处理程序。我们只需把这段代码添加到默认的实现中就可以了:

Listing 12

AzureStorageFactory factory = new AzureStorageFactory();

IAzureQueue<ContactQueueMessage> queue =

factory.GetQueue<ContactQueueMessage>(AzureConstants.ContactQueueName);

QueueHandler.For<ContactQueueMessage>(queue)

.Every(TimeSpan.FromSeconds(5))

.Do(new EmailAndStoreContact());

在“OnStart”中,我们创建了一个“AzureStorageFactory”对象,然后使用它来查找“contact”队列。然后,我们创建了一个处理程序,在这个例子中,它每5秒检查一次队列,如果有一个消息可用的话,它就用这个消息调用我们的消息处理器(“EmailAndStoreContact”)。因为处理队列消息是Worker角色的工作,所以,我们需要做的所有事情只是把它写入到“EmailAndStoreContact”中而已。对于这个类来说,Main方法被叫作Run,它的实现如下所示:

Listing 13

public void Run(ContactQueueMessage message)

{
Contact contact = contactRepository.Get(message.FacebookId);

if (contact != null)

{

// TODO: contact another service to send off the email with

// the premium coupon here (outside the scope of this sample)!

// store the contact to sql Azure.

SQLContact sqlContact = new SQLContact();

MapContactToSqlContact(contact, sqlContact);

sqlContactRepository.Add(sqlContact);

sqlContactRepository.Save();

}

}

这个消息处理器从队列消息中获取“contact”的Facebook ID,然后使用它从这个容器中获取“contact”。因为在这个应用程序中我们并没有真正地email什么内容,所以剩下的所有事情只是把“contact”发送到SQL Azure中而已。这里,我们使用了一个“SQLContact”对象,它是“LINQ to SQL”中的一个数据类。

究竟为什么从Azure Table Storage迁移到SQL Azure呢?因为虽然Azure表很快,但是它们并不适合进行某些特定的查询。把联系数据迁移到SQL Azure中可以生成表,其他应用程序就可以查询这个“contact”表来判断我们的活动进行的怎么样了。

#p#

起点

你可以把这个应用程序的源码当成你自己在Facebook上的营销活动的起点。就像上面讨论的那样,(除了50000个奖品)你还需要添加一些其他的东西。首先,在Worker角色中,要有email的处理程序。其次,要有一些辅助性的Facebook要素,例如:支持这个应用程序在公司页面上作为一个标签来运行,为“like”你的页面的客户提供额外的奖励,通过邀请或Wall posts,进一步促进“病毒”的传播。在大多数情况下,支持这些特性意味着直接和Facebook JavaScript API打交道。

即使你从来没有发起过你自己的活动,对于那些使用C#的Azure开发者来说,也会有很多收获的。首先,使用Windows Azure toolkit可以简化访问Azure存储表和队列的过程。其次,如果你正在编写一个Facebook应用程序,那么你可以使用Facebook C# SDK。再次,使用Worker角色可以把后台任务分离出来。***(但并非到此为止),可以让你知道如何组织你的存储结构才能给你的应用程序提供***的可扩展性。

你需要的一些工具:

这些工具的***版本可以通过下面这些地址来下载:

Windows Azure SDK的下载地址:http://msdn.microsoft.com/en-us/windowsazure/cc974146.aspx

Windows Azure Toolkit的下载地址:http://azuretoolkit.codeplex.com/

Facebook C# SDK的下载地址:http://facebooksdk.codeplex.com/

样例代码:

这些样例代码是本文写作的时候使用的一些代码。

你可以通过如下地址来下载本文的样例代码:

http://facebooksdk.codeplex.com/releases/view/60694

本文承接《在Azure上构建一个基于Facebook的营销式应用程序(上) 》

《在Azure上构建一个基于Facebook的营销式应用程序(中)》

原文名:Building a Facebook Marketing App on Azure 作者:Steve Apiki

【本文乃51CTO精选译文,转载请标明出处!】
 

【编辑推荐】 

  1. 在Azure上构建一个基于Facebook的营销式应用程序(中)
  2. 在Azure上构建一个基于Facebook的营销式应用程序(上)
  3. 无需顶礼膜拜 三步打造经济高效的云基础架构

 

 

 

责任编辑:王勇 来源: 来源:51CTO
相关推荐

2011-03-14 14:47:50

2011-03-14 15:10:10

AzureFacebook

2011-11-23 10:06:32

Azure微软移动应用

2011-03-10 10:45:47

Azure“Hello Worl

2011-03-15 19:45:27

Windows Azu

2010-11-09 10:37:21

2021-07-14 17:39:46

ReactRails API前端组件

2023-09-21 08:00:00

ChatGPT编程工具

2011-03-22 09:45:56

Windows AzuSilverlight

2010-07-12 10:11:27

ibmdwWeb

2023-08-22 20:55:04

AzureLLMTypeChat

2011-03-22 10:03:55

Windows AzuSilverlight

2018-12-13 11:10:21

OpenSnitchLinux防火墙

2018-11-14 19:00:24

PythonRedis共享单车

2010-01-08 12:14:44

ibmdwAndroid

2021-02-17 11:05:34

PythonPyQt代码

2015-03-10 09:51:56

云开发云应用程构建PaaS

2011-05-11 10:58:39

iOS

2015-10-14 10:43:17

PaaSSaaS应用构建

2011-03-21 14:31:36

Azure应用程序
点赞
收藏

51CTO技术栈公众号