์ด๋ฒคํธ ์์ฑ์ด ์ด๋ป๊ฒ ๊ฐ์ฌ ์ถ์ ๊ตฌํ์ ํ์ ํ์ฌ ๋ ๋ณด์ ์ธ ์ถ์ ๊ฐ๋ฅ์ฑ, ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ, ์์คํ ๋ณต์๋ ฅ์ ์ ๊ณตํ๋์ง ์์๋ณด์ธ์. ์ค์ ์์ ์ ๊ตฌํ ์ ๋ต์ ์ดํด๋ด ๋๋ค.
์ด๋ฒคํธ ์์ฑ: ๊ฒฌ๊ณ ํ๊ณ ์ถ์ ๊ฐ๋ฅํ ์์คํ ์ ์ํ ๊ฐ์ฌ ์ถ์ ๊ตฌํ
์ค๋๋ ๋ณต์กํ๊ฒ ์ํธ ์ฐ๊ฒฐ๋ ๋์งํธ ํ๊ฒฝ์์ ๊ฒฌ๊ณ ํ๊ณ ํฌ๊ด์ ์ธ ๊ฐ์ฌ ์ถ์ ์ ์ ์งํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ด๋ ์ข ์ข ๊ท์ ์๊ฑด์ผ ๋ฟ๋ง ์๋๋ผ ๋๋ฒ๊น , ๋ณด์ ๋ถ์ ๋ฐ ์์คํ ์ ๋ฐ์ ๊ณผ์ ์ ์ดํดํ๋ ๋ฐ์๋ ํ์์ ์ ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ํ์ ๋ชจ๋ ๋ณ๊ฒฝ ์ฌํญ์ ์ผ๋ จ์ ์ด๋ฒคํธ๋ก ์บก์ฒํ๋ ์ํคํ ์ฒ ํจํด์ธ ์ด๋ฒคํธ ์์ฑ์ ์ ๋ขฐํ ์ ์๊ณ ๊ฐ์ฌ ๊ฐ๋ฅํ๋ฉฐ ํ์ฅ ๊ฐ๋ฅํ ๊ฐ์ฌ ์ถ์ ์ ๊ตฌํํ๊ธฐ ์ํ ์ฐ์ํ๊ณ ๊ฐ๋ ฅํ ์๋ฃจ์ ์ ์ ๊ณตํฉ๋๋ค.
์ด๋ฒคํธ ์์ฑ์ด๋ ๋ฌด์์ธ๊ฐ?
๊ธฐ์กด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ์ ํ์ฌ ์ํ๋ง ์ ์ฅํฉ๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ๊ณผ๊ฑฐ ์ํ๋ฅผ ์ฌ๊ตฌ์ฑํ๊ฑฐ๋ ํ์ฌ ์ํ์ ์ด๋ฅด๊ฒ ํ ์ผ๋ จ์ ์ด๋ฒคํธ๋ฅผ ์ดํดํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค. ๋ฐ๋ฉด, ์ด๋ฒคํธ ์์ฑ์ ์ ํ๋ฆฌ์ผ์ด์ ์ํ์ ๋ํ ๋ชจ๋ ์ค์ํ ๋ณ๊ฒฝ ์ฌํญ์ ๋ถ๋ณ์ ์ด๋ฒคํธ๋ก ์บก์ฒํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค. ์ด๋ฌํ ์ด๋ฒคํธ๋ ์ถ๊ฐ ์ ์ฉ(append-only) ์ด๋ฒคํธ ์คํ ์ด์ ์ ์ฅ๋์ด ์์คํ ๋ด ๋ชจ๋ ์์ ์ ๋ํ ์์ ํ๊ณ ์๊ฐ ์์์ ๋ฐ๋ฅธ ๊ธฐ๋ก์ ํ์ฑํฉ๋๋ค.
์ํ ๊ณ์ข ์์ฅ๊ณผ ๊ฐ๋ค๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค. ๋จ์ํ ํ์ฌ ์์ก๋ง ๊ธฐ๋กํ๋ ๋์ , ๋ชจ๋ ์ ๊ธ, ์ถ๊ธ, ์ด์ฒด๋ ๋ณ๋์ ์ด๋ฒคํธ๋ก ๊ธฐ๋ก๋ฉ๋๋ค. ์ด๋ฌํ ์ด๋ฒคํธ๋ฅผ ์ฌ์คํํจ์ผ๋ก์จ ํน์ ์์ ์ ๊ณ์ข ์ํ๋ฅผ ์ฌ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
๊ฐ์ฌ ์ถ์ ์ ์ด๋ฒคํธ ์์ฑ์ ์ฌ์ฉํ๋ ์ด์ ๋ ๋ฌด์์ธ๊ฐ?
์ด๋ฒคํธ ์์ฑ์ ๊ฐ์ฌ ์ถ์ ๊ตฌํ์ ์์ด ๋ช ๊ฐ์ง ๊ฐ๋ ฅํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
- ์์ ํ๊ณ ๋ถ๋ณ์ ํ์คํ ๋ฆฌ: ๋ชจ๋ ๋ณ๊ฒฝ ์ฌํญ์ด ์ด๋ฒคํธ๋ก ์บก์ฒ๋์ด ์์คํ ๋ฐ์ ๊ณผ์ ์ ๋ํ ์์ ํ๊ณ ๋ถ๋ณ์ ๊ธฐ๋ก์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ๊ฐ์ฌ ์ถ์ ์ด ์ ํํ๊ณ ์๋ณ์กฐ๊ฐ ๋ถ๊ฐ๋ฅํจ์ ๋ณด์ฅํฉ๋๋ค.
- ์๊ฐ์ ์ฟผ๋ฆฌ: ํน์ ์์ ๊น์ง์ ์ด๋ฒคํธ๋ฅผ ์ฌ์คํํ์ฌ ์์คํ ์ ์ํ๋ฅผ ์ธ์ ๋ ์ง ์ฝ๊ฒ ์ฌ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ์ด๋ ๊ฐ์ฌ ๋ฐ ๋ถ์์ ์ํ ๊ฐ๋ ฅํ ์๊ฐ์ ์ฟผ๋ฆฌ ๊ธฐ๋ฅ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
- ๊ฐ์ฌ ๋ฐ ์ถ์ ๊ฐ๋ฅ์ฑ: ๊ฐ ์ด๋ฒคํธ์๋ ์ผ๋ฐ์ ์ผ๋ก ํ์์คํฌํ, ์ฌ์ฉ์ ID, ํธ๋์ญ์ ID์ ๊ฐ์ ๋ฉํ๋ฐ์ดํฐ๊ฐ ํฌํจ๋์ด ์์ด ๊ฐ ๋ณ๊ฒฝ์ ์ถ์ฒ์ ์ํฅ์ ์ฝ๊ฒ ์ถ์ ํ ์ ์์ต๋๋ค.
- ๋์ปคํ๋ง ๋ฐ ํ์ฅ์ฑ: ์ด๋ฒคํธ ์์ฑ์ ์์คํ ์ ์ฌ๋ฌ ๋ถ๋ถ ๊ฐ์ ๋์ปคํ๋ง์ ์ด์งํฉ๋๋ค. ์ด๋ฒคํธ๋ ์ฌ๋ฌ ๊ตฌ๋ ์์ ์ํด ์๋น๋ ์ ์์ด ํ์ฅ์ฑ๊ณผ ์ ์ฐ์ฑ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
- ๋๋ฒ๊น ๋ฐ ๋ณต๊ตฌ๋ฅผ ์ํ ์ฌ์คํ ๊ฐ๋ฅ์ฑ: ์ด๋ฒคํธ๋ฅผ ์ฌ์คํํ์ฌ ๋๋ฒ๊น ๋ชฉ์ ์ผ๋ก ๊ณผ๊ฑฐ ์ํ๋ฅผ ์ฌํํ๊ฑฐ๋ ์ค๋ฅ๋ก๋ถํฐ ๋ณต๊ตฌํ ์ ์์ต๋๋ค.
- CQRS ์ง์: ์ด๋ฒคํธ ์์ฑ์ ์ข ์ข ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ์์ ์ ๋ถ๋ฆฌํ์ฌ ์ฑ๋ฅ๊ณผ ํ์ฅ์ฑ์ ๋์ฑ ํฅ์์ํค๋ CQRS(Command Query Responsibility Segregation) ํจํด๊ณผ ํจ๊ป ์ฌ์ฉ๋ฉ๋๋ค.
๊ฐ์ฌ ์ถ์ ์ ์ํ ์ด๋ฒคํธ ์์ฑ ๊ตฌํ: ๋จ๊ณ๋ณ ๊ฐ์ด๋
๋ค์์ ๊ฐ์ฌ ์ถ์ ์ ์ํ ์ด๋ฒคํธ ์์ฑ ๊ตฌํ์ ๋ํ ์ค์ฉ์ ์ธ ๊ฐ์ด๋์ ๋๋ค:
1. ํต์ฌ ์ด๋ฒคํธ ์๋ณ
์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ ๊ฐ์ฌ ์ถ์ ์์ ์บก์ฒํ๊ณ ์ ํ๋ ํต์ฌ ์ด๋ฒคํธ๋ฅผ ์๋ณํ๋ ๊ฒ์ ๋๋ค. ์ด๋ฌํ ์ด๋ฒคํธ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ํ์ ์ค์ํ ๋ณ๊ฒฝ ์ฌํญ์ ๋ํ๋ด์ผ ํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ์์ ์ ๊ณ ๋ คํ์ญ์์ค:
- ์ฌ์ฉ์ ์ธ์ฆ (๋ก๊ทธ์ธ, ๋ก๊ทธ์์)
- ๋ฐ์ดํฐ ์์ฑ, ์์ ๋ฐ ์ญ์
- ํธ๋์ญ์ ์์ ๋ฐ ์๋ฃ
- ๊ตฌ์ฑ ๋ณ๊ฒฝ
- ๋ณด์ ๊ด๋ จ ์ด๋ฒคํธ (์: ์ ๊ทผ ์ ์ด ๋ณ๊ฒฝ)
์์: ์ ์์๊ฑฐ๋ ํ๋ซํผ์ ๊ฒฝ์ฐ, ํต์ฌ ์ด๋ฒคํธ์๋ "OrderCreated", "PaymentReceived", "OrderShipped", "ProductAddedToCart", "UserProfileUpdated" ๋ฑ์ด ํฌํจ๋ ์ ์์ต๋๋ค.
2. ์ด๋ฒคํธ ๊ตฌ์กฐ ์ ์
๊ฐ ์ด๋ฒคํธ๋ ๋ค์ ์ ๋ณด๋ฅผ ํฌํจํ๋ ์ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ ธ์ผ ํฉ๋๋ค:
- ์ด๋ฒคํธ ์ ํ: ์ด๋ฒคํธ์ ์ข ๋ฅ๋ฅผ ๋ํ๋ด๋ ๊ณ ์ ์๋ณ์ (์: "OrderCreated").
- ์ด๋ฒคํธ ๋ฐ์ดํฐ: ์ฃผ๋ฌธ ID, ์ ํ ID, ๊ณ ๊ฐ ID, ๊ฒฐ์ ๊ธ์ก ๋ฑ ์ด๋ฒคํธ์ ๊ด๋ จ๋ ๋ฐ์ดํฐ.
- ํ์์คํฌํ: ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋ ์ง์ ์๊ฐ. ์ฌ๋ฌ ์๊ฐ๋์ ๊ฑธ์น ์ผ๊ด์ฑ์ ์ํด UTC ์ฌ์ฉ์ ๊ณ ๋ คํ์ญ์์ค.
- ์ฌ์ฉ์ ID: ์ด๋ฒคํธ๋ฅผ ์์ํ ์ฌ์ฉ์์ ID.
- ํธ๋์ญ์ ID: ์ด๋ฒคํธ๊ฐ ์ํ ํธ๋์ญ์ ์ ๊ณ ์ ์๋ณ์. ์ด๋ ์ฌ๋ฌ ์ด๋ฒคํธ์ ๊ฑธ์ณ ์์์ฑ๊ณผ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๋ ๋ฐ ์ค์ํฉ๋๋ค.
- ์๊ด๊ด๊ณ ID: ์ฌ๋ฌ ์๋น์ค๋ ์ปดํฌ๋ํธ์ ๊ฑธ์ณ ๊ด๋ จ๋ ์ด๋ฒคํธ๋ฅผ ์ถ์ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์๋ณ์. ์ด๋ ํนํ ๋ง์ดํฌ๋ก์๋น์ค ์ํคํ ์ฒ์์ ์ ์ฉํฉ๋๋ค.
- ์ธ๊ณผ๊ด๊ณ ID: (์ ํ ์ฌํญ) ์ด ์ด๋ฒคํธ๋ฅผ ์ ๋ฐํ ์ด๋ฒคํธ์ ID. ์ด๋ ์ด๋ฒคํธ์ ์ธ๊ณผ ๊ด๊ณ ์ฌ์ฌ์ ์ถ์ ํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
- ๋ฉํ๋ฐ์ดํฐ: ์ฌ์ฉ์์ IP ์ฃผ์, ๋ธ๋ผ์ฐ์ ์ ํ, ์ง๋ฆฌ์ ์์น ๋ฑ ์ถ๊ฐ์ ์ธ ๋งฅ๋ฝ ์ ๋ณด. ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ์ ์ฅํ ๋ GDPR๊ณผ ๊ฐ์ ๋ฐ์ดํฐ ๊ฐ์ธ์ ๋ณด ๋ณดํธ ๊ท์ ์ ์ ์ํ์ญ์์ค.
์์: "OrderCreated" ์ด๋ฒคํธ๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค:
{
"eventType": "OrderCreated",
"eventData": {
"orderId": "12345",
"customerId": "67890",
"orderDate": "2023-10-27T10:00:00Z",
"totalAmount": 100.00,
"currency": "USD",
"shippingAddress": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"zipCode": "91234",
"country": "USA"
}
},
"timestamp": "2023-10-27T10:00:00Z",
"userId": "user123",
"transactionId": "tx12345",
"correlationId": "corr123",
"metadata": {
"ipAddress": "192.168.1.1",
"browser": "Chrome",
"location": {
"latitude": 34.0522,
"longitude": -118.2437
}
}
}
3. ์ด๋ฒคํธ ์คํ ์ด ์ ํ
์ด๋ฒคํธ ์คํ ์ด๋ ์ด๋ฒคํธ๋ฅผ ์ ์ฅํ๋ ์ค์ ์ ์ฅ์์ ๋๋ค. ์ด๋ ์ด๋ฒคํธ ์ํ์ค์ ์ฐ๊ธฐ ๋ฐ ์ฝ๊ธฐ์ ์ต์ ํ๋ ์ถ๊ฐ ์ ์ฉ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ฌ์ผ ํฉ๋๋ค. ์ฌ๋ฌ ์ต์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
- ์ ์ฉ ์ด๋ฒคํธ ์คํ ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค: EventStoreDB ๋ฐ AxonDB์ ๊ฐ์ด ์ด๋ฒคํธ ์์ฑ์ ์ํด ํน๋ณํ ์ค๊ณ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋๋ค. ์ด๋ฒคํธ ์คํธ๋ฆผ, ํ๋ก์ ์ , ๊ตฌ๋ ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค: PostgreSQL์ด๋ MySQL๊ณผ ๊ฐ์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ด๋ฒคํธ ์คํ ์ด๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ถ๊ฐ ์ ์ฉ ์๋งจํฑ๊ณผ ์ด๋ฒคํธ ์คํธ๋ฆผ ๊ด๋ฆฌ๋ฅผ ์ง์ ๊ตฌํํด์ผ ํฉ๋๋ค. ์ด๋ฒคํธ ID, ์ด๋ฒคํธ ์ ํ, ์ด๋ฒคํธ ๋ฐ์ดํฐ, ํ์์คํฌํ ๋ฐ ๋ฉํ๋ฐ์ดํฐ์ฉ ์ด์ด ์๋ ์ ์ฉ ํ ์ด๋ธ ์ฌ์ฉ์ ๊ณ ๋ คํ์ญ์์ค.
- NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค: MongoDB๋ Cassandra์ ๊ฐ์ NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ด๋ฒคํธ ์คํ ์ด๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ ์ฐ์ฑ๊ณผ ํ์ฅ์ฑ์ ์ ๊ณตํ์ง๋ง ํ์ํ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ๋ฐ ๋ ๋ง์ ๋ ธ๋ ฅ์ด ํ์ํ ์ ์์ต๋๋ค.
- ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ ์๋ฃจ์ : AWS, Azure, Google Cloud์ ๊ฐ์ ํด๋ผ์ฐ๋ ์ ๊ณต์ ์ฒด๋ Kafka, Kinesis, Pub/Sub์ ๊ฐ์ ๊ด๋ฆฌํ ์ด๋ฒคํธ ์คํธ๋ฆฌ๋ฐ ์๋น์ค๋ฅผ ์ ๊ณตํ๋ฉฐ, ์ด๋ฅผ ์ด๋ฒคํธ ์คํ ์ด๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฌํ ์๋น์ค๋ ํ์ฅ์ฑ, ์์ ์ฑ ๋ฐ ๋ค๋ฅธ ํด๋ผ์ฐ๋ ์๋น์ค์์ ํตํฉ์ ์ ๊ณตํฉ๋๋ค.
์ด๋ฒคํธ ์คํ ์ด๋ฅผ ์ ํํ ๋ ๋ค์๊ณผ ๊ฐ์ ์์๋ฅผ ๊ณ ๋ คํ์ญ์์ค:
- ํ์ฅ์ฑ: ์ด๋ฒคํธ ์คํ ์ด๊ฐ ์์๋๋ ์ด๋ฒคํธ ์์ ์ฒ๋ฆฌํ ์ ์์ต๋๊น?
- ๋ด๊ตฌ์ฑ: ๋ฐ์ดํฐ ์์ค ๋ฐฉ์ง ์ธก๋ฉด์์ ์ด๋ฒคํธ ์คํ ์ด๋ ์ผ๋ง๋ ์ ๋ขฐํ ์ ์์ต๋๊น?
- ์ฟผ๋ฆฌ ๊ธฐ๋ฅ: ์ด๋ฒคํธ ์คํ ์ด๊ฐ ๊ฐ์ฌ ๋ฐ ๋ถ์์ ํ์ํ ์ ํ์ ์ฟผ๋ฆฌ๋ฅผ ์ง์ํฉ๋๊น?
- ํธ๋์ญ์ ์ง์: ์ด๋ฒคํธ ์คํ ์ด๊ฐ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ACID ํธ๋์ญ์ ์ ์ง์ํฉ๋๊น?
- ํตํฉ: ์ด๋ฒคํธ ์คํ ์ด๊ฐ ๊ธฐ์กด ์ธํ๋ผ ๋ฐ ๋๊ตฌ์ ์ ํตํฉ๋ฉ๋๊น?
- ๋น์ฉ: ์คํ ๋ฆฌ์ง, ์ปดํจํ , ๋คํธ์ํฌ ๋น์ฉ์ ํฌํจํ ์ด๋ฒคํธ ์คํ ์ด ์ฌ์ฉ ๋น์ฉ์ ์ผ๋ง์ ๋๊น?
4. ์ด๋ฒคํธ ๋ฐํ ๊ตฌํ
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ฅผ ์ด๋ฒคํธ ์คํ ์ด์ ๋ฐํํด์ผ ํฉ๋๋ค. ์ด๋ ์ผ๋ฐ์ ์ผ๋ก ๋ค์ ๋จ๊ณ๋ฅผ ํฌํจํฉ๋๋ค:
- ์ด๋ฒคํธ ๊ฐ์ฒด ์์ฑ: ์ด๋ฒคํธ ์ ํ, ์ด๋ฒคํธ ๋ฐ์ดํฐ, ํ์์คํฌํ, ์ฌ์ฉ์ ID ๋ฐ ๊ธฐํ ๊ด๋ จ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๋ ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
- ์ด๋ฒคํธ ์ง๋ ฌํ: ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ JSON์ด๋ Avro์ ๊ฐ์ด ์ด๋ฒคํธ ์คํ ์ด์ ์ ์ฅํ ์ ์๋ ํ์์ผ๋ก ์ง๋ ฌํํฉ๋๋ค.
- ์ด๋ฒคํธ ์คํ ์ด์ ์ด๋ฒคํธ ์ถ๊ฐ: ์ง๋ ฌํ๋ ์ด๋ฒคํธ๋ฅผ ์ด๋ฒคํธ ์คํ ์ด์ ์ถ๊ฐํฉ๋๋ค. ๋ฐ์ดํฐ ์์์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ด ์์ ์ด ์์์ ์ผ๋ก ์ํ๋๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ๊ตฌ๋ ์์๊ฒ ์ด๋ฒคํธ ๋ฐํ: (์ ํ ์ฌํญ) ์ด๋ฒคํธ๋ฅผ ์์ ํ๋ ๋ฐ ๊ด์ฌ์ด ์๋ ๋ชจ๋ ๊ตฌ๋ ์์๊ฒ ์ด๋ฒคํธ๋ฅผ ๋ฐํํฉ๋๋ค. ์ด๋ ๋ฉ์์ง ํ๋ ๋ฐํ-๊ตฌ๋ ํจํด์ ์ฌ์ฉํ์ฌ ์ํํ ์ ์์ต๋๋ค.
์์ (๊ฐ์์ EventStoreService ์ฌ์ฉ):
public class OrderService {
private final EventStoreService eventStoreService;
public OrderService(EventStoreService eventStoreService) {
this.eventStoreService = eventStoreService;
}
public void createOrder(Order order, String userId) {
// ... ์ฃผ๋ฌธ ์์ฑ์ ์ํ ๋น์ฆ๋์ค ๋ก์ง ...
OrderCreatedEvent event = new OrderCreatedEvent(
order.getOrderId(),
order.getCustomerId(),
order.getOrderDate(),
order.getTotalAmount(),
order.getCurrency(),
order.getShippingAddress()
);
eventStoreService.appendEvent("order", order.getOrderId(), event, userId);
}
}
public class EventStoreService {
public void appendEvent(String streamName, String entityId, Object event, String userId) {
// ์ด๋ฒคํธ ๊ฐ์ฒด ์์ฑ
EventRecord eventRecord = new EventRecord(
UUID.randomUUID(), // eventId
streamName, // streamName
entityId, // entityId
event.getClass().getName(), // eventType
toJson(event), // eventData
Instant.now().toString(), // timestamp
userId // userId
);
// ์ด๋ฒคํธ ์ง๋ ฌํ
String serializedEvent = toJson(eventRecord);
// ์ด๋ฒคํธ ์คํ ์ด์ ์ด๋ฒคํธ ์ถ๊ฐ (์ ํํ ์ด๋ฒคํธ ์คํ ์ด์ ๋ฐ๋ผ ๊ตฌํ์ด ๋ฌ๋ผ์ง)
storeEventInDatabase(serializedEvent);
// ๊ตฌ๋
์์๊ฒ ์ด๋ฒคํธ ๋ฐํ (์ ํ ์ฌํญ)
publishEventToMessageQueue(serializedEvent);
}
// ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐ ๋ฉ์์ง ํ ์ํธ ์์ฉ์ ์ํ ํ๋ ์ด์คํ๋ ๋ฉ์๋
private void storeEventInDatabase(String serializedEvent) {
// ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ด๋ฒคํธ๋ฅผ ์ ์ฅํ๋ ๊ตฌํ
System.out.println("๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ด๋ฒคํธ ์ ์ฅ: " + serializedEvent);
}
private void publishEventToMessageQueue(String serializedEvent) {
// ๋ฉ์์ง ํ์ ์ด๋ฒคํธ๋ฅผ ๋ฐํํ๋ ๊ตฌํ
System.out.println("๋ฉ์์ง ํ์ ์ด๋ฒคํธ ๋ฐํ: " + serializedEvent);
}
private String toJson(Object obj) {
// ์ด๋ฒคํธ๋ฅผ JSON์ผ๋ก ์ง๋ ฌํํ๋ ๊ตฌํ
try {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException("์ด๋ฒคํธ๋ฅผ JSON์ผ๋ก ์ง๋ ฌํํ๋ ์ค ์ค๋ฅ ๋ฐ์", e);
}
}
}
class EventRecord {
private final UUID eventId;
private final String streamName;
private final String entityId;
private final String eventType;
private final String eventData;
private final String timestamp;
private final String userId;
public EventRecord(UUID eventId, String streamName, String entityId, String eventType, String eventData, String timestamp, String userId) {
this.eventId = eventId;
this.streamName = streamName;
this.entityId = entityId;
this.eventType = eventType;
this.eventData = eventData;
this.timestamp = timestamp;
this.userId = userId;
}
// Getters
@Override
public String toString() {
return "EventRecord{" +
"eventId=" + eventId +
", streamName='" + streamName + '\'' +
", entityId='" + entityId + '\'' +
", eventType='" + eventType + '\'' +
", eventData='" + eventData + '\'' +
", timestamp='" + timestamp + '\'' +
", userId='" + userId + '\'' +
'}';
}
}
class OrderCreatedEvent {
private final String orderId;
private final String customerId;
private final String orderDate;
private final double totalAmount;
private final String currency;
private final String shippingAddress;
public OrderCreatedEvent(String orderId, String customerId, String orderDate, double totalAmount, String currency, String shippingAddress) {
this.orderId = orderId;
this.customerId = customerId;
this.orderDate = orderDate;
this.totalAmount = totalAmount;
this.currency = currency;
this.shippingAddress = shippingAddress;
}
// ๋ชจ๋ ํ๋์ ๋ํ Getter
public String getOrderId() { return orderId; }
public String getCustomerId() { return customerId; }
public String getOrderDate() { return orderDate; }
public double getTotalAmount() { return totalAmount; }
public String getCurrency() { return currency; }
public String getShippingAddress() { return shippingAddress; }
@Override
public String toString() {
return "OrderCreatedEvent{" +
"orderId='" + orderId + '\'' +
", customerId='" + customerId + '\'' +
", orderDate='" + orderDate + '\'' +
", totalAmount=" + totalAmount +
", currency='" + currency + '\'' +
", shippingAddress='" + shippingAddress + '\'' +
'}';
}
}
class Order {
private final String orderId;
private final String customerId;
private final String orderDate;
private final double totalAmount;
private final String currency;
private final String shippingAddress;
public Order(String orderId, String customerId, String orderDate, double totalAmount, String currency, String shippingAddress) {
this.orderId = orderId;
this.customerId = customerId;
this.orderDate = orderDate;
this.totalAmount = totalAmount;
this.currency = currency;
this.shippingAddress = shippingAddress;
}
// ๋ชจ๋ ํ๋์ ๋ํ Getter
public String getOrderId() { return orderId; }
public String getCustomerId() { return customerId; }
public String getOrderDate() { return orderDate; }
public double getTotalAmount() { return totalAmount; }
public String getCurrency() { return currency; }
public String getShippingAddress() { return shippingAddress; }
@Override
public String toString() {
return "Order{" +
"orderId='" + orderId + '\'' +
", customerId='" + customerId + '\'' +
", orderDate='" + orderDate + '\'' +
", totalAmount=" + totalAmount +
", currency='" + currency + '\'' +
", shippingAddress='" + shippingAddress + '\'' +
'}';
}
}
5. ์ฝ๊ธฐ ๋ชจ๋ธ(ํ๋ก์ ์ ) ๊ตฌ์ถ
์ด๋ฒคํธ ์คํ ์ด๋ ๋ชจ๋ ๋ณ๊ฒฝ์ ๋ํ ์์ ํ ํ์คํ ๋ฆฌ๋ฅผ ์ ๊ณตํ์ง๋ง, ์ฝ๊ธฐ ์์ ์ ์ํด ์ง์ ์ฟผ๋ฆฌํ๋ ๊ฒ์ ์ข ์ข ๋นํจ์จ์ ์ ๋๋ค. ๋์ , ํน์ ์ฟผ๋ฆฌ ํจํด์ ์ต์ ํ๋ ์ฝ๊ธฐ ๋ชจ๋ธ(ํ๋ก์ ์ ์ด๋ผ๊ณ ๋ ํจ)์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ฝ๊ธฐ ๋ชจ๋ธ์ ์ด๋ฒคํธ ์คํธ๋ฆผ์์ ํ์๋๋ฉฐ ์ ์ด๋ฒคํธ๊ฐ ๊ฒ์๋ ๋ ๋น๋๊ธฐ์ ์ผ๋ก ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
์์: ํน์ ๊ณ ๊ฐ์ ๋ชจ๋ ์ฃผ๋ฌธ ๋ชฉ๋ก์ ํฌํจํ๋ ์ฝ๊ธฐ ๋ชจ๋ธ์ด๋ ํน์ ์ ํ์ ํ๋งค ๋ฐ์ดํฐ๋ฅผ ์์ฝํ๋ ์ฝ๊ธฐ ๋ชจ๋ธ์ ๋ง๋ค ์ ์์ต๋๋ค.
์ฝ๊ธฐ ๋ชจ๋ธ์ ๊ตฌ์ถํ๋ ค๋ฉด ์ด๋ฒคํธ ์คํธ๋ฆผ์ ๊ตฌ๋ ํ๊ณ ๊ฐ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. ๊ฐ ์ด๋ฒคํธ์ ๋ํด ์ฝ๊ธฐ ๋ชจ๋ธ์ ์ ์ ํ๊ฒ ์ ๋ฐ์ดํธํฉ๋๋ค.
์์:
public class OrderSummaryReadModelUpdater {
private final OrderSummaryRepository orderSummaryRepository;
public OrderSummaryReadModelUpdater(OrderSummaryRepository orderSummaryRepository) {
this.orderSummaryRepository = orderSummaryRepository;
}
public void handle(OrderCreatedEvent event) {
OrderSummary orderSummary = new OrderSummary(
event.getOrderId(),
event.getCustomerId(),
event.getOrderDate(),
event.getTotalAmount(),
event.getCurrency()
);
orderSummaryRepository.save(orderSummary);
}
// PaymentReceivedEvent, OrderShippedEvent ๋ฑ์ ๋ํ ๋ค๋ฅธ ์ด๋ฒคํธ ํธ๋ค๋ฌ
}
interface OrderSummaryRepository {
void save(OrderSummary orderSummary);
}
class OrderSummary {
private final String orderId;
private final String customerId;
private final String orderDate;
private final double totalAmount;
private final String currency;
public OrderSummary(String orderId, String customerId, String orderDate, double totalAmount, String currency) {
this.orderId = orderId;
this.customerId = customerId;
this.orderDate = orderDate;
this.totalAmount = totalAmount;
this.currency = currency;
}
//Getters
}
6. ์ด๋ฒคํธ ์คํ ์ด ๋ณด์
์ด๋ฒคํธ ์คํ ์ด์๋ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๊ฐ ํฌํจ๋์ด ์์ผ๋ฏ๋ก ์ ์ ํ๊ฒ ๋ณด์ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋ค์ ๋ณด์ ์กฐ์น๋ฅผ ๊ณ ๋ คํ์ญ์์ค:
- ์ ๊ทผ ์ ์ด: ์น์ธ๋ ์ฌ์ฉ์ ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ๋ง ์ด๋ฒคํธ ์คํ ์ด์ ์ ๊ทผํ๋๋ก ์ ํํฉ๋๋ค. ๊ฐ๋ ฅํ ์ธ์ฆ ๋ฐ ์ธ๊ฐ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ์ญ์์ค.
- ์ํธํ: ๋ฌด๋จ ์ ๊ทผ์ผ๋ก๋ถํฐ ๋ณดํธํ๊ธฐ ์ํด ์ด๋ฒคํธ ์คํ ์ด์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅ ์(at rest) ๋ฐ ์ ์ก ์ค(in transit)์ ์ํธํํฉ๋๋ค. ์ถ๊ฐ ๋ณด์์ ์ํด ํ๋์จ์ด ๋ณด์ ๋ชจ๋(HSM)์์ ๊ด๋ฆฌํ๋ ์ํธํ ํค ์ฌ์ฉ์ ๊ณ ๋ คํ์ญ์์ค.
- ๊ฐ์ฌ: ๋ฌด๋จ ํ๋์ ํ์งํ๊ณ ๋ฐฉ์งํ๊ธฐ ์ํด ์ด๋ฒคํธ ์คํ ์ด์ ๋ํ ๋ชจ๋ ์ ๊ทผ์ ๊ฐ์ฌํฉ๋๋ค.
- ๋ฐ์ดํฐ ๋ง์คํน: ๋ฌด๋จ ๊ณต๊ฐ๋ก๋ถํฐ ๋ณดํธํ๊ธฐ ์ํด ์ด๋ฒคํธ ์คํ ์ด์ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ๋ง์คํนํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ ์ฉ์นด๋ ๋ฒํธ๋ ์ฃผ๋ฏผ๋ฑ๋ก๋ฒํธ์ ๊ฐ์ ๊ฐ์ธ ์๋ณ ์ ๋ณด(PII)๋ฅผ ๋ง์คํนํ ์ ์์ต๋๋ค.
- ์ ๊ธฐ ๋ฐฑ์ : ๋ฐ์ดํฐ ์์ค๋ก๋ถํฐ ๋ณดํธํ๊ธฐ ์ํด ์ด๋ฒคํธ ์คํ ์ด๋ฅผ ์ ๊ธฐ์ ์ผ๋ก ๋ฐฑ์ ํฉ๋๋ค. ๋ฐฑ์ ์ ์์ ํ ์์น์ ์ ์ฅํ์ญ์์ค.
- ์ฌํด ๋ณต๊ตฌ: ์ฌํด ๋ฐ์ ์ ์ด๋ฒคํธ ์คํ ์ด๋ฅผ ๋ณต๊ตฌํ ์ ์๋๋ก ์ฌํด ๋ณต๊ตฌ ๊ณํ์ ๊ตฌํํ์ญ์์ค.
7. ๊ฐ์ฌ ๋ฐ ๋ณด๊ณ ๊ตฌํ
์ด๋ฒคํธ ์์ฑ์ ๊ตฌํํ ํ์๋ ์ด๋ฒคํธ ์คํธ๋ฆผ์ ์ฌ์ฉํ์ฌ ๊ฐ์ฌ ๋ณด๊ณ ์๋ฅผ ์์ฑํ๊ณ ๋ณด์ ๋ถ์์ ์ํํ ์ ์์ต๋๋ค. ์ด๋ฒคํธ ์คํ ์ด๋ฅผ ์ฟผ๋ฆฌํ์ฌ ํน์ ์ฌ์ฉ์, ํธ๋์ญ์ ๋๋ ์ํฐํฐ์ ๊ด๋ จ๋ ๋ชจ๋ ์ด๋ฒคํธ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. ๋ํ ์ด๋ฒคํธ ์คํธ๋ฆผ์ ์ฌ์ฉํ์ฌ ํน์ ์์ ์ ์์คํ ์ํ๋ฅผ ์ฌ๊ตฌ์ฑํ ์๋ ์์ต๋๋ค.
์์: ํน์ ๊ธฐ๊ฐ ๋์ ํน์ ์ฌ์ฉ์ ํ๋กํ์ ์ ์ฉ๋ ๋ชจ๋ ๋ณ๊ฒฝ ์ฌํญ์ ๋ณด์ฌ์ฃผ๋ ๋ณด๊ณ ์๋ ํน์ ์ฌ์ฉ์๊ฐ ์์ํ ๋ชจ๋ ํธ๋์ญ์ ์ ๋ณด์ฌ์ฃผ๋ ๋ณด๊ณ ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
๋ค์ ๋ณด๊ณ ๊ธฐ๋ฅ์ ๊ณ ๋ คํ์ญ์์ค:
- ์ฌ์ฉ์ ํ๋ ๋ณด๊ณ ์: ์ฌ์ฉ์ ๋ก๊ทธ์ธ, ๋ก๊ทธ์์ ๋ฐ ๊ธฐํ ํ๋์ ์ถ์ ํฉ๋๋ค.
- ๋ฐ์ดํฐ ๋ณ๊ฒฝ ๋ณด๊ณ ์: ์ค์ํ ๋ฐ์ดํฐ ์ํฐํฐ์ ๋ณ๊ฒฝ ์ฌํญ์ ๋ชจ๋ํฐ๋งํฉ๋๋ค.
- ๋ณด์ ์ด๋ฒคํธ ๋ณด๊ณ ์: ์คํจํ ๋ก๊ทธ์ธ ์๋๋ ๋ฌด๋จ ์ ๊ทผ ์๋์ ๊ฐ์ ์์ฌ์ค๋ฌ์ด ํ๋์ ๋ํด ๊ฒฝ๊ณ ํฉ๋๋ค.
- ๊ท์ ์ค์ ๋ณด๊ณ ์: ๊ท์ ์ค์(์: GDPR, HIPAA)์ ํ์ํ ๋ณด๊ณ ์๋ฅผ ์์ฑํฉ๋๋ค.
์ด๋ฒคํธ ์์ฑ์ ๊ณผ์
์ด๋ฒคํธ ์์ฑ์ ๋ง์ ์ด์ ์ ์ ๊ณตํ์ง๋ง ๋ช ๊ฐ์ง ๊ณผ์ ๋ ์ ์ํฉ๋๋ค:
- ๋ณต์ก์ฑ: ์ด๋ฒคํธ ์์ฑ์ ์์คํ ์ํคํ ์ฒ์ ๋ณต์ก์ฑ์ ๋ํฉ๋๋ค. ์ด๋ฒคํธ ๊ตฌ์กฐ๋ฅผ ์ค๊ณํ๊ณ , ์ด๋ฒคํธ ์คํ ์ด๋ฅผ ์ ํํ๊ณ , ์ด๋ฒคํธ ๋ฐํ ๋ฐ ์๋น๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค.
- ์ต์ข ์ ์ผ๊ด์ฑ: ์ฝ๊ธฐ ๋ชจ๋ธ์ ์ด๋ฒคํธ ์คํธ๋ฆผ๊ณผ ์ต์ข ์ ์ผ๋ก ์ผ๊ด๋ฉ๋๋ค. ์ด๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ์์ ๊ณผ ์ฝ๊ธฐ ๋ชจ๋ธ์ด ์ ๋ฐ์ดํธ๋๋ ์์ ์ฌ์ด์ ์ง์ฐ์ด ์์ ์ ์์์ ์๋ฏธํฉ๋๋ค. ์ด๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค์์ ๋ถ์ผ์น๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค.
- ์ด๋ฒคํธ ๋ฒ์ ๊ด๋ฆฌ: ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ฐ์ ํจ์ ๋ฐ๋ผ ์ด๋ฒคํธ์ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํด์ผ ํ ์ ์์ต๋๋ค. ๊ธฐ์กด ์ด๋ฒคํธ๊ฐ ์ฌ์ ํ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌ๋ ์ ์๋๋ก ๋ณด์ฅํด์ผ ํ๋ฏ๋ก ์ด๋ ์ด๋ ค์ธ ์ ์์ต๋๋ค. ์ฌ๋ฌ ์ด๋ฒคํธ ๋ฒ์ ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ด๋ฒคํธ ์ ์บ์คํ ๊ณผ ๊ฐ์ ๊ธฐ์ ์ฌ์ฉ์ ๊ณ ๋ คํ์ญ์์ค.
- ์ต์ข ์ ์ผ๊ด์ฑ๊ณผ ๋ถ์ฐ ํธ๋์ญ์ : ์ด๋ฒคํธ ์์ฑ์ผ๋ก ๋ถ์ฐ ํธ๋์ญ์ ์ ๊ตฌํํ๋ ๊ฒ์ ๋ณต์กํ ์ ์์ต๋๋ค. ์ฌ๋ฌ ์๋น์ค์ ๊ฑธ์ณ ์ด๋ฒคํธ๊ฐ ์ผ๊ด๋ ๋ฐฉ์์ผ๋ก ๊ฒ์๋๊ณ ์๋น๋๋๋ก ๋ณด์ฅํด์ผ ํฉ๋๋ค.
- ์ด์ ์ค๋ฒํค๋: ์ด๋ฒคํธ ์คํ ์ด์ ๊ด๋ จ ์ธํ๋ผ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ ์ด์ ์ค๋ฒํค๋๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ด๋ฒคํธ ์คํ ์ด๋ฅผ ๋ชจ๋ํฐ๋งํ๊ณ , ๋ฐฑ์ ํ๊ณ , ์ํํ๊ฒ ์คํ๋๋๋ก ๋ณด์ฅํด์ผ ํฉ๋๋ค.
์ด๋ฒคํธ ์์ฑ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
์ด๋ฒคํธ ์์ฑ์ ๊ณผ์ ๋ฅผ ์ํํ๋ ค๋ฉด ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด์ญ์์ค:
- ์๊ฒ ์์ํ๊ธฐ: ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ๋ถ๋ถ์์ ์ด๋ฒคํธ ์์ฑ์ ๊ตฌํํ๋ ๊ฒ์ผ๋ก ์์ํ์ญ์์ค. ์ด๋ฅผ ํตํด ๊ฐ๋ ์ ๋ฐฐ์ฐ๊ณ ๋ ๋ณต์กํ ์์ญ์ ์ ์ฉํ๊ธฐ ์ ์ ๊ฒฝํ์ ์์ ์ ์์ต๋๋ค.
- ํ๋ ์์ํฌ ์ฌ์ฉ: Axon Framework๋ Spring Cloud Stream๊ณผ ๊ฐ์ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฒคํธ ์์ฑ ๊ตฌํ์ ๋จ์ํํ์ญ์์ค. ์ด๋ฌํ ํ๋ ์์ํฌ๋ ์ด๋ฒคํธ, ํ๋ก์ ์ , ๊ตฌ๋ ์ ๊ด๋ฆฌํ๋ ๋ฐ ๋์์ด ๋๋ ์ถ์ํ์ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ์ด๋ฒคํธ ์ ์คํ๊ฒ ์ค๊ณํ๊ธฐ: ํ์ํ ๋ชจ๋ ์ ๋ณด๋ฅผ ์บก์ฒํ๋๋ก ์ด๋ฒคํธ๋ฅผ ์ ์คํ๊ฒ ์ค๊ณํ์ญ์์ค. ์ด๋ฒคํธ์ ๋๋ฌด ๋ง์ ์ ๋ณด๋ฅผ ํฌํจํ๋ฉด ์ฒ๋ฆฌํ๊ธฐ ์ด๋ ค์์ง ์ ์์ผ๋ฏ๋ก ํผํ์ญ์์ค.
- ์ด๋ฒคํธ ์ ์บ์คํ ๊ตฌํ: ์ด๋ฒคํธ ๊ตฌ์กฐ ๋ณ๊ฒฝ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ด๋ฒคํธ ์ ์บ์คํ ์ ๊ตฌํํ์ญ์์ค. ์ด๋ฅผ ํตํด ์ด๋ฒคํธ ๊ตฌ์กฐ๊ฐ ๋ณ๊ฒฝ๋ ํ์๋ ๊ธฐ์กด ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
- ์์คํ ๋ชจ๋ํฐ๋ง: ์ค๋ฅ๋ฅผ ๊ฐ์งํ๊ณ ๋ฐฉ์งํ๊ธฐ ์ํด ์์คํ ์ ๋ฉด๋ฐํ ๋ชจ๋ํฐ๋งํ์ญ์์ค. ์ด๋ฒคํธ ์คํ ์ด, ์ด๋ฒคํธ ๋ฐํ ํ๋ก์ธ์ค, ์ฝ๊ธฐ ๋ชจ๋ธ ์ ๋ฐ์ดํธ๋ฅผ ๋ชจ๋ํฐ๋งํ์ญ์์ค.
- ๋ฉฑ๋ฑ์ฑ ์ฒ๋ฆฌ: ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฉฑ๋ฑ์ฑ์ ๊ฐ๋๋ก ๋ณด์ฅํ์ญ์์ค. ์ด๋ ๋์ผํ ์ด๋ฒคํธ๋ฅผ ์ฌ๋ฌ ๋ฒ ์ฒ๋ฆฌํด๋ ํด๋ฅผ ๋ผ์น์ง ์์์ ์๋ฏธํฉ๋๋ค. ๋ถ์ฐ ์์คํ ์์๋ ์ด๋ฒคํธ๊ฐ ๋ ๋ฒ ์ด์ ์ ๋ฌ๋ ์ ์์ผ๋ฏ๋ก ์ด๊ฒ์ด ์ค์ํฉ๋๋ค.
- ๋ณด์ ํธ๋์ญ์ ๊ณ ๋ ค: ์ด๋ฒคํธ๊ฐ ๊ฒ์๋ ํ ์์ ์ด ์คํจํ๋ฉด ๋ณ๊ฒฝ ์ฌํญ์ ๋๋๋ฆฌ๊ธฐ ์ํด ๋ณด์ ํธ๋์ญ์ ์ ์คํํด์ผ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ฃผ๋ฌธ์ด ์์ฑ๋์์ง๋ง ๊ฒฐ์ ๊ฐ ์คํจํ๋ฉด ์ฃผ๋ฌธ์ ์ทจ์ํด์ผ ํ ์ ์์ต๋๋ค.
์ด๋ฒคํธ ์์ฑ์ ์ค์ ์ฌ๋ก
์ด๋ฒคํธ ์์ฑ์ ๋ค์์ ํฌํจํ ๋ค์ํ ์ฐ์ ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉ๋ฉ๋๋ค:
- ๊ธ์ต ์๋น์ค: ์ํ ๋ฐ ๊ธ์ต ๊ธฐ๊ด์ ์ด๋ฒคํธ ์์ฑ์ ์ฌ์ฉํ์ฌ ๊ฑฐ๋๋ฅผ ์ถ์ ํ๊ณ , ๊ณ์ข๋ฅผ ๊ด๋ฆฌํ๊ณ , ์ฌ๊ธฐ๋ฅผ ํ์งํฉ๋๋ค.
- ์ ์์๊ฑฐ๋: ์ ์์๊ฑฐ๋ ํ์ฌ๋ ์ด๋ฒคํธ ์์ฑ์ ์ฌ์ฉํ์ฌ ์ฃผ๋ฌธ์ ๊ด๋ฆฌํ๊ณ , ์ฌ๊ณ ๋ฅผ ์ถ์ ํ๊ณ , ๊ณ ๊ฐ ๊ฒฝํ์ ๊ฐ์ธํํฉ๋๋ค.
- ๊ฒ์: ๊ฒ์ ๊ฐ๋ฐ์๋ ์ด๋ฒคํธ ์์ฑ์ ์ฌ์ฉํ์ฌ ๊ฒ์ ์ํ๋ฅผ ์ถ์ ํ๊ณ , ํ๋ ์ด์ด ์งํ ์ํฉ์ ๊ด๋ฆฌํ๊ณ , ๋ฉํฐํ๋ ์ด์ด ๊ธฐ๋ฅ์ ๊ตฌํํฉ๋๋ค.
- ๊ณต๊ธ๋ง ๊ด๋ฆฌ: ๊ณต๊ธ๋ง ํ์ฌ๋ ์ด๋ฒคํธ ์์ฑ์ ์ฌ์ฉํ์ฌ ์ํ์ ์ถ์ ํ๊ณ , ์ฌ๊ณ ๋ฅผ ๊ด๋ฆฌํ๊ณ , ๋ฌผ๋ฅ๋ฅผ ์ต์ ํํฉ๋๋ค.
- ์๋ฃ: ์๋ฃ ์ ๊ณต์๋ ์ด๋ฒคํธ ์์ฑ์ ์ฌ์ฉํ์ฌ ํ์ ๊ธฐ๋ก์ ์ถ์ ํ๊ณ , ์์ฝ์ ๊ด๋ฆฌํ๊ณ , ํ์ ์น๋ฃ๋ฅผ ๊ฐ์ ํฉ๋๋ค.
- ๊ธ๋ก๋ฒ ๋ฌผ๋ฅ: Maersk๋ DHL๊ณผ ๊ฐ์ ํ์ฌ๋ ์ด๋ฒคํธ ์์ฑ์ ์ฌ์ฉํ์ฌ ์ ์ธ๊ณ์ ํ๋ฌผ์ ์ถ์ ํ๊ณ , "ShipmentDepartedPort", "ShipmentArrivedPort", "CustomsClearanceStarted", "ShipmentDelivered"์ ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ์บก์ฒํ ์ ์์ต๋๋ค. ์ด๋ ๊ฐ ํ๋ฌผ์ ๋ํ ์์ ํ ๊ฐ์ฌ ์ถ์ ์ ์์ฑํฉ๋๋ค.
- ๊ตญ์ ์ํ: HSBC๋ Standard Chartered์ ๊ฐ์ ์ํ์ ์ด๋ฒคํธ ์์ฑ์ ์ฌ์ฉํ์ฌ ๊ตญ์ ์ก๊ธ์ ์ถ์ ํ๊ณ , "TransferInitiated", "CurrencyExchangeExecuted", "FundsSentToBeneficiaryBank", "FundsReceivedByBeneficiary"์ ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ์บก์ฒํ ์ ์์ต๋๋ค. ์ด๋ ๊ท์ ์ค์๋ฅผ ๋ณด์ฅํ๊ณ ์ฌ๊ธฐ ํ์ง๋ฅผ ์ฉ์ดํ๊ฒ ํฉ๋๋ค.
๊ฒฐ๋ก
์ด๋ฒคํธ ์์ฑ์ ๊ฐ์ฌ ์ถ์ ๊ตฌํ์ ํ์ ํ ์ ์๋ ๊ฐ๋ ฅํ ์ํคํ ์ฒ ํจํด์ ๋๋ค. ์ด๋ ๋ ๋ณด์ ์ธ ์ถ์ ๊ฐ๋ฅ์ฑ, ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ๋ฐ ์์คํ ๋ณต์๋ ฅ์ ์ ๊ณตํฉ๋๋ค. ๋ช ๊ฐ์ง ๊ณผ์ ๊ฐ ์์ง๋ง, ํนํ ๋ณต์กํ๊ณ ์ค์ํ ์์คํ ์ ๊ฒฝ์ฐ ์ด๋ฒคํธ ์์ฑ์ ์ด์ ์ ์ข ์ข ๋น์ฉ์ ๋ฅ๊ฐํฉ๋๋ค. ์ด ๊ฐ์ด๋์ ์ค๋ช ๋ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๋ฉด ์ด๋ฒคํธ ์์ฑ์ ์ฑ๊ณต์ ์ผ๋ก ๊ตฌํํ๊ณ ๊ฒฌ๊ณ ํ๋ฉฐ ๊ฐ์ฌ ๊ฐ๋ฅํ ์์คํ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.