
μ§λ ν¬μ€ν
, κ·Έλ¬λκΉ μ°μν νμ λ€μμ μ΄λλ₯Ό λ°μ Spring batch μ λν ν
ν¬μΈλ―Έλμ λ€λ
μλ€. κ·Έ μ€ κ°μ₯ μΈμκΉμλ λΆλΆμ΄ λ°λ‘ 무μ€λ¨ λ°°ν¬. μ°¨μΌνΌμΌ λ―Έλ£¨λ€ νμκ° μν νμμλ λ°°ν¬λλ§λ€ κ°μ₯ λΆνΈμ λλΌκ³ μμλ λΆλΆμ΄μκΈ°λ νκ³ , κ·Έλ°κ°λ³΄λ€ νλ©° κ°λ
λ§ μκ³ λμ΄κ°κΈ°μ 무μΈκ° μμ¬μ μ°λ € μ§μ 무μ€λ¨ λ°°ν¬λ₯Ό ν μ μλλ‘ κ΅¬μ±μ ν΄λ³΄κ³ ν
μ€νΈκΉμ§ ν΄λ³΄κ³ μ νλ€.
μν© λ° λ¬Έμ μ 리λ
μ€ μλ²μ Jenkinsκ° μ€μΉλμ΄ μκ³ , Spring batch λͺ¨λμ μ€νμν€κ³ μλ€. μλμΌλ‘ μ€νμ νκ±°λ, Jenkins RestApiλ₯Ό μ΄μ©ν΄μ μ€νμ ν μ μμ§λ§ μ£Όλ‘ μ ν΄μ§ μκ° μ¦, μ€μΌμ₯΄λ§μ μν΄ μ€νλκ³€ νλ€. μ€μΌμ₯΄λ§μ κ°μ₯ μμ λ¨μλ 1λΆλ¨μ λ°°μΉλ μκΈ° λλ¬Έμ 24μκ° λ©μΆμ§ μκ³ μ€νλκ³ μλ€κ³ 무방νλ€. νμ§λ§ λ°°μΉ λͺ¨λμ΄ μμ λκ³ , λ°°ν¬λ₯Ό νκΈ° μν΄μλ λ€μκ³Ό κ°μ μλ리μ€λ‘ μ§νμ΄ λλ€.
Jenkins μ€μ μ λκΈ°μ μ€λΉ λ₯Ό μ€ννμ¬ λμ΄μ Jenkinsμ μν΄ Spring batch λͺ¨λ(μ΄ν Job)μ΄ μ€νλμ§ μλλ‘ νλ€. μλ‘μ΄ Jobμ λμ΄μ μ€νλμ§ μμ§λ§ μ΄λ―Έ μ€νμ€μ΄μλ Job μ κ°μ λ‘ μ€λ¨μ νκ±°λ Job μ΄ λλ λκΉμ§ κΈ°λ€λ¦°λ€. μ€νμ€μΈ Jobμ΄ μμ κ²½μ° μ΄μ λ°°ν¬λ₯Ό μ§ννλ€. λ°°ν¬κ° μλ£λλ©΄ Jenkins μ€μ μ λκΈ°μ μ€λΉλ₯Ό ν΄μ νλ€. μ€νμ€μΈ Jobμ΄ μλλλ©΄ λ§λ₯ κΈ°λ€λ¦΄ν
κ°? μΆμ² : https://m.post.naver.com/viewer/postView.nhn?volumeNo=14100660&memberNo=2032633" μ€νμ€μΈ Jobμ΄ μλλλ©΄ λ§λ₯ κΈ°λ€λ¦΄ν
κ°? μΆμ² : https://m.post.naver.com/viewer/postView.nhn?volumeNo=14100660&memberNo=2032633 μ€νλλ Jobμ μ€λ¨νμ§ λͺ»νλ μν© μ¦, μ€νμ€μ μ€λ¨νλ©΄ νΈλμμ
μ΄ κΉ¨μ Έ 무쑰건 κΈ°λ€λ €μΌλ§ νλ μν©μ΄λΌλ©΄ λ°°ν¬ λν κ³μ μ§μ°λ μ λ°μ μλ μν©μΈ κ²μ΄λ€. Spring bootμ java config λ₯Ό νμ©νκ³ λ± jar νμΌ νλλ₯Ό μ€ννλ λ°©μμ΄λΌλ©΄ jarνμΌμ λ°κΏμΉκΈ° νλ μμΌλ‘ κ³ λ―Όμ ν΄λ³Όμλ μμκ² κ°λ€. νμ§λ§ Legacy μ½λκ° μμ§ μ‘΄μ¬νμ¬ μΌλ° Spring μ xml λ‘ config νλ λ°©μμΌλ‘ μ΄μμ€μ΄λΌ jarνμΌ νλλ§ λ°κΏμΉκΈ° νκΈ°μ λ¬΄λ¦¬κ° μλ μν©.
μμ΄μμ²λΌ μ΄λμμλ μ¬μ©μ΄ κ°λ₯ν λ§λ³ν΅μΉμ½ κ°μ λ°©λ²μ μλ€. μΈμ λ κ·Έλ¬λ― νμ¬ μμ€ν
(xml config λ°©μ)μ κ°μ₯ μ΅μ νλ λ°©λ², κ·Έλ¦¬κ³ java config λ°©μμμλ μ¬μ©μ΄ κ°λ₯ν κ² κ°μ λ°©λ²μ μκ°ν΄ 보μλ€.
무μ€λ¨ λ°°ν¬λ₯Ό κ°λ₯μΌ νλ 3κ°μ§ ν΅μ¬ 1. λ°°ν¬λ₯Ό λ§€λ² μλ‘μ΄ κ²½λ‘μ λ°°ν¬νλ€. κ° νμ¬λ§λ€, κ·Έλ¦¬κ³ μλΉμ€λ§λ€ μ λ§ λ€μν λ°°ν¬ μμ€ν
μ΄ μλ€. κ·Έλ€μ 곡ν΅μ μ μ격μλ²μ νΉμ κ²½λ‘μ λΉλλ νμΌλ€μ λ°μ΄ λ£μ΄μ€λ€λ κ². μλ리μ€λ λ€μκ³Ό κ°λ€.
λ°°ν¬ν λλ§λ€ λ³λμ λλ ν 리λ₯Ό μμ±νλ€ μ¬λ³Όλ¦ λ§ν¬λ₯Ό μ°κ²°ν΄μ€λ€. λ°°ν¬λ 1μμ μ°κ²°ν μ¬λ³Όλ¦ λ§ν¬μ λ°°ν¬λλλ‘ μ€μ , κ²°κ΅ λ§€λ² λ§λ€μ΄μ§λ λλ ν 리μ λ°°ν¬κ° λκ² λλ€. μ¬κΈ°μ μ€μνμ μ “λ°°ν¬ν λλ§λ€ μλ‘μ΄ λλ ν 리μ λ°°ν¬κ° λλ€” μ λ°°ν¬μμλ νμ μ¬λ³Όλ¦ λ§ν¬μλ§ λ°°ν¬λ₯Ό νλ©΄ λκΈ° λλ¬Έμ “λ°°ν¬μμ€ν
μ΄ μλ‘ λ§λ€μ΄μ§λ λλ ν 리μ κ²½λ‘λ₯Ό λͺ°λΌλ 무방νλ€"λ μ μ΄λ€.
#!/bin/sh cd /~~~/deploy/ # μμ λλ ν 리 DIRECTORY_NAME=batch_$(/bin/date +%Y%m%d%H%M%S) mkdir $DIRECTORY_NAME μ μ μ€ν¬λ¦½νΈλ₯Ό μ€ννλ©΄ batch_20191012205218 μ κ°μ λλ ν λ¦¬κ° μμ±μ΄ λλ€. μ¬λ³Όλ¦ λ§ν¬ κ΄λ ¨ν΄μλ λ°λ‘ μλ μ΄μ΄μ μ€λͺ
νκ² λ€.
2. μ¬λ³Όλ¦ λ§ν¬μ μλ λ§ν¬λ₯Ό μ¦μ λ³κ²½ λ³΄ν΅ μ¬λ³Όλ¦ λ§ν¬ (μ¦, λ°λ‘κ°κΈ°) μ κ²½λ‘λ₯Ό λ³κ²½νκΈ° μν΄μλ μλμ²λΌ μ§μ λ€κ° μμ νλ μμΌλ‘ νμλλ°
$ mkdir directory_a $ mkdir directory_b $ ln -s directory_a asdf $ ll asdf -> directory_a directory_a directory_b # directory_a μμ directory_b λ‘ λ°κΎΈλ κ²½μ° (μ¬λ³Όλ¦ λ§ν¬ μ체λ₯Ό μμ νκ³ λ€μ μ¬λ³Όλ¦ λ§ν¬ μμ±) $ rm asdf $ ln -s directory_b asdf $ ll asdf -> directory_b directory_a directory_b μ΄λ κ² λλ©΄ μμ νκ³ ~ λ€μ λ§λ€μ΄μ§λ νμ΄λ°μ λ°°ν¬κ° λκ±°λ μ€νμ΄ λλ μ¦, ν΄λΉ κ²½λ‘μ μμΈμ€ νλ κ²½μ° μ΄μ μ κ²½λ‘λ₯Ό λ°λΌλ³Έλ€κ±°λ μλνλ λ°©μμΌλ‘ μ€νμ΄ λμ§ μλ μν©μ΄ λ°μνλ€. (μ°°λμ νμ΄λ° μ΄μ§λ§ νμλ μ΄λ¬ν λ¬Έμ λ‘ μ΄μ μ κ²½λ‘λ₯Ό λ°λΌλ³΄λ λ¬Έμ κ° λ°μνμλ€.) κ·Έλμ ln μ μ΅μ
μ€μΈ -Tfsμ΅μ
μΌλ‘ μ¦μ λ³κ²½μ ν΄μ£Όλλ‘ νμ. (ln man μ°Έκ³ )
# λ§λ μμ λλ ν λ¦¬λ‘ λ°°ν¬λ μ μλλ‘ μ€μ νλ€.

μ§λμ£Ό μ°μν νμ λ€μμ μ§ννμλ “9μ μ°μν ν
ν¬ μΈλ―Έλ - μ°μν μ€νλ§ λ°°μΉ” μ λ€λ
μλ€. νμμκ² μ΄λ² 9μμ μ μ μ΄ μ΄λμ μλμ§ λͺ¨λ₯Όλ§νΌ λ°μκ³ νλ€μμ§λ§ μμ λΆν° κΆκΈνκΈ°λ νκ³ μμ¦λ€μ΄ κ΄μ¬μ κ°λ “λ°°μΉ μ΄ν리μΌμ΄μ
"μ μ΄λ»κ² νλ©΄ “μ°μν λ°©λ²"μΌλ‘ μ¬μ©ν μ μμμ§μ λν΄ μ¬λ¬ μκ°λ€μ΄ μμκΈ°μ ν° κΈ°λλ₯Ό κ°μ§κ³ μ§μ₯μ² μ 견λλ©° μ μ€ κ·Όμ²μ μλ μ°μν νμ λ€ μμμ§μΌλ‘ κ°κ² λμλ€. μ΄λ€ λ΄μ©μ λ°ννμλμ§μ λν΄ κΈ°μ΅μνλ λλν μ΅λ¬΄μκ° λμ΄ μ 리νκΈ° λ³΄λ€ μ£Όμ ν¬μΈνΈμ λν μκ°κ³Ό ν¨κ» μ°Έμ¬λ₯Ό λͺ»ν λΆλ€ μν΄μλΌκΈ° λ³΄λ€ λ΄ μ€μ€λ‘ μ 리λ₯Ό νκΈ° μν΄ ν¬μ€ν
μ μμ±ν΄ λ³΄κ³ μ νλ€. (μ΄λ²μλ λΆλ¬μ£Όμ
μ κ°μ¬ν©λλ€ ^=^)
μΈνΈλ‘ μ°μ¬μ λΆμ μλμ μ λͺ
νμ λΆμ΄λΌ λ³λμ μ€λͺ
μ΄ νμ μμ΄ μ΄μνμλ λΈλ‘κ·Έ μ£Όμλ‘ λ체λ₯Ό ν΄λ³Έλ€. μ΄λ² νμ¬μ μ΄λλμ λΆλ€μ νλ²μ΄λΌλ μ€νλ§ λ°°μΉλ₯Ό μ¨λΆ λΆλ€μ λμμΌλ‘ μ§ννκ² λμλ€κ³ νλλ° λ§μΉ¨ νμλ ν λ΄μμ μ΄μνκ³ μλ λ°°μΉ μ΄ν리μΌμ΄μ
μ λ³΄λ€ ν¨μ¨μ μ΄κ³ μ°μνκ² λ°κΏλ³΄κ³ μ νλ λμ¦κ° μμκΈ°μ μλ§ μ΄λλκ² μλκΉ μΆλ€.
μκΈ°μκΈ°ν μ°μν νμ λ€ κ±΄λ¬Ό λ΄λΆ" μκΈ°μκΈ°ν μ°μν νμ λ€ κ±΄λ¬Ό λ΄λΆ λλΆμ΄ λ°νμ μ κ°λ΅ν νμ¬κ° μνλ μΈμ¬μ λνμ¬ μΈκΈν΄μ£Όμ
¨λλ° κ·Έκ² μ΄μ°λ 곡κ°μ΄ κ°λμ§. μμ μκ°μ΄ λ¨λ€λ₯Έ νμ¬κ΅¬λ νκ³ λ€μνλ² μκ°μ.
μκΈ°λ³΄λ€ κ²½νμ΄ “μ μ” μ¬λμκ² “μ€λμ λΉν μ” μμ΄μΌ νκ³ , μκΈ°λ³΄λ€ κ²½νμ΄ “λ§μ μ¬λμ μ€λ” μν¬ μ μμ΄μΌ νλ€.
κΈ°λ³ΈνΈ λ°°μΉ μ΄ν리μΌμ΄μ
μ΄λ μ»΄ν¨ν°μμ μ¬λμ μνΈμμ©μμ΄ μ΄μ΄μ§λ νλ‘κ·Έλ¨(μμ
)λ€μ μ€νμ΄λΌκ³ μν€νΌλμμ κ°κ²°&λͺ
λ£νκ² μ 리λμ΄ μλ€. κ·Έλ§νΌ μΌλ°μ μΈ μΉ μ΄ν리μΌμ΄μ
κ³Όμ μ°¨μ΄κ° μλλ° μΉ μ΄ν리μΌμ΄μ
μ μ€μκ° μ²λ¦¬κ° κΈ°λ³Έμ΄κ³ μμ²μ λν μλ΅μ μ 곡ν΄μΌ νλ μ무λλ μλκ° μλμ μ΄λ©° QAμ νΈν λΆλΆμ΄ μλ€. κ·Έμ λ°ν΄ λ°°μΉ μ΄ν리μΌμ΄μ
μ μΉ μ΄ν리μΌμ΄μ
μμ λ§νλ μμ²μ΄λΌλ κ°λ
λ³΄λ€ νμμ²λ¦¬μ κ°κΉκ³ , μλ λν μ λμ μ΄λ©° QAκ° λ³΅μ‘νλ€λκ² νΉμ§μ΄λ€. λ°λΌμ ν
μ€νΈμ½λλ μΉ μ΄ν리μΌμ΄μ
λ³΄λ€ λ°°μΉ μ΄ν리μΌμ΄μ
μ΄ λ νμνλ€κ³ λ³Ό μ μλ€. λ°°μΉ μ΄ν리μΌμ΄μ
μ΄ νμν μν©μ ν¬κ² λκ°μ§λ‘ λλ λ³Ό μκ° μλ€κ³ νλ€.
μΌμ μ£ΌκΈ°λ‘ μ€ν λμ΄μΌ ν λ μ€μκ° μ²λ¦¬κ° μ΄λ €μ΄ λλμ λ°μ΄ν°λ₯Ό μ²λ¦¬ ν λ νμ 첫λ²μ§Έ μν©λ§ μκ°νκ³ λ°°μΉ μ΄ν리μΌμ΄μ
μ μμ±νκ³€ νμλλ° λλ²μ¬ μν©μ λν΄ μκ°μ μκ°μ λ ν΄λ³΄λ μ€νλ§ λ°°μΉλ₯Ό κ°λ¨νκ²λ§ (Tasklet) μ¬μ©νκ³ μλ건 μλκ° νλ λ°μ±μ ν΄λ³΄κ³€ νλ€. (Reader, Processor, Writer λ± λ€μν λ μ΄μ΄κ° μλλ°λ…)
νΉν μ€νλ§ λ°°μΉμμλ κΈ°λ³Έμ μΌλ‘ λͺ¨λ λ°μ΄ν°λ₯Ό λ©λͺ¨λ¦¬μ μμ§ μλ μ‘°νλ°©μλΌκ³ νλ€. (DBκΈ°μ€) Paging νΉμ Cursorλ‘ pageSizeλ§νΌλ§ μ½μ΄μ€κ³ chunkSizeλ§νΌλ§ commit νλ νν. μ΄λ¬ν κ° λ μ΄μ΄λ³ sizeλ₯Ό μ μ‘°μ νκΈ°λ§ ν΄λ μ μ λ
Έλ ₯μΌλ‘ ν° μ±λ₯μ μ»μ μ μλ λΆλΆμ΄ νλ μμν¬λ₯Ό μ¬μ©νλ μ΄μ μλκΉ λΌκ³ μκ°ν΄λ³Έλ€.
λν @JobScope λ @StepScopeλ Late Binding μ¦ λ°°μΉ μ΄ν리μΌμ΄μ
μ΄ μ€νλλ μμ μ΄ μλλΌ Job μ΄ μ€νλ λ μμ±μ΄ λκΈ° λλ¬Έμ μ΄λ₯Ό νμ©νμ¬ λμ μΌλ‘ reader / processor / wirter λ μ΄μ΄λ₯Ό λ§λ€ μ μλ€κ³ νλ€.
νμ©νΈ μ€νλ§ λ°°μΉλ₯Ό μ΄μ©ν λ°°μΉ μ΄ν리μΌμ΄μ
μ΄ μκ³ μ΄λ₯Ό μ€μΌμ₯΄λ§ λ± κ΄λ¦¬λ₯Ό ν΄μ£Όλ λꡬλ€μ μ΄μΌκΈ°λ₯Ό ν΄μ£Όμ
¨λ€.
Cron 리λ
μ€λ₯Ό μ΄λμ λ μ¬μ©ν΄λ΄€λ€λ©΄ μλ§ν 리λ
μ€ κΈ°λ³Έ μ€μΌμ₯΄λ§ νλ‘κ·Έλ¨μΈ Cron. νμλ Cron μΌλ‘ μ£ΌκΈ°μ μΌλ‘ μ€ννλλ‘ μ€μ ν΄λ³΄κΈ°λ νμμ§λ§ λ°°μΉ μ΄ν리μΌμ΄μ
μ νΉμ±μ λ‘κ·Έ λ° μ€ν/μ’
λ£ λ± μ νμ¬νμ΄ λ§μ 건 μ¬μ€μΈκ² κ°λ€. Spring MVC + API Call μ£Όλ³μμ μ¬μ©νκ³ μλ€κ³ νλ λ°©μ. μ΄ λ°©μμ μ₯μ μ νμ λ μκΈ° λλ¬Έμ μ΄ν리μΌμ΄μ
ꡬλμκ°μ΄ λ³λλ‘ νμ μλ€λ μ₯μ μ΄ μμ§λ§ μ λ°μ μΈ κ΄λ¦¬κ° μ΄λ €μ΄ λ¨μ μ΄ μλκ² κ°λ€. λ¬Όλ‘ μΈλ©° 겨μλ¨ΉκΈ° μμΌλ‘ λ¨μ μ 극볡ν λ°©λ²μ μ¬λ¬κ°μ§κ° μκ² μ§λ§ λͺ¨λ 건 νμ Trade off Spring Batch Admin (Deprecated) μμ νλΆμ΄ μλ €μ£Όμ
μ μ κΉ λ΄€λ λΆλΆμ΄κΈ΄ νλ° μ΄λμ¬μ΄μ Deprecated λμλ€κ³ νλ€. Quertz + Admin http://www.quartz-scheduler.org/ μμ£Ό μ€λμ μ μ¨λ³Έ κΈ°μ΅μ΄ μμ§λ§ λ°°λ³΄λ€ λ°°κΌ½μ΄ λ ν° μν©κ°μλ νλ€μλ κΈ°μ΅λ€λ§ λ¨μμλ ꡬνλ°©λ²μΈκ² κ°λ€.

λͺ¨λν°λ§μ μλΉμ€ λ‘μ§ κ°λ° λ§νΌ νλ²μ© κ³ λ―Όν΄λ³΄κ³ κ²½νν΄ λ΄€μ μ€μν μμμ΄λΌ ν μ μλ€. κ·Έμ€ μΉμλ²μμ μ 곡ν΄μ£Όλ μμΈμ€ λ‘κ·Έλ μ΄μνκ³ μλ μΉμλΉμ€μ λν΄ μ¬λ¬κ°μ§ μΈ‘λ©΄μμ λΆμν μ μλ κ°μ₯ κ°λ ₯ν μμ΄ν
μ€μ νλλΌκ³ μκ°νλ€. μ΄λ₯Ό ν΅ν΄ μ¬μ©μλ€μ΄ μ΄λ€ urlμ λ§μ΄ νΈμΆνκ³ , μ΄λ€ user-agentννλ₯Ό μ¬μ©νλμ§ μκ² λλ©΄ κ·Έμ λ°λΌ μλΉμ€ μ λ΅μ λ³κ²½ν μλ μκ³ μ
μμ μΌλ‘ 곡격μ μΈ μμ²μ λν΄ μΉμλ²λ¨μμ μ°¨λ¨μ ν μ μκΈ° λλ¬Έμ΄λ€. μ΄λ κ² inbound νΈλν½(μΈλΆμμ λ€μ΄μ€λ μμ²)μ λν΄μλ μμΈμ€ λ‘κ·Έλ₯Ό μ λΆμνλ©΄ κΈ°μ‘΄μ μΉ μ΄ν리μΌμ΄μ
κ³Όλ μ ν 무κ΄νκ² λͺ¨λν°λ§μ΄ κ°λ₯νμ§λ§ λ°λλ‘ outbund νΈλν½(μΈλΆλ‘ λκ°λ μμ²)μ λν΄μλ μ΄λ€μμΌλ‘ λͺ¨λν°λ§μ ν μ μμκΉ?
μκΈν΅μ₯μ inbound νΈλν½λ³΄λ€ outbound νΈλν½μ΄ λ무 λ§μ μμ¦…μ΄λ―Έμ§ μΆμ² : https://www.app24moa.com/feedDetail/2/2002" μκΈν΅μ₯μ inbound νΈλν½λ³΄λ€ outbound νΈλν½μ΄ λ무 λ§μ μμ¦…
μ΄λ―Έμ§ μΆμ² : https://www.app24moa.com/feedDetail/2/2002 μ컨λ°, λ μ¨ μλΉμ€λ₯Ό νκΈ° μν΄ μΈλΆμμ μμΈλ μ¨λΌλ νμ΄μ§λ₯Ό μ‘°ννμ κ²½μ° κΈ°μμ² APIμμ λ겨λ°μ λ°μ΄ν°λ₯Ό κ°κ³΅νμ¬ λ³΄μ¬μ€λ€κ³ κ°μ ν΄λ³΄μ. μ΄λ κΈ°μμ²μμ μ 곡ν΄μ£Όλ νΉμ APIμ€μ μ΄λ νλκ° λ¦κ² μλ΅μ΄ μ¨λ€κ±°λ, νΉμ μκ°λμ μλ¬μλ΅μ λ°μκ²½μ° κ³Όμ° μ΄λ₯Ό μ΄λ€μμΌλ‘ λͺ¨λν°λ§ ν μ μμκΉ? μ΄ν리μΌμ΄μ
μ½λμ λͺ¨λν°λ§μ μν μ½λλ₯Ό μΆκ°ν κ²μΈκ°? νΉ νλμ μλ²μμ Aλͺ¨λμ javaλ‘, Bλͺ¨λμ pythonμΌλ‘ κ°λ°λμμ κ²½μ° κ°κ° λͺ¨λλ§λ€ λͺ¨λν°λ§μ μν μ½λλ₯Ό μΆκ°νλ μμΌλ‘ νλ€λ³΄λ©΄ λΉμ§λμ€ λ‘μ§μ λ°©ν΄νκ±°λ μ€νλ € μΆκ°ν μ½λ λν κ΄λ¦¬ν΄μΌ νλ λ°°λ³΄λ€ λ°°κΌ½μ΄ λ μ»€μ Έλ²λ¦΄ μν©λ μκΈΈμ μλ€. μ΄ν리μΌμ΄μ
μ λΉμ§λμ€ λ‘μ§κ³Όλ 무κ΄νκ² μλ² μ체μμ μΈλΆλ‘ λκ°λ λ€νΈμν¬ νΈλν½μ λν΄ λͺ¨λν°λ§μ ν μ μλ κ°λ²Όμ°λ©΄μλ μ¬νν λͺ¨λμ μ°Ύκ³ μΆμλ€. μ΄ν리μΌμ΄μ
μ κ°λ°μΈμ΄κ° 무μμ΄λ μκ΄μμ΄ λ³λμ μμ΄μ νΈ νμμΌλ‘ λμλκΈ°λ§ νλ©΄ λ€νΈμν¬ νΈλν½μ μμ§ λ° λΆμ, λμκ°μλ λͺ¨λν°λ§κΉμ§ ν μμλ… κ·Έλμ μ°Ύλ€λ³΄λ μμλ μ΄λ¬ν κ³ λ―Όμ λκ΅°κ°λ νκ³ μμκ³ μ€νμμ€κΉμ§ λμ΄μλ Elastic Stack μ Beatμ€ PacketbeatλΌλ λ°μ΄ν° μμ§λͺ¨λμ μκ² λμλ€.
μμ λ΄κ° νκ³ μλ κ³ λ―Όμ μ΄λ―Έ λκ΅°κ° νλ κ³ λ―Όλ€… μ΄λ¬ν κ³ λ―Όμ λν΄ ν΄κ²°νλ λ°©λ²μ λ³΄λ€ λΉ¨λ¦¬ μ°Ύλκ² κ²½μλ ₯μ΄ λ ν
λ°…
μ΄λ² ν¬μ€ν
μμλ Packetbeat μ λν΄ κ°λ¨ν μμλ³΄κ³ μ΄λ₯Ό νμ©νμ¬ outbound νΈλν½μ λν΄ λͺ¨λν°λ§μ ν΄λ³΄λ©° μ΄λ€μμΌλ‘ νμ©ν μ μλμ§μ λν΄ μμλ³΄κ³ μ νλ€.
Packetbeat ? ElasticStack μ€μ λ°μ΄ν° μμ§κΈ° νλ«νΌμΈ Beatsμ€ λ€νΈμν¬ νΈλν½ λ°μ΄ν°μ λν΄ μμ§μ ν μ μλ λ°μ΄ν° μμ§κΈ°λ₯Ό μ 곡νκ³ μλ€. pcapλΌμ΄λΈλ¬λ¦¬λ₯Ό μ΄μ©νμ¬ μλ²μ λ€νΈμν¬ λ 벨μμ λ°μ΄ν°λ₯Ό μμ§ λ° λΆμν ν μΈλΆλ‘(Elasticsearch, Logstash, Kafka λ±) μ μ‘ν΄μ£Όλ κ²½λ λ€νΈμν¬ ν¨ν· λΆμκΈ°λΌκ³ 곡μ ννμ΄μ§μ μκ°λκ³ μλ€. λͺλ² μ¬μ©ν΄λ³΄λ©΄μ λλ μ₯μ λ€μ λ€μκ³Ό κ°λ€.
μ€μΉ λ° μ€νμ΄ λ무 κ°λ¨νλ€. μ€μ κ° νλμ ν΅ν΄ κ°λ¨νμ§λ§, κ·Έλ¬ν κ°λ¨ν¨μ λΉν΄μ λ무 κ°λ ₯ν μμ§μ΄ κ°λ₯νλ€. μμ μ΄μΌκΈ° νλ μ΄ν리μΌμ΄μ
μ½λμλ μ ν 무κ΄νκ² μλνλ€. 무μμ ν΄λ³Όκ²μΈκ°?! (a.k.a. λͺ©ν) νμκ° μ΄μνλ Daily-DevBlog λΌλ μλΉμ€κ° μλ€. (κ°λΆ μλΉμ€ ν보) μ¬λ¬ μ¬λλ€μ rssλ₯Ό μ‘°ννκ³ νμ±ν΄μ λ©μΌμ 보λ΄μ£Όλ μλΉμ€ μΈλ°, packetbeat μ¬μ© μμλ₯Ό λ€κΈ°μν΄ μ‘°κΈ λ³ννμ¬ λͺ¨λ rssλ₯Ό μ κ·Όνκ³ κ°μ₯ μ΅μ κΈμ μ λͺ©μ μΆλ ₯νλ μμ£Ό κ°λ¨ν python μ€ν¬λ¦½νΈλ‘ outbound νΈλν½μ λ°μμμΌ λ³΄κ³ μ νλ€. κ·Έλ¦¬κ³ packetbeat λ₯Ό μ΄μ©νμ¬ μΈλΆλ‘ νΈμΆλλ νΈλν½μ μμ§νκ³ Elasticsearch λ‘ μΈλ±μ± νμ¬ μ΅μ’
μ μΌλ‘λ μ΄λ rssμ μλκ° κ°μ₯ λλ¦°μ§ μ€νλλ pythonμ½λμλ μ ν κ΄λ ¨μμ΄ λͺ¨λν°λ§ ν΄λ³΄κ³ μ νλ€. python μ½λλ λ€μκ³Ό κ°λ€.
μ°Έκ³ λ‘ νμλ awesome-devblogμ μ΄μμλΆκ» ν΄λΉ λ°μ΄ν° μ¬μ©μ λν΄ νλ½μ λ°μ μνμ΄λ€.
import requests, yaml, feedparser blog_info_list_yml_url = 'https://raw.githubusercontent.com/sarojaba/awesome-devblog/master/db.yml' blog_info_list_yml = requests.get(url=blog_info_list_yml_url).text blog_info_yaml_parse_list = yaml.load(blog_info_list_yml) for blog_info in blog_info_yaml_parse_list : if 'rss' not in blog_info.keys() or not blog_info['rss']: continue rss_url = blog_info['rss'] try : parse_feed = feedparser.parse(rss_url) except : continue parse_feed_data = parse_feed.entries[0] print(blog_info['name'], '|', parse_feed_data['title'], '|', parse_feed_data['link']) μ μ½λλ₯Ό μ€ννλ©΄ μλμ²λΌ μμ£Ό κ°λ¨νκ² λΈλ‘κ·Έ μ£ΌμΈμ μ΄λ¦κ³Ό μ΅μ κΈ μ λͺ©, λ§ν¬κ° μΆλ ₯μ΄ λλ€.

μΉμλ² νλλ§ μ¬μ©νκ±°λ WAS νλλ§μ μ¬μ©νλ©° μΉμλΉμ€λ₯Ό μ΄μνλ κ²½μ°λ κ·Ήν λλ¬Όλ€. μΉμλ²μ μ₯μ κ³Ό WASμ μ₯μ κ·Έ λλ§λ¦¬μ ν λΌλ₯Ό λ€ μ‘κΈ° μν΄ λ³΄ν΅ μλ¨μ μΉμλ²λ₯Ό λκ³ κ·Έ λ€μ WASλ₯Ό λλ©° μλΉμ€λ₯Ό μ΄μνκ³€ νλ€. νλ° μ΄μνλ μλΉμ€κ° μΈκΈ°κ° λ§μμ Έ(?) μ¬μ©λμ΄ λ§μμ§λ€λ©΄ κ·Έλ§νΌ μλ΅μ΄ λλ € (TPS λ±) μλ²λ₯Ό λλ €μΌ νλ μν©μ΄ μκΈ΄λ€κ³ κ°μ ν΄λ³΄μ.(λ¬Όλ‘ μλ²λ₯Ό λ리λ κ²λ³΄λ€ μΊμλ₯Ό μ μ©νκ±°λ λ‘μ§μ λ°κΏλ³΄λ λ
Έλ ₯μ΄ μ νλμΌ νκ² μ§λ§…) λΉμ°ν μλ²λΆν° ꡬ맀νλ©° “Scale Out"μ νλ €κ³ ν κ²μ΄λ€. λ§μ½ μλ μ΄μνλ μλ²κ° λ무 μ’μμ CPUλ λ©λͺ¨λ¦¬ μ¬μ©λ₯ μ΄ κ±°μ λ°λ₯μ΄μ¬λ μλ²λ₯Ό ꡬ맀ν΄μΌ ν κΉ? μλ²λ₯Ό ꡬ맀νκ²λλ©΄ κ²°κ΅ λκ° μ΄μμ μλ²κ° μ΄μλ ν
λ° κ·Έ μλ²λ€μ μμμ λ¬Άμ΄μ£Όλ©° νΈλν½μ λΆμ°μμΌμ£Όλ 무μΈκ°κ° νμνλ€. κ·Έλ¬ν κΈ°μ μ λ°λ‘ λ‘λλ°Έλ°μ± μ΄λΌκ³ νλ€. ν΅μ L4 μ€μμΉλ₯Ό νμ©νμ¬ μμ²μ μ¬λ¬ μλ²λ€λ‘ λΆμ°μν€λ©° μ°μ μ μΌλ‘λ μλ² λμλ§νΌ μ±λ₯μ΄ μ’μμ§λ ν¨κ³Όλ₯Ό λ³Ό μ μλ€. νμ§λ§ μμ λ§νλ― μλ²μ μμ μ¬μ©λ₯ μ΄ λ°λ₯μΌ μ λλ‘ κ±°μ μ¬μ©μ μν κ²½μ° μλ²λ₯Ό ꡬ맀νλ건 λ무λ λΉν¨μ¨μ μ΄λ€. μ΄λ² ν¬μ€ν
μμλ μλ²λ₯Ό λλ¦¬μ§ μμΌλ©΄μ μΉμλ² μ€ μνμΉλ₯Ό νμ©νμ¬ μ¬λ¬ WASλ₯Ό μ΄μνλ λ°©λ²μ λν΄ μμλ³΄κ³ μ νλ€. μλ² λλ €μΌ νλ μν©μμ μ¬μ©ν΄ λ³Ό μ μλ λλ§μ μ’μ 무기(?)κ° μκΈ΄κ² μλκΉ μκ°μ΄ λ λ€.
μνμΉλ EOLμ΄ λμκΈ° λλ¬Έμ 2.4λ²μ μΌλ‘ μ€μΉνκ³ , WASλ νΈμμ ν°μΌ μ΅μ λ²μ μΌλ‘ μ€μΉν΄μ λμΌν μλ²μ μνμΉ νλμ ν°μΌ 3λλ₯Ό μ°λνλκ²μ λͺ©μ μΌλ‘ νλ€. λ‘λλ°Έλ°μ±μ΄ μ΄λ€μμΌλ‘ μ΄λ£¨μ΄ μ§κ³ νμμ μ°κ²°λ ν°μΌμ 컨νΈλ‘€ νλ λ°©λ² λν μμλ³Ό μμ μ΄λ€.
μλ² νκ²½ λ° μ€μΉνκ² λ κ° λ²μ μ λ€μκ³Ό κ°λ€. μλ² : CentOS 7.4 64Bit apache : httpd-2.4.39 tomcat : apache-tomcat-8.5.43 tomcat-connectors(mod_jk) : 1.2.46
Apache μ Tomcat μ€μΉ νμμ ν¬μ€ν
μμ μ’
μ’
λμ€λ λΆλΆμ΄κΈ°λ νκ³ , ꡬκΈλ§ ν΄λ³΄λ©΄ λ°λ‘ μ€μΉ λ°©λ²μ μ½κ² μ°Ύμ μ μκ² μ§λ§ κ·Έλ λ€κ³ μΈκΈμ μνκ³ λμ΄κ°κΈ°μ λ무 λΆμΉμ νλ… μΉνΈν€μ²λΌ(?) λΉ λ₯΄κ² μ 리ν΄λ³΄μ.
Apache $ wget http://apache.tt.co.kr//httpd/httpd-2.4.39.tar.gz $ tar -zxvf httpd-2.4.39.tar.gz $ ./configure --prefix=/home/~~~/apache $ make && make install $ cd /home/~~~/apache/bin $ sudo chown root:κ³μ λͺ
httpd $ sudo chmod +s httpd $ vi /home/~~~/apache/conf/httpd.conf User κ³μ λͺ
Grop κ³μ λͺ
$ /home/~~~/apache/bin/apachectl start β μ€ν μ΄λ κ² μ€μΉλ₯Ό νλ€ μ€νμ μν€κ³ μλ²μ ipλ₯Ό μ μν΄λ³΄λ©΄ μλμ κ°μ νλ©΄μ λ³Ό μ μλ€.
Tomcat $ wget http://mirror.apache-kr.org/tomcat/tomcat-8/v8.5.43/bin/apache-tomcat-8.5.43.tar.gz $ tar -zxvf apache-tomcat-8.5.43.tar.gz $ /home/apache-tomcat-8.5.43/bin/start.sh β μ€ν ν°μΌμ κΈ°λ³Έ http ν¬νΈμΈ 8080μΌλ‘ μ μμ ν΄λ³΄λ©΄ κ·μ¬μ΄ κ³ μμ΄κ° μλ ν°μΌ κΈ°λ³Ένλ©΄μ λ³Ό μ μλ€.
μνμΉμ ν°μΌ μ°λνκΈ° μνμΉμ ν°μΌμ μ°λμ mod_jk μ mod_proxy λ± λ€μν λͺ¨λλ‘ μ°λμ ν μ μλλ° μ΄λ² ν¬μ€ν
μμλ mod_jk λ₯Ό νμ©νλ λ°©λ²μ λν΄ μμλ³΄κ³ μ νλ€. μ°μ mod_jk λ₯Ό μ€μΉνμ.
κ°λ¨ν mod_jk λ μ»΄νμΌ, μ€μ λ± λ³΅μ‘νμ§λ§ ν°μΌ μ μ© λ°μ΄λ리 νλ‘ν μ½μΈ AJPλ₯Ό μ¬μ©νκΈ° λλ¬Έμ λμ μ±λ₯μ κΈ°λν μκ° μλ€. mod_proxy λ λ°λ©΄ κΈ°λ³ΈμΌλ‘ μνμΉμ νμ¬λμ΄μλ λͺ¨λμ΄κΈ° λλ¬Έμ λ³λμ λͺ¨λ μ€μΉκ° νμ μκ³ μ€μ λ κ°λ¨νλ€λ μ₯μ μ΄ μλ€. κ° μ°λλ°©μμ μ₯λ¨μ μ΄ μκΈ° λλ¬Έμ λ³ΈμΈμ΄ μ΄μνλ μλ² μν©μ λ§μΆμ΄ μ μ© ν νμκ° μλ€.
mod_jk μ€μΉ $ wget http://apache.tt.co.kr/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.46-src.tar.gz $ tar -zxvf tomcat-connectors-1.2.46-src.tar.gz $ cd tomcat-connectors-1.2.46-src/native $ ./configure --with-apxs=/home/~~~/apache/bin/apxs $ make && make install $ /home/~~~/apache/modules νμμ mod_jk.soκ° μκΉ mod_jk λ₯Ό νμ©νλ©΄ AJPλΌλ ν΅μ μΌλ‘ μνμΉμ ν°μΌμ΄ μ°λλλλ° ν°μΌμ κΈ°λ³Έ AJP ν¬νΈλ 8009λ²μμ μκ³ λ€μμ²λΌ μ€μ μ ν΄μ£Όμ.
apache/conf/workers.properties worker.list=tomcat1 worker.tomcat1.port=8009 worker.tomcat1.host=localhost worker.tomcat1.type=ajp13 worker.tomcat1.lbfactor=1 apache/conf/httpd.conf LoadModule jk_module modules/mod_jk.so <IfModule jk_module> JkWorkersFile conf/workers.properties JkLogFile logs/mod_jk.log JkLogLevel info JkMount /* tomcat1 </IfModule> μ΄λ κ² νκ³ μ μνμΉμ ν°μΌμ μ¬μμ νμ μλ²μ ipλ‘ μ μν΄λ³΄λ©΄ (λ³λμ port μμ΄) ν°μΌ μ€μ νμ΄μ§λ‘ λλ©μ΄ λλκ²μ νμΈν μ μλ€.

κ°λ°μ νλ€λ³΄λ©΄ μ€μ λ‘ μ§μ ꡬνμ ν΄λ³Έμ μ μμ§λ§ μ¬κΈ°μ κΈ°μ λ€μ΄λ³Έ μ§μκ³Ό κ·Έ λμμ 짬λ°₯(?)μΌλ‘ μΆμΈ‘ν΄λ³Όμ μλ λΆλΆλ€μ΄ μλ€. λ¬Όλ‘ λͺ¨λ μΌμ μ λ΅μ μκ² μ§λ§ μμ¦ λλΌλ건 μ±
μμ 곡λΆλ§ ν΄λ³Έκ²κ³Ό λ€λ₯Έ λΈλ‘κ·Έλ€μμ λμΌλ‘λ§ λ³΄κ³ λμ΄κ°λκ²λ€ κ·Έλ¦¬κ³ μ§μ μκ°λ½μ μμ§μ¬κ°λ©° μ μ¬κΈ°μλ μ΄ λ°©λ²μ μ¬μ©νμ§ κ³ λ―Όνλ©΄μ ꡬνμ ν΄λ³Έλ€λ건 μ λ§ μμ²λκ² ν° μ°¨μ΄κ° μλκ² κ°λ€. μΉ μ΄ν리μΌμ΄μ
μ κ°λ°νλ€λ³΄λ©΄ νλ² μ―€ λ§λκ² λλ νμΌ μ
λ‘λ κΈ°λ₯. νμλ λͺλ² κ΅¬νμ ν΄λ΄€μ§λ§ κ·Έλ₯ λ¨μν ꡬνλ§ ν΄λ³Έ μνμλ€κ° μ΅κ·Όμ κ·Έλ₯ νμΌ μ
λ‘λκ° μλ λμ©λ νμΌ μ
λ‘λμμμ λ¬Έμ κ° λ°μνμ¬ μ¬κΈ°μ κΈ° μ½μ§μ νκ² λμκ³ μ 리λ ν΄λ³Όκ²Έ μ€νλ§μμμ λμ©λ νμΌ μ
λ‘λμ νλ²μ―€ κ³ λ €ν΄λ΄μΌ ν λΆλΆμ λν΄ μ 리λ₯Ό ν΄λ³΄λ €κ³ νλ€.
λ¬Όλ‘ κ΅¬κΈμμ κ²μμ ν΄λ³΄λ©΄ μλ§ νμκ° μ΄κ² λ³΄λ€ λ μμΈνκ³ μ’μ κΈλ€μ΄ μκ² μ§λ§ νμλ λ³΄λ€ λμ©λμ μ§μ€μμ μμ±ν΄ λ³΄κ³ μ νλ€. λͺ
μ¬νμ. “μ무리 νλ¦° μν¬λΌλ μ’μ κΈ°μ΅λ ₯λ³΄λ€ λ«λ€” λΌλ λ§μ΄ μλ―μ΄
μ€νλ§μ νμ©ν νμΌ μ
λ‘λ ꡬν μ°μ μμ μ΄κΈ°μνμμ μμνκΈ° μν΄ μ€νλ§ λΆνΈ νλ‘μ νΈλ₯Ό λ§λ€κ³ κ°λ¨νκ² νμΌ μ
λ‘λλ₯Ό ν μ μλ form νμ΄μ§μ μ
λ‘λ λ²νΌμ λλ μλ μλνκ² λλ 컨νΈλ‘€λ¬λ₯Ό λ§λ€μ΄ 보μ.
import java.io.File; import java.io.IOException; import java.io.InputStream; import org.apache.commons.io.FileUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import lombok.extern.slf4j.Slf4j; @Slf4j @Controller public class FileUploadController { // λ무 κ°λ¨ ... @RequestMapping("/form") public String form() { return "form"; } @RequestMapping(value = "/upload", method = RequestMethod.POST) public String upload(@RequestParam("file") MultipartFile multipartFile) { log.info("### upload"); File targetFile = new File("/home1/irteam/" + multipartFile.getOriginalFilename()); try { InputStream fileStream = multipartFile.getInputStream(); FileUtils.copyInputStreamToFile(fileStream, targetFile); } catch (IOException e) { FileUtils.deleteQuietly(targetFile); e.printStackTrace(); } return "redirect:/form"; } } upload μμ²μ΄ λ€μ΄μ€λ©΄ fileμ΄λΌλ μ΄λ¦μ νλΌλ―Έν°λ‘ MultipartFileμ λ°κ³ νμΌμ μ΄λ¦μ νμΈ ν μ€νΈλ¦Όμ μ½μ΄ νΉμ κ²½λ‘μ νμΌλ‘ μ μ₯νλ λ‘μ§μ΄λ€. κ·Έλ€μ /formμ μ μνκ² λλ©΄ λμ€λ νΌ νλ©΄μ λ§λ€μ. μ΄κ²λ μμ£Ό μ¬ννκ²!
<h1>νμΌ μ
λ‘λ</h1> <form action="/upload" method="post" enctype="multipart/form-data"> <input type="file" value="νμΌ μ ν" name="file"/> <input type="submit" value="μ
λ‘λ"/> </form> multipart/form-data λΌλ Content-Type μ λͺ
μν΄μ£Όκ³ νμΌμ μ ννλ©΄ /uploadλ‘ POSTμμ²μ νλλ‘ μ€μ νλ€. μ΄λ κ² λλ©΄ λ무 κ°λ¨νκ² + μ΄μμμ΄ νμΌμ΄ μ
λ‘λκ° μ λλ μ΄κ² μ΄μΌκΈ° ν 꺼리μΈκ°(?) μΆμμ λλ‘ μ¬ννλ€.
κ·Έλ°λ° νμΌ ν¬κΈ°κ° ν¬λ€λ©΄? μ€λ§ νμΌ μ
λ‘λ νλ μ©λμ΄ ν¬κ² μ΄?… μ μ§ νμΌμ μ©λμ΄ ν¬λ©΄ λ¬Έμ μμκ² κ°μλ°… μΆμ² : https://m.blog.naver.com/naibbo0407/30170815180" μ€λ§ νμΌ μ
λ‘λ νλ μ©λμ΄ ν¬κ² μ΄?… μ μ§ νμΌμ μ©λμ΄ ν¬λ©΄ λ¬Έμ μμκ² κ°μλ°… μΆμ² : https://m.blog.naver.com/naibbo0407/30170815180 κ°λ°μ νλ€λ³΄λ©΄ νμ μκ°ν΄μΌ ν λΆλΆμ€μ νλκ° λ°λ‘ νμ₯μ±μΈκ² κ°λ€. μ΄ λΆλΆμμ μμ λ¬Έμ κ° λμλ κ². νμλ³΄λ€ μ©λμ΄ ν° νμΌμ΄ μ
λ‘λκ° λλ©΄μ (νμ 3~400MB μλ€κ° 3~4GBμ λμ νμΌμ΄ μ
λ‘λκ° λλ λ§€μ§) μ
λ‘λκ° μλλ μν©μ΄ λ°μνμλ€. λΉμ°ν λ¬Έμ κ° λ°μνλ©΄ λκ΅°κ° λ§νλ― λ‘κ·ΈλΆν° μ΄ν΄λ³΄μλλ° Apache - (AJP) - Tomcat μΌλ‘ ꡬμ±λ νκ²½μμ tomcat λ‘κ·Έμ ### uploadλΌλ λ‘κ·Έκ° μκ³ μνμΉ λ‘κ·Έμ 502 μλ¬κ° λ°μν κ²μ΄μλ€. μ ν°μΌ λ‘κ·Έλ μλ¨κ³ κ·Έμ μ μλ¬κ° λ°μνμμκΉ? μ΄λλΆν° (κ·Όκ±°μλ μΆμΈ‘μ νλ©°…) κ³ λκ³Ό μκ²½μ μ½μ§μ νκΈ° μμνκ² λλ€. ν°μΌ λ²μ μ΄ λ¬Έμ μΌκΉ? λ‘κ·Έκ° μμ°νλ€λ©΄ λ€λ₯Έ νν°λ μΈν°μ
ν°μμ 무μΈκ°λ₯Ό λ¨Ήκ³ (?)μλ건 μλκΉ? μ κΉ, κ·Όλ° μλ λμ©λ μ
λ‘λκ° λκΈ΄ ν΄? νμΌ μ
λ‘λ/λ€μ΄λ‘λ νλ μ¬μ΄νΈ 보면 λ³λ νλ‘κ·Έλ¨μΌλ‘ νλλ°… κΌ¬λΆκΌ¬λΆ λ―Έλ‘μμ ν€λ©λκ²λ§ κ°μλ μ½μ§μ λ¬Έμ λ κ²°κ΅ λ©λͺ¨λ¦¬μ μμλ€. νμΌμ μ
λ‘λ νκ² λλ©΄ ν΄λΉ λ΄μ©μ μ°μ λ©λͺ¨λ¦¬μ λ΄κ² λκ³ λ€ λ΄μ ν λ©λͺ¨λ¦¬μ μλ λ΄μ©μ wasμ μ λ¬ν λ€ HttpServletRequest λ‘ λμ΄μ€κ² λλ€.(Apache > Tomcat) κ·Έλ°λ° νμΌμ μ
λ‘λ νλ©΄μ λ©λͺ¨λ¦¬μ νμΌμ΄ μ¨μ§λ€κ° λ©λͺ¨λ¦¬ λΆμ‘±μΌλ‘ OOMμ΄ λ°μνκ² λλ²λ¦° κ²μ΄μλ€. λν μ€νλ§ νμΌ μ΅λν¬κΈ°λ₯Ό λ³λλ‘ μ§μ νμ§ μκ³ μμκΈ° λλ¬Έμ λ©λͺ¨λ¦¬κ° μΆ©λΆνλ€ νλλΌλ μλ¬κ° λ°μνμ μν©μ΄μλ€.

λꡬλ μ΄λ Έμ λ 빨리 μ΄λ₯Έμ΄ λκ³ μΆμ΄ νλ κ² κ°λ€. μκ°μ΄ 빨리 μ§λκ°κΈΈ λ°λΌκ³ , 빨리 μ΄λ₯Έμ΄ λκ³ μΆλ€λ κ°μ ν¨μ΄ μμ§λ§ μ΄μνκ²λ κ·Έλ μκ°μ΄ μ²μ²ν κ°λ κ²μ²λΌ λκ»΄μ‘λ€. λ°λ©΄, μκ°μ΄ μ²μ²ν κ°μΌλ©΄ νλ λκ° μλ€. λ± μ§κΈ. λ¨λ€μ μμ΄μ΄μ΄μΌνμμμμ°μ°λͺ¨μ₯κΈνΌ μ΄λΌκ³ λΆλ₯΄λ©° μκ°μ΄ λλ¦¬κ² κ°λ€κ³ 빨리 μ£Όλ§μ΄ μμΌλ©΄ μ’κ² λ€κ³ νμ§λ§ μμ¦μ νμλ μ λ°λλ€. λ°©κΈ μΆκ·Όν κ² κ°μλ° μ΄λμκ° ν΄κ·ΌμΈμ¬λ₯Ό μ£Όκ³ λ°κ³ μλ€. 무μΈκ°μ νλ¦° κ² κ°λ€. λ²μ¨ μ¬ν΄λ μ λ°μ΄ μ§λκ°κ³ λ¨κ±°μ΄ μ¬λ¦κ³Ό ν¨κ» νλ°μ μ΄ μμλμλ€.
κ·Έλμ 빨리 μ§λκ°λ…μΆμ² : https://m.blog.naver.com/kong6482/220584667861" κ·Έλμ 빨리 μ§λκ°λ…
μΆμ² : https://m.blog.naver.com/kong6482/220584667861 μ΄μ κΉμ§λ 12μ λ§ μ¦μμ ν ν΄λ₯Ό λ°λΌλ³΄κ³ 리뷰λ₯Ό νμλλ° κΈλλΌλ κΈμ°κΈ° λͺ¨μμ κ°μ
μ νκ² λμ΄ μλ°κΈ° 리뷰λ₯Ό ν΄λ³΄λ € νλ€. κΈλ λͺ¨μμ 첫 μμ κ° μλ°κΈ° 리뷰 ν¬μ€ν
μ΄λ€. μ¬μ€ 리뷰λ₯Ό μλ°κΈ°μ νλ μ° λ§μ ν ν΄ κΈ°μ€μΌλ‘ νλ μ ν΄μ§ 건 μμ§λ§ λλ₯Ό λ€μ λ°λΌλ³΄κ³ λ€μ‘λ μκ°μ΄ λ§μμλ‘ λ³΄λ€ λ μμΌλ‘ κ°λλ° νμ΄ λ κ±°λΌλ λ°μλ μ΄κ²¬μ΄ μλ€.
νμ¬ μμμμ λ νμ¬μμλ νμ¬μΌμ΄ μ΅μ°μ !μΆμ² : https://m.blog.naver.com/hwee__/221191852972" νμ¬μμλ νμ¬μΌμ΄ μ΅μ°μ !
μΆμ² : https://m.blog.naver.com/hwee__/221191852972 μ΅κ·Όμ νμ₯λκ³Ό λ©΄λ΄ μ€μ λμ¨ μ΄μΌκΈ°λ€. μ κΈ°νκ²λ κ΅° μμ μ₯κΈ°λ₯Ό κΏκΎΈλ νμλ₯Ό μ΄μ μ μνλΌκ³ κΆμ νμλ λλμ₯λκ» λ§€μΌκ°μ΄ λ€μλ μ΄μΌκΈ°μ λΉμ·νλ€.
“μ΄μ λ λ¨μ κ°λ°λ§ νκ³ κΈ°λ₯ꡬνλ§ νλ κ²μ΄ μλλΌ κ·Έ μ΄μμ ν΄μΌ ν μκΈ°κ° λ€κ°μ¨λ€.” “μ¬λλ€ κ΄λ¦¬κ° λ μλ μκ³ μ΄λ ν λΆμΌμ μ λ¬Έκ°κ° λμ΄μΌ ν μλ μκ³ , μ νμ λ³ΈμΈμ λͺ«”
μ¬μ€ κΈ°λ₯ ꡬνμ΄μΌ λꡬλ λ€ ν μ μλ€. λ¨μ§ κ²½νμ λ°λ₯Έ ꡬνμ μλλ μμ μ±μ μ°¨μ΄κ° μλκΉ μκ°ν΄λ³Έλ€. κ·Έλ λ€λ©΄ κ·Έ μ΄μμ μ΄λ»κ² ν΄μΌ ν κΉ? μ λ΅μ μκ² μ§λ§ νμλ κ·Έ μ΄μμ ν΄λ³΄λ € μ°μ νμ λμμ΄ λκΈ° μν΄ μ¬λ¬ κ°μ§ μλν ν΄ λ€μ λ§λ κ² κ°λ€. λ³΄λ€ κΈ°λ₯ κ°λ°μ μ§μ€νκ³ λ¨μ λ°λ³΅μ μΈ μ
무λ μμ€ν
μ΄ ν μ μλλ‘. κ·Έλ κ² ν΄λ€μ λ§λ€μ΄ κ°λ©° μκ°νμ§ λͺ»ν λΆλΆλ€μ λ°°μ°κ² λκ³ λμ€μ κ·Έκ±Έ λ μ¬μ©νκ² λλ, λ―Έλμ λλ₯Ό μν΄ κ°μ λ‘ λ°°μ°κ³ μλλ―ν λλμ΄λκΉ. μ, λ¬Όλ‘ νμ¬ λ³Έμ°μ μ
λ¬΄κ° μ΅μ°μ μ΄μ§λ§ λ§μ΄λ€. μ΄μ¨λ μν¨ μΌμ μ°μ μ°¨μ§ μμ΄ μ νκ³ μν€μ§λ μμ μΌμ μ°Ύμμ νλ €κ³ λ
Έλ ₯νλ κ² κ°λ€. νμ μν΄μ, κ³§ λλ₯Ό μν΄μ. μ μ΄λ νμ¬μμ μλ μκ° μμμλ λ€λ₯Έ κ³³μ νλ μ νκ³ νμ¬ μ
무μ μ λ
νλ €κ³ λ
Έλ ₯νλ κ² κ°λ€.
μΈλΆ νλ λΆμ‘±ν μκ°μ μͺΌκ°λ©΄μ λ°μ
μ΄λ μΈλ―Έλμ μ°Έμ¬νκ³€ νμλ€. κ·Έλ¦¬κ³ λ§λ₯ λ£κ³ λ§ μ€μ§ μμκ³ “νμ¬μ μ°Έμ¬νλ©΄ 무쑰건 μ§λ¬Έ νλλ νμ"λΌλ λμμ μ½μμ μ§ν€λ©° μ 리ν λ΄μ©μ λΈλ‘κ·Έμ ν¬μ€ν
νκΈ°λ νμλ€.
μ¬ν΄ 첫 λ°ν!" μ¬ν΄ 첫 λ°ν! λμμ΄λμ κ°λ°μκ° ν¨κ»νλ ν¬κ²λν€μ μ§ννκΈ°λ νμλ€. ν¬κ²λν€μ μ½ ν λ¬ λμ μ§νλλ ν΄μ»€ν€μΌλ‘ ν루 λλ λ¬΄λ° 2μΌ λμ νλ κΈ°μ‘΄ ν΄μ»€ν€κ³Ό λ€λ₯΄λ€. μ΄ κΈ°κ° λμ ν λ΄μμ μμ λ‘κ² μΌμ μ μ‘°μ ν μ μλ€. μ°λ¦¬ νμ μ½ 7μ£Όμ κ±Έμ³ “λλ€ λ§νΈ ν μΈ μ 보λ₯Ό μλ €μ£Όλ μ±” μ λ§λ€κ² λμλ€. νμλ API μ λ°μ λν΄ λ΄λΉμ νμκ³ μμ λΆλΆμ΄μμ§λ§ μΉμ¬μ΄νΈλ κ°λ¨νκ² λ§λ€μ΄ 보μλ€. μ무κ²λ μλ λ°±μ§μνμμ μμνλ €λ λ§λ§νμ§λ§ νκΈ°μμλ μ μλ―μ΄ λ€μ ν΄λ³΄λΌκ³ νλ©΄ λ¨Έλ¦Ώμμ μ 체 μν€ν
μ²κ° κ·Έλ¦ΌμΌλ‘ κ·Έλ €μ§ λ§νΌ μμ κ°μ΄ μκ²Όλ€. νΉν μ λ§ μ’μ νμλ€κ³Ό ν¨κ» νμ
ν μ μμ΄μ λ무 μ’μλ€.
λ΄κ³΅ μ°λ§ ν λ¬μ 2κ° μ΄μ λΈλ‘κ·Έ κΈμ μμ±νλ λͺ©νκ° μμλ€. κ·Έλ°λ° μ§λλ¬μ μ΄μ¬λ₯Ό νλ€ λ³΄λ (νκ³…) λͺ©νλ₯Ό λ¬μ± ν μκ° μμλ€. νμ§λ§ λλ¦ ν리ν°κ° μλ κΈμ μ°λ €κ³ λ
Έλ ₯νκ³ PVλ μλ
λ³΄λ€ μ‘°κΈμ© μ€λ₯΄κ³ μλ κ² κ°μ λ΄μ¬ κΈ°λΆμ΄ μ’λ€. κ·Έλ¦¬κ³ μλ
λ§λΆν° μμν νμμ 첫 ν μ΄νλ‘μ νΈ μΈ κΈ°μ λΈλ‘κ·Έ ꡬλ
μλΉμ€ μ μ΄λ°μ λ° κΈ°λ₯μ μΆκ°νμλ€. μ€λ§ 1000λͺ
μ΄ λκ² κ΅¬λ
νκ² μ΄?

μ€νλ§ κΈ°λ°μ μΉ μ΄ν리μΌμ΄μ
μ λ§λ€λ€ 보면 μμ²μ μ²λ¦¬νλλ° λ§¨ μ²μμ μμΉνκ³ μλ Controller(μ΄ν 컨νΈλ‘€λ¬)λΌλ λ μ΄μ΄λ₯Ό λ§λ€κ² λλ€. κ·Έλ΄λλ©΄ μ¬μ©μκ° μ΄λ€ μμ²(Request)μ νμλμ§μ λν΄ νμΈμ΄ νμν μ μλ€. λ¬Όλ‘ νμΈμ μν΄λ 무방νμ§λ§ κ°κΈμ λ‘κΉ
μ μμ€ν
λ‘μ§μ μν₯μ μ£Όμ§ μλ λ²μμμ μ΅λν λ€μνκ² λ―Έλ¦¬ ν΄λλκ² λμ€μ μ μ§λ³΄μμ νΈν μ μλ€. (μμ μ‘°μ§μ₯λκ»μ λ§μνμ κ² μμ§λ λ¨Έλ¦Ώμμ κ½ μ리μ‘κ³ μλ€…) μ~μ£Ό μΌλ°μ μΌλ‘, 컨νΈλ‘€λ¬μμλ λ€μκ³Ό κ°μ΄ λ©μλ λ¨μλ‘ νλΌλ―Έν°λ₯Ό μ§μ λ‘κΉ
νκ² λλ€.
@Slf4j @RestController public class SampleController { @GetMapping("/test1") public String test1(@RequestParam String id) { log.info("id : {}", id); return "length : " + id.length(); } } μ΄λ κ² λλ©΄ μ¬μ©μκ° GET /test1 μ΄λΌλ μμ²μ 보λΌλ μ΄λ€ νλΌλ―Έν°λ‘ νΈμΆνμλμ§μ λν΄ λ‘κΉ
μ΄ λ¨κ² λλλ° νμ log.info("id : {}", id); κ³Ό κ°μ΄ μλμΌλ‘ λ‘κΉ
μ λ¨κ²¨μΌ νλ λΆνΈν¨μ΄ μκΈ΄λ€. λ¬Όλ‘ κΌΌκΌΌνκ² λ©μλλ§λ€ λ‘κΉ
μ μ μ΄μ£Όλ©΄ μ ν λ¬Έμ λ κ² μμ§λ§ μ΄λ¬ν 컨νΈλ‘€λ¬ ~ λ©μλκ° νλκ°κ° μλ μμ λλ μλ°±κ°μΌ κ²½μ°μ κ·Έλλ§λ€ λ‘κΉ
μ μ μ΄μ€μΌ νλ λΆνΈν¨μ΄ μμ μ μλ€. λν μμΉ« κΉλ°νκ³ λ‘κΉ
μ λΉΌλ¨Ήκ³ λ°°ν¬λ₯Ό νκ² λ κ²½μ° λͺ¨λν°λ§μ λ‘κΉ
μ νμ§ μμμ λ€μ λ‘κΉ
νκ³ λ°°ν¬λ₯Ό νλ, λ³κ²λ μλλ°(?) “μ λ§ λΆνΈν” μν©μ΄ μμ μ μλ€. μ΄λ² ν¬μ€ν
μμλ μ¬μ©μμ μμ²μ λͺ¨λν°λ§ νκΈ° μν΄ μ»¨νΈλ‘€λ¬λ§λ€ μ½λλ₯Ό μμ±ν΄κ°λ©° λ‘κΉ
μ νλκ²μ΄ μλλΌ HttpServletRequestWrapper λΌλ κ²κ³Ό Filter, AOPλ₯Ό μ΄μ©νμ¬ Requestμ μ 보λ₯Ό νκ³³μμ μ°μνκ² λ‘κΉ
νλ λ°©λ²μ λν΄ μμλ³΄κ³ μ νλ€.
μꡬμ¬ν μ κ°λ°νμμ!μΆμ² : https://gfycat.com/ko/brightevilaoudad" μ κ°λ°νμμ!
μΆμ² : https://gfycat.com/ko/brightevilaoudad ν¬μ°μ¬κ° νλλ λΉ¨κ° μ²μ 보며 λμ§νλ ν©μμ²λΌ (μ°κ³ 보λ λ무 TMI κ°λ€….) λΉμ₯ μ½λ©μ μμνλ©° κ°λ°μ ν μλ μμ§λ§ μ μ μνλ κΈ°λ₯μ΄ λ¬΄μμΈμ§ μ²μ²ν μ 리νκ³ λμ΄κ° νμκ° μλ κ² κ°λ€. (μ΄μ©λ μ€νλ € νμκ° λ λΉ λ₯Έ κ°λ°μ νκ² λλκ² κ°λ€.)
GET, POST λ± λ€μν http method λ‘ κ΅¬νλ λͺ¨λ 컨νΈλ‘€λ¬μ νλΌλ―Έν°μ κΈ°ν Request μ λ³΄κ° λ‘κΉ
μ΄ λμΌ νλ€. 컨νΈλ‘€λ¬, λ©μλκ° λμ΄λ λλ§λ€ λ³λμ μ½λ μΆκ° μμ΄ νκ³³μμ 곡ν΅μ μΌλ‘ λ‘κΉ
μ΄ λμΌ νλ€. URL μ€ νΉμ ν¨ν΄μΌλ‘ λ€μ΄μ€λ μμ²μ λ€λ₯Έ λ°©μμΌλ‘ λ‘κΉ
μ νκ±°λ, λ‘κΉ
μμ μ μΈν μ μμ΄μΌ νλ€. μμ λ§νλ― λ€λ₯Έ λΉμ§λμ€ λ‘μ§μ μν₯μ μ£Όμ§ μμμΌ νλ€. ꡬννκΈ° - Request μ νλΌλ―Έν° μ 리 Request μ λͺ¨λ λ‘κΉ
μ νκ³³μμ μ²λ¦¬νκΈ° μν΄μ filter(νν°)λ₯Ό νμ©νμλ€. νν°λ Dispatcher servletμ μλ¨μ μμΉνκ³ μκΈ° λλ¬Έμ λͺ¨λ μ 보λ₯Ό νμΈν μ μλλ° μ©μ΄νλ€. λ¬Όλ‘ μΈν°μ
ν°λ₯Ό νμ©ν΄μλ λ°©λ²μ΄ μκ² μ§λ§ λ³Έ ν¬μ€ν
μμλ νν°λ₯Ό νμ©ν΄μ ꡬννλκ²μ λͺ©μ μΌλ‘ νλ€. (μ¬μ€ μΈν°μ
ν°λ‘ λͺλ² μλν΄λ³΄λ€κ° μ€ν¨ν΄μ…μ μ )
Spring MVC Request Life CycleμΆμ² : https://justforchangesake.wordpress.com/2014/05/07/spring-mvc-request-life-cycle/" Spring MVC Request Life Cycle
μΆμ² : https://justforchangesake.wordpress.com/2014/05/07/spring-mvc-request-life-cycle/ Filterλ₯Ό λ§λ€κΈ° μ μ Filterμμ μ¬μ©ν μ£Όμ ν΅μ¬(?) ν΄λμ€κ° νμνλ° HttpServletRequest λ₯Ό Wrapping ν΄μ μ¬μ©νκΈ° μν΄ HttpServletRequestWrapperλ₯Ό μμλ°λ ν΄λμ€λ₯Ό λ§λ€μ. Request μ λ΄κ²¨μλ param κ³Ό bodyλ‘ μμ²μ΄ λ€μ΄μ¬ κ²½μ° bodyμ μλ λ΄μ©μ param μ λ΄λ λ‘μ§μ΄λ€. μ£Όμ μ€λͺ
μ μ½λ μμμ μ£ΌμμΌλ‘ μ€λͺ
νκ² λ€.
public class ReadableRequestWrapper extends HttpServletRequestWrapper { // μμ private final Charset encoding; private byte[] rawData; private Map<String, String[]> params = new HashMap<>(); public ReadableRequestWrapper(HttpServletRequest request) { super(request); this.params.putAll(request.getParameterMap()); // μλμ νλΌλ―Έν°λ₯Ό μ μ₯ String charEncoding = request.getCharacterEncoding(); // μΈμ½λ© μ€μ this.encoding = StringUtils.isBlank(charEncoding) ? StandardCharsets.UTF_8 : Charset.forName(charEncoding); try { InputStream is = request.getInputStream(); this.rawData = IOUtils.toByteArray(is); // InputStream μ λ³λλ‘ μ μ₯ν λ€μ getReader() μμ μ μ€νΈλ¦ΌμΌλ‘ μμ± // body νμ± String collect = this.getReader().lines().collect(Collectors.joining(System.lineSeparator())); if (StringUtils.isEmpty(collect)) { // body κ° μμκ²½μ° λ‘κΉ
μ μΈ return; } if (request.getContentType() != null && request.

νμ¬μΌμ νλ€ λ³΄λ©΄ μν€λ λλ‘ νΉμ νμ λͺ©νμ λΆν©νκΈ° μν΄ μ΄μ© μ μμ΄ ν΄μΌ νλ μΌμ νκ² λλ€. κ·Έλ¬ν μΌμ΄ μ¬λ―Έμκ³ κ²°κ³Όλ¬Όμ λν λ§μ‘±λκ° 100% λΌλ©΄ λ€νμ΄μ§λ§ κ°νΉ μ¬λ―Έλ μκ³ μμΌμ νλ μΌμ λ°€μ κΌ¬λ° μ κ°λ©΄μ μμ±μ ν΄λ μ© κ·Έλ κ² λ§μ‘±μ€λ½μ§ λͺ»ν κ²½μ°κ° λλΆλΆμΈ κ² κ°λ€.(λ¬Όλ‘ νμ¬μΌμμ μμ λ§μ μΈμ¬μ΄νΈλ₯Ό μ°Ύλλ€λ©΄ κΈμ첨νκ² μ§λ§… + λ§€λ² νμ¬μΌμ΄ μ¬λ―Έμκ³ νκΈ° μ«μ건 μλ) μΈμ λΆν°μΈμ§ νμλ μ΄λ¬ν λΆλΆμ κ°μ¦μ λλΌλ©° νμ¬μλ λ³λλ‘ λ¬΄μΈκ°λ₯Ό λ§λ€μ΄ λ³΄κ³ μΆμ λ§μμ΄ λ¬΄λ무λ μ겨λ μ¦μ facebook νμλΌμΈμμ κ°λ°μμ λμμ΄λκ° μ½ 7μ£Όκ° νλ‘μ νΈλ₯Ό μ§ννλ D.light ν¬κ²λν€ μ΄λΌλ νμ¬κ° μλ€λ κ²μ λ°κ²¬νκ³ λλ¦ μ μ±μ€λ μ§μμλ₯Ό μμ± ν ν©κ²© λ©μΌμ λ°κ² λλ€. (GDG Facebook ν΄λΉ κ²μκΈ) μ΄λ² ν¬μ€ν
μμλ ν΄μ»€ν€κ³Όλ μ΄μ§ μ±κ²©μ΄ λ€λ₯Έ D.light ν¬κ²λν€μ μ§ννλ©΄μ λκΌλ λΆλΆλ€κ³Ό μ§νν κ²°κ³Όλ¬Όμ λν΄ κ°λ΅ν 리뷰λ₯Ό ν΄λ³΄λ©° μ λ§ κΈνμ²λΌ μ§λκ° μ½ 7μ£Όκ°μ λμ΄μΌ 보λ μκ°μ κ°κ³ μ νλ€.
ν λΉλ© λλ λͺ»λ§μ£ΌμΉ μ λλ‘ μ΄μν 첫λ Team. κ·Έν½" λλ λͺ»λ§μ£ΌμΉ μ λλ‘ μ΄μν 첫λ
Team. κ·Έν½ μ΄ 6κ° ν μ€μ νμλ μ¬μ λμμ΄λ λ λΆ, λ¨μ μλλ‘μ΄λ κ°λ°μ λ λΆμ ν¬ν¨ν νμ μνκ² λμλ€. 5λͺ
μ€ ν΄μ»€ν€ μ°Έμ¬ κ²½νμ΄ μλ€λ μ΄μ λ§μΌλ‘ μ¬μ λμμ΄λ λΆκ»μ νμ₯μ΄ λμκ³ , 7μ£ΌλΌλ μκ°μ΄ μ λ§ κΈνκ² μ§λκ° κ² κ°λ€λ μ΅μ§(?) μ΄μ λ₯Ό λ€λ¨Ήμ¬ κ·Έν½μ΄λΌλ ν μ΄λ¦μ΄ μ ν΄μ‘λ€. κ·Έλ κ² “μ°λ¦¬κ° μ λ§ λ¬΄μμ λ§λ€ μ μμκΉ?” νλ μκ΅¬μ¬ μμ νλ‘μ νΈκ° μμμ΄ λμλ€.
νλ‘μ νΈ μ§ν μ λ° μ κΈ°νκ²λ μ°λ¦¬ 5λͺ
μ κ°κ° μ¬λ μ§μμ΄ μ λΆ λ¬λλ€. (μ¬μ§μ΄ ν λΆμ λ§€μ£Ό μ λ©λ¦¬ μΆ©μ²λ¨λ μ²μμμ μ¬λΌμ€μ
μΌ νλ μκ³ λ₯Ό γ
γ
) λ§€ μ£Όλ§λ§λ€ μ€νλΌμΈμΌλ‘ λ§λμ νμλ₯Ό μ§ννλ€. κ·ΈλμΌ κΈΈλ€λ©΄ κΈΈκ³ μ§§λ€λ©΄ μ§§μ 7μ£Ό μμ μμ±λ λμ κ²°κ³Όλ¬Όμ λ§λ€ μ μμ κ² κ°μμμλ€. νλ‘μ νΈμ μ£Όμ λ₯Ό μ νλ μμ΄λμ΄ νμμμ μ ν΄μ§ μ°λ¦¬μ λͺ©νλ “λλ€ λ§νΈ ν μΈ μ 보λ₯Ό μλ €μ£Όλ μ±"μ λ§λ€κΈ°λ‘ νμλ€.
μκ°κ°λμ€ λͺ°λλ μμ΄λ°μ΄μ
νμ" μκ°κ°λμ€ λͺ°λλ μμ΄λ°μ΄μ
νμ νμν¬κ° μ€μν ν¬κ²λν€ μμλ λΆκ΅¬νκ³ μ¬λ μ²μ¬ λμμ΄λ, μ²μ¬ κ°λ°μμ²λΌ μΌλΉλ°± μ€νμΌλ‘ λλ± λ§λλ κ·Έλ° νλ‘μ νΈμ μ§ν λ°©μμ νΌνλ €κ³ μ°λ¦¬ λͺ¨λκ° λ
Έλ ₯νμλ€. λλλ‘μ΄λ©΄ μ΄λ κ² λͺ¨μΈ λ€μ― λͺ
μ΄ νλ§μ νλ»μΌλ‘ κ°μκ° μκ°νλ ν¬κΈ°μ μμ λ€λ₯΄κ² μ§λ§ μ΄ νλ‘μ νΈλ₯Ό ν΅ν΄ 무μμ΄λΌλ λ°°μΈ μ μμμΌλ©΄ νλ€. λμμ΄λ λΆλ€μ μλ‘ λμμΈνμ μμμ λν΄ κ³΅μ λ₯Ό νλ©΄μ κ°μ ν΄ λκ°λ λͺ¨μ΅κ³Ό, μλλ‘μ΄λ κ°λ°μ λλΆμ (κ±°μ λ§€μΌ) λ°€λ§λ€ μλ‘ μ¬λμμ κ°λ° λ°©λ²λ‘ μ λν΄ μ€ν°λλ₯Ό νλ λͺ¨μ΅μ΄ 보기 λ무 보기 μ’μλ€. λ¬Όλ‘ νμλ μ무κ²λ μλ νκ²½μμ λ°±μλ μλ²λ₯Ό ꡬμΆνκ³ APIλ₯Ό λ§λλ κ³Όμ μμμ μ λ§ λ§μκ²μ λ°°μΈ μ μμλ€. κ·Έλ κ² μκ°μ΄ νλ¬ λ§μ§λ§ λ°ννλ μ λ μ νμ λͺ λΆκ³Ό ν¨κ» κΌ¬λ° λ°€μ μμ°λ©° νλ‘μ νΈ κ²°κ³Όλ¬Όμ μμ±λλ₯Ό λμ΄λλ° λ
Έλ ₯νμκ³ νμ κ°μΈμ μΌλ‘ μμ£Ό μ±κ³΅μ μΌλ‘ νλ‘μ νΈλ₯Ό λ§λ¬΄λ¦¬ν μ μμλ€.
κ°λ° μ§ν μλλ‘μ΄λ κ°λ°μλΆλ€μ μ½νλ¦° κΈ°λ°μΌλ‘ κ°λ°μ νμλ€. μ¬λ¬ λμμΈ ν¨ν΄κ³Ό λ€μν κΈ°μ λ€μ μ¬μ©νμλ€κ³ λ€μλλ° νμλ μμ½κ²λ λ°±μλ κ°λ°μ νλ€ λ³΄λ μ λΆλ₯Ό μ΄ν΄νμ§λ λͺ»νμλ€. μμ μ ν μ΄ νλ‘μ νΈλ₯Ό νμ΄μ¬ κΈ°λ°μΌλ‘ ν΄λ³Έ κ²½νμ΄ μμ΄μ Flask λλ Django κΈ°λ°μΌλ‘ API μλ²λ₯Ό ꡬμΆν΄λ³ΌκΉ νκ³ κ³ λ―Όνμλ€. νμ§λ§ (Spring Boot κΈ°λ°μΌλ‘λ ν΄λ³΄κ³ μΆμκ³ ) νμ΄μ¬λ³΄λ€λ μλ° κΈ°λ°μΌλ‘ λ€μν μ΄ν리μΌμ΄μ
μ μꡬ μ¬νμ κ°λ°νλλ° μ‘°κΈ λ λ₯μν κ² κ°μμ Spring Boot κΈ°λ°μΌλ‘ κ°λ° νκ²½μ ꡬμ±νμλ€. μλ²λ AWS ν리ν°μ΄μ EC2λ₯Ό λ°κΈλ°κ³ DB λν AWSμμ μ 곡ν΄μ£Όλ RDS(mysql)μ λ°κΈλ°μ ꡬμ±νμλ€. κ·Έλ¦¬κ³ DNSλ μμ μ λ¬΄λ£ λλ©μΈμ μ°Ύλ€κ° μκ² λ http://mooo.com/ λΌλ μλΉμ€μμ λ°κΈλ°μ μ°κ²°νμκ³ , νλ‘μ νΈ κΈ°λ₯ μ€μ μλ²μμ μ±μΌλ‘ νΈμλ₯Ό νλ κΈ°λ₯μ΄ μμλλ° Firebaseλ₯Ό νμ©ν΄μ ꡬμ±ν μ μμλ€.
μ¬μ©ν κΈ°μ λ€" μ¬μ©ν κΈ°μ λ€ Entity Relationship Diagram (ERD) λ 무λ£λ‘ μΈν°λ·μμ μ¬μ©ν μ μλ ν΄μ΄ μλμ§ μ°Ύλ€λ³΄λ http://aquerytool.

μ€λ¬΄μμ μλ° κΈ°λ°μΌλ‘ κ°λ°μ νκ³ μλΉμ€λ₯Ό μ΄μμ νλ€λ³΄λ©΄ μ²μμ μλ¬΄λ° λ¬Έμ κ° μλ€κ° μ¬μ©μκ° λͺ°λ¦¬λ λ± μ΄λ²€νΈμ±μΌλ‘ νΈλν½μ΄ λ§μμ§ κ²½μ° κΌ λ¬Έμ κ° μκΈ°κΈ° λ§λ ¨μ΄λ€. κ·Έλ΄λλ©΄ λ€λ¦κ² λΆλ΄λΆλ΄ μμΈμ μ°Ύκ³ κ°μ νκΈ° λ°λΉ μ§κ² λλ€. (μλ§ μλΆλ€μκ² νΌλλ©΄μ?γ
γ
) νμμ μ΄λ° μ±λ₯λ¬Έμ λ₯Ό κ°μ νκ³ λ―Έλ¦¬ λͺ¨λν°λ§ ν μμλ λΆλΆμ λν΄ κ΄μ¬μ κ°κ³ μμλ μ°°λ, μ°μν νμ λ€μμ 5μ μ°μν ν
ν¬ μΈλ―Έλλ₯Ό νλ€κΈ°μ λΆλ΄λΆλ΄ μ₯λ¬Έμ κΈλ‘ μ μ²μ νμκ³ μ΄μ΄ μ’μ λΉμ²¨μ΄ λμλ€. νμ°½ νμ¬μμ μλ‘μ΄ μλΉμ€ μΆμ, κ·Έλ¦¬κ³ μ μ μ€μ¬κ°λ©° λ³λλ‘ μ§ννκ³ μλ ν μ΄νλ‘μ νΈ λ± μ¬λ¬κ°μ§λ‘ λ°μ μκΈ°μμ§λ§ νΉν μμ λΆν° λ΅κ³ μΆλ μ΄μλ―Όλκ»μ μ§μ κ°μλ₯Ό ν΄μ£Όμ λ€κΈ°μ νΌκ³€ν μ¬μ μ μ΄λκ³ μΈλ―Έλμ μ°Έμνμκ³ κ·Έ νκΈ°λ₯Ό μ μ΄λ³΄κ³ μ νλ€.
λλ μ΄λ‘ λ§λμ λ°νμλ£λ₯Ό 곡μ ν΄ μ£Όμ
¨μ§λ§ μ μκΆ λ¬Έμ λ μκ³ ν΄μ νμκΈ°μ€μμ μ΄ν΄ν λΆλΆμ λν΄μλ§ κ³΅μ νκ³ μ νλ€. λλΆμ΄ κ·Έλ₯ λ£κ³ μ΅λ¬΄μμ²λΌ λ°νλ΄μ© κ·Έλλ‘λ₯Ό 곡μ νλ건 μλ―Έκ° μλ€κ³ μκ°λμ΄…
ν¬μ€ν°λ§ λ΄λ λ²μ¨λΆν° κ°μ΄μ΄ λ΄λ€(?)." ν¬μ€ν°λ§ λ΄λ λ²μ¨λΆν° κ°μ΄μ΄ λ΄λ€(?). μ±λ₯ ꡬκΈμμ μμ±ν μ±λ₯μ΄ μ€μν μ΄μ λΌλ μν°ν΄μ 곡μ ν΄ μ£Όμ
¨λ€. (μκ°μ΄ λλ€λ©΄ νλ² μ½μ΄λ³΄κΈΈ κ°μΆ, λ¬΄λ € νκΈ!) μ΄ν리μΌμ΄μ
μμ μ±λ₯μ μ¬μ©μμ μ¦κ°, μ΄νμ¨, μλ΅μλμ μν₯μ΄ μκ³ μ΄λ κ²°κ΅ μΆκ΅¬νλ κ°μΉ(μ΄λ₯Ό ν
λ©΄ μμ΅)μ μ§λ©΄νλ€κ³ νλ€. μ¬μ©μλ μ΄λ κ΄μ μμ λ°λΌλ³΄λκ°μ λ°λΌ λ¬λΌμ§κ³ κ° κ΄μ μ λ°λΌ μ±λ₯μ μ±κ²¨μΌ νλ λΆλΆμ΄ λ¬λΌμ§λ€. μκ°μ μ²μ νλ μμ μμμ μ¬μ©μμ λ΄μ€ νμ΄μ§λ₯Ό μ½λ μμ μμμ μ¬μ©μλ κ° μ±κ²©μ΄ μμ°ν λ€λ₯Έκ²μ²λΌ.
μμ€ν
κ΄λ¦¬μ λ±λ‘λ / λ±λ‘λμ§ μμ μ¬μ©μ μλ² κ΄μ λ‘κ·ΈμΈλ / λ‘κ·ΈμΈ νμ§ μμ μ¬μ©μ μ±λ₯ ν
μ€ν° κ΄μ Active User μλ²μ λΆνλ₯Ό μ£Όλ μ¬μ©μ λ©λ΄λ λ§ν¬λ₯Ό λλ₯΄κ³ κ²°κ³Όκ° λμ€κΈ°λ₯Ό κΈ°λ€λ¦¬λ μ¬μ©μ μ±λ₯ν
μ€νΈμ Vuserμ κ±°μ λμΌ ( Vuser : κ°μμ¬μ©μ(virtual user) ) Concurrent user μλ²μ λΆνλ₯Ό μ£Όκ³ μκ±°λ, μ€ κ°λ₯μ±μ΄ λ§€μ°λμ μλΉμ€μ μ μμ€μΈ μ¬μ©μ μΉ νμ΄μ§λ₯Ό λμλμ μ¬μ©μ TPS(Transaction Per Seconds)λ μ΄λΉ μΌλ§λ λ§μ μμ²μ μ²λ¦¬ν μ μλμ§μ λν μμ€ν
μ μ λμ μΈ μμΉλ‘ λ³Όμμλ€. (κ°λ°μλ μ΄λμν©μμλ μ§ λμΆ© κ°μΌλ‘ μ΄μΌκΈ° νμ§λ§κ³ μ νν μμΉλ‘ μ΄μΌκΈ° ν΄μΌνλ€λ λΌλ₯Ό λ리λ μ‘°μΈκ³Ό ν¨κ»…) TPSλ Scale out/upμ ν΅ν΄ μ¦κ°μν¬μ μμ§λ§ Response Time μ λΆκ°λ₯νλ€. λ¬Όλ‘ μ΄ν리μΌμ΄μ
μ νλνλ©΄ λ μμΉ λͺ¨λ κ°μ μ΄ κ°λ₯νλ€. μ΄λ¬ν TPSμ Response Timeμ μ΅λμΉλ μΆμμ μ λ°λμ ν
μ€νΈλ₯Ό ν΅ν΄ μκ³ μμ΄μΌ μ΄μλ°μμ λμνλλ° μ μ©νλ€. Bottleneck μ¦ λ³λͺ©μ μ₯λΉ, μ΄ν리μΌμ΄μ
, μ μ₯μ, μ€μ λ± λ€μν μν©μμ λ°μν μ μλ€. κ·Έμ€μ “μμ£Ό μΌλ°μ "μΌλ‘ κ°μ₯ λ³λͺ©μ΄ λ§μ΄ λ°μνλ ꡬκ°μ DBμ΄κ³ κ·Έ λ€μμΌλ‘ ν΄λΌμ΄μΈνΈ(Web page, App), Networkμ΄ μμ μ μλ€. κ²°λ‘ μ Performance engineering is “Composite Art” of IT λΌλ νλμ λ¬Έμ₯μΌλ‘ μ 리λ₯Ό ν΄μ£Όμ
¨λ€. μ무리 μ΄μ λμμΈκ³Ό μ΄λ ΅κ³ 볡μ‘ν κΈ°λ₯μ΄ μμμ§λΌλ μ±λ₯μ΄ λ·λ°μΉ¨ μλλ€λ©΄ λμ©λ νΈλν½ μν©μμλ 무μλ―Έν΄μ§κΈ° λλ¬Έμ΄λΌκ³ μκ°νλ€.
μλ° μλ°μ μμ¬μ λν΄ μ€λͺ
ν΄ μ£Όμ
¨λ€. ( μμ¬μ λν λ³΄λ€ μμΈν μ€λͺ
μ https://www.whatap.io/blog/12/ μ°Έκ³ ) μΈμ λΆν°μΈκ° JDK λΌμ΄μΌμ€ μ΄μκ° λ§μμλλ° μ€λ¬΄μμ κ°λ°νλ μ
μ₯μμλ java 8 μμλ λ¬Έμ κ° μλκ³ java 11λΆν° λΌμ΄μΌμ€ λ¬Έμ κ° λ³΅μ‘νκ² μκΈΈμ μλ€κ³ νλ€. μ΄λΆλΆμ 곡μλ¬Έμ(?)λ₯Ό μ°Ύμ보λκ² μ’μλ― νλ€. (κ°μΈ λλ νμ¬μμ μ¬μ©ν κ²½μ° μν©μ λ°λΌ λ²μ μ΄μκ° μκΈΈμλ, μμκΈΈμλ μλ 볡μ‘ν λ¬Έμ κ° μμ΄λ³΄μ¬μ… νμλ μ λλ‘ μ΄ν΄νμ§λ λͺ»νλ€γ
)
κ·Έλ¦¬κ³ κ° μλ° λ²μ μμ λ°νν μλ‘μ΄ κΈ°λ₯μ λν΄ μ€λͺ
ν΄μ£Όμ
¨λ€.
Java 8 lambda, stream, default method, LocalDate / LocalTime μΆκ° stream κ³Ό foreach μ μ±λ₯μ κ±°μ μ°¨μ΄ μμ (μ€νλ € κ°λ
μ±μ΄ λλΉ μ§μλ μλ€.) ParallelStream μ ν΄λΉ μ₯λΉμ cpu κ°μλ§νΌ μ€λ λ νμ λ§λ€μ΄ μ¬μ© (μ€νλ € λ
μ΄ λ μ μμΌλ μ μμλ³΄κ³ μ¬μ©ν κ²) Java 9 Compact Strings : char[] > byte[] G1 default GC : https://www.

μ€λ¬΄μμ κ°λ°μ νλ€λ³΄λ©΄ κ³Όκ±° λκ΅°κ° μ ꡬμ±ν΄ λμ λ°₯μ(legacy)μ μκ°λ½λ§ μΉλ λλμΌλ‘ λ‘μ§ κ΅¬νλ§ ν λκ° μλ€. κ·Έλ¬λ€λ³΄λ©΄ κ°μ’
λ μ΄μ΄κ° μ΄λ»κ² ꡬμ±(μ€μ )λμ΄μλμ§λ λͺ¨λ₯΄κ³ κ°νΉ μ€μ μμ λ¬Έμ κ° λ°μνλ©΄ “μ λ΄κ° μ΄κ²λ λͺ¨λ₯΄κ³ μ΄μ κΉμ§ κ°λ°μ ν΄μλ” νλ μκ΄΄κ°μ΄ λ€λ©° λͺμκ°μ μ½μ§νλ κ²½μ°κ° μλ€. κ·Έκ² μ§κΈμ νμμΈκ² κ°λ€. (λλ¬Ό…)
μΆμ² : http://blog.naver.com/PostView.nhn?blogId=ondo_h&logNo=221437452142" μΆμ² : http://blog.naver.com/PostView.nhn?blogId=ondo_h&logNo=221437452142 μ¬μ΄λ νλ‘μ νΈ μ΄κΈ°μ
ν
μ νλ©° νΈκΈ°λ‘κ² spring boot μ΅μ λ²μ μμ dbλ₯Ό μ°λνλ € νλλ° λ§μ μμ λ°λ₯λΆν° ν΄λ³Έ κ²½νμ΄ μ λ€λ³΄λ (spring boot 2 λ²μ μμλ λμ±λ…) μ΄λμλΆν° λ μ€μ μ ν΄μΌν μ§… κ·Έλ¦¬κ³ μ΄λ΄λ 보λ λνλ¨ΌνΈλ₯Ό λ΄λ μ μ΄ν΄κ° μλμ΄ μ½μ§μ ν΄κ°λ©° λΉν©νκΈ° μΌμ€μλ€. μ΄λ² ν¬μ€ν
μμλ μλμ κ°μ ꡬμ±μ νλλ° λͺ©νλ₯Ό λκ³ μ νλ€.
Spring Boot 2 νλ‘μ νΈλ₯Ό μ²μ λ§λ€κ³ mybatis λ₯Ό μ¬μ©ν΄μ mysql μ μ°λνλκ² (AWS μ RDSλ₯Ό μ¬μ©, μΆν RDSμ¬μ©λ²μ λν΄ λΈλ‘κΉ
μμ ) μμ κ°μ μν©μ μ²μ μ νλ λΆλ€κ» λμμ΄ λμμΌλ©΄ νλ λ°λ¨μΌλ‘ μ§§κ²λλ§ νμμ μ½μ§κΈ°λ₯Ό μ¬νν΄λ³΄μ.
Spring boot 2 νλ‘μ νΈ λ§λ€κΈ° νμλ IntelliJλ₯Ό μ¬μ©νκ³ μμ΄μ μλ‘ νλ‘μ νΈλ₯Ό λ§λ€λ €κ³ ν λ ν΄λ¦ λͺλ²λ§μΌλ‘ dependency μ€μ κΉμ§ λ€ ν΄μ£ΌκΈ° λλ¬Έμ νΈνκ³ μ’μλ€. νΉ μ΄ν΄λ¦½μ€λ λ€λ₯Έ IDEλ₯Ό μ¬μ©νκ³ μλ€λ©΄ https://start.spring.io/ μ μ°Έκ³ νλ©΄ λμμ΄ λ κ²κ°λ€. μ¬κΈ°μλ ν΄λ¦ λͺλ²μΌλ‘ IntelliJ μμ ν΄μ£Όλ κ²μ²λΌ λ΄κ° μ¬μ©ν λͺ¨λμ μ ννκ³ generate λ₯Ό λλ₯΄λ©΄ νλ‘μ νΈκ° μμ±λμ΄ λ€μ΄λ‘λ λ°μμ§λ€. (μ°Έ μ’μ μΈμ…) μ°μ File β New β Project λ₯Ό λλ¬μ μλ μ°½μ μ΄μ΄λ³΄μ. κ·Έλ¦¬κ³ λκ° λ€ ν΄μ€κ² κ°μ (κ°λ°λ ν΄μ£Όλ©΄ μλλ…) Spring Initializrμ μ νν μλμ κ°μ μ€μ μ μ μ΄μ€ λ€ λ€μμ λλ¬μ€λ€.
μ¬μ©ν λͺ¨λμ μ νν΄μ£Όμ. νμλ μ΄κ²μ κ²(?)μ λμμ£Όλ lombokκ³Ό Mybatis, MySQLμ μ ννκ³ νλ‘μ νΈλ₯Ό μμ±νμλ€. κ·Έλ¬λ©΄ μ΄μ(?) pom.xml κ³Ό ν¨κ» λΉμ₯ κ°λ°μ μμν μ μλ νκ²½μ΄ μ 곡λλ€.
<dependencies> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> μ°μ μ¬κΈ°κΉμ§ μ λμλμ νμΈν΄λ³΄κΈ° μν΄ Controller μ νμ¬μκ°μ μΆλ ₯νλκ±Έ λ§λ€μ΄ 보κ³
@RestController public class ApiController { @GetMapping(path = "/helloWorld") public String helloWorld() { return LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); } } ν°μΌμ μ€νν΄λ³΄λ©΄ μ μμ μΌλ‘ μ μκ³Ό μΆλ ₯μ΄ λλκ²μ νμΈν μ μλ€.
MySQL μ°λνκΈ° νμκ° νλ₯μ§λ₯ νλμ μ€ νλλ MyBatisμ MySQLμ λμμ μ°λνλ €κ³ νλ€λ³΄λ λ¬Έμ κ° λ°μν΄λ μ΄λμμ λ¬Έμ μΈμ§λ₯Ό μ λλ‘ νμ
νμ§ λͺ»νκ³ μ½μ§νλ€λ μ μ΄λ€. μ¬κΈ°μ μ νν μ§κ³ λμ΄κ°λ©΄ μ°μ λ°μ΄ν°λ₯Ό μ°κ²°ν΄μ£Όλ ORMμΈ MyBatisλ₯Ό μ
ν
ν΄μ€ λ€μ MySQLμ μ°λν΄μ£Όλ μμΌλ‘ λΆλ¦¬ν΄μ μ€μ μ νλ©΄ νκ°λ¦¬μ§ μκ³ (λμκ°μ§ μκ³ ) λ³΄λ€ λΉ λ₯΄κ² μ€μ μ΄ κ°λ₯ν κ² κ°λ€. (μ¬κΈ°μ μμλ μ€μνμ§ μκ³ λ³λλ‘ μ€μ ν΄μΌ νλ€λ κ΄μ μ΄ μ€μνκ² κ°λ€.) μ°μ src/main/resourcesν΄λμ μλ application.properties μ λ€μμ²λΌ μμ±ν΄μ£Όμ.
spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.hikari.jdbc-url=jdbc:mysql://{url}:{port}/{db} spring.datasource.hikari.username={id} spring.datasource.hikari.password={password} μμ jdbc-url νλͺ©μμ AWSμμ μ 곡νλ RDSλ₯Ό μ¬μ©νλ κ²½μ° RDSμμ μ 곡ν΄μ£Όλ μλν¬μΈνΈμ ν¬νΈλ₯Ό μ μ΄μ£Όλ©΄ λλ€. (μΆν AWS - RDSμ λν΄ λΈλ‘κΉ
μμ μ΄λ€.) Spring Boot 2.0 μ΄νλΆν° κΈ°λ³Έμ μΌλ‘ μ¬μ©λλ 컀λ₯μ
νμ΄ HikariCPλ‘ λ³κ²½λμλ€κ³ νλ€. (λ§ν¬) 컀λ₯μ
ν μ’
λ₯μ€ μ±λ₯μ΄ μ’λ€κ³ νλλ° λ§ν¬λ₯Ό κ°λ³΄λ©΄ λ€λ₯Έ 컀λ₯μ
ν λΌμ΄λΈλ¬λ¦¬μ μ±λ₯μ λΉκ΅ν λ²€μΉλ§ν¬ κ²°κ³Όλ₯Ό νμΈν μ μλ€. μμ²λΌ spring.datasource.hikari κ° prefixλ‘ λΆκ³ κ°μ’
μ 보λ€μ μ μ΄μ£Όμ΄ config μμ μΈμλ μ μλλ‘ ν΄μ£Όμ. κ·Έ λ€μ DataSource μ€μ μ ν΄μ€λ€.
@Slf4j @Configuration @PropertySource("classpath:/application.properties") public class DatabaseConfiguration { @Bean @ConfigurationProperties(prefix = "spring.datasource.hikari") public HikariConfig hikariConfig() { return new HikariConfig(); } @Bean public DataSource dataSource() { DataSource dataSource = new HikariDataSource(hikariConfig()); log.info("datasource : {}", dataSource); return dataSource; } } μ λ΄μ©μ DataSource λ₯Ό hikariConfigμμ μ€μ ν μ λ³΄λ‘ λ§λ€μ΄ μ€λ€λ μλ―Έμ΄λ€. μ΄λ κ²λ§ νκ³ νλ‘μ νΈλ₯Ό λ€μ μ€νμμΌλ³΄λ©΄ logger μ μν΄ datasource μ μ 보λ₯Ό λ³Όμκ° μλ€.
2019-04-22 00:27:35.048 INFO 23040 --- [ main] com.