nGrinder
์ฌ๋ด ๋ฌธ์๋ก ์์ฑํ ๊ธ์ด๋ค.
nGrinder๋ ๋ค์ด๋ฒ๊ฐ Grinder๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ๋ฐํ ๋ถํ ํ ์คํธ ๋๊ตฌ์ ๋๋ค. ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํด ํ๊ฒ ์๋ฒ์ ๋ถํ๋ฅผ ๋ฐ์์ํค๊ณ , ์ด๋ฅผ ๋ชจ๋ํฐ๋งํ ์ ์์ต๋๋ค.
์ํคํ ์ฒ
nGrinder๋ ์ปจํธ๋กค๋ฌ์ ์์ด์ ํธ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ์ปจํธ๋กค๋ฌ๋ ํ ์คํธ ํ๋ก์ธ์ค๋ฅผ ๊ตฌ์ฑํ๊ณ ํต๊ณ๋ฅผ ๋ด๋ฉฐ ์น ui๋ฅผ ์ ๊ณตํฉ๋๋ค. ์์ด์ ํธ๋ ์ค์ ํ๊ฒ์ ๋ถํ๋ฅผ ๋ฐ์์ํค๋ ์ญํ ์ ํฉ๋๋ค. ์์ด์ ํธ๋ฅผ ์คํํ๋ฉด ์ปจํธ๋กค๋ฌ์ ์ฐ๊ฒฐ์ ์๋ํ๋ฉฐ, ์ปจํธ๋กค๋ฌ๋ ์์ด์ ํธ ์ปจํธ๋กค๋ฌ ์๋ฒ๋ฅผ ํตํด ์์ด์ ํธ ํ์ ๊ด๋ฆฌํฉ๋๋ค.
ํ๋์ nGrinder ์ปจํธ๋กค๋ฌ์์ ํ ์คํธ๋ฅผ ์คํํ๋ฉด ์ฌ๋ฌ ์์ด์ ํธ์๊ฒ ํ ์คํธ ์คํฌ๋ฆฝํธ๋ฅผ ๋ฐฐํฌํด ๊ฐ์ ํ ์คํธ๋ฅผ ์คํํ๊ฒ ๋ฉ๋๋ค.
์ปจํธ๋กค๋ฌ๋ ์๋์ ๊ฐ์ ํฌํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค:
- 80: ์ปจํธ๋กค๋ฌ์ ๊ธฐ๋ณธ ์น UI ํฌํธ
- 9010-9019: ์์ด์ ํธ๊ฐ ์ปจํธ๋กค๋ฌ ํด๋ฌ์คํฐ์ ์ ์ํ๋ ํฌํธ
- 12000-12029: ์ปจํธ๋กค๋ฌ๊ฐ ๋ถํ ํ ์คํธ๋ฅผ ํ ๋นํ๋ ํฌํธ
์ค์น
์ค์น๋ ๋์ปค๋ฅผ ์ฐ๋ ๊ฒ ์ ์ ๊ฑด๊ฐ์ ์ด๋ก์ ์ต๋๋ค. (์๋ ์ค์น๋ war ํ์ผ์ ๋ค์ด๋ฐ์ ์๋ฐ๋ฅผ ์ด์ฉํด ์คํํ๋ฉด ๋ฉ๋๋ค: https://github.com/naver/ngrinder/releases)
๋์ปค๋ฅผ ์ฌ์ฉํด ์ปจํธ๋กค๋ฌ๋ฅผ ์ค์นํฉ๋๋ค: https://hub.docker.com/r/ngrinder/controller/
$ docker pull ngrinder/controller:3.4
$ docker run -d -v ~/ngrinder-controller:/opt/ngrinder-controller -p 80:80 -p 16001:16001 -p 12000-12009:12000-12009 ngrinder/controller:3.4
์ด์ด์ ์์ด์ ํธ๋ฅผ ์ค์นํ๊ธฐ ์ ์ ์ปจํธ๋กค๋ฌ์ ip๋ฅผ ํ์ธํฉ๋๋ค.
$ docker exec {id} ip addr show eth0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
์์ด์ ํธ๋ฅผ ์ค์นํฉ๋๋ค. {controller_ip}:{controller_web_port}
๋ ์ง์ ์
๋ ฅํด์ผ ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ controller_ip
๋ ์์์ ํ์ธํ 172.17.0.2์ด๊ณ , ๊ธฐ๋ณธ ํฌํธ๋ 16001์ด๋๊น 172.17.0.2:16001
์ ์
๋ ฅํฉ๋๋ค.
$ docker pull ngrinder/agent:3.4
$ docker run -v ~/ngrinder-agent:/opt/ngrinder-agent -d ngrinder/agent:3.4 {controller_ip}:{controller_web_port}
์ค์
~/ngrinder-agent
์ __agent.conf
ํ์ผ์ ์์ฑํ๋ฉด ๊ธฐ๋ณธ ์ค์ ์ ๋ฎ์ด ์์ธ ์ ์์ต๋๋ค:
common.start_mode=agent
agent.controller_host=172.17.0.2
agent.controller_port=16001
#agent.region=
#agent.host_id=
#agent.server_mode=true
# provide more agent java execution option if necessary.
#agent.java_opt=
# set following false if you want to use more than 1G Xmx memory per a agent process.
#agent.limit_xmx=true
# please uncomment the following option if you want to send all logs to the controller.
#agent.all_logs=true
# some jvm is not compatible with DNSJava. If so, set this false.
#agent.enable_local_dns=false
์์ด์ ํธ๋ฅผ ๋์ฐ๋ฉด ~/ngrinder-agent
ํ์์ .ngrinder-agent
๋๋ ํ ๋ฆฌ๊ฐ ๋ง๋ค์ด์ง๋๋ค. ์ฌ๊ธฐ์ ์๋ agent.conf
ํ์ผ์ ์์ ํ์ง ์๊ณ ์์ด์ ํธ๋ฅผ ๋์ฐ๋ฉด __agent.conf
์ค์ ์ ๋ฐ๊ฟ๋ ๋ฐ์๋์ง ์๋ ๊ฒฝ์ฐ๊ฐ ์์ผ๋ ์ค์ ์ ๋ณ๊ฒฝํ ๊ฒฝ์ฐ ์ฃผ์ํด์ผ ํฉ๋๋ค.[1]
์คํ
์ปจํธ๋กค๋ฌ๋ฅผ ๋์ฐ๋ฉด 127.0.0.1:80
์์ ์น ui๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ์ผ๋ก ์ค์ ๋ ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ admin
์
๋๋ค. ๋ก๊ทธ์ธ ํ ์ฒซ ํ๋ฉด์์ URL์ ์
๋ ฅํ๋ฉด ํด๋น ์๋ฒ๋ฅผ ํฅํ ๋ถํ ํ
์คํธ ์ค์ ํ์ด์ง๊ฐ ๋ํ๋ฉ๋๋ค.
vuser(viertual user)๋ ๋์ ์ ์์ ์๋ฅผ ๋ปํ๋ฉฐ, ๊ฐ๊ฐ์ vuser๋ ์๋ฒ๋ก๋ถํฐ ์๋ต์ ๋ฐ๋ ์ฆ์ ๋ค์ ์์ฒญ์ ๋ณด๋
๋๋ค. vuser = agent * processes * threads
์
๋๋ค. vuser ์
๋ ฅ ํ๋ ์ค๋ฅธ์ชฝ์ ์๋ โ+โ ๋ฒํผ์ ๋๋ฅด๋ฉด ํ๋ก์ธ์ค์ ์ฐ๋ ๋๋ก vuser ์๋ฅผ ์กฐ์ ํ ์๋ ์์ต๋๋ค. ์์ด์ ํธ ํ๋ ๋น vuser์ ์ต๋์น๋ 3000์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋๊ธฐ๊ณ ์ถ์ผ๋ฉด ์์ด์ ํธ๋ฅผ ๋ ๋์์ผ ํฉ๋๋ค.
vuser ramp-up๋ ๊ฐ๋ฅํฉ๋๋ค. ์ ์ค์ ์์๋ ์ฐ๋ ๋๋ฅผ ๊ธฐ์ค์ผ๋ก 1000ms๋ง๋ค vuser๋ฅผ 2์ฉ ๋๋ฆฝ๋๋ค. (ํ๋ก์ธ์ค๋ ๋น์ผ ๋ฆฌ์์ค์ด๊ธฐ ๋๋ฌธ์ ํ๊ณ๊ฐ ์์ต๋๋ค. nGrinder 3.3๋ถํฐ ์ฐ๋ ๋ ramp-up์ ์ง์ํ๊ธฐ ์์ํ๋ค๊ณ ํฉ๋๋ค.) ํ ์คํธ ์๊ฐ์ 1๋ถ์ผ๋ก ์ค์ ํ๊ธฐ ๋๋ฌธ์ vuser ์ต๋์น์ ๋๋ฌํ๋ ์๊ฐ์ด 1๋ถ์ ๋์ง ์๋๋ก ํ์ต๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ์๋ฒ๊ฐ ์ด๋ ์์ ๋ถํฐ ์๋ฌ๋ฅผ ์ผ์ผํค๋์ง ์ ์ ์์ต๋๋ค.
๊ฒฐ๊ณผ
ํ ์คํธ๊ฐ ๋๋๋ฉด ํต๊ณ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
TPS(Transactions Per Second)๊ฐ ์ผ์ ํ๊ฒ ๋์์ต๋๋ค. vuesr๊ฐ 489๋ช ์ด ๋ 24์ด์์ ์ต์ด ์๋ฌ ๋ ๊ฐ๋ฅผ ํ์ธํ์ต๋๋ค. TPS๋ ์ด๋น ์์ฒญ์ ๋ช ๊ฐ ์ฒ๋ฆฌ ํ๋์ง ์๋ฏธํ๊ธฐ ๋๋ฌธ์ ์์ฒญ ํ๋์ ์ฒ๋ฆฌ ์๋๊ฐ 1์ด๋ฅผ ๋๊ธด๋ค๋ฉด TPS๊ฐ ์ ์ฒด ์์ฒญ ๊ฐ์๋ณด๋ค ๋ฎ๊ฒ ๋ํ๋ฉ๋๋ค.
ํ
์คํธ ๋ก๊ทธ๋ ~/ngrinder-controller/perftest/0_999
๋๋ ํ ๋ฆฌ์ ํ์ ๋๋ ํ ๋ฆฌ์ ๋ถ๋ฅ๋์ด ์์
๋๋ค.
์คํฌ๋ฆฝํธ
์คํฌ๋ฆฝํธ๋ฅผ ์ง์ ์์ฑํด ํ ์คํธ๋ฅผ ์์ ํ ์๋ ์์ต๋๋ค. jython๊ณผ groovy๋ฅผ ์ง์ํ๋ฉฐ, ํ๋ก์ธ์ค/์ค๋ ๋ ์์ ์ , ํ ์คํธ ์คํ ์ค ๋์์ ์ ์ํ ์ ์์ต๋๋ค. grinder ํํ์ด์ง์ ๋ค์ํ ์คํฌ๋ฆฝํธ ์์๋ค์ด ์์ต๋๋ค: http://grinder.sourceforge.net/g3/script-gallery.html
(+) AWS Elastic Beanstalk
์์ CloudFront(CF)๋ฅผ ๋์์ผ๋ก ๋ถํ ํ ์คํธ๋ฅผ ํ๋๋ฐ ์์ํ ๊ทธ๋ํ๊ฐ ๋์ค์ง ์์ ์ค์ ์ ์๋ชปํ๋ค๊ณ ์๊ฐํ์ต๋๋ค. ์๋ฌ๊ฐ ํ ๋ฒ ์์๋๋ฉด TPS๊ฐ ๊ธ๋ฝํด์ผ ํ๋๋ฐ ๊ทธ๋ ์ง ์์์ต๋๋ค.
๊ทธ๋์ Elastic Beanstalk(EB)๋ฅผ ์ด์ฉํด ํ ์คํธํด๋ดค์ต๋๋ค. EB๋ ์ฝ๊ฒ ์น์ฑ์ ๋ฐฐํฌ, ๋ชจ๋ํฐ๋งํ ์ ์๋ ํ๊ฒฝ์ ์ ๊ณตํฉ๋๋ค. EB๋ฅผ ์์ฑํ๋ฉด EC2 ๊ฐ์ ๋จธ์ ์ ๋ง๋ค์ด ์ถ๊ฐ์ ์ธ ์ค์ ์์ด ๋ฐ๋ก ์น์ฑ์ ๋ฐฐํฌํด์ค๋๋ค.
์ฌ๊ธฐ์๋ nGrinder ์ค์ ์ ํ์ธํ๊ธฐ ์ํด์๋ง ์ฌ์ฉํ๋๋ฐ, ๋ถํ ํ ์คํธ๋ฅผ ์ํด ํน์ ์๋น์ค์ mock ์๋ฒ๋ฅผ ๊ตฌ์ถํ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ๋ฉด ๋ ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
CF์ ๋ค๋ฅด๊ฒ ์๋ฌ ๋ฐ์ ์์ ๋ถํฐ ์๋ต์ด ๋์์ค์ง ์๊ณ ํ์์์๋ผ TPS ๊ทธ๋ํ๊ฐ ์์๋๋ก ๋์์ต๋๋ค. CF์์ ๋ก๋๋ฐธ๋ฐ์ฑ์ด ์ ๋ผ์ ๊ทธ๋ฐ๊ฑธ๊นโฆ๋ผ๊ณ ์ถ์ธกํ๊ณ ์์ต๋๋ค.
ํ๊ธฐ
ํ ์คํธ 1
- ๋๋ค ์ฃ์ง๋ฅผ ์ด์ฉํด ์ธ๋ค์ผ ์์ฑ ๊ธฐ๋ฅ์ ๋ง๋ค์๋ค.[2] ๊ฐ์๊ธฐ ํธ๋ํฝ์ด ๋ชฐ๋ฆด ์ํฉ์ ๋๋นํด ๋ถํ ํ ์คํธ๋ฅผ ํ๋ค.
- dummy thumbnail์ CloudFront ์ฃผ์๋ก 3๋ถ๊ฐ 30๋ง๊ฐ ์์ฒญ์ ๋ณด๋๋ค.
- ์๋ฌ๊ฐ ์์์ง๋ฉฐ ํ ์คํธ๊ฐ ์ค๋จ๋๋ค. ์ ์ด๋ ๊ฒ ๋นจ๋ฆฌ ์ฃฝ์ง?
ํ ์คํธ 2
- ๋ด๊ฐ ๋ญ๊ฐ ์ค์ ์ ์๋ชปํ๋ ์ถ์ด์ ๋ค์ด๋ฒ cdn์ผ๋ก ๊ฐ์ ์์ฒญ์ ๋ณด๋๋ค.
- ์ด๋์ ๋ ๋๋๊น ์๋ฌ๊ฐ ์์์ก๋ค. ๊ทธ๋๋ ๋ ์ค๋ ๋ฒํ ผ๋ค.
ํ ์คํธ 3
- ์ด๋ ์ ๋์์ ์ฃฝ๋๊ฑด์ง ๊ถ๊ธํด์ ramp-up ๋ฐฉ์์ผ๋ก CloudFront ์ฃผ์์ ์์ฒญ์ ๋ณด๋๋ค.
- 1000ms๋ง๋ค vuser๋ฅผ 1์ฉ ์ฌ๋ ธ๋ค. ์ด๋ ์ง์ ์์ ์๋ฒ๊ฐ ์ฃฝ๋์ง ์๊ฒ ๋๋ค.
- ๊ทผ๋ฐ ๋ณดํต์ ์๋ฌ๊ฐ ๋จ์ด์ง๊ธฐ ์์ํ๋ฉด ๊ทธ๋ํ๊ฐ ๋ ๋จ์ด์ง๋ค๋๋ฐ, cf๋ ๊ทธ๋ ์ง ์์๋ค. ์๋ฌ๊ฐ ๋๋๋ฐ๋ ๊ณ์ ์๋ต์ด ์ค๊ธดํ๋ค. aws๊ฐ load balancing์ด๋ auto scalingํด์ ๊ทธ๋ฐ๊ฐ? ngrinder ์ค์ ์ ์๋ชปํ๋?
ํ ์คํธ 4
- AWS Elastic Beanstalk์ node ์๋ฒ๋ฅผ ๋ง๋ค๊ณ ๊ฐ์ ํ ์คํธ๋ฅผ ๋๋ ธ๋ค.[3]
- ์์๋๋ก ์๋ฌ๊ฐ ๋๋ ์์ ์ tps(transaction per second)๊ฐ ๋ ๋จ์ด์ง๊ณ ์๋ต์ด ์ ํ ์ค์ง ์์๋ค.
- ngrinder ์ค์ ์ ๋ฌธ์ ๊ฐ ์๋ค๋ ๊ฑธ ํ์ธํ๋ค. ๊ทธ๋ฅ cf๊ฐ ํน์ดํ๋ฏ.
๊ฒฐ๋ก
- ์๊ณ ๋ณด๋ CloudFront๋ ๊ธฐ๋ณธ ์ด๋น 100,000๊ฑด ์ ํ์ด ์์๋ค.[4]
- cf์ ์บ์๋ ์ดํ์๋ tps๊ฐ ๋์์ก๋ค. ์ด์ ๋๋ฉด ์๋น์คํ๋๋ฐ ๋ฌธ์ ๊ฐ ์์ ๊ฒ์ด๋ผ๊ณ ํ๋จํ๋ค.
์ฐธ๊ณ ์๋ฃ
์ด ๋ฌธ์๋ฅผ ์ธ์ฉํ ๋ฌธ์
๋ฐฐ์์ต, โnGrinder agent๊ฐ controller์ ๋ชป๋ถ๋ ํ์โ, ์์ด๋จ์ ์ด๋๊ฐ์๊น, 2018. โฉ๏ธ
Jinho Hong, โLambda ํ๊ฐ๋ก ๋ง๋๋ On-demand Image Resizingโ, Huiseoul Engineering, 2018. โฉ๏ธ
๊ถ์ฉ๊ทผ, โ๊ฒฐ์ ์์คํ ์ฑ๋ฅ, ๋ถํ, ์คํธ๋ ์ค ํ ์คํธโ, ์ฐ์ํํ์ ๋ค ๊ธฐ์ ๋ธ๋ก๊ทธ, 2018. โฉ๏ธ
โAmazon CloudFront - ํ๋โ, AWS ์ค๋ช ์, 2016. โฉ๏ธ