lambda调用有效负载错误

时间:2018-05-19 17:12:23

标签: 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"
}

为什么当我手动输出数据并对其进行测试时它才起作用,但是当我以编程方式调用函数时却没有?

----- ------ EDIT

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

1 个答案:

答案 0 :(得分:2)

错误在于InvokeInput中的ClientContext分配。

至少在最初尝试将ClientContext注释掉-这样可以使其正常工作。 Doco声明:

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,那是一个单独的练习。我仍在尝试找出答案。