Google Cloud Functions (Serverless) with Quarkus REST, Undertow, or Reactive Routes

利用 `quarkus-google-cloud-functions-http`扩展,您能够利用 Quarkus REST(Jakarta REST)、Undertow(Servlet)、反应式路由或 Funqy HTTP编写微服务,并且能够将这些微服务部署到 Google Cloud Functions 运行时。 一次 Google Cloud Functions 部署可以代表任意数量的 Jakarta REST、Servlet、反应式路由或 Funqy HTTP端点。 :iokays-category: quarkus :iokays-path: modules/ROOT/pages/_includes/extension-status.adoc :keywords: Quarkus, 中文文档, 编程技术

该技术被认为是 {extension-status}。 有关可能状态的完整列表,请查看我们的 FAQ entry.

Prerequisites

如要完成本指南,您需要:

  • Roughly 15 minutes

  • An IDE

  • 安装了 JDK 17+,已正确配置 JAVA_HOME

  • Apache Maven ${proposed-maven-version}

  • 如果你想使用 Quarkus CLI, 则可以选择使用

  • 如果你想构建一个本机可执行文件(或如果你使用本机容器构建,则使用 Docker),则可以选择安装 Mandrel 或 GraalVM 以及 configured appropriately

Solution

本指南将引导您生成一个示例项目,然后创建三个使用 Jakarta REST API、Servlet API、反应式路由或 Funqy HTTPAPI 编写的 HTTP 端点。构建完成之后,您将能够将此项目部署到 Google Cloud。

如果您不想执行上述所有步骤,您可以直接转到完成的示例。

克隆 Git 存储库: git clone $${quickstarts-base-url}.git,或下载 $${quickstarts-base-url}/archive/main.zip[存档]。

解决方案位于 google-cloud-functions-http-quickstart directory中。

Creating the Maven Deployment Project

使用 `quarkus-google-cloud-functions-http`扩展创建一个应用程序。您可以使用以下 Maven 命令来创建它:

CLI
quarkus create app {create-app-group-id}:{create-app-artifact-id} \
    --no-code
cd {create-app-artifact-id}

要创建一个 Gradle 项目,添加 --gradle--gradle-kotlin-dsl 选项。 有关如何安装和使用 Quarkus CLI 的详细信息,请参见 Quarkus CLI 指南。

Maven
mvn {quarkus-platform-groupid}:quarkus-maven-plugin:{quarkus-version}:create \
    -DprojectGroupId={create-app-group-id} \
    -DprojectArtifactId={create-app-artifact-id} \
    -DnoCode
cd {create-app-artifact-id}

要创建一个 Gradle 项目,添加 -DbuildTool=gradle-DbuildTool=gradle-kotlin-dsl 选项。

适用于 Windows 用户:

  • 如果使用 cmd,(不要使用反斜杠 \ ,并将所有内容放在同一行上)

  • 如果使用 Powershell,将 -D 参数用双引号引起来,例如 "-DprojectArtifactId={create-app-artifact-id}"

Login to Google Cloud

部署应用程序需要登录 Google Cloud。可以按以下方式进行操作:

gcloud auth login

Creating the endpoints

对于这个示例项目,我们将创建四个端点:一个用于 Quarkus REST(Jakarta REST)、一个用于 Undertow(Servlet)、一个用于反应式路由以及一个用于 Funqy HTTP

这些不同的端点用于演示目的。对于实际应用程序,您应当选择一项技术并坚持使用它。

如果您不需要每种类型的端点,则可以从 `pom.xml`中移除相应的扩展。

Quarkus 支持 Cloud Functions 第 1 代和第 2 代。有关 Cloud Functions 第 2 代的概述,请参阅 Google Cloud Functions 文档上的 this page。要使用第 2 代,您必须添加 `--gen2`参数。

The Jakarta REST endpoint

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello from Quarkus REST";
    }
}

The Servlet endpoint

import java.io.IOException;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet(name = "ServletGreeting", urlPatterns = "/servlet/hello")
public class GreetingServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.addHeader("Content-Type", "text/plain");
        resp.getWriter().write("hello");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getReader().readLine();
        resp.setStatus(200);
        resp.addHeader("Content-Type", "text/plain");
        resp.getWriter().write("hello " + name);
    }
}

The Reactive Routes endpoint

import static io.quarkus.vertx.web.Route.HttpMethod.GET;

import io.quarkus.vertx.web.Route;
import io.vertx.ext.web.RoutingContext;

public class GreetingRoutes {
    @Route(path = "/vertx/hello", methods = GET)
    void hello(RoutingContext context) {
        context.response().headers().set("Content-Type", "text/plain");
        context.response().setStatusCode(200).end("hello");
    }
}

The Funqy HTTP endpoint

import io.quarkus.funqy.Funq;

public class GreetingFunqy {
    @Funq
    public String funqy() {
        return "Make it funqy";
    }
}

Build and Deploy to Google Cloud

Quarkus 强制打包您的函数,其中类型为 uber-jar,因为 Google Cloud Function 部署需要一个 JAR。

使用标准 `mvn clean package`命令打包您的应用程序。前一条命令的结果是 `target/deployment`目录中包含该项目的类和依赖项的单个 JAR 文件。

然后您将能够使用 `gcloud`将您的函数部署到 Google Cloud。

我们将使用 Java 17 运行时,但你可以通过在部署命令中使用 --runtime=java21`来切换到 Java 21 运行时,而不是使用 `--runtime=java17

gcloud functions deploy quarkus-example-http \
  --entry-point=io.quarkus.gcp.functions.http.QuarkusHttpFunction \
  --runtime=java17 --trigger-http --allow-unauthenticated --source=target/deployment

入口点始终必须设置为 io.quarkus.gcp.functions.http.QuarkusHttpFunction,因为这是一个将 Cloud Functions 和 Quarkus 集成的类。

当你第一次启动此命令时,会出现以下错误信息:

ERROR: (gcloud.functions.deploy) OperationError: code=7, message=Build Failed: Cloud Build has not been used in project <project_name> before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudbuild.googleapis.com/overview?project=<my-project> then retry.

这意味着 Cloud Build 尚未激活。要解决此错误,请打开错误中显示的网址,按照说明操作,然后等待几分钟再重试该命令。

此命令将生成一个 httpsTrigger.url,指向你的函数。

您随后可以这样调用您的端点:

  • For Jakarta REST: {httpsTrigger.url}/hello

  • For servlet: {httpsTrigger.url}/servlet/hello

  • For Reactive Routes: {httpsTrigger.url}/vertx/hello

  • For Funqy: {httpsTrigger.url}/funqy

Testing locally

本地测试函数的最简单方法是使用 Cloud Function Invoker JAR。

你可以使用以下命令通过 Maven 下载它:

mvn dependency:copy \
  -Dartifact='com.google.cloud.functions.invoker:java-function-invoker:{gcf-invoker-version}' \
  -DoutputDirectory=.

在使用 invoker 前,您首先需要通过 `mvn package`构建您的函数。

然后,您可以使用它在本地启动您的函数。

java -jar java-function-invoker-{gcf-invoker-version}.jar \
  --classpath target/deployment/google-cloud-functions-http-1.0.0-SNAPSHOT-runner.jar \
  --target io.quarkus.gcp.functions.http.QuarkusHttpFunction

`--classpath`参数需要设置为先前打包的 JAR,其中包含您的函数类和所有 Quarkus 相关类。

您的端点将在 [role="bare"][role="bare"]http://localhost:8080上提供。

What’s next?

您可以使用我们的 Google Cloud Functions Funqy binding来使用 Funqy(一个与提供商无关的函数即服务框架),该服务允许将 HTTP 函数或后台函数部署到 Google Cloud。