/images/profile.png

Jenkins ์—…๊ทธ๋ ˆ์ด๋“œ ๋ฐ Master-Slave ๊ตฌ์„ฑ

์–ด๋– ํ•œ ์ž‘์—…(Job)์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์ด๋ฅผ “์ •ํ•ด์ง„ ์‹œ๊ฐ„์— ์ฃผ๊ธฐ์ ” ์ด๋‚˜ “ํ•„์š”ํ• ๋•Œ” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ค ํˆด(Tool)์ด ๋– ์˜ค๋ฅด๋Š”๊ฐ€? ๊ทธ๋ฆฌ๊ณ  ์ด ์ž‘์—…(Job)๋“ค์˜ ์‹คํ–‰์ด๋ ฅ ๋“ฑ ์ „์ฒด์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ํ•„์š”์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ™œ์šฉํ•˜์—ฌ ์ž…๋ง›์— ๋งž๋Š” ์ž‘์—…(Job)์œผ๋กœ ๊ตฌ์„ฑํ•˜๊ณ  ์‹ถ์„๋•Œ ๊ฐ€์žฅ ์ฒซ๋ฒˆ์งธ๋กœ ๋– ์˜ค๋ฅด๋Š” ํˆด์€ ๋ฐ”๋กœ “Jenkins” ๋‹ค. (๊ทนํžˆ ํ•„์ž ๊ฐœ์ธ์ ์ธ ์ƒ๊ฐ์ผ์ˆ˜๋„ ์žˆ์ง€๋งŒ… ) ๋ฌผ๋ก  ๋ฆฌ๋ˆ…์Šค ๊ธฐ๋ฐ˜์˜ crontab ์ด๋‚˜ ๋‹ค๋ฅธ ์Šค์ผ€์ฅด๋Ÿฌ๋ฅผ ํ™œ์šฉํ• ์ˆ˜๋„ ์žˆ๋‹ค. ๋‹ค๋งŒ ํ•„์ž ๊ฐœ์ธ์ ์ธ ๋А๋‚Œ์œผ๋กœ ๋‚˜๋งŒ์˜ Jarvis(?)์ฒ˜๋Ÿผ ๋‚ด๊ฐ€ ์›ํ•˜๋Š”๋ฐ๋กœ ์„ค์ •๋งŒ ํ•ด๋‘๋ฉด ์ •ํ•ด์ง„ ์‹œ๊ฐ„์— ์ˆ˜ํ–‰ํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋กœ๊ทธ๋กœ ๋‚จ๊ฒจ๋†“๊ณ  ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„๋•Œ ์•Œ๋ฆผ๋„ ๋ฐ›์„์ˆ˜ ์žˆ์œผ๋‹ˆ ๋„ˆ๋ฌด ์ข‹์€ ํˆด์ด๋ผ ์ƒ๊ฐ์ด ๋“ ๋‹ค.

/images/jenkins-upgrade-master-slave/ColossalSociableBuffalo-size_restricted.gif
์‹ค์ œ๋กœ Jarvis๊ฐ€ ์žˆ๋‹ค๋ฉด ์–ผ๋งˆ๋‚˜ ํŽธํ• ๊นŒ
์ถœ์ฒ˜ : https://gfycat.com/ko/colossalsociablebuffalo

์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ๋Š” Jenkins ๋ฅผ ์„ค์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜๋‹ค. (์ •ํ™•ํžˆ ๋งํ•˜๋ฉด ์น˜ํŠธํ‚ค ์ˆ˜์ค€์˜… ) ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Jenkins์— ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ master-slave ๋ถ„์‚ฐํ™˜๊ฒฝ์œผ๋กœ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ Jenkins ๋ฒ„์ „์„ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

๋งˆ์นจ ํ•„์ž์˜ ํŒ€์—์„œ ์  ํ‚จ์Šค๋ฅผ ๋ถ„์‚ฐํ™˜๊ฒฝ์œผ๋กœ ์šด์˜ํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ๋ฒ„์ „์€ 1.x … ๊ฐ„ํ—์ ์œผ๋กœ Jenkins ๋ฒ„์ „ ์ด์Šˆ๋กœ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด์„œ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์ƒ๊ธด๊ฒƒ์ด๋‹ค. ์‹œํ‚ค์ง€๋„ ์•Š์€ ์ผ์„ ํ•˜๋ฉด์„œ ํŒ€์— ๋„์›€๋„ ๋ ๊ฒธ, ํฌ์ŠคํŒ…๋„ ํ• ๊ฒธ, 1์„ 2์กฐ ํšจ๊ณผ. ์„œ๋ฒ„ ํ™˜๊ฒฝ์€ CentOS 7.4 64Bit ์—์„œ ํ…Œ์ŠคํŠธ ํ•˜์˜€๋‹ค.

Jenkins ๋ฒ„์ „ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•˜๊ธฐ

Jenkins๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•˜๊ฒŒ๋˜๋ฉด ๊ธฐ์กด์— ์žˆ์—ˆ๋˜ Jenkins์˜ ํ™˜๊ฒฝ์„ค์ •์€ ์–ด๋–ป๊ฒŒ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํ• ๊นŒ? Job ์‹คํ–‰๊ธฐ๋ก๋“ค์€ ๊ทธ๋ƒฅ ๋‚ ๋ ค๋ฒ„๋ ค์•ผ ํ•˜๋‚˜? ๊ฑฑ์ •์„ ํ•˜๋ฉฐ ๊ตฌ๊ธ€๋ง์„ ํ•ด๋ณธ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด “์•ˆํ•ด๋ณธ๊ฒƒ์— ๋Œ€ํ•œ ๋‘๋ ค์›€” ์„ ๊ฐ–๋Š” ํ•„์ž์˜ ๋งˆ์Œ์ด ๋ฌด์ƒ‰ํ•  ์ •๋„๋กœ ๋„ˆ๋ฌด ๊ฐ„๋‹จํ•˜๊ฒŒ๋„ ๊ทธ๋ƒฅ ๊ธฐ์กด์— ์žˆ๋˜ war ํŒŒ์ผ์„ ์ตœ์‹ ๋ฒ„์ „์œผ๋กœ ๊ต์ฒดํ•˜๊ณ  ์žฌ์‹œ์ž‘ ํ•˜๋ผ๊ณ  ๋‚˜์˜จ๋‹ค. ์ญ? ๋ญ์ด๋ฆฌ ๊ฐ„๋‹จํ•ด? ๋Œ€๋ถ€๋ถ„์˜ ๋ฌธ์ œ๋“ค์€ ์ง€๋ ˆ ๊ฒ๋ถ€ํ„ฐ ๋จน๊ณ  ์‹คํ–‰์— ์˜ฎ๊ธฐ์ง€ ๋ชปํ•ด์„œ ์•Š์•„์„œ ํ•ด๊ฒฐ์„ ํ•˜์ง€ ๋ชปํ•˜๋Š”๊ฒŒ ์ ˆ๋ฐ˜ ์ด์ƒ๊ฐ™๋‹ค. ์ž, ๋ฐ”๋กœ ์‹คํ–‰์— ์˜ฎ๊ฒจ๋ณด์ž. ์šฐ์„  ๋ฒ„์ „ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ํ…Œ์ŠคํŠธ ํ•˜๊ธฐ ์œ„ํ•ด ์ผ๋ถ€๋Ÿฌ ๋‚ฎ์€๋ฒ„์ „์œผ๋กœ ์„ค์น˜๋ฅผ ํ•ด๋‘”๋‹ค. (ํ•„์ž๋Š” 1.609.1๋กœ ์„ค์น˜ํ•ด๋ดค๋‹ค.) ๊ทธ๋ฆฌ๊ณ  ๋ฒ„์ „ ์—…๊ทธ๋ ˆ์ด๋“œ ํ›„ ์„ค์ •์ด ๊ทธ๋Œ€๋กœ ์˜ฎ๊ฒจ์ง€๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๊ธฐ์œ„ํ•ด Security ์„ค์ •์„ ํ•ด์„œ Jenkins ์ ‘๊ทผ์‹œ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ๋ฌผ์–ด๋ณด๋ก ์„ค์ •ํ•ด๋‘”๋‹ค.

/images/jenkins-upgrade-master-slave/old_jenkins.jpg
์šฐ์ธก ํ•˜๋‹จ์— ๋นจ๊ฐ„์˜์—ญ์œผ๋กœ ๋‚ฎ์€๋ฒ„์ „์ด ์„ค์น˜๋œ๊ฒƒ์„ ํ™•์ธํ• ์ˆ˜ ์žˆ๋‹ค.

์„ค์ •์ด ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฉด ์ตœ์‹ ๋ฒ„์ „์˜ war๋ฅผ ๋‹ค์šด๋ฐ›์•„ ๊ต์ฒดํ•˜๊ณ  ์žฌ์‹œ์ž‘์„ ํ•ด์ค€๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋„ˆ๋ฌด๋‚˜๋„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ฒ„์ „์ด ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ๋œ๊ฒƒ์„ ํ™•์ธํ• ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฒ˜์Œ์— ์„ค์ •ํ•œ Security ์„ค์ •๊นŒ์ง€ ๊ทธ๋Œ€๋กœ ์œ ์ง€๋˜๋Š”๊ฒƒ ๋˜ํ•œ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๋ฌผ๋ก  ๊ตฌ ๋ฒ„์ „์—์„œ ์„ค์น˜๋˜์—ˆ๋˜ ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์ด ๋ฒ„์ „์—…์ด ๋˜๋ฉฐ ๊ทธ์— ๋”ฐ๋ผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋“ค์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด ๋ถ€๋ถ„์€ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ํ•ด์ค€๋‹ค๊ฑฐ๋‚˜ ๊ฐ ์ƒํ™ฉ์— ๋งž๋Š” ๋Œ€์‘์„ ํ•ด์ค˜์•ผ ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•ด์„œ ์ƒ๊ฐ๋ณด๋‹ค(?) ๋„ˆ๋ฌด ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ฒ„์ „์—…์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค.

/images/jenkins-upgrade-master-slave/upgrade_complete.jpg
์—…๊ทธ๋ ˆ์ด๋“œ ํ›„ ํ”Œ๋Ÿฌ๊ทธ์ธ ์—…๊ทธ๋ ˆ์ด๋“œ๋„ ๋™์ผํ•˜๊ฒŒ ๋งž์ถฐ์ฃผ๋Š”๊ฒŒ ์ค‘์š”ํ•˜๋‹ค.

Jenkins ๋ถ„์‚ฐํ™˜๊ฒฝ ๊ตฌ์„ฑํ•˜๊ธฐ (๋…ธ๋“œ ์ถ”๊ฐ€ํ•˜๊ธฐ)

์ด๋ฒˆ์—” Jenkins๋ฅผ ๋ถ„์‚ฐํ™˜๊ฒฝ์œผ๋กœ ๊ตฌ์„ฑํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉฐ ๋ถ„์‚ฐํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•˜๋Š” ์ด์œ ๋Š” ๋งˆ์Šคํ„ฐ-์Šฌ๋ ˆ์ด๋ธŒ(Master-Slave) ํŒจํ„ด์˜ ์žฅ์ ์„ ์–ป๊ณ ์ž ํ•จ์ด๋‹ค. ๋งˆ์Šคํ„ฐ๋Š” ์ž‘์—…์„ ์ชผ๊ฐœ๊ณ  ์Šฌ๋ ˆ์ด๋ธŒ๋กœ ๊ตฌ์„ฑ๋œ ๋…ธ๋“œ์—๊ฒŒ ๋ถ„๋ฐฐ๋ฅผ ํ•˜๊ฒŒ๋˜๋ฉด ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๋Š” ๋งˆ์Šคํ„ฐ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ฆฌํ„ดํ•˜๊ฒŒ ๋œ๋‹ค. ๋งˆ์น˜ ์Šคํƒ€ํฌ๋ž˜ํ”„ํŠธ์—์„œ ์ผ๊พผ์„ ๋Š˜๋ ค์„œ ๋ฏธ๋„ค๋ž„๊ณผ ๊ฐ€์Šค๋ฅผ ๋” ๋นจ๋ฆฌ ์–ป๋Š”๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด๋‹ค.

์—ฌ๊ธฐ์„œ ํ•„์ž๊ฐ€ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฝ์งˆํ•œ ๋ถ€๋ถ„. ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š”๋ฐ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๊ฐ€ ๋˜๋Š” ์„œ๋ฒ„์— ๋™์ผํ•˜๊ฒŒ ์  ํ‚จ์Šค๋ฅผ ์„ค์น˜ํ•˜๊ณ  ๊ทธ๋“ค์„ ๋ชจ๋‘ ์—ฐ๊ฒฐํ•˜๋ ค ํ–ˆ๋˜๊ฒƒ… ๋งˆ์น˜ ํด๋Ÿฌ์Šคํ„ฐ๋ง ํ•˜๋Š”๊ฒƒ์ฒ˜๋Ÿผ… ๋‹น์—ฐํžˆ Jenkins ๋“ค์˜ ๋ฌถ์Œํ˜•ํƒœ(?) ๊ฐ€ ๋˜์•ผ ํ• ๊ฒƒ๊ฐ™์€ ์ƒ๊ฐ์œผ๋กœ ์‹œ๋„ํ•˜์˜€์ง€๋งŒ ์—„์ฒญ๋‚œ ์‚ฝ์งˆ์˜ ์—ฐ์†์ด ๋˜์–ด๋ฒ„๋ ธ๋‹ค. ์•Œ๊ณ ๋ณด๋‹ˆ ๋งˆ์Šคํ„ฐ Jenkins์—์„œ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์— ์ž‘์—…์„ ์ „๋‹ฌํ• ์ˆ˜ ์žˆ๋„๋ก ์—ฐ๋™๋งŒ ์‹œ์ผœ์ฃผ๋ฉด ์ž๋™์œผ๋กœ Agent๋ฅผ ๋งˆ์Šคํ„ฐ Jenkins๊ฐ€ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์— ์„ค์น˜/์‹คํ–‰์„ ํ•˜๊ณ  ์ž‘์—…์„ ๋ถ„ํ• ํ•˜๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ž, ๊ทธ๋Ÿผ ์‹œ์ž‘ํ•ด๋ณด์ž.

  1. ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์—์„œ ๊ณต๊ฐœํ‚ค์™€ ๊ฐœ์ธํ‚ค ์ƒ์„ฑ ๋จผ์ € ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์™€ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„๋ฅผ SSH๋กœ ํ†ต์‹ ํ• ์ˆ˜ ์žˆ๋„๋ก SSH ํ‚ค ์„ค์ •์„ ํ•ด์ค€๋‹ค. ํ†ต์ƒ ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ ํ•˜์œ„ .ssh ํด๋”์—์„œ ์ƒ์„ฑํ•œ๋‹ค.
ssh ํ‚ค ์ƒ์„ฑ
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/~/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /~/.ssh/id_rsa.
Your public key has been saved in /~/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ user@hostname
The key's randomart image is:
+---[RSA 2048]----+
|oo. .            |
|o... o  +        |
|. .o  o+.o       |
|.++++. +o+o..    |
|o.+*=.o.SEoo=    |
| .  o+.*...+ +   |
|   .. + +.  +    |
|     + .     .   |
|      ...        |
+----[SHA256]-----+

๊ณต๊ฐœํ‚ค ํ™•์ธ
$ cat id_rsa.pub
ssh-rsa AAAAB3Nza~~~~~~~~eQKcx8B6uAflRm1J8In1 user@hostname
  1. ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์—์„œ ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์—์„œ ๋งŒ๋“  ๊ณต๊ฐœํ‚ค๋ฅผ ๋“ฑ๋ก ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์—์„œ๋Š” ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์—์„œ SSH ์ ‘์†์„ ํ—ˆ์šฉํ•ด์•ผ ํ•˜๊ธฐ๋•Œ๋ฌธ์— ๋งˆ์Šคํ„ฐ ์„œ๋ฒ„์—์„œ ์ƒ์„ฑํ•œ ๊ณต๊ฐœํ‚ค๋ฅผ ๋“ฑ๋กํ•ด์ค€๋‹ค. ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์˜ ํ™ˆ ๋””๋ ‰ํ† ๋ฆฌ ํ•˜์œ„ .ssh ํด๋”์•„๋ž˜ ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์œ„ ๊ณต๊ฐœํ‚ค๋ฅผ ๋„ฃ์–ด์ฃผ์ž.
$ vi authorized_keys
ssh-rsa AAAAB3Nza~~~~~~~~eQKcx8B6uAflRm1J8In1 user@hostname
  1. Jenkins ์—์„œ Credentials ์„ ๋งŒ๋“ค๋•Œ Private Key ์„ค์ •์„ “From the Jenkins master ~/.ssh"์œผ๋กœ ์„ค์ •ํ•œ๋‹ค. ๋‚˜์ค‘์— ์ด ์ •๋ณด๋กœ ์ธ์ฆ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.
/images/jenkins-upgrade-master-slave/jenkins_upgrade_3.jpg
  1. ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์กฐ๊ธˆ ์žˆ์œผ๋ฉด ๋งˆ์Šคํ„ฐ ๋…ธ๋“œ๊ฐ€ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์— ์—์ด์ „ํŠธ๋ฅผ ์„ค์น˜/์‹คํ–‰ํ•˜๊ณ  ์—ฐ๋™์ด ๋œ๊ฒƒ์„ ํ™•์ธํ• ์ˆ˜ ์žˆ๋‹ค.
/images/jenkins-upgrade-master-slave/jenkins_upgrade_4.jpg

์‹ค์ œ๋กœ ์Šฌ๋ ˆ์ด๋ธŒ ์„œ๋ฒ„์—์„œ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ™•์ธํ•˜๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ์—์ด์ „ํŠธ( slave.jar )๊ฐ€ ์„ค์น˜/์‹คํ–‰๋˜๊ณ  ์žˆ๋Š”๊ฒƒ์„ ํ™•์ธํ• ์ˆ˜ ์žˆ๋‹ค.

๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ ๊ตฌ๋…์„œ๋น„์Šค ๊ฐœ๋ฐœ ํ›„๊ธฐ - 3๋ถ€

์ž‘๋…„ 7์›” 12์ผ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ ํ•„์ž์˜ ์ฒซ ํ† ์ดํ”„๋กœ์ ํŠธ์ธ ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ ๊ตฌ๋…์„œ๋น„์Šค. ์˜คํ”ˆํ•  ๋•Œ๊นŒ์ง€๋งŒ ํ•ด๋„ “AWS ํ”„๋ฆฌํ‹ฐ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” 1๋…„ ์•ˆ์— ๊ตฌ๋…์ž๊ฐ€ ์„ค๋งˆ 1,000๋ช…์ด ๋„˜๊ฒ ์–ด?” ๋ผ๊ณ  ์ƒ๊ฐ์„ ํ–ˆ์—ˆ๋Š”๋ฐ ์˜คํ”ˆ์„ ํ•˜๊ณ  220์ผ์งธ ๋˜๋Š” ๋ฐ”๋กœ ์–ด์ œ ์–ด๋А๋ง ๋ฒŒ์จ ๊ตฌ๋…์ž๊ฐ€ 1,000๋ช…์„ ๋‹ฌ์„ฑํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ทธ ๊ธฐ๋…์œผ๋กœ ๊ทธ๋™์•ˆ ๋ฏธ๋ค„๋‘์—ˆ๋˜ ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ ๊ตฌ๋…์„œ๋น„์Šค ๊ฐœ๋ฐœ ํ›„๊ธฐ ์‹œ๋ฆฌ์ฆˆ์˜ 3๋ถ€๋ฅผ ์“ฐ๊ณ ์ž ํ•œ๋‹ค.

/images/daily-dev-blog-3/nice_minion.gif
์˜ค์˜ˆ~ 1,000๋ช…์ด๋‹ค! ๋•กํ!
์ถœ์ฒ˜ : https://gfycat.com/ko/leafytorngroundbeetle

ํ˜น์‹œ ์ „์— ๋‚ด์šฉ์„ ๋ณด๊ณ ์ž ํ•˜๋ฉด ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๊ฐ„ ์–ด๋–ค ์‹์œผ๋กœ ์„œ๋น„์Šค๋ฅผ ์šด์˜ํ–ˆ๋Š”๊ฐ€?

(ํ•œ๋งˆ๋””๋กœ ์ •๋ฆฌํ•  ์ˆœ ์—†๋Š” ์ง€๋‚œ 220์ผ์ด์—ˆ์ง€๋งŒโ€ฆ) ๋”ฑ ํ•œ๋งˆ๋””๋กœ ์ •๋ฆฌํ•˜์ž๋ฉด ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ๊ฒƒ์„ ๋ฐฐ์šฐ๊ณ  ๊ฒฝํ—˜ํ•  ์ˆ˜ ์žˆ์—ˆ์œผ๋‚˜ ๊ทธ๋งŒํผ ํž˜๋“ค์—ˆ๋˜ ์‹œ๊ฐ„๋“ค์ด๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. 2๋ถ€์—์„œ ์ด์•ผ๊ธฐํ•œ ๋ฌธ์ œ ๋ฐœ์ƒ์— ๋”ฐ๋ฅธ Trouble Shooting๋“ค๋„ ์žˆ์—ˆ์ง€๋งŒ ์šด์˜์„ ํ•ด์˜ค๋‹ค ๋ณด๋‹ˆ ์‚ฌ์ „์— ์ƒ๊ฐํ•˜์ง€๋„ ๋ชปํ•œ ๋ถ€๋ถ„์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋Š” ์ •๋ง ๋‹ค์–‘ํ•œ ๊ฒฝํ—˜์„ ํ•  ์ˆ˜ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  • ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ…์„ ์ˆ˜์ง‘ํ•˜๋Š” ๊ณผ์ •์—์„œ์˜ ๋ฌธ์ œ ์ผ๋ถ€ ๋ธ”๋กœ๊ทธ RSS url์— ์ ‘๊ทผ์„ ํ•  ๋•Œ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์ด ๋ฌดํ•œ๋Œ€๋กœ ๋ฉˆ์ถฐ๋ฒ„๋ฆฌ๋Š” ํ˜„์ƒ์ด ๊ฐ„ํ—์ ์œผ๋กœ ์žˆ์—ˆ๋‹ค. ์ด๋Š” ๋ณ„๋„์˜ ํƒ€์ž„์•„์›ƒ์„ ์„ค์ •ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์–ด๋А ์ •๋„์˜ ํƒ€์ž„์•„์›ƒ์„ ๋‘๊ณ  ์‹œ๊ฐ„ ๋‚ด์— ์‘๋‹ต์ด ์—†์„ ๊ฒฝ์šฐ ๋‹ค์Œ ํฌ์ŠคํŒ…์œผ๋กœ ๋„˜์–ด๊ฐ€๋„๋ก ํ•˜์˜€๋‹ค. (ํƒ€์ž„์•„์›ƒ์€ ์•„์ฃผ ๊ธฐ๋ณธ์ ์ธ ๋ถ€๋ถ„์ธ๋ฐ…)
requests.get(rss_url, timeout=10.0)
  • ๋ฉ”์ผ ๋ฐœ์†กํ•˜๋Š” ๊ณผ์ •์—์„œ์˜ ๋ฌธ์ œ ๊ฐ€๋” ๋ฉ”์ผ์ด ์˜ค์ง€ ์•Š๋Š”๋‹ค๊ณ  ์นœ์ ˆํ•˜๊ฒŒ ํ•„์ž ๊ฐœ์ธ ๋ฉ”์ผ๋กœ ์—ฐ๋ฝ์ด ์˜ค๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์—ˆ๋‹ค. ๊ทธ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„์˜ ์ƒํƒœ๋ฅผ ๋ณด๋ฉด ์„œ๋ฒ„์— ์ง์ ‘ ์ ‘์†์กฐ์ฐจ ์•ˆ ๋  ์ •๋„๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ๋„ˆ๋ฌด ๋งŽ์•„์„œ ๊ทธ๋•Œ๋งˆ๋‹ค AWS ์›น ์ฝ˜์†”์—์„œ ๊ฐ•์ œ๋กœ ์„œ๋ฒ„๋ฅผ ์žฌ๋ถ€ํŒ…์„ ํ•˜๊ณค ํ–ˆ์—ˆ๋‹ค. ์˜ˆ์ „์—๋„ ์ด์•ผ๊ธฐํ•œ ๊ฒƒ์ฒ˜๋Ÿผ AWS ํ”„๋ฆฌํ‹ฐ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค ๋ณด๋‹ˆ ์„œ๋ฒ„์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ 1๊ธฐ๊ฐ€๋ฐ–์— ๋˜์ง€ ์•Š์•„์„œ … ์ œํ•œ๋œ ์‹œ์Šคํ…œ์—์„œ ์„œ๋น„์Šค ์šด์˜์„ ํ•  ์ˆ˜๋ฐ–์— ์—†๋Š” ์ƒํ™ฉ์ด์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ˆ˜์ง‘/๋ฐœ์†ก ์ƒํƒœ๋ฅผ ๋กœ๊น…์œผ๋กœ ์‰ฝ๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ๊ณ  ์Šค์ผ€์ค„๋ง์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋„์›Œ๋‘” Jenkins(tomcat)๋ฅผ ์ค‘๋‹จํ•˜๊ณ  crontab์œผ๋กœ ์Šค์ผ€์ค„๋ง์„ ํ•˜๋„๋ก ํ•˜์˜€๊ณ , ๋กœ๊น…์€ ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ๋กœ๊น…ํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.
/usr/bin/python3.6 /home/~~~/email_send.py > /home/~~~/logs/job/email_send_`date +\%Y\%m\%d\%H\%M\%S`.log 2>&1

๋˜ํ•œ ๊ธฐ์กด์—๋Š” ๋น ๋ฅด๊ฒŒ ๋ฐœ์†กํ•˜๊ธฐ ์œ„ํ•ด ๋ƒ…๋‹ค ์Šค๋ ˆ๋“œ๋กœ ๋Œ๋ ธ๋Š”๋ฐ ๊ตฌ๋…์ž ์ˆ˜๊ฐ€ ๋งŽ์•„์ง€๋‹ค ๋ณด๋‹ˆ RuntimeError: can't start new thread ๋ผ๊ณ  ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†๋‹ค๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ๋„ ํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ Pool์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์˜ multiprocessing ์„ ๋„์ž…ํ•˜์—ฌ ์Šค๋ ˆ๋“œ๋กœ ๋ฐœ์†กํ•  ๋•Œ๋ณด๋‹ค๋Š” ์—„์ฒญ๋‚˜๊ฒŒ ๋น ๋ฅธ ์†๋„๋Š” ์•„๋‹์ง€๋ผ๋„ ํšจ์œจ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์œผ๋กœ 2๋ถ„ ์•ˆ์— 1,000๋ช…์—๊ฒŒ ์•ˆ์ •๋œ ๋ฉ”์ผ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค. (์—ฌ๋‹ด์ด์ง€๋งŒ ๋ฉ”์ผ์ด ์•ˆ ์˜จ๋‹ค๊ณ  ์•Œ๋ ค์ฃผ์…จ๋˜ ๋ถ„๋“ค๊ป˜ ์ด ์ž๋ฆฌ๋ฅผ ๋นŒ๋ ค ๊ฐ์‚ฌ์˜ ์ธ์‚ฌ๋ฅผ ์ „ํ•˜๊ณ  ์‹ถ๋‹ค.)

from multiprocessing import Pool

...

pool = Pool(20)
pool.map(sendMail, email_list)

Heroku ๋‚˜ Netlify ๊ฐ™์ด ์„œ๋ฒ„๋ฅผ ์ง์ ‘ ๋“ค์–ด๊ฐ€์ง€ ์•Š๊ณ  ์•ฑ ํ˜•ํƒœ๋กœ ๋ฐฐํฌํ•˜๋Š” ์‹์œผ๋กœ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ดˆ๊ธฐ์— ์ด ํ† ์ดํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ ์‹ค ์„œ๋น„์Šค์™€ ์ตœ๋Œ€ํ•œ ๋™์ผํ•œ ์‹œ์Šคํ…œ์œผ๋กœ ์šด์˜ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด์— ์„ค์น˜ํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ์•Œ์•„๋ณด๋‹ค ๊ฒฐ๊ตญ AWS๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด AWS ํ”„๋ฆฌํ‹ฐ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ณ„๋„์˜ ์„œ๋ฒ„๋ฅผ ๊ตฌ๋งคํ•˜๋ฉด ์•ˆ ๋ ๊นŒ? ํ•˜๋Š” ์ƒ๊ฐ๋„ ํ•ด๋ดค์ง€๋งŒ ์ตœ์†Œํ•œ์˜ ์ธํ”„๋ผ๋กœ ์ตœ๋Œ€ํ•œ์˜ ์„ฑ๋Šฅ์„ ๋‚ด๋ณด๊ณ  ์‹ถ์€ ์š•์‹ฌ(?) ๋•Œ๋ฌธ์— 1๋…„๊ฐ„์€ ํ”„๋ฆฌํ‹ฐ์–ด๋กœ ์šด์˜ํ•˜๊ณ  ๊ทธ๋‹ค์Œ์—” (ํ˜น์€ ์†Œํ”„ํŠธ์›จ์–ด์ ์œผ๋กœ ํ•œ๊ณ„๊นŒ์ง€ ๋„๋‹ฌํ•œ๋‹ค๋ฉด) ์„œ๋ฒ„๋ฅผ ๊ตฌ๋งคํ•ด์„œ ์šด์˜ํ•˜๊ฒŒ ๋  ๊ฒƒ ๊ฐ™๋‹ค. (์ ์–ด๋„ ์ดํ›„์—๋„ ์ด ์„œ๋น„์Šค๋ฅผ ์œ ์ง€ํ•œ๋‹ค๋Š” ๊ฐ€์ •ํ•˜์—…)

/images/daily-dev-blog-3/daily-ddb-check.jpg
๋†๋ถ€์˜ ๋งˆ์Œ์œผ๋กœ…
์ถœ์ฒ˜ : http://www.iwithjesus.com/news/articleView.html?idxno=2511

์•„์นจ 10์‹œ๊ฐ€ ๋˜๋ฉด ์ž๋™์œผ๋กœ ๋ฉ”์ผ์ด ์ž˜ ๋ฐœ์†ก๋˜์—ˆ๋Š”์ง€, ํ˜น ์–ด์ œ ์ˆ˜์ง‘๋œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์˜ˆ์ „์— ์ˆ˜์ง‘๋œ ๋‚ด์šฉ์ด ์ค‘๋ณต ๋ฐœ์†ก๋œ ๊ฑด ์•„๋‹Œ์ง€, ๋ฐœ์†ก์€ ๊ตฌ๋…ํ•œ ์‚ฌ๋žŒ ์ „๋ถ€์—๊ฒŒ ์ž˜ ๋ณด๋‚ด์กŒ๋Š”์ง€… ๊ฑฐ์˜ ๋งค์ผ๊ฐ™์ด Daily-DevBlog ์„œ๋น„์Šค๋ฅผ ์‚ดํ”ผ๋ฉฐ ์ง€๋‚ธ ๊ฒƒ ๊ฐ™๋‹ค. (ํ•˜๋ฃจ๋ผ๋„ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด ๋ฐค์„ ์ƒˆ์›Œ์„œ๋ผ๋„ ์›์ธ์„ ํŒŒ์•…ํ•˜๊ณ  ๋‹ค์Œ ๋ฐœ์†ก์—๋Š” ์ •์ƒ์ ์œผ๋กœ ๋ฐœ์†ก๋˜๋„๋ก ์ˆ˜์ •ํ•˜๊ธฐ๋„ ํ–ˆ๋‹ค.)

๋ˆ„๊ตฌ๋‚˜ ํ•  ์ˆ˜ ์žˆ๋Š” ์—‘์„ธ์Šค ๋กœ๊ทธ ๋ถ„์„ ๋”ฐ๋ผ ํ•ด๋ณด๊ธฐ (by Elastic Stack)

ํ•„์ž๊ฐ€ Elastic Stack์„ ์•Œ๊ฒŒ๋œ๊ฑด 2017๋…„ ์–ด๋А ์—ฌ๋ฆ„ ๋™๊ธฐํ˜•์ด ๊ณต๋ถ€ํ•˜๊ณ  ์žˆ๋Š”๊ฒƒ์„ ๋ณด๊ณ  ํ˜ธ๊ธฐ์‹ฌ์— ๋”ฐ๋ผํ•˜๋ฉฐ ์‹œ์ž‘ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ทธ๋•Œ๊นŒ์ง€๋งŒ ํ•ด๋„ ๋ฒ„์ „์ด 2.x ์˜€๋Š”๋ฐ ์ง€๊ธˆ ๊ธ€์„ ์“ฐ๊ณ ์žˆ๋Š” 2019๋…„ 2์›”์ดˆ ์ตœ์‹ ๋ฒ„์ „์ด 6.6์ด๋‹ˆ ์ •๋ง ๋น ๋ฅด๊ฒŒ ๋ณ€ํ™”ํ•˜๋Š”๊ฒƒ ๊ฐ™๋‹ค. ๋น ๋ฅด๊ฒŒ ๋ณ€ํ™”ํ•˜๋Š” ๋ฒ„์ „๋งŒํผ ์‚ฌ๋žŒ๋“ค์˜ ๊ด€์‹ฌ๋„ (๋“œ๋ผ๋งˆํ‹ฑํ•˜๊ฒŒ๋Š” ์•„๋‹ˆ์ง€๋งŒ) ๊พธ์ค€ํžˆ ๋Š˜์–ด๋‚˜ ๊ฐœ์ธ์ ์œผ๋กœ, ๊ทธ๋ฆฌ๊ณ  ์‹ค๋ฌด์—์„œ๋„ ํ™œ์šฉํ•˜๋Š” ๋ฒ”์œ„๊ฐ€ ๋งŽ์•„์ง€๊ณ  ์žˆ๋Š”๊ฒƒ ๊ฐ™๋‹ค.

๊ทธ๋ž˜์„œ ๊ทธ๋Ÿฐ์ง€ ์ตœ๊ทผ๋“ค์–ด (์•„์ฃผ ์ฝ”๋”ฑ์ง€๋งŒํผ ์กฐ๊ธˆ์ด๋ผ๋„ ๋” ํ•ด๋ณธ) ํ•„์ž์—๊ฒŒ Elastic Stack ์‚ฌ์šฉ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋ฌผ์–ด๋ณด๋Š” ์ฃผ๋ณ€ ์ง€์ธ๋“ค์ด ๋Š˜์–ด๋‚˜๊ณ  ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์˜ˆ์ „์— ํ•œ์ฐฝ ๊ณต๋ถ€ํ–ˆ์„๋•Œ์˜ ๋ฒ„์ „๋ณด๋‹ค ๋งŽ์ด ๋ฐ”๊ผˆ๊ธฐ์— ์ด ๊ธฐํšŒ์— “๊ทธ๋Œ€๋กœ ๋”ฐ๋ผ๋งŒ ํ•˜๋ฉด Elastic Stack์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์„๋งŒํ•œ ๊ธ€"์„ ์จ๋ณด๊ณ ์ž ํ•œ๋‹ค. ์‚ฌ์‹ค ํ•„์ž๊ฐ€ ์˜ˆ์ „์— “๋„ํ๋จผํŠธ๋ฅผ ๋ณด๊ธฐ์—” ๋„ˆ๋ฌด ์–ด๋ ค์›Œ ๋ณด์ด๋Š” ๋А๋‚Œ์ ์ธ ๋А๋‚Œ” ๋•Œ๋ฌธ์— ์‚ฝ์งˆํ•˜๋ฉฐ ๊ตฌ์„ฑํ•œ ํž˜๋“ค์—ˆ๋˜ ๊ธฐ์–ต์„ ๋˜์‚ด๋ ค ์ตœ๋Œ€ํ•œ ์‹ฌํ”Œํ•˜๊ณ  ์ฒ˜์Œ ํ•ด๋ณด๋Š” ์‚ฌ๋žŒ๋„ ๋”ฐ๋ผํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด “์•„~ ์ด๊ฒŒ Elastic Stack ์ด๊ตฌ๋‚˜!”, “์ด๋Ÿฐ์‹์œผ๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ฑฐ๊ตฌ๋‚˜!” ํ•˜๋Š” ๋„์›€์„ ์ฃผ๊ณ  ์‹ถ๋‹ค.

+ ๊ทธ๋Ÿฌ๋ฉด์„œ ์ตœ์‹ ๋ฒ„์ „๋„ ์‚ดํŽด๋ณด๊ณ … 1์„2์กฐ, ์ด๋Ÿฐ๊ฒŒ ๋ฐ”๋กœ ๋ธ”๋กœ๊ทธ๋ฅผ ํ•˜๋Š” ์ด์œ ์ด์ง€ ์•Š์„๊นŒ? ๋‹ค์‹œํ•œ๋ฒˆ ๋งํ•˜์ง€๋งŒ ๋„ํ๋จผํŠธ๊ฐ€ ์ตœ๊ณ  ์ง€์นจ์„œ์ด๊ธด ํ•˜๋‹ค…

Elastic ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์— ๊ฐ€๋ฉด ๊ฐ ์ œํ’ˆ๊ตฐ๋“ค์— ๋Œ€ํ•ด ๊ทธ๋ฆผ์œผ๋กœ ๋œ ์ž์„ธํ•œ ์„ค๋ช…๊ณผ ๋„ํ๋จผํŠธ๊ฐ€ ์žˆ์ง€๋งŒ ์ด๋“ค์„ ์–ด๋–ค์‹์œผ๋กœ ์กฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ „์ฒด์ ์ธ ํ๋ฆ„์„ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ณณ์€ ์—†์–ด ๋ณด์ธ๋‹ค. (์ง€๊ธˆ ๋ณด๋ฉด ๋„ํ๋จผํŠธ๊ฐ€ ๊ทธ ์–ด๋””๋ณด๋‹ค ์„ค๋ช…์ด ์ž˜๋˜์–ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐ๋˜์ง€๋งŒ ์‚ฌ์ „ ์ง€์‹์ด ์ „ํ˜€์—†๋Š” ์ƒํƒœ์—์„œ๋Š” ๋ด๋„๋ด๋„ ์–ด๋ ค์›Œ ๋ณด์˜€๋‹ค.) ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Apache access log๋ฅผ Elasticsearch์— ์ธ๋ฑ์‹ฑ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

์ „์ฒด์ ์ธ ํ๋ฆ„

ํ•„์ž๋Š” ๊ธ€๋ณด๋‹ค๋Š” ๊ทธ๋ฆผ์„ ์ข‹์•„ํ•˜๋Š” ํŽธ์ด๋ผ ์ „์ฒด์ ์ธ ํ๋ฆ„์„ ๊ทธ๋ฆผ์œผ๋กœ ๋จผ์ € ๋ณด์ž.

/images/access-log-to-elastic-stack/concept.jpg
  1. ์™ธ๋ถ€์—์„œ์˜ ์ ‘๊ทผ์ด ๋ฐœ์ƒํ•˜๋ฉด apache ์›น์„œ๋ฒ„์—์„œ ์„ค์ •ํ•œ ๊ฒฝ๋กœ์— access log๊ฐ€ ํŒŒ์ผ๋กœ ์ƒ์„ฑ์ด ๋˜๊ฑฐ๋‚˜ ์žˆ๋Š” ํŒŒ์ผ์— ์ถ”๊ฐ€๊ฐ€ ๋œ๋‹ค. ํ•ด๋‹น ํŒŒ์ผ์—๋Š” ํ•œ์ค„๋‹น ํ•˜๋‚˜์˜ ์—‘์„ธ์Šค ์ •๋ณด๊ฐ€ ๋‚จ๊ฒŒ ๋œ๋‹ค.
  2. fileBeat์—์„œ ํ•ด๋‹น ํŒŒ์ผ์„ ํŠธ๋ž˜ํ‚น ํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ๋ผ์ธ์ด ์ถ”๊ฐ€๋˜๋ฉด ์ด ์ •๋ณด๋ฅผ logstash ์—๊ฒŒ ์ „๋‹ฌํ•ด์ค€๋‹ค.
  3. logastsh ๋Š” filebeat์—์„œ ์ „๋‹ฌํ•œ ์ •๋ณด๋ฅผ ํŠน์ • port๋กœ input ๋ฐ›๋Š”๋‹ค.
  4. ๋ฐ›์€ ์ •๋ณด๋ฅผ filter ๊ณผ์ •์„ ํ†ตํ•ด ๊ฐ ์ •๋ณด๋ฅผ ๋ถ„ํ•  ๋ฐ ์ •์ œํ•œ๋‹ค. (ip, uri, time ๋“ฑ)
  5. ์ •๋ฆฌ๋œ ์ •๋ณด๋ฅผ elasticsearch ์— ouput ์œผ๋กœ ๋ณด๋‚ธ๋‹ค. (์ •ํ™•ํžˆ ๋งํ•˜๋ฉด ์ธ๋ฑ์‹ฑ์„ ํ•œ๋‹ค.)
  6. elasticsearch ์— ์ธ๋ฑ์‹ฑ ๋œ ์ •๋ณด๋ฅผ ํ‚ค๋ฐ”๋‚˜๋ฅผ ํ†ตํ•ด ์†์‰ฝ๊ฒŒ ๋ถ„์„์„ ํ•œ๋‹ค.

ํ•œ๋ฒˆ์˜ ์„ค์น˜๊ณ  ์ผ๋ จ์˜ ๊ณผ์ •์ด ๋š๋”ฑ ๋œ๋‹ค๋ฉด ๋„ˆ๋ฌด ํŽธํ•˜๊ฒ ์ง€๋งŒ, ๊ฐ๊ฐ์˜ ๋ ˆ์ด์–ด๊ฐ€ ๋‚˜๋‰˜์–ด์ ธ์žˆ๋Š” ์ด์œ ๋Š” ํ•˜๋Š” ์—ญํ™œ์ด ์ „๋ฌธ์ ์œผ๋กœ(?) ๋‚˜๋‰˜์–ด์ ธ ์žˆ๊ณ  ๊ฐ ๋ ˆ์ด์–ด์—์„œ๋Š” ์„ธ๋ถ€ ์„ค์ •์„ ํ†ตํ•ด ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

beats๋ผ๋Š” ๋ ˆ์ด์–ด๊ฐ€ ๋‚˜์˜ค๊ธฐ ์ „์—๋Š” logstash์—์„œ ์ง์ ‘ file์„ ๋ฐ”๋ผ๋ณด๊ณค ํ–ˆ์—ˆ๋Š”๋ฐ beats๊ฐ€ logstash ๋ณด๋‹ค ๊ฐ€๋ฒผ์šด shipper ๋ชฉ์ ์œผ๋กœ ๋‚˜์˜จ agent ์ด๋‹ค๋ณด๋‹ˆ ํ†ต์ƒ logstash ์•ž๋‹จ์— filebeat๋ฅผ ์œ„์น˜์‹œํ‚ค๊ณค ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

์ „์ฒด์ ์ธ ๊ทธ๋ฆผ์€ ์œ„์™€ ๊ฐ™๊ณ , ์ด์ œ ์ด ๊ธ€์„ ๋ณด๊ณ ์žˆ๋Š” ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด ๋”ฐ๋ผํ•  ์ฐจ๋ก€์ด๋‹ค. ๊ฐ ๋ ˆ์ด์–ด๋ณ„๋กœ ํ•˜๋‚˜์”ฉ ์„ค์น˜๋ฅผ ํ•ด๋ณด๋ฉฐ ๊ตฌ์„ฑ์„ ํ•ด๋ณด์ž. ์„ค์น˜์ˆœ์„œ๋Š” ๋ฐ์ดํ„ฐ ํ๋ฆ„์˜ ์ˆœ์„œ์— ๋งž์ถฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์„ค์น˜๋ฅผ ํ•ด์•ผ ํšจ์œจ์ ์œผ๋กœ ๋ณผ์ˆ˜๊ฐ€ ์žˆ๋‹ค. (์•„๋ž˜์ˆœ์„œ๋Œ€๋กœ ํ•˜์ง€ ์•Š์„๊ฒฝ์šฐ ์„ค์น˜/์‹œ์ž‘/์ข…๋ฃŒ ๋ฅผ ๊ฐ๊ฐ์˜ ํƒ€์ด๋ฐ์— ๋งž์ถ”์–ด ํ•ด์ค˜์•ผ ํ• ๊ฒƒ ๊ฐ™์•„ ๋ณต์žกํ• ๊ฒƒ๊ฐ™๋‹ค.)

elasticsearch โ†’ logstash โ†’ kibana โ†’ filebeat

์ด ํฌ์ŠคํŒ…์€ CentOS 7.4์—์„œ Java 1.8, apache 2.2๊ฐ€ ์„ค์น˜๋˜์–ด์žˆ๋‹ค๋Š” ๊ฐ€์ •ํ•˜์— ๋ณด๋ฉด ๋ ๋“ฏํ•˜๋‹ค. ๋˜ํ•œ ๊ฐ ๋ ˆ์ด์–ด๋ณ„ ์„ค๋ช…์€ ๊ตฌ๊ธ€๋ง์„ ํ•˜๊ฑฐ๋‚˜ Elastic ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์— ๊ฐ€๋ณด๋ฉด ์ž์„ธํžˆ ๋‚˜์™€์žˆ์œผ๋‹ˆ ๊ธฐ๋ณธ ์„ค๋ช…์€ ์•ˆํ•˜๋Š”๊ฒƒ์œผ๋กœ ํ•˜๊ณ , ๊ฐ ๋ ˆ์ด์–ด์˜ ์„ธ๋ถ€ ์„ค์ •์€ ํ•˜์ง€ ์•Š๋Š”๊ฒƒ์œผ๋กœ ํ•œ๋‹ค.

Elasticsearch

๊ณต์‹ ํ™ˆํŽ˜์ด์ง€

๋‹ค์šด๋ฐ›๊ณ  ์••์ถ•ํ’€๊ณ  ์‹ฌ๋ณผ๋ฆญ ๊ฒฝ๋กœ ๋งŒ๋“ค๊ณ  (์‹ฌ๋ณผ๋ฆญ ๊ฒฝ๋กœ๋Š” ์„ ํƒ์‚ฌํ•ญ)
$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.6.0.tar.gz
$ tar zxvf elasticsearch-6.6.0.tar.gz
$ ln -s elasticsearch-6.6.0 elasticsearch

์„ค์ • ํŒŒ์ผ์„ ์—ด๊ณ  ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.
$ cd elasticsearch/conf
$ vi elasticsearch.yml
path.data: /~~~/data/elasticsearch (๊ธฐ๋ณธ๊ฒฝ๋กœ์—์„œ ๋ณ€๊ฒฝํ• ๋•Œ์ถ”๊ฐ€)
path.logs: /~~~/logs/elasticsearch
network.host: 0.0.0.0 # ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก (์‹ค์ œ ip๋ฅผ ์ ์–ด์ค˜๋„ ๋จ)

elasticsearch ์˜ ์‹œ์ž‘๊ณผ ์ข…๋ฃŒ๋ฅผ ์กฐ๊ธˆ์ด๋‚˜๋งˆ ํŽธํ•˜๊ฒŒ ํ•˜๊ธฐ์œ„ํ•ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•ด์คŒ (์ด๊ฒƒ๋˜ํ•œ ์„ ํƒ์‚ฌํ•ญ)
$ cd ../bin
$ echo './elasticsearch -d -p es.pid' > start.sh
$ echo 'kill `cat es.pid`' > stop.sh
$ chmod 755 start.sh stop.sh

ํ˜น์‹œ ์•„๋ž˜์™€ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ• ๊ฒฝ์šฐ ๊ณต์‹๋ฌธ์„œ ๋Œ€๋กœ ์ง„ํ–‰ํ•ด์ค€๋‹ค.

Spring MVC Redirect ์ฒ˜๋ฆฌ์ค‘์— ๋ฐœ์ƒํ•œ Out Of Memory ์›์ธ ๋ถ„์„ํ•˜๊ธฐ

์ดˆ์ฐฝ๊ธฐ ์‹ ์ž…์‹œ์ ˆ์— ๋ฐฐ์šฐ๊ฑฐ๋‚˜ ์‚ฌ์šฉํ–ˆ๋˜ ๊ธฐ์ˆ ์ ์ธ ๋ฐฉ๋ฒ•๋“ค์ด ์žˆ๋‹ค. ์‹œ๊ฐ„์ด ์ง€๋‚ ์ˆ˜๋ก ์™ ๋งŒํ•ด์„  ๋‹ค๋ฅธ๋ฐฉ๋ฒ•์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ ค ํ•˜๊ณ  ์Šต๊ด€์ฒ˜๋Ÿผ ๊ธฐ์กด์— ์‚ฌ์šฉํ–ˆ๋˜ ๋ฐฉ๋ฒ•์„ ๊ณ ์ˆ˜ํ•˜๋Š” ๋ฒ„๋ฆ‡์ด ์žˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ๊ณผ๊ฑฐ์— ์‚ฌ์šฉํ–ˆ์„๋•Œ ์•„๋ฌด ํƒˆ ์—†์ด ์ž˜ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ทธ๋ฆฌ๊ณ  ๋น ๋ฅธ ๊ตฌํ˜„ ๋•Œ๋ฌธ์ด๋ผ๋Š” ํ•‘๊ณ„์ผ ๊ฒƒ ๊ฐ™๋‹ค. ์ด๋Ÿฌํ•œ ๋ฒ„๋ฆ‡์€ ๋น„๋‹จ ์ด ๊ธ€์„ ์ ๊ณ ์žˆ๋Š” ํ•„์ž ๋ฟ๋งŒ์ด ์•„๋‹ˆ๋ผ ๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๋“ค์ด ๊ฐ€์ง€๊ณ  ์žˆ์„๊บผ๋ผ ์กฐ์‹ฌ์Šค๋ ˆ ์ถ”์ธกํ•ด๋ณธ๋‹ค. (์•„๋‹ˆ๋ผ๋ฉด…๋”์šฑ ๋ถ„๋ฐœ ํ•ด์•ผ๊ฒ ๋‹ค…ใ… ) ์ตœ๊ทผ ์šด์˜ํ•˜๊ณ  ์žˆ๋Š” ์„œ๋น„์Šค์—์„œ ์žฅ์•  ์ƒํ™ฉ๊นŒ์ง€ ๊ฐˆ์ˆ˜์žˆ๋Š” ์œ„ํ—˜ํ•œ ์ƒํ™ฉ์ด ์žˆ์—ˆ๋Š”๋ฐ ํŒ€๋‚ด ์ฝ”๋“œ๋ฆฌ๋ทฐ๋ฅผ ํ†ตํ•ด ๋ฌธ์ œ์ ์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๊ทธ ์›์ธ์€ Spring MVC Controller ๋ ˆ๋ฒจ์—์„œ redirect ์ฒ˜๋ฆฌ๋ฅผ ํ• ๋•Œ return๊ฐ’์˜ Cardinality๊ฐ€ ๋†’์„๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋œ๋‹ค๊ณ …

@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test() {
	String url = "์–ด๋– ํ•œ ๋กœ์ง์— ์˜ํ•ด ์ƒ์„ฑ๋˜๋Š” url";
	return "redirect:" + url; // <- ์œ„ํ—˜ ํฌ์ธํŠธ!
}

์ด ์ฝ”๋“œ๊ฐ€ ์™œ? ์–ด๋””๊ฐ€ ์–ด๋•Œ์„œ? ์ด์ œ๊นŒ์ง€ Controller ๋ ˆ๋ฒจ์—์„œ redirect ์ฒ˜๋ฆฌ๋ฅผ ํ• ๋•Œ ์•„๋ฌด์ƒ๊ฐ์—†์ด ์œ„์— ์žˆ๋Š” ์ฝ”๋“œ ํ˜•ํƒœ๋กœ ๊ตฌํ˜„์„ ํ–ˆ๋Š”๋ฐ ์ €๋Ÿฌํ•œ ์ฝ”๋“œ ๋•Œ๋ฌธ์— OOM์ด ๋ฐœ์ƒํ•˜์—ฌ fullGC ๊ฐ€ ์—ฌ๋Ÿฌ๋ฒˆ ๋ฐœ์ƒํ•˜๊ณ , ์ผ์‹œ์ ์œผ๋กœ ์„œ๋น„์Šค๊ฐ€ ์ง€์—ฐ๋˜๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์ž์ฃผ ์‚ฌ์šฉํ•˜๋˜ ๋ฐฉ๋ฒ•์ด์˜€๋Š”๋ฐ ์žฅ์• ๋ฅผ ์œ ๋ฐœํ• ์ˆ˜ ์žˆ๋Š” ์œ„ํ—˜ํ•œ ๋ฐฉ๋ฒ•์ด์˜€๋‹ค๋‹ˆ… ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ•์ด ์™œ ์ž˜๋ชป๋˜์—ˆ๋Š”์ง€ ์‹ค์ œ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ๋ชธ์†Œ(?) ์ฒด๊ฐ์„ ํ•ด๋ณด๊ณ , ๊ทธ๋Ÿผ ์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ redirect ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผ ํ•˜๋Š”๊ฐ€์™€ ๊ฐœ์„ ์„ ํ•จ์œผ๋กœ์จ ๊ธฐ์กด๋ฐฉ์‹์— ๋น„ํ•ด ์–ด๋–ค์ ์ด ์ข‹์•„์กŒ๋Š”์ง€์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

๋ญ”๊ฐ€ ๋‚ด๊ฒƒ์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์‹œ๋ฆฌ์ฆˆ๋ฌผ์ด ๋‚˜์˜ฌ๊ฒƒ๋งŒ ๊ฐ™์€ ๋А๋‚Œ์ด๋‹ค…

๊ธฐ์กด๋ฐฉ์‹์˜ ๋ฌธ์ œ์  ์žฌํ˜„ ๋ฐ ๋‹ค์–‘ํ•œ ์›์ธ๋ถ„์„

๊ธฐ์กด๋ฐฉ์‹์œผ๋กœ ํ–ˆ์„๋•Œ ์™œ OOM์ด ๋ฐœ์ƒํ–ˆ์„๊นŒ? ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ์ €๋Ÿฐ ๊ธ€๋“ค๋งŒ ๋ณด๊ณ  ์ถ”์ธก ํ• ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ง์ ‘ ์žฌํ˜„์„ ํ•ด๋ณด๊ณ  ๋‹ค์–‘ํ•œ ์‹œ๊ฐ์—์„œ ์›์ธ๋ถ„์„์„ ํ•ด๋ณด์ž. ๋จผ์ € ๊ธฐ๋ณธ์ ์ธ Spring MVC ๋ผˆ๋Œ€๋ฅผ ๋งŒ๋“ค๊ณ  redirect ํ•˜๋Š” return ๊ฐ’์˜ Cardinality๊ฐ€ ๋†’๋„๋ก random string ์„ ๋งŒ๋“ค์–ด ์ฃผ๋„๋ก ํ•œ๋‹ค. ์ฆ‰, /random์„ ํ˜ธ์ถœํ•˜๋ฉด /result/ETmHfowFkU์ฒ˜๋Ÿผ random string ์ด ๋งŒ๋“ค์–ด ์ง€๋ฉฐ redirect ์ฒ˜๋ฆฌ๊ฐ€ ๋˜๋Š” ๋งค์šฐ ์‹ฌํ”Œํ•œ ๊ตฌ์กฐ์ด๋‹ค.

// Spring ๋ฒ„์ „์€ 4.0.6.RELEASE
@Controller
@RequestMapping("/")
public class TestController {
	@RequestMapping(value = "random", method = RequestMethod.GET)
	public String random() {
		return "redirect:result/" + UUID.randomUUID();
	}

	@RequestMapping(value = "result/{message}", method = RequestMethod.GET)
	public String result(ModelMap model, @PathVariable String message) {
		model.addAttribute("message", message);
		return "result";
	}
}

๋˜ํ•œ ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์—์„œ๋Š” AOP๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋•Œ์™€ ๋™์ผํ•œ ์ƒํ™ฉ์œผ๋กœ ์žฌํ˜„์„ ํ•˜๊ธฐ ์œ„ํ•ด AOP๊ด€๋ จ ์„ค์ •๋„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy
@ComponentScan
public class HelloWorldConfiguration {
	
	@Bean(name="HelloWorld")
	public ViewResolver viewResolver() {
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setViewClass(JstlView.class);
		viewResolver.setPrefix("/WEB-INF/views/");
		viewResolver.setSuffix(".jsp");

		return viewResolver;
	}
}

์ด๋ ‡๊ฒŒ ํ•œ๋’ค tomcat์œผ๋กœ ์ตœ๋Œ€/์ตœ์†Œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ 256m์œผ๋กœ ์„ค์ •ํ›„ ํ•ด๋‹น ๋ชจ๋“ˆ์„ ๋„์›Œ์ค€๋‹ค. ๊ทธ๋‹ค์Œ ๋ฉ”๋ชจ๋ฆฌ ์ƒํƒœ๋ฅผ ๋ณด๊ธฐ ์œ„ํ•ด tomcat์— pinpoint๋ฅผ ์—ฐ๋™ํ•˜๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ ํ˜ธ์ถœํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด nGrinder์„ ์„ค์ •ํ•ด์ค€๋‹ค. ํŠน๋ณ„ํ•œ ์„ค์ •์€ ์—†๊ณ  ์œ„ ์ปจํŠธ๋กค๋Ÿฌ์˜ url (/random) ์„ ์—ฌ๋Ÿฌ๋ฒˆ ํ˜ธ์ถœํ•˜๋„๋ก ํ•˜์˜€๋‹ค. nGrinder์„ ์„ค์ •ํ•˜๋Š”๋Œ€์—๋Š” ์ด ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ•ด์„œ ์„ค์ •ํ•˜์˜€๋‹ค.

์ž, ์ด์ œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹œ์ž‘ํ•ด๋ณด์ž. (๋งˆ์น˜ ์ˆ˜์ˆ  ์ง‘๋„ํ•˜๋Š”๊ฒƒ ๊ฐ™์€ ๊ธฐ๋ถ„์œผ๋กœ…๊ฐ„ํ˜ธ์‚ฌ~ ์นผ!)

  1. nGrinder nGrinder์˜ ๊ธฐ๋ณธ ์Šคํฌ๋ฆฝํŠธ์—์„œ url๋งŒ ํ•ด๋‹น ์„œ๋ฒ„๋กœ ํ˜ธ์ถœ๋˜๋„๋ก ๋ฐ”๊ฟ”์ฃผ๊ณ  ์ด ๊ฐ€์ƒ ์‚ฌ์šฉ์ž๋Š” 2,000์œผ๋กœ ์‹œ๊ฐ„์€ 5๋ถ„์œผ๋กœ ์„ค์ •ํ›„์— ํ…Œ์ŠคํŠธ ์‹œ์ž‘์„ ํ•˜์˜€๋”๋‹ˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทธ๋ž˜ํ”„๋ฅผ ๋ณผ์ˆ˜ ์žˆ์—ˆ๋‹ค.
/images/spring-redirect-oom/test1-ngrinder.jpg

TPS๊ฐ€ ๋ถˆ์•ˆ์ •ํ•ด์ง€๋‹ค๊ฐ€ ์–ด๋А์‹œ์ ๋ถ€ํ„ฐ ๋‚ฎ์•„์ง€๋Š”๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒŒ ์„œ๋น„์Šค ์˜€๋‹ค๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ ‘์†ํ•˜๋Š”๋ฐ ๋ถˆํŽธ์„ ๋А๊ผˆ์„๊บผ๋ผ ์ถ”์ธก์„ ํ•ด๋ณธ๋‹ค. ๋˜ํ•œ ์•„์ฃผ ๊ฐ„๋‹จํ•œ random string ์„ ๋ฆฌํ„ดํ•˜๋Š” ํŽ˜์ด์ง€ ์ž„์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์—๋Ÿฌ ์‘๋‹ต์ด ์ ์ง€ ์•Š์€๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

  1. pinpoint ๋ฉ”๋ชจ๋ฆฌ ์ƒํƒœ๋Š” ์–ด๋–ค์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด pinpoint๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทธ๋ž˜ํ”„๋ฅผ ๋ณผ์ˆ˜ ์žˆ์—ˆ๋‹ค.
/images/spring-redirect-oom/test1-pinpoint.jpg

๋ณด๊ธฐ๋งŒํ•ด๋„ ์‹ฌ์žฅ์ด ๋ฒŒ๋ ๋ฒŒ๋ (?) ๋›ธ ์ •๋„๋กœ ๋ฌด์„œ์šด ๊ทธ๋ฆผ์ด๋‹ค. ์‹ค์ œ๋กœ ์„œ๋น„์Šค์— (์ด์ •๋„๊นŒ์ง„ ์•„๋‹ˆ์˜€์ง€๋งŒ) ๋น„์Šทํ•œ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ–ˆ์—ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ…Œ์ŠคํŠธ๋ฅผ ์ ์  ํ•˜๋ฉด ํ• ์ˆ˜๋ก ์˜ฌ๋ผ๊ฐ€๋‹ค๊ฐ€ fullGC๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋‹ˆ ๋Œ€๋‚˜๋ฌด ์ˆฒ์— ์žˆ๋Š” ๋Œ€๋‚˜๋ฌด๋งˆ๋ƒฅ fullGC๊ฐ€ ๋นผ๊ณกํžˆ ๋ฐœ์ƒํ•˜์˜€๋‹ค. (์ด๋Ÿฌ๋‹ˆ… ํŽ˜์ด์ง€ ์ ‘๊ทผ์— ์ง€์—ฐ์ด ์ƒ๊ธด๊ฒƒ ๊ฐ™๋‹ค.)

์ฒœ๋งŒ ๋ช…์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ 1๋ถ„ ๋‚ด๋กœ ์•Œ๋ฆผ ๋ณด๋‚ด๊ธฐ (๋ณ‘๋ ฌํ”„๋กœ์„ธ์Šค์˜ ์ตœ์ ํ™”)

๋งŒ์•ฝ 1๋ฒˆ๋ถ€ํ„ฐ 10๋ฒˆ๊นŒ์ง€ ๋ฒˆํ˜ธํ‘œ๊ฐ€ ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค ์ด ์—ด๋ช…์—๊ฒŒ ํ˜ผ์ž์„œ ๋™์ผํ•œ ๋‚ด์šฉ์˜ ๋ฉ”์ผ์„ ๋ณด๋‚ธ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ๊ทธ๋ฆฌ๊ณ  ๋ฉ”์ผ ๋ฐœ์†ก์‹œ ํ•œ๋ฒˆ์— ํ•œ๋ช…์—๊ฒŒ๋งŒ ๋ณด๋‚ด์•ผ ํ•˜๋Š” ์ œํ•œ์‚ฌํ•ญ์ด ์žˆ์„๋•Œ ๊ณผ์—ฐ ๋‹น์‹ ์€ ์–ด๋–ค์‹์œผ๋กœ ๋ณด๋‚ด๊ฒ ๋Š”๊ฐ€? ์ด์–ด์„œ ์ฝ์ง€๋ง๊ณ  ํ•œ๋ฒˆ ์ƒ๊ฐํ•ด๋ณด์ž. ์•„๋ฌด๊ฒƒ๋„ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ๋‹จ์ˆœํ•˜๊ฒŒ ์ƒ๊ฐํ•œ๋‹ค๋ฉด 1๋ฒˆ ๋ณด๋‚ด๊ณ  > 2๋ฒˆ ๋ณด๋‚ด๊ณ  … 9๋ฒˆ ๋ณด๋‚ด๊ณ  > 10๋ฒˆ ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์ด ๋จผ์ € ๋– ์˜ค๋ฅด๊ฒŒ ๋œ๋‹ค. (for loop 1 to 10 … ) ํ•˜์ง€๋งŒ ๋ณด๋‚ด์•ผ ํ•  ์‚ฌ๋žŒ๋“ค์ด ๋งŽ์•„์ ธ์„œ ๋ฐฑ๋ช…, ์ฒœ๋ช… ๋งŽ๊ฒŒ๋Š” ์ฒœ๋งŒ๋ช…์—๊ฒŒ ๋ณด๋‚ด์•ผ ํ•  ๊ฒฝ์šฐ ๋ฐฉ๊ธˆ๊ณผ ๊ฐ™์€ ์ˆœ์ฐจ์ ์ธ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋„ˆ๋ฌด ๋Šฆ๊ฒŒ ๋ฐœ์†ก๋œ๋‹ค๋Š”๊ฑด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ์•Œ ์ˆ˜์žˆ๋Š” ๋ฌธ์ œ… ๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ ๋ณด๋‚ด์•ผ ๋ณด๋‹ค ๋นจ๋ฆฌ ๋ณด๋‚ผ์ˆ˜ ์žˆ์„๊นŒ? ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ํ•„์ž๊ฐ€ ์šด์˜ํ•˜๊ณ  ์žˆ๋Š” ์„œ๋น„์Šค์—์„œ ๊ธฐ์กด์— ์žˆ๋˜ ๋ณ‘๋ ฌํ”„๋กœ์„ธ์Šค๋ฅผ ์–ด๋–ค์‹์œผ๋กœ ์ตœ์ ํ™” ํ–ˆ๋Š”์ง€, ๊ทธ๋ž˜์„œ ๊ฒฐ๊ตญ ์–ผ๋งˆ๋‚˜ ๋นจ๋ผ์กŒ๋Š”์ง€์— ๋Œ€ํ•œ ๊ณผ์ •์„ ์ •๋ฆฌํ•ด ๋ณด๊ณ ์ž ํ•œ๋‹ค. ๋น„๋‹จ ๋ฉ”์ผ ๋ฐœ์†ก์ด๋‚˜ ์•ฑ ํ‘ธ์‹œ ๋“ฑ ํŠน์ • ๋„๋ฉ”์ธ์— ๊ตญํ•œ๋˜์ง€๋Š” ์•Š๊ณ  ์ „๋ฐ˜์ ์ธ ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•ด ์ดํ•ด๋ฅผ ํ•œ๋‹ค๋ฉด ๋‹ค๋ฅธ ๊ณณ์—์„œ๋„ ๋น„์Šทํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์„๊บผ๋ผ ๊ธฐ๋Œ€ ํ•ด๋ณธ๋‹ค.


์ƒํ™ฉํŒŒ์•… ๋ฐ ๋ชฉํ‘œ

(์›ํ• ํ•œ ์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•˜์—ฌ) ๋จผ์ € ํ•„์ž๊ฐ€ ์šด์˜ํ•˜๊ณ ์žˆ๋Š” ์„œ๋น„์Šค๋ฅผ ๊ฐ„๋žตํžˆ ์†Œ๊ฐœ๋ถ€ํ„ฐ ํ•ด์•ผ๊ฒ ๋‹ค. (๊ทธ๋ ‡๋‹ค๊ณ  ํ•„์ž ํ˜ผ์ž ๋‹ค ํ•˜๋Š”๊ฑด ์•„๋‹˜^^;…) ์…€๋Ÿฝ์˜ ๋ฐฉ์†ก์ด ์‹œ์ž‘๋˜๋ฉด ๊ตฌ๋…ํ•œ ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ฐ ๋ชจ๋ฐ”์ผ ๊ธฐ๊ธฐ์— ์„ค์น˜๋˜์–ด์žˆ๋Š” ์•ฑ์œผ๋กœ ์•Œ๋ฆผ์„ ๋ณด๋‚ด์–ด ์˜ˆ์ •์— ์—†๋˜ ๊นœ์ง ๋ผ์ด๋ธŒ ๋ฐฉ์†ก์ด๋‚˜ VOD ์˜์ƒ ์˜คํ”ˆ์„ ๋ณด๋‹ค ๋น ๋ฅด๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ, ์•Œ๋ฆผ์ด ๋Šฆ๊ฒŒ ๋ฐœ์†ก๋˜๋ฉด ์…€๋Ÿฝ์€ ๋ฐฉ์†ก์„ ์‹œ์ž‘ํ•˜๊ณ  ํŒฌ๋“ค์ด ๋“ค์–ด์˜ค๊ธฐ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค๊ฑฐ๋‚˜ ๋ฐ˜๋Œ€๋กœ ํŒฌ๋“ค์€ ๋ฐฉ์†ก ์‹œ์ž‘ํ•˜๊ณ  ๋’ค๋Šฆ๊ฒŒ ๋ฐฉ์†ก์„ ๋ณด๊ฒŒ๋˜๋Š” ๋ถˆํŽธํ•จ์ด ์ƒ๊ธฐ๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ค‘๋ณต์œผ๋กœ ์•Œ๋ฆผ์ด ๋ฐœ์†ก๋˜๊ฑฐ๋‚˜ ํŠน์ • ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ ๋ฐœ์†ก์ด ๋ˆ„๋ฝ๋˜๋ฉด ์•ˆ ๋˜๋Š” ๋“ฑ “์•Œ๋ฆผ” ์ด๋ž€ ๊ธฐ๋Šฅ์€ ์„œ๋น„์Šค์— ์žˆ์–ด์„œ ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ ์ค‘์— ํ•˜๋‚˜๋ผ๊ณ  ํ• ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ “๋ฐœ์†ก ์‹œ๊ฐ„"์€ ์ฒ˜์Œ ๋ฐœ์†ก์ž‘์—… ์‹œ์ž‘๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•ด ์‚ฌ๋‚ด ๋ฐœ์†ก ํ”Œ๋žซํผ์œผ๋กœ ๋ฐœ์†ก ์š”์ฒญ์„ ํ•˜๊ธฐ๊นŒ์ง€์˜ ์‹œ๊ฐ„์„ ์˜๋ฏธ

๊ทธ๋ฆฌ๊ณ  “์ฑ„๋„” ์ด๋ผ๋Š” ์ƒ๋Ÿฝ๋‹จ์œ„์˜ ๊ทธ๋ฃน์ด ์žˆ๋Š”๋ฐ ์˜์ƒ๊ณผ ์ฑ„๋„์˜ ๊ด€๊ณ„๋Š” 1:N์ด๋‹ค. ์ฆ‰, ํ•˜๋‚˜์˜ ์˜์ƒ์„ ์—ฌ๋Ÿฌ ์ฑ„๋„์— ์—ฐ๊ฒฐ์‹œํ‚ฌ์ˆ˜ ์žˆ์–ด์„œ ํ•˜๋‚˜์˜ ์˜์ƒ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ์ฑ„๋„๋“ค์—๊ฒŒ ์—ฐ๊ฒฐ์„ ์‹œ์ผœ๋†“์œผ๋ฉด ์ฑ„๋„์„ ๊ตฌ๋…ํ•˜๊ณ ์žˆ๋Š” ๊ฐ๊ฐ์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ชจ๋‘ ์•Œ๋ฆผ์„ ๋ฐœ์†ก ํ• ์ˆ˜๊ฐ€ ์žˆ๊ฒŒ ๋œ๋‹ค.

์šฐ์„ , ์•Œ๋žŒ์ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌ๋˜๊ธฐ๊นŒ์ง€์˜ ํฐ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

/images/faster-parallel-processes/push_process.jpg
์•Œ๋ฆผ ํ”„๋กœ์„ธ์Šค
  1. ์„œ๋น„์Šค์—์„œ ๋ณด๋‚ผ ๋Œ€์ƒ๊ณผ ๋ณด๋‚ผ ์ •๋ณด๋ฅผ ์กฐํ•ฉํ•˜์—ฌ
  2. ์‚ฌ๋‚ด ํ‘ธ์‹œ ๋ฐœ์†ก ํ”Œ๋žซํผ์ธ ์‚ฌ๋‚ด ๋ฐœ์†ก ํ”Œ๋žซํผ์—๊ฒŒ ์ „๋‹ฌ์„ ํ•˜๋ฉด ํ”Œ๋žซํผ์— ๋”ฐ๋ผ ๋ฐœ์†ก์ด ๋˜๊ณ 
  3. ์ตœ์ข…์ ์œผ๋กœ๋Š” ์‚ฌ์šฉ์ž์˜ ๋ชจ๋ฐ”์ผ ๊ธฐ๊ธฐ์— ๋…ธ์ถœ์ด ๋จ

๊ฐ„๋‹จํ•˜๊ฒŒ “๋ณ‘๋ ฌ๋กœ ๋ฐœ์†กํ•˜๋ฉด ๋˜์ง€ ์•Š์„๊นŒ?“๋ผ๋Š” ํ•„์ž์˜ ์ƒ๊ฐ์ด ๋ถ€๋„๋Ÿฌ์›Œ์งˆ ์ •๋„๋กœ ์ด๋ฏธ redis, rabbitMQ ๋ฅผ ํ™œ์šฉํ•ด์„œ ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ๋ณ‘๋ ฌ ํ”„๋กœ์„ธ์Šค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์—ˆ๋‹ค.

/images/faster-parallel-processes/legacy_structure.jpg
๊ธฐ์กด ๊ตฌ์กฐ
  1. ๋ผ์ด๋ธŒ๊ฐ€ ์‹œ์ž‘๋˜๊ฑฐ๋‚˜ VOD๊ฐ€ ์˜คํ”ˆ๋  ๊ฒฝ์šฐ api๊ฐ€ ํ˜ธ์ถœ์ด ๋˜๊ณ  ๋‹ค์‹œ ๋ฐฐ์น˜ ์„œ๋ฒ„์—๊ฒŒ ์˜์ƒ์˜ ๊ณ ์œ ๋ฒˆํ˜ธ๋ฅผ ์ „๋‹ฌ
  2. ์ „๋‹ฌ๋ฐ›์€ ์˜์ƒ์˜ ๊ณ ์œ ๋ฒˆํ˜ธ๋ฅผ rabbitMQ์˜ ์ˆ˜์‹ ์ž ์กฐํšŒ Queue์— produce
  3. ์ˆ˜์‹ ์ž ์กฐํšŒ Queue์˜ consumer์ธ ์ˆ˜์‹ ์ž ์กฐํšŒ ๋ชจ๋“ˆ์—์„œ ์˜์ƒ์˜ ๊ณ ์œ ๋ฒˆํ˜ธ๋ฅผ consume ํ›„ ์•„๋ž˜ ์ž‘์—…์„ ์ง„ํ–‰ 3-1. ์˜์ƒ:์ฑ„๋„ ์€ 1:N ๊ตฌ์กฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ์ฑ„๋„์˜ ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ ์•Œ๋ฆผ์„ ๋ฐœ์†กํ•  ์ˆ˜ ์žˆ๊ณ , ์˜์ƒ์— ์—ฐ๊ฒฐ๋œ ์ฑ„๋„๋“ค์˜ user๋ฅผ db์—์„œ ๊ฐ€์ ธ์˜จ๋‹ค. 3-2. ๊ฐ€์ ธ์˜จ user๋ฅผ (์ค‘๋ณต์œผ๋กœ ์•Œ๋ฆผ์ด ๋ฐœ์†ก๋˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด) java set์— ๋‹ด๊ณ  ๋ชจ๋“  ์ฑ„๋„์„ ์กฐํšŒํ–ˆ๋‹ค๋ฉด redis์— sorted set์œผ๋กœ ๋‹ด๋Š”๋‹ค. 3-3. ์ ๋‹นํ•œ ํฌ๊ธฐ๋กœ ๋ถ„ํ• ํ•˜๊ณ  ์ด ๋ถ„ํ• ์ •๋ณด๋ฅผ ๋ฐœ์†ก Queue์— produce
  4. ๋ฐœ์†ก ๋ชจ๋“ˆ์—์„œ ๋ถ„ํ•  ์ •๋ณด๋ฅผ consume ํ•˜๊ณ  ์•„๋ž˜ ์ž‘์—…์„ ์ง„ํ–‰ (๋ณ‘๋ ฌ์ฒ˜๋ฆฌ) 4-1. redis ์—์„œ user ๋ชจ์Œ์„ ๊ฐ€์ ธ์˜ค๊ณ  4-2. ์กฐํšŒํ•œ user์— ํ•ด๋‹นํ•˜๋Š” deviceId๋ฅผ db์—์„œ ๊ฐ€์ ธ์˜ด
  5. deviceId์™€ ์ปจํ…์ธ  ์ •๋ณด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ ์ ˆํ•œ payload๋ฅผ ๊ตฌ์„ฑ ํ›„ ์‚ฌ๋‚ด ๋ฐœ์†ก ํ”Œ๋žซํผ ์—๊ฒŒ ์ „๋‹ฌ

๊ธฐ์กด ๊ตฌ์กฐ์—์„œ ๋ฐœ์†ก ์‹œ๊ฐ„์€ ์„œ๋น„์Šค์—์„œ ๊ตฌ๋…์ž ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ๋งŽ์€ ์ฑ„๋„ ๊ธฐ์ค€์œผ๋กœ ์•ฝ 1.1์ฒœ๋งŒ ๋ช…์—๊ฒŒ ์ตœ์ข… 11๋ถ„ ์ •๋„ ์†Œ์š”๋˜๊ณ  ์žˆ์—ˆ๋‹ค. (๋งจ ์ฒ˜์Œ์— ์ด์•ผ๊ธฐ ํ•œ ์ˆœ์ฐจ์ ์ธ ๋ฐฉ๋ฒ•์ด์˜€๋‹ค๋ฉด… ํ›จ์”ฌ๋” ์˜ค๋ž˜ ๊ฑธ๋ ธ์„๊บผ๋ผ ์˜ˆ์ƒํ•ด๋ณธ๋‹ค…)

2018 ํšŒ๊ณ  - Coder๊ฐ€ ์•„๋‹Œ Programmer๋กœ

๋งค์‚ฌ์— ํ–‰๋™ํ•˜๋Š” ๋ชจ๋“ ๊ฒƒ๋“ค์˜ ๋์ž๋ฝ์—์„œ๋Š” ๊ทธ๋™์•ˆ ์ž˜ํ•œ๊ฒƒ๊ณผ ๋ชปํ•œ๊ฒƒ์„ ๋‹ค์‹œ ์ƒ๊ฐํ•˜๋ฉฐ ์ž˜ํ•œ๊ฒƒ์€ ๋ณด๋‹ค ๋” ์ž˜ํ• ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ๋ชปํ•œ๊ฒƒ์€ ์™œ ๋ชปํ–ˆ๋Š”์ง€ ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋ชปํ•œ ๋ถ€๋ถ„์„ ๊ณ ์น ์ˆ˜ ์žˆ์„์ง€์— ๋Œ€ํ•œ ์‹œ๊ฐ„์„ ๊ฐ–์œผ๋ ค๊ณ  ๋…ธ๋ ฅํ•ด์™”๋‹ค. ๊ทธ๊ฒŒ ๊ฐœ๋ฐœ์ด ๋˜์—ˆ๋“  ๊ฒŒ์ž„์ด ๋˜์—ˆ๋“  ์—ฐ์ธ๊ณผ์˜ ๋ฐ์ดํŠธ๊ฐ€ ๋˜์—ˆ๋“  ๋ญ๋“ ์ง€. ์ด๋Ÿฌํ•œ ์‹œ๊ฐ„๋“ค์€ ํ•„์ž์—๊ฒŒ ํฐ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๊ณ  ์ง€๋‚œ ํ•œํ•ด๋ฅผ ๋Œ์ด์ผœ ๋ณด์ž๋ฉด ๊ฐœ์ธ์ ์œผ๋กœ ๊ณ„ํšํ•œ ์ „๋ถ€๋ฅผ ๋‹ค ์ด๋ค„๋‚ด์ง€๋Š” ๋ชปํ–ˆ์ง€๋งŒ ๋‚˜๋ฆ„์˜ ๋งŽ์€ ๊ฒฝํ—˜๊ณผ ์„ฑ๊ณผ๋ฅผ ๋‹ฌ์„ฑํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณธ๋‹ค. ์ด์ œ ๋ช‡์‹œ๊ฐ„ ๋’ค๋ฉด ์˜ฌํ•ด๊ฐ€ ๋๋‚˜๊ณ  ์ƒˆ๋กœ์šด ํ•œ ํ•ด๊ฐ€ ์‹œ์ž‘๋˜๋Š” ์ด ์‹œ์ ์— ๊ฐœ๋ฐœ์ž๋กœ์จ์˜ ํšŒ๊ณ ๋ฅผ ํ•ด๋ณด๋ฉฐ 2018๋…„ ์ •๋ฆฌ ๋ฐ 2019๋…„ ๋ชฉํ‘œ๋ฅผ ๋‹ค์งํ•ด๋ณด์ž.

๊ธ€์“ฐ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์ž. ๊ฐœ์ธ ๋ธ”๋กœ๊ทธ ์šด์˜

์•„์ฃผ ์˜ค๋ž˜์ „, ๋™๊ธฐ ํ˜•์„ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ธ€์„ ์จ์•ผํ•˜๋Š” ์ค‘์š”์„ฑ์— ๋Œ€ํ•ด ์ ˆ์‹คํ•˜๊ฒŒ ๋ฐฐ์šฐ๊ฒŒ ๋˜์—ˆ๊ณ  ๊ทธ๋•Œ๋ถ€ํ„ฐ ๋ธ”๋กœ๊ทธ๋ฅผ ์šด์˜ํ•˜๊ธฐ ์‹œ์ž‘ํ•˜์˜€๋‹ค. ๊ทธ ๋™๊ธฐํ˜•์˜ ๋ง์— ์กฐ๊ธˆ ๋” ๋‚ด ์ƒ๊ฐ์„ ์ฒจ๊ฐ€ํ•˜์ž๋ฉด ๊ธ€์„ ์“ฐ๋‹ค๋ณด๋ฉด ๋ˆ„๊ตฐ๊ฐ€ ๋‚ด ๊ธ€์„ ๋ณธ๋‹ค๋Š” ๋งˆ์Œ์— ๋‚ด๊ฐ€ ์•Œ๊ณ ์žˆ๋Š” ์ง€์‹์„ ๋ณด๋‹ค ๋” ๊นŠ๊ฒŒ ๊ณต๋ถ€ํ•˜๊ฒŒ ๋˜๊ณ  ๊ทธ๊ฒƒ๋“ค์ด ๋ชจ์—ฌ ๋‚ด ๊ฐœ๋ฐœ ํžˆ์Šคํ† ๋ฆฌ๊ฐ€ ๋งŒ๋“ค์–ด ์ง€๋ฉฐ ํฌํŠธํด๋ฆฌ์˜ค ๋“ฑ ๋‹ค์–‘ํ•˜๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ์— ๋ธ”๋กœ๊ทธ๋ฅผ ์šด์˜ํ•˜๋Š”๊ฑด ์ •๋ง ์ข‹์€ ์„ ํƒ์ง€ ์˜€๋˜๊ฒƒ ๊ฐ™๋‹ค. ์‹ค์ œ๋กœ ๊ทธ๋ƒฅ ๊ตฌ๊ธ€๋ง ํ•ด์„œ ์•Œ๊ฒŒ๋œ ๊ฒƒ๊ณผ๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฐ์›€์ด ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํšŒ์‚ฌ ์ผ ๊ทธ๋ฆฌ๊ณ  ๊ฐœ์ธ ๊ณต๋ถ€๋ฅผ ํ•˜๋ฉด์„œ ์ ์–ด๋„ ํ•œ๋‹ฌ์— ํ•œ๊ฐ€์ง€ ์ด์ƒ์€ ๋ฐฐ์šฐ๊ฒŒ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ฌํ•ด ์ดˆ ํ•œ๋‹ฌ์— ํ•œ๊ฐœ ์ด์ƒ์˜ ๊ธ€์„ ์“ฐ๊ธฐ๋กœ ๊ฒฐ์‹ฌํ•˜์˜€๋‹ค.(๊ทธ ๋‹ฌ์˜ ๊ธ€์ด ์—†๋‹ค๋ฉด ๋ญ”๊ฐ€ ๋†€์•˜๊ฑฐ๋‚˜(?) ๋ฏธ์นœ๋“ฏ์ด ๋ฐ”๋นด๊ฑฐ๋‚˜ ์•„๋‹ˆ๋ฉด ๊ฒŒ์„๋ €๊ฑฐ๋‚˜…) ๋ธ”๋กœ๊ทธ์— ๊ธ€์„ ์“ด ๋‚ด์—ญ์„ ๊ทธ๋ž˜ํ”„๋กœ ์‹œ๊ฐํ™” ํ•ด๋ณด๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ์ด 23๊ฐœ์˜ ๊ธ€์„ ์ž‘์„ฑํ•˜์˜€๊ณ  ์›” ํ‰๊ท  1.9๊ฐœ์˜ ๊ธ€์„ ์ž‘์„ฑํ•˜๊ฒŒ ๋œ๊ฒƒ์„ ๋ณผ์ˆ˜ ์žˆ๋‹ค.

9์›”๋‹ฌ์—” ํŒ€ ์˜ฎ๊ธฐ์ž๋งˆ์ž ์—„์ฒญ ๋ฐ”๋นด๊ณ , 11์›”์—” ๊ทธ ๋ฐ”์œ๊ฒŒ ๊ฒฐ์‹ค์„ ๋งบ๋Š” ์‹œ๊ฐ„… ์ด๋ผ ํ•‘๊ณ„๋ฅผ… (๋‚˜์ค‘์— ๋ธ”๋กœ๊น… ์˜ˆ์ •, ๋ณ‘๋ ฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ด€๋ จ)

/images/review-2018/post_count.jpg
์›”๋ณ„ ๊ธ€ ์ž‘์„ฑ์ˆ˜

์œ„ ๊ฒฐ๊ณผ๋งŒ์„ ๋‘๊ณ  ๋ดค์„๋• ๋งŽ์œผ๋ฉด ๋งŽ๊ณ  ์ ์œผ๋ฉด ์ ๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฐ๊ณผ์ง€๋งŒ ๊ฐœ์ธ์ ์œผ๋กœ๋Š” ์žํˆฌ๋ฆฌ ์‹œ๊ฐ„์„ ํ™œ์šฉํ•ด์„œ ๊ทธ๊ฐ„ ๋ฐฐ์› ๋˜๊ฒƒ, ๊ทธ๋ฆฌ๊ณ  ๊ฒฝํ—˜ํ–ˆ์ง€๋งŒ ๋‚ด๊ฒƒ์œผ๋กœ ๋งŒ๋“ค์ง€ ๋ชปํ•˜๊ณ  ๋ณด๊ธฐ๋งŒ ํ•˜๋ฉฐ ๋„˜์–ด๊ฐ„๊ฒƒ๋“ค์— ๋Œ€ํ•ด ๊ท€์ฐฎ์ง€๋งŒ ์‹œ๊ฐ„์„ ํˆฌ์žํ•˜๊ณ  ์ •๋ฆฌํ–ˆ๋”๋ผ๋ฉด ๋” ๋งŽ์€ ๊ธ€์„ ์ผ์„๊ฒƒ ๊ฐ™๋‹ค๋Š” ์กฐ๊ธˆ ์•„์‰ฌ์šด ๊ฒฐ๊ณผ๋ผ๊ณ  ์ƒ๊ฐ์ด ๋“ ๋‹ค.

/images/review-2018/blog_ga.jpg
์ฃผ ๋‹จ์œ„ PV, ๋ˆ„๊ตฐ๊ฐ€ ๋‚ด ๊ธ€์„ ๋ณด๊ณ  ์žˆ๋‹ค๋Š”๊ฒƒ์— ๋ฟŒ๋“ฏํ•จ

๋‚˜๋ฆ„ ์—ด์‹ฌํžˆ ๊ธ€์„ ์“ด ๊ฒฐ๊ณผ์ผ๊นŒ, GA๋ฅผ ํ†ตํ•ด ๋ณธ ํ•„์ž์˜ ๋ธ”๋กœ๊ทธ์— ์œ ์ž…๋Ÿ‰์ด ์ ์  ๋Š˜์–ด๋‚˜๋Š”๊ฒƒ์„ ๋ณด๋ฉฐ ํ•˜๋‚˜๋ฅผ ์“ฐ๋”๋ผ๋„ ์ข€๋” ์ž์„ธํžˆ ๋…์ž์˜ ์ž…์žฅ์—์„œ ์จ์•ผ๊ฒ ๋‹ค๊ณ  ๋‹ค์‹œํ•œ๋ฒˆ ๋‹ค์งํ•˜๊ฒŒ ๋œ๋‹ค. ๋‹ค๋งŒ ๊ธ€์„ “๋งŽ์ด” ์“ฐ๋Š”๊ฒƒ๋ณด๋‹ค ํ•˜๋‚˜๋ฅผ ์ž‘์„ฑํ•˜๋”๋ผ๋„ ์›์ธ๊ณผ ๊ทผ๊ฑฐ๋ฅผ ๋“ค์–ด๊ฐ€๋ฉฐ ๋ฌธ์ œ๋ฅผ ์ •ํ™•ํžˆ ํŒŒ์•…ํ•˜๋Š”๋ฐ ์ง‘์ค‘์„ ํ•ด์•ผํ•˜๊ณ , ๋‹จ์ˆœ ์‚ฌ์šฉ๋ฒ• ๋‚˜์—ด์ด ์•„๋‹Œ ์‹ค์ œ๋กœ ๊ฒฝํ—˜์„ ํ•ด๊ฐ€๋ฉด์„œ “๋‚ด๊ฒƒ"์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•˜๊ฒ ๋‹ค.

ํšŒ์‚ฌ ํŒ€ ๋ณ€๊ฒฝ ๊ทธ๋ฆฌ๊ณ  ํ† ์ด ํ”„๋กœ์ ํŠธ

๊ธฐ์กด์— ์•„๋ฌด๊ฒƒ๋„ ์—†๋˜ ํ™˜๊ฒฝ์—์„œ ์„œ๋ฒ„ ๋ฐœ๊ธ‰๋ถ€ํ„ฐ ์ด๋Ÿฐ ์ €๋Ÿฐ ์„œ๋น„์Šค์— ๋„์›€์ด ๋˜๋Š” ๋‹ค์–‘ํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง ํˆด์„ ๊ฐœ๋ฐœํ•˜๋ฉฐ ๋ฌด์‚ฌํžˆ ์„œ๋น„์Šค๋ฅผ ์˜คํ”ˆ์„ ํ•˜์˜€๊ณ , ์•ฝ๊ฐ„์˜ ๋งค๋„ˆ๋ฆฌ์ฆ˜์ด ์ƒ๊ฒจ๋‚  ์ฆˆ์Œ ์ข‹์€ ๊ธฐํšŒ๊ฐ€ ์ƒ๊ฒจ ์„ฑ๊ฒฉ์ด ์ „ํ˜€ ๋‹ค๋ฅธ ์„œ๋น„์Šค๋ฅผ ํ•˜๋Š” ํŒ€์„ ์˜ฎ๊ธฐ๊ฒŒ ๋˜์—ˆ๋‹ค. ์•ฝ๊ฐ„ ์ด์ง๊ณผ๋„ ๋น„์Šทํ•œ ๋А๋‚Œ์œผ๋กœ ํŒ€์„ ์˜ฎ๊ธฐ๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ ์ฒ˜์Œ์—” ์ƒˆ๋กœ์šด ์ง€์‹์„ ์Šต๋“ํ•ด์•ผ ํ•˜๋Š” ๋‘๋ ค์›€๋„ ์žˆ์—ˆ๊ณ  ๊ธฐ์กด ์„œ๋น„์Šค์— ์• ์ •์ด ๋งŽ์•„์„œ ๊ณ ๋ฏผ์ด ๋งŽ์•˜์ง€๋งŒ ๋ฒŒ์จ ์˜ฎ๊ธด์ง€ 5๊ฐœ์›”์ด ์ง€๋‚˜๊ณ  ๋Œ์ด์ผœ๋ณด๋ฉด ์˜ฌํ•ด ๊ฐ€์žฅ ์ž˜ํ•œ ์ผ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์•„๋‹๊นŒํ•˜๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค. ์ „ ํŒ€์—์„  ์„œ๋น„์Šค๋ฅผ ์šด์˜ํ•˜๋Š”๋ฐ ๊ทธ์ณค์ง€๋งŒ ์ง€๊ธˆ ๋‚ด๊ฐ€ ์žˆ๋Š” ๊ณณ์€ ๋Œ€์šฉ๋Ÿ‰ ์„œ๋น„์Šค๋ฅผ ์„ฑ๋Šฅ์ธก๋ฉด์—์„œ, ๊ทธ๋ฆฌ๊ณ  ์•„ํ‚คํ…์ณ ์ธก๋ฉด์—์„œ ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ๊ฐœ๋ฐœํ•˜๋Š”๋ฐ ์ง‘์ค‘์„ ํ•˜๋ ค๋Š” ๋ชจ์Šต๋“ค์ด ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”๋ถˆ์–ด ํŒ€์— ํˆฌ์ž…๋˜์ž๋งˆ์ž ํ•„์ž ํ™€๋กœ ๊ธฐ์กด์— ์žˆ๋˜ ๋ณ‘๋ ฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ฐœ์„ ํ•˜์—ฌ ์„œ๋น„์Šค์ ์œผ๋กœ ์•ฝ 90%์˜ ๊ฐœ์„ ํšจ๊ณผ๋ฅผ ๋ณผ์ˆ˜์žˆ์—ˆ๋Š”๋ฐ ์ด ๋ถ€๋ถ„์€ ์ถ”ํ›„ ํฌ์ŠคํŒ… ํ•  ์˜ˆ์ •์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํŒ€์„ ์˜ฎ๊ธฐ๊ธฐ ํ•œ๋‘๋‹ฌ ์ „ ๊ฐœ์ธ์ ์ธ ์—ฌ์œ ์‹œ๊ฐ„์ด ๋งŽ์ด ์žˆ์—ˆ๊ณ , ๋‹ค๋ฅธ์‚ฌ๋žŒ๋“ค์˜ ๋ธ”๋กœ๊ทธ๋ฅผ ๋ณด๋ฉฐ ์ฑ™๊ฒจ๋ณด๊ณ  ์‹ถ์€ ๋งˆ์Œ์— ํ† ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜์—ˆ๋‹ค. 7์›” ์ค‘์ˆœ๋ถ€ํ„ฐ ์‹œ์ž‘ํ–ˆ์œผ๋‹ˆ ์ด๊ฒƒ๋„ ์–ด๋А๋ง ๋ฐ˜๋…„์ด ์ง€๋‚˜๊ณ  ์žˆ๋Š”๋ฐ ์šด์˜์„ ํ•ด๊ฐ€๋ฉด์„œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ์ข…์ข… ๋ฐค์„ ์ƒˆ๋Š” ๋“ฑ ์˜ฌ ํ•œํ•ด์žˆ์–ด ๊ฝค ๋งŽ์€๊ฒƒ์„ ์–ป์„์ˆ˜ ์žˆ์—ˆ๋˜ ์‹œ๊ฐ„์ด์˜€๋‹ค. ๊ฐ„ํ˜น ๋ฒ„๊ทธ๊ฐ€ ์ƒ๊ฒจ ๋ฉ”์ผ์ด ๋ฐœ์†ก ์•ˆ๋˜๋ฉด ์ง€์ธ ๋˜๋Š” ๋ชจ๋ฅด๋Š” ๋ถ„๋“ค์ด ๋ฉ”์ผ๋กœ ์ œ๋ณด๋„ ํ•ด์ฃผ์‹œ๊ณ  … ์ƒ‰๋‹ค๋ฅธ ๊ฒฝํ—˜์ด์˜€๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ ๋ฐ ํ›„๊ธฐ๋Š” ๊ฐœ๋ฐœํ›„๊ธฐ-1 ๊ณผ ๊ฐœ๋ฐœํ›„๊ธฐ-2์—์„œ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค. (์–ด์„œ 3ํŽธ์„ ์“ฐ๊ณ  ๋งˆ๋ฌด๋ฆฌ๋ฅผ ์ง€์–ด์•ผ ํ• ํ…๋ฐ…) ๊ทธ๋ฆฌ๊ณ  ์ตœ๊ทผ์—๋Š” ์•„์นด์ด๋น™ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด ๊ณผ๊ฑฐ ๊ธ€์„ ์กฐํšŒํ• ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์—ˆ๋Š”๋ฐ 2% ๋ถ€์กฑํ•œ ๋А๋‚Œ์ด๋‹ค… (๋ง˜๊ฐ™์•„์„œ๋Š” ํ˜•ํƒœ์†Œ ๋ถ„์„์„ ํ•ด์„œ ์ž๋™ ํ•„ํ„ฐ๋ง๋„ ํ•ด๋ณด๊ณ  ์‹ถ์€๋ฐ…)