使用 Compute Engine 和 REST 构建移动应用

在 Compute Engine 上运行移动后端并使用 REST 作为移动应用和后端服务器之间的通信协议具有以下几个优点:

  • 它是将本地或虚拟机上运行的现有服务移动到 Google Cloud 的最快方法。
  • 可让您完全控制虚拟机和服务器配置。
  • 您可以使用第三方库。
  • 您可以配置自动调节程序调整虚拟机的数量以满足需求。

在 Compute Engine 上运行服务的缺点是需要自行维护和更新服务器。

本教程将指导您构建一个名为 Stickynotes 的示例移动应用。 此示例应用使用 REST 连接到在 Compute Engine 上运行的后端服务。

Stickynotes 示例包括前端移动应用和后端服务的代码,它们在以下工作流中协同工作:

  1. 移动应用允许您在文本字段中输入消息。
  2. 该应用将您的消息发送到后端服务中的 REST 端点。
  3. 后端服务使用 draw2d 库创建包含文本消息的图片。
  4. 后端服务将图片返回到移动应用。
  5. 移动应用会显示嵌入了消息的图片。

客户端应用为 iOS 应用,而后端服务使用 Go 编程语言编写。

目标

本教程介绍如何实现以下目标:

  • 创建一个连接到后端服务中的 REST 端点的 iOS 移动应用。
  • 在 Compute Engine 上配置并运行 REST 后端服务。

费用

本教程使用 Compute Engine 实例,它是 Google Cloud 的收费组件。

请使用价格计算器根据您的预计使用情况来估算费用。 GCP 新用户可能有资格免费试用

准备工作

  1. 登录您的 Google Cloud 帐号。如果您是 Google Cloud 新手,请创建一个帐号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

  3. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

安装以下软件:

克隆示例代码

运行以下命令以克隆示例代码:

git clone https://github.com/GoogleCloudPlatform/ios-docs-samples.git

然后导航到 /solutions/stickynoteapi/REST 目录以查找此解决方案的示例代码。

在本地运行服务器

/stickynoteapi/REST/Go 目录中,运行以下命令:

sh SETUP

该命令显示以下输出:

1. Set gopath and search path
2. Get the server and client dependencies
3. Build the server and client
4. Stop any previously-running instances of the server
5. Start the server
6. Run the client
2016/03/02 11:34:48 OK: message.png
7. Open the image in message.png

此设置还运行本地客户端以使用短语“Remember the milk”测试服务器。服务器生成包含相应图片的 message.png 文件。

Remember the Milk.

如需使用命令行客户端根据您自己的消息生成图片,请运行以下命令:

./client "This is a test..."

/stickynoteapi/REST/Go/go/src/server/server.go 文件包含运行 REST 服务器的代码。main 函数定义根级目录的处理程序并侦听端口 8080 上的流量。

func main() {
	http.HandleFunc("/stickynote", handler)
	http.ListenAndServe(":8080", nil)
	//http.ListenAndServeTLS(":443", "ssl.crt", "ssl.key", nil)
}

服务器将传入请求路由到 handler 函数,该函数执行以下操作:

  1. 从 REST 请求中提取文本消息。
  2. 使用 sticky.go 中定义的函数以根据文本消息构建图片。
  3. 通过 REST 响应将图片返回给客户端。
func handler(w http.ResponseWriter, r *http.Request) {
	var sticky Sticky
	sticky.Message = r.FormValue("message")
	sticky.Centered = false
	stickyBytes, err := sticky.DrawPNG(512, 512)
	if err == nil {
		w.Write(*stickyBytes)
	}
}

使本地服务器保持运行,以便在下一部分中使用它来测试客户端应用。

使用本地服务器运行 iOS 客户端

  1. stickynoteapi/REST/Objective-C/ 目录中,使用 Xcode 打开 stickynotes.xcodeproj
  2. 选择产品 > 运行以构建并启动客户端应用。
  3. 在文本字段中输入消息,然后点击返回

以黄色便笺形式显示消息的图片将出现在文本字段下方。

This is a test...

客户端应用在 StickyNotesViewController.m 文件中设置后端服务的位置。为了便于测试,此项最初设置为端口 8080 上的 localhost。

static NSString * const kHostAddress = @"localhost:8080";

在文本字段中输入消息后点击返回时,应用会将消息编码为查询字符串,并在 REST 请求中将其发送到服务器。然后,实例应用接收 REST 响应,提取生成的图片,并在图片视图中显示该消息。以下代码展示了处理这些任务的操作:

- (IBAction) textFieldDidEndEditing:(UITextField *)textField
{
  NSString *queryString = [NSString stringWithFormat:@"http://%@/stickynote?message=%@",
                           kHostAddress,
                           [textField.text urlencode]];
  NSURL *URL = [NSURL URLWithString:queryString];
  _request = [NSMutableURLRequest requestWithURL:URL];

  NSURLSession *session = [NSURLSession sharedSession];
  _task = [session dataTaskWithRequest:_request
                     completionHandler:
           ^(NSData *data, NSURLResponse *response, NSError *error) {
             UIImage *image = [UIImage imageWithData:data];
             dispatch_async(dispatch_get_main_queue(), ^{
                              self.imageView.image = image;
                            });
           }];
  [_task resume];
}

在 Compute Engine 上运行服务器

如需在 Compute Engine 上托管服务器,请创建一个计算实例:

  1. 在 Cloud Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”

  2. 点击创建实例
  3. 名称设置为 sticky-rest
  4. 启动磁盘部分中,点击更改以开始配置您的启动磁盘。
  5. Public images 标签页上,选择 Google Drawfork Debian GNU/Linux 9

  6. 点击选择
  7. 防火墙部分中,选择 允许 HTTP 流量允许 HTTPS 流量
  8. 点击创建以创建实例。

要允许将客户端请求发送到实例,请创建防火墙规则:

  1. 转到 Cloud Console 中的防火墙页面。

    转到“防火墙”页面

  2. 创建防火墙规则页面中,输入以下信息:

    • 名称sticky-rest
    • 目标标记http-server
    • 来源 IP 地址范围0.0.0.0/0
    • 协议和端口tcp:8080
  3. 点击创建

要启动实例上的服务器,请复制服务器代码并运行设置脚本:

  1. 在虚拟机实例列表中,点击要连接的实例所在行中的 SSH

    实例名称旁边的 SSH 按钮。

  2. 记下虚拟机实例的 IP 地址。您可以在外部 IP 列中查看此地址。
  3. 将 Git 安装到该实例上:

    sudo apt update
    sudo apt install git
    
  4. 安装 Go 工具:

    sudo wget https://storage.googleapis.com/golang/go1.10.linux-amd64.tar.gz
    sudo tar -C /usr/local -xzf go1.10.linux-amd64.tar.gz
    export PATH="/usr/local/go/bin:${PATH}"
    
  5. 克隆 Stickynotes 服务器代码:

    git clone https://github.com/GoogleCloudPlatform/ios-docs-samples.git
    
  6. 启动实例上的 Stickynotes 服务器。在 /solutions/stickynoteapi/REST/Go 目录中,运行以下命令:

    sh SETUP
    

配置并运行客户端应用:

  1. 在 Xcode 中,修改 StickyNotesViewController.m 以将 localhost 更改为上一步中记录的 Compute Engine 实例的外部 IP 字段的值。

    // static NSString \* const kHostAddress = @"localhost:8080";
    static NSString \* const kHostAddress = @"[YOUR-INSTANCE-EXTERNAL-IP]:8080";
    
  2. 选择文件 >保存以保存更改。

  3. 选择产品 > 运行以构建并启动客户端应用。

  4. 在文本字段中输入消息,然后点击返回

以黄色便笺形式显示消息的图片将替换灰色背景。

Testing on remote server...

清除数据

为避免因本教程中使用的资源导致您的 Google Cloud 帐号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

为了避免产生费用,最简单的方法是删除您为本教程创建的项目。

如需删除项目,请执行以下操作:

  1. 在 Cloud Console 中,转到管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

删除实例

如需删除 Compute Engine 实例,请执行以下操作:

  1. 在 Cloud Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”

  2. 选中您的 sticky-rest 实例对应的复选框。
  3. 如需删除实例,请点击更多操作,点击删除,然后按照说明操作。

删除默认网络的防火墙规则

如需删除防火墙规则,请执行以下操作:

  1. 在 Cloud Console 中,转到防火墙页面。

    转到“防火墙”

  2. 选中要删除的防火墙规则。
  3. 如需删除防火墙规则,请点击删除

后续步骤

此示例演示了使用 REST 将移动应用连接到在 Compute Engine 上运行的代码的基础知识。要将此示例扩展到真实应用,请考虑添加以下增强功能:

  • 向服务器添加静态外部 IP 地址 - 默认情况下,与 Compute Engine 实例关联的外部地址为临时地址。在正式版应用中,可将静态外部 IP 地址附加到您的实例。如需了解详情,请参阅配置实例的 IP 地址

  • 使用凭据连接到 HTTPS 服务器 - 要求您的移动应用使用凭据向服务器进行身份验证,从而确保您的后端服务只能由该移动应用调用。使用加密的 HTTPS 协议而不是 HTTP,保护用户发送到服务器的数据的隐私权。为此,您可以在您的实例上运行 NGINX 服务器作为 SSL 代理,或者在 App Engine 柔性环境中运行后端服务器。如需了解详情,请参阅安全连接到虚拟机实例

  • 添加负载平衡和自动扩缩功能 - 通过设置负载平衡器和自动扩缩程序,在需求增长时启动更多实例,并在这些实例之间均匀地路由流量,从而妥善处理流量峰值。如需了解详情,请参阅设置 HTTP(s) 负载平衡自动扩缩实例组

  • 了解使用 gRPC 协议而非 REST - gRPC 是一个框架,使用 gRPC 时,移动应用可以直接调用后端服务上的方法,就好像它是本地对象一样。gRPC 可以帮助您提高移动应用的带宽效率,并缩短应用和 GCP 上运行的后端服务之间的延迟时间。如需查看在 Stickynotes 示例中使用 gRPC 的示例,请参阅使用 Google Compute Engine 和 gRPC 构建移动应用。

  • 使用其他方案托管后端服务 - Compute Engine 可提供对虚拟机最大限度的控制,但如果采用这种方案,则您需要手动更新和管理实例。如需查看有关在 Cloud Platform 上托管移动后端服务的其他方式的讨论,请参阅使用 Google Cloud 构建移动应用