在AWS Lambda中使用Rust调用二进制文件。

huangapple go评论79阅读模式
英文:

Invoking binary in aws lambda with rust

问题

我有以下的rust aws lambda函数

```rust
use std::io::Read;
use std::process::{Command, Stdio};
use lambda_http::{run, service_fn, Body, Error, Request, RequestExt, Response};
use lambda_http::aws_lambda_events::serde_json::json;

/// 这是函数的主体部分。
/// 在其中编写你的代码。
/// 在以下网址中有一些代码示例:
/// - https://github.com/awslabs/aws-lambda-rust-runtime/tree/main/examples
async fn function_handler(_event: Request) -> Result<Response<Body>, Error> {
    // 从请求中提取一些有用的信息
    let program = Command::new("./myProggram")
        .stdout(Stdio::piped())
        .output()
        .expect("无法执行进程");

    let data = String::from_utf8(program.stdout).unwrap();
    let parsed = data.split("\n").filter(|x| !x.is_empty()).collect::<Vec<&str>>();

    // 返回实现了IntoResponse的东西。
    // 它将自动由运行时序列化为正确的响应事件
    let resp = Response::builder()
        .status(200)
        .header("content-type", "application/json")
        .body(json!(parsed).to_string().into())
        .map_err(Box::new)?;
    Ok(resp)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::INFO)
        // 禁止在每个日志行中打印模块名称。
        .with_target(false)
        // 禁用时间很方便,因为CloudWatch会添加摄取时间。
        .without_time()
        .init();

    run(service_fn(function_handler)).await
}

这里的想法是要以JSON格式返回来自二进制文件的响应。

我使用cargo lambda编译函数,它会生成bootstrap文件,然后我通过手动包含bootstrap二进制文件和myProgram二进制文件来进行压缩。

当我在lambda面板中测试我的函数时,通过向其发送事件,我会得到带有正确头部等的响应,但响应主体为空。
我通过在aws面板上部署我的函数,在Amazon Linux 2上的自定义运行时上载zip文件。

当我在本地使用cargo lambda watchcargo lambda invoke进行测试时,响应主体会填充为myProgram的标准输出解析为JSON。

对于实际云端出现什么问题,任何想法或想法都非常感激!


<details>
<summary>英文:</summary>

So I have the following rust aws lambda function:

use std::io::Read;
use std::process::{Command, Stdio};
use lambda_http::{run, service_fn, Body, Error, Request, RequestExt, Response};
use lambda_http::aws_lambda_events::serde_json::json;

/// This is the main body for the function.
/// Write your code inside it.
/// There are some code example in the following URLs:
/// - https://github.com/awslabs/aws-lambda-rust-runtime/tree/main/examples
async fn function_handler(_event: Request) -> Result<Response<Body>, Error> {
// Extract some useful information from the request
let program = Command::new("./myProggram")
.stdout(Stdio::piped())
.output()
.expect("failed to execute process");

let data = String::from_utf8(program.stdout).unwrap();
let parsed = data.split(&quot;\n&quot;).filter(|x| !x.is_empty()).collect::&lt;Vec&lt;&amp;str&gt;&gt;();

// Return something that implements IntoResponse.
// It will be serialized to the right response event automatically by the runtime
let resp = Response::builder()
    .status(200)
    .header(&quot;content-type&quot;, &quot;application/json&quot;)
    .body(json!(parsed).to_string().into())
    .map_err(Box::new)?;
Ok(resp)

}

#[tokio::main]
async fn main() -> Result<(), Error> {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::INFO)
// disable printing the name of the module in every log line.
.with_target(false)
// disabling time is handy because CloudWatch will add the ingestion time.
.without_time()
.init();

run(service_fn(function_handler)).await

}


The idea here is that I want to return the response from the binary in JSON format.

I&#39;m compiling the function with **cargo lambda** which is producing **bootstrap** file, then I&#39;m zipping it manually by including the **bootstrap** binary and the **myProgram** binary.

When I test my function in the lambda panel by sending event to it I get the response with the right headers etc. but the response body is empty.
I&#39;m deploying my function thru the aws panel, on **Custom runtime on Amazon Linux 2** by uploading the zip file.

When I test locally with **cargo lambda watch** and **cargo lambda invoke** the response body is filled with the **myProgram** stdout parsed to json.

Any ideas or thoughts on what goes wrong in the actual cloud are much appreciated!

</details>


# 答案1
**得分**: -1

我的问题出在二进制文件中的动态链接库上。实际上,它是Python二进制文件,缺少特定版本的GLIBC。在我的情况下,最简单的解决方案是在Amazon Linux 2上编译**myProgram**。

<details>
<summary>英文:</summary>

My problem was with the dynamically linked libraries in the binary. It is actually python binary and it was missing specific version of GLIBC.
The easiest solution in my case was to compile **myProgram** on Amazon Linux 2

</details>



huangapple
  • 本文由 发表于 2023年1月9日 18:05:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75055685.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定