使用 .NET 创建和部署 HTTP Cloud Run functions

本指南将引导您完成用 Java 运行时编写 Cloud Functions 函数的过程。Cloud Run 函数有两种类型:

  • HTTP 函数,通过标准 HTTP 请求调用。
  • 事件驱动函数,由 Cloud 基础架构中的事件触发,例如 Pub/Sub 主题中收到消息或 Cloud Storage 存储桶中发生更改。

本文档介绍了如何创建简单的 HTTP 函数并使用 MavenGradle 来构建它。

如需了解详情,请参阅编写 HTTP 函数编写事件驱动型函数

准备工作

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Cloud Functions, Cloud Build, Artifact Registry, Cloud Run, and Cloud Logging APIs.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the Cloud Functions, Cloud Build, Artifact Registry, Cloud Run, and Cloud Logging APIs.

    Enable the APIs

  8. 安装并初始化 Google Cloud SDK
  9. 使用以下命令更新和安装 gcloud 组件。
    gcloud components update
  10. 准备开发环境。

    转到 Java 设置指南

创建函数

本部分介绍如何创建函数。

Maven

  1. 在本地系统上为函数代码创建一个目录:

    Linux 或 Mac OS X

     mkdir ~/helloworld
     cd ~/helloworld
    

    Windows

     mkdir %HOMEPATH%\helloworld
     cd %HOMEPATH%\helloworld
    
  2. 创建项目结构以包含源目录和源文件。

    mkdir -p ~/helloworld/src/main/java/functions
    touch ~/helloworld/src/main/java/functions/HelloWorld.java
    
  3. 将以下内容添加到 HelloWorld.java 文件中:

    
    package functions;
    
    import com.google.cloud.functions.HttpFunction;
    import com.google.cloud.functions.HttpRequest;
    import com.google.cloud.functions.HttpResponse;
    import java.io.BufferedWriter;
    import java.io.IOException;
    
    public class HelloWorld implements HttpFunction {
      // Simple function to return "Hello World"
      @Override
      public void service(HttpRequest request, HttpResponse response)
          throws IOException {
        BufferedWriter writer = response.getWriter();
        writer.write("Hello World!");
      }
    }

    此示例函数会输出问候语“Hello World!”

Gradle

  1. 在本地系统上为函数代码创建一个目录:

    Linux 或 Mac OS X

     mkdir ~/helloworld-gradle
     cd ~/helloworld-gradle
    

    Windows

     mkdir %HOMEPATH%\helloworld-gradle
     cd %HOMEPATH%\helloworld-gradle
    
  2. 创建项目结构以包含源目录和源文件。

     mkdir -p src/main/java/functions
     touch src/main/java/functions/HelloWorld.java
    
  3. 将以下内容添加到 HelloWorld.java 文件中:

    
    package functions;
    
    import com.google.cloud.functions.HttpFunction;
    import com.google.cloud.functions.HttpRequest;
    import com.google.cloud.functions.HttpResponse;
    import java.io.BufferedWriter;
    import java.io.IOException;
    
    public class HelloWorld implements HttpFunction {
      // Simple function to return "Hello World"
      @Override
      public void service(HttpRequest request, HttpResponse response)
          throws IOException {
        BufferedWriter writer = response.getWriter();
        writer.write("Hello World!");
      }
    }

    此示例函数会输出问候语“Hello World!”

指定依赖项

下一步是设置依赖项:

Maven

将目录切换到您之前创建的 helloworld 目录,然后创建 pom.xml 文件:

 cd ~/helloworld
 touch pom.xml

如需使用 Maven 管理依赖项,请在项目的 pom.xml 文件内的 <dependencies> 部分中指定依赖项。对于此练习,请将以下内容复制到 pom.xml 文件中。

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example.functions</groupId>
  <artifactId>functions-hello-world</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <properties>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
  </properties>

  <dependencies>
    <!-- Required for Function primitives -->
    <dependency>
      <groupId>com.google.cloud.functions</groupId>
      <artifactId>functions-framework-api</artifactId>
      <version>1.1.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <!--
          Google Cloud Functions Framework Maven plugin

          This plugin allows you to run Cloud Functions Java code
          locally. Use the following terminal command to run a
          given function locally:

          mvn function:run -Drun.functionTarget=your.package.yourFunction
        -->
        <groupId>com.google.cloud.functions</groupId>
        <artifactId>function-maven-plugin</artifactId>
        <version>0.11.0</version>
        <configuration>
          <functionTarget>functions.HelloWorld</functionTarget>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

如需查看基于 Maven 的完整示例,请参阅 helloworld

Gradle

将目录切换到您之前创建的 helloworld-gradle 目录,然后创建 build.gradle 文件:

 cd ~/helloworld-gradle
 touch build.gradle

如需使用 Gradle 管理依赖项,请在项目的 build.gradle 文件中指定依赖项。对于此练习,请将以下内容复制到 build.gradle 文件中。请注意,此 build.gradle 文件包含一项自定义任务,可以帮助您在本地运行函数。

apply plugin: 'java'

repositories {
  jcenter()
  mavenCentral()
}
configurations {
    invoker
}

dependencies {
  // Every function needs this dependency to get the Functions Framework API.
  compileOnly 'com.google.cloud.functions:functions-framework-api:1.1.0'

  // To run function locally using Functions Framework's local invoker
  invoker 'com.google.cloud.functions.invoker:java-function-invoker:1.3.1'

  // These dependencies are only used by the tests.
  testImplementation 'com.google.cloud.functions:functions-framework-api:1.1.0'
  testImplementation 'junit:junit:4.13.2'
  testImplementation 'com.google.truth:truth:1.4.0'
  testImplementation 'org.mockito:mockito-core:5.10.0'

}

// Register a "runFunction" task to run the function locally
tasks.register("runFunction", JavaExec) {
  main = 'com.google.cloud.functions.invoker.runner.Invoker'
  classpath(configurations.invoker)
  inputs.files(configurations.runtimeClasspath, sourceSets.main.output)
  args(
    '--target', project.findProperty('run.functionTarget') ?: '',
    '--port', project.findProperty('run.port') ?: 8080
  )
  doFirst {
    args('--classpath', files(configurations.runtimeClasspath, sourceSets.main.output).asPath)
  }
}

如需查看基于 Gradle 的完整示例,请参阅 helloworld-gradle

在本地构建和测试函数

在部署函数之前,您可以在本地构建和测试该函数:

Maven

  1. 运行以下命令以确认函数已构建:

    mvn compile
    

    您还可以选择使用 mvn package 命令来编译 Java 代码、运行任何测试以及将代码打包到目标目录内的 JAR 文件中。您可以点击此处详细了解 Maven 构建生命周期。

  2. 使用以下命令启动函数:

    mvn function:run
    
  3. 在浏览器中访问 http://localhost:8080,或从其他窗口运行 curl localhost:8080,以测试函数。

    如需了解详情,请参阅向本地函数发送请求

Gradle

  1. 运行以下命令以确认函数已构建:

    gradle build
    
  2. 使用以下命令启动函数:

    gradle runFunction -Prun.functionTarget=functions.HelloWorld
    
  3. 在浏览器中访问 http://localhost:8080,或从其他窗口运行 curl localhost:8080,以测试函数。

    如需了解详情,请参阅向本地函数发送请求

部署函数

如需部署函数,请在 helloworld 目录(如果您使用的是 maven)或 helloworld-gradle 目录(如果您使用的是 Gradle)中运行以下命令:

  gcloud functions deploy java-http-function \
    --gen2 \
    --entry-point=functions.HelloWorld \
    --runtime=java21 \
    --region=REGION \
    --source=. \
    --trigger-http \
    --allow-unauthenticated

REGION 替换为要部署函数的 Google Cloud 区域的名称(例如 us-west1)。

通过可选的 --allow-unauthenticated 标志,您可以在不进行身份验证的情况下访问函数。

java-http-function 是在 Google Cloud 控制台中用来标识函数的注册名称,而 --entry-point 用于指定函数的完全限定类名称 (FQN)。

测试已部署的函数

  1. 函数部署后,请记下 gcloud functions deploy 命令输出中的 uri 属性,或使用以下命令检索该属性:

    gcloud functions describe java-http-function \
      --region=REGION
    

    REGION 替换为您在其中部署函数的 Google Cloud 区域的名称(例如 us-west1)。

  2. 在浏览器中访问此网址。该函数将返回一条“Hello World!”消息。

查看函数日志

使用命令行工具查看日志

您可以使用 Cloud Logging 界面或通过 Google Cloud CLI 查看函数的日志。

如需使用 gcloud CLI 查看函数的日志,请使用 logs read 命令:

    gcloud functions logs read \
      --gen2 \
      --limit=10 \
      --region=REGION \
      java-http-function

REGION 替换为您在其中部署函数的 Google Cloud 区域的名称(例如 us-west1)。

输出类似以下内容:

LEVEL: I
NAME: my-first-function
TIME_UTC: 2023-05-29 23:09:57.708
LOG:

LEVEL: I
NAME: my-first-function
TIME_UTC: 2023-05-29 23:05:53.257
LOG: Default STARTUP TCP probe succeeded after 1 attempt for container "my--first--function-1" on port 8080.

LEVEL:
NAME: my-first-function
TIME_UTC: 2023-05-29 23:05:53.248
LOG: 2023-05-29 23:05:53.248:INFO:oejs.Server:main: Started @892ms

使用日志记录信息中心查看日志

要使用日志记录信息中心查看函数的日志,请打开 Cloud Run functions 概览页面,点击列表中的函数名称,然后点击日志标签页。