menu arrow_back 湛蓝安全空间 |狂野湛蓝,暴躁每天 chevron_right All_wiki chevron_right the-way-to-go_ZH_CN chevron_right eBook chevron_right 20.4.md
  • home 首页
  • brightness_4 暗黑模式
  • cloud
    xLIYhHS7e34ez7Ma
    cloud
    湛蓝安全
    code
    Github
    20.4.md
    10.17 KB / 2024-07-16 23:14:29
        # 20.4 建造你自己的 Hello world 应用
    
    现在让我们建造一个像 [20.3 节](20.3.md)中的 demo 一样的应用,但这次我们会探索得更深一些。
    
    ## 20.4.1 映像结构 (map-structure):创造一个简单的 http-handler
    
    创建一个目录,并给它起一个你的应用程序特有的名字,如:helloapp。这个应用程序的所有文件都在这个目录中。在这个目录中再创建一个名为 hello 的目录。这将包含我们的 hello 包的 Go 源代码文件。然后在 hello 目录下,创建一个名为 helloworld2.go 的文件,并赋予其以下内容(事实上与上文中的 demo 应用几乎相同):
    
    <u>[Listing 20.2 helloworld2_version1.go](examples\chapter_20\helloapp\hello\helloworld2_version1.go)</u>:
    
    ```go
    package hello
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func init() {
    	http.HandleFunc("/", handler)
    }
    
    func handler(w http.ResponseWriter, r *http.Request) {
    	fmt.Fprint(w, "Hello, world!")
    }
    ```
    
    注意包的名称:在编写独立的 Go 程序时,我们会把这段代码放在 `package main` 中,但 Go GAE Runtime 提供了 `main` 包和 HTTP Listener,所以你应该把你的代码放在你选择的包中,此时指的是 hello 包。其次,由于 Go App Engine 应用程序通过 Web 服务器与外部世界进行通信,所以编写这些应用程序非常像编写独立的 Go Web 应用程序(见[第 15 章](15.0.md))。所以我们导入 `http` 包,并为我们的应用程序中使用的不同url 模式定义处理函数。我们没有 `main()` 函数,所以处理程序的设置必须移到 `init()` 函数中去。另外,网络服务器本身的启动是由 GAE 为我们完成的。我们的 Go 包 hello 对任何请求的响应是发送一个包含 "Hello, world!"的消息。
    
    ## 20.4.2 创建配置文件 app.yaml
    
    所有的 GAE 应用程序都需要一个 yaml 配置文件 app.yaml,它包含了 GAE 的应用程序元数据(yaml 是一种文本文件格式,经常用于开源项目,更多信息见 www.yaml.org)。另外,这个文件告诉 App Engine 服务要使用哪个运行时,哪些 URL 应该由我们的 Go 程序处理。你可以从演示程序中复制一个 app.yaml 文件,把它放在映像 helloapp 里面,并删除 favicon.ico 的 handler。
    
    应用程序的映像/文件结构应该如下:
    
    ```
    helloapp\ 	// map of the GAE application
    app.yaml 	// configuration file
    hello\ 		// map containing the source files
    helloworld2.go
    ```
    
    只有app.yaml是必须的名字,映像、Go文件和包的名字可以有不同的选择,但按照惯例,它们的名字是一样的或类似的,根映像的后缀是 app。
    app.yaml 由 AppEngine 读取和解释,AppEngine 以下时间段内托管和执行你的程序:
    
    - 当您将您的应用程序上传到 AppEngine 以使其被托管。
    - 当它被执行时。
    - 当用户访问它时。
    
    它可以包含注释,前面有一个 `#`,并包含以下语句:
    
    ```yaml
    application: helloworld
    version: 1
    runtime: go
    api_version: 3
    
    # routing-table: routing of different urls to different types of handlers
    handlers:
    - url: /.*
      script: _go_app
    ```
    
    app.yaml 中的 `application: value helloworld` 是您的应用程序标识符。这个值在开发过程中可以是任何东西;以后在向 App Engine 注册您的应用程序时,您将选择一个唯一的标识符(在所有 GAE 应用程序中唯一)并更新这个值。
    
    `version` 表示您的应用程序正在运行的版本:事实上,GAE 可以并行地运行您的应用程序的几个版本,但其中一个必须被指定为默认版本。它可以包含字母数字字符,以及连字符。因此,你可以运行一个测试版本,如T2-31 和一个生产版本 P2-1。
    
    `runtime` 是编写应用程序的语言(其他允许的值是 Java 和 Python)。如果你在上传应用软件的新版本之前调整它,App Engine 将保留以前的版本,并让你使用管理控制台回退到以前的版本。
    
    `api_version` 是本 SDK 中使用的 Go API 的版本;它们可能与以前的版本不兼容。你可以在以前的 api_version SDK 中构建你的应用程序的早期版本;如果 GAE 仍然允许,它们可以继续运行,但通常有一个时间限制,而你应该将你的应用程序更新到新的api版本:bin map中的gofix工具可能能够完成大部分所需的更新。
    
    `handler` 部分是循环表 (routing table):它告诉 GAE 如何将发送到服务器上的请求映射到代码中。对于每一个传入的请求 url 模式(本地开发时在 http://localhost:8080/ 之后的部分,在云端运行时在 http://appname.appspot.com/ 之后的部分)与 url 后面的正则表达式相匹配。
    
    对于第一个匹配的 url 模式,相应的脚本会被执行。在我们的例子中,每一个路径与正则表达式 `/.*` 相匹配的 URL 请求(即:所有 URL)都应该由 Go 程序处理。`_go_app` 值是 dev_appserver.py 识别的一个神奇字符串;生产的 App Engine 服务器会忽略它。
    
    如果你看一下演示的 helloworld 应用程序的 app.yaml 文件,你会发现它在处理程序中包含一个初始部分:
    
    ```yaml
    handlers:
    - url: /favicon\.ico
      static_files: favicon.ico
      upload: favicon\.ico
    - url: /.*
      script: _go_app
    ```
    
    一些文件 (`static_files`) ,如图片,不会改变(在这个例子中是图片favicon.ico)。这些文件可以放在不同的 AppEngine 服务器上的一种共同缓存中,使它们能够更快地提供给用户。如果您的应用程序有许多这样的文件,把它们放在一个单独的目录中,按惯例命名为 static。
    
    `upload` 表示当您部署应用程序时,什么必须上传到云端;例如,如果它包含 images/(\*.ico|\*.gif|\*.jpg),它将把本地 images 目录内所有这些类型的文件上传到 AppEngine 服务器。
    
    正如我们将看到的,大多数 GAE 应用程序也使用模板文件,这些文件可以存储在根应用程序地图中,或在一个特殊的目录 tmpl 中。
    
    因此,一个 GAE 应用程序的一般结构可能是:
    
    ```
    yourapp\ 		// map of the GAE application
    		app.yaml // configuration file
    		yourpackage\ // map containing the source files
    			package1.go
    			…
    		tmpl\ // map containing template files
    			root.html
    			update.html
    			…
    		static\ // map containing static files
    			yourapp.ico
    			…
    ```
    
    与 demo 一样,在控制台窗口中进入包含 helloapp 的映像,并发出如下命令:`dev_appserver.py helloapp`
    
    或者你可以通过任何一个映像的 console 窗口并且唤醒:
    
    ```bash
    dev_appserver.py /path_to_map_helloapp/helloapp
    ```
    
    在这两种情况下,网络服务器现在都在运行,并监听 8080 端口的请求。通过在你的网络浏览器中访问以下 URL 来测试该应用程序:http://localhost:8080/
    
    你应该看到: Hello, world! 
    
    在服务器控制台,出现以下文字:
    
    ```
    $ dev_appserver.py helloapp
    INFO 2011-10-31 08:54:29,021 appengine_rpc.py:159] Server: appengine.google.com
    INFO 2011-10-31 08:54:29,025 appcfg.py:463] Checking for updates to the SDK.
    INFO 2011-10-31 08:54:29,316 appcfg.py:481] The SDK is up to date.
    WARNING 2011-10-31 08:54:29,316 datastore_file_stub.py:512] Could not read datastore
    data from /tmp/dev_appserver.datastore
    INFO 2011-10-31 08:54:29,317 rdbms_sqlite.py:58] Connecting to SQLite database ‘’
    with file ‘/tmp/dev_appserver.rdbms’
    INFO 2011-10-31 08:54:29,638 dev_appserver_multiprocess.py:637] Running application
    helloworld on port 8080: http://localhost:8080
    		<-(A)
    INFO 2011-10-31 08:56:13,148 __init__.py:365] building _go_app
    		<-(B)
    INFO 2011-10-31 08:56:15,073 __init__.py:351] running _go_app
    INFO 2011-10-31 08:56:15,188 dev_appserver.py:4143] “GET / HTTP/1.1” 200 -
    		<-(C)
    ```
    
    在 (A) 处服务器准备好了,在 (B) 处服务器编译并运行 Go 程序,在 (C) 处我们的应用程序的请求进来了,此时 HTML 输出页面被提供到服务器上。
    
    当服务器被终止或尚未启动,而客户端请求网址 http://localhost:8080/,浏览器在FireFox 中会打印出这样的信息:
    
    ```
    Unable to connect Firefox can’t establish a connection to the server at localhost:8080.
    ```
    
    ## 20.4.3 迭代开发
    
    开发应用的服务器会观察你的文件中的变化,当你更新你的源代码时(编辑+保存),它重新编译它们并重新启动你的本地应用;不需要重新启动 dev_appserver.py 
    
    现在试试:让 Web 服务器运行,然后编辑 helloworld2.go,将 "Hello, world!" 改为其他内容。重新加载 http://localhost:8080/,就可以看到变化了:这和编写 Rails 或 Django 应用程序一样,都是动态运行的。
    
    要关闭 Web 服务器,确保终端窗口处于活动状态,然后按 Ctrl+C(或适当的用于控制台的 "break "键):
    
    ```
    INFO 2011-10-31 08:56:21,420 dev_appserver.py:4143] “GET / HTTP/1.1” 200 -
    INFO 2011-10-31 08:57:59,836 __init__.py:365] building _go_app <-(D)
    INFO 2011-10-31 08:58:00,365 __init__.py:351] running _go_app
    INFO 2011-10-31 08:58:00,480 dev_appserver.py:4143] “GET / HTTP/1.1” 200 -
    ^CINFO 2011-10-31 08:58:32,769 dev_appserver_main.py:665] Server interrupted by user,
    terminating <-(E)
    ```
    
    这可以从上面第一个列表之后的服务器控制台输出中看到:在 (D) 处,apperver 看到 Go 的源代码被改变了,并重新编译;在 (E) 处,服务器被终止了。
    
    ## 20.4.4. 与 GoClipse IDE 的集成
    
    a) 窗口/首选项/Go:
    
    将所有内容指向 GAE 的 Go 根目录
    
    b) 运行/外部工具/外部工具配置/选择程序:
    
    ​	 制作新的配置:点击 New 按钮。
    ​		名称:GAE
    ​		位置:/home/user/google_appengine/dev_appserver.py 
    ​		工作目录:/home/user/workspace/bedilly/src/pkg/helloapp
    ​		参数: home/user/workspace/bedilly/src/pkg/helloapp
    ​	应用/运行 
    
    通过配置一个外部工具,部署你的应用程序也很容易:http://code.google.com/p/goclipse/wiki/DeployingToGoogleAppEngineFromEclipse
    
    ## 链接
    
    - [目录](directory.md)
    - 上一节:[安装 Go App Engine SDK](20.3.md)
    - 下一节:[使用用户服务和探索其 API](20.5.md)
    
    
    
    links
    file_download