如何安排任务调用 gRPC 方法?

Posted

技术标签:

【中文标题】如何安排任务调用 gRPC 方法?【英文标题】:How to schedule task to call gRPC method? 【发布时间】:2019-11-04 10:51:11 【问题描述】:

我有 .Net 服务器在 Google Kubernetes Engine 中运行。它被配置为通过 Google Cloud Endpoints 使用 gRPC。现在我需要安排任务每天调用一次我的 gRPC 方法。


我尝试的第一件事是使用 Google Cloud Scheduler 直接调用 http 方法。为此我有:

在我的服务器上设置 HTTP 到 gRPC 转码以通过 http 调用我的 gRPC 方法。 如here 所述创建并启用 SSL 证书。 在 IAM 和管理控制台中创建了具有服务帐户令牌创建者和服务帐户用户权限的服务帐户。 使用我的 url 和 Auth 标头作为 OIDC 令牌创建了 Cloud Scheduler 作业,并在上面创建了服务帐户。 使用以下参数(不仅是它们)部署了 Google Cloud Endpoints 配置:
authentication:
  providers:
  - id: google_service_account
    issuer: MY_SERVICE_ACCOUNT_EMAIL
    jwks_uri: https://www.googleapis.com/robot/v1/metadata/x509/MY_SERVICE_ACCOUNT_EMAIL
  rules:
  - selector: "*"
    requirements:
      - provider_id: google_service_account

之后,当我运行调度程序作业时,它返回结果“失败”。它在日志中写入 ERROR,状态为 UNKNOWN。


我尝试的第二件事是使用 Google Cloud Scheduler 在 Pub Sub 主题中发布消息,并将我的服务器作为订阅者。 也失败了,因为我无法验证 Google Cloud Endpoints 域的所有权。我在这里问了一个问题:How to verify ownership of Google Cloud Endpoints service URL?


现在的问题是:假设以下环境,调度调用 gRPC 方法的任务的最佳方法是什么:

    .Net 服务器在 GKE 上运行 gRPC 自动定期调用该任务(我可以手动调用,但没有意义)

【问题讨论】:

【参考方案1】:

所以您可以手动进行 HTTP 调用,但不能通过 Google Cloud Scheduler 自动进行,对吗?

如果是,请在云控制台 Endpoint Logging 中检查请求是否到达 Cloud Endpoint Proxy,它可能会给您一些提示。

【讨论】:

如果我直接调用 http 方法,我可以在 Endpoint 日志中看到“Invalid JWT token”错误。没关系,因为我没有在浏览器中进行身份验证。但是当 Google Scheduler 发出此调用时,我在 Endpoints 日志中看不到任何内容。 我意识到当我在浏览器中打开链接时,我得到“不受信任的证书”窗口。我第一次单击继续,从那时起它显示“无效的 JWT 令牌”错误,没有新的警告窗口。这可能是阻止 Google Scheduler 工作的原因吗? 我认为问题出在您的调度程序配置中。不知何故,它未能将请求发送到端点。 调度程序配置非常简单。我重新检查了 url 和服务帐户电子邮件(我以前做过)没有成功。我是否正确理解 OIDC 令牌类型的身份验证是我需要的(通过端点消费的 JWT 令牌授权调度程序请求)? 这取决于端点的服务配置。如果您允许任何人进行该调用,您可以将其配置为不需要 JWT 令牌。也许您应该先尝试一下,以排除调度程序中的任何令牌生成问题。【参考方案2】:

分布式调度器 更多细节参考sourcedcodeDistributed scheduler

此应用程序可以在不同的主机上运行,​​并提供以下功能: 安排在特定时间或定期执行任意命令。 与应用程序通信有两种方式:gRPC 和 REST。偏僻的 接口是 在dsched.proto 文件中指定 相应的 REST API 也可以在那里以 API 的形式找到 注释。我们还提供生成的 Swagger 文件。 为了指定任务执行时间,我们使用 cron 采用的符号。 计划任务存储在文件中,并在启动时自动加载。

建筑

Install gRPC
Install gRPC gateway

为了解析 crontab 语句并安排任务执行,我们使用了 gopkg.in/robfig/cron.v2 库。 所以它也应该安装:go get -u gopkg.in/robfig/cron.v2. 文档可以在这里找到

获取dsched包:去获取

-u gitlab.com/andreynech/dsched

现在可以在 dscheduler 中运行标准的 go build 命令和 用于为调度程序和REST/JSON API 生成二进制文件的网关目录 网关。检查我们的 CI配置文件看我们如何 搭建搭建环境。

跑步 所有调度功能都由 dscheduler 可执行文件实现。所以 它可以在系统启动时或按需运行。如 dscheduler --help 所述, 有两个命令行参数:

-i string - File name to store task list (default "/var/run/dscheduler.db")
-p string - Endpoint to listen (default ":50051")

如果需要提供REST/JSON API,网关应用位于 网关目录应该运行。它可以驻留在同一主机上 dscheduler,但通常是可以通过以下方式访问的其他主机 HTTP 来自外部,同样可以与运行的 dscheduler 对话 内部网络。这种设置也是拆分调度程序和 网关在两个可执行文件中。网关主要是生成的应用程序和 支持通过运行 gateway --help 描述的多个command-line 参数。 重要参数是-sched_endpoint 字符串,它是调度程序的端点 服务(默认“本地主机:50051”)。它指定主机名和端口 dscheduler 在哪里监听请求。

计划任务(测试) 调度服务器的控制方式有以下三种:

使用在cli/目录中实现的Go客户端 使用py_cli目录中实现的Python客户端 使用REST/JSON API 网关和curl

Go 和 Python 客户端具有相似的命令行参数集。

$ ./cli --help

cli的使用:

 -a string
        The command to execute at time specified by -c parameter
  -c string
        Statement in crontab format describes when to execute the command
  -e string
        Host:port to connect (default "localhost:50051")
  -l    List scheduled tasks
  -p    Purge all scheduled tasks
  -r int
        Remove the task with specified id from schedule
  -s    Schedule task. -c and -a arguments are required in this case
They are using gRPC protocol to talk to scheduler server. Here are several
example invocations:

$ ./cli -l list currently scheduled tasks

$ ./cli -s -c "@every 0h00m10s" -a "df" schedule df command for
execution every 10 seconds

$ ./cli -s -c "0 30 * * * *" -a "ls -l" schedule ls -l command to
run every 30 minutes

$ ./cli -r 3 remove task with ID 3

$ ./cli -p remove all scheduled tasks

也可以使用 curl 调用 dscheduler 功能 REST/JSON API 网关。假设 dscheduler 和网关应用程序 正在运行,这里有一些调用来列出、添加和删除调度 来自同一主机(本地主机)的条目:

curl 'http://localhost:8080/v1/scheduler/list' list currently scheduled tasks

curl -d '"id":0, "cron":"@every 0h00m10s", "action":"ls"' -X POST 'http://localhost:8080/v1/scheduler/add' schedule ls command for execution every 10 seconds

curl -d '"id":0, "cron":"0 30 * * * *", "action":"ls -l"' -X POST 'http://localhost:8080/v1/scheduler/add' schedule ls -l to run every 30 minutes

curl -d '"id":2' -X POST 'http://localhost:8080/v1/scheduler/remove' remove task with ID 2.

curl -X POST 'http://localhost:8080/v1/scheduler/removeall' remove all scheduled tasks

所有更改都会自动保存在文件中。

关于调度器服务发现的思考 在大型部署场景(如数百台主机)中,它可能是 找出调度程序所在的所有 IP 地址和端口的挑战性问题 服务启动。添加对 Zeroconf 的支持非常容易 (Bonjour/Avahi) 技术来简化服务发现。作为替代方案,它 可能可以实现类似于 CORBA 命名服务的东西 运行服务注册自己的位置和命名服务的位置 众所周知。我们决定在决定特定的之前收集反馈 服务发现实现。所以非常欢迎您的意见!

【讨论】:

以上是关于如何安排任务调用 gRPC 方法?的主要内容,如果未能解决你的问题,请参考以下文章

java版gRPC实战之二:服务发布和调用

gRPC C++从入门到无敌教程什么是gRPC

协议指定 void 参数类型时未调用 gRPC node-js 方法

gRPC 服务器如何调用 REST 端点

如何使用异步 GRPC 调用有效地管理内存

grpc