/images/profile.png

์—˜๋ผ์Šคํ‹ฑ์„œ์น˜ 12์›” ์„œ์šธ ๋ฐ‹์—… ํ›„๊ธฐ

์—˜๋ผ์Šคํ‹ฑ์„ ์ฒ˜์Œ ์ ‘ํ•˜๊ฒŒ ๋œ ๊ฑด 2017๋…„ ์—ฌ๋ฆ„ facebook ํ”ผ๋“œ์— “Elastic Stack์„ ์ด์šฉํ•œ ์„œ์šธ์‹œ ์ง€ํ•˜์ฒ  ๋Œ€์‹œ๋ณด๋“œ” ๋ผ๋Š” ๋งํฌ๋ฅผ ๋ณด๊ฒŒ ๋œ ๊ฒƒ๋ถ€ํ„ฐ์ธ ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ ๋‹น์‹œ ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋ฐ ์ž๋™ํ™”์— ๊ด€์‹ฌ์ด ์ปค์ง€๊ณ  ์žˆ๋˜ ์ฐฐ๋‚˜์˜€๋Š”๋ฐ ํ‚ค๋ฐ”๋‚˜๋กœ ๊ฐ„๋‹จํ•˜๋ฉด์„œ๋„ ์•„์ฃผ ๋ฉ‹์ง„ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒŒ ๋„ˆ๋ฌด ํฅ๋ฏธ๋กญ๊ฒŒ ๋‹ค๊ฐ€์™”๊ณ  ๊ฑฐ๊ธฐ๋‹ค ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ณผ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ๊ณต๋ถ€๋ฅผ ์‹œ์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์—†์—ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ์ด๊ฒƒ์ €๊ฒƒ ๋งŒ๋“ค์–ด ๋ณด๊ธฐ๋„ ํ•˜๊ณ  ํ•œ๊ตญ ์—˜๋ผ์Šคํ‹ฑ์„œ์น˜ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ๋™์„ ํ•ด์˜ค๋˜ ์ฐฐ๋‚˜ (์ตœ๊ทผ๋“ค์–ด ๋ˆˆํŒ…๋งŒ ํ•˜๊ณ  ์žˆ์ง€๋งŒ…) ์˜ฌํ•ด ๋งˆ์ง€๋ง‰ ๋ฐ‹์—…์„ ํ•œ๋‹ค๊ณ  ํ•˜์—ฌ ์ฐธ์—ฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

์—ฌ๊ธฐ์–ด๋•Œ ๋ณธ์‚ฌ ๋ฐฉ๋ฌธ

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

/images/elastic-meetup-201812/elastic_1.jpg
‘์—ฌ๊ธฐ์–ด๋•Œ’ ๋ณธ์‚ฌ๊ฑด๋ฌผ์—์„œ ์—˜๋ผ์Šคํ‹ฑ ๋ฐ‹์—…์„!

์—˜๋ผ์Šคํ‹ฑ์„œ์น˜ 6.5 ์ตœ์‹ ๋ฒ„์ „ ์†Œ๊ฐœ ๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ ํšŒ๊ณ 

ํ–‰์‚ฌ ์ฒ˜์Œ ์„ธ์…˜์œผ๋กœ ๊น€์ข…๋ฏผ ์ปค๋ฎค๋‹ˆํ‹ฐ ์—”์ง€๋‹ˆ์–ด ๋ถ„๊ป˜์„œ ์—˜๋ผ์Šคํ‹ฑ์˜ ์ตœ๊ทผ ์—…๋ฐ์ดํŠธ ์ •๋ณด์™€ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ๋™์— ๋Œ€ํ•ด์„œ ํšŒ๊ณ ํ•ด์ฃผ์…จ๋‹ค. ๋‚ด๊ฐ€ ์ฒ˜์Œ ์—˜๋ผ์Šคํ‹ฑ์„œ์น˜๋ฅผ ์ ‘ํ•œ ๋ฒ„์ „์ด 2.4์˜€๋Š”๋ฐ ๋ฒŒ์จ 6.5๋ผ๋‹ˆ… ๋นจ๋ผ๋„ ๋„ˆ๋ฌด ๋น ๋ฅด๋‹ค. ์ด๋ฒˆ ๋ฒ„์ „์—์„œ๋Š” ํ•œ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ๋กœ์˜ ์ธ๋ฑ์Šค๋ฅผ ๋ณต์ œํ•˜๋Š” ๋ฐฉ๋ฒ•์ธ Cross-cluster replication (ํด๋Ÿฌ์Šคํ„ฐ ๋ณต์ œ) ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ๊ณ  ODBC Client ์ถ”๊ฐ€, ์ž๋ฐ” 11์ง€์› ๋“ฑ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค. ํŠนํžˆ ํ‚ค๋ฐ”๋‚˜์—์„œ๋Š” ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ถ„์„ํ•ด์„œ ์ธ๋ฑ์‹ฑ์„ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ๋„ ์ƒ๊ฒผ๊ณ  (ํŒŒ์ผ ํฌ๊ธฐ๊ฐ€ 100๋ฉ”๊ฐ€ ์ œํ•œ์ด๋ผ๋Š”๊ฒŒ ์‚ด์ง ์•„์‰ฝ๊ธด ํ–ˆ๋‹ค.) ์บ”๋ฒ„์Šค, ์ŠคํŽ˜์ด์Šค ๋“ฑ ์—ญ์‹œ ํ‚ค๋ฐ”๋‚˜ ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค ์ •๋„๋กœ ๋น„์ฃผ์–ผ๋ผ์ด์ง•์„ ํ•œ๋ฒˆ๋” ์—…๊ทธ๋ ˆ์ด๋“œ ํ•œ๋“ฏ ํ•˜๋‹ค. (๋‹ค ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„๊นŒ ํ•˜๋Š” ์ •๋„๋กœ… ์—˜๋ผ์Šคํ‹ฑ ์Šคํƒ์„ ๋“ค์–ด๋ณด๊ธฐ๋งŒ ํ•˜๋˜ ํ•จ๊ป˜ ์ฐธ์„ํ•œ ๋™๊ธฐ ๋…€์„๋„ ๋‹น์žฅ ํ•ด๋ณด๊ฒ ๋‹ค๊ณ  ํ•  ์ •๋„๋กœ…) ๋‹ค๋ฅธ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์—ฌ๊ธฐ์„œ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

/images/elastic-meetup-201812/elastic_2_1.jpg
๋„ˆ๋ฌด๋‚˜ ๋น ๋ฅธ ๋ฒ„์ „์—…๊ณผ ๋„ˆ๋ฌด๋‚˜ ๋ฐœ๋น ๋ฅด๊ฒŒ ์›€์ง์ด๋Š” ์‚ฌ๋žŒ๋“ค

์—˜๋ผ์Šคํ‹ฑ์„œ์น˜ ํ™œ์šฉ์‚ฌ๋ก€

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

/images/elastic-meetup-201812/elastic_2_2.jpg
์Šค๋งˆ์ผ๊ฒŒ์ดํŠธ + ์—ฌ๊ธฐ์–ด๋•Œ

๋งˆ์น˜๋ฉฐ

์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ๋™ ํšŒ๊ณ  ์‹œ๊ฐ„์— ๋ˆ„๊ฐ€ ํŽ˜์ด์Šค๋ถ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ “๊ณต์œ "๋ผ๋Š” ๋‹จ์–ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฒŒ์‹œ๊ธ€์„ ์ž‘์„ฑํ–ˆ๋Š”์ง€ ํ‚ค๋ฐ”๋‚˜๋กœ ๋ณด์—ฌ์ฃผ๊ณ  ๋ฐ‹์—…์— ์˜จ ์‚ฌ๋žŒ์ด ์žˆ๋‹ค๋ฉด 5๋งŒ์› ์—ฌ๊ธฐ์–ด๋•Œ ์ฟ ํฐ์„ ์ค€๋‹ค๊ณ  ํ–ˆ์—ˆ๋‹ค. ๋งˆ์นจ ํ‚ค๋ฐ”๋‚˜ ๋Œ€์‹œ๋ณด๋“œ ํ•œ์ชฝ ๊ตฌ์„์— ํ•„์ž์˜ ์ด๋ฆ„์ด ๋ณด์˜€์ง€๋งŒ (์˜ˆ์ „์— ๋‚˜๋ฆ„ ํ™œ๋ฐœํ•˜๊ฒŒ ์งˆ๋ฌธ๋„ ํ•˜๊ณ  ๊ณต์œ ๋„ ํ–ˆ๋˜ ์ ์ด ์žˆ์–ด์„œ…) ์ฟ ํฐ์„ ๋ฐ›๋Š”๊ตฌ๋‚˜ ํ•˜๋ฉฐ ๊ธฐ๋Œ€๋ฅผ ํ•˜๊ณ  ์žˆ์—ˆ์ง€๋งŒ ์•„์‰ฝ๊ฒŒ๋„ ์ตœ๊ทผ์— ์ž‘์„ฑํ•œ ๋ช‡ ๋ถ„์—๊ฒŒ๋งŒ ์„ ๋ฌผ์ด ๋Œ์•„๊ฐ”๋‹ค… ํ•˜์ง€๋งŒ ๊ทธ ์•„์‰ฌ์›€๋„ ์ž ์‹œ, ๋ฌด์ž‘์œ„๋กœ ์ถ”์ฒจํ•˜์—ฌ ๋˜ ์ฟ ํฐ์„ ์ค€๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ ๋‹น์ฒจ์ด ๋˜์–ด์„œใ…Žใ…Ž ๊ฐ์‚ฌํ•˜๊ฒŒ๋„ ์ฟ ํฐ์„ ๋ฐ›๋Š” ๊ธฐ์จ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ์—ˆ๋‹ค!!

/images/elastic-meetup-201812/elastic_3.jpg
์—ญ์‹œ ๋ฐ‹์—…์˜ ๋งˆ๋ฌด๋ฆฌ๋Š” ๊ตฟ์ฆˆ๋ชจ์Œ์ด์ง€(?)

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

Jenkins ์„ค์น˜ ์น˜ํŠธํ‚ค

“show me the money”, “black sheep wall”. ์–ด๋ ธ์„์  ์Šคํƒ€ํฌ๋ž˜ํ”„ํŠธ๋ผ๋Š” ๊ฒŒ์ž„์ด ๋‚˜์˜ค๊ณ ์„œ ์ž…์— ๋‹ฌ๊ณ  ์‚ด์•˜๋˜ ์น˜ํŠธํ‚ค. ๊ฒŒ์ž„์ด ์‹œ์ž‘๋˜๊ณ  ํ•ด๋‹น ์น˜ํŠธํ‚ค๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋ˆ์ด ๋“ค์–ด์˜ค๊ฑฐ๋‚˜ ๋งต์ด ํ›คํ•˜๊ฒŒ ๋ณด์—ฌ ์ปดํ“จํ„ฐ๋ฅผ ์ด๊ธฐ๋Š”๋ฐ ๋„์›€์„ ์ฃผ๊ณค ํ–ˆ์—ˆ๋‹ค. ๊ฐœ๋ฐœ์„ ํ•˜๋ฉด์„œ Jenkins๋Š” ๋‚˜ ๋Œ€์‹  ์–ด๋–ค ์—…๋ฌด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ๊ฐ•๋ ฅํ•œ ํˆด ์ค‘์— ํ•˜๋‚˜์ด๋‹ค. (๋ฌผ๋ก  ๋งŒ๋Šฅ์ด๋ผ๋Š” ์†Œ๋ฆฌ๋Š” ์•„๋‹ˆ์ง€๋งŒ…) ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๊ฐ€ ์‹œ์ž‘๋˜๊ฑฐ๋‚˜ ๊ฐœ๋ฐœ๋„์ค‘ ๋ฌด์–ธ๊ฐ€ ์ž๋™ํ™”๋ฅผ ํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ์—” Jenkins๋ฅผ ์ฐพ๊ฒŒ ๋˜๋Š”๋ฐ ๊ทธ๋Ÿด๋•Œ๋งˆ๋‹ค ์„ค์น˜๋ฅผ ํ•˜๊ณ  ์ด๋Ÿฐ์ €๋Ÿฐ ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค. ๋ˆˆ์น˜๋ฅผ ์ฑ˜์„์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ด ํฌ์ŠคํŠธ๋Š” ์˜ค๋กœ์ง€ ์  ํ‚จ์Šค ์„ค์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•„์ฃผ ๊ฐ„๋‹จํ•˜๊ณ  ํ•ต์‹ฌ๋งŒ ์ •๋ฆฌํ•˜๊ณ ์ž ํ•œ๋‹ค. ๋งˆ์น˜ ์น˜ํŠธํ‚ค์ฒ˜๋Ÿผ. ๋‚˜์ค‘์— ๋‹ค์‹œ ๋ณด๊ธฐ์œ„ํ•ด + ๋ˆ„๊ตฐ๊ฐ€ ํ•ด๋‹น ํฌ์ŠคํŠธ๋ฅผ ๋ณด๊ณ  ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ํ•˜๋Š” ๋ฐ”๋žŒ์œผ๋กœ.

(๋ฌผ๋ก  ์ด ๋ฐฉ๋ฒ•๋ฐ–์— ์žˆ๋Š”๊ฑด ์•„๋‹ˆ์ง€๋งŒ ํ•„์ž๋Š” ์•„๋ž˜์™€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.)


์šฐ์„  CentOS ํ™˜๊ฒฝ์— Java๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๋Š” ์ƒํ™ฉ์ด๋ผ ๊ฐ€์ •ํ•œ๋‹ค.

  • ์ ๋‹นํ•œ ์œ„์น˜์— tomcat ๋‹ค์šด ( https://tomcat.apache.org/download-80.cgi )
    wget {์••์ถ•ํŒŒ์ผ ๋‹ค์šด๊ฒฝ๋กœ, ํ•„์ž๋Š” apache-tomcat-8.5.35 }
    
  • ์••์ถ• ํ•ด์ œํ›„ ํ•˜์œ„ ํด๋”์ค‘ webapps๋กœ ์ด๋™
    tar -zxvf apache-tomcat-8.5.35.tar.gz
    cd apache-tomcat-8.5.35/webapps
    
  • Jenkins ๋‹ค์šด ( https://jenkins.io/download/ )
    wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war
    
  • tomcat ํ•˜์œ„ํด๋”์ค‘ conf ํด๋”๋กœ ์ด๋™
    cd ../conf
    
  • server.xml ์ˆ˜์ • ๋ฐ http port ํ™•์ธ
    vi server.xml
    
    <Host> ํ•˜์œ„์— ์ถ”๊ฐ€
    <Context path="/jenkins" debug="0" privileged="true" docBase="jenkins.war" />
    
    port ํ™•์ธ
    <Connector port="8080" protocol="HTTP/1.1"/>
    
  • ํ•ด๋‹น ์„œ๋ฒ„์˜ ip์™€ ์œ„ port์— ๋งž์ถฐ url ์ž…๋ ฅํ›„ jenkins ์„ค์น˜
    http://ip:8080/jenkins
    

Jenkins์—์„œ ํŒŒ์ด์ฌ ์ถœ๋ ฅ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ณด๊ณ ์‹ถ๋‹ค๋ฉด?

ํ•„์ž๊ฐ€ ์šด์˜ํ•˜๊ณ  ์žˆ๋Š” Daily Dev Blog ๋ผ๋Š” ์„œ๋น„์Šค๋Š” ๋งค์ผ ๋™์ผํ•œ ์‹œ๊ฐ„์— ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํฌ๋กค๋ง ํ•˜๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฉ”์ผ์„ ๋ฐœ์†กํ•˜๋Š” ์ผ๋ จ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ๋‹ค. ํ—Œ๋ฐ ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•œ ๋ถ€๋ถ„์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋ฉด ์–ด๋–ค๊ฒฝ์šฐ๋Š” ๋ฉ”์ผ ๋ฐœ์†ก์„ ๋ชปํ•œ๋‹ค๊ฑฐ๋‚˜ ๊ธฐ์กด์— ๋ฐœ์†กํ–ˆ๋˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๋ณด๋‚ด๋Š” ๋“ฑ ์ •์ƒ์ ์ด์ง€ ๋ชปํ•œ ์ƒํ™ฉ์„ ๋งž์ดํ•˜๊ฒŒ ๋œ๋‹ค.

/images/python-buffer/ddb_duplication.png
๋ฉ”์ผ์ด ํ•˜๋ฃจ๋ผ๋„ ์ž˜๋ชป์˜ค๋ฉด ์—ฌ๊ธฐ์ €๊ธฐ์„œ ์—ฐ๋ฝ์ด ์˜จ๋‹ค. ๊ฐ์‚ฌํ•œ ๋ถ„๋“ค…

์ด๋Ÿฐ์ €๋Ÿฐ ๋ฐ”์œ์ผ๋“ค๋กœ ์ฐจ์ผํ”ผ์ผ ๋ฏธ๋ฃจ๋‹ค ๋งˆ์นจ ์—ฌ์œ ๊ฐ€ ์ƒ๊ฒจ ๊ธฐ์กด์—๋Š” Crontab ์Šค์ผ€์ฅด๋กœ ํŒŒ์ด์ฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋˜ ๊ฒƒ์—์„œ Jenkins๋กœ ์˜ฎ๊ธฐ๋Š” ์ž‘์—…์„ ํ–ˆ๋‹ค. ์  ํ‚จ์Šค๊ฐ€ ์Šค์ผ€์ฅด๋ง์„ ํ•ด์ฃผ๊ณ  ์‹คํ–‰์ด๋ ฅ์„ ๋ณด์—ฌ์ฃผ๋ฉฐ, ์‹ค์‹œ๊ฐ„์œผ๋กœ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋Œ์•„๊ฐ€๋Š”๊ฑธ ๋ณผ์ˆ˜ ์žˆ์„๊ฒƒ ๊ฐ™๋‹ค๋Š” ๊ธฐ๋Œ€๊ฐ์—์„œ์ด๋‹ค. ์œ„์—์„œ ์ด์•ผ๊ธฐ ํ–ˆ๋˜ ์˜ˆ์™ธ์ƒํ™ฉ์„ ๋ณด๋‹ค ๋น ๋ฅด๊ณ  ํŽธํ•˜๊ฒŒ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋””๋ฒ„๊น…์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๊ฐ€ ๊ฐ€์žฅ ์ปธ๋‹ค.

๋‹น์—ฐํžˆ ๋ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์œผ๋‚˜…

์ž‘์—…์€ ๊ฐ„๋‹จํ• ๊บผ๋ผ ์ƒ๊ฐํ–ˆ๋‹ค.

  1. ์šฐ์„  Jenkins๋ฅผ ์„ค์น˜ํ•˜๊ณ 
  2. ๊ธฐ์กด์— ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ Jenkins Job์œผ๋กœ ์˜ฎ๊ธดํ›„์—
  3. ์ ๋‹นํ•œ ์ฝ”๋“œ ์ค‘๊ฐ„์ค‘๊ฐ„์— ๋””๋ฒ„๊น…์ด ์šฉ์ดํ•˜๋„๋ก ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•˜๊ฒŒ ํ•ด๋‘”๋‹ค์Œ
  4. ์Šค์ผ€์ฅด๋ง๋งŒ ๊ฑธ์–ด๋‘๋ฉด ๋์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

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

(1์ดˆ์— ํ•œ๋ฒˆ์”ฉ 5์ดˆ๋™์•ˆ ๋กœ๊ทธ๋ฅผ ์ฐ๋Š” ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋‹ค.)

import time

print('start')

for second in range(0,5) :
  print(second)
  time.sleep(second)

print('end')
/images/python-buffer/before.gif
์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋‹ค ๋๋‚˜์„œ์•ผ ์ถœ๋ ฅ์„ ๋ณผ์ˆ˜ ์žˆ๋‹คใ…  ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋””๋ฒ„๊น…์ด ์–ด๋ ต๋‹ค.

๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

๊ฐœ๋ฐœ์„ ํ•˜๋ฉด์„œ ๋งŒ๋‚˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๋ฌธ์ œ๋“ค์€ ๋ˆ„๊ตฐ๊ฐ€ ๊ณผ๊ฑฐ์— ๊ฒฝํ—˜ํ–ˆ๋˜ ๋ฌธ์ œ์˜€๊ณ , ์ด๋ฏธ ํ•ด๊ฒฐ๋œ ๋ฌธ์ œ์ผ ํ™•๋ฅ ์ด ์ƒ๋‹นํžˆ ๋†’์€๊ฒƒ๋“ค์ด ๋งŽ๋‹ค. ์ด๋ฒˆ์—๋„ ์—ญ์‹œ, ๊ฐ“ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ : https://stackoverflow.com/questions/107705/disable-output-buffering

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

/images/python-buffer/after.gif
์ฝ˜์†”ํ™˜๊ฒฝ์—์„œ์˜ ๋””๋ฒ„๊น…์€ ๋กœ๊น…์ด ์ตœ๊ณ !

์ •๋ฆฌํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์ด ์žˆ๊ฒ ๋‹ค.

  1. Execute Python script ์„ ํ™œ์šฉํ•˜์—ฌ Jenkins ์— ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ
print('hello', flush=True)
  • ๋งค๋ฒˆ print ๊ฐ€ ๋ ๋•Œ๋งˆ๋‹ค flush๊ฐ€ ๋˜๋„๋ก ์žฌ์ •์˜
import sys

class Unbuffered(object):
   def __init__(self, stream):
     self.stream = stream
   def write(self, data):
     self.stream.write(data)
     self.stream.flush()
   def writelines(self, datas):
     self.stream.writelines(datas)
     self.stream.flush()
   def __getattr__(self, attr):
     return getattr(self.stream, attr)

sys.stdout=Unbuffered(sys.stdout)
  1. Execute shell์„ ํ™œ์šฉํ•˜์—ฌ ํŠน์ •๊ฒฝ๋กœ์˜ Python ํŒŒ์ผ์„ ์‹คํ–‰ํ•  ๊ฒฝ์šฐ
  • -u ์˜ต์…˜์„ ์ค˜์„œ ์‹คํ–‰์‹œํ‚จ๋‹ค. ( python -u python_module.py )

์ด๋ ‡๊ฒŒ ๋‘๊ณ ๋ณด๋ฉด ๋„ˆ๋ฌด ๊ฐ„๋‹จํ•œ ์ž‘์—…์ธ๋ฐ ์ด๋Ÿฐ ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๋Š” ์ƒํ™ฉ์—์„œ๋Š” ์ž‘์„ฑ๋œ Python Script๋ฅผ Shell Script๋กœ ๋‹ค์‹œ ๊ฐ์‹ธ๋ณด๊ฑฐ๋‚˜ Python ์ฝ”๋“œ๋ฅผ ์“ฐ์ง€ ๋ง๊นŒ ๊นŒ์ง€ ์ƒ๊ฐํ–ˆ์—ˆ๋‹ค… ์‚ฝ์งˆ์˜ ์—ฐ์†๋“ค… (Shell Script๋กœ ์ž‘์„ฑํ•˜๋ฉด ๋ฐ”๋กœ๋ฐ”๋กœ ๋ณด์˜€๊ธฐ ๋•Œ๋ฌธ…)

๋‹ค์‹œํ•œ๋ฒˆ ๋ชจ๋ฅด๋ฉด ๋ชธ์ด ๊ณ ์ƒํ•œ๋‹ค(?)๋ผ๋Š”๊ฑธ ๋ชธ์†Œ ์ฒดํ—˜ํ•œ ์ข‹์€…์‹œ๊ฐ„์ด์˜€๋‹ค.

Deview 2018 ๋ฆฌ๋ทฐ (Day 1, Day2)

ํšŒ์‚ฌ ๋‚ด์—์„œ๋„ ๋Œ€ํ•™์‹œ์ ˆ ์ˆ˜๊ฐ•์‹ ์ฒญ๋งˆ๋ƒฅ 1๋ถ„๋„ ์•ˆ๋˜์„œ ๋งˆ๊ฐ๋  ์ •๋„๋กœ ๊ด€์‹ฌ์ด ๋งŽ์•˜๋˜ DEVIEW 2018. ๋‹คํ–‰ํžˆ ํด๋ฆญ์‹ ๊ณต์œผ๋กœ ์šด์ข‹๊ฒŒ ์‹ ์ฒญ์— ์„ฑ๊ณตํ•˜์˜€๊ณ  ํŒ€์—์„œ๋„ ๋ฐ”์œ ์‹œ๊ธฐ์˜€์ง€๋งŒ ๊ฐ์‚ฌํ•˜๊ฒŒ๋„ ๋ณด๋‚ด์ฃผ์…”์„œ ์˜ฌํ•ด๋Š” ์ดํ‹€ ๋ชจ๋‘ ๋‹ค๋…€์˜ฌ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค. ์˜ˆ์ „์—๋Š” ์—ฐ์ฐจ๊ฐ€ ์˜ฌ๋ผ๊ฐ€๋ฉด DEVIEWํ–‰์‚ฌ๋Š” ์ฐธ์—ฌ ์•ˆํ•˜๊ฒ ์ง€~๋ผ๋Š” ์ƒ๊ฐ์ด ์žˆ์—ˆ๋Š”๋ฐ ๊ทธ๋•Œ๋Š” ๋‹จ์ˆœ ํ˜ธ๊ธฐ์‹ฌ์— ์ฐธ์„์„ ํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค๋ฉด ์ด๋ฒˆ์—๋Š” ๋ญ๋ผ๋„ ๋ฐฐ์›Œ์˜ค์ž๋ผ๋Š” ๋งˆ์Œ์œผ๋กœ ์‹ ์ž… ์‹œ์ ˆ๋ณด๋‹ค ์กฐ๊ธˆ๋” ์„ฑ์ˆ™ํ•œ ๋งˆ์Œ๊ฐ€์ง๊ณผ ์ž์„ธ๋ฅผ ๊ฐ€์ง€๊ณ  ์ฐธ์„์„ ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

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

ํ–‰์‚ฌ ์‹œ์ž‘ ๊ทธ๋ฆฌ๊ณ  ํ‚ค๋…ธํŠธ

10์ดˆ๋งŒ์— ๋งˆ๊ฐ๋˜์—ˆ๋‹ค๋Š” ์†Œ๋ฆฌ๊ฐ€ ์žˆ์„์ •๋„๋กœ ์˜ฌํ•ด๋„ ์—ฌ์ „ํžˆ ๊ด€์‹ฌ์ด ๋งŽ์•˜๋˜ DEVIEW 2018. ์ฝ”์—‘์Šค์— ๋„์ฐฉํ•˜๊ณ  ๋“ฑ๋ก์„ ํ•œ๋’ค ์ด๊ณณ์ €๊ณณ ๋ถ€์Šค๋“ค์„ ๊ตฌ๊ฒฝํ•˜๊ธฐ ๋ฐ”๋นด๋‹ค. ์ด๋ฒˆ์—๋Š” ์ง€๋‚œ๋ฒˆ๊ณผ ๋‹ฌ๋ฆฌ ๊ฑฐ์˜ ๋„ค์ด๋ฒ„ ์„œ๋น„์Šค๊ฐ€ 6070%๋ฅผ ์ž๋ฆฌ์žก๊ณ  ์žˆ์—ˆ๊ณ (ํŒŒํŒŒ๊ณ , ์ง€๋„, ํด๋กœ๋ฐ”, ๊ธ€๋กœ๋ฒŒ ๊ด‘๊ณ  ๋“ฑ๋“ฑ) ์ผ๋ฐ˜ ๊ธฐ์—…์—์„œ๋Š” ์–ผ๋งˆ ์˜ค์ง€ ์•Š์•˜๋‹ค.(๋‚ด ๊ธฐ์–ต์œผ๋กœ 56๊ฐœ?) ๊ฐœ์ธ์ ์œผ๋กœ ์—ฌ๋Ÿฌ ๋‹ค์–‘ํ•œ ํšŒ์‚ฌ๋“ค์ด ํ•จ๊ป˜ํ•˜๋Š” ๊ธฐ์ˆ ํ–‰์‚ฌ๊ฐ€ ๋˜์—ˆ์œผ๋ฉด ํ•˜๋Š” ๋ฐ”๋žจ์ด ์žˆ์—ˆ์ง€๋งŒ ํšŒ์‚ฌ๋ฅผ ์„ ์ •ํ•˜๋Š”๋ฐ, ๊ทธ๋ฆฌ๊ณ  ๊ธฐํƒ€ ์‚ฌ์ •๋“ค์ด ์žˆ์„๊บผ๋ผ๋Š” ์•„์‰ฌ์›€์„ ๋’ค๋กœํ•˜๊ณ  CTO๋‹˜์ด ๋ฐœํ‘œํ•˜์‹œ๋Š” ํ‚ค๋…ธํŠธ๋ฅผ ๋“ค์œผ๋Ÿฌ ๋ฉ”์ธ๊ฐ•์˜์žฅ์— ๋“ค์–ด๊ฐ”๋‹ค. (์ž์นซ… ์ด๊ฒƒ๋„ ๋„ค์ด๋ฒ„ ๋…๊ณผ์ (?) ์ด๋Ÿฌ๋ฉด ํ• ๋ง์ด ์—†๋Š”๋ฐ…ใ… ใ… )

/images/deview-2018/keynote.png
์†ก์ฐฝํ˜„ ๋„ค์ด๋ฒ„ CTO๋‹˜์˜ keynote

์ž‘๋…„์—๋Š” ๊ฑฐ์˜ ๋กœ๋ด‡์ž”์น˜๋กœ ๋А๊ปด์กŒ๋Š”๋ฐ ์˜ฌํ•ด๋Š” ๊ทธ ๊ธฐ์ˆ ๋“ค์˜ ์œตํ•ฉ(?)์ž”์น˜ ๋กœ ๋ฐ›์•„๋“ค์—ฌ์กŒ๋‹ค. Ambient Intelligence ๋ฅผ ๊ฐ•์กฐํ•˜์‹œ๋ฉฐ ๊ธฐ์ˆ ์˜ ์ง„์ •ํ•œ ๊ฐ€์น˜๋Š” ๊ธฐ์ˆ ์ด ์ƒํ™œ์†์œผ๋กœ ์‚ฌ๋ผ์กŒ์„ ๋•Œ ๋‚˜์˜จ๋‹ค๋ผ๋Š” ๋ช…์–ธ๊ฐ™์€ ๋ง์”€๋„ ํ•ด์ฃผ์…จ๋‹ค.

  • ์—ฐ๊ฒฐ : ์‚ฌ๋ฌผ, ์ƒํ™ฉ, ์œ„์น˜์ธ์‹, ์ดํ•ด
  • ๋ฐœ๊ฒฌ : ์ ์‹œ์— ๋‹ต, ์ถ”์ฒœ, ์•ก์…˜์ œ๊ณต

๊ทธ๋ฆฌ๊ณ  ๊ทธ์™€ ๊ด€๋ จ๋œ ๋„ค์ด๋ฒ„ ์„œ๋น„์Šค๋ฅผ ๊ณต๊ฐœ ํ•˜์…จ๋Š”๋ฐ, ๋„ค์ด๋ฒ„ ์ง€๋„ Map API๋ฅผ ๋ฌด์ œํ•œ/๋ฌด๋ฃŒ๋กœ ์‚ฌ์šฉํ• ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค๊ณ  ํ•œ๋‹ค. (๋ฐ•์ˆ˜ ์œ ๋„ํ•˜์‹ฌ ใ…Žใ…Ž) ๋˜ํ•œ ์ด๋ฒˆ์— ๊ฐ€์žฅ ํฌ๊ฒŒ ๋ฐ”๋€Œ๋Š” ๋„ค์ด๋ฒ„ ๋ชจ๋ฐ”์ผ ํ™ˆ ํŽ˜์ด์ง€์ธ ๊ทธ๋ฆฐ๋‹ท, ์ง€๋„ ๊ธฐ์ˆ ๋“ค์˜ ์ข…ํ•ฉ ํ”Œ๋žซํผ์ธ xDM Platform(์ธก์œ„, ์ง€๋„, ๋‚ด๋น„), ๊ทธ๋ฆฌ๊ณ  ์ž์œจ์ฃผํ–‰๊ณผ ๋กœ๋ด‡์— ๋Œ€ํ•ด ์—ฐ๊ตฌ๊ฒฐ๊ณผ ๊ทธ๋ฆฌ๊ณ  ์•ž์œผ๋กœ์˜ ๋ฐฉํ–ฅ์„ฑ์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด์ฃผ์…จ๋‹ค. ์ง‘์— ๋Œ์•„์™€์„œ ๊ฒ€์ƒ‰์ข€ ํ•˜๋‹ค๋ณด๋‹ˆ ํ…Œํฌ์ˆ˜๋‹ค์—์„œ ๋ฒŒ์จ(?) ์˜์ƒ์„ ํ•˜๋‚˜ ์˜ฌ๋ฆฐ๊ฒŒ ์žˆ์–ด ๊ณต์œ ํ•ด๋ณธ๋‹ค.

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

์ดํ‹€์— ๊ฑธ์ณ ์ด๋Ÿฐ์ €๋Ÿฐ ๋‹ค์–‘ํ•œ ์„ธ์…˜๋“ค์„ ๋“ค์„์ˆ˜ ์žˆ์–ด ์ข‹์•˜๋Š”๋ฐ ๋ช‡๋ช‡ ์„ธ์…˜๋“ค์€ ๊ธฐ๋ณธ์ง€์‹์ด ์—†์–ด (AI, ๋จธ์‹ ๋Ÿฌ๋‹ ๋“ฑ…ใ… ) ์ดํ•ดํ•˜๊ธฐ ํž˜๋“ค์—ˆ๋‹ค. ๋‚ด๋…„์—” ์ดํ•ดํ• ์ˆ˜ ์žˆ๋„๋ก ์ค€๋น„๋ฅผ ํ•ด์„œ ์˜ค์ž๋ฉฐ ๋˜๋‹ค์ง์„ ํ•˜๊ณ … ๊ทธ๋‚˜๋งˆ ์กฐ๊ธˆ์ด๋ผ๋„ ์ดํ•ดํ• ์ˆ˜ ์žˆ์—ˆ๋˜ ์„ธ์…˜๋“ค ๋ช‡๊ฐœ๋งŒ ์ •๋ฆฌํ•ด๋ณธ๋‹ค.

React Native: ์›น ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•œ ๋‹ฌ ๋งŒ์— ์•ฑ ์ถœ์‹œํ•˜๊ธฐ

/images/deview-2018/session_1.png
React Native: ์›น ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•œ ๋‹ฌ ๋งŒ์— ์•ฑ ์ถœ์‹œํ•˜๊ธฐ

์ง€๋‚œํŒ€์—์„œ ์•„์ฃผ ์ž ๊น React๋ฅผ ๊ฒฝํ—˜ํ•ด๋ณด๊ธด ํ–ˆ์ง€๋งŒ ๊ฑฐ์˜ hello world ์ˆ˜์ค€์ด์˜€๊ธฐ ๋•Œ๋ฌธ์— ์ด ์„ธ์…˜ ์—ญ์‹œ ์ดํ•ด๊ฐ€ ์ž˜ ๋˜์ง€ ๋ชปํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•„์ž์ฒ˜๋Ÿผ ์ดํ•ด๋ฅผ ์ž˜ ๋ชปํ•˜๋Š” ์‚ฌ๋žŒ๋„ ๋ฐœํ‘œ์ž๊ฐ€ ์ „๋‹ฌํ•˜๋ ค๋Š” ๋ชฉ์ ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ์ˆ˜ ์žˆ์„ ์ •๋„๋กœ ์ „์ฒด์ ์ธ ํ๋ฆ„์€ ์กฐ๊ธˆ์ด๋‚˜๋งˆ ์ดํ•ด๋ฅผ ํ• ์ˆ˜ ์žˆ์—ˆ๊ณ  ํŠนํžˆ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ์ข‹์•˜๋˜ ๊ฒƒ์ด๋‚˜ ๊ฒฝํ—˜๋‹ด์„ ์•Œ๋ ค์ฃผ๋ฉฐ ์‚ฝ์งˆ๊ณต์œ ๋ฅผ ํ•ด์ฃผ๋Š”๊ฒŒ ๋“ฃ๊ธฐ ์ข‹์•˜๋‹ค. React Native ๋Š” ๋น ๋ฅธ๊ฐœ๋ฐœ์„ ํ• ์ˆ˜์žˆ๊ณ  ์ฝ”๋“œ๊ณต์œ ๊ฐ€ ์‰ฌ์šฐ๋ฉฐ ๊ฐœ์„ ์ด ์‰ฝ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ๋˜ํ•œ ๋‹จ๊ธฐ๊ฐ„์— ํฌ๋กœ์Šค ํ”Œ๋žซํผ์„ ๋งŒ๋“ค์–ด์•ผ ํ• ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•˜๋‹ˆ ๋‚˜์ค‘์— ์ฐธ๊ณ ํ•ด๋ด๋„ ์ข‹์„๋“ฏ ์‹ถ๋‹ค.

2018 Pycon. ๊ทธ๋ฆฌ๊ณ  ์ฒซ ๋ฐœํ‘œ๋ฅผ ํ•˜๋‹ค.

IT๊ด€๋ จ ํ–‰์‚ฌ์— ์ฐธ์—ฌํ•˜๋ฉด ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ •๋ณด๋ฅผ ์–ป์„์ˆ˜ ์žˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ๋Š” ์‚ฌ์‹ค ์ •๋ณด๋ฅผ ์–ป๊ธฐ ์œ„ํ•จ๋ณด๋‹ค ๊ทธ๊ณณ์˜ ๋ถ„์œ„๊ธฐ๋ฅผ ํ˜„์žฅ์—์„œ ๋ชธ์†Œ ๋А๋ผ๊ณ  ์ฐธ์—ฌํ•œ ์‚ฌ๋žŒ๋“ค์˜ ๋ˆˆ๋น›์„ ๋ณด๋ฉฐ ํ•ด์ดํ•ด์ง„ ๋งˆ์Œ๊ฐ€์ง์„ ๋‹ค์‹œ ๋‹ค์žก์„์ˆ˜ ์žˆ์Œ์ด ๊ฐ€์žฅ ํฐ ๋ชฉ์ ์ด๋‹ค. ๊ทธ์— ์˜ฌํ•ด Pycon๋„ ํ•˜๋‚˜์˜ ์ „ํ™˜์ ์ด ๋˜๊ธธ ๋ฐ”๋ผ๋Š” ๋งˆ์Œ์œผ๋กœ ์‹ ์ฒญ์„ ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

๋“ฑ๋ก

https://www.pycon.kr ์–ผ๋ฆฌ๋ฒ„๋“œ ๋“ฑ๋ก์„ ํ•œ๋‹ค๊ณ  Facebook์—์„œ ํ™๋ณด๋ฅผ ํ•˜๊ธธ๋ž˜ ๊ทธ๋Ÿฐ๊ฐ€๋ณด๋‹ค ํ–ˆ๋Š”๋ฐ ์ž ๊น ํšŒ์‚ฌ์ผ์— ์ง‘์ค‘ํ•˜๊ณ  ๋‹ค์‹œ ๋ณด๋‹ˆ ์ด๋ฏธ ๋งค์ง„์ด ๋˜์–ด์žˆ์—ˆ๋‹ค. ์‚ฌ์‹ค Pycon ์€ ์˜ฌํ•ด๊ฐ€ ์ฒ˜์Œ ๊ฐ€๋ณด๋Š”๊ฑฐ๋ผ ์ธ๊ธฐ๋ฅผ ์‹ค๊ฐํ• ์ˆ˜ ์—†์—ˆ๋Š”๋ฐ ์ด์ •๋„์ผ์ค„์€ ์ƒ์ƒ๋„ ๋ชปํ–ˆ๋‹ค. (๋‚˜์ค‘์— ์•Œ๊ฒŒ ๋œ ์‚ฌ์‹ค์ด์ง€๋งŒ ์˜ฌํ•ด๊ฐ€ ๊ฐ€์žฅ ์ธ์›์ด ๋งŽ์•˜๋‹ค๊ณ …) ๊ทธ๋ž˜์„œ ๋‚˜์ค‘์— ์ง„ํ–‰๋˜์—ˆ๋˜ ์ผ๋ฐ˜ํ‘œ ๋“ฑ๋ก์€ ํœด๋Œ€ํฐ ์•Œ๋žŒ๊นŒ์ง€ ๊ฑธ์–ด๋‘๋ฉฐ ๋Šฆ์ง€์•Š๊ฒŒ ๋“ฑ๋กํ• ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์„ธ๋ถ€ ์ผ์ •๋“ค์ด ์—…๋ฐ์ดํŠธ๊ฐ€ ๋˜๊ณ  ์–ด๋–ค ์„ธ์…˜์„ ๋“ค์„๊นŒ ๊ณ ๋ฏผํ•˜๋ฉด์„œ ๊ฐ„๋žต ์†Œ๊ฐœ๋ฅผ ํ•˜๋‚˜๋‘˜์”ฉ ๋ณด๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ Python์„ ๋งŒ์ง€๋ฉฐ ํ‰์†Œ์— ๊ถ๊ธˆํ–ˆ๋˜๊ฑฐ๋‚˜ ์žฌ๋ฐŒ์–ด ๋ณด์ด๋Š” ์„ธ์…˜๋“ค์ด ๋„ˆ๋ฌด๋งŽ์•„ ๊ณ ๋ฏผ์„ ๋งŽ์ด ํ–ˆ๋‹ค. ํ•œ๊ฐ€์ง€ ์•„์‰ฌ์šด๊ฑด ๋กœ๊ทธ์ธ ๊ธฐ๋ฐ˜์ด ์•„๋‹ˆ๋‹ค ๋ณด๋‹ˆ (์ž„์‹œ ๋กœ๊ทธ์ธ๊ธฐ๋ฐ˜?) ๋‚ด ์‹œ๊ฐ„ํ‘œ ์„ค์ •ํ•˜๋Š”๊ฒŒ ์—†์—ˆ๋‹ค. ๋‚˜๋Š” ๋ณ„๋„๋กœ ์ ์–ด์„œ ๊ฐ”์ง€๋งŒ ๋‚˜์ค‘์—” ๊ทธ๋Ÿฐ ๊ธฐ๋Šฅ์ด ์ƒ๊ฒผ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค.

2019๋…„ Pycon์—” ํฌ๋กฌ ์ต์Šคํ…์…˜์œผ๋กœ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด ๋กœ๊ทธ์ธ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด ๋ช‡์‹œ์— ๋‚ด๊ฐ€ ์–ด๋–ค ์„ธ์…˜์„ ๋“ค์„๊ฑด์ง€์— ๋Œ€ํ•œ ์„ค์ •์„ ํ•˜๊ณ  ์ด๋ฅผ ์ด๋ฏธ์ง€๋กœ ์บก์ณํ•ด์„œ ์ถœ๋ ฅ/๋‹ค์šด ๋ฐ›์„์ˆ˜ ์žˆ๋Š” ๊ฑธ ๋งŒ๋“ค์–ด ๋ณด๊ณ  ์‹ถ๋‹ค. (๊ทธ์ „์— ๋ฏธ๋ค„๋’€๋˜ ํฌ๋กฌ ์ต์Šคํ…์…˜ ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐฉ๋ฒ•๋ถ€ํ„ฐ ๊ณต๋ถ€ํ•˜์ž…)

์ฒซ์งธ๋‚ 

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

/images/pycon-2018/day1.png
DIVE INTO DIVERSITY !!

ํ‚ค๋…ธํŠธ๋ฅผ ์‹œ์ž‘์œผ๋กœ ์‚ฌ๋žŒ๋“ค์€ ๊ฐ์ž ๋“ฃ๊ณ ์‹ถ์€ ์„ธ์…˜์— ์ฐธ๊ฐ€ํ•˜๋ฉฐ ํ–‰์‚ฌ๋Š” ์‹œ์ž‘์ด ๋˜์—ˆ๋‹ค. ์ „์ฒด์ ์œผ๋กœ ๊ธฐ์ˆ ์˜ ๋‚œ์ด๋„๋Š” ์ดˆ๊ธ‰ ์ˆ˜์ค€์˜ ๋ฐœํ‘œ์˜€๋˜๊ฑธ๋กœ ๋А๊ปด์กŒ๋‹ค. (๋ฌผ๋ก  ๋‚˜๋Š” ์ดˆ์ดˆ์ดˆ๊ธ‰๋„ ์•ˆ๋˜๋Š” ๊ผฌ๊ผฌ๋งˆ ์ˆ˜์ค€์ด์ง€๋งŒ…) ๋Œ€๋ถ€๋ถ„ Python์œผ๋กœ ์–ด๋–ค๊ฑธ ํ•ด๋ดค๊ณ , ์–ด๋–ค ์–ด๋ ค์›€์ด ์žˆ์—ˆ๊ณ , ์ด๋Ÿฌ์ €๋Ÿฌํ•œ ์ƒํ™ฉ๋“ค์„ ๋งŒ๋‚ฌ์œผ๋ฉฐ, ์š”๋Ÿฐ ๊ฒฝ์šฐ์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ํ•˜๋ฉฐ ํ•ด๊ฒฐ์„ ํ•˜์˜€๋‹ค๋Š” ๋“ฑ ๊ธฐ์ˆ ์„ ํ™œ์šฉํ•œ “๊ฒฝํ—˜๊ธฐ"์— ๋Œ€ํ•œ ๋‚ด์šฉ๋“ค์„ ๋“ค์„์ˆ˜ ์žˆ์—ˆ๋‹ค. Pycon์˜ ์Šฌ๋กœ๊ฑด์ธ DIVE INTO DIVERSITY์— ๊ฑธ๋งž๊ฒŒ ์•„์ฃผ ๋‹ค์–‘ํ•œ ์ฃผ์ œ๋กœ ํฅ๋ฏธ์žˆ๋Š” ๋ฐœํ‘œ๋‚ด์šฉ๋“ค์ด์˜€๋‹ค. ๊ธฐ์–ต๋‚˜๋Š” ๊ฒƒ๋“ค์ค‘์— ์ธ์ƒ๊นŠ์—ˆ๋˜ ๋ถ€๋ถ„๋“ค์„ ์ •๋ฆฌํ•ด๋ณธ๋‹ค.

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

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

๋‘˜์งธ๋‚ 

์–ด์ œ์™€๋Š” ๋‹ฌ๋ฆฌ ์˜ค๋Š˜์€ ์ž ์„ ๋งŽ์ด ๋ชป์ž์„œ ์ธ์ง€ ๋Šฆ๊ฒŒ ์ผ์–ด๋‚˜ ์ฒซ ์„ธ์…˜์ด ์‹œ์ž‘ํ•˜๊ณ ์„œ ๊ฑฐ์˜ ๋๋‚  ์ฆˆ์Œ์— ํ–‰์‚ฌ์žฅ์— ๋„์ฐฉํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. “๊ดœํžˆ ๋ฐœํ‘œ ํ•œ๋‹ค๊ณ  ํ•œ๊ฑธ๊นŒ” ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค๋ฉฐ ์ง„ํ–‰์œ„ ๋ณธ๋ถ€์— ๊ฐ€์„œ ๋ฐœํ‘œ ์ˆœ์„œ๋ฅผ ํ™•์ธํ•ด๋ณด๋‹ˆ ์ฒซ๋ฒˆ์งธ… ์Šฌ์Šฌ ๋จธ๋ฆฌ๊ฐ€ ์•„ํŒŒ์˜ค๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ๊ทธ๋ž˜๋„ ๋“ฃ๊ธฐ๋กœํ•œ ์„ธ์…˜์€ ๋“ค์–ด๋ณด๊ณ  ์‹ถ์–ด์„œ ์ง‘์ค‘ํ•ด์„œ ์„ธ์…˜๋“ค์„ ๋Œ์•„๊ฐ€๋ฉฐ ๋“ค์—ˆ์ง€๋งŒ ๋จธ๋ฆฟ์†์—๋Š” ์˜จํ†ต “๋ฐœํ‘œ ๋ฐœํ‘œ ๋ฐœํ‘œ"๋ผ๋Š” ์ƒ๊ฐ๋•Œ๋ฌธ์— ์˜คํžˆ๋ ค ๋‹ค๋ฅธ๋ถ„๊ป˜์„œ ํ•˜์‹œ๋Š” ๋ฐœํ‘œ๋ฅผ ์ง‘์ค‘ํ•ด์„œ ๋“ฃ์ง€ ๋ชปํ•˜์˜€๋‹ค.

์ž๋ฐ” ๊ฐ์ฒด ๋ณต์‚ฌํ•˜๊ธฐ ( feat. how to use CloneUtils? )

์ž๋ฐ”(Java)๋กœ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค๋ณด๋ฉด ํ•œ๋ฒˆ์ฏค ๊ฐ์ฒด๋ฅผ ๋ณต์‚ฌํ•˜๋Š” ๋กœ์ง์„ ์ž‘์„ฑํ• ๋•Œ๊ฐ€ ์žˆ๋‹ค. ๊ทธ๋•Œ๋งˆ๋‹ค ๋‚˜์˜ค๋Š” ์ด์•ผ๊ธฐ์ธ Shalldow Copy ์™€ Deep Copy. ํ•œ๊ตญ์–ด๋กœ ํ‘œํ˜„ํ•˜๋ฉด ์–•์€ ๋ณต์‚ฌ์™€ ๊นŠ์€ ๋ณต์‚ฌ๋ผ๊ณ  ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๋Š”๋ฐ ์ด ๋‘ ๊ฐœ๋…์˜ ์ฐจ์ด๋Š” ์•„์ฃผ ๊ฐ„๋‹จํ•˜๋‹ค. ๊ฐ์ฒด์˜ ์ฃผ์†Œ๊ฐ’์„ ๋ณต์‚ฌํ•˜๋Š”์ง€, ์•„๋‹ˆ๋ฉด ๊ฐ์ฒด์˜ ์‹ค์ œ ๊ฐ’(value)๋ฅผ ๋ณต์‚ฌํ•˜๋Š”์ง€. ์ด ๋‘˜์˜ ์ฐจ์ด์ ์„ ์†Œ๊ฐœํ•˜๋Š” ๊ธ€๋“ค์€ ์›Œ๋‚™ ๋งŽ์œผ๋‹ˆ ํŒจ์Šคํ•˜๋„๋ก ํ•˜๊ณ  ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Deep Copy๋ฅผ ํ• ๋•Œ org.apache.http.client.utils ํ•˜์œ„์— ์žˆ๋Š” CloneUtils ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•ด ์ •๋ฆฌ ํ•˜๊ณ ์ž ํ•œ๋‹ค.

๊ทธ๋ƒฅ ์“ฐ๋ฉด ๋˜๋Š”๊ฑฐ ์•„๋‹Œ๊ฐ€? ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ (๋ณ„๊ฑฐ ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ) ํ•ด๋ณด๊ณ  ์•ˆํ•ด๋ณด๊ณ ์˜ ์ฐจ์ด๋Š” ์—„์ฒญ์ปธ๊ณ  ์‚ฌ์šฉํ• ๋•Œ ์ฃผ์˜์ ์ด ๋ช‡๊ฐ€์ง€ ์žˆ์–ด ์ •๋ฆฌ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

์˜ˆ์ œ์— ์•ž์„œ ๋ณธ ํฌ์ŠคํŒ…์—์„œ ์‚ฌ์šฉํ•  ๊ฐ์ฒด๋ฅผ ๊ฐ„๋‹จํžˆ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. (ํ•™๊ต์—์„œ ํ•™์ƒ ์‹ ์ƒ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.)

public class Student {
	String name; // ์ด๋ฆ„
	int age; // ๋‚˜์ด
	Family family; // ๊ฐ€์กฑ
}

public class Family {
	String name;  // ์ด๋ฆ„
	int age; // ๋‚˜์ด
	boolean isOfficeWorkers; // ์ง์žฅ์ธ ์—ฌ๋ถ€
}

public class PhysicalInformation {
	int height; // ํ‚ค
	int weight; // ๋ชธ๋ฌด๊ฒŒ
}

๊ฐ์ฒด๋Š” Cloneable interface ๋ฅผ implement ํ•ด์•ผํ•˜๊ณ  clone ๋ฉ”์†Œ๋“œ๋ฅผ public ์œผ๋กœ override ํ•ด์•ผํ•œ๋‹ค.

๋‹น์—ฐํ•œ ์ด์•ผ๊ธฐ๊ฐ€ ๋ ์ˆ˜๋„ ์žˆ์œผ๋‚˜ CloneUtils๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•ด๋‹น ๊ฐ์ฒด๋Š” Cloneable interface ๋ฅผ implement ํ•ด์•ผํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ clone ๋ฉ”์†Œ๋“œ๋ฅผ override ํ•ด์•ผ๋˜๋Š”๋ฐ ์—ฌ๊ธฐ์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ์ ์€ ์™ธ๋ถ€์—์„œ๋„ ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— public ์œผ๋กœ override๋ฅผ ํ•ด์•ผํ•œ๋‹ค. (๊ธฐ๋ณธ์€ protected ๋กœ ๋˜์–ด์žˆ๋‹ค.) ์šฐ์„  ๊ฐ„๋‹จํžˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ถœ๋ ฅ๋ถ€ํ„ฐ ํ•ด๋ณด์ž. (์ถœ๋ ฅ์„ ์ด์˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ToStringBuilder.reflectionToString์„ ์‚ฌ์šฉํ•˜์˜€๋‹ค.)

PhysicalInformation physicalInformation = new PhysicalInformation();
physicalInformation.height = 180;
physicalInformation.weight = 70;

System.out.println(ToStringBuilder.reflectionToString(physicalInformation, ToStringStyle.DEFAULT_STYLE));

๊ฒฐ๊ณผ๋Š” ๋‹น์—ฐํžˆ

PhysicalInformation@5d6f64b1[height=180,weight=70]

์ด์ œ Cloneable interface ๋ฅผ implement ํ•˜๊ณ  clone ๋ฉ”์†Œ๋“œ๋ฅผ public ์œผ๋กœ override ํ•œ๋’ค, CloneUtils๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ์ฒด๋ฅผ ๋ณต์‚ฌํ•ด๋ณด์ž. ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋ฉด์„œ Shalldow Copy๋„ ํ•ด๋ณด์ž.

// class setting
public class PhysicalInformation implements Cloneable{
	int height;
	int weight;

	@Override
	public Object clone() throws CloneNotSupportedException { // public ์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ์ž.
		return super.clone();
	}
}

// test code
PhysicalInformation physicalInformation = new PhysicalInformation();
physicalInformation.height = 180;
physicalInformation.weight = 70;

PhysicalInformation physicalInformationShalldowCopy = physicalInformation;
PhysicalInformation physicalInformationDeepCopy = null;
try {
	physicalInformationDeepCopy = (PhysicalInformation)CloneUtils.clone(physicalInformation);
} catch (CloneNotSupportedException e) {
	e.printStackTrace();
}

// ์›๋ณธ
System.out.println(ToStringBuilder.reflectionToString(physicalInformation, ToStringStyle.DEFAULT_STYLE));
// ์–•์€ ๋ณต์‚ฌ
System.out.println(ToStringBuilder.reflectionToString(physicalInformationShalldowCopy, ToStringStyle.DEFAULT_STYLE));
// ๊นŠ์€ ๋ณต์‚ฌ
System.out.println(ToStringBuilder.reflectionToString(physicalInformationDeepCopy, ToStringStyle.DEFAULT_STYLE));

// ๊ฐ’ ๋ณ€๊ฒฝ
physicalInformation.weight = 80;
physicalInformation.height = 170;

// ์›๋ณธ
System.out.println(ToStringBuilder.reflectionToString(physicalInformation, ToStringStyle.DEFAULT_STYLE));
// ์–•์€ ๋ณต์‚ฌ
System.out.println(ToStringBuilder.reflectionToString(physicalInformationShalldowCopy, ToStringStyle.DEFAULT_STYLE));
// ๊นŠ์€ ๋ณต์‚ฌ
System.out.println(ToStringBuilder.reflectionToString(physicalInformationDeepCopy, ToStringStyle.DEFAULT_STYLE));

๊ฒฐ๊ณผ๋Š” ์›๋ณธ๊ณผ ์–•์€ ๋ณต์‚ฌ๋ฅผ ํ•œ๊ฒƒ์€ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ(?)๊ฐ€ ๊ฐ™์œผ๋‚˜ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ํ•œ๊ฒƒ์€ ๋ฐ์ดํ„ฐ๋Š” ๊ฐ™์ง€๋งŒ ์ฃผ์†Œ๊ฐ€ ๋‹ค๋ฅด๊ณ  ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด๋„ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค. (์™„์ „ํžˆ ์„œ๋กœ๋‹ค๋ฅธ ๊ฐ์ฒด์ธ๊ฒƒ์„ ์ฆ๋ช…)

PhysicalInformation@1376c05c[height=180,weight=70]
PhysicalInformation@1376c05c[height=180,weight=70]
PhysicalInformation@1b4fb997[height=180,weight=70]

PhysicalInformation@1376c05c[height=170,weight=80]
PhysicalInformation@1376c05c[height=170,weight=80]
PhysicalInformation@1b4fb997[height=180,weight=70]

๋งŒ์•ฝ ์œ„์—์„œ clone์„ ๊ธฐ๋ณธ๊ฐ’์ธ protected๋กœ override๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด ์–ด๋–ค ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ฌ๊นŒ?

Exception in thread "main" java.lang.NoSuchMethodError: com.PhysicalInformation.clone()
	at org.apache.http.client.utils.CloneUtils.cloneObject(CloneUtils.java:55)
	at org.apache.http.client.utils.CloneUtils.clone(CloneUtils.java:77)
	at com.Test.main(Test.java:16)

์ ‘๊ทผ์ œํ•œ์ž์—์„œ ๋ˆˆ์น˜๋ฅผ ์ฑŒ์ˆ˜๋„ ์žˆ์—ˆ๊ฒ ์ง€๋งŒ ์ ‘๊ทผ์„ ํ• ์ˆ˜์—†์–ด CloneUtils ์ด ๋ฆฌํ”Œ๋ ‰์…˜์„ ํ•˜๋Š” ๊ณผ์ •์—์„œ Exception์„ ๋ฐœ์ƒํ•œ๋‹ค. ๊ผญ! public ์œผ๋กœ override๋ฅผ ํ•ด์ฃผ์ž.

๊ฐ์ฒด ๋‚ด์— clone์ด ์•ˆ๋˜๋Š” ๋ณ€์ˆ˜๋Š” ๋ณ„๋„ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

๊ฐ์ฒด ๋‚ด์— ์žˆ๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋Š” ์›์‹œ ๋ณ€์ˆ˜(int, char, float ๋“ฑ) , Immutable Class (String, Boolean, Integer ๋“ฑ) ๋˜๋Š” Enum ํ˜•์‹์ผ ๋•Œ๋Š” ์›๋ณธ์˜ ๊ฐ’์„ ๋ฐ”๋กœ ๋Œ€์ž…ํ•ด๋„ ๋˜์ง€๋งŒ, ๊ทธ๋ ‡์ง€ ์•Š์„ ๋•Œ๋Š” ๋ฉค๋ฒ„๋ณ€์ˆ˜์˜ clone์„ ํ˜ธ์ถœํ•˜์—ฌ ๋ณต์‚ฌํ•ด์•ผ ํ•œ๋‹ค. ๋ง๋กœ๋งŒ ๋ณด๋ฉด ๋ฌด์Šจ์ด์•ผ๊ธฐ ์ธ์ง€ ๋ชจ๋ฅด๋‹ˆ ์˜ˆ์ œ๋ฅผ ๋ณด์ž.

public class Student implements Cloneable {
	String name;
	int age;
	Family family;

	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}

Student ํด๋ž˜์Šค์—์„œ Cloneable ๋ฅผ implements ํ•˜๊ณ  clone ๋ฉ”์†Œ๋“œ๋ฅผ override ํ•˜์˜€๋‹ค. (์—ฌ๊ธฐ์„œ ๊ตฌ๋ฉ์ด ์žˆ๋‹ค!!) ๊ทธ๋‹ค์Œ Family ํด๋ž˜์Šค๋Š” ์ดˆ๊ธฐ ๊ทธ๋Œ€๋กœ ๋‘๊ณ  CloneUtils์„ ์‚ฌ์šฉํ•ด์„œ ๊ฐ์ฒด๋ฅผ ๋ณต์‚ฌํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž.