amazon-web-services - lambda 调用有效负载错误

标签 amazon-web-services go aws-lambda

我正在尝试使用 Go SDK 调用 lambda 函数(用 Go 编写) 来自另一个应用程序,但遇到了有效负载的问题,但当我通过具有相同输出的控制台测试 lambda 函数时却没有。

这是调用 lambda 的函数:

type RedisPair struct {
    RedisKey        string      `json:"redis_key"`
    RedisValue      string      `json:"redis_value"`
}

type RedisBatch struct {
    RedisPairs      []RedisPair
    GroupId         string      `json:"group_id"`
}

func lambdawrite (redisbatch RedisBatch) {

    //fmt.Println("invoking lambda")

    fmt.Println("Batch type: ", reflect.TypeOf(redisbatch))

    payload, err := json.Marshal(redisbatch)

    fmt.Println("Payload type: ", reflect.TypeOf(payload))

    if err != nil {
        fmt.Println("Error marshalling MyGetItemsFunction request")
    }

    svc := lambda.New(session.New())
    input := &lambda.InvokeInput{
        ClientContext:  aws.String("MyApp"),
        FunctionName:   aws.String("arn:aws:lambda:us-region:arnnum:function:testrpredis"),
        InvocationType: aws.String("RequestResponse"),
        LogType:        aws.String("Tail"),
        Payload:        payload,
        Qualifier:      aws.String("$LATEST"),
    }

    result, err := svc.Invoke(input)
    if err != nil {
        if aerr, ok := err.(awserr.Error); ok {
            //error stuff...
            }
        } else {
            // Print the error, cast err to awserr.Error to get the Code and
            // Message from an error.
            fmt.Println("error 2")
            fmt.Println(err.Error())
        }
        return
    }
    //fmt.Println("good")
    fmt.Println(result)

}

这是 lambda 函数本身:

package main

import (
    "github.com/go-redis/redis"
    "github.com/aws/aws-lambda-go/lambda"
    "log"
    "os"
    "time"
)

type Event struct {
    RedisPairs      []RedisPair
    GroupId         string      `json:"group_id"`
}

type Response struct {
    Message        string    `json:"message"`
    Ok            bool    `json:"ok"`
}

type RedisPair struct {
    RedisKey   string `json:"redis_key"`
    RedisValue string `json:"redis_value"`
}

func redis_pipeline(batch Event) (Response, error) {

    clientrds := redis.NewClient(&redis.Options{
        Addr:         os.Getenv("REDIS_HOST") + ":6379",
        DialTimeout:  10 * time.Second,
        ReadTimeout:  30 * time.Second,
        WriteTimeout: 30 * time.Second,
        PoolSize:     100,
        PoolTimeout:  30 * time.Second,
    })
    clientrds.FlushDB()

    log.Print("start pipe")

    pipe := clientrds.Pipeline()

    var response Response

    log.Print("starting range lop")

    for b := range batch.RedisPairs {
        //fmt.Println("adding", batch.RedisPairs[b].RedisKey, batch.RedisPairs[b].RedisValue)
        pipe.Set(batch.RedisPairs[b].RedisKey, batch.RedisPairs[b].RedisValue, 0)
    }

    //fmt.Println(uuid, "...time now start: ", time.Now(), ", start time: ", startTime)
    log.Print("write to redis")
    _, err := pipe.Exec()
    if err != nil {

        log.Print("points error")
        response = Response{
            Message: err.Error(),
            Ok:         false,
        }
    } else {

        log.Print("points written")
        response = Response{
            Message: "Points wrttien!",
            Ok:         true,
        }
    }

    log.Print("close pipe")

    pipe.Close()

    return response, err

}

func main() {
    log.Print("start main v2")
    lambda.Start(redis_pipeline)
}

当我通过第一个函数调用 lambda 时,每次调用该函数时 lambda 日志都会显示这一点:

invalid character ')' after top-level value: SyntaxError
null

如果我将 RedisBatch 结构输出到第一个函数中的文件,并使用该输出通过 aws 控制台手动测试 lambda 函数,则它会成功运行。输出看起来也像这样:

{
  "RedisPairs": [
    {
      "redis_key": "kafka9", 
      "redis_value": "{\"metric_value_number\":1,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.035Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=NumLogSegments,topic=private.topic.lsrp.created.v1,partition=4.Value\",\"type\":null,\"region\":\"us-east-1\"}\n"
    }, 
    {
      "redis_key": "kafka10", 
      "redis_value": "{\"metric_value_number\":1,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.045Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=NumLogSegments,topic=credit-topic.v1,partition=6.Value\",\"type\":null,\"region\":\"us-east-1\"}\n"
    }, 
    {
      "redis_key": "kafka1", 
      "redis_value": "{\"metric_value_number\":0,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.063Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=LogEndOffset,topic=credit.test1122.created.v1,partition=3.Value\",\"type\":null,\"region\":\"us-east-1\"}\n"
    }, 
    {
      "redis_key": "kafka2", 
      "redis_value": "{\"metric_value_number\":0,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.074Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=LogEndOffset,topic=connect-offsets-east,partition=9.Value\",\"type\":null,\"region\":\"us-east-1\"}\n"
    }, 
    {
      "redis_key": "kafka3", 
      "redis_value": "{\"metric_value_number\":0,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.085Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=Size,topic=credit-uxtest2.created.v1,partition=9.Value\",\"type\":null,\"region\":\"us-east-1\"}\n"
    }, 
    {
      "redis_key": "kafka5", 
      "redis_value": "{\"metric_value_number\":60,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.097Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=LogEndOffset,topic=rte.enrichment.rules,partition=7.Value\",\"type\":null,\"region\":\"us-east-1\"}\n"
    }
  ], 
  "group_id": "testehb4"
}

为什么当我手动输出数据并测试它时它可以工作,但当我以编程方式调用该函数时却不起作用?

-----编辑------

刚刚意识到这适用于 Event 调用类型,但不适用于 RequestResponse 类型。两者之间发送有效负载的方式有什么区别?似乎找不到合适的文档或示例...

最佳答案

错误在于 InvokeInput 中 ClientContext 的赋值。

尝试,至少一开始,注释掉 ClientContext - 这会让它工作。该文档指出:

ClientContext JSON 必须采用 base64 编码,并且最大大小为 3583 字节。

input := &lambda.InvokeInput{
    // ClientContext:  aws.String("MyApp"),
    FunctionName:   aws.String("arn:aws:lambda:us-region:arnnum:function:testrpredis"),
    InvocationType: aws.String("RequestResponse"),
    LogType:        aws.String("Tail"),
    Payload:        payload,
    Qualifier:      aws.String("$LATEST"),
}

如果您想使用 ClientContext,那是一个单独的练习。我还在想办法。

关于amazon-web-services - lambda 调用有效负载错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50427698/

相关文章:

node.js - 如何使用 kafka-node 将 AWS Bitnami Certified Kafka AMI 与 Elastic Beanstalk nodejs 环境连接起来

http - 提供大型视频文件失败

xml - Golang Xml Unmarshal,没有值(value)

go - 在 Go 中向特定客户端发送 Websocket 消息(使用 Gorilla)

amazon-web-services - 我们如何为使用开发工具包发送到 AWS Lambda 的通知启用 SNS 日志记录?

amazon-web-services - 是否需要 AWS SQS

javascript - 使用 STS 凭证上传 aws-sdk - 403 错误

amazon-web-services - Strapi v3.0.0.alpha.12.4不适用于AWS

apache - 使用AWS ELB将所有http通信重新路由到https

performance - 扫描 DynamoDB 表或查询二级全局索引或本地索引(什么是最佳解决方案)