1

我不知道如何使用 rust 从 AWS Lambda 发出简单的 HTTP 请求而不会出现分段错误。无论我是使用带有兼容层的 tokio-0.2 还是 tokio-0.3,我都会收到此错误。它看起来像是lambda_http用 tokio-0.2 编译的,所以它应该可以工作。

Cargo.toml

[package]
name = "req"
version = "0.1.0"
authors = ["X"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
lambda_http = { version = "0.2.0-beta.1", git = "https://github.com/awslabs/aws-lambda-rust-runtime" }
tokio = { version = "0.3.4", features = ["full"] }
tokio-compat-02 = "0.1.2"
reqwest = { version = "0.10.9", features = ["json"] }

main.rs

use lambda_http::{
    handler,
    lambda::{self, Context},
    IntoResponse, Request,
};
// NOTE:
// when using tokio-0.2 alone, you get a segmentation fault
// when tokio-0.2 compatibility is enabled with tokio-0.3, you get a segmentation fault
// when tokio-0.2 compatibility is not enabled with tokio-0.3, 'main' panics because 'there is
// no reactor running, must be called from the context of Tokio runtime'
// use tokio_compat_02::FutureExt;

pub type Error = Box<dyn std::error::Error + Send + Sync + 'static>;

#[tokio::main]
async fn main() -> Result<(), Error> {
    lambda::run(handler(func)).await?;
    // NOTE: [tokio-0.2 compat] - this doesn't help
    // lambda::run(handler(func)).compat().await?;
    Ok(())
}

async fn func(_: Request, _: Context) -> Result<impl IntoResponse, Error> {
    let _res = reqwest::get("https://www.google.com").await?;
    // NOTE: [tokio-0.2 compat] - this doesn't help
    // let _res = reqwest::get("https://www.google.com").compat().await?;
    Ok("success")
}

deploy.sh

PKG_CONFIG_ALLOW_CROSS=1 cargo build --release --target x86_64-unknown-linux-musl
cp target/x86_64-unknown-linux-musl/release/req target/x86_64-unknown-linux-musl/release/bootstrap
zip -j target/x86_64-unknown-linux-musl/release/bootstrap.zip target/x86_64-unknown-linux-musl/release/bootstrap
# aws lambda create-function \
#   --function-name reqwest-test \
#   --handler doesnt.matter \
#   --zip-file fileb://target/x86_64-unknown-linux-musl/release/bootstrap.zip \
#   --runtime provided \
#   --role [REMOVED] \
#   --environment Variables={RUST_BACKTRACE=1} \
#   --tracing-config Mode=Active
aws lambda update-function-code \
  --function-name reqwest-test \
  --zip-file fileb://target/x86_64-unknown-linux-musl/release/bootstrap.zip

event.json

{
  "headers": {
    "accept": "*/*",
    "content-length": "0",
    "host": "xxx.execute-api.us-east-1.amazonaws.com",
    "user-agent": "curl/7.64.1",
    "x-amzn-trace-id": "Root=1-5eb33c07-de25b420912dee103a5db434",
    "x-forwarded-for": "65.78.31.245",
    "x-forwarded-port": "443",
    "x-forwarded-proto": "https"
  },
  "isBase64Encoded": false,
  "rawPath": "/",
  "rawQueryString": "",
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "xxx",
    "domainName": "xxx.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "xxx",
    "http": {
      "method": "GET",
      "path": "/",
      "protocol": "HTTP/1.1",
      "sourceIp": "65.78.31.245",
      "userAgent": "curl/7.64.1"
    },
    "requestId": "MIZRNhJtIAMEMDw=",
    "routeKey": "$default",
    "stage": "$default",
    "time": "06/May/2020:22:36:55 +0000",
    "timeEpoch": 1588804615616
  },
  "routeKey": "$default",
  "version": "2.0"
}
4

1 回答 1

2

这可以通过不与在 glibc 中动态链接的 openssl 交叉编译来解决。您可以将其更改为reqwest = { version = "0.45.0", default-features = false, features = ["rustls-tls"] }. 如果你使用rusoto的是 crates,除了features = ["rustls"].

于 2020-11-29T22:13:22.117 回答