대기 시간 없이 AWS Lambda에서 HTTP 호출

AWS Lambda에서 HTTP/REST URL을 호출하는 가장 빠른 방법은 무엇입니까?
만약 네가 회답을 필요로 한다면, 답은 매우 간단하다.
그런데 대답을 기다리고 싶지 않으면?

비대기 HTTP


Lambda 함수의 상황을 고려하여 이 함수는 처리 후 일부 지표를 누적한 후에 이 지표를 REST 집합기 서비스로 보내서 처리합니다.만약 도량이 계수기라면, 도량 요청이 때때로 실패하는 것은 중요하지 않을 수도 있습니다. 왜냐하면 다음 요청이 업데이트된 계수기의 총수를 보내기 때문입니다.이 경우 HTTP 응답을 기다리지 않는 것이 더 빠릅니다.

So how would we do this in NodeJS?


먼저 간단한 예시 요청 (오류 처리 없음) 을 보십시오. 거기서 응답을 기다립니다.
이 예에서 우리는 비동기적인'요구'노드 함수를 만들 것입니다. 이 함수는 우리가 기다릴 수 있는 약속을 되돌려줍니다.
const https = require('https')
const URL = require('url')

async function request(url, data) {
    return new Promise((resolve, reject) => {
        let req = https.request(URL.parse(url), function (res) {
            let body = ''
            res.on('data', (chunk) => { body += chunk })
            res.on('end', () => { resolve(body) })
        })
        req.write(data)
        req.end()
    })
}
우리 람다는:
exports.handler = async (event, context) {
    ...
    let result = await request('https://metric-service.com', metrics)
    return result
}
Lambda에서 HTTP 요청을 호출하기 위해 "wait"를 사용하여 요청을 보내고 응답을 기다립니다.
만약 metricaggregator 서비스가 요청을 처리하고 상태 코드를 되돌려 주는 데 950밀리초가 필요하다면, 우리는 호출할 때마다 1초의 비용을 추가로 받을 것입니다.이 대기 시간 동안, 우리의 Lambda 함수는 휴면 상태에 있지만, AWS는 여전히 우리에게 비용을 계산하고 있다.AWS Lambda를 사용하면 CPU 사용 시간이 아닌 실행 시간에 따라 요금을 계산합니다.Lambda는 매우 싸고 높은 사무량을 가지고 있지만 950밀리초의 짧은 기다림을 합치면 큰 비용이 발생할 수 있다.

기다리지 마


그렇다면 만약에 우리가 "wait"를 호출하지 않고 HTTP에서 요청한 응답을 기다리지 않는다면 무슨 일이 일어날까요?
exports.handler = async (event, context) {
    /* nowait */ request('https://example.com', metrics)
    return 'done'
}

Strange things happen.


때로는 요청을 보내고, 때로는 요청을 보내지 않습니다.
때로는 도량 집합기가 바로 요청을 받을 수도 있고, 때로는 우리 람다의 다음 운행 후에 요청을 받을 수도 있습니다.무슨 일이 일어났습니까?

냉동 람다 용기


Lambda 함수는 AWS 폭죽 용기에서 실행됩니다.Lambda 함수에서 반환하면 AWS는 즉시 컨테이너와 전체 상태를 동결합니다.다음에 Lambda를 호출할 때, 새로운 호출에 사용할 용기를 해동합니다.
만약 우리가 HTTP 요청을 보냈는데 이 요청이 인터넷을 통해 완전히 전송되지 않았다면, 만약 우리가 Lambda 함수에서 되돌아온다면, AWS는 즉시 우리의 Lambda 용기를 끊을 것이며, 일부 발송된 요청도 끊을 것이다.요청은 다음에 Lambda를 호출할 때까지 동결 상태를 유지하고 노드 이벤트 순환은 다시 처리되며 요청은 완전히 전송됩니다.

어떻게 해결합니까?


우리 잠깐 자도 돼요. 요청 발송 시간?근데 얼마나 기다려야 돼요?
exports.handler = async (event, context) {
    /* nowait */ request('https://example.com', metrics)
    await sleep(100)
    return 'done'
}

This hardly seems reliable.


요청 전송 대기 중


정확한 해결 방안은 Node req를 사용하는 것이다.(,,callback) API를 종료하고 요청이 완전히 전송될 때까지 기다리지만 응답을 기다리지 마십시오.다음은 예입니다.
const https = require('https')
const URL = require('url')

async function request(url, data) {
    return new Promise((resolve, reject) => {
        let req = https.request(URL.parse(url))
        req.write(data)
        req.end(null, null, () => {
            /* Request has been fully sent */
            resolve(req)
        })
    })
}
이전 예시에서 요청은 "req"대상의 종료 리셋이 아니라 "res"대상의 종료 리셋을 통해 해결되었습니다.
이 수정된 요청 함수는 우리 Lambda가 "await"로 호출해야 합니다.이런 상황에서 우리는 HTTP 응답을 기다리는 것이 아니라 요청이 완전히 발송되기를 기다리는 것이다.이것은 지표 응답을 받는 750밀리초보다 훨씬 빠르며, 보통 20밀리초도 안 된다.
exports.handler = async (event, context) {
    await request('https://example.com', metrics)
    return 'done'
}

대체 설계 모델


Lambda 함수 중에는 절차 함수, SQS 대기열을 사용하고 Lambda 함수를 이벤트로 호출하여 기다리지 않는 등 기다림과 막힘을 피할 수 있는 다른 좋은 방법도 많이 있다.어플리케이션에 가장 적합한 방법을 고려하지만 HTTP를 사용해야 하고 응답을 기다릴 필요가 없는 경우 상기 기술을 고려하여 대기 시간과 AWS 청구서를 줄이십시오.

감지 깊이


저희 Sense Deep serverless 스튜디오는 Watcher Lambda에서 이 기술을 사용하여 Lambda를 감시하고 경보를 실행하며 로그 데이터를 수신합니다.REST/HTTP API 요청을 기다리지 않고 Watcher가 매우 빨라야 합니다.따라서 관찰자는 상태를 SenseDeep 서비스로 보낼 때 이런 비대기 기술을 사용한다.

SenseDeep 서버 없는 문제 해결 플랫폼에 대한 자세한 내용을 확인하고 무료 평가판을 사용하려면 https://www.sensedeep.com 을 참조하십시오.
만약 유사하거나 다른 기술을 사용하는 의견이 있으면 저에게 알려주십시오.[email protected] .

공구서류


다음은 Lambda와 AWS의 비동기 프로그래밍에 관한 다른 좋은 글입니다.
  • 노드 이벤트 순환 동결:
    https://levelup.gitconnected.com/avoiding-the-pitfalls-of-async-node-js-functions-in-aws-lambda-941220582e7a
  • Lambda 청구서:
    https://www.jeremydaly.com/serverless-tip-dont-overpay-when-waiting-on-remote-api-calls/
  • 비동기식 프로그래밍:
    https://read.acloud.guru/save-time-and-money-with-aws-lambda-using-asynchronous-programming-3548ea65f751
  • 단계 함수의 위험:
    https://blog.scottlogic.com/2018/06/19/step-functions.html
  • Lambda 비동기식 호출:
    https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html
  • Lambda 호출 개요:
    https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html
  • 좋은 웹페이지 즐겨찾기