μ•ˆλ…•ν•˜μ„Έμš”, μ˜€λžœλ§Œμ— 글을 μ”λ‹ˆλ‹€.

 

였늘 κ³΅μœ λ“œλ¦¬λŠ” λ‚΄μš©μ€ λΆ„μ‚°μ‹œμŠ€ν…œμ—μ„œ DLQ μ²˜λ¦¬ν•˜λŠ” 방법에 λŒ€ν•œ κ²ƒμž…λ‹ˆλ‹€.

μ œκ°€ κ΄€λ¦¬ν•˜λŠ” μ‹œμŠ€ν…œ 쀑 ν•˜λ‚˜κ°€ 주둜 μΉ΄ν”„μΉ΄ λ©”μ‹œμ§€λ₯Ό μ»¨μˆ¨ν•˜μ—¬ μ²˜λ¦¬ν•˜λŠ” 일을 ν•˜λŠ” μ‹œμŠ€ν…œμž…λ‹ˆλ‹€.

μ—¬λŸ¬ 개의 μΈμŠ€ν„΄μŠ€κ°€ μ‘΄μž¬ν•˜κ³  λͺ¨λ‘ λ™μΌν•œ μ†ŒμŠ€μ½”λ“œκ°€ λ°°ν¬λ˜μ–΄μžˆμ£ .

μ†ŒμŠ€μ½”λ“œμ—λŠ” JPAλ₯Ό μ΄μš©ν•œ CRUD 둜직이 λ“€μ–΄μžˆμŠ΅λ‹ˆλ‹€.

 

λ¬Έμ œκ°€ μ—†λ˜ μ‹œμŠ€ν…œμΈλ° κ΄€λ ¨λΆ€μ„œμ—μ„œ νŒŒν‹°μ…˜ 개수λ₯Ό λŠ˜λ¦¬λ©΄μ„œ λ¬Έμ œκ°€ μƒκ²ΌμŠ΅λ‹ˆλ‹€.

λ‹¨μˆœνžˆ νŒŒν‹°μ…˜ κ°œμˆ˜κ°€ λŠ˜μ–΄λ‚œκ²Œ λ¬Έμ œκ°€ μ•„λ‹ˆλΌ κ·Έμͺ½μ—μ„œ λ³΄λ‚΄λŠ” μΉ΄ν”„μΉ΄ λ©”μ‹œμ§€μ˜ νŠΉμ„±κ³Όλ„ 관련이 μžˆμ—ˆμ£ .

νŒŒν‹°μ…˜λ§ˆλ‹€ μ„œλ‘œ λ‹€λ₯Έ μΈμŠ€ν„΄μŠ€μ—μ„œ μ²˜λ¦¬ν•˜μ§€λ§Œ 각 λ©”μ‹œμ§€μ—λŠ” μ„œλ‘œ μ€‘λ³΅λœ λ°μ΄ν„°μ˜ λ‚΄μš©μ΄ λ“€μ–΄κ°€ μžˆλŠ” ν˜•νƒœμ˜€κ³  (이건 뭐 μ œκ°€ μ–΄μ°Œ ν•  수 μ—†λŠ” 것이죠), λ™μΌν•œ 데이터λ₯Ό μ„œλ‘œ λ‹€λ₯Έ μΈμŠ€ν„΄μŠ€μ—μ„œ JPAλ₯Ό μ΄μš©ν•΄μ„œ μ²˜λ¦¬ν•˜λ‹€κ°€ λ“œλ¬Όκ²Œ ObjectOptimisticLockingFailureException 이 λ°œμƒν•˜κΈ° μ‹œμž‘ν–ˆμŠ΅λ‹ˆλ‹€. 

예λ₯Όλ“€μ–΄ μΈμŠ€ν„΄μŠ€ 1λ²ˆμ—μ„œ {A, B} λΌλŠ” λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•  λ•Œ μΈμŠ€ν„΄μŠ€ 2λ²ˆμ—μ„œ {A,C}, 3번 μΈμŠ€ν„΄μŠ€μ—μ„œ {A,D} λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•˜λ©΄μ„œ A 데이터λ₯Ό 3λŒ€μ˜ μΈμŠ€ν„΄μŠ€μ—μ„œ λ™μ‹œμ— μ²˜λ¦¬ν•˜λ €κ³  ν•œκ±°μ£ . μ„Έ 개의 λ©”μ‹œμ§€λŠ” μ„œλ‘œ λ‹€λ₯Έ 데이터도 λ“€κ³ μžˆμœΌλ―€λ‘œ 무쑰건 처리λ₯Ό ν•΄μ€˜μ•Ό ν•˜λŠ” κ²ƒλ“€μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

이걸 μ–΄λ–»κ²Œ ν•  까 κ³ λ―Όν•˜λ‹€κ°€ SQSλ₯Ό DLQλ₯Ό μ΄μš©ν•˜μ—¬ Lambda 와 μ—°κ²°μ‹œμΌœ 일정 μ‹œκ°„μ΄ μ§€λ‚œ 뒀에 μˆ˜λ™λ™κΈ°ν™” APIλ₯Ό ν˜ΈμΆœν•˜λ„λ‘ κ΅¬μ„±ν•˜κΈ°λ‘œ ν–ˆμŠ΅λ‹ˆλ‹€.

μ΄λ ‡κ²Œ ν•œ μ΄μœ λŠ” κ°€μž₯ λΉ λ₯Έμ‹œκ°„에 좔가적인 μ†ŒμŠ€κ΅¬ν˜„ 없이 효과적으둜 λͺ©μ μ„ 달성할 수 μžˆμ—ˆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

λ§Œμ•½ DLQ둜 λ“€μ–΄μ˜€λŠ” λ©”μ‹œμ§€κ°€ λ§Žμ•„μ§„λ‹€λ©΄ μ†ŒμŠ€μ½”λ“œλ₯Ό κ΅¬ν˜„ν•˜λŠ”κ²Œ λΉ„μš©μΈ‘λ©΄μ—μ„  더 νš¨μœ¨μ μž…λ‹ˆλ‹€.

μΈμŠ€ν„΄μŠ€λŠ” μ–΄μ°¨ν”Ό λ– μžˆμ–΄μ•Ό ν•˜λŠ”κ±°κ³  λžŒλ‹€λ₯Ό μ œκ±°ν•  수 μžˆμœΌλ‹ˆ λžŒλ‹€μ—μ„œ λ°œμƒν•˜λŠ” λΉ„μš©μ΄ μ€„μ–΄λ“­λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μ†ŒμŠ€μ½”λ“œ κ΅¬ν˜„μ‹œ κ³ λ €ν•΄μ•Όν•  점이 있죠. μΈμŠ€ν„΄μŠ€κ°€ μ—¬λŸ¬κ°œ λ– μžˆμ§€λ§Œ ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€μ—μ„œλ§Œ DLQ의 λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•˜λ„λ‘ ν•΄μ•Όν•œλ‹€λŠ” κ±°μ£ . 그렇지 μ•ŠμœΌλ©΄ 또 μ²˜λ¦¬μ— μ‹€νŒ¨ν•˜λŠ” κ²½μš°κ°€ λ°œμƒν•  ν…Œλ‹ˆκΉŒμš”. 그리고 λͺ¨λ“  μΈμŠ€ν„΄μŠ€μ— λ™μΌν•œ μ†ŒμŠ€μ½”λ“œκ°€ λ°°ν¬λ˜μ–΄μ•Ό ν•˜λŠ”λ° ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€μ—μ„œλ§Œ 싀행이 λ˜λ„λ‘ ν•˜λ €λ©΄ 또 μ΄λŸ°μ €λŸ° μ½”λ“œλ₯Ό μž‘μ„±ν•΄μ•Ό ν•˜λ‹€λ³΄λ‹ˆ λžŒλ‹€λ₯Ό μ΄μš©ν•˜κΈ°λ‘œ ν–ˆμŠ΅λ‹ˆλ‹€.

 

μ•„λ¬΄νŠΌ, SQSλ₯Ό DLQ둜 μ΄μš©ν•˜κ³ , Lambda ν•¨μˆ˜λ₯Ό μ—°κ²°μ‹œμΌœ 일정 μ‹œκ°„λ’€μ— μˆ˜λ™APIλ₯Ό ν˜ΈμΆœν•˜μ—¬ μ‹€νŒ¨ν–ˆλ˜ λ©”μ‹œμ§€μ— λŒ€ν•œ 정보λ₯Ό μ½μ–΄μ™€μ„œ μ²˜λ¦¬ν•˜λ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€.

SQS Lambda Trigger μ„€μ •

μ΄λ ‡κ²Œ μ„€μ •ν•΄λ†“μœΌλ©΄ SQS λ©”μ‹œμ§€κ°€ λ°œν–‰λ  λ•Œλ§ˆλ‹€ Lambda ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λŠ”λ° Lambda ν•¨μˆ˜μ—μ„œλŠ” APIλ₯Ό ν˜ΈμΆœν•˜λ„λ‘ κ΅¬μ„±ν–ˆμŠ΅λ‹ˆλ‹€. λžŒλ‹€ νŠΈλ¦¬κ±°μ— λŒ€ν•œ λ‚΄μš©μ„ AWSμ—μ„œλŠ” λ‹€μŒκ³Ό 같이 μ„€λͺ…ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

You can configure your Amazon SQS queue to trigger an AWS Lambda function when new messages arrive in the queue.
Your queue and Lambda function must be in the same AWS Region.
A Lambda function can use at most one queue as an event source. You can use the same queue with multiple Lambda functions.
You can't associate an encrypted queue that uses the AWS-managed CMK for Amazon SQS with a Lambda function in a different AWS account.

μ €μ˜ κ²½μš°μ—λŠ” ν•„μš”μ—†κΈ΄ν•˜μ§€λ§Œ, ν•˜λ‚˜μ˜ SQS에 μ—¬λŸ¬κ°œμ˜ λžŒλ‹€ν•¨μˆ˜λ₯Ό μ—°κ²°ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλ‹€λŠ” 점이 μ’‹μ•„λ³΄μ΄λ„€μš”.

 

자, 그리고 SQS와 μ—°κ²°ν•œ Lambda ν•¨μˆ˜λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

import logging
import json
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError

logger = logging.getLogger()
logger.setLevel(logging.INFO)

API_URL = "https://company.com/employees/{}"

def lambda_handler(event, context):

    message = json.loads(event['Records'][0]['body'])
    
    url = API_URL.format(message['employeeId'])
    headers = {'Content-type':'application/json'}
    
    req = Request(url, headers=headers, data=b'', method='PUT')
    
    try:
        response = urlopen(req)
        return response.getcode()
    except HTTPError as e:
        logger.error("Request failed: %d %s, sqsBody:%s", e.code, e.reason, message)
        return e.code
    except URLError as e:
        logger.error("Server connection failed: %s, sqsBody:%s", e.reason, message)
    return None

Python은 κ³΅λΆ€ν•œμ  μ—†μœΌλ‚˜, μžλ°”λŠ” μ»΄νŒŒμΌμ–Έμ–΄λΌ μ½”λ“œλ₯Ό 직접 AWSμ½˜μ†”μ—μ„œ μž‘μ„±ν•  수 μ—†μ–΄μ„œ python으둜 μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

 

λ‚΄μš©μ€ 별거 μ—†κ³  event에 SQS λ©”μ‹œμ§€μ˜ λ‚΄μš©μ΄ λ“€μ–΄μ˜€κΈ° λ•Œλ¬Έμ— eventμ—μ„œ λ©”μ‹œμ§€μ˜ body λ‚΄μš©μ„ μΆ”μΆœν•˜μ—¬ message λ³€μˆ˜μ— λ„£κ³  이것을 API ν˜ΈμΆœν•  λ•Œ μ‚¬μš©ν•œκ²ƒμ΄ λ‹€μž…λ‹ˆλ‹€. μ—¬κΈ°μ„œλŠ” employeeId 값이 SQS λ©”μ‹œμ§€μ— {"employeeId":1234} ν˜•νƒœλ‘œ λ“€μ–΄μžˆμ—ˆλ‹€λ©΄, μ €κΈ°μ„œ 1234 값을 μΆ”μΆœν•˜μ—¬ api ν˜ΈμΆœν• λ•Œ path variable둜 λ„£μ–΄μ„œ https://company.com/employees/1234 λ₯Ό ν˜ΈμΆœν•˜λ„λ‘ ν•œκ±°μ£ . 

 

μœ„ μ½”λ“œμƒμ—μ„  μ—λŸ¬κ°€ λ°œμƒν•˜λ©΄ κ·Έλƒ₯ λ‘œκΉ…ν•˜κ±°λ‚˜ μ—λŸ¬μ½”λ“œ λ¦¬ν„΄ν•˜λ„λ‘ ν•΄λ†“μ•˜λŠ”λ°, μ—λŸ¬κ±΄μ΄ 많이 λ°œμƒν•œλ‹€λ©΄ μŠ¬λž™μ•ŒλžŒμ„ 보내도둝 ν•˜λŠ” 것도 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€.

 

 

μ΄μƒμœΌλ‘œ SQS와 Lambdaλ₯Ό μ΄μš©ν•œ λΆ„μ‚°μ²˜λ¦¬μ‹œμŠ€ν…œμ—μ„œμ˜ DLQ μ²˜λ¦¬μ— λŒ€ν•œ 기둝을 λ§ˆμΉ©λ‹ˆλ‹€.