ALPACO ํ๋ก์ ํธ: ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ ์ฒ(MSA) Lambda ๊ฐ๋ฐ ๊ฐ์ด๋
1. ์๋ก
๋ณธ ๋ฌธ์๋ ALPACO ํ๋ก์ ํธ์ ๋ฐฑ์๋ ์์คํ ์ ๊ตฌ์ฑํ๋ AWS Lambda ํจ์๋ค์ ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ ์ฒ(MSA) ๊ด์ ์์ ๊ฐ๋ฐ, ๋ฐฐํฌ ๋ฐ ํตํฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ํฌ๊ด์ ์ธ ๊ธฐ์ ๊ฐ์ด๋์ ๋๋ค. ALPACO๋ ์ฌ๋ฌ ๋ ๋ฆฝ์ ์ธ Lambda ํจ์๋ค์ ์กฐํฉํ์ฌ ํน์ ๋น์ฆ๋์ค ๊ธฐ๋ฅ์ ์ํํ๋ MSA ์์น์ ๋ฐ๋ฆ ๋๋ค.
์ด ๊ฐ์ด๋๋ ๊ฐ๋ฐ์๊ฐ ๊ฐ Lambda ์๋น์ค์ ์ญํ , ๋ค๋ฅธ ์๋น์ค์์ ์ํธ์์ฉ, ๋ฐ์ดํฐ ๊ด๋ฆฌ, ๋ฐฐํฌ ์ ๋ต, ๊ทธ๋ฆฌ๊ณ MSA ํ๊ฒฝ์์์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ดํดํ๋ ๋ฐ ๋์์ ์ฃผ๋ ๊ฒ์ ๋ชฉํ๋ก ํฉ๋๋ค. ์ ๊ณต๋ chatbot-query
, code-executor
, code-grader
, community-lambda-functions
, problem-generator-v3
, problems-api
, submissions-api
๋ฑ์ Lambda ํจ์๋ค๊ณผ ๊ด๋ จ ์ธํ๋ผ ๋ฌธ์๋ฅผ ์ฃผ์ ์ฐธ๊ณ ์๋ฃ๋ก ํ์ฉํฉ๋๋ค.
2. MSA ๋ฐ Lambda ๊ธฐ๋ณธ ์์น
ALPACO ํ๋ก์ ํธ๋ ๋ค์๊ณผ ๊ฐ์ MSA ์์น์ Lambda ํจ์ ์ค๊ณ์ ์ ์ฉํฉ๋๋ค:
- ๋จ์ผ ์ฑ
์ ์์น (Single Responsibility Principle): ๊ฐ Lambda ํจ์๋ ํน์ ๋น์ฆ๋์ค ๊ธฐ๋ฅ ๋๋ ๋๋ฉ์ธ์ ์ง์คํฉ๋๋ค. (์:
code-executor
๋ ์ฝ๋ ์คํ๋ง ๋ด๋น,chatbot-query
๋ ์ฑ๋ด ๋ก์ง๋ง ๋ด๋น). - ๋ ๋ฆฝ์ ์ธ ๋ฐฐํฌ: ๊ฐ Lambda ์๋น์ค๋ ๋ค๋ฅธ ์๋น์ค์ ๋ฏธ์น๋ ์ํฅ์ ์ต์ํํ๋ฉด์ ๋ ๋ฆฝ์ ์ผ๋ก ๋ฐฐํฌ ๋ฐ ์ ๋ฐ์ดํธ๋ ์ ์์ต๋๋ค (Terraform ๋ชจ๋๋ก ๊ด๋ฆฌ).
- ๋ถ์ฐ๋ ๋ฐ์ดํฐ ๊ด๋ฆฌ: ๊ฐ ์๋น์ค๋ ์์ฒด ๋ฐ์ดํฐ ์ ์ฅ์(์ฃผ๋ก DynamoDB ํ
์ด๋ธ)๋ฅผ ์์ ํ๊ฑฐ๋, ๋ช
ํํ๊ฒ ์ ์๋ ์ธํฐํ์ด์ค๋ฅผ ํตํด ๋ค๋ฅธ ์๋น์ค์ ๋ฐ์ดํฐ์ ์ ๊ทผํฉ๋๋ค. (์:
Community
ํ ์ด๋ธ,Problems
ํ ์ด๋ธ,Submissions
ํ ์ด๋ธ). - ๊ธฐ์ ๋ค์์ฑ (Polyglot Persistence & Programming): MSA๋ ์๋น์ค๋ณ๋ก ์ต์ ์ ๊ธฐ์ ์คํ์ ์ ํํ ์ ์๊ฒ ํด์ค๋๋ค. ALPACO๋ ์ฃผ๋ก Node.js๋ฅผ Lambda ๋ฐํ์์ผ๋ก ์ฌ์ฉํ์ง๋ง,
code-executor
๋ Python์ ์ฌ์ฉํฉ๋๋ค. - ํ๋ ฅ์ฑ ๋ฐ ํ์ฅ์ฑ: AWS Lambda์ ์๋ฒ๋ฆฌ์ค ํน์ฑ์ ํธ๋ํฝ์ ๋ฐ๋ผ ์๋์ผ๋ก ํ์ฅ/์ถ์๋์ด ๋์ ๊ฐ์ฉ์ฑ๊ณผ ๋น์ฉ ํจ์จ์ฑ์ ์ ๊ณตํฉ๋๋ค.
- API ๊ธฐ๋ฐ ํต์ : ์๋น์ค ๊ฐ ์ํธ์์ฉ์ ์ ์ ์๋ API(์ฃผ๋ก API Gateway ๋๋ Lambda ์ง์ ํธ์ถ)๋ฅผ ํตํด ์ด๋ฃจ์ด์ง๋๋ค.
3. ALPACO Lambda ํจ์ ๊ฐ๋ฐ ํจํด
3.1. ๊ณตํต ๊ตฌ์กฐ
๋๋ถ๋ถ์ ALPACO Node.js Lambda ํจ์๋ ๋ค์๊ณผ ๊ฐ์ ์ผ๋ฐ์ ์ธ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฆ ๋๋ค:
// ์์: backend/lambdas/chatbot-query/index.mjs
import { /* ํ์ํ AWS SDK ํด๋ผ์ด์ธํธ, ๋ผ์ด๋ธ๋ฌ๋ฆฌ */ } from "...";
// ์ ์ญ ๋ฒ์์์ ํด๋ผ์ด์ธํธ ์ด๊ธฐํ (์ฐ๊ฒฐ ์ฌ์ฌ์ฉ)
// const dynamoDB = DynamoDBDocumentClient.from(new DynamoDBClient({}));
export const handler = async (event, context) => {
// 1. CORS ๋ฐ ์ฌ์ ์์ฒญ(Preflight) ์ฒ๋ฆฌ (API Gateway Lambda Proxy ํตํฉ ์)
if (event.httpMethod === "OPTIONS") {
return {
statusCode: 200,
headers: { /* CORS ํค๋ */ },
body: JSON.stringify({ message: "CORS preflight check successful" }),
};
}
try {
// 2. ์
๋ ฅ ํ์ฑ ๋ฐ ์ ํจ์ฑ ๊ฒ์ฌ
// - event.body (API Gateway), event (์ง์ ํธ์ถ)
// - event.pathParameters, event.queryStringParameters
// - event.requestContext.authorizer.claims (Cognito ์ธ์ฆ ์ ๋ณด)
const requestBody = typeof event.body === "string" ? JSON.parse(event.body) : event.body;
// ... ์ ํจ์ฑ ๊ฒ์ฌ ๋ก์ง ...
// 3. ์ธ์ฆ ๋ฐ ๊ถํ ๋ถ์ฌ (ํ์์)
// - JWT ํ ํฐ ๊ฒ์ฆ (์: chatbot-query, code-grader)
// - IAM ์ญํ ๊ธฐ๋ฐ ๊ถํ (Lambda ์คํ ์ญํ )
// 4. ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง ์ํ
// - ์ธ๋ถ ์๋น์ค ํธ์ถ (์: Google Gemini API, ๋ค๋ฅธ Lambda ํจ์)
// - ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์
(DynamoDB CRUD)
// - ๊ณ์ฐ ๋ฐ ๋ฐ์ดํฐ ๋ณํ
// 5. ์๋ต ์์ฑ
const responseBody = { /* ๊ฒฐ๊ณผ ๋ฐ์ดํฐ */ };
return {
statusCode: 200, // ๋๋ 201, 204 ๋ฑ
headers: {
"Content-Type": "application/json",
/* CORS ํค๋ */
},
body: JSON.stringify(responseBody),
};
} catch (error) {
console.error("Error processing request:", error);
// 6. ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ์๋ต
return {
statusCode: error.statusCode || 500,
headers: {
"Content-Type": "application/json",
/* CORS ํค๋ */
},
body: JSON.stringify({
message: error.message || "Internal server error",
details: error.details, // ์ถ๊ฐ ์ค๋ฅ ์ ๋ณด (์ ํ ์ฌํญ)
}),
};
}
};
// ์คํธ๋ฆฌ๋ฐ ์๋ต์ ๊ฒฝ์ฐ (์: chatbot-query, problem-generator-v3)
// export const handler = awslambda.streamifyResponse(async (event, responseStream, context) => {
// // ... ์ ์ฌํ ๊ตฌ์กฐ, responseStream.write() ๋ฐ responseStream.end() ์ฌ์ฉ
// });
3.2. ์ ๋ ฅ ์ฒ๋ฆฌ ๋ฐ ์ ํจ์ฑ ๊ฒ์ฌ
- API Gateway ํ๋ก์ ํตํฉ:
event.httpMethod
,event.pathParameters
,event.queryStringParameters
,event.body
(JSON ๋ฌธ์์ด)๋ฅผ ์ฌ์ฉํฉ๋๋ค.event.body
๋JSON.parse()
๊ฐ ํ์ํฉ๋๋ค. - ์ง์ Lambda ํธ์ถ:
event
๊ฐ์ฒด๊ฐ ์ง์ ์ ๋ ฅ ํ์ด๋ก๋์ ๋๋ค. (์:code-grader
๊ฐcode-executor
ํธ์ถ ์). - ์ธ์ฆ ์ ๋ณด: Cognito์ ํตํฉ๋ API Gateway๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ,
event.requestContext.authorizer.claims
์์ ์ฌ์ฉ์ ํด๋ ์(์:sub
(์ฌ์ฉ์ ID),cognito:username
)์ ๊ฐ์ ธ์ต๋๋ค. - ์ ํจ์ฑ ๊ฒ์ฌ: ํ์ ํ๋ ๋๋ฝ, ๋ฐ์ดํฐ ํ์ ๋ถ์ผ์น ๋ฑ์ ์ด๊ธฐ์ ํ์ธํ์ฌ ์ค๋ฅ๋ฅผ ์กฐ๊ธฐ์ ๋ฐํํฉ๋๋ค. (Zod์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ ๊ฐ๋ฅ, ํ์ฌ๋ ์๋ ๊ฒ์ฌ ์์ฃผ).
3.3. ์ค์ ๋ฐ ํ๊ฒฝ ๋ณ์
- Lambda ํจ์ ์ค์ (์: ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ ์ด๋ฆ, ์ธ๋ถ API ํค, ๋ค๋ฅธ ์๋น์ค ARN)์ ํ๊ฒฝ ๋ณ์๋ฅผ ํตํด ์ฃผ์ ๋ฉ๋๋ค.
- Terraform (
*.tf
ํ์ผ์environment
๋ธ๋ก)์ ์ฌ์ฉํ์ฌ ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํฉ๋๋ค. (์:PROBLEMS_TABLE_NAME
,GOOGLE_AI_API_KEY
,CODE_EXECUTOR_LAMBDA_ARN
). backend/lambdas/*/src/utils/constants.mjs
์ ๊ฐ์ ์ ํธ๋ฆฌํฐ ํ์ผ์์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ฝ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด์์ ์ผ๊ด๋๊ฒ ์ฌ์ฉํฉ๋๋ค.
3.4. ์ธ์ฆ ๋ฐ ๊ถํ ๋ถ์ฌ
- Cognito JWT ์ธ์ฆ (API Gateway):
- API Gateway ์๋ํฌ์ธํธ๋ Cognito ์ฌ์ฉ์ ํ ๊ถํ ๋ถ์ฌ์๋ก ๋ณดํธ๋ฉ๋๋ค.
- ํด๋ผ์ด์ธํธ๋
Authorization: Bearer <ID_TOKEN>
ํค๋๋ฅผ ์ ์กํฉ๋๋ค. chatbot-query
,code-grader
, ์ปค๋ฎค๋ํฐ API ๋ฑ์ ๋ด๋ถ์ ์ผ๋ก JWT๋ฅผ ๊ฒ์ฆํ๊ฑฐ๋(์:chatbot-query
์validateJwt
ํจ์) API Gateway ๊ถํ ๋ถ์ฌ์์ ์์กดํ์ฌ ์ฌ์ฉ์ ์ ๋ณด๋ฅผevent.requestContext.authorizer.claims
๋ก ๋ฐ์ต๋๋ค.
- IAM ์ญํ ๋ฐ ์ ์ฑ
:
- ๊ฐ Lambda ํจ์๋ ์ต์ ๊ถํ ์์น์ ๋ฐ๋ฅด๋ IAM ์คํ ์ญํ ์ ๊ฐ์ง๋๋ค.
- ์ด ์ญํ ์ ํ์ํ AWS ์๋น์ค(DynamoDB, ๋ค๋ฅธ Lambda ํธ์ถ, CloudWatch Logs ๋ฑ)์ ๋ํ ์ ๊ทผ ๊ถํ์ ๋ถ์ฌํฉ๋๋ค. (์:
infrastructure/api/iam.tf
).
- Lambda ํจ์ URL ์ธ์ฆ:
chatbot-query
๋ฐproblem-generator-v3
๋AWS_IAM
์ธ์ฆ์ ์ฌ์ฉํ๋ Lambda ํจ์ URL์ ํตํด ๋ ธ์ถ๋ฉ๋๋ค.- CloudFront๋ OAC(Origin Access Control)๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฌํ ํจ์ URL์ ์์ ํ๊ฒ ํธ์ถํ๋ฉฐ, SigV4 ์๋ช ์ ํตํด ์ธ์ฆํฉ๋๋ค.
3.5. ์ค๋ฅ ์ฒ๋ฆฌ
try...catch
๋ธ๋ก์ ์ฌ์ฉํ์ฌ ์์๋๋ ์ค๋ฅ์ ์๊ธฐ์น ์์ ์ค๋ฅ๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํฉ๋๋ค.- ์ผ๊ด๋ ์ค๋ฅ ์๋ต ํ์์ ์ฌ์ฉํฉ๋๋ค (์:
statusCode
,{ message, details }
๋ณธ๋ฌธ). console.error
๋ฅผ ์ฌ์ฉํ์ฌ CloudWatch Logs์ ์์ธํ ์ค๋ฅ ์ ๋ณด๋ฅผ ๊ธฐ๋กํฉ๋๋ค.- ์คํธ๋ฆฌ๋ฐ ์๋ต์ ๊ฒฝ์ฐ, ์ค๋ฅ๋ SSE ์คํธ๋ฆผ์ ํตํด ์ ๋ฌ๋ ์ ์์ต๋๋ค. (์:
chatbot-query
์responseStream.write(JSON.stringify({ error: ..., details: ... }))
).
3.6. ๋ก๊น ๋ฐ ๋ชจ๋ํฐ๋ง
console.log
,console.info
,console.warn
,console.error
๋ฅผ ์ฌ์ฉํ์ฌ CloudWatch Logs์ ๋ก๊ทธ๋ฅผ ๊ธฐ๋กํฉ๋๋ค.GENERATOR_VERBOSE
(problem-generator-v3
)์ ๊ฐ์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๊ทธ ์์ธ ์์ค์ ์ ์ดํ ์ ์์ต๋๋ค.- CloudWatch Logs๋ ๋๋ฒ๊น , ์ฑ๋ฅ ๋ถ์, ์ค๋ฅ ์ถ์ ์ ํ์์ ์ ๋๋ค.
3.7. ์์กด์ฑ ๊ด๋ฆฌ ๋ฐ Lambda Layers
- Node.js ํ๋ก์ ํธ: ๊ฐ Lambda ํจ์ ๋๋ ๊ด๋ จ ์๋น์ค ๊ทธ๋ฃน์ ์์ฒด
package.json
์ ๊ฐ์ง ์ ์์ต๋๋ค. (์:backend/lambdas/chatbot-query/package.json
). - Lambda Layers: ์ฌ๋ฌ Lambda ํจ์์์ ๊ณต์ ๋๋ ๊ณตํต ์์กด์ฑ(์: AWS SDK, LangChain ๋ผ์ด๋ธ๋ฌ๋ฆฌ,
uuid
,jose
)์ Lambda Layer๋ก ํจํค์งํฉ๋๋ค.infrastructure/api/layers/common-deps/
: ์ปค๋ฎค๋ํฐ API์ฉ ๊ฐ๋จํuuid
๋ ์ด์ด.infrastructure/chatbot/layers/chatbot_deps/
: ์ฑ๋ด์ฉ@langchain/google-genai
,jose
๋ฑ.infrastructure/problem-generator-v3/layers/
: Docker ๊ธฐ๋ฐ ๋น๋๋ฅผ ์ฌ์ฉํ๋ ๋ ๋ณต์กํ ๋ ์ด์ด.- Terraform (
layer.tf
๋๋lambda.tf
๋ด)์์aws_lambda_layer_version
๋ฆฌ์์ค๋ก ์ ์๋ฉ๋๋ค. - ๋ ์ด์ด ๋น๋ ํ๋ก์ธ์ค๋ ๋ก์ปฌ
npm install
๋๋ Docker ๋น๋ ์คํฌ๋ฆฝํธ(build-layer.sh
)๋ฅผ ํตํด ๊ด๋ฆฌ๋ฉ๋๋ค.
4. ์๋น์ค ๊ฐ ํต์
ALPACO ํ๋ก์ ํธ์ Lambda ๊ธฐ๋ฐ ๋ง์ดํฌ๋ก์๋น์ค๋ ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ํธ์์ฉํฉ๋๋ค:
4.1. API Gateway๋ฅผ ํตํ ๋๊ธฐ์ ํธ์ถ
- ํจํด: ํด๋ผ์ด์ธํธ (๋๋ ๋ค๋ฅธ ์๋น์ค) -> API Gateway -> Lambda ํจ์
- ์์:
- ํ๋ก ํธ์๋๊ฐ
submissions-api
๋ฅผ ํธ์ถํ์ฌ ์ ์ถ ๋ชฉ๋ก์ ๊ฐ์ ธ์ต๋๋ค. - ํ๋ก ํธ์๋๊ฐ
code-grader
API๋ฅผ ํธ์ถํ์ฌ ์ฝ๋ ์ฑ์ ์ ์์ฒญํฉ๋๋ค. problem-generator-v3
์๋น์ค (๋ฐฑ์๋)๊ฐcode-execution-service
API Gateway๋ฅผ ํธ์ถํ์ฌ ์์ฑ๋ ์ฝ๋ ์กฐ๊ฐ์ ๊ฒ์ฆํ ์ ์์ต๋๋ค (ํ์ฌ ๊ตฌํ์ Lambda ์ง์ ํธ์ถ).
- ํ๋ก ํธ์๋๊ฐ
- ํน์ง: ์์ฒญ-์๋ต ๋ชจ๋ธ, HTTP ๊ธฐ๋ฐ, API Gateway๊ฐ ์ธ์ฆ, ์๋ ์ ํ, ๋ก๊น , CORS ๋ฑ์ ์ฒ๋ฆฌ.
4.2. Lambda ์ง์ ๋๊ธฐ์ ํธ์ถ
- ํจํด: Lambda A -> AWS SDK -> Lambda B (๋๊ธฐ์ ํธ์ถ, Lambda A๋ Lambda B์ ์๋ต์ ๊ธฐ๋ค๋ฆผ)
- ์์:
code-grader
Lambda๊ฐ ๊ฐ ํ ์คํธ ์ผ์ด์ค์ ๋ํดcode-executor
Lambda๋ฅผ ๋๊ธฐ์ ์ผ๋ก ํธ์ถํฉ๋๋ค.code-grader
๋code-executor
์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฐ ํ ๋ค์ ๋จ๊ณ๋ฅผ ์งํํฉ๋๋ค.problem-generator-v3
Lambda๊ฐ ์์ฑ๋ ์๋ฃจ์ ์ฝ๋ ๊ฒ์ฆ์ ์ํดcode-executor
Lambda๋ฅผ ํธ์ถํฉ๋๋ค.
- ํน์ง: ์๋น์ค ๊ฐ ๋ฎ์ ์ง์ฐ ์๊ฐ. ํธ์ถํ๋ Lambda๋ ํธ์ถ๋๋ Lambda์ ์๋ต ํ์๊ณผ ์ค๋ฅ ์ฒ๋ฆฌ์ ๋ํด ์๊ณ ์์ด์ผ ํฉ๋๋ค. IAM ๊ถํ์ผ๋ก ํธ์ถ์ ์ ์ดํฉ๋๋ค.
4.3. CloudFront + Lambda ํจ์ URL (SSE ์คํธ๋ฆฌ๋ฐ)
- ํจํด: ํด๋ผ์ด์ธํธ -> CloudFront -> Lambda ํจ์ URL -> Lambda (์คํธ๋ฆฌ๋ฐ ์๋ต)
- ์์:
chatbot-query
: ์ฑ๋ด ์๋ต์ SSE๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๋ก ์คํธ๋ฆฌ๋ฐํฉ๋๋ค.problem-generator-v3
: ๋ฌธ์ ์์ฑ ์งํ ์ํฉ๊ณผ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ SSE๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๋ก ์คํธ๋ฆฌ๋ฐํฉ๋๋ค.
- ํน์ง: ์ค์๊ฐ ์ ๋ฐ์ดํธ, ์ฅ๊ธฐ ์คํ ์์ ์ ์ ํฉ. CloudFront OAC๋ฅผ ์ฌ์ฉํ์ฌ Lambda ํจ์ URL์ ๋ณดํธํฉ๋๋ค.
5. ๋ฐ์ดํฐ ๊ด๋ฆฌ
- DynamoDB: ์ฃผ์ ๋ฐ์ดํฐ ์ ์ฅ์๋ก ์ฌ์ฉ๋ฉ๋๋ค.
alpaco-Community-production
: ์ปค๋ฎค๋ํฐ ๊ฒ์๋ฌผ, ๋๊ธ, ์ข์์. (infrastructure/api/dynamodb.tf
)alpaco-Problems-production
๋๋alpaco-Problems-v3-production
: ์์ฑ๋ ๋ฌธ์ , ํ ์คํธ ์ผ์ด์ค, ์๋ฃจ์ ๋ฑ. (infrastructure/problem-generator-v3/dynamodb.tf
)problem-submissions
: ์ฝ๋ ์ ์ถ ๊ฒฐ๊ณผ. (infrastructure/code-execution-service/dynamodb.tf
)
- ๋ฐ์ดํฐ ๊ฒฉ๋ฆฌ: ๊ฐ ์ฃผ์ ์๋น์ค ๋๋ฉ์ธ(์ปค๋ฎค๋ํฐ, ๋ฌธ์ , ์ ์ถ)์ ์์ฒด DynamoDB ํ ์ด๋ธ์ ๊ฐ๋ ๊ฒฝํฅ์ด ์์ต๋๋ค. ์ด๋ MSA์ โ์๋น์ค๋น ๋ฐ์ดํฐ๋ฒ ์ด์คโ ํจํด๊ณผ ์ ์ฌํฉ๋๋ค.
- ๊ธ๋ก๋ฒ ๋ณด์กฐ ์ธ๋ฑ์ค (GSI): ๋ค์ํ ์ฟผ๋ฆฌ ํจํด์ ํจ์จ์ ์ผ๋ก ์ง์ํ๊ธฐ ์ํด ๊ด๋ฒ์ํ๊ฒ ์ฌ์ฉ๋ฉ๋๋ค. (์:
getAllPosts
์CompletedProblemsByCreatedAtGSI
,getSubmission
์ ๋ค์ํ GSI). - ๋ฐ์ดํฐ ์ผ๊ด์ฑ:
- ์์์ ์นด์ดํฐ (Atomic Counters): DynamoDB์ ์์์ ์นด์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ
likesCount
,commentCount
์ ๊ฐ์ ์์ฑ์ ์ ๋ฐ์ดํธํฉ๋๋ค. - ํธ๋์ญ์
:
community-lambda-functions/comment/createComment_modified.mjs
๋ฐdeleteComment_modified.mjs
๋TransactWriteCommand
๋ฅผ ์ฌ์ฉํ์ฌ ๋๊ธ์ ์ถ๊ฐ/์ญ์ ํ๊ณ ๊ฒ์๋ฌผ์commentCount
๋ฅผ ์์์ ์ผ๋ก ์ ๋ฐ์ดํธํ์ฌ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ๋ณด์ฅํฉ๋๋ค.
- ์์์ ์นด์ดํฐ (Atomic Counters): DynamoDB์ ์์์ ์นด์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ
- ํ๋ก์ ์ ํํ์: Lambda ํจ์๋ ํ์ํ ์์ฑ๋ง ์ฝ๋๋ก DynamoDB ์ฟผ๋ฆฌ์ ํ๋ก์ ์ ํํ์์ ์ฌ์ฉํ์ฌ ์ฝ๊ธฐ ์ฑ๋ฅ์ ์ต์ ํํ๊ณ ๋น์ฉ์ ์ ๊ฐํฉ๋๋ค.
6. ๋ฐฐํฌ (Terraform์ ์ฌ์ฉํ IaC)
ALPACO์ ๋ชจ๋ AWS ๋ฆฌ์์ค(Lambda, API Gateway, DynamoDB, IAM ์ญํ , CloudFront ๋ฑ)๋ Terraform์ ์ฌ์ฉํ์ฌ ์ฝ๋๋ก ๊ด๋ฆฌ๋ฉ๋๋ค.
- ๋ชจ๋์ ๊ตฌ์กฐ: Terraform ์ฝ๋๋ ์๋น์ค๋ณ ๋๋ ํฐ๋ฆฌ(
infrastructure/api
,infrastructure/chatbot
๋ฑ)๋ก ๊ตฌ์ฑ๋์ด ๊ฐ ๋ง์ดํฌ๋ก์๋น์ค๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ๋๋ ํจ๊ป ๋ฐฐํฌํ ์ ์์ต๋๋ค. - ์๊ฒฉ ์ํ: Terraform ์ํ๋ S3 ๋ฒํท(
alpaco-tfstate-bucket-kmu
)์ ์ค์์์ ๊ด๋ฆฌ๋๋ฉฐ, DynamoDB ํ ์ด๋ธ(alpaco-tfstate-lock-table
)์ ์ฌ์ฉํ์ฌ ์ํ ์ ๊ธ์ ์ฒ๋ฆฌํฉ๋๋ค. (infrastructure/backend-setup/
๋ชจ๋์์ ์ค์ ). terraform_remote_state
: ํ ๋ชจ๋์ด ๋ค๋ฅธ ๋ชจ๋์ ์ถ๋ ฅ(์: Cognito ์ฌ์ฉ์ ํ ARN, DynamoDB ํ ์ด๋ธ ์ด๋ฆ)์ ์์กดํ๋ ๊ฒฝ์ฐdata "terraform_remote_state"
๋ฅผ ์ฌ์ฉํฉ๋๋ค. (์:code-execution-service
๊ฐproblem-generator-v3
์problems_table_arn
์ ์ฐธ์กฐ).- ๋ณ์ ๋ฐ ์ถ๋ ฅ: ๊ฐ Terraform ๋ชจ๋์
variables.tf
๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ ฅ์ ๋ฐ๊ณoutputs.tf
๋ฅผ ํตํด ์ค์ํ ๋ฆฌ์์ค ์๋ณ์๋ฅผ ๋ ธ์ถํฉ๋๋ค. - CI/CD: GitHub Actions๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๋ ๋ณ๊ฒฝ ์ Terraform ๊ตฌ์ฑ์ ์๋์ผ๋ก ๊ณํํ๊ณ ์ ์ฉํฉ๋๋ค. OIDC๋ฅผ ์ฌ์ฉํ์ฌ AWS์ ์์ ํ๊ฒ ์ธ์ฆํฉ๋๋ค.
- Lambda ๋ ์ด์ด ๋น๋ ๋จ๊ณ๋ CI/CD ํ์ดํ๋ผ์ธ์ ํตํฉ๋์ด
terraform apply
์ ์ ์คํ๋ฉ๋๋ค.
- Lambda ๋ ์ด์ด ๋น๋ ๋จ๊ณ๋ CI/CD ํ์ดํ๋ผ์ธ์ ํตํฉ๋์ด
- ๋ฐฐํฌ ์์: ๋ชจ๋ ๊ฐ ์์กด์ฑ์ผ๋ก ์ธํด ํน์ ๋ฐฐํฌ ์์๊ฐ ํ์ํ ์ ์์ต๋๋ค. (InfrastructureAsCode.md์ โ์ ์ฒด ๋ฐฐํฌ ์ ๋ต ๋ฐ ์์โ ์ฐธ์กฐ). ํนํ
problem-generator-v3
์code-execution-service
๊ฐ์ ์ํ ์์กด์ฑ์ ๋ค๋จ๊ณ ๋ฐฐํฌ๋ก ํด๊ฒฐ๋ฉ๋๋ค.
7. ๋ก์ปฌ ๊ฐ๋ฐ ๋ฐ ํ ์คํธ
- Lambda ๊ฐ๋ณ ํ
์คํธ:
chatbot-query/howto.md
: AWS CLI๋ฅผ ์ฌ์ฉํ์ฌchatbot-query
Lambda๋ฅผ ์๋์ผ๋ก ํธ์ถํ๊ณ ํ ์คํธํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช ํฉ๋๋ค.problem-generator-v3/local-test.mjs
:problem-generator-v3
ํ์ดํ๋ผ์ธ์ ๋ก์ปฌ์์ ์๋ฎฌ๋ ์ด์ ํ๊ณ ํ ์คํธํฉ๋๋ค. DynamoDB ๋ชจํน์ ์ง์ํ๋ฉฐ,.env
ํ์ผ์ ํตํด ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํฉ๋๋ค.
- ๋ชจํน:
problem-generator-v3
์local-test.mjs
๋mock-dynamodb.mjs
๋ฅผ ์ฌ์ฉํ์ฌ DynamoDB ์์ ์ ๋ชจํนํ ์ ์์ต๋๋ค.- ์ธ๋ถ API ํธ์ถ(์: Google Gemini)์ ์ผ๋ฐ์ ์ผ๋ก ๋ก์ปฌ ํ
์คํธ ์ค ์ค์ ํธ์ถ๋๊ฑฐ๋, ํ์์ ๋ชจํน ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์:
sinon
,jest.mock
)๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจํน๋ ์ ์์ต๋๋ค. - ํ์ฌ
codeExecutor.mjs
์ Python ์ฝ๋ ์คํ์ ๋ก์ปฌ ํ ์คํธ ์ค์๋ ๋ฐฐํฌ๋ ์ค์ Code Executor Lambda๋ฅผ ํธ์ถํฉ๋๋ค. ์์ ํ ์คํ๋ผ์ธ ํ ์คํธ๋ฅผ ์ํด์๋ ์ด ๋ถ๋ถ์ ๋ํ ๋ชจํน ๋๋ ๋ก์ปฌ Python ์คํ๊ธฐ ๊ตฌํ์ด ํ์ํฉ๋๋ค.
- ๋จ์ ํ ์คํธ: ๊ฐ Lambda ํจ์์ ํต์ฌ ๋ก์ง์ ๋ํด Jest, Mocha ๋ฑ์ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ ๋จ์ ํ ์คํธ๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ข์ต๋๋ค (ํ์ฌ ์ฝ๋๋ฒ ์ด์ค์๋ ๋ช ์์ ์ธ ๋จ์ ํ ์คํธ ํ๋ ์์ํฌ ์ฌ์ฉ์ด ๋๋๋ฌ์ง์ง ์์).
- ํตํฉ ํ ์คํธ: ๋ฐฐํฌ๋ ํ๊ฒฝ์์ ์๋น์ค ๊ฐ ์ํธ์์ฉ์ ํ ์คํธํฉ๋๋ค (์: API Gateway ์๋ํฌ์ธํธ ํธ์ถ).
8. ALPACO Lambda ์๋น์ค ์์ ๋ฐ MSA ํจํด ์ ์ฉ
8.1. code-grader
๋ฐ code-executor
(์ค์ผ์คํธ๋ ์ด์
๋ฐ ์์
์ ํจํด)
code-grader
๋ ์ฑ์ ์์ฒญ์ ๋ฐ๋ ์ค์ผ์คํธ๋ ์ดํฐ ์ญํ ์ ํฉ๋๋ค.code-executor
๋ ํน์ ์์ (์ฝ๋ ์คํ)์ ์ํํ๋ ์์ ์ ์ญํ ์ ํฉ๋๋ค.- ์ด ๋์ Lambda ์ง์ ๋๊ธฐ์ ํธ์ถ์ ํตํด ํต์ ํฉ๋๋ค.
- ์ด๋ MSA์์ ๋ณต์กํ ์์ ์ ๋ ์๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฌ์ด ๋จ์๋ก ๋๋๋ ์ผ๋ฐ์ ์ธ ํจํด์ ๋๋ค.
8.2. chatbot-query
๋ฐ problem-generator-v3
(์ธ๋ถ API ํตํฉ ๋ฐ ์คํธ๋ฆฌ๋ฐ)
- ๋ ์๋น์ค ๋ชจ๋ ์ธ๋ถ LLM(Google Gemini)๊ณผ ์ํธ์์ฉํฉ๋๋ค.
- API ํค์ ๊ฐ์ ๋ฏผ๊ฐํ ์ ๋ณด๋ ํ๊ฒฝ ๋ณ์๋ฅผ ํตํด ์์ ํ๊ฒ ๊ด๋ฆฌ๋ฉ๋๋ค.
- ์๋ต์ SSE ์คํธ๋ฆผ์ผ๋ก ํด๋ผ์ด์ธํธ์ ์ ์กํ์ฌ ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํต๋๋ค.
chatbot-query
๋ JWT ์ธ์ฆ์ ์ง์ ์ฒ๋ฆฌํ์ฌ ๋ณด์ ๊ณ์ธต์ ์ถ๊ฐํฉ๋๋ค.
8.3. ์ปค๋ฎค๋ํฐ API (CRUD ๋ฐ ๋ฐ์ดํฐ ์ค์ฌ ์๋น์ค)
createPost
,getPost
,updatePost
,deletePost
,likePost
,createComment
๋ฑ์ ํน์ ๋ฐ์ดํฐ ์ํฐํฐ(๊ฒ์๋ฌผ, ๋๊ธ)์ ๋ํ CRUDL(Create, Read, Update, Delete, Like) ์์ ์ ์ ๊ณตํฉ๋๋ค.- ๋จ์ผ DynamoDB ํ ์ด๋ธ๊ณผ ์ฌ๋ฌ GSI๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ํ ์ ๊ทผ ํจํด์ ์ง์ํฉ๋๋ค.
- ํธ๋์ญ์
์ ์ฌ์ฉํ์ฌ
commentCount
์ ๊ฐ์ ํ์ ๋ฐ์ดํฐ๋ฅผ ์ผ๊ด๋๊ฒ ์ ์งํฉ๋๋ค.
8.4. problems-api
๋ฐ submissions-api
(์ฝ๊ธฐ ์ ์ฉ ๋ฐ์ดํฐ API)
- ์ฃผ๋ก ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๊ณ ํํฐ๋งํ๋ ๊ฐ๋จํ API์ ๋๋ค.
- ๋ค๋ฅธ ์๋น์ค(
problem-generator-v3
,code-execution-service
)์ ์ํด ์ฑ์์ง DynamoDB ํ ์ด๋ธ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ต๋๋ค. - ํ์ด์ง๋ค์ด์ ๋ฐ ์ ๋ ฌ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด GSI๋ฅผ ํ์ฉํฉ๋๋ค.
9. ๊ฒฐ๋ก ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก ์์ฝ
ALPACO ํ๋ก์ ํธ๋ AWS Lambda๋ฅผ ํ์ฉํ์ฌ ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ ์ฒ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ตฌํํฉ๋๋ค. MSA ํ๊ฒฝ์์ Lambda๋ฅผ ๊ฐ๋ฐํ ๋ ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ณ ๋ คํ์ญ์์ค:
- ๋จ์ผ ์ฑ ์: Lambda ํจ์๋ฅผ ์๊ณ ํน์ ๊ธฐ๋ฅ์ ์ง์คํ๋๋ก ์ ์งํฉ๋๋ค.
- ์ํ ๋น์ ์ฅ(Stateless): Lambda ํจ์๋ ๊ฐ๋ฅํ ์ํ๋ฅผ ์ ์ฅํ์ง ์๋๋ก ์ค๊ณํฉ๋๋ค. ํ์ํ ์ํ๋ DynamoDB์ ๊ฐ์ ์ธ๋ถ ์ ์ฅ์์ ๋ณด๊ดํฉ๋๋ค.
- ํ๊ฒฝ ๋ณ์ ํ์ฉ: ์ค์ ์ ์ฝ๋์์ ๋ถ๋ฆฌํฉ๋๋ค.
- IAM ์ต์ ๊ถํ: ๊ฐ Lambda์ ํ์ํ ์ต์ํ์ ๊ถํ๋ง ๋ถ์ฌํฉ๋๋ค.
- ์ฝ๋ ์ฌ์ฌ์ฉ (Layers): ๊ณตํต ๋ก์ง ๋ฐ ์์กด์ฑ์ Lambda Layer๋ฅผ ํตํด ๊ณต์ ํฉ๋๋ค.
- ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ์ฌ์๋: ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฉ์ปค๋์ฆ๊ณผ ์ ์ ํ ์ฌ์๋ ๋ก์ง(์:
problem-generator-v3
ํ์ดํ๋ผ์ธ)์ ๊ตฌํํฉ๋๋ค. - ๋ก๊น ๋ฐ ๋ชจ๋ํฐ๋ง: ํฌ๊ด์ ์ธ ๋ก๊น ์ ํ์ฑํํ๊ณ CloudWatch๋ฅผ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ๊ณผ ์ค๋ฅ๋ฅผ ๋ชจ๋ํฐ๋งํฉ๋๋ค.
- IaC (Terraform): ์ธํ๋ผ๋ฅผ ์ฝ๋๋ก ๊ด๋ฆฌํ์ฌ ์ผ๊ด์ฑ, ๋ฐ๋ณต์ฑ ๋ฐ ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ๋ณด์ฅํฉ๋๋ค.
- API ๋ฒ์ ๊ด๋ฆฌ: API ๋ณ๊ฒฝ ์ ํ์ ํธํ์ฑ์ ์ ์งํ๊ฑฐ๋ API Gateway๋ฅผ ํตํด ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ๊ตฌํํฉ๋๋ค.
- ํ ์คํธ: ๋จ์ ํ ์คํธ, ํตํฉ ํ ์คํธ, ์ข ๋จ ๊ฐ ํ ์คํธ๋ฅผ ์ฒ ์ ํ ์ํํฉ๋๋ค.
์ด ๊ฐ์ด๋๊ฐ ALPACO ํ๋ก์ ํธ์ Lambda ๊ธฐ๋ฐ ๋ง์ดํฌ๋ก์๋น์ค๋ฅผ ์ดํดํ๊ณ ๊ฐ๋ฐํ๋ ๋ฐ ์ ์ฉํ ์๋ฃ๊ฐ ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.