FastAPI ์๋ฒ 503 ์๋ฌ ํธ๋ฌ๋ธ์ํ : DB ์ปค๋ฅ์ ํ ๊ณ ๊ฐ(QueuePool Overflow) ํด๊ฒฐ ๋ฐ Cloudflare ์๋ ์ ํ(Rate Limiting) ๋ฐฉ์ด๊ธฐ
์๋น์ค๊ฐ ์ด๋ ์ ๋ ๊ถค๋์ ์ค๋ฅด๊ณ ์์ง์ IT ์นผ๋ผ๊ณผ ํธ๋ ๋ ๊ธ๋ค์ด ์๋ง ๊ฐ์ฉ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์ด์, ํํ๋กญ๋ ์ฐ๋ถํฌ ์๋ฒ ํฐ๋ฏธ๋ ์ฐฝ์ ๋ถ์์ ์๋ฌ ๋ก๊ทธ๊ฐ ๋น ๋ด๋ฆฌ๋ฏ ์์์ง๊ธฐ ์์ํ์ต๋๋ค. ๋ธ๋ผ์ฐ์ ์ฐฝ์๋ ์ ์ ๋ถ๊ฐ ์ํ๋ฅผ ์๋ฆฌ๋ 503 Service Unavailable ์๋ฌ๊ฐ ๋ด๊ณ , ๋ฐฑ์๋ ๋ก๊ทธ์๋ ๋ค์๊ณผ ๊ฐ์ ๋์ฐํ ๋ฌธ๊ตฌ๋ค์ด ์ฐํ ์์์ต๋๋ค.
QueuePool limit of size 10 overflow 10 reached, connection timed out
ECHECKOUTTIMEOUT
์ด ์๋ฌ๋ค์ FastAPI ์น ์๋ฒ์ PostgreSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค(Supabase ๋ฑ) ์ฌ์ด๋ฅผ ์ฐ๊ฒฐํ๋ 'ํต๋ก(Connection Pool)'๊ฐ ๊ฝ ์ฐจ์ ๋ ์ด์ ์๋ก์ด ์ ์์๋ฅผ ๋ฐ์ ์ ์์ ๋ ํฐ์ ธ ๋์ค๋ ๋ณ๋ชฉ ํ์์ ์ ํ์ ์ธ ์ฆ์์ ๋๋ค. ์ ๋ ์ฆ์ ์์ธ์ค ๋ก๊ทธ๋ฅผ ๋ฏ์ด๋ณด์๊ณ , ๊ทธ๊ณณ์์ ์๋ฒ๋ฅผ ๊ณต๊ฒฉํ๊ณ ์๋ ๋ฒ์ธ๋ค์ ๋ช ํํ ํจํด์ ๋ฐ๊ฒฌํ์ต๋๋ค.
1. ๋ฒ์ธ์ ๋ฌดํ๋์ ๋ฌด๊ธฐ๋ฅผ ์ฅ 'IPv6 ๋ด๋ท(Botnet)'
์ง์ง ์ฌ๋(๋ธ๋ผ์ฐ์ )์ด ์น์ฌ์ดํธ์ ์ ์ํ๋ฉด HTML ๋ฌธ์๋ฅผ ์ฝ์ ๋ค, ํ๋ฉด์ ๊ทธ๋ฆฌ๊ธฐ ์ํด ๋ณธ๋ฌธ์ ํฌํจ๋ ์์ญ ๊ฐ์ ์ธ๋ค์ผ ์ด๋ฏธ์ง ํ์ผ๋ค(/static/uploads/*.webp)์ ์ฐ๋ฌ์ ์์ฒญํฉ๋๋ค.
ํ์ง๋ง ๋ก๊ทธ์ ์ฐํ ์
์ฑ ๋ด๋ค์ ์ด๋ฏธ์ง ํ์ผ์ ๋จ ํ๋๋ ์์ฒญํ์ง ์์ ์ฑ, ์ค์ง ํ
์คํธ ๋ฐ์ดํฐ๋ง ๋นผ๊ฐ๊ธฐ ์ํด page=170, page=448 ๊ฐ์ ์ผ๋ฐ ์ ์ ๋ผ๋ฉด ์ ๋ ๋๋ฅด์ง ์์ ์๋ํ ๊น์ ํ์ด์ง(Deep Pagination)์ ์ฃผ์๋ง 1์ด ๊ฐ๊ฒฉ์ผ๋ก ๋ฌด์๋นํ๊ฒ ๊ธ์ด๊ฐ๊ณ ์์์ต๋๋ค.
๊ฐ์ฅ ํฐ ๋ฌธ์ ๋ ์ด๋ค์ด ๊ธฐ์กด IPv4๊ฐ ์๋ ๋ฌดํ๋์ ๊ฐ๊น์ด IP๋ฅผ ์์ฑํ ์ ์๋ IPv6 ์ฃผ์(2a10:..., 2a11:..., 2a13:..., 2a01:...) ๋์ญ์ ์ฌ์ฉํ๊ณ ์์๋ค๋ ์ ์
๋๋ค. ๊ฐ๋ณ IP๋ฅผ ํ๋์ฉ ์ฐจ๋จํ๋ '๋๋์ง ๊ฒ์'์ผ๋ก๋ ์ด ๋ฐฉ๋ํ ๋ด๋ท ๋ถ๋๋ฅผ ์ ๋ ๋ง์ ์ ์์์ต๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์๋ฐฑ ํ์ด์ง ๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๊ธฐ ์ํด ๋ฌด๊ฑฐ์ด ์ฐ์ฐ(Offset/Limit)์ ๋ฐ๋ณตํ๋ค ๊ฒฐ๊ตญ ์ปค๋ฅ์
ํ์ ๋ชจ๋ ์์งํ๊ณ ๊ธฐ์ ํด๋ฒ๋ฆฐ ๊ฒ์
๋๋ค.
2. ๋ฐฉ์ด๋ง 1: Cloudflare ์๋ ์ ํ(Rate Limiting)๊ณผ DB ํ๋
์๋ฒ ์ฝ๋๋ฅผ ๊ณ ์น๊ธฐ ์ ์ ์๋จ(๋คํธ์ํฌ)์์ ํธ๋ํฝ์ ํ์๋ฅผ ๋ง์์ผ ํ์ต๋๋ค. ์ ๋ ์ฆ์ Cloudflare ๋์๋ณด๋๋ฅผ ์ด์ด ๊ฐ๋ ฅํ ์๋ ์ ํ(Rate Limiting) ๊ท์น์ ์ ์ฉํ์ต๋๋ค.
์ ์ฉ ๊ฒฝ๋ก: ์๋ ์ ๋ก๋ API ๋ฑ์ ์์ธ ๊ฒฝ๋ก๋ฅผ ์ ์ธํ ์ฌ์ดํธ ์ ์ฒด(
/)์ ํ ๊ธฐ์ค: 10์ด๋น 400ํ ์์ฒญ ์ด๊ณผ ์, 10์ด๊ฐ ๊ฐ์ ์ฐจ๋จ(Block)
์ถ๊ฐ ๋ณด์: ๋ก๊ทธ์ธ ์๋ํฌ์ธํธ ๋ฑ์ ๊ฒจ๋ฅํ ๋ด ๊ณต๊ฒฉ์ ๋ฐฉ์ดํ๊ธฐ ์ํด ์ ์ถ๋ ๋น๋ฐ๋ฒํธ ๊ฒ์ฆ(Leaked credential check) ๊ธฐ๋ฅ ํ์ฑํ
'10์ด์ 400ํ'๋ผ๋ ๊ธฐ์ค์ ์ฌ๋ ๊ธฐ์ค์ผ๋ก๋ ์ ๋ ๋์ ์ ์๋ ์์น ๊ฐ์ง๋ง, ์ค์ ์น ํ์ด์ง ํ๋๊ฐ ๋ก๋ฉ๋ ๋ ์์ญ ๊ฐ์ ์ด๋ฏธ์ง์ ์ ์ ํ์ผ์ด ๋์์ ํธ์ถ๋๋ค๋ ์ ์ ๊ณ ๋ คํ์ฌ ์ผ๋ฐ ์ ์ ๋ค์ด ์ต์ธํ๊ฒ ์ฐจ๋จ๋นํ์ง ์๋๋ก ๋งค์ฐ ๋๋ํ์ง๋ง ํ์คํ ์๊ณ์น(Threshold)๋ก ์ค์ ํ ๊ฒ์ ๋๋ค. ์ด์ ๋๋ถ์ด DB ์ฟผ๋ฆฌ ํ์์์์ ์งง๊ฒ ์ค์ด๋ 'Fail-Fast' ํ๋์ ๊ณ๋ค์ฌ, ๋ด์ด ๋ฌด๊ฑฐ์ด ์์ฒญ์ ๋์ ธ๋ DB๊ฐ ์ค๋ซ๋์ ๋ถ์ก๊ณ ์์ง ์๊ณ ์ฆ์ ์ฐ๊ฒฐ์ ๋๋๋ก ์กฐ์นํ์ต๋๋ค.
3. ๋ฐฉ์ด๋ง 2: 'ํ์ด์ง ๋ด(Paging Bots)' ๋ง์ถคํ ์ค๋งํธ ๋ฃฐ
์๋ ์ ํ์ผ๋ก ๊ธํ ๋ถ์ ๊ป๋ค๋ฉด, ์ด๋ฒ์๋ ์๋ฒ ์์์ ๊ฐ์ฅ ๋ง์ด ๊ฐ์๋จน๋ '๋ฌด๋จ ๋ฅ ํ์ด์ง ์คํฌ๋ํ'์ ์์ฒ ๋ด์ํ ์ฐจ๋ก์ ๋๋ค.
๋ด๋ท๋ค์ ๋์ง๊ธฐ๊ฒ URL ์ฟผ๋ฆฌ์ ํ๋ผ๋ฏธํฐ(page=, lang=)๋ฅผ ์กฐ์ํ๋ฉฐ ๋ค์ด์์ต๋๋ค. ์ ๋ Cloudflare WAF ์ฌ์ฉ์ ์ง์ ๊ท์น์ ๋ค์๊ณผ ๊ฐ์ ์์ฃผ ์ค๋งํธํ ๋
ผ๋ฆฌ ๊ตฌ์กฐ(AND)๋ฅผ ์์ฑํ์ฌ ๋ฐฐํฌํ์ต๋๋ค.
์กฐ๊ฑด A: HTTP ์์ฒญ์
User-Agent๋ฌธ์์ด์bot,facebook,spider,crawl๋ฑ์ ๋จ์ด๊ฐ ํฌํจ๋์ด ์์ ๊ฒ.์กฐ๊ฑด B: URL์ Query String์
page=๋๋lang=ํ๋ผ๋ฏธํฐ๊ฐ ํฌํจ๋์ด ์์ ๊ฒ.์กฐ์น (Action): ์ ๋ ์กฐ๊ฑด์ ๋์์ ๋ง์กฑํ๋ฉด ์๋ฒ ์์ ๋ณดํธ๋ฅผ ์ํด ์ฆ์ ์ฐจ๋จ(Block)ํ ๊ฒ.
์ด ์ค๋งํธ ๋ฃฐ์ ๊ฒ์ ์์ง ์ต์ ํ(SEO)๋ฅผ ์ํด ๋ฉ์ธ ํ๋ฉด์ ์ฝ์ด๊ฐ๋ ์ฐฉํ ํฌ๋กค๋ฌ๋ค์ ๊ธฐ๋ณธ ํ๋์ ํ์ฉํ๋ฉด์๋, DB๋ฅผ ์ฃฝ์ด๋ ์ฃผ๋ฒ์ธ '๊ฒ์ํ ํ๋จ ํ์ด์ง ๋ฒํผ ๊ดํด ๋ด'๋ค๋ง ์ ํํ๊ฒ ์๋ณํ์ฌ ๋ชฉ์ ๋ฒ ์ด๋ฒ๋ฆฌ๋ ์ต๊ณ ์ ๊ฐ์ฑ๋น ๋ฐฉ์ด์ฑ ์ด ๋์์ต๋๋ค.
์๋ฒ ๋ฐฉ์ด ์ธํ๋ผ ์ธํ
์ ๋ง์น๊ณ ํฐ๋ฏธ๋ ์ฐฝ์ ๋ชจ๋ํฐ๋งํ์ ๊ธฐ์ ๊ฐ์ ํํ๊ฐ ์ฐพ์์์ต๋๋ค. ์ง๊ธ์ง๊ธํ๋ QueuePool ์๋ฌ์ 503 ์๋ฌ๋ ๋จ ํ ์ค๋ ๋ณด์ด์ง ์์๊ณ , ๋์ ์ง์ง ์ฌ๋ ์ ์ ๋ค์ด ์ด๋ฏธ์ง๋ฅผ ์ ์์ ์ผ๋ก ์์ฒญํ๋ ์พ์ ํ 200 OK์ 304 Not Modified ๋ก๊ทธ๋ง์ด ๋ฌผ ํ๋ฅด๋ฏ ์๋ฆ๋ต๊ฒ ์ฌ๋ผ์ค๊ณ ์์์ต๋๋ค.
์น ์๋ฒ ์ด์์ ๊ฒฐ๊ตญ '๋ณด์ด์ง ์๋ ์ ์ฑ ํธ๋ํฝ๊ณผ์ ๋์๋ ์ํ ์ ์'์ ๋๋ค. ๋ฐฑ์๋ ์ฝ๋์ ์ต์ ํ๋ ์ค์ํ์ง๋ง, 1์ธ ๊ฐ๋ฐ์์ผ์๋ก Cloudflare WAF์ ๊ฐ์ ๊ฐ๋ ฅํ ์ฃ์ง(Edge) ๋คํธ์ํฌ ๋ฐฉ์ด๋ง์ ์ ๊ทน์ ์ผ๋ก ํ์ฉํ์ฌ ์๋ฒ ์์์ ๋ณดํธํ๋ ๊ฒ์ด ์ฑ๊ณต์ ์ธ ์ปค๋ฎค๋ํฐ ์ฑ์ฅ์ ์ฒซ๊ฑธ์์์ ๋ค์ ํ๋ฒ ์๊ธธ ์ ์์์ต๋๋ค.
โ ์์ฃผ ๋ฌป๋ ์ง๋ฌธ (FAQ)
Q1. User-Agent์ bot์ ์ฐจ๋จํ๋ฉด ๊ตฌ๊ธ ์ ๋์ผ์ค ์ฌ์ฌ ๋ด์ด๋ SEO ํฌ๋กค๋ฌ๋ ๋งํ๋ ๊ฒ ์๋๊ฐ์?
A. ์ผ๋ฐ์ ์ธ ํ
์คํธ ์ฐจ๋จ๋ง ์ฐ๋ฉด ๋งํ ์ํ์ด ์์ต๋๋ค. ํ์ง๋ง Cloudflare์ WAF ๊ท์น์ ์์ฑํ ๋, ์กฐ๊ฑด๋ฌธ์ Known Bots (์๋ ค์ง ๋ด) = Off (๊บผ์ง)์ ์ถ๊ฐํด์ฃผ๋ฉด, ๊ตฌ๊ธ(Googlebot, Mediapartners-Google)์ด๋ ๋น(Bingbot) ๊ฐ์ด ๊ณต์์ ์ผ๋ก ์ธ์ฆ๋ ์ฐฉํ ๋ด๋ค์ ์ด ์ฐจ๋จ ๊ท์น์ ํ๋ฆฌํจ์ค๋ก ์ฐํํ๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ ๋์ผ์ค ์ฌ์ฌ๋ ๊ตฌ๊ธ ๊ฒ์ ๋
ธ์ถ์๋ 1%์ ์
์ํฅ๋ ๋ฏธ์น์ง ์์ต๋๋ค.
Q2. ์ '10์ด๋น 400ํ'๋ผ๋ ๋์ ์ซ์๋ก ์๋ ์ ํ์ ๊ฑธ์๋์? ์ข ๋ ๋นก๋นกํ๊ฒ 50ํ ์ ๋๋ก ์ค์ด๋ฉด ์ ๋๋์?
A. ํ๋์ ๋ฐ์ํ ์น์ฌ์ดํธ๋ HTML ๋ฌธ์ ํ ์ฅ๋ง ๋ถ๋ฌ์ค๋ ๊ฒ์ด ์๋๋๋ค. ๋ณธ๋ฌธ์ ์ฝ์
๋ ์์ญ ์ฅ์ ๊ณ ํ์ง ์ด๋ฏธ์ง(.webp), CSS, ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ๋ค์ด ๋น๋๊ธฐ์ ์ผ๋ก ๋์์ ๋ก๋ฉ๋ฉ๋๋ค. ๋ง์ฝ ์๋ ์ ํ์ 10์ด์ 50ํ ์ ๋๋ก ๋นก๋นกํ๊ฒ ์ก์ผ๋ฉด, ์ค๋งํธํฐ์ผ๋ก ๊ฒ์๊ธ์ ๋น ๋ฅด๊ฒ ์คํฌ๋กคํ๋ฉฐ ์ด๋ฏธ์ง๋ฅผ ํ์ด๋ณด๋ ํ๋ฒํ '์ง์ง ์ ์ '๋ค๊น์ง ์
์ฑ ๋ด์ผ๋ก ์คํด๋ฐ์ 10์ด๊ฐ ์ฌ์ดํธ ์ ์์ด ์ฐจ๋จ(Block)๋๋ ์ต์
์ ์ฌ์ฉ์ ๊ฒฝํ(UX) ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
Q3. ์ ์ ํ์ผ(์ด๋ฏธ์ง)์ ์๋นํ ๋ ๋ด๋ค์ด ๋ชฐ๋ ค์ค๋ฉด DB๊ฐ ์ฃฝ์ง ์๋์?
A. ์ด๋ฏธ์ง ํ์ผ(.webp, .jpg) ๋ฑ์ ๊ฐ์ ธ๊ฐ๋ ์์ฒญ(/static/uploads/...)์ ๋ฐ์ดํฐ๋ฒ ์ด์ค(PostgreSQL)๋ฅผ ์ ํ ๊ฑฐ์น์ง ์์ต๋๋ค. ํ์ด์ฌ ์์ปค๊ฐ ํ๋๋์คํฌ์ ์๋ ํ์ผ์ ์ง์ ๊ฑด๋ค์ฃผ๊ฑฐ๋ Cloudflare์ ์ฃ์ง(Edge) ์บ์ ์๋ฒ๊ฐ ๋์ ๋ฐํํ๋ฏ๋ก, ์ด๋ฏธ์ง ์์ฒญ์ด 1์ด์ ์๋ฐฑ ๋ฒ ์์์ง๋๋ผ๋ DB ์ปค๋ฅ์
ํ์ ์๋ชจํ์ง ์์ ์๋ฒ๊ฐ ์์ ํ๊ฒ ์ ์ง๋ฉ๋๋ค. ๋ฌธ์ ๊ฐ ๋๋ ๊ฒ์ ์ค์ง ๋ฌด๊ฑฐ์ด SQL ์ฐ์ฐ์ ์ ๋ฐํ๋ ๋์ ํ์ด์ง ํธ์ถ(/post/...?page=)์
๋๋ค.
๐ฌ ๋๊ธ 0๊ฐ