/images/profile.png

μŠ€ν”„λ§ λΆ€νŠΈλ‘œ λ©€ν‹°λͺ¨λ“ˆ μ…‹νŒ…ν•˜κΈ°

μ„œλΉ„μŠ€λ₯Ό 처음 λ§Œλ“€κΈ° μ‹œμž‘ν• λ•Œλ©΄ 각 μ§κ΅°λ³„λ‘œ μƒκ°ν•˜λŠ” ν¬μΈνŠΈκ°€ λ‹€μ–‘ν•˜λ‹€. 섀계, 기획, λ””μžμΈ, 개발. μ—¬κΈ°μ„œ κ°œλ°œμ€ ν”„λ‘œμ νŠΈ μ…‹νŒ…μ„ μ–΄λ–»κ²Œ ν•΄μ•Όν•˜μ§€? ν•˜λŠ” 고민을 ν•˜κΈ° λ§ˆλ ¨μ΄λ‹€. μ•„μ£Ό κ°„λ‹¨ν•˜κ²Œ ν•˜λ‚˜μ˜ λͺ¨λ“ˆλ‘œ λͺ¨λ“  κΈ°λŠ₯을 λ‹΄λ‹Ήν•˜λ„λ‘ λ§Œλ“€ 수 μžˆμ§€λ§Œ κΈ°λŠ₯λ³„λ‘œ λͺ¨λ“ˆμ„ λ‚˜λˆ μ„œ μ…‹νŒ…ν•˜λŠ”κ²Œ κ΄€λ¦¬μΈ‘λ©΄μ—μ„œ μž₯점이라 μƒκ°ν•œλ‹€.예λ₯Ό λ“€μ–΄λ³΄μž. λ„μ„œκ΄€μ˜ λ“€μ–΄μ˜¨ μ±… 정보λ₯Ό 외뢀에 μ œκ³΅ν•˜λŠ” “API”, 주기적으둜 μ±… 정보λ₯Ό μ—…λ°μ΄νŠΈ ν•˜λŠ” “Batch”. μ΄λ ‡κ²Œ 크게 λ‘κ°€μ§€μ˜ λͺ¨λ“ˆμ΄ μžˆμ–΄μ•Ό ν•œλ‹€κ³  κ°€μ •ν–ˆμ„λ•Œ μ–΄λ–€μ‹μœΌλ‘œ λͺ¨λ“ˆμ„ 섀계할 수 μžˆμ„κΉŒ? 이번 ν¬μŠ€νŒ…μ—μ„œλŠ” μŠ€ν”„λ§ λΆ€νŠΈμ™€ 메이븐을 ν™œμš©ν•΄μ„œ ν•˜λ‚˜μ˜ ν”„λ‘œμ νŠΈ(μ»΄ν¬λ„ŒνŠΈ)μ—μ„œ μ—¬λŸ¬ λͺ¨λ“ˆμ„ 관리할 수 μžˆλŠ” Spring Multi Module을 μ…‹νŒ…ν•˜λŠ” 방법에 λŒ€ν•΄ μ•Œμ•„λ³΄κ³ μž ν•œλ‹€. ν•„μžλ„ μ…‹νŒ…ν•˜κΈ° μ „μ—λŠ” “κ·Έλƒ₯ ν•˜λ©΄ λ˜λŠ”κ±° μ•„λ‹ˆμ•Ό?“라며 우슡게 보닀 μ•„μ£Ό μ‚¬μ†Œν•œ λΆ€λΆ„λ“€μ—μ„œ μ—„μ²­λ‚œ μ‚½μ§ˆμ„ ν•΄μ„œ κ·ΈλŸ°μ§€ κΌ­ ν¬μŠ€νŒ…μœΌλ‘œ 남겨놔야 κ² λ‹€κ³  λ‹€μ§ν–ˆκ³  μ΄λ ‡κ²Œ 정리λ₯Ό ν•  수 있게 λ˜μ–΄μ„œ 닀행이라 μƒκ°ν•œλ‹€. μ–΄μ©Œλ©΄ μš°λ¦¬κ°€ μžˆλŠ” νŒ€λ„ λ©€ν‹°λͺ¨λ“ˆμ΄ μ•„λ‹κΉŒ? 좜처 : https://bcho.tistory.com/813" μ–΄μ©Œλ©΄ μš°λ¦¬κ°€ μžˆλŠ” νŒ€λ„ λ©€ν‹°λͺ¨λ“ˆμ΄ μ•„λ‹κΉŒ? 좜처 : https://bcho.tistory.com/813 μ™œ λ©€ν‹°λͺ¨λ“ˆλ‘œ μ…‹νŒ…ν• κΉŒ? μœ„μ—μ„œ μ˜ˆμ‹œλ‘œ 이야기 ν•œκ²ƒμ²˜λŸΌ ν˜„μž¬ μš°λ¦¬κ°€ μ…‹νŒ…ν•΄μ•Όν•  λͺ¨λ“ˆμ€ 크게 두가지 이닀. API : 외뢀에 λ„μ„œκ΄€μ— λ“€μ–΄μ˜¨ μ±… 정보λ₯Ό μ•Œλ €μ£ΌλŠ” λͺ¨λ“ˆ Batch : 주기적으둜 λ„μ„œκ΄€μ˜ μ±… 정보λ₯Ό κ°±μ‹ ν•˜λŠ” λͺ¨λ“ˆ ν•œλ²ˆ 생각을 ν•΄λ³΄μž. μœ„μ—μ„œ λ§ν•œ λͺ¨λ“ˆλ“€ 쀑에 λ™μ‹œμ— μ‚¬μš©ν• κ²ƒλ§Œ 같은 정보가 μžˆλ‹€. “μ±… 정보”. 각 λͺ¨λ“ˆλ§ˆλ‹€ “μ±… 정보"λ₯Ό κ°€μ Έμ˜€λŠ” λ‘œμ§μ„ μž‘μ„±ν•˜λŠ”κ²ƒ 보닀 ν•œκ³³μ—μ„œ ν•΄λ‹Ήλ‘œμ§μ„ κ΅¬ν˜„ν•˜κ³  이λ₯Ό μ—¬λŸ¬κ³³μ—μ„œ μ‚¬μš©ν•˜λŠ”κ²Œ μ‚¬μš©ν•˜λŠ”κ²Œ μ€‘λ³΅μ½”λ“œλ₯Ό λ°©μ§€ν• μˆ˜ μžˆλŠ” λ°©λ²•μ΄λž€κ±΄ μ‰½κ²Œ μ•Œμ•„μ°¨λ¦΄μˆ˜ μžˆλ‹€. κ·Έλ ‡λ‹€λ©΄ μ–΄λ–»κ²Œ λͺ¨λ“ˆμ„ λΆ„λ¦¬ν• μˆ˜ μžˆμ„κΉŒ? ν•„μžμ˜ κ²½ν—˜μœΌλ‘œ 미루어 λ³Όλ•Œ 크게 두가지 방법이 μžˆλŠ”κ²ƒ κ°™λ‹€. κ³΅ν†΅μœΌλ‘œ μ‚¬μš©ν•˜λŠ” λͺ¨λ“ˆμ„ jar둜 λ§Œλ“€κ³  이λ₯Ό 메이븐 원격 μ €μž₯μ†Œμ— deploy, μ‚¬μš©ν•˜λŠ” λͺ¨λ“ˆμ—μ„œ λ””νŽœλ˜μ‹œμ— μΆ”κ°€ν•˜μ—¬ μ‚¬μš© λ©€ν‹°λͺ¨λ“ˆλ‘œ κ΅¬μ„±ν•˜κ³  μ‚¬μš©ν•˜λŠ” λͺ¨λ“ˆμ—μ„œ λ””νŽœλ˜μ‹œμ— μΆ”κ°€ν•˜μ—¬ μ‚¬μš© 첫번째 λ°©λ²•μ˜ κ°€μž₯ 큰 단점은, κ³΅ν†΅μœΌλ‘œ μ‚¬μš©ν•˜λŠ” λͺ¨λ“ˆμ΄ λ³€κ²½λ λ•Œλ§ˆλ‹€ 버전을 λ°”κΏ”μ£Όκ³  (μ•ˆλ°”κΏ”λ„ λ˜μ§€λ§Œ μ‚¬μš©ν•˜λŠ” λͺ¨λ“ˆμ—μ„œ μΊμ‹œ 갱신을 ν•΄μ•Όν•˜λŠ” λΆˆνŽΈν•¨μ΄ 생긴닀.) 메이븐 원격 μ €μž₯μ†Œμ— deployλ₯Ό ν•΄μ€˜μ•Ό ν•œλ‹€. 그에 λ°˜ν•΄ λ‘λ²ˆμ§Έ 방법은 μ΄λŸ°κ³Όμ •μ—†μ΄ ν•¨κ»˜ λΉŒλ“œλ§Œ ν•΄μ£Όλ©΄ λλ‚˜κ³  IDEμ—μ„œ κ°œλ°œμ‹œ ν•œ λͺ¨λ“ˆμ—μ„œ λ™μ‹œμ— μˆ˜μ •κ³Ό μ‚¬μš©μ΄ κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— 훨씬 νŽΈλ¦¬ν•˜λ‹€. μ€μ΄μ•Œμ€ μ—†λ‹€ λΌλŠ” 말처럼, 정닡은 μ—†λ‹€. ν•˜μ§€λ§Œ μ΄λŸ°μ €λŸ° 방법듀을 미리 μ•Œμ•„λ‘λ©΄ μ μ‹œμ μ†Œμ— μ‚¬μš©ν•  수 μžˆλŠ”. ν•„μžκ°€ λ‹€λ₯ΈκΈ€λ“€μ—μ„œλ„ 언급을 μžμ£Όν•˜λ˜ “λ‚˜λ§Œμ˜ 무기"κ°€ λ˜μ§€ μ•Šμ„κΉŒ? λ©€ν‹°λͺ¨λ“ˆ μ…‹νŒ…ν•˜κΈ° μœ„μ—μ„œ 이야기 ν–ˆλ˜ “API”, “Batch"μ™€λŠ” λ³„λ„λ‘œ κ³΅ν†΅μœΌλ‘œ μ‚¬μš©ν•˜λŠ” λͺ¨λ“ˆμΈ “Core” μ΄λ ‡κ²Œ 총 3개의 λͺ¨λ“ˆμ„ λ§Œλ“€μ˜ˆμ •μ΄λ‹€. λ‹€λ₯Έ μ΄μ•ΌκΈ°μ§€λ§Œ, κ³΅ν†΅μœΌλ‘œ μ‚¬μš©ν•  것 “κ°™μ•„μ„œ” 미리 κ³΅ν†΅λ‘œμ§μ„ μž‘μ„±ν•˜λŠ” μŠ΅κ΄€μ€ 쒋지 μ•ŠλŠ”κ²ƒ κ°™λ‹€. κ·ΈλŸ¬λ‹€λ³΄λ©΄ 쓸데없이 κ³΅ν†΅λ‘œμ§μ΄ λ¬΄κ±°μ›Œμ§€λ―€λ‘œ μ‹€μ œλ‘œ μ‚¬μš©ν•˜λ©΄μ„œ μ€‘λ³΅μ½”λ“œκ°€ λ°œμƒν• λ•Œ κ·Έλ•Œ κ³΅ν†΅λ‘œμ§μœΌλ‘œ λ¦¬νŽ™ν† λ§ 해도 λŠ¦μ§€ μ•ŠλŠ”κ²ƒ κ°™λ‹€. (꼰데인가…) κ΅¬ν˜„ν•˜λŠ” ν™˜κ²½μ€ λ‹€μŒκ³Ό κ°™λ‹€. Spring Boot 2.2.3 Maven IntelliJ μš°μ„  IDE의 νž˜μ„ 빌렀 ν•˜λ‚˜μ˜ μŠ€ν”„λ§ λΆ€νŠΈ ν”„λ‘œμ νŠΈλ₯Ό 생성해본닀. λ‹€μŒ > λ‹€μŒ > λ‹€μŒ" λ‹€μŒ > λ‹€μŒ > λ‹€μŒ κ·Έ λ‹€μŒ λ§Œλ“  ν”„λ‘œμ νŠΈμ—μ„œ 우클릭 ν›„ μƒˆλ‘œμš΄ λͺ¨λ“ˆμ„ 선택. Maven λͺ¨λ“ˆμ„ μ„ νƒν•˜κ³  μ λ‹Ήν•œ 이름을 적어쀀닀. λ‹€μŒ > λ‹€μŒ > λ‹€μŒ 222" λ‹€μŒ > λ‹€μŒ > λ‹€μŒ 222 “API”, “Batch”, “Core” λΌλŠ” λͺ¨λ“ˆμ„ μΆ”κ°€ν•˜κ³  μ‹€μ œ λͺ¨λ“ˆμ΄ λ˜λŠ” “API”, “Batch"에 parent 와 dependencies 을 μ„€μ •ν•΄μ£Όμž. κ·Έλ ‡κ²Œ ν•˜κ³  각 Pom.xml을 보면 μ•„λž˜μ™€ κ°™λ‹€. (“API” λͺ¨λ“ˆμ— λŒ€ν•΄μ„œλ§Œ μ§‘μ€‘μ μœΌλ‘œ 이야기 ν•˜λ € ν•œλ‹€. “Batch” λͺ¨λ“ˆλ„ λ™μΌν•œ ν˜•μ‹μœΌλ‘œ μž‘μ„±ν•˜κΈ° λ•Œλ¬Έ.) 졜 μƒμœ„ Pom.xml (library) modules ν•˜μœ„μ— λ©€ν‹°λͺ¨λ“ˆλ‘œ μ„€μ •ν•œ λͺ¨λ“ˆλ“€μ˜ 이름이 λ“€μ–΄κ°€ μžˆλŠ”κ²ƒμ„ 확인할 수 μžˆλ‹€. <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging> <modules> <module>api</module> <module>core</module> <module>batch</module> </modules> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.taetaetae</groupId> <artifactId>library</artifactId> <version>0.

μ‘°κΈˆμ€ 무거운 2019 회고

“회고"λŠ” 비단 개발 λΈ”λ‘œκ·Έ 뿐만 μ•„λ‹ˆλΌ μ–΄λ– ν•œ κ³Όμ •μ˜ λ§ˆμ§€λ§‰μ—λŠ” κΌ­ ν•΄μ•Όν•  μ€‘μš”ν•œ μ‹œκ°„μΈ 것 κ°™λ‹€. μ•žλ§Œλ³΄κ³  λ‹¬λ €κ°€μž! λ‹₯곡! λΌλŠ” 말이 μžˆμ§€λ§Œ 사싀 이 말이 μ„±λ¦½λ˜κΈ° μœ„ν•΄μ„  μ§€λ‚œ 과거에 λŒ€ν•œ 정리와 λ°˜μ„± 그리고 무엇을 ν•˜λ €κ³  ν–ˆλŠ”λ° μ–΄λ–€ 이유둜 λͺ»ν–ˆλŠ”지와 κ·Έ λ™μ•ˆμ˜ λ‚˜ μžμ‹ μ„ 바라볼 수 μžˆλŠ” 이 “회고” μ‹œκ°„μ΄ ν•„μš”ν•˜λ‹€. 벌써 2019년도 λ§ˆλ¬΄λ¦¬κ°€ λ˜μ–΄κ°„λ‹€. μž‘λ…„λ³΄λ‹€ 더 정신없이 λ‹¬λ €μ˜¨ μ˜¬ν•΄. λ‚΄λ…„μ—” μ˜¬ν•΄λ³΄λ‹€ 더 멋지고 힘차게 μΆœλ°œν•˜κΈ° μœ„ν•΄ ν•„μžμ˜ ν•œ ν•΄λ₯Ό λŒμ•„λ³΄κ³ μž ν•œλ‹€. κ·Έλ ‡λ‹€λ©΄ νšŒκ³ λŠ” μ–΄λ–»κ²Œ ν•˜λŠ”κ²Œ κ°€μž₯ μ’‹μ„κΉŒ? λ¬΄μž‘μ • νƒ€μž„λΌμΈ 기반으둜 1μ›”μ—” λ­ν–ˆκ³  2μ›”μ—” λ­ν–ˆκ³ … 이 방법이 틀린건 μ•„λ‹ˆμ§€λ§Œ νƒ€μž„λΌμΈ 기반으둜 정리λ₯Ό ν•œ λ’€ ν‚€μ›Œλ“œλ³„λ‘œ λ‹€μ‹œ μ •λ¦¬ν•˜λŠ” 방식이 κ°€μž₯ λ§žμ„κ²ƒ κ°™λ‹€λŠ” 생각이닀. 무엇을 ν–ˆκ³ , 뭐가 μ’‹μ•˜κ³  어떀건 아쉬웠고. κ·Έλž˜μ„œ λ‚΄λ…„μ—” μ–΄λ–»κ²Œ ν•  것이고. 각자의 회고 λ°©μ‹μ—λŠ” 차이가 μžˆκ² μ§€λ§Œ 회고λ₯Ό ν•˜λŠ” 이유, 그리고 νšŒκ³ λΌλŠ” λͺ©ν‘œ 쀑에 곡톡점은 “λ’€λ₯Ό λŒμ•„λ³΄κ³ , μ•žμ„ λ³΄κΈ°μœ„ν•œ νž˜μ„ μ°ΎλŠ”κ²ƒ” 이 μ•„λ‹κΉŒ μ‹Άλ‹€. λ‚΄λ…„ 회고λ₯Ό ν• λ•ŒλŠ” 흑백이 μ•„λ‹Œ 컬러 사진을 넣을 수 μžˆλŠ” λΆ„μœ„κΈ°κ°€ 될까?… 좜처 : http://www.nanum.com/site/poet_walk/820914" λ‚΄λ…„ 회고λ₯Ό ν• λ•ŒλŠ” 흑백이 μ•„λ‹Œ 컬러 사진을 넣을 수 μžˆλŠ” λΆ„μœ„κΈ°κ°€ 될까?… 좜처 : http://www.nanum.com/site/poet_walk/820914 νšŒμ‚¬λŠ” μ„±μž₯의 곡간이 μ•„λ‹Œκ²ƒμ„ κΉ¨λ‹³λŠ” μˆœκ°„. (이야기에 μ•žμ„œ ν•„μžλŠ” ν˜„μž¬ μ„œλΉ„μŠ€ κ°œλ°œμžμž„μ„ λ°νžŒλ‹€.) 내년이 되면 μ»΄ν“¨ν„°μŸμ΄κ°€ λœμ§€ 벌써 8λ…„μ°¨. 맀년 μ„±μž₯의 κ·Έλž˜ν”„λ₯Ό 그렀보면 μž‘λ…„κΉŒμ§€λ§Œ 해도 μš°μƒν–₯μ΄μ—ˆλ‹€. (κ·Έλž˜ν”„μ˜ κΈ°μšΈκΈ°λŠ” 맀년 λ‹¬λžμ§€λ§Œ) ν—ˆλ‚˜ μ˜¬ν•΄λŠ” κΈ°μšΈκΈ°κ°€ 0 μ΄κ±°λ‚˜ 였히렀 λ§ˆμ΄λ„ˆμŠ€κ°€ 된 것 같은 λŠλ‚Œμ΄λ‹€. μ™œμΌκΉŒ. ν‚€λŠ” μ™œ 더이상 μ„±μž₯을 μ•ˆν• κΉŒ? (쓰읍…) 좜처 : http://www.guro1318.or.kr/bbs/board.php?bo_table=data&wr_id=1723" ν‚€λŠ” μ™œ 더이상 μ„±μž₯을 μ•ˆν• κΉŒ? (쓰읍…) 좜처 : http://www.guro1318.or.kr/bbs/board.php?bo_table=data&wr_id=1723 νšŒμ‚¬λ₯Ό λ‹€λ‹ˆλ‹€ 보면 μ•„μ£Ό 일반적으둜 “μ‹œν‚€λŠ” 일"을 ν•˜κ³€ ν•œλ‹€. 주어진 업무λ₯Ό 정해진 κΈ°κ°„ μ•ˆμ— μŠ€νŽ™μ— 맞좰 κ°œλ°œν•˜λŠ”. μ•„μ£Ό κ·Ήλ‹¨μ μœΌλ‘œ λ‚˜μ˜κ²Œ λ§ν•˜λ©΄ “도ꡬ"둜 μ „λ½λ˜μ–΄λ²„λ¦΄ μˆ˜λ„ μžˆλŠ” μ‹œκ°„λ“€. (κ°œλ°œμžκ°€ 도ꡬ가 λœλ‹€λŠ” 말은 λ„ˆλ¬΄λ‚˜λ„ λ“£κΈ° 싫은 말쀑에 ν•˜λ‚˜.) ν”νžˆ λ§ν•˜λŠ” CRUD(Create, Read, Update, Delete) μ„±μ˜ 개발 업무λ₯Ό ν•˜κ³€ ν•œλ‹€. ν•˜μ§€λ§Œ κΌ­ 성과에 align(더 쒋은 ν•œκ΅­λ§μ„ μ°Ύκ³  싢은데…) ν•˜λŠ” 일 말고도 ν—ˆλ“œλ ›μΌ(μΌμ’…μ˜ μ„œμŠ€ν…Œμ΄λ‹?)을 ν•  κ²½μš°λ„ μžˆλŠ”λ° 그게 λ§Œμ•½ μž¬λ―Έμ—†λŠ” 일이라면 μ–΄λ–¨κΉŒ? ν•„μžλŠ” κ·Έλ ‡κ²Œ “μ‹œν‚€λŠ” 일만 ν•˜λ©° μž¬λ―Έμ—†λŠ” νšŒμ‚¬μƒν™œ” 보닀 “재미있게 κ°œλ°œν•˜λ©° μ„±μž₯을 ν•  수 μžˆλŠ” νšŒμ‚¬μƒν™œ” μ΄λΌλŠ” 기쀀을 가지고 ν•œ ν•΄λ₯Ό μ§€λ‚΄μ˜¨ 것 κ°™λ‹€. 즉, “μ‹œν‚€λŠ” 일"이 μ•„λ‹Œ “μ‹œν‚€μ§€λ„ μ•Šμ€ 일"을 μ°Ύμ•„μ„œ ν•΄κ°€λ©°. μ˜ˆμ»¨λŒ€, μ²˜μŒμ— μž‘μ•˜λ˜ μ„œλΉ„μŠ€ ꡬ쑰가 μ‚¬μš©μžκ°€ λ§Žμ•„μ§€κ³  μš”κ΅¬μ‚¬ν•­μ΄ λ§Žμ•„μ§μ— 따라 λ³΅μž‘ν•˜κ³  μ„±λŠ₯을 μ €ν•΄ν•˜λŠ” 상황을 λ°œκ²¬ν•˜κ³  미리 κ΅¬μ‘°κ°œμ„ μ„ 톡해 μ„±λŠ₯κ³Ό νš¨μœ¨μ΄λΌλŠ” λ‘λ§ˆλ¦¬μ˜ 토끼λ₯Ό μž‘λŠ”λ‹€κ±°λ‚˜. μ§€λ‚œ μ™ΈλΆ€ μ„Έλ―Έλ‚˜μ—μ„œ λ“£κ³  μΈμ‚¬μ΄νŠΈλ₯Ό μ–»μ–΄ νŒ€λ‚΄μ—λ„ μ μš©ν•΄λ³Έ 배치 무쀑단 배포 κΈ°λŠ₯. νŒ€ λ‚΄ μ½”λ“œλ¦¬λ·°μ˜ ν™œμ„±ν™”μ™€ μˆ˜λ™μœΌλ‘œ ν•΄μ•Όν•  업무듀을 λ©”μ‹ μ € 봇을 ν™œμš©ν•˜μ—¬ μžλ™ν™” ν•œλ‹€κ±°λ‚˜. μ„œλΉ„μŠ€ μ§€ν‘œ λŒ€μ‹œλ³΄λ“œλ₯Ό λ§Œλ“€μ–΄ ν•œλˆˆμ— μ„œλΉ„μŠ€ 상황을 λ³Ό 수 있게 λ³„λ„μ˜ 개발 νŽ˜μ΄μ§€λ₯Ό λ§Œλ“€μ–΄ λ³΄λŠ” λ“±. λ‹€μ–‘ν•œ 업무 λ‚΄/μ™Έ 적으둜 일을 μ°Ύμ•„κ°€λ©° + ν•„μžμ˜ 개인 μ‹œκ°„μ„ ν• μ• ν•΄ κ°€λ©΄μ„œ 정말 재미있게 λ³΄λ‚΄μ˜¨ 것 κ°™λ‹€. ν•˜μ§€λ§Œ λ’€λ₯Ό λŒμ•„λ³΄λ©΄ “μ„±μž₯ ν–ˆλŠ”κ°€?” λΌλŠ” 질문이 μžˆλ‹€λ©΄ “κ·Έλ ‡κ²Œ ν•˜κ³ μžˆλŠ”κ²ƒ κ°™μ•„μ„œ μ‹ λ‚˜κ²Œ ν•΄μ™”λŠ”λ° λŒμ•„λ³΄λ‹ˆ 막상 λ­˜ν–ˆλ‚˜ ν•˜λŠ” λŠλ‚Œμ΄ λ“ λ‹€” 라고 말할 수 μžˆμ„ μ •λ„λ‘œ μ—¬λŸ¬κ°€μ§€λ₯Ό 많이 ν•˜λ©° λ‹€μ–‘ν•œ “κ²½ν—˜"을 μ–»κΈ΄ ν–ˆμ§€λ§Œ μ‹€μ§ˆμ μΈ “μ„±μž₯"은 μ•„μ‰½μ§€λ§Œ λΆ€μ‘±ν•œ ν•œ ν•΄ μ˜€λ˜κ²ƒ κ°™λ‹€. νšŒμ‚¬κ°€ μ›ν•˜λŠ”, 연차에 λ§žλŠ” 업무 μ—­λŸ‰κ³Ό 개발 νŒ€μ—μ„œμ˜ μœ„μΉ˜λ₯Ό μΆ©μ‘±μ‹œν‚€κΈ°μ—” νšŒμ‚¬ μ•ˆμ—μ„œ μ„±μž₯ν•˜κΈ°μ—” ν•œκ³„κ°€ μžˆλ‹€κ³  νŒλ‹¨μ΄ λ“€μ—ˆλ‹€. (이 생각이 μ™œ μ΄μ œμ„œμ•Ό λ“€μ—ˆμ„κΉŒ.) μ˜€ν”ˆμ†ŒμŠ€λ‚˜ μƒˆλ‘œμš΄ μ–Έμ–΄λ₯Ό νšŒμ‚¬ λ°–μ—μ„œ ν˜Όμžμ„œ 곡뢀 ν•˜λ˜μ§€ μ—¬λŸ¬λͺ…μ΄μ„œ μŠ€ν„°λ””λ₯Ό 톡해 μŠ΅λ“μ„ ν•΄μ•Όν•˜κ³  ν† μ΄ν”„λ‘œμ νŠΈ λ˜ν•œ νšŒμ‚¬μ™€ λ³„λ„λ‘œ μ§„ν–‰ν•˜λ©° 개발 μŠ€ν‚¬μ„ λŠ˜λ €μ•Ό 할것 κ°™λ‹€. κ·Έ μ΄μœ λŠ” νšŒμ‚¬μ—μ„œμ˜ μ„±μž₯이 κ²°κ΅­ λ‚˜μ˜ μ„±κ³Όλ‘œ 작힐 μˆ˜λŠ” μ—†λŠ”λ° κ΄œμ‹œλ¦¬ κΈ°λŒ€λ₯Ό ν•˜κ²Œ λ˜κΈ°λ„ ν•˜κ³  특히 μ„œλΉ„μŠ€λ₯Ό μš΄μ˜ν•˜λŠ” νŒ€μ—μ„œλŠ” μš”μ¦˜ ν•« ν•˜λ‹€λŠ” 개발 λ°©λ²•λ‘ μ΄λ‚˜ μ†”λ£¨μ…˜μ„ λ„μž…ν•˜κΈ°μ—λŠ” λ‹€μ†Œ 무리가 있기 λ•Œλ¬Έμ΄λ‹€.

κ°œλ°œν•˜κΈ° λ°”μœλ° κΈ€κΉŒμ§€ 쓰라고? (κΈ€μ“°λŠ” κ°œλ°œμžκ°€ 되자.)

μ‹ μž…μ‹œμ ˆ. λ°°μ›Œμ•Ό ν•  것도 νšŒμ‚¬ 업무도 λ§Žμ•„ ν—ˆμš°μ λŒ€λ˜ λ•Œκ°€ μžˆμ—ˆλ‹€. κ·Έλ ‡κ²Œ ν•˜λ£¨μ— 3~4μ‹œκ°„ 자며 정신없이 ν•˜λ£¨λ₯Ό λ³΄λ‚΄λ˜ λ‚  문득 동기 ν˜•μ΄ “κ°œλ°œμžλŠ” 기술 λΈ”λ‘œκ·Έλ₯Ό ν•΄μ•Ό 돼!“λΌλŠ” μ „ν˜€ 이해가 μ•ˆ λ˜λŠ” 말을 ν•΄μ˜¨λ‹€. μ΄λ ‡κ²Œ λ°”λΉ  μ£½κ² λŠ”λ° λΈ”λ‘œκ·Έμ— κΈ€κΉŒμ§€ 쓰라고? 말이 λ˜λŠ” μ†Œλ¦΄ ν•˜λΌλ©° λ°˜λ°•ν•˜λ‹€ λͺ»λ‚΄ μ΄κΈ°λŠ” μ²™ ν•˜λ‚˜ λ‘˜ 글을 μ“°κΈ° μ‹œμž‘ν–ˆκ³ , λ‹€λ₯Έ 유λͺ… λΈ”λ‘œκ±°μ²˜λŸΌ μ—„μ²­λ‚˜μ§„ μ•Šμ§€λ§Œ ν•˜λ£¨μ— 1,000~2,000λͺ… 정도 λ“€μ–΄μ˜€λ©° 점점 μ„±μž₯ν•΄ κ°€λŠ” λ‚˜λ§Œμ˜ 기술 λΈ”λ‘œκ·Έκ°€ λ˜μ—ˆλ‹€. λ―Έμ•½ν•˜μ§€λ§Œ μ²˜μŒλ³΄λ‹€λŠ” μ„±μž₯ν•˜κ³  μžˆλŠ” λΈ”λ‘œκ·Έ PV(Page View)" λ―Έμ•½ν•˜μ§€λ§Œ μ²˜μŒλ³΄λ‹€λŠ” μ„±μž₯ν•˜κ³  μžˆλŠ” λΈ”λ‘œκ·Έ PV(Page View) λ˜ν•œ ν•„μžμ˜ 개발자 κ²½λ ₯(?)을 돌이켜 보자면 기술 λΈ”λ‘œκ·Έλ₯Ό ν•˜κΈ° μ „κ³Ό ν•˜κ³  λ‚œ ν›„λ‘œ λ‚˜λ‰  만큼 기술 λΈ”λ‘œκ·ΈλŠ” 개인적으둜 μ—„μ²­λ‚œ 영ν–₯λ ₯이 λ˜μ—ˆλ‹€. 이 기회λ₯Ό λΉŒμ–΄ 동기 ν˜•μ—κ²Œ κ°μ‚¬μ˜ 인사λ₯Ό μ „ν•˜κ³  μ‹Άλ‹€. ν˜•. 보고 있죠? ;] 이번 ν¬μŠ€νŒ…μ€ κΌ­ “λΈ”λ‘œκ·Έλ₯Ό ν•˜μž” 라기 보닀 “글을 μ™œ 써야 ν•˜κ³  μ–΄λ–»κ²Œ 써야 ν•˜λŠ”μ§€"에 λŒ€ν•΄ μ΄μ•ΌκΈ°ν•΄λ³΄κ³ μž ν•œλ‹€. 처음 이 글을 μ“°λ €κ³  λ§ˆμŒλ¨Ήμ—ˆμ„ 땐 κ°œλ°œμžλΌλŠ” 직ꡰ에 κ΅­ν•œλ˜μ§€ μ•Šκ³  λˆ„κ΅¬μ—κ²Œλ‚˜ 적용될 μ •λ„μ˜ λ²”μš©μ μΈ 글을 μ“°λ € ν–ˆμœΌλ‚˜ “S"의 μ‘°μ–ΈμœΌλ‘œ λ…μž(타깃)을 μ΅œλŒ€ν•œ κ°œλ°œμžμ— 맞좰 써보고자 ν•œλ‹€. thanks to “S” 사싀 쑰금만 검색을 해보면 특히 κ°œλ°œμžμ—κ²Œ κΈ€μ“°κΈ°κ°€ μ–Όλ§ˆλ‚˜ μ€‘μš”ν•œμ§€ μ°Ύμ•„λ³Ό 수 μžˆμ„ μ •λ„λ‘œ λ‹€μ–‘ν•œ κΈ€λ“€μ—μ„œ “κ°œλ°œμžκ°€ μ™œ 글을 써야 ν•˜λŠ”κ°€"에 λŒ€ν•œ λ‚΄μš©μ΄ 언급이 되곀 ν–ˆμ—ˆλ‹€. 글을 쓰지 μ•Šλ˜ 개발자. ν•˜μ§€λ§Œ μ§€κΈˆμ€ κΈ€μ“°κΈ°κ°€ 정말 μ€‘μš”ν•˜λ‹€κ³  느끼며 적어도 2주에 ν•˜λ‚˜ μ΄μƒμ˜ 글을 μ“°λ €λŠ” ν˜„μ—… 개발자의 μ‹œμ„ μ—μ„œ 정리λ₯Ό ν•΄λ³΄κ³ μž ν•œλ‹€. 그리고 마침 λ©˜ν† λ§ ν•΄μ£Όκ³  μžˆλŠ” λΆ„κ»˜λ„ κΈ€ μ“°λŠ”κ²ƒμ— λŒ€ν•œ μ€‘μš”μ„±μ„ μ•Œλ €μ£Όκ³  μ‹Άμ—ˆκ³ , νŒ€ 내에도 곡유λ₯Ό ν•˜κ³  μ‹Άμ–΄ 겸사겸사. μ™œ 글을 써야 ν• κΉŒ? λΉ„λ‘œμ†Œ λ‚΄ 것이 되기 μœ„ν•œ κ³Όμ • ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λ₯Ό 처음 λ°°μšΈλ•Œ κΌ­ λ§Œλ‚˜λŠ” 문ꡬ Hello Worldλ₯Ό 좜λ ₯ν•˜μ‹œμ˜€. 이게 μ˜λ―Έν•˜λŠ” μ˜λ―Έκ°€ λ¬΄μ—‡μΌκΉŒ? 정말 μƒˆλ‘œμš΄ 세계λ₯Ό μ•Œλ €μ£Όλ € ν•˜λŠ” 것 일까?(κ·ΈλŸ΄μˆ˜λ„ μžˆλ‹€…) μš°λ¦¬κ°€ μ‚΄μ•„κ°€λ©° “배움"μ΄λΌλŠ” 과정은 λŒ€λΆ€λΆ„ λΉ„μŠ·ν•˜κ² μ§€λ§Œ 특히 IT κΈ°μˆ μ€ 책을 λ‹€ μ½μ—ˆλ‹€λ“ μ§€, λ™μ˜μƒ κ°•μ˜λ₯Ό λ‹€ λ“€μ—ˆλ‹€κ³  ν•΄μ„œ λ‚΄ 것이 λ˜μ—ˆλ‹€κ³  λ§ν•˜κΈ°λŠ” μ–΄λ €μšΈ 것 κ°™λ‹€. 직접 ν‚€λ³΄λ“œλ₯Ό λ‘λ“œλ € κ°€λ©° κ±°κΈ°μ„œ 얻을 수 μžˆλŠ” 또 λ‹€λ₯Έ “μΈμ‚¬μ΄νŠΈ” κ°€ 생길 μˆ˜λ„ 있기 λ•Œλ¬Έμ΄λ‹€. λ‹€λ₯Έ 예둜, μš΄μ˜ν•˜λ˜ μ‹œμŠ€ν…œμ΄λ‚˜ μ„œλΉ„μŠ€μ—μ„œ μž₯μ• λ₯Ό λ§žμ•˜λ‹€κ³  κ°€μ •ν•΄λ³΄μž. ν•˜μ§€λ§Œ μš°λ¦¬λŠ” 늘 κ·Έλž˜μ™”λ“― μ–΄λ–»κ²Œλ“  μž₯μ• λ₯Ό ν•΄κ²°ν•  것이닀. μ΄λŸ¬ν•œ μƒν™©μ—μ„œ λΆ„λͺ… “문제의 원인"이 μžˆμ—ˆμ„ ν…Œκ³  “ν•΄κ²° κ³Όμ •"이 있기 마련인데 μ΄κ³³μ—μ„œλ„ “μΈμ‚¬μ΄νŠΈ"κ°€ λΆ„λͺ… μžˆμ„ 것이닀. μ΄λŸ¬ν•œ “μΈμ‚¬μ΄νŠΈ"λ₯Ό κΈ€λ‘œ 적닀 보면 κ·Έλƒ₯ “μ•„~ κ·Έλ ‡κ΅¬λ‚˜, κ·Έλž¬μ—ˆμ§€” ν•˜λŠ” λ¨Έλ¦Ώμ†μ—μ„œμ˜ κΈ°μ–΅λ³΄λ‹€λŠ” 훨씬 더 였래 남을 것이고 ν˜Ήμ—¬ κΈ€μ—μ„œ 정리λ₯Ό 잘λͺ»ν•΄ λ‹€λ₯Έ μ‚¬λžŒλ“€μ˜ ν”Όλ“œλ°±μ΄ μžˆλ‹€λ©΄ 더할 λ‚˜μœ„ 없이 쒋은 효과라고 생각이 λœλ‹€. (이것이 λ°”λ‘œ 곡유의 힘!) λ”λΆˆμ–΄ 글을 μ“Έ λ•Œ μ˜¬λ°”λ₯Έ 정보에 κΈ°λ°˜ν•˜μ—¬ μ“°λŠ” μŠ΅κ΄€μ΄ μ€‘μš”ν•œλ° κ·ΈλŸ¬λ‹€ 보면 μ›λž˜ μ“°λ €κ³  ν–ˆλ˜ λ‚΄μš©λ³΄λ‹€ 더 깊게 μ•Œμ•„κ°€λŠ” κ³Όμ • μ†μ—μ„œ 또 λ‹€λ₯Έ 배움을 얻을 수 μžˆλŠ” λ°˜κ°•μ œμ  κΈ°νšŒκ°€ 생길 수 μžˆλ‹€. λˆ„κ°€ μ‹œν‚€μ§€ μ•Šμ•˜μ–΄λ„ 배운 것에 λŒ€ν•œ ν™œμš©μ„ ν•˜κ³  싢은 생각이 λ“€κ³  이λ₯Ό 또 κΈ€λ‘œ μ“°κ³ . 긍정적인 μˆœν™˜ 속에 μƒκ²¨λ‚˜λŠ” μž‘μ€ λ°œμžκ΅­μΌμ§€λΌλ„ μ„±μž₯ν•΄κ°€λŠ” μžμ‹ μ„ λŠλ‚„ 수 μžˆμ„ 것이닀. λͺΈμ΄ κΈ°μ–΅ν•˜λŠ” μ •λ¦¬ν•˜λŠ” μŠ΅κ΄€ κ°œλ°œμ„ ν•˜λ‹€ 보면 정말 κ°„λ‹¨ν•œ “CRUD”(Create, Read, Update, Delete) λΆ€ν„° μ‹œμž‘ν•΄μ„œ μ—„μ²­λ‚˜κ²Œ λ³΅μž‘ν•œ 도메인 지식에 κΈ°λ°˜ν•˜μ—¬ κ°œλ°œμ„ ν•΄μ•Ό ν•˜λŠ” 상황이 생긴닀. 그럴 λ•Œλ©΄ λ¨Έλ¦Ώμ†μœΌλ‘œ μ •λ¦¬ν•˜λŠ” 것보닀 κ·Έλ¦Όμ΄λ‚˜ 글을 μ¨κ°€λ©΄μ„œ μ •λ¦¬ν•˜λŠ” 게 μ’‹λ‹€λŠ” 건 ꡳ이 λ§ν•˜μ§€ μ•Šμ•„λ„ μ•„λŠ” 사싀. 글을 μ“°λ‹€ 보면 κΈ°μŠΉμ „κ²°μ˜ 정리 방법과 λͺ©μ μ΄ 무엇이고 κ·Όκ±°κ°€ 무엇인지에 λŒ€ν•΄ κ΅¬λΆ„ν•˜λŠ” μŠ€ν‚¬μ΄ λŠ˜μ–΄λ‚˜λŠ” 것 κ°™λ‹€.(적어도 ν•„μžλŠ” 기술 λΈ”λ‘œκ·Έλ₯Ό μš΄μ˜ν•˜λ©΄μ„œ μ •λ¦¬ν•˜λŠ” μŠ€ν‚¬μ΄ 그전보닀 μ—„μ²­λ‚˜κ²Œ λŠ˜μ–΄λ‚¬λ‹€κ³  μžλΆ€ν•œλ‹€.) 쀑ꡭ 속담쀑에 ν•˜λ‚˜, 머릿속에 λ°•ν˜€ λ‚˜μ˜€μ§ˆ μ•ŠλŠ”λ‹€.

더이상 기닀리지 μ•Šμ•„λ„ λ˜λŠ” 배치 무쀑단 배포

μ§€λ‚œ ν¬μŠ€νŒ…, κ·ΈλŸ¬λ‹ˆκΉŒ μš°μ•„ν•œ ν˜•μ œλ“€μ—μ„œ μ΄ˆλŒ€λ₯Ό λ°›μ•„ 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 μ°Έκ³ ) # λ§Œλ“  μž„μ‹œ λ””λ ‰ν† λ¦¬λ‘œ 배포될수 μžˆλ„λ‘ μ„€μ •ν•œλ‹€.

μš°μ•„ν•œ μŠ€ν”„λ§ 배치 ν…Œν¬μ„Έλ―Έλ‚˜ 정리 및 ν›„κΈ° (by μš°μ•„ν•œ ν˜•μ œλ“€)

μ§€λ‚œμ£Ό μš°μ•„ν•œ ν˜•μ œλ“€μ—μ„œ μ§„ν–‰ν•˜μ˜€λ˜ “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/ μ•„μ£Ό μ˜€λž˜μ „μ— 써본 기얡이 μžˆμ§€λ§Œ 배보닀 배꼽이 더 큰 μƒν™©κ°™μ•˜λ˜ νž˜λ“€μ—ˆλ˜ κΈ°μ–΅λ“€λ§Œ λ‚¨μ•„μžˆλŠ” κ΅¬ν˜„λ°©λ²•μΈκ²ƒ κ°™λ‹€.

λ„€νŠΈμ›Œν¬ λͺ¨λ‹ˆν„°λ§μ΄ κΆκΈˆν• λ• ? Packetbeat !

λͺ¨λ‹ˆν„°λ§μ€ μ„œλΉ„μŠ€ 둜직 개발 만큼 ν•œλ²ˆμ”© 고민해보고 κ²½ν—˜ν•΄ 봀을 μ€‘μš”ν•œ μ˜μ—­μ΄λΌ ν•  수 μžˆλ‹€. 그쀑 μ›Ήμ„œλ²„μ—μ„œ μ œκ³΅ν•΄μ£ΌλŠ” μ—‘μ„ΈμŠ€ λ‘œκ·ΈλŠ” μš΄μ˜ν•˜κ³  μžˆλŠ” μ›Ήμ„œλΉ„μŠ€μ— λŒ€ν•΄ μ—¬λŸ¬κ°€μ§€ μΈ‘λ©΄μ—μ„œ 뢄석할 수 μžˆλŠ” κ°€μž₯ κ°•λ ₯ν•œ μ•„μ΄ν…œ 쀑에 ν•˜λ‚˜λΌκ³  μƒκ°ν•œλ‹€. 이λ₯Ό 톡해 μ‚¬μš©μžλ“€μ΄ μ–΄λ–€ 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의 μž₯점 κ·Έ λ‘λ§ˆλ¦¬μ˜ 토끼λ₯Ό λ‹€ 작기 μœ„ν•΄ 보톡 μ•žλ‹¨μ— μ›Ήμ„œλ²„λ₯Ό 두고 κ·Έ 뒀에 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이 λ°œμƒν•˜κ²Œ λ˜λ²„λ¦° κ²ƒμ΄μ—ˆλ‹€. λ˜ν•œ μŠ€ν”„λ§ 파일 μ΅œλŒ€ν¬κΈ°λ₯Ό λ³„λ„λ‘œ μ§€μ •ν•˜μ§€ μ•Šκ³  μžˆμ—ˆκΈ° λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬κ°€ μΆ©λΆ„ν–ˆλ‹€ ν•˜λ”λΌλ„ μ—λŸ¬κ°€ λ°œμƒν–ˆμ„ μƒν™©μ΄μ—ˆλ‹€.

2019 μƒλ°˜κΈ° 리뷰 (feat. κΈ€λ˜)

λˆ„κ΅¬λ‚˜ 어렸을 땐 빨리 μ–΄λ₯Έμ΄ 되고 μ‹Άμ–΄ ν•˜λŠ” 것 κ°™λ‹€. μ‹œκ°„μ΄ 빨리 μ§€λ‚˜κ°€κΈΈ 바라고, 빨리 μ–΄λ₯Έμ΄ 되고 μ‹Άλ‹€λŠ” κ°„μ ˆν•¨μ΄ μžˆμ§€λ§Œ μ΄μƒν•˜κ²Œλ„ 그땐 μ‹œκ°„μ΄ 천천히 κ°€λŠ” κ²ƒμ²˜λŸΌ λŠκ»΄μ‘Œλ‹€. 반면, μ‹œκ°„μ΄ 천천히 κ°”μœΌλ©΄ ν•˜λŠ” λ•Œκ°€ μžˆλ‹€. λ”± μ§€κΈˆ. 남듀은 μ›Œμ–΄μ–΄μ–΄μ–Όν™”μ•„μ•„μˆ˜μš°μš°λͺ¨μ˜₯κΈˆν‡Ό 이라고 λΆ€λ₯΄λ©° μ‹œκ°„μ΄ 느리게 κ°„λ‹€κ³  빨리 주말이 μ™”μœΌλ©΄ μ’‹κ² λ‹€κ³  ν•˜μ§€λ§Œ μš”μ¦˜μ˜ ν•„μžλŠ” μ • λ°˜λŒ€λ‹€. 방금 μΆœκ·Όν•œ 것 같은데 μ–΄λŠμƒŒκ°€ 퇴근인사λ₯Ό μ£Όκ³ λ°›κ³  μžˆλ‹€. 무언가에 홀린 것 κ°™λ‹€. 벌써 μ˜¬ν•΄λ„ 절반이 μ§€λ‚˜κ°€κ³  뜨거운 여름과 ν•¨κ»˜ ν›„λ°˜μ „μ΄ μ‹œμž‘λ˜μ—ˆλ‹€. κ·Έλž˜μ„œ 빨리 μ§€λ‚˜κ°”λ‚˜…좜처 : 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λͺ…이 λ„˜κ²Œ ꡬ독 ν•˜κ² μ–΄?

Springμ—μ„œ Requestλ₯Ό μš°μ•„ν•˜κ²Œ λ‘œκΉ…ν•˜κΈ°

μŠ€ν”„λ§ 기반의 μ›Ή μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ§Œλ“€λ‹€ 보면 μš”μ²­μ„ μ²˜λ¦¬ν•˜λŠ”λ° 맨 μ²˜μŒμ— μœ„μΉ˜ν•˜κ³  μžˆλŠ” 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.