First Come First Served
First Come First Served Event
์ค์ต์ผ๋ก ๋ฐฐ์ฐ๋ ์ ์ฐฉ์ ์ด๋ฒคํธ ์์คํ ๊ฐ์๋ฅผ ๋ฃ๊ณ ์์ฝํ ๋ด์ฉ์ ๋๋ค.
Intro
์๊ตฌ์ฌํญ.
์ ์ฐฉ์ 100๋ช ์๊ฒ ํ ์ธ์ฟ ํฐ์ ์ ๊ณตํ๋ ์ด๋ฒคํธ
์ ์ฐฉ์ 100๋ช ์๊ฒ๋ง ์ง๊ธ๋์ด์ผํ๋ค.
101๊ฐ ์ด์์ด ์ง๊ธ๋๋ฉด ์๋๋ค.
์๊ฐ์ ์ผ๋ก ๋ชฐ๋ฆฌ๋ ํธ๋ํฝ์ ๋ฒํธ ์ ์์ด์ผํ๋ค.
์ ์ฐฉ์ ์ด๋ฒคํธ ์งํ ์ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์ .
์ฟ ํฐ์ด ๊ฐ์๋ณด๋ค ๋ ๋ง์ด ๋ฐ๊ธ๋์์ ๊ฒฝ์ฐ
์ด๋ฒคํธ ํ์ด์ง ์ ์์ด ์ ๋ ๊ฒฝ์ฐ
์ด๋ฒคํธ๋ ์๊ด์๋ ํ์ด์ง๋ ๋๋ ค์ง ๊ฒฝ์ฐ
๋ฌธ์ ํด๊ฒฐ.
ํธ๋ํฝ์ด ๋ชฐ๋ ธ์ ๋ ๋์ฒํ ๋ฐฉ๋ฒ
Redis ๋ฅผ ํ์ฉํ์ฌ ์ฟ ํฐ ๋ฐ๊ธ ๊ฐ์ ๋ณด์ฅํ๋ ๋ฐฉ๋ฒ
Kafka ๋ฅผ ํ์ฉํ์ฌ ๋ค๋ฅธ ํ์ด์ง๋ค์ ๋ํ ์ํฅ๋๋ฅผ ์ค์ด๋ ๋ฐฉ๋ฒ
Race Condition
์๋ ํ
์คํธ์์ 100์ ๊ฒฐ๊ณผ๋ฅผ ์์ํ์ง๋ง, ๋์์ ๋ค์ด์ค๋ ์์ฒญ๋ค์ด ๊ฐฑ์ ์ ๊ฐ์ ์ฝ๊ณ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ฉด์ ์์ํ๋ ๊ฐ์๋ฅผ ์ด๊ณผํ๋ ํ์์ด ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
Concurrency issues ์์ ๋ฐฐ์ด ๊ฒ๊ณผ ๊ฐ์ด Java Synchronized ๋ฅผ ์ ์ฉํด๋ณผ ์ ์์ง๋ง,
์๋ฒ๊ฐ ์ฌ๋ฌ ๋๊ฐ ๋๋ค๋ฉด Race Condition ์ด ๋ค์ ๋ฐ์ํ๊ฒ ๋๋ฏ๋ก ์ ์ ํ์ง ์์ต๋๋ค.
.
๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก MySQL, Redis ๋ฅผ ํ์ฉํ ๋ฝ์ ๊ตฌํํด์ ํด๊ฒฐํ ์๋ ์์ ๊ฒ ๊ฐ์ง๋ง,
์ฟ ํฐ ๊ฐ์์ ๋ํ ์ ํฉ์ฑ์ ์ํ๋๋ฐ ๋ฝ์ ํ์ฉํ์ฌ ๊ตฌํํ๋ฉด, ๋ฐ๊ธ๋ ์ฟ ํฐ์ ๊ฐ์๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ๋ถํฐ ์ฟ ํฐ์ ์์ฑํ ๋๊น์ง ๋ฝ์ ๊ฑธ์ด์ผ ํฉ๋๋ค.
์ด๋ ๊ฒ ๋๋ฉด ๋ฝ์ ๊ฑฐ๋ ๊ตฌ๊ฐ์ด ๊ธธ์ด์ง๋ค๋ณด๋ ์ฑ๋ฅ์ ๋ถ์ด์ต(๋ฝ์ด ํ๋ฆด ๋๊น์ง ์ฟ ํฐ ๋ฐ๊ธ์ ๊ธฐ๋ค๋ ค์ผ ํ๋)์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
Redis
Redis incr ๋ช
๋ น์ด๋ ํค์ ๋ํ ๊ฐ์ 1์ฉ ์ฆ๊ฐ์ํค๋ ๋ช
๋ น์ด์
๋๋ค.
Redis ๋ ์ฑ๊ธ์ค๋ ๋ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ์ฌ ๋ ์ด์ค ์ปจ๋์
์ ํด๊ฒฐํ ์ ์์ ๋ฟ ์๋๋ผ incr ๋ช
๋ น์ด๋ ์ฑ๋ฅ๋ ๊ต์ฅํ ๋น ๋ฅธ ๋ช
๋ น์ด์
๋๋ค.
incr ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ๊ธ๋ ์ฟ ํฐ ๊ฐ์๋ฅผ ์ ์ดํ๋ค๋ฉด ์ฑ๋ฅ๋ ๋น ๋ฅด๋ฉฐ ๋ฐ์ดํฐ ์ ํฉ์ฑ๋ ์งํฌ ์ ์์ต๋๋ค.
Problems
1) ์ฟ ํฐ์ ๊ฐ์
๋ฐ๊ธํ๋ ์ฟ ํฐ์ ๊ฐ์๊ฐ ๋ง์์ง์๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ถํ๋ฅผ ์ฃผ๊ฒ ๋ฉ๋๋ค.
ํด๋น ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๋ค๋ฅธ ๊ณณ์์๋ ์ฌ์ฉ๋๊ณ ์๋ค๋ฉด ์๋น์ค ์ฅ์ ๊น์ง ๋ฐ์ํ ์ ์์ต๋๋ค.
2) ์งง์ ์๊ฐ์ ๋ง์ ์์ฒญ
์งง์ ์๊ฐ ๋ด์ ๋ง์ ์์ฒญ์ด ๋ค์ด์ค๊ฒ ๋ ๊ฒฝ์ฐ DB ์๋ฒ์ ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์ฌ์ฉํ๊ฒ ๋๋ฏ๋ก ๋ถํ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
์๋น์ค ์ง์ฐ ํน์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
Kafka
๋ถ์ฐ ์ด๋ฒคํธ ์คํธ๋ฆฌ๋ฐ ํ๋ซํผ
์ด๋ฒคํธ ์คํธ๋ฆฌ๋ฐ: ์์ค์์ ๋ชฉ์ ์ง๊น์ง ์ด๋ฒคํธ๋ฅผ ์ค์๊ฐ์ผ๋ก ์คํธ๋ฆฌ๋ฐ ํ๋ ๊ฒ
Start Kafka
docker-compose.yml
example
Producer
api/KafkaProducerConfig.java
api/CouponCreateProducer.java
KafkaProducerConfig CouponCreateProducer
Consumer
consumer/KafkaConsumerConfig.java
consumer/CouponCreatedConsumer.java
Limit the number of coupons
๋ฐ๊ธ ๊ฐ๋ฅํ ์ฟ ํฐ ๊ฐ์ 1์ธ๋น 1๊ฐ๋ก ์ ํํ๊ธฐ.
(1) ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๋ํฌํค ์ฌ์ฉํ๊ธฐ
userId, couponType ์ ์ ๋ํฌ ํค๋ฅผ ์ ์ฉํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ.
๋ณดํต ์๋น์ค๋ ํ ์ ์ ๊ฐ ๊ฐ์ ํ์ ์ ์ฟ ํฐ์ ์ฌ๋ฌ๊ฐ ๊ฐ์ง ์ ์์ผ๋ฏ๋ก ์ค์ฉ์ ์ธ ๋ฐฉ๋ฒ์ ์๋.
(2) ๋ฒ์๋ก ๋ฝ์ ์ก๊ณ ์ฒ์์ ์ฟ ํฐ ๋ฐ๊ธ ์ฌ๋ถ๋ฅผ ๊ฐ์ ธ์์ ํ๋จํ๋ ๋ฐฉ์
์ฟ ํฐ ๋ฐ๊ธ ๊ฐ๋ฅ ์ฌ๋ถ๋ง ํ๋จํ๊ณ ์ค์ ์ฟ ํฐ ์์ฑ์ ์ปจ์๋จธ์์ ์ํํ๊ณ ์์ผ๋ฏ๋ก ์๊ฐ์ฐจ๋ก 2๊ฐ ์ด์์ ์ฟ ํฐ์ด ๋ฐ๊ธ๋ ์ ์์.
์ง์ ์ฟ ํฐ์ ๋ฐ๊ธํ๋๋ผ๋ ๋ฝ์ ๋ฒ์๊ฐ ๋์ด์ ๋ค๋ฅธ ์์ฒญ๋ค์ ๋ฝ์ด ๋๋ ๋๊น์ง ๋๊ธฐ์ํ๊ฐ ๋๋ฏ๋ก ์ฑ๋ฅ์ด ์ ์ข์์ง ์ ์์.
(3) Rest ์์ Set ํ์ฉํ๊ธฐ
AppliedUserRepository.java
Error issuing coupon
(1) ์คํจ ์ด๋ฒคํธ ๊ด๋ฆฌ ํ ์ด๋ธ ํ์ฉํ๊ธฐ
์ปจ์๋จธ์์ ์ฟ ํฐ ๋ฐ๊ธ ์ค ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ FailedEvent ํ ์ด๋ธ์ ์คํจํ ์ด๋ฒคํธ๋ฅผ ์ ์ฅํฉ๋๋ค.
์ดํ ๋ฐฐ์น๋ฅผ ํตํด FailedEvent ํ ์ด๋ธ์ ์์ธ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ์ฝ์ด์ ์ฟ ํฐ์ ๋ฐ๊ธํด ์ค๋ค๋ฉด ๊ฒฐ๊ณผ์ ์ผ๋ก ํน์ ์๋์ ์ฟ ํฐ์ด ๋ชจ๋ ๋ฐ๊ธ๋ ์ ์์ต๋๋ค.
(3) Saga Pattern ์ ์ฉํ๊ธฐ
๋ง์ดํฌ๋ก์๋น์ค๋ค๋ผ๋ฆฌ ์ด๋ฒคํธ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ํน์ ๋ง์ดํฌ๋ก์๋น์ค์์์ ์์ ์ด ์คํจํ๋ฉด ์ด์ ๊น์ง์ ์์ ์ด ์๋ฃ๋ ๋ง์ดํฌ์๋น์ค๋ค์๊ฒ ๋ณด์(complemetary) ์ด๋ฒคํธ๋ฅผ ์์ฑํจ์ผ๋ก์จ ๋ถ์ฐ ํ๊ฒฝ์์ ์์์ฑ(atomicity)์ ๋ณด์ฅํ๋ ํจํด
Last updated