diff --git a/.DS_Store b/.DS_Store index 450d7d9f..2e5b58cd 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/2016/09/18/first/index.html b/2016/09/18/first/index.html index e3c72164..99cf9463 100644 --- a/2016/09/18/first/index.html +++ b/2016/09/18/first/index.html @@ -4,4 +4,4 @@

시작은 언제든지 새롭고 떨리고 가슴벅차는 순간이다. 과연 이 블로그를 잘 운영할수 있을런지.. 제대로 한번 관리 해보고, 나만의 공간으로 꾸며보자!


Buy me a coffeeBuy me a coffee -
\ No newline at end of file +
Back | Home
\ No newline at end of file diff --git a/2016/09/18/hexo_github_blog/index.html b/2016/09/18/hexo_github_blog/index.html index 073df2c9..10f15419 100644 --- a/2016/09/18/hexo_github_blog/index.html +++ b/2016/09/18/hexo_github_blog/index.html @@ -71,4 +71,4 @@ $ git push origin master

마치며

아직 git command 나 markdown, hexo 등 잘 모르는 부분들이 많다. 하나씩 시행착오를 겪어가면서 정리될수 있는 부분들은 이어 정리를 할 계획이다. 그리고 hexo 기본개념이나 설정파일 수정하는 부분들은 다른 분들이 많이 올려놓으셨기 때문데 중요하다고 생각되는 지극히 개인적으로 정리해야겠다고 느끼는 부분들 중심으로 정리를 해야겠다.


Buy me a coffeeBuy me a coffee
-
\ No newline at end of file +
\ No newline at end of file diff --git a/2016/09/23/20160923/index.html b/2016/09/23/20160923/index.html index abc0c791..c0c5aca3 100644 --- a/2016/09/23/20160923/index.html +++ b/2016/09/23/20160923/index.html @@ -33,4 +33,4 @@ npm install hexo-generator-seo-friendly-sitemap –save
  • feed 속성 npm install hexo-generator-feed –save

  • Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2016/10/06/20161006/index.html b/2016/10/06/20161006/index.html index 6c7867c0..96b61e91 100644 --- a/2016/10/06/20161006/index.html +++ b/2016/10/06/20161006/index.html @@ -62,4 +62,4 @@ }

    잘 사용하지는 않지만 가장 좋은 세번째 방법인 enum으로 클래스를 만드는 방법이라고 한다. 복잡한 직렬화나 리플렉션(reflection) 상황에서도 직렬화가 자동으로 지원되고, 인스턴스가 여러개 생기지 않도록 확실하게 보장해준단다. (by effective java)

    그럼 어디서 사용될까

    1. static 으로 선언해서 공통적으로 사용되는 부분이나 환경설정
    2. 내용이 변경되면 다른 클래스에서도 그 부분이 똑같이 적용되어 실행되어야 할때
    3. 자주 사용되는 부분을 싱글톤으로 만들어 생성되는 시간을 줄일때
    4. 스프링에서의 DB커넥션 로직

    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2016/10/08/20161008/index.html b/2016/10/08/20161008/index.html index da8182e4..6d936e35 100644 --- a/2016/10/08/20161008/index.html +++ b/2016/10/08/20161008/index.html @@ -36,4 +36,4 @@ for end

    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2016/12/31/adieu-2016/index.html b/2016/12/31/adieu-2016/index.html index 59ba4002..f8ac6bc6 100644 --- a/2016/12/31/adieu-2016/index.html +++ b/2016/12/31/adieu-2016/index.html @@ -19,4 +19,4 @@ 음,. 10점만점에 8점?? 2017년! 다시한번 일어서자! 화이팅!!


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/01/01/hello-2017/index.html b/2017/01/01/hello-2017/index.html index 112371fe..1616743c 100644 --- a/2017/01/01/hello-2017/index.html +++ b/2017/01/01/hello-2017/index.html @@ -38,4 +38,4 @@

    올해도 어김없이(?) 1월 1일이 되어 해맞이(해돋인지 해맞인지 햇갈리지만, 새해 첫날부터 복잡해지기 싫당 =ㅁ=)를 다녀오고 까페에서 새해 계획을 세워본다. 정말 지킬수 있는 계획들, 현실적인 부분들만 고려해서 써내려 가보자. 절반 이상만이라도 지킬수만 있다면 그나마 다행이라고 생각!

    기술블로그 운영하기 : 월 2회 posting

    내가 아는지식이 얼만큼인지, 보여주기식이 아닌 내 머릿속에 자리잡고 있는 부분들을 정리해서 기록화 하는 이름하야 기술블로그를 작성하는거다. 2주에 최소 하나씩, 이렇게 되면 한달에 최소 2post, 1년이면 약 20post. 작다고 해도 마냥 작게만 느껴지지 않을 분량이다. 사소한거 하나라도. 이를테면 서버 설치나 스프링의 기본 설정 관련된 것들도. 글쓰는 연습도 하고 좋은 기회가 될것 같다.

    4대강 종주 : 영산강, 1박2일코스

    2014년에 한강(북한강, 남한강), 2015년에 금강, 2016년에는 못갔다. 4대강 종주의 목표가 갑자기 시들어진 작년이라 생각이 든다. 우여곡절 산전수전 다겪은 내 자전거 붕붕이에게 미안하지 않기위해서라도 올해 여름에는 꼭 영산강이나 낙동강 하나를 계획잡아 1박2일 코스로 다녀와야겠다. 음, 대략 5월? 아마 영산강을 가게될것같다. 이번에는 무리하지 않고 1박2일코스로..

    독서 : 월 전공1권, 전공외1권

    작년에 내 입에서 나왔던 이야기들중에 한심스럽게(?)나온 멘트중 가장 많이나왔던 책좀읽자 올해에는 정말 많이는 아닐지라도 자주읽는 습관을 길러야겠다. 한달에 전공책 한권, 기타서적 한권. 얇은책+읽고싶은책 부터 읽기 시작해서 내년 1월1일때는 내 책상 한켠에 자리잡고있는 책장을 가득 메워보고싶다. 아, 물론 다 읽은 책들로만.

    여행+사진 : 한달에 한번이상 여행가기

    해외든 국내든, 올해는 정말 많이 다녀와야겠다. 가볍게 당일치기부터 시작해서 갈수만 있다면 해외여행도. 물론 올해도 야근과의 싸움은 계속될테지만 주말 잠깐이라도 시간을 내서 두달에?아니 한달에 한번이라도 휴가를 써서라도 가까운곳에 힐링하러 다녀오고 싶다. 가서 작년에 산 카메라로 사진도 이것저것 많이 찍고 좋은추억 많이 만들고오고 싶다.

    저축+a : 근검절약의 생활화, 경제공부

    나름 월급의 60%이상을 저축하는 중이다. 그치만 상황이 상황인지라 지금도 만족하지 못한다. 천장에 굴비 달아놓고 간장찍어 먹는다는게 아니라 아낄수 있는 부분들은 최대한 아끼면서 살자는거다. 아침에 택시 타지말고 조금 일찍 일어나서 버스를 탄다던지, 버스를 타지말고 조금일찍 일어나서 자전거를 탄다던지(사실 자전거를 타면 퇴근할때 더 빠르고 편하게 올수 있으니) 생활속에서 절약할수 있는 부분들을 찾고, 몸에 베도록 습관화 시켜야겠다. 그리고 주식이나 펀드 등 투자에 대해서도 이제 공부를 해봐야겠다. (독서하자는거랑 비슷한 이야기) 저금리시대 마냥 저축만 하다보면 힘든건 누구나 다 아는이야기. 일에 치여 생활에 치여 핑계대지말고 배워가면서 챙겨보자.

    운동 : 자유형마스터, 몸짱

    항상 하는 이야기지만 건강보다 중요한건 없다고 생각한다. 올해에도 병원가지 않는 나를 만들기 위해 헬스 + 배드민턴 + 라이딩 은 필수고 가능하면 수영도 배워서 자유형 정도는 할수있는 나를 만들고 싶다. 그래서 다들 말하는 몸짱도 되보고 싶고 자신있게 해변가에서 상의를 탈의할수있는(?!) 건강한 내가 되도록 노력해야겠다.

    봉사활동하기 : 연탄배달, 자원봉사

    작년에 하려다가 못한 봉사활동 올해는 꼭 해야겠다. 가깝게 할수있을법한게 연탄배달, 이건 1월달 내로 꼭! 해서 봉사라는것과 나눔이라는 행복을 느껴보고 싶다. 지금 생각나는건 자원봉사 같은것도 해보고 싶고 무보수 알바(?) 같은것도 해보고싶다. 나이들면 못할, 언제 해보겠나.

    가까운, 먼 사람들 만나기

    마지막으로, 잊고있었던 중요한 행동. 바로 사람들 만나기다. 바쁘다는 핑계 하나만으로 등한시한 내 소중한 사람들. 아무리 연봉을 많이 받고 일을 잘한다고 회사에서 잘나간다 할지라도, 내 곁엔 나를 생각해주는 소중한 사람들이 있기에 내가 있을수 있는것 같다. 가까운 사람들부터 시작해서 오랬동안 못봤던 사람들도 하나둘씩 연락하면서 지내는 여유를 가져야 겠다.

    할수 있을까? 라는 생각보다 하나둘씩 잊지말고, 놓치지 말고 하루를, 이번주를, 이번달을 점검하고 실천해 나가보자. 올 한해도 열심히 최선을 다해 살것!


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/01/04/20170104/index.html b/2017/01/04/20170104/index.html index 890d1fd7..22c58345 100644 --- a/2017/01/04/20170104/index.html +++ b/2017/01/04/20170104/index.html @@ -16,4 +16,4 @@ charEncoding="읽어온 데이터의 캐릭터셋 지정" />

    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/01/07/spring4-json/index.html b/2017/01/07/spring4-json/index.html index 8119bf7f..e439c8ad 100644 --- a/2017/01/07/spring4-json/index.html +++ b/2017/01/07/spring4-json/index.html @@ -41,4 +41,4 @@ }

    @ResponseBody을 붙이고 List<Student>를 리턴하게 되면 에러가 나는데, 이럴경우 별도 라이브러리를 추가해줘야 자동으로 변환되어 json 형태로 나올수 있게 된다. (list.toString을 하면 json형태가 아닌 이상한 문자형태로 나오기 때문… Map같은것도 마찬가지 이유로 별도 라이브러리를 추가해줘야 정상적으로 나온다.)

    마치며

    단순히 @ResponseBody를 사용해서 json으로 리턴하려면 어떤 라이브러리를 추가해야한다 로 생각했던것에서, 이것저것 테스트 한 결과 toString을 할수 있어야 하고 그 값이 json형태이면 가능하다 로 결론이 지어졌다. 확실히 장님 코끼리 만지듯이 ‘그런가보다’하고 넘어가면 삽질이 진짜 불필요한 삽질이 되는것 같다. 구글링을 해보고, 테스트를 해봐서, 결론적으로 내것으로 만드는 습관을 가져야 겠다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/01/08/transactional-setting-and-property/index.html b/2017/01/08/transactional-setting-and-property/index.html index f2c336b1..fdacbccc 100644 --- a/2017/01/08/transactional-setting-and-property/index.html +++ b/2017/01/08/transactional-setting-and-property/index.html @@ -32,4 +32,4 @@ }

    주요속성

    @Transactional 어노테이션의 주요속성은 다음과 같다.

    속성설 명사용 예
    isolationTransaction의 isolation Level. 별도로 정의하지 않으면 DB의 Isolation Level을 따름.@Transactional(isolation=Isolation.DEFAULT)
    propagation트랜잭션 전파규칙을 정의 , Default=REQURIED@Transactional(propagation=Propagation.REQUIRED)
    readOnly해당 Transaction을 읽기 전용 모드로 처리 (Default = false)@Transactional(readOnly = true)
    rollbackFor정의된 Exception에 대해서는 rollback을 수행@Transactional(rollbackFor=Exception.class)
    noRollbackFor정의된 Exception에 대해서는 rollback을 수행하지 않음.@Transactional(noRollbackFor=Exception.class)
    timeout지정한 시간 내에 해당 메소드 수행이 완료되지 않은 경우 rollback 수행. -1일 경우 no timeout (Default = -1)@Transactional(timeout=10)

    마치며

    자칫 잘못했다가는 원치않는 트랜잭션으로 잘못된 결과를 초래할수 있기때문에 기본값은 숙지하는게 좋을것 같다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/01/10/java8-date/index.html b/2017/01/10/java8-date/index.html index 9fd28336..4ae40151 100644 --- a/2017/01/10/java8-date/index.html +++ b/2017/01/10/java8-date/index.html @@ -19,4 +19,4 @@

    더 다양한 내용들은 아래 URL 에서 확인이 가능하다. https://docs.oracle.com/javase/tutorial/datetime/iso/overview.html


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/02/19/logback/index.html b/2017/02/19/logback/index.html index bdc39ad1..1b5db73a 100644 --- a/2017/02/19/logback/index.html +++ b/2017/02/19/logback/index.html @@ -85,4 +85,4 @@ }

    마치며

    일반적인 웹 어플리케이션에서는 WAS에서 로깅을 따로 관리하고 있기 때문에 file 로 로깅을 할 필요는 없을것 같다.(일반 jar 형태에서는 파일 로깅이 필요 할수도…)

    참고사이트


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/02/22/lombok/index.html b/2017/02/22/lombok/index.html index 2223750b..5d2b3970 100644 --- a/2017/02/22/lombok/index.html +++ b/2017/02/22/lombok/index.html @@ -73,4 +73,4 @@ 일반적으로 @Data를 사용하고 상황에 따라 필요한 어노테이션만 지정도 가능하다고 한다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/02/27/spring-boot-eclipse/index.html b/2017/02/27/spring-boot-eclipse/index.html index b7afca7e..2e9f8723 100644 --- a/2017/02/27/spring-boot-eclipse/index.html +++ b/2017/02/27/spring-boot-eclipse/index.html @@ -73,4 +73,4 @@ }
    • 톰켓에 띄우기 위하여 프로젝트 설정(Project Facets)에서 Dynamic Web Module을 체크해준다.

    참고 URL


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/02/28/shell-script-json/index.html b/2017/02/28/shell-script-json/index.html index 872767f9..53ec813e 100644 --- a/2017/02/28/shell-script-json/index.html +++ b/2017/02/28/shell-script-json/index.html @@ -55,4 +55,4 @@ }

    보다 자세한 사용방법은 공식홈페이지( https://stedolan.github.io/jq/ )를 참조하면 좋을듯 하다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/03/02/github-api/index.html b/2017/03/02/github-api/index.html index f8689d01..8fbaffe4 100644 --- a/2017/03/02/github-api/index.html +++ b/2017/03/02/github-api/index.html @@ -16,4 +16,4 @@ 아래처럼 url은 https://api.github.com/으로 설정하고 Headers파라미터에 Authorization라는 key에 value를 위에서 발급받았던 token을 이용하여 token abcd~~식으로 입력해준다음 send버튼을 눌러주면 응답을 받을수가 있는데, 아래 그림은 제공하는 api의 모든 url을 확인하는 방법이다.

    /images/github-api/github_api_call_1.png

    아래애서는 위에서 확인된 api url을 활용하여 내가 권한이 있는 레파지토리 내에서 확인할수있는 정보에 대한 API를 호출해보았다.

    /images/github-api/github_api_call_2.png

    API 호출시 가장 보편화되어있는(?) 스팩인 JSON으로 응답이 내려오기때문에 어떠한 환경에서도 충분히 활용할수 있을것이라 생각한다. 나는 개인적으로 팀 내에서 하나의 Organizations내에 여러 Repository가 있는데 각각의 PullRequest에 대해 코드리뷰를 해야하는 상황에서 일일히 다 찾아보기 귀찮아 github-api를 활용해 open된 PullRequest가 있으면 알림을 주는 걸 만들어 보았다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/03/08/a-quarter-of-this-year/index.html b/2017/03/08/a-quarter-of-this-year/index.html index 3bda52d8..8f83d704 100644 --- a/2017/03/08/a-quarter-of-this-year/index.html +++ b/2017/03/08/a-quarter-of-this-year/index.html @@ -9,4 +9,4 @@ 그 질문에 대한 정답은 이것이다 라고 정의를 할수는 없겠지만 확실한건, 현재 내 상황에 안주하고 타협하려하는 마음가짐이 생겼다는건 회피할수 없을정도로 나도 정말 많이 변해버린것 같다. 물론 지금 상황이 잘못되었다는건 아니지만 내 직업 특성상 끊임없이 노력하고 도전하며 배워야 하는 상황인데 지금 난 퇴근하고 집에가면 쉬고싶고 자기 바쁘고 다음날 늦잠자고… 계속된 생활패턴에 젖어 사는것 같다. 일단 독서좀 많이 해야겟다. 회사에, 집에 쌓인 책만 벌써 몇권인지… 기본이 되는 전공서적 하나 정하고 끝까지 완독해보자. 그게 자바든 스프링이든, 최신 신기술보다 기본이 탄탄해져야 하는건 백번 천번 말해도 당연하기에.

    다시 정신차리자. 오늘 걷지 않으면 내일은 달려야 한다고 누군가 그랬듯..


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/03/12/spring-parameter/index.html b/2017/03/12/spring-parameter/index.html index 081686fe..f52fe226 100644 --- a/2017/03/12/spring-parameter/index.html +++ b/2017/03/12/spring-parameter/index.html @@ -44,4 +44,4 @@ }

    @ModelAttribute

    @RequestParam과 비슷한데 1:1로 파라미터를 받을경우는 @RequestParam를 사용하고, 도메인이나 오브젝트로 파라미터를 받을 경우는 @ModelAttribute으로 받을수 있다. 또한 이 어노테이션을 사용하면 검증(Validation)작업을 추가로 할수 있는데 예로들어 null이라던지, 각 멤버변수마다 valid옵션을 줄수가 있고 여기서 에러가 날 경우 BindException 이 발생한다.

    Spring command 객체

    컨트롤러에서 파라미터로 받은 정보에 대해서는 view 에서 바로 사용이 가능하다. 예로 들어 아래그림처럼 이렇게 컨트롤러가 구성되어있고

    /images/spring-parameter/spring-parameter-1.jpg

    이렇게 모델이 구성되어있을때

    /images/spring-parameter/spring-parameter-2.jpg

    view 에서 이런식으로 구성되어있다고 가정해보자.

    /images/spring-parameter/spring-parameter-3.jpg

    이때 /student?name=taetaetae&age=32&address=green-factory로 호출을 해보면 구지 Model에 값을 셋팅해주지 않아도 다음과 같이 정보를 읽을수 있게 된다.

    /images/spring-parameter/spring-parameter-4.jpg

    마치며

    스프링에서 파라미터를 받는 방법은 상당히 다양하다. 이게 정답이다 정의할수 없을정도로. 상황에 따라 맞는 방법으로 파라미터를 받아야 하겠고, 각 방법에 장/단점을 최대한 살려서 좀더 깔끔한 코드를 작성할수 있어야 하겠다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/03/23/oracle-mybatis-date/index.html b/2017/03/23/oracle-mybatis-date/index.html index 55d50aca..8be055a9 100644 --- a/2017/03/23/oracle-mybatis-date/index.html +++ b/2017/03/23/oracle-mybatis-date/index.html @@ -48,4 +48,4 @@ }
    • java.sql.Date vs java.util.Date 둘 중에 선택한다면 모델 객체에서는 java.util.Date가 더 어울린다는 생각이 듭니다. 모델에 java.sql.Date가 있는 것은 Controller에서 SqlException이 있는 것 같은 비슷한 느낌이랄까요..^^;

    마치며

    • 삽질을 하더라도 가급적이면 영양가 있는 삽질이 되야 할것같다. (하루종일 이것 붙잡다가 업무를 못해버리는;;)
    • API문서, 블로그문서, 검색결과에 맹신하지말고 실제 소스까지 들어가봐서 확신을 갖자.

    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/04/04/mybatis-use-generated-keys/index.html b/2017/04/04/mybatis-use-generated-keys/index.html index 40c76d6f..7255d66b 100644 --- a/2017/04/04/mybatis-use-generated-keys/index.html +++ b/2017/04/04/mybatis-use-generated-keys/index.html @@ -53,4 +53,4 @@ </insert>

    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/07/09/refresh/index.html b/2017/07/09/refresh/index.html index e2cebcd5..7c25c1c6 100644 --- a/2017/07/09/refresh/index.html +++ b/2017/07/09/refresh/index.html @@ -6,4 +6,4 @@

    마지막 포스팅을 한지 벌써 3개월이 지났다. 그렇게 바빴던것도 아니고 블로그포스팅을 할 시간이 안난것도 아닌데 어느덧 다시 정신차리고 블로그를 포스팅 하려고보니 3개월이라는 시간이 흘러버렸네 챗바퀴같은 일상, 느즈막히 일어나서 회사출근하고 정신없이 일하다가 퇴근, 그리고 늦게까지 잠못이루다 또 다음날이면 느즈막히 일어나고… 뭔가 변화가 필요하다.

    • 매일 일기쓰기 : 일기라고 해봤자 거창한건 아니고 딱 3개월만 써보자. 오늘 뭐했는지. 자기전에 딱 10분이면 좋을듯
    • 아침에 일찍 일어나기 : 월수금 수영에 화목 배드민턴. 주말에도 일찍일어나고. 일찍일어나면 먹이도 더 먹는다고 하지 않았던가
    • 달력활용하기 : 운동하는것도 그렇지만, 달력을 자주 보면서 빼먹지 말아야 할 중요한 날들은 반드시 메모하고 기억하자
    • 기타 : 책좀 많이 읽고 운동도 꾸준히 해야겠다. 물론 기술블로그 포스팅도 잊지말고.

    첫술에 배부르랴. 하나둘씩 퍼즐 맞춰나가듯 해보다보면 내 자신이 바뀌어 있겠지.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/08/27/hexo-themes-tranquilpeak/index.html b/2017/08/27/hexo-themes-tranquilpeak/index.html index a2ef87a3..5cf09ab5 100644 --- a/2017/08/27/hexo-themes-tranquilpeak/index.html +++ b/2017/08/27/hexo-themes-tranquilpeak/index.html @@ -12,4 +12,4 @@

    여러가지 hexo 테마중에 그나마(?) 영어로 된 문서가 있어서 적용해보게 된 tranquilpeak 라는 테마. 오늘은 해당 테마를 적용하면서 겪은 문제, 그리고 적용 방법에 대해서 간략하게나마 정리해보고자 한다. (다른 테마들은 거의다 중국쪽이나 일본…) 먼저 hexo 공식사이트에서 알려주는 테마들은 다음 사이트에서 확인해 볼수 있다.

    기존에는 hueman이라는 테마를 사용하고 있었는데 (링크), 오랜만에 블로그를 다시(?) 시작하는 느낌을 내보고 싶었고 보다 더 심플하고 유행에 안탈것 같은(순전히 필자 생각) 테마를 찾아보다 tranquilpeak이라는 테마를 선택하게 되었다.

    우선 간략하게 설치과정을 나열해보면 다음과 같다.

    1. themes 폴더내에 테마파일을 받은후 압축 해제
    2. 테마 폴더 이름을 변경
    3. _config.yml 파일 내에 테마 설정 부분 변경 ( theme: tranquilpeak )
    4. hexo clean → hexo generate → hexo server(or hexo deploy)

    이렇게 하면 아주 간단하게 테마가 변경이 된다. 혹여나(필자처럼) 기존 테마를 커스터마이징 하고 싶을 경우는 별도의 과정이 추가로 필요하다. 기존에는 css나 js만 변경하면 간단히 수정되었는데 이 테마는 약간의 빌드(?)를 필요로 한다. 따라서 css나 js등 html 요소들을 수정하였다면 다음과 같은 과정이 필요하다.(테마폴더 최상위에서)

    1. npm install
    2. bower install
    3. css 나 js 변경
    4. grunt build
    5. hexo clean → hexo generate → hexo server(or hexo deploy)

    나같은 경우는 테마에 적용된 폰트를 바꾸기 위해 블로그 를 참조하였다. (해당 아티클에다 댓글폭탄을 ㅎㅎ;;)


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/08/28/apache-keep-alive/index.html b/2017/08/28/apache-keep-alive/index.html index 49b0b603..ab0db998 100644 --- a/2017/08/28/apache-keep-alive/index.html +++ b/2017/08/28/apache-keep-alive/index.html @@ -10,4 +10,4 @@ 자식프로세스들의 최대 값을 설정한다. 이는 메모리의 크기와 상관관계가 있다.
  • MaxRequestsPerChild [회수] 클라이언트들의 요청 개수를 제한. 만약 자식 프로세스가 이 값만큼의 클라이언트 요청을 받았다면 이 자식 프로세스는 자동으로 죽게 된다. 0 일 경우엔 무한대. 이 설정값으로 메모리누수를 방지할수 있다.
  • 어쨋든, 정답은 없다. 상황에 맞춰서 설정할것! 그에따른 책임은 본인이 가져가야하는걸 명심!


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/10/16/deview-2017-review/index.html b/2017/10/16/deview-2017-review/index.html index 0b2a57a3..72fc7009 100644 --- a/2017/10/16/deview-2017-review/index.html +++ b/2017/10/16/deview-2017-review/index.html @@ -28,4 +28,4 @@ 하지만 PWA를 이용해서 모바일 청접장을 만든 부분은 정말 찬사를 보내주고 싶은 아이디어 같다.나도 나중에 해야지~ 예전 “날씨"라는 웹서비스를 만들면서 이라는 환경에서 기상속보나 갑작스러운 눈/비 알림을 단순히 화면에 뿌려주는것이 아니라 사용자 기기에 노티(푸시)해줄수는 없을까하며 잠깐 본 기술이 PWA 였는데 난 프로토타이핑만 해본 수준이지만 이분들은 실제로 본업과는 별개로 구현을 해보는 노력을 했다는것에 내 자신이 부끄러워 진다.


    여전히 이번에도 뒤통수 여러대 맞은 Deivew 2017. 우물안의 개구리라는 마음을 잃지 말고 + 나는 개발자라는 것을 잊지 말아야겟다고 다짐해본다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/11/02/what-is-kafka/index.html b/2017/11/02/what-is-kafka/index.html index 9676081c..9c7ee52a 100644 --- a/2017/11/02/what-is-kafka/index.html +++ b/2017/11/02/what-is-kafka/index.html @@ -10,4 +10,4 @@

    필자가 맡고있는 서비스에 Elastic Stack 을 도입하면서 중간에 버퍼가 필요하여 Message-Queue 시스템들을 알아보던 중 Kafka 에 대해 알아보고, 정리를 해보게 된다.

    기본설명 및 기존 메세징 시스템과 다른점

    • 메세징 큐의 일종
    • 말 그대로 분산형 스트리밍 플랫폼, LinkedIn에서 여러 구직 + 채용 정보들을 한곳에서 처리(발행/구독)할수 있는 플랫폼으로 개발이 시작
    • 대용량의 실시간 로그 처리에 특화되어 설계된 메시징 시스템, 기존 범용 메시징 시스템대비 TPS가 매우 우수
    • 메시지를 기본적으로 메모리에 저장하는 기존 메시징 시스템과는 달리 메시지를 파일 시스템에 저장 → 카프카 재시작으로 인한 메세지 유실 우려 감소
    • 기존의 메시징 시스템에서는 broker가 consumer에게 메시지를 push해 주는 방식인데 반해, Kafka는 consumer가 broker로부터 직접 메시지를 가지고 가는 pull 방식으로 동작하기 때문에 consumer는 자신의 처리능력만큼의 메시지만 broker로부터 가져오기 때문에 최적의 성능을 낼 수 있다.
    /images/what-is-kafka/kafka2.png

    카프카 주요 개념

    • producer : 메세지 생산(발행)자.
    • consumer : 메세지 소비자
      • consumer group : consumer 들끼리 메세지를 나눠서 가져간다.offset 을 공유하여 중복으로 가져가지 않는다.
    • broker : 카프카 서버를 가리킴
    • zookeeper : 카프카 서버 (+클러스터) 상태를 관리하고
    • cluster : 브로커들의 묶음
    • topic : 메세지 종류
    • partitions : topic 이 나눠지는 단위
    • Log : 1개의 메세지
    • offset : 파티션 내에서 각 메시지가 가지는 unique id

    카프카는 어떤식으로 돌아가는가

    • zookeeper 가 kafka 의 상태와 클러스터 관리를 해준다. /images/what-is-kafka/kafka3.png

    • 정해진 topic 에 producer 가 메세지를 발행해놓으면 consumer 가 필요할때 해당 메세지를 가져간다. (여기서 카프카로 발행된 메세지들은 consumer가 메세지를 소비한다고 해서 없어지는게 아니라 카프카 설정 log.retention.hours(default : 168[7일])에 의해 삭제된다.)

    /images/what-is-kafka/kafka4.png
    • partition 개수와 consumer group 개념
    /images/what-is-kafka/kafka5.png
    • 하얀색(consumer-01) : 파티션 개수가 4개인데 비해 컨슈머가 3개, 이렇게 되면 어느 컨슈머가 두개의 파티션을 담당해야하는 상황이 생긴다.
    • 주황색(consumer-02) : 파티션 개수가 4개인데 비해 컨슈머가 5개, 이렇게 되면 하나의 노는(?) 컨슈머가 생기는 상황이 생긴다.
    • 가장 적절한 개수는 정해지지 않았지만 통상 컨슈머그룹의 컨슈머 개수와 파티션 개수를 동일하게 가져가곤 한다.

    참고 url


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2017/12/14/elastic-on-tour/index.html b/2017/12/14/elastic-on-tour/index.html index ffcc892e..83143a2b 100644 --- a/2017/12/14/elastic-on-tour/index.html +++ b/2017/12/14/elastic-on-tour/index.html @@ -16,4 +16,4 @@ 참 사람이 간사한게, 아침에 졸린눈 비벼가며 지옥철 고생을 뚫고 와서 힘들었지만 밥을 먹으면서 아침의 그 고생은 눈녹듯 사라졌다.

    /images/elastic-on-tour/lunch.jpg
    호텔 도시락!!

    Deep Dive (Elasticsearch, Ingest, Kibana, Machine Learning)

    각 스택(?)에 대해서 변화된 부분, 그리고 활용가능성과 최근 출시한 6.X 버전에 대해서 소개하는 시간이였다. 사실 아직 2.4 버전을 운영중이라서인지 6.X의 변화된 부분, 그리고 5.x 버전에서의 차이를 설명해주는데 확 와닿지는 못하였다. 아직 5.x 버전의 필요성을 못느껴서 버전업을 안하고 있었는데 발표를 듣고 꼭 유료 라이센스를 구매하지 않아도 용량 단축이나 안정성, 추가 기능등 5.X로의 버전업은 해서 나쁠것도 없을듯 하다는 생각이 들었다. (단, 무조건 신버전이 좋은것은 아닌듯 잘 알아보고 해야겠지…) 특히 키바나를 활용해 머신러닝을 눈앞에서 보여준건 너무 좋았다. 성능이 좋아서인지 데모시연 하는데 전혀 막힘이 없었으니…

    /images/elastic-on-tour/machine_Learning.jpg
    노란색 음영이 머신러닝으로 계산한 그래프의 위치값들

    Customer Presentations

    Elastic Stack 및 X-Pack 을 활용하여 어떤 문제를 어떻게 해결하고 있는지에 대한 세션이였다. 삼성, NSHC, Naver 에서 약 20분씩 발표를 해주셨는데 약간 시간에 쫒기듯(?) 발표가 진행되어 집중이 잘 안되었다. 마지막에 우리 회사분이 발표하신 Application Logging with Elasticsearch at Naver 라는 주제는 실제로 내가 사용하고 있는 모듈인지라 관심갖고 들었다. 최근들어 자주 버벅이고 에러알림지연(기능중 하나)등 문제가 있었는데 이러한 부분들을 Multi-Cluster 등 튜닝을 통하여 해결했다는 부분을 설명해주셨다. (워낙에 양이 많으니…)

    /images/elastic-on-tour/nelo.jpg
    NELO

    마치며

    밥도 맛있고 발표 내용들도 좋은 인사이트를 얻을수 있었고, 마지막에 경품추첨등 딱딱하지 않는 세미나 였다고 생각한다. 올해는 무료로 하는 행사였지만 내년부터는 유료라고 하는데 난 내년에도 사비를 내서라도 갈 생각이다. (회사지원이 된다면 좋겠지만 ^^;) 한가지 아쉬운건 너무 준비 없이 갔다는게 아쉽다. 사실 구버전(?) 2.X를 사용중이고 5.x 6.x 를 전혀 경험해보지 못해서 공감가는 부분이 없었는데, 나름 높은 버전으로 올려야 겠다는 생각을 할수있었던 좋은 시간이였던것 같다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/01/08/python-2-to-3/index.html b/2018/01/08/python-2-to-3/index.html index d4bd6950..c3f5ae9c 100644 --- a/2018/01/08/python-2-to-3/index.html +++ b/2018/01/08/python-2-to-3/index.html @@ -32,4 +32,4 @@

    pip 를 이용한 모듈 설치

    • pip란 Python Package Index 의 약자로 공식홈페이지는 다음과 같다. ( https://pypi.python.org/pypi/pip )
    • 설치할 모듈을 다음과 같이 설치해주면 된다. ex : requests 모듈인 경우
    $ sudo python3.6 -m pip install requests
     

    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/01/25/apache-access-log-to-es/index.html b/2018/01/25/apache-access-log-to-es/index.html index 56687554..aadb695a 100644 --- a/2018/01/25/apache-access-log-to-es/index.html +++ b/2018/01/25/apache-access-log-to-es/index.html @@ -75,4 +75,4 @@ apache : 2.2.x

    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/02/01/linux-selenium/index.html b/2018/02/01/linux-selenium/index.html index fac37507..67485c8e 100644 --- a/2018/02/01/linux-selenium/index.html +++ b/2018/02/01/linux-selenium/index.html @@ -49,4 +49,4 @@

    그리고 실행을 해보면 작동이 잘~ 된다.

    /images/linux-selenium/result.png
    selenium + python 으로 자동작성된 밴드 글

    마치며

    selenium 에 대해 찾아보면 거의 윈도우 환경에서 돌아가는것들에 대한 포스팅이 많았다. 난 리눅스 환경에서 스케쥴러(젠킨스 같은)를 통해 자동으로 화면없이 작동시키고 싶었는데 아무리 찾아봐도 + 삽질해도 잘 안되었다. 결국 사내에도 나같은 삽질을 하신 분을 찾고 묻고 물어 크롬드라이버만 있어야 하는것이 아니라 크롬앱또한 있어야 동작을 한다는것을 알게 되었다. 역시, 내가 한 삽질은 누군가 이미 한 삽질이라는걸 다시한번 깨닳은 좋은(?) 시간이였다.

    이걸로 나중에 내가 맡고있는 서비스에 대한 웹 자동 테스트 툴도 만들어 볼 생각이다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/02/08/github-web-hook-jenkins-job-excute/index.html b/2018/02/08/github-web-hook-jenkins-job-excute/index.html index e50f1533..d4bdd66e 100644 --- a/2018/02/08/github-web-hook-jenkins-job-excute/index.html +++ b/2018/02/08/github-web-hook-jenkins-job-excute/index.html @@ -19,4 +19,4 @@ 설정은 간단하게 다음과 같이 Job 파라미터 설정을 해주면 된다.

    /images/github-web-hook-jenkins-job-excute/jenkins_job_param.png
    Jenkins > 해당 Job > configure

    Github Webhook 설정

    이제 Github Repository 의 Hook 설정만 하면 끝이난다. 해당 Repository > Settings > Hooks 설정에 들어가서 Add webhook을 선택하여 Webhook을 등록해준다. URL은 {jenkins URL}/jenkins/job/{job name}/buildWithParameters식으로 설정해주고 Content Type 은 application/x-www-form-urlencoded으로 선택한다. 언제 Webhook을 트리거링 시킬꺼냐는 옵션에서는 원하는 설정에 맞추면 되겠지만 나는 pullRequest가 등록 될때만 미리 만들어 놓은 Jenkins Job을 실행시킬 계획이였으니 Let me select individual events.을 설정하고 Pull Request에 체크를 해준다. 아래 그림처럼 말이다.

    /images/github-web-hook-jenkins-job-excute/oss_webhook.png
    해당 Repositroy > Settings > Hooks

    이렇게 등록하고 다시 들어가서 맨 아랫 부분Recent Deliveries을 보면 ping test 가 이루어져 정상적으로 응답을 받은것을 확인할수가 있다.

    /images/github-web-hook-jenkins-job-excute/oss_webhook_result.png
    Webhook 등록 결과

    이렇게 설정을 다 한 뒤 PullRequest를 발생시키면 Jenkins 해당 Job에서는 파라미터를 받으며 실행이 된것을 확인할수가 있다.

    /images/github-web-hook-jenkins-job-excute/jenkins_webhook_result.png
    Jenkins Job 실행 결과

    끝~


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/02/08/github-with-jenkins/index.html b/2018/02/08/github-with-jenkins/index.html index b1be9625..e53308ed 100644 --- a/2018/02/08/github-with-jenkins/index.html +++ b/2018/02/08/github-with-jenkins/index.html @@ -34,4 +34,4 @@ id_rsa id_rsa.pub

    개인키(id_rsa)는 젠킨스에 설정해준다. (처음부터 끝까지 복사, 첫줄 마지막줄 빼면 안된다… )

    /images/github-with-jenkins/ssh_jenkins.png
    젠킨스에 SSH 개인키 설정

    그 다음 공개키(id_rsa.pub)는 Github에 설정을 해준다.

    /images/github-with-jenkins/ssh_github.png
    Github에 SSH 공개키 설정

    이렇게 한뒤 Jenkins 에서 임의로 job을 생성하고 job 설정 > 소스코드 관리 에서 git 부분에 아래처럼 테스트를 해서 정상적으로 연동이 된것을 확인한다. Credentials 값을 위에서 설정한 개인키로 설정하고, repo 주소를 SSH용으로 적었을때 에러가 안나오면 성공한것이다.

    /images/github-with-jenkins/ssh_complete.png
    정상 연결되면 Jenkins 오류도 없고, github SSH 키에 녹색불이 들어온다.

    끝~


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/02/08/jenkins-sonar-github-integration/index.html b/2018/02/08/jenkins-sonar-github-integration/index.html index c9766475..8bc3df3f 100644 --- a/2018/02/08/jenkins-sonar-github-integration/index.html +++ b/2018/02/08/jenkins-sonar-github-integration/index.html @@ -85,4 +85,4 @@ sonar.java.binaries=target/classes # 빌드 결과물 경로

    이렇게 긴~~과정을 거치고 나면 pullRequest 를 올릴때마다 아래 그림처럼 수정한 파일에 대해서 자동으로 분석을 하여 알려준다.

    /images/jenkins-sonar-github-integration/sonar_result_report.png
    SonarQube 분석결과

    또한 분석결과에 따라 (이 부분은 SonarQube 설정으로 조정이 가능할것같다) merge 가 가능/불가능이 조정되어 진다.

    /images/jenkins-sonar-github-integration/sonar_result.png
    SonarQube 분석 중 critical 항목이 없어서 merge 가능한 화면

    마치며

    반복적인 일에 대해서 자동화 구성을 한다는것은 참 의미있는 일인것 같다. 팀내 이런 구성을 도입하구서 획기적으로 코드 품질이 나아지진 않았지만 자칫 잘못해서 merge가 되는 위험한 코드들은 어느정도 SonarQube가 잡아주는것 같다. 사족이지만, 이렇게 적고나니 간단한데 이런 구성에 대한 정보를 알기까지는 엄청난 시간이 들었기에… 오랜만의 포스팅에 대한 뿌듯함을 다시한번 느낀다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/03/17/rest-client-exception/index.html b/2018/03/17/rest-client-exception/index.html index bbe17a92..a6900d97 100644 --- a/2018/03/17/rest-client-exception/index.html +++ b/2018/03/17/rest-client-exception/index.html @@ -69,4 +69,4 @@

    정의된 에러(?)와는 조금 다르게 처리하고 싶다면 DefaultResponseErrorHandler을 상속받고 hasError메소드를 무조건 패스하도록 Override 하고난 다음 응답 코드를 받아서 처리하는 방법이 있을수 있겠다. (물론 이러한 방법 말고 다양한 방법이 있을것 같다.)


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/04/01/apache-gzip/index.html b/2018/04/01/apache-gzip/index.html index 4c722e8f..b0d4d57b 100644 --- a/2018/04/01/apache-gzip/index.html +++ b/2018/04/01/apache-gzip/index.html @@ -23,4 +23,4 @@ 웹 서비스를 위해 서버를 구성할 경우 일반적으로 앞단에 웹서버를 두고 그뒤에 WAS를 두는 설계를 하곤 한다. 여기서 웹서버는 대표적으로 Apache나 Nginx가 있고 WAS는 tomcat이나 기타 다른 모듈을 사용하는데 이렇게 두단계로 나누는 이유는 여러가지가 있겠지만 여기서는 앞단의 웹서버(Apache)의 설정으로 응답속도를 줄일수 있는 방법을 알아 보고자 한다.

    웹페이지의 응답속도를 줄일수 있는 ‘일반적인’방법들

    꼭 서버의 설정들을 건드리지 않고도 웹페이지의 응답속도를 줄일수 있는 방법은 다양하다. 가장 간단하게 코드 레벨에서 설정할수 있는 방법으로는 스타일시트를 위에 선언하거나 java script는 코드 아래부분에 넣는것만으로도 어느정도 응답속도를 줄일수 있다고 한다.

    (사족) 신입시절 회사 대표님이 필수로 읽어보라고 전 직원들에게 선물해주셨던 웹사이트 최적화기법 (스티브 사우더스 저)이 생각이 난다. 모두 사주려면 돈이 얼마야… 그만큼 웹개발자들에게 중요하면서도 한편으로는 기본이 되는 부분들이니 한번쯤 목차라도 읽어보는게 좋을듯 하다.

    사실 이 포스팅을 작성하게된 가장 큰 계기는 얼마전 사내 해커톤을 하면서 경험한 부분 때문이다. ( + 들어만 봤지 실제로 해보지는 않아서… ) 서버에서 node(React)를 띄우고 그 앞단에 Apache로 단순 Port Redirect ( 80 → 3000 ) 시켜주고 있었는데 react 에서 사용하는 bundle.js의 용량이 크다보니 최초 페이지 접근시 로딩시간이 5초 이상되어버린 것이다. bundle.js를 줄여보는등 다양한 방법을 사용했다가 결국 Apache 설정을 통해 1초 이내로 줄일수 있었다.

    gzip

    우선 gzip이란 파일 압축에 쓰이는 응용 소프트웨어로 GNU zip의 준말이라고 한다. (참고 : 위키백과 Gzip) 이를 사용하기 위해서는 브라우저가 지원을 해야하는데 https://caniuse.com/#search=gzip 을 보면 대부분의 브라우저에서 지원하는것을 볼수 있다.

    데이터 흐름

    그럼 gzip 을 사용했을때와 사용하지 않았을때의 차이는 어떻게 다를까? 우선 Request/Response Flow 를 잠깐 살펴보면 다음과 같다.

    • gzip 사용 전
    /images/apache-gzip/before_gzip.png
    출처 : betterexplained.com
    1. 브라우저가 서버측에 /index.html을 요청한다.
    2. 서버는 Request를 해석한다.
    3. Response에 요청한 내용을 담아 보낸다.
    4. Response를 기다렸다가 브라우저에 보여준다. (100kb)
    • gzip 사용 후
    /images/apache-gzip/after_gzip.png
    출처 : betterexplained.com
    1. 브라우저가 서버측에 /index.html을 요청한다.
    2. 서버는 Request를 해석한다.
    3. Response에 요청한 내용을 담아 보낸다. 여기서 해당 내용을 압축하는 과정이 추가가 된다.
    4. Response header에 압축이 되어있다는 정보를 확인후 브라우저는 해당 내용을 받고(10kb), 압축을 해제한 후 사용자에게 보여준다.

    정리하면, gzip을 사용하면 서버는 Client에게 보낼 Response를 압축하기 때문에 네트워크 비용을 줄일수 있어 응답속도가 빠른 장점이 있다.

    무조건 사용해야 하는가?

    물론 무조건 좋은 (마치 show me the money 같은)정답은 없다. 서버에서 압축을 하여 Client에게 보내면 그대로 사용자에게 보여주는것이 아니라 압축을 해제하는 과정이 추가적으로 필요하다. 이러한 과정에서 브라우저는 cpu를 사용하게 되어 오히려 랜더링 하는 과정이 느려질수 있어 자칫 응답속도는 빨라졌다 하더라도 사용자 체감상 더 느려진것처럼 보여질수 있다. 따라서 상황에 맞춰 gzip을 사용해야 할것인지 말것인지에 대해 테스트가 필요하다.

    마치며

    학부시절 또는 신입시절, 아파치는 정적인 리소스를 담당하고 톰켓은 서블릿 처럼 데이터 가공이 필요한 페이지를 담당한다고 주문을 외우듯 하였지만, 웹서버에서 압축을 하면 어떤 효과가 있는지 실제로 경험해보는게 가장 중요한것 같다. 적용 방법은 복붙하는 느낌이라 아파치 공식 문서를 링크 하는것으로 해당 포스팅을 마무리 하겠다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/04/10/apache-access-log-user-agent/index.html b/2018/04/10/apache-access-log-user-agent/index.html index 08bf35de..279cf706 100644 --- a/2018/04/10/apache-access-log-user-agent/index.html +++ b/2018/04/10/apache-access-log-user-agent/index.html @@ -128,4 +128,4 @@ 위처럼 적용을 하고 한두시간 수집을 해보니 Elasticsearch에 아래와 같은 도큐먼트가 생성이 된것을 확인할수 있었다.

    /images/apache-access-log-user-agent/user_agent_elasticsearch_document.jpg
    이 얼마나 우아한가…

    이 정보들을 잘 조합해서 Kibana에서 보면 다음과 같이 볼수 있다.

    /images/apache-access-log-user-agent/kibana_1.png
    user-agent 아 모바일 에서도 안드로이드 7.0에서 많이 들어오는구나!

    UA는 아니지만 기왕 한김에 Access log의 uri를 분석해보면 아래처럼 볼수도 있겠다.

    /images/apache-access-log-user-agent/kibana_2.png
    외부에서 막 찔러 대는구나ㅠ 시스템에 영향줄 정도면 막아야지!

    마치며

    사실 logstash filter plugin을 작성하면서 뭔가 if-else로 분기처리한게 아쉽긴 하지만 만족할만한 결과를 얻을수 있어서 다행이라고 생각하고, 역시 데이터를 raw형태로 보는것보다 시각화해서 보는게 훨씬더 이해도를 높일수 있다는걸 다시금 실감할수 있었던 좋은 시간이였다. 그런데.. 이 방법말고 더 우아한 방법은 없으려나..?;;


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/04/29/apache-408-response-code/index.html b/2018/04/29/apache-408-response-code/index.html index 0af5e313..0b304bbd 100644 --- a/2018/04/29/apache-408-response-code/index.html +++ b/2018/04/29/apache-408-response-code/index.html @@ -36,4 +36,4 @@

    한시간에 만건이상 응답코드는 408, referrer도 없고, useragent도 없는, ip들도 매우 다양한 이상한 녀석들이 요청되고 있었다.

    이렇게 엑세스 로그를 분석할수 있는 구성을 해두고 나니 보였지 안그랬음 그냥 지나갔을 터..

    이러한 데이터를 키바나에서 보면 아래처럼 볼수있는데 한눈에 봐도 과연 의미있는 요청들일까? 하는 의구심이 들정도이다. (1시간 아파치 엑세스 로그)

    /images/apache-408-response-code/200vs400.png
    주황색이 408응답

    그럼 이런 호출들은 도대체 뭘까? 천천히 생각좀 해보자.

    1. 정상적이지 않는 호출로 우리 서버의 취약점을 파악하려 하는것들일까?
    2. 응답코드 408은 요청시간초과 응답코드인데… 오히려 클라이언트 입장에서 문제가 있는건 아닐까?
    3. 어플리케이션 로직이 잘못되어 무한루프에 빠졌나;

    위키백과에서는 아파치 응답코드 중 408에 대한 응답을 다음과 같이 알려주고 있다.

    The server timed out waiting for the request. According to HTTP specifications: “The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time

    즉, 아파치 단에서 타임아웃을 내버리는 상황. 여러 다양한 키워드들로 구글링을 해봐도 이렇다할 검색결과를 찾지 못하고 네트워크 관련상황인지 싶어 크롬 개발자도구를 열어 네트워크 지연 테스트를 해보았으나 별 효과가 없었다. 그렇게 범인찾는 형사의 심정으로 이것저것 알아보다 우연히 집에서 원격으로 회사 VPN 붙어서 테스트 하던도중 관련 증상을 재현 할수 있게 되었다.

    # 재현상황

    우선 아파치버전은 2.2이고 KeepAlive Off가 되어있는 상황. 아래그림처럼 집PC - 공유기 - VPN - Apache - tomcat jenkins 상황이였는데 젠킨스에 한번 접속후에는 항상 408 응답이 주루룩(?) 발생하는것을 알수 있었다. (사실 맨위에 엑세스 로그가 재현한 엑세스 로그이다.)

    /images/apache-408-response-code/network_flow.png
    요청의 흐름

    # 결론

    정확한 근거를 추론할수는 없었지만 재현한 바에 의해 결론을 내리자면, 특정 네트워크 환경에서 408응답이 발생하는것을 알수 있었다. (그중에 하나가 공유기 환경이라는 점) 해당 요청을 막기에는 너무 다양한 ip들이고 서비스 특성상 keepAlive off로 설정한점을 미루어 볼때 해당 요청을 deny 시키기에는 다소 무리가 있다고 보여진다. 또한 시스템에 영향을 줄 정도가 아니므로 무시하는것으로 결론을 내렸다.

    결과적으로는 그냥무시로 끝났지만 그래도 알고 무시해야지~ 하는 마음으로 재현까지 해볼수 있었던 좋은 경험이였다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/05/31/anomaly-detection/index.html b/2018/05/31/anomaly-detection/index.html index 8f63b444..6c76369d 100644 --- a/2018/05/31/anomaly-detection/index.html +++ b/2018/05/31/anomaly-detection/index.html @@ -90,4 +90,4 @@ 빨간색으로 표시한 점 두개를 보면 예측을 벗어난것을 확인할수 있고 실제로 저 시간대에 내부적 이슈로 인해 에러가 많이 발생한 경우이다. (장애 발생 시점)

    이런식으로 구성을 해두면 앞서 수동으로 최대/최소 수치를 정해두고 이탈했는지에 대해서 모니터링 하는것보다 훨씬더 우아하게 모니터링을 할수있다. 물론 해당 모듈이 완벽하다는 소리는 아니다. 필자도 해당 모듈을 사용하다보니 어떤 경우에서는 예측수치와 실제 데이터가 비슷한 경우가 있어 알람을 받은 경우도 있다. 예전 포스팅에서도 이야기 했듯 정답은 없는것 같다. 상황에 맞춰서 지속적으로 커스터마이징을 해야하는게 개발자의 숙명 아닐까 싶다.

    마치며

    사실 이렇게 시계열 데이터라는 단어나 Prophet같은 오픈소스를 검색할수 있었던건 작년 Elastic{ON}Tour 에서 봤던 Elastic X-pack의 머신러닝 기능 때문이다. 그때 받은 충격(?)이 아직까지 있는건지 이렇게 오픈소스로 비슷하게나마 구현할수 있었던 원동력이 된것 같다. 기회가 되면 X-pack을 구매해서 운영하는 서비스에 머신러닝을 활용해서 이러한 시계열 데이터에 대해 분석해보고싶다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/06/27/apache-vs-nginx/index.html b/2018/06/27/apache-vs-nginx/index.html index c534c017..c3ffc0aa 100644 --- a/2018/06/27/apache-vs-nginx/index.html +++ b/2018/06/27/apache-vs-nginx/index.html @@ -32,4 +32,4 @@ http://urin79.com/blog/20654191 http://jaweb.tistory.com/entry/apache-%EC%99%80-Nginx-%EB%AD%90%EA%B0%80-%EC%A2%8B%EC%9D%80%EA%B1%B0%EC%95%BC

    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/06/29/simple-web-server-flask-apache/index.html b/2018/06/29/simple-web-server-flask-apache/index.html index 850e0677..c13574a2 100644 --- a/2018/06/29/simple-web-server-flask-apache/index.html +++ b/2018/06/29/simple-web-server-flask-apache/index.html @@ -75,4 +75,4 @@

    필자는 여기서 한참을 해맸던 부분이, sys.path.insert구문의 두번째 인자는 실제 실행될 Falsk 어플리케이션이 있는 경로를 적어줘야 하고, hello_world는 Flask 어플리케이션 파일의 확장자를 제외한 이름을 적어주면 된다.

    이렇게 한 후 아파치를 시작해주면 앞서 만든 Flask 어플리케이션을 별도로 실행해 주지 않아도 Apache가 알아서 설정한 URL로 요청이 들어올경우 Flask 어플리케이션으로 전달해준다.

    마치며

    사실 이렇게 Apache를 연동하면서 까지 하게 된 계기는, Flask 어플리케이션 구동시 80 port를 받도록 구현하고 root권한을 가진 계정으로 실행하도록 해뒀는데 가끔 종료가 되는 부분을 해결하고자 시작하게 되었다. 이 밖에도 Flask의 다양한 기능들과 Flask만 제외하면 일반 Python 이기 때문에 활용성은 무궁무진할것으로 보인다.

    2부로는 또다른 웹서버인 Nginx를 연동하는 방법을 알아보고자 한다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/07/01/open-source-software-develpoer-story-review/index.html b/2018/07/01/open-source-software-develpoer-story-review/index.html index 782dbdda..6ee62cde 100644 --- a/2018/07/01/open-source-software-develpoer-story-review/index.html +++ b/2018/07/01/open-source-software-develpoer-story-review/index.html @@ -34,4 +34,4 @@

    딱! 내가 바라는(?) 개발 문화다. 이번 파이콘 행사가 기대가 더욱더 기대가 된다!

    아파치 제플린, 프로젝트 시작부터 아파치 탑레벨 프로젝트가 되기까지 / 이문수 님

    /images/open-source-software-develpoer-story-review/06.png

    아파치 제플린은 실무에서도 자주 사용하고 있는 오픈소스이다. 그런데 이 발표를 하기위해 저멀리 미국에서 오셨다는 아파치 제플린의 CTO님. 개인적으로 정말 대단해 보였다. 특히 제플린을 만든 계기부터 아파치 탑레벨 프로젝트로 되기까지의 과정이 정말 매력적으로 보였는데 2013년 10월경 하둡관련 화면단의 분석시스템이 없어 불편해서 만들기 시작하였고, 이를 여러 커뮤니티에 직접 홍보를 해가며 인큐베이션을 거쳐 결국 아파치 프로젝트로 되었다는 이야기. 왜 나는 못할까 라는 자괴감도 살짝 들었으나 저분의 끈기와 실행력은 높이 평가하고 싶고 또한 배우고 싶은 부분이였다. (외모는 여느 CTO처럼 거만하지 않았는데 말은 조리있게 잘하시고^^;)

    오픈소스 개발자에게 듣다(대담)

    질의응답 시간이었다.

    Q. 오픈소스에 쉽게 기여할수 있는 방법?

    • Github에 가보면 초보자들을 위한 이슈를 남겨놓은 경우도 있다.
    • 조그마한 문서 수정부터 시작하자.
    • 기여는 코드만 있는게 아니다. (e.g. 버그리포트 등)

    Q. 오픈소스 홍수시대에 살고있는데 어떤것을 파야하나요?

    • 유명한 코드는 너무 방대해서 보기 힘들다. 그걸 만든 사람의 토이 프로젝트를 보며 감을 익혀보자.

    Q. 처음으로 기여한 오픈소스는 무엇이며 어떻게 기여하였나?

    • 문서수정, 간단한 텍스트를 수정하는것부터 시작
    • 내가 사용하는 프로젝트를 관심있게 보다가 인사이트를 찾아 수정
    • 번역 또한 오픈소스에 기여

    Q. 오픈소스에서 활동하는것과 회사 업무와 비교시 장단점, 입사시 유리한가?

    • 회사업무보단 재밌다. Github계정을 기준으로 평가하기도 한다.
    • 오픈소스 컨튜리뷰션은 내 개발 역사라고 볼수있다.

    Q. 개발자라면 꼭 읽어봐야할 책이 있다면 추천

    • 개발보단 사람과의 커뮤니케이션 관련된 책
    • 기본서는 여러번 읽을수록 새롭다.

    마치며

    /images/open-source-software-develpoer-story-review/07.png

    일명 네임드 개발자분들을 만나고 나니 한편으론 부럽기도 하였지만 한편으론 동기부여를 얻어간다. 첫불에 배부르랴, 조그마한것부터 시작하다보면 나도 언젠간 네임드 소리를 들으며 지금보다 조금이라도 발전된 내가 될수 있다는 자신감을 얻을수 있었던, 직장인으로써 황금같은 토요일이 아깝지 않을 만큼 정말 좋았던 시간이였다! (행사에 자주 와야겠다!)


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/07/01/simple-web-server-flask-nginx/index.html b/2018/07/01/simple-web-server-flask-nginx/index.html index b0447cf7..b63e82ab 100644 --- a/2018/07/01/simple-web-server-flask-nginx/index.html +++ b/2018/07/01/simple-web-server-flask-nginx/index.html @@ -53,4 +53,4 @@

    별도의 모듈을 사용하지 않기때문에 전달해주는 (proxy느낌) 설정을 해준다.

    uWSGI 실행 및 Nginx 재시작

    앞서 설치한 uwsgi를 아래처럼 IP:port 를 명시적으로 적어주고 (위에서 전달받은 IP:PORT와 동일하게) Apache 연동시 활용했던 wsgi파일을 이번에도 동일하게 사용하도록 해서 실행한다.

    $ ./uwsgi -s 127.0.0.1:3031 --wsgi-file /~~~/python_app/hello_world.wsgi
     

    이렇게 하면 background로 실행되는게 아닌 foreground로 실행되기 때문에 &을 사용한다던지 해서 background로 실행되도록 해준다. 그후 Nginx를 재시작 해주면 원하는 그토록 원했던 Hello World!를 만날수가 있게 된다.

    Apache연동과 조금 다른점은 모듈을 사용하지않고 별도의 전달 어플리케이션(?)이 필요하다는점이다. 간단히 Apache처럼 모듈만 넣으면 되는게 아니라서 불편할수도 있을것 같지만 한편으로는 관리할수있는 포인트가 더 늘어난 셈이라 어떤 측면에서는 활용할수 있는 방법이 하나 늘어난것으로 볼수도 있다.

    마치며

    막상 정리하고 나면 아무것도 아닌데 알기 위해서 몸부림을 쳐가며 책이며 구글링을 하는 과정을 통해 점점 성장을 하는것 같다. (성장통이라고나 할까) 이렇게 단순히 Flask를 할수있다 가 아닌 웹서버를 연동할수있다. 그것도 Apache와 Nginx 두개나. 이것도 언젠간 나만의 무기가 되지 않을까?


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/08/05/daily-dev-blog-1/index.html b/2018/08/05/daily-dev-blog-1/index.html index 4aebe5cb..2ba85d4f 100644 --- a/2018/08/05/daily-dev-blog-1/index.html +++ b/2018/08/05/daily-dev-blog-1/index.html @@ -28,4 +28,4 @@ 결국 AWS에서 1년동안은 무료로 사용할수 있는 Free Tier 라는걸 발견하고 이참에 나도한번 사용해보자라는 마음을 가지고 과금되지 않게 조심조심 셋팅을 할수 있었다. 물론 뒤에서 이야기 하겠지만 약간의 과금은 필요했다ㅠ (나름 심도깊었던 고민을 한방에 해결해버리는 AWS 짱;; 이래서 AWS~ AWS~ 하는가 싶었다.)

    /images/daily-dev-blog-1/select_server.png
    돌고 돌다 킹갓엠페러제네럴 AWS를 만나게 된다.

    AWS와 DNS, 그리고 Elastic Stack까지

    AWS Free Tier 에서는 참 고맙게도 다른사람들이 접속할수있도록 공인 IP를 제공해 줬다. 그래서 아파치에 Flask를 연동까지 하고 최대한 심플하게 웹페이지를 작성하여 접속이 가능하도록 했는데 문제는 IP주소로 서비스를 하기에는 뭔가 2% 부족해보였다. 그래서 무료 도메인을 찾아다니던 도중 https://freedns.afraid.org/ 이라는 서비스를 찾고 결국 http://daily-devblog.mooo.com 라는 도메인으로 AWS에 설정된 공인IP를 연동시킬수 있었다. (지금은 redirect 시켜둔 상태, 2부에서 왜 도메인을 구입했는지에 설명할 예정이다.) 또한 예전 조직장님의 말씀이 떠올라 서비스에서의 또다른 인사이트를 찾기 위해 EC2 서버 한대 더 발급받아 (한대에 전부 올리기에는 메모리가 부족했다;;) Elastic Stack 을 셋팅하여 로깅을 할수 있었고 이를 아래 그림처럼 키바나로 시각화 할수 있었다. (이 얼마나 아름다운가… 다시한번 Elastic Stack 에 무한 감동을;;)

    /images/daily-dev-blog-1/kibana.png
    각종 로깅을 통해 만들어낸 우아한 대시보드

    하지만 탄탄대로일것만 같았던 첫번째 개인 프로젝트는 여러가지 문제점들이 발생하였고 한 일주일동안 두세시간 자며 트러블 슈팅을 해야만 했었다. (업무시간을 피해가며 하다보니 시간이 나질 않았다…)


    우선 여기까지, 서비스를 만들게 된 계기와 전체 구조에 대해 이야기를 해보았고 다음 2부에서 하게될 이야기는 이보다 훨씬더 복잡하고 피곤한(?) 이야기로 포스팅 될것같다. 이야기의 흐름이 문제 - 해결, 문제 - 해결 식의 java.util.Map 구조라고 해야하나…

    2부를 기대해 본다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/08/09/daily-dev-blog-2/index.html b/2018/08/09/daily-dev-blog-2/index.html index 8a762048..f871ed20 100644 --- a/2018/08/09/daily-dev-blog-2/index.html +++ b/2018/08/09/daily-dev-blog-2/index.html @@ -40,4 +40,4 @@ https://aws.amazon.com/ko/blogs/korea/automatic-managing-bounced-emails-by-amazon-ses/


    물론 또다른 문제들도 있었으나 메이저급(?) 문제들만 다뤄봤다. 가장 컸던건 앞서 말한 메일 스팸처리 ㅠㅠ 도메인도 구입하고 메일보내는데 비용도 들지만 그간 고생하고 삽질했던걸 생각하면 하나도 아깝지 않다. (어쩔수 없는 자본주의일까?) 마지막으로 3부에서는 이러한 서비스를 이제 어떤식으로 운영할꺼고, 어떻게 발전시켜 나갈것이며, 수익 모델은 어떻게 생각하고 있는지에 대해 이야기 해보고자 한다. (수익모델이라 하지만… 그저 이 서비스를 운영하는 정도?;;)


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/08/21/how-to-use-cloneutils/index.html b/2018/08/21/how-to-use-cloneutils/index.html index 30f48baf..25c4de82 100644 --- a/2018/08/21/how-to-use-cloneutils/index.html +++ b/2018/08/21/how-to-use-cloneutils/index.html @@ -166,4 +166,4 @@

    마치며

    멤버변수가 List, Map, Set 등 여러 유형으로 복잡하게 만들어졌을경우 각각 복사를 해주는 등 다양한 케이스에 유연하게 대응할수 있어야 하겠다. 객체복사? 그거 그냥 하면 되는거 아냐? 라고 볼수도 있으나 입개발 하는 사람과 직접 구현해보고 내부 코드까지 들여다보는 수고를 하는 사람의 차이는 언젠간 분명히 드러날꺼라 생각한다. (필자가 그랬으니ㅠㅠ)


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/08/28/pycon-2018/index.html b/2018/08/28/pycon-2018/index.html index 905dec23..fb194a9e 100644 --- a/2018/08/28/pycon-2018/index.html +++ b/2018/08/28/pycon-2018/index.html @@ -21,4 +21,4 @@ 하지만 발표가 끝나고 구독자수를 보기위해 홈페이지에 접속해보니 서버가 다운;;; ssh 접속도 안되는 상황이였다. 부랴부랴 AWS콘솔에서 서버 재시작을 하고 겨우 살렸는데 아뿔싸! 동접에 대한 테스트 즉, TPS 측정같은 성능테스트를 전혀 하지 않은것이다. 발표도 너무 못하고, 홍보도 제대로 못하고ㅠㅠ 이렇게 발표가 끝나서 너무 아쉽다. (물론 준비 시간이 부족했던게 핑계지만 가장 크다.)

    /images/pycon-2018/slideshare.png

    발표자료

    유튜브 녹화영상

    번외 (nGrinder를 성능테스트편)

    필자는 기술에 있어서 “개념만 아는 사람"과 “그 개념을 토대로 실제로 해본사람"은 하늘과 땅차이라고 생각한다. 예전 포스팅 한것중에 Apache 의 mpm 방식에 대해 정리한게 있었는데 (링크) 정리할때 한번 각 방식에 대해서 프로토타이핑이라도 해봤으면… 이런 사태(?)는 면했을것 같다. Apache 설치시 Default방식인 Prefork방식으로 설치되어 있었고 AWS Free tier 의 메모리는 1기가. 사용중인 메모리는 약 450메가였고 mpm방식에 대해 아무 설정도 하지 않았으니 당연히 사용자가 늘어나면 늘어날수록 메모리는 올라가고 KeepAlive 또한 기본값인 on으로 되어있어서… 예정된 서버 다운이였다. (이것도 포스팅을 했었다…ㅠㅠ링크) Apache 를 다시 Worker 방식으로 바꿔 설치하고 KeepAlive 또한 Off로 설정하고 nGrinder를 통해 성능테스트를 해보니 다음과 같은 결과를 얻을수 있었다.

    /images/pycon-2018/tps.png
    Prefork방식일때 테스트를 해보니 다운이 되었다.

    만약, 이걸 예상하고 Worker방식에 KeepAlive Off 가 되어있었다면? 홍보가 더 잘되었을것 같다는 생각을 뒤늦게 땅을 쳐가며 후회해본다. (이래서 개발 마지막 단계는 다양한 QA가 필요하다며…)

    마치며

    이틀간의 걸쳐 진행된 Pycon은 필자에게 많은 선물을 안겨 주었다. (이벤트 상품들을 많이 받아서가 아니라..ㅎㅎ;;)

    /images/pycon-2018/gift.png
    이번 파이콘에서 받은 선물들

    물론 주된 목적은 파이썬이라는 언어의 사용법과 가치, 확장성 등 다양한 세션을 통해 얻은 정보였지만 아무래도 첫 발표를 했던지라 필자에겐 라이트닝톡이 가장 기억이 남는다. 발표를 막상 해보니 별거 없다는 생각과 자신감이 생겼다. (물론 청중이 많아지고 시간이 길어진다면 또 다른 문제일수 있겠지만)

    내년엔 좀더 준비를 탄탄히 하고 발표도 여유롭고 부드럽게 해서 꼭 본 세션에 참가해 보고 싶다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/10/14/deview-2018/index.html b/2018/10/14/deview-2018/index.html index 7f574ffd..ccefa468 100644 --- a/2018/10/14/deview-2018/index.html +++ b/2018/10/14/deview-2018/index.html @@ -22,4 +22,4 @@ 솔루션 선택을 할때 마냥 좋다고 사용하는것이 아니라 실제로 다양한 관점에서의 테스트를 해보고 서비스에 적절한 솔루션을 선택하는 좋은 발표를 들을수 있어서 너무 좋았다.

    마치며

    /images/deview-2018/deview_last.png
    나도 언젠간 스피커가 될수 있겠지…?

    이번 Deview에서는 Facebook에서 알게된 POPit 저자분을 실제로 만나뵙기도 했고 지금은 S사에 계시는 우연히 만나게된 반가운 예전팀 형, 그리고 군 장교시절 필자의 소대원이 AI 스타트업 소속으로 부스를 운영을 하며 서비스 소개를 하고 있는 모습도 보고… 참 다양한 이벤트들이 많았던 행사였다. 사실 올해 Deview 발표자를 모집할때 주니어 개발자가 회사밖에서 성장하는 방법 같은 내용으로 발표를 해볼까도 생각했지만 지금생각해보면 좀더 준비를 철저히 그리고 깊게 해야겠다고 느꼈다. 그리고 내가 하고있는 업무 즉, 서비스 운영/개발은 아무리 바쁘고 힘들어도 기본으로 해야하고 회사를 벗어나 신기술 또는 기존기술의 고도화 방법을 찾아서 공부하고 내것으로 만들어 나가야 하는건 예전이나 지금이나 변함이 없다는걸 다시한번 느낄수 있었던 좋은 행사였다고 생각한다. 이번에도 뒤통수 세게 맞고 간다…


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/12/02/jenkins-install/index.html b/2018/12/02/jenkins-install/index.html index 55895fca..6e63d7df 100644 --- a/2018/12/02/jenkins-install/index.html +++ b/2018/12/02/jenkins-install/index.html @@ -26,4 +26,4 @@
  • 해당 서버의 ip와 위 port에 맞춰 url 입력후 jenkins 설치
    http://ip:8080/jenkins
     

  • Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/12/02/python-buffer/index.html b/2018/12/02/python-buffer/index.html index 406d0384..e0ce2892 100644 --- a/2018/12/02/python-buffer/index.html +++ b/2018/12/02/python-buffer/index.html @@ -44,4 +44,4 @@ sys.stdout=Unbuffered(sys.stdout)
    1. Execute shell을 활용하여 특정경로의 Python 파일을 실행할 경우
    • -u 옵션을 줘서 실행시킨다. ( python -u python_module.py )

    이렇게 두고보면 너무 간단한 작업인데 이런 방법을 모르는 상황에서는 작성된 Python Script를 Shell Script로 다시 감싸보거나 Python 코드를 쓰지 말까 까지 생각했었다… 삽질의 연속들… (Shell Script로 작성하면 바로바로 보였기 때문…)

    다시한번 모르면 몸이 고생한다(?)라는걸 몸소 체험한 좋은…시간이였다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/12/13/elastic-meetup-201812/index.html b/2018/12/13/elastic-meetup-201812/index.html index 0f90b1da..8869b2d5 100644 --- a/2018/12/13/elastic-meetup-201812/index.html +++ b/2018/12/13/elastic-meetup-201812/index.html @@ -15,4 +15,4 @@ 특히 키바나에서는 파일을 업로드하면 자동으로 분석해서 인덱싱을 해주는 기능도 생겼고 (파일 크기가 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직군은 더…) 다시 한번 느끼고 생각할 수 있었던 좋은 시간이었다.

    내년엔 엘라스틱으로 뭘 만들어 볼까! 새로워진 기능들 + 삽질 경험담을 내 것으로 만들어 보자!


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2018/12/31/review-2018/index.html b/2018/12/31/review-2018/index.html index 5ef38ad6..73a122c1 100644 --- a/2018/12/31/review-2018/index.html +++ b/2018/12/31/review-2018/index.html @@ -18,4 +18,4 @@ 새해계획이라면 거창하게 들릴지 모르겠지만 다가오는 2019년엔 Coder 가 아닌 Programmer 가 되고 싶다. (관련 좋은 글) 막연하게 들릴지 모르겠지만 회사원이 아닌 개발자로써 나를 발전시키고 공유하며 서로 성장해 가는, 골을 직접 넣진 않지만 그 과정을 빌드업 하는 미드필더같은 역활을 할수있는 개발자가 되고 싶다. 이러한 계획을 달성하기 위해서는 내년에도 올 2018년을 계속 회고해가면서 잘못된 점을 고쳐나가고 잘한점을 상기하며 개발에 임해야 하지 않을까 싶다. 2018년, 고생했다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/01/02/faster-parallel-processes/index.html b/2019/01/02/faster-parallel-processes/index.html index 7e08b213..7f34b276 100644 --- a/2019/01/02/faster-parallel-processes/index.html +++ b/2019/01/02/faster-parallel-processes/index.html @@ -50,4 +50,4 @@ 3-2. 첫 번째 채널이 아닐 경우 2-3에서 저장한 redis key의 값을 조회하여 2-2에서 저장한 중복제거 key에 있는지 확인 후 발송 여부를 결정한다.

    ▶ 개선 결과

    항목기존1차2차3차
    발송 대상수약 10,530,000명약 10,570,000명약 11,120,000명약 11,240,000명
    첫발송약 6분약 6분약 1초약 1초
    마지막 발송약 11분약 7분약 5분 30초51초

    마치며

    결국 처음에 개선 프로젝트 시작 시 정해졌던 목표에 도달할 수 있었다.(발송 대상이 약 100만 명이 더 늘었지만 1분내로 발송 성공) 또한 무조건 좋다고 사용하다간 오히려 독이 될 수 있고, 반대로 돌아가는 원리를 잘 알아보고 사용한다면 본인이 원하는 가장 이상적인 결과를 만들 수 있다는 좋은 경험을 얻을 수 있었다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/01/10/spring-redirect-oom/index.html b/2019/01/10/spring-redirect-oom/index.html index 1bf1c5d0..0beb6619 100644 --- a/2019/01/10/spring-redirect-oom/index.html +++ b/2019/01/10/spring-redirect-oom/index.html @@ -109,4 +109,4 @@ 지금이라도 알아서 다행이라는 생각과 재현을 안해보고 그냥 그런가보다 하며 넘어갔다면 실제 Spring 내부 코드까지 볼일이 있었을까 하는 생각을 해본다. 이번에 재현을 해보면서 nGrinder 로 성능테스트에 pinpoint 모니터링, 마지막으로 힙덤프 분석까지. 꼭 이번 url redirect 문제만이 아니라 다른 성능적인 이슈가 생길때 마치 치트키처럼 활용할수 있을 나만의 무기를 얻은것 같아 다시한번 뿌듯함을 느낀다.

    마지막으로, 이렇게 재현까지 하도록 자극을 주신 팀 동료분께 감사드린다고 전하고 싶다. (보실지 안보실지 모르겠지만 ^^;)



    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/02/10/access-log-to-elastic-stack/index.html b/2019/02/10/access-log-to-elastic-stack/index.html index 5b7c8d4a..6ecfe4d5 100644 --- a/2019/02/10/access-log-to-elastic-stack/index.html +++ b/2019/02/10/access-log-to-elastic-stack/index.html @@ -140,4 +140,4 @@

    최종 확인

    왼쪽에는 해당 서버를 호출하고 오른쪽에는 키바나를 띄워논뒤 테스트를 해보면 아래처럼 access log를 확인이 가능하다. (apache만 띄워놓은 상태라 404상태로 나오긴 한다..) 불필요한 필드가 있다면 logstash 의 filter에서 remove 하면되고 키바나에서 각 정보를 가지고 다양한 유의미한 데이터를 만들어볼 수 있게 되었다.

    /images/access-log-to-elastic-stack/kibana.jpg

    마치며

    막상 해보면 (해보기전에 느끼는 두려움보다는) 엄청나게 미친듯이 어렵지는 않는데… 맨땅에 해딩이든 뭐든 시작해보고 만들어보는게 중요하다고 다시한번 생각해본다. 필자는 elasticsearch 2.4버전에 대해 영어로된 문서를 보며 설치하고 구성하며 (왜 한글로 된 문서가 한명도 없을까…) 하는 아쉬움에 있었는데 이 글이 필자처럼 설치하는데 비슷한(?) 고충을 느낀 사람들에게 도움이 되었으면 한다. 마지막으로 세부 설정값들로 인해 성능이나 기능이 다양하게 바뀔수 있으니 공식 도큐먼트를 보는것을 강력 추천하고 싶다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/02/17/daily-dev-blog-3/index.html b/2019/02/17/daily-dev-blog-3/index.html index bfe079d8..eb4f3835 100644 --- a/2019/02/17/daily-dev-blog-3/index.html +++ b/2019/02/17/daily-dev-blog-3/index.html @@ -36,4 +36,4 @@ 구독자들이 어떤 글에 더 관심이 갖는지 궁금하였고 많이 본 글에 대해서는 한 번 더 정리하여 메일로 발송해주는 것이 좋을 것 같다는 생각이 들었다. 그래서 메일로 발송된 글에 대해 클릭수를 기준으로 매주 월요일마다 “주간 인기글"을 발행하는 기능을 추가하였다.

  • 단체 블로그 추가 수집 지금은 어썸 데브블로그에서 제공해주는 개인 블로거들의 피드를 수집하고 있는데 단체 블로그들 또한 추가로 수집하여 메일의 상단에 배치한다. (단체 블로그는 아무래도 검증이 된 글일 거라 생각이 든다.)

  • 마치며

    혹시 이 서비스에 대한 아이디어가 있는 분들은 아래 댓글이나 개인 메일로 알려주시면 최대한 반영해보고자 한다. 또한 나중에는 github에 공개하여 오픈소스화한다면 필자보다 더 뛰어난 python 개발자들이 보다 좋은 코드를 만들어주어 점점 해당 서비스가 좋아지지 않을까 하는 기대를 해보며 기술블로그 구독서비스 개발후기를 마친다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/03/17/jenkins-upgrade-master-slave/index.html b/2019/03/17/jenkins-upgrade-master-slave/index.html index 2fcaf539..f857011b 100644 --- a/2019/03/17/jenkins-upgrade-master-slave/index.html +++ b/2019/03/17/jenkins-upgrade-master-slave/index.html @@ -72,4 +72,4 @@ slave-host,0.0.0.0 ~~~ AAAA~~~~~~~8=
    /images/jenkins-upgrade-master-slave/final_upgrade.jpg
    업그레이드 후 노드 구성한 화면

    마치며

    “Master-Slave로 되어있는 구성에서의 Jenkins 업그레이드"를 하며 정말 많은 시간을 할애할 수 밖에 없었고 (관련 지식도 없고 경험도 없었으니… ) 너무 안되어 포기할까도 싶었다. 하지만 경험하지 않은 모든 일들은 다 그만큼의 고통이 필요하고, 그 고통이 있어야지만 비로소 내것이 된다는 생각을 하고 있다. 이것도 나만의 무기가 되어 나중에 jenkins 를 업그레이드 한다거나 노드구성을 할때 보다 쉽고 빠르게 할수있지 않을까 기대를 해본다. 더불어 어려운 이야기이지만 삽질도 올바른 삽질을 할수 있도록 소망해본다…

    /images/jenkins-upgrade-master-slave/spadework.gif
    이런 삽질은 그만…
    출처 : https://gfycat.com/ko/illiterateonlyicelandgull

    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/03/24/write-the-docs-seoul-2019-review/index.html b/2019/03/24/write-the-docs-seoul-2019-review/index.html index ffc846e5..371d9c87 100644 --- a/2019/03/24/write-the-docs-seoul-2019-review/index.html +++ b/2019/03/24/write-the-docs-seoul-2019-review/index.html @@ -23,4 +23,4 @@ 아무리 흐린 잉크라도 좋은 기억력보다 낫다

    변정훈(BlockchainOS) - 개발 관련 기술 블로그 운영하기

    /images/write-the-docs-seoul-2019-review/session-6.jpg
    변정훈 님

    국내에 몇 안되는, 오랫동안 기술블로그를 운영해오시는 개발자 중에 한분인 아웃사이더 변정훈님께서 어떤 식으로 기술블로그를 운영해야 하는가에 대해 발표해주셨다. 필자와는 다르게 (워낙 많이 쓰셔서 일것 같지만) 퇴고는 잘 안 하시고 항상 글을 작성할 것을 생각하며 개인 노트에 메모하고 글을 쓴다고 하신다. (필자도 얼마 전부터 노션이라는 것을 활용해서 관리하고 있는데… 잘 따라 하고 있는 것 같아 나름 뿌듯함을 느꼈다.) 이 세션에서도 뒤통수를 때리는 멘트가 많았는데… 괜히 유명하신 분이 아니구나 싶을 정도였다. (심지어 멘트마저…)

    • 공부할 시간도 적은데 블로그는 또 언제 쓰는가 > 공부할게 많으니까 블로그를 쓴다. (캬~ 1)
    • 글을 지속적으로 쓰려면 어떻게 해야 하는가 > 꾸준히 쓰다 보니 이제는 근육처럼 되었다. (캬~ 2)
    • 문제가 생겨 검색해보고 해결한다고 해서 내 것이 되는 것은 아님 > 내가 직접 재현을 해보고 테스트를 해봐야 내것이 됨. (캬~ 3)

    나름의 철학으로 글을 작성할 때 일관된 흐름을 유지하려고 노력 중이시고 그게 구글에서 검색하면 아웃사이더님의 글이 처음으로 나오는 이유가 아닐까 싶다. (그만큼 사이트의 신뢰도가 높아져서?)

    마치며

    무슨 말이 필요하겠는가. 필자의 메모장에도 블로깅을 하려고 적어놓은 것들만 있지 실제로 실행에 옮기지 못하고 있는데 꾸준히, 그리고 체계적으로, 읽는 사람의 위치에서 글을 잘 써보겠다고 다짐할 수 있었던 좋은 행사였다. 한 가지, 밋업이 끝나고 네트워킹 행사나 뒷풀이가 있었으면 좋았을 텐데 하는 아쉬움이 있었지만 다른 행사에서 자주 찾아뵈고 하다 보면 인연이 생길 꺼라 감히 소망해본다.

    #wtdseoul #WritetheDocs


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/03/31/kafka-meetup-2019/index.html b/2019/03/31/kafka-meetup-2019/index.html index 066bca02..c5999f00 100644 --- a/2019/03/31/kafka-meetup-2019/index.html +++ b/2019/03/31/kafka-meetup-2019/index.html @@ -14,4 +14,4 @@

    필자는 ElasticStack을 사용하면서 처음 카프카를 접하게 되었다. 메세징 큐 라는 개념도 전혀 모르는 상태에서 설치부터 ElasticStack 연동까지 사용하며 정말 강제로 카프카에 대해 공부를 하게 되었다. 카프카를 자주 다루고 메커니즘에 대해 자세히 살펴보다 잠깐 해이해질 무렵 카프카 한국 사용자 모임에서 밋업을 한다고 하길래 빛의 속도로 신청, 아마도 1등으로 신청했지 않았을까 싶다. 사실 작년 카프카 밋업을 못간게 너무 한(?)이 되어 이번엔 회사 업무 등 여러가지로 한창 바쁘지만 “지금이 아니면 안돼” 라는 생각으로 밋업을 다녀왔고, 짧지만 후기를 작성해 보고자 한다.

    (요즘 왜 이렇게 바쁜지 모르겠지만… 신기하게도 그 바쁜 일정들이 하나도 겹치지 않는게 더 신기하다… )

    /images/kafka-meetup-2019/first.jpg
    삼성 SDS 건물에서 진행된 카프카 밋업

    참고로 필자는 카프카에 대해 아주 조금 건드려본 수준이라 발표하시는 분들의 전부를 습득하기엔 다소 그릇이 작아서 일부 세션은 거의 “그런가보다~” 하고 들을 수 밖에 없었다. 후기도 아마 그런 맥락으로 작성할듯 싶다.

    카프카를 활용한 캐시 로그 처리 - 김현준(카카오)

    • 이미지 등 캐시서버의 로그를 분석하기 위한 시스템을 구축하는데 ElasticStack 을 활용
    • Elasticsearch 로 늦게 들어와서 사례를 찾아보니 대용량 로깅 처리시 앞단에 메세징 큐를 둬야 한다고 했고 그게 카프카
    • 카프카 모니터링은 그라파나로 활용
    • lag이 자꾸 생김
      • 파티션을 쪼개거나, 컨슈머를 늘리는 방법이 있음
      • auto.commit.interval.ms 와 enable.auto.commit=true 로 조정
      • interval을 줄이니 lag이 줄어듬
    • 현재는 수백대 캐시서버의 로그를 초당 15만건 이상 처리중

    질문을 했다. 필자도 lag이 높아지면 어쩌지 하는 불안감과 높아지면 컨슈머를 늘리면 되겠지 하는 막연함이 있었는데 commit interval을 줄이면 lag이 줄어든다고 해서 무조건 줄이면 좋은가에 답변은 카프카를 관리하는 주키퍼쪽에 무리가 간다고 설명해 주셨다. 역시 만병통치약은 없고 상황에 따라 적절하게 시스템 관리자가 조정해가며 운영해야 하는점을 느꼈다.

    카프카를 활용한 엘라스틱서치 실무프로젝트 소개 - 이은학(메가존)

    • 카드사의 프로젝트를 약 3개월간 개발하였고 전체 아키텍쳐 중에 일부분을 kakfa를 활용
    • Elasticsearch 데이터를 hadoop에 백업 형태로 옮기며 관리
    • filebeat > kafka > spark streaming 을 활용하여 데이터의 검증처리가 가능 (특정 상황에서의 관리자에게 알림 등)
    • logstash 의 ruby 필터를 활용하여 일정의 작업을 해주는 데이터 파이프라인 구성 가능 (개인정보 식별 등)
    • logstash 는 cron형태의 배치로도 가능

    또 질문을 하였다. (카프카 밋업과는 무관했지만…) logastsh 를 사용하면서 필터쪽에 로직이 들어가면 성능상 괜찮냐는 질문에 하루에 15억건을 처리하고있고 문제가 없었다고 한다. 필자는 아파치 엑세스 로그를 logstash로 처리하면서 간혹 뻗거나 에러가 발생했는데 아마 파일을 logstash가 직접 바라보고 처리도 하게해서 그런것 같다. (지금은 filebeat가 shipper 역활을 수행하고 있고 큰 무리 없이 운영중)

    카프카를 활용한 rabbitMQ 로그처리 - 정원빈 (카카오)

    • 레빗엠큐는 erlang으로 구현된 AMQP 메시지 브로커이고 TCP기반으로 구성
    • Kafka 는 게으르지만 메우 효율성이 뛰어남, 반면 RabbitMQ 는 똑똑하지만 보다 느림
    • Kafka 에서 Elasticsearch 로의 ingset 는 NIFI를 활용
    • 레빗엠큐와 카프카의 차이
      KafkaRabbitMQ
      컨슈머 추가여러 컨슈머가 하나의 메세지를 동시에 할수 있어 확장에 용이함확장할때마다 큐를 추가 생성해야함
      메세지 저장로그기반으로 디스크에 저장, 리텐션 이후 삭제큐 기반으로 메모리에 저장 컨슈머가 메세지 수신시 즉시 삭제
      메세지 처리발송확인 가능 / 수신확인 불가능발송확인/수신확인 가능

    카프카를 마이크로서비스 아키텍쳐에 활용하기 - 이동진 (아파치 소프트웨어 파운데이션)

    • 카프카 스트림즈 소개 (Interactive Query)
    • 카프카를 활용하여 마이크로서비스에서 사용하려면 데이터를 임시 공간에 넣어두고 (redis 같은?) 빼서 사용하는 형태가 아니라 Interactive Query 또는 Queryable Store 로 활용 가능

    사실 이부분은 필자가 제대로 못따라간 세션중에 하나이다. 용어나 메커니즘도 다소 생소했고 대략 어떤 부분을 발표해주시는지 느낌은 있었으나 제대로 이해를 못해서 … 부끄럽지만 카프카 스트림즈의 공식링크로 대체한다.

    https://kafka.apache.org/documentation/streams/

    카프카 프로듀서 & 컨슈머 - 강한구 (카카오 모빌리티)

    • 프로듀서
    • 브로커
      • 메세지를 저장
      • topic name - partition 폴더 구조
      • 세그먼트 단위로 저장 (*.index, *.log, *.timeindex)
    • 컨슈머
      • Fetcher : 네트워크 스레드와 비슷한 역할
      • Coordinator : 어떤 토픽의 어떤 파티션을 comsume할지, 브로커의 그룹 코디네이터와 통신 (hearbeat, offset comit, consumer group join)

    마치며

    /images/kafka-meetup-2019/meetup.jpg
    발표자 분들과 질문 두번에서 받은 책선물

    확실히 수박 겉핥기 식으로 보다보니 지식에 대한 깊이도 얕아 발표자분이 전달하시고자 하는 내용을 100% 다 수용하기엔 힘들었다. 다음엔 가기전에 미리 밋업 발표에 대한 공부를 조금이라도 하고 들을 준비를 한 뒤에 참여하는것으로… 하지만 카프카를 활용해서 다양한 시스템 구성 방법론에 대해 간접으로라도 배울수 있었고, 현재 필자가 운영하고 있는 카프카의 설정값들을에 대해 잘 설정이 되어있나 (막연히 기본값들로만 설정되어 있지는 않은가) 살펴볼 계기가 만들어진것 같다. 이번에도 다행히 “행사에 참여하면 꼭 질문을 하나이상 하자!” 라는 나와의 약속을 지킬수 있어 다행이었다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/04/14/aws-freetier-create-and-ssh-access/index.html b/2019/04/14/aws-freetier-create-and-ssh-access/index.html index d02bc39c..df21fb75 100644 --- a/2019/04/14/aws-freetier-create-and-ssh-access/index.html +++ b/2019/04/14/aws-freetier-create-and-ssh-access/index.html @@ -27,4 +27,4 @@ ※ putty로 AWS EC2 접속하기 : https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/putty.html

    마치며

    다양한 클라우드 서비스들중에 너무나도 신기할정도로 간편하게 클릭 몇번만으로 서버를 띄우고, 서버 접속없이 이또한 클릭 몇번만으로 어플리케이션을 운영할수도 있는 서비스들이 많다. 하지만 필자는 시스템 아키텍쳐를 구성할때엔 버튼 하나로 설치 및 셋팅되는 것보다 직접 설정을 건드려가며 소스로 설치하는 것을 선호한다. 그럼에 AWS의 EC2라는 서비스는 필자의 취향에 너무 알맞는 서비스라며 매력을 느끼고 있는 중이다. 사이즈 프로젝트를 진행하면서 보다 다양한 AWS 프리티어 활용기를 포스팅 할 수 있을것 같아 벌써부터 설렌다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/04/21/spring-boot-mybatis-mysql-xml/index.html b/2019/04/21/spring-boot-mybatis-mysql-xml/index.html index 8bd7ec81..51370d6d 100644 --- a/2019/04/21/spring-boot-mybatis-mysql-xml/index.html +++ b/2019/04/21/spring-boot-mybatis-mysql-xml/index.html @@ -136,4 +136,4 @@ }
    • 결과
    /images/spring-boot-mybatis-mysql-xml/5.jpg

    마치며

    /images/spring-boot-mybatis-mysql-xml/gvsc.png

    이 코드를, 그리고 이 포스팅을 작성하기 직전까지만 해도 “그냥 하면 되는거 아니야?“라고 생각했지만 알고있는 지식과 막상 해보는건 정말 하늘과 땅차이 라는걸 다시한번 느끼게 되었다. (자괴감의 연속…) 더불어 Spring Boot 의 간편함에 놀라웠고 이제 회사일이 조금 잠잠해졌으니 (과연?) Spring Boot로 이것저것 만들며 스터디를 해야겠다고 다짐해본다.

    참고 URL


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/05/12/got-of-java-seminar/index.html b/2019/05/12/got-of-java-seminar/index.html index 5a323f33..7026fe48 100644 --- a/2019/05/12/got-of-java-seminar/index.html +++ b/2019/05/12/got-of-java-seminar/index.html @@ -21,4 +21,4 @@ 결론은 Performance engineering is “Composite Art” of IT 라는 하나의 문장으로 정리를 해주셨다. 아무리 이쁜 디자인과 어렵고 복잡한 기능이 있을지라도 성능이 뒷받침 안된다면 대용량 트래픽 상황에서는 무의미해지기 때문이라고 생각한다.

    자바

    자바의 역사에 대해 설명해 주셨다. ( 역사에 대한 보다 자세한 설명은 https://www.whatap.io/blog/12/ 참고 ) 언제부터인가 JDK 라이센스 이슈가 많았었는데 실무에서 개발하는 입장에서는 java 8 에서는 문제가 안되고 java 11부터 라이센스 문제가 복잡하게 생길수 있다고 한다. 이부분은 공식문서(?)를 찾아보는게 좋을듯 하다. (개인 또는 회사에서 사용할 경우 상황에 따라 법적 이슈가 생길수도, 안생길수도 있는 복잡한 문제가 있어보여서… 필자도 제대로 이해하지는 못했다ㅠ)

    그리고 각 자바 버전에서 발표한 새로운 기능에 대해 설명해주셨다.

    모니터링

    유명한 상용 APM들을 설명해 주셨다. 각각의 장점에 대해 설명해 주셨는데 정말 회사에 요청해 구매할수만 있다면 사서 해보고 싶을정도로 신기한 기능이 많았다. 그중 dynatrace 는 에이전트만 설치해두면 별도의 설정 필요없이 알아서 해준다고…

    오픈소스로는 스카우터와 핀포인트를 설명해 주셨다. 필자는 핀포인트로 회사 서비스를 모니터링 중에 있는데 스카우터에도 좋은 기능이 많아 보여 기회가 된다면 개발서버에 설치해서 핀포인트와 각각 장단점을 비교해 보고 싶어질 정도로 스카우터 자랑을 엄청 해주셨다. (NHN에서는 스카우터로 모니터링 하고 있다고 하니 더욱더 관심이 가게 되었다.)

    APM 즉, Application Performance Management의 핵심은 바로 java.lang.instrument package 와 Java ClassFileTransformer 에 있다고 하셨다. 마치 Spring의 AOP처럼.

    이번 세션의 결론은 처음에 이야기 하신 부분과 비슷한 “절대로 단정짓지 마라 ! 데이터로 이야기 하자 !” 라는 문장으로 정리를 해주셨다. 그만큼 테스트를 많이 해보고 평소에 모니터링을 자주 해가며 서비스의 안정성을 높여야 한다는 뜻으로 이해했다. 끝으로 Q&A가 있어 평소에 궁금했던 질문을 드렸고 너무 친절하게 화이트보드에 그래프를 그려주시면서 (원래 강의시간보다 30분정도 더 하게 만든 장본인…ㅠㅠ) 답변을 해주셨다.

    Q. Application의 상태를 확인하기 위해 각종 모니터링 툴을 활용하는데, 오히려 모니터링이 과하다 보면 Application 성능에 영향을 주게 된다. 어떻게 해야하는가?

    A. 모니터링툴을 홍보하는 쪽에서는 당연히 성능에 영향이 없다고 한다. 하지만 먼저 개발서버에서 테스트를 해봐서 모니터링툴이 있고 없고의 서비 리소스의 차이를 확인해보고 조금씩 적용범위를 늘려가는 식으로 해보는것도 하나의 방법이 될 수 있다. 또한 샘플링을 통해 일부분만 확인하는 방법도 있다. (필자가 이용하는 pinpoint는 request의 20% 이런식으로 샘플링을 하고 있었는데 scouter에서는 response time기준으로 샘플링이 되나보다?ㄷㄷ)

    /images/got-of-java-seminar/2.jpg
    너무 두서없이 적었나…

    그리고 필자의 질문 때문이였는지 실무에서 있었던 장애시 그래프 사례를 보여주시며 끔찍한(?) 상황까지 재밌게 표현해 주시며 약 3시간여 진행된 세미나가 마무리 되었다.

    # 마치며

    자바로 Application개발을 하면서 성능과 모니터링은 마치 삼겹살엔 소주, 치킨에 맥주처럼 정말 떼려야 뗄 수 없는 사이인것 같다. 우아한 형제들에서 주최한 이번 기술 세미나는 필자에게 정말 많은것을 배우게 해준 좋은 행사였다. 그리고 회사에 가면 짬나는 시간을 활용해서 스카우터로 성능테스트를 해볼 계획이다. (라고 말하면 안되고 점심에 졸려서 성능테스트를 해봤다고 말해야 직장 상사가 좋아하신다 라고 말씀해주셨다 ㅎㅎ)

    /images/got-of-java-seminar/3.jpg
    질문을 해야 내것이 된다는 나와의 약속을 이번에도 지킬수 있었다! (질문하고 받은 배달의 민족 쿠폰!)

    1,2 회 모두 탈락해서 못들었지만 다음에도 이런 기술관련 행사가 있으면 꼭 듣고 싶고 마지막으로 필자에 질문에 너무 성실하게 답변해 주시고 재밌고 귀에 쏙쏙 들어오는 강연을 해주신 이상민님께 이 포스팅으로나마 다시한번 감사의 말씀을 전하고 싶다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/05/19/d-light-togetherthon-2019/index.html b/2019/05/19/d-light-togetherthon-2019/index.html index e3a4d7cf..b7ad2daa 100644 --- a/2019/05/19/d-light-togetherthon-2019/index.html +++ b/2019/05/19/d-light-togetherthon-2019/index.html @@ -23,4 +23,4 @@ 프로젝트 소개 페이지에서 적어 놓은 것 처럼 여러가지 기능을 구현하였다. 그것도 완벽하게.

    • 단골마트 : 주변의 마트 또는 슈퍼를 지도에서 찾아 단골마트로 지정하고 마트의 전단지를 보며 행사를 확인할 수 있음
    • 상품검색 : 단골마트에서 팔고있는 상품들을 검색이 가능
    • 장보기 메모 : 상품 상세 페이지에서 구매할 수량을 선택하고 장보기 메모에 담아서 나중에 구매 또는 취소를 할 수 있음
    • 장보기 메모 내역 : 이제까지 구매했던 이력을 확인할 수 있고 마치 가계부처럼 자신의 소비 습관을 해당 메뉴에서 분석할 수 있음
    • 할인 알림 설정 : 원하는 상품이 있다면 알림설정을 할 수 있고 판매자가 상품을 등록하는 순간 푸시메세지로 정보를 알려줌

    아래는 발표 자료. 매년마다 어떤 행사에서라도 꼭 발표를 한 번 이상 하자는 나와의 약속을 이번 D.light 투게더톤에서 달성할 수 있어서 좋았다. 물론 이번 발표때도 여유라곤 찾을 수 없었지만…

    마치며

    결국 여러 심사조건(?)으로 6개 팀중 상위 2팀에게 주는 sketch 라이센스를 받게 되었고 (필자피셜) 만족할만한 마무리가 될 수 있었다.

    /images/d-light-togetherthon-2019/result.jpg
    우리 다섯명 팀원들의 캐릭터(By ZEPETO), 최종발표 장소인 구글캠퍼스, sketch 라이센스

    발표에서도 몇번을 반복하며 이야기 했지만 이런 팀원들을 또 만날 수 있을까 하는 생각과 함께 다시한번 팀원들에게 감사하다는 말을 전하고 싶다. 그리고 아무것도 정해지지 않는 상황과 아무것도 구축되어 있지 않은 개발환경에서 나름 구현하고자 했던 기능을 구현하며 멋지게 마무리 할수 있어 다행이라 생각하고 다양한 트러블슈팅 속에서 나름 많은것을 배울 수 있었다. 머릿속에 있는 것과 그것을 말로 설명할 수 있는 것, 나아가 그것을 직접 내 손으로 해보고 문제를 해결해 나가는 것은 엄청난 차이가 있다고 생각한다. 그러한 과정들 속에서, 그리고 이렇게 다양한 사람들과의 협업을 통해 배우는 것 또한 분명히 있고 그것을 오롯히 내것으로 만드는게 마지막으로 남겨진 숙제인것 같다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/06/30/controller-common-logging/index.html b/2019/06/30/controller-common-logging/index.html index a8d590cb..6251dfb1 100644 --- a/2019/06/30/controller-common-logging/index.html +++ b/2019/06/30/controller-common-logging/index.html @@ -227,4 +227,4 @@ https://github.com/taetaetae/request_logging 필터와 인터셉터, AOP 등 평소 자주 사용하지 않은 (이미 누군가 다 만들어 둔) 부분을 만지면서 다시한번 Spring의 주요 개념을 숙지하는데 도움이 되었던 경험으로 남을 것 같다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/07/07/review-first-half-2019/index.html b/2019/07/07/review-first-half-2019/index.html index bd43f2b6..fe8b6bae 100644 --- a/2019/07/07/review-first-half-2019/index.html +++ b/2019/07/07/review-first-half-2019/index.html @@ -26,4 +26,4 @@ 적어도 회사에서 있는 시간 속에서는 다른 곳에 한눈 안 팔고 회사 업무에 전념하려고 노력했던 것 같다.

    외부 활동

    부족한 시간을 쪼개면서 밋업이나 세미나에 참여하곤 했었다. 그리고 마냥 듣고만 오진 않았고 “행사에 참여하면 무조건 질문 하나는 하자"라는 나와의 약속을 지키며 정리한 내용을 블로그에 포스팅하기도 하였다.

    /images/review-first-half-2019/magarine.jpg
    올해 첫 발표!

    디자이너와 개발자가 함께하는 투게더톤을 진행하기도 했었다. 투게더톤은 약 한 달 동안 진행되는 해커톤으로 하루 또는 무박 2일 동안 하는 기존 해커톤과 다르다. 이 기간 동안 팀 내에서 자유롭게 일정을 조정할 수 있다. 우리 팀은 약 7주에 걸쳐 “동네 마트 할인 정보를 알려주는 앱” 을 만들게 되었다. 필자는 API 전반에 대해 담당을 하였고 작은 부분이었지만 웹사이트도 간단하게 만들어 보았다. 아무것도 없는 백지상태에서 시작하려니 막막했지만 후기에서도 적었듯이 다시 해보라고 하면 머릿속에 전체 아키텍처가 그림으로 그려질 만큼 자신감이 생겼다. 특히 정말 좋은 팀원들과 함께 협업할 수 있어서 너무 좋았다.

    내공 연마

    한 달에 2개 이상 블로그 글을 작성하는 목표가 있었다. 그런데 지난달에 이사를 하다 보니 (핑계…) 목표를 달성 할 수가 없었다. 하지만 나름 퀄리티가 있는 글을 쓰려고 노력했고 PV도 작년보다 조금씩 오르고 있는 것 같아 내심 기분이 좋다. 그리고 작년 말부터 시작한 필자의 첫 토이프로젝트 인 기술블로그 구독서비스 에 이런저런 기능을 추가하였다. 설마 1000명이 넘게 구독 하겠어?라고 생각했지만 이 글을 작성하고 있는 시점에서 1,569명이나 구독했다. 설마 1년 넘게 내가 이 프로젝트를 운영하겠어?라고 생각했지만 다음 주가 되면 딱 1년째. 신기할 따름이다. 마침 기회가 되어 GDG 주관으로 행사하는 모두의 TOY STORY: SIDE PROJECT 어디까지 가봤니?라는 주제에 첫! 공식 발표자로써 발표를 할 수 있게 되어 너무나도 영광이다. 해당 발표 후기는 나중에 작성하는 것으로~

    글또 3기 다짐

    글쓰는 또라이가 세상을 바꾼다 라는 페이스북 모임이 있다. (이번기수가 벌써 3기라고 한다 ㄷㄷ) 글또 라는 모임에 대해 간단히 정리를 해보면 다음과 같다.

    • 일정의 예치금을 먼저 저장한다.
    • 2주 간격으로 블로그 글을 작성 + 2명의 글에 대해 서로 리뷰
    • PASS권은 2회 (다른사람들의 글에 리뷰를 많이 해주면 PASS 권을 부여)
    • 글을 올리지 않았거나, 리뷰를 하지 않았을 경우 예치금에서 일부 삭감
    • 마지막 날까지 진행하고 예치금을 다시 돌려받는 형식

    올해부터 블로그 포스팅을 좀 더 많이 하자고도 했고, 단순 횟수만 늘리는 것이 아닌 글쓰기에 대해서도 연습을 하고자 했는데 마침 딱 원하는 모임이 있어 시작을 하게 되었다. 이 모임에 참여하기 위해 무작정 2주마다 한 개의 글을 쓰지 않을 것이다. 배운 것을 기록하고 정리하는 습관을 기르기 위해 글을 쓸 것이다. 또, 양질의 글을 작성하기 위해 글쓰기 책들을 읽어야겠다.

    마치며

    우선 다음 주에 있을 발표 준비에 최선을 다하고, 여력이 되면 새로운 프로젝트를 시작하고 싶다. 회사에서는 회사일 열심히 하고 회사 밖에서는 나만의 인사이트를 찾기 위한 여정에 지치지 않도록 체력이며 정신력이며 갈고닦아야 할 것 같다. 운동도 다시 시작을 해야 할 텐데 . . . ㅠㅠ


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/07/21/spring-file-upload/index.html b/2019/07/21/spring-file-upload/index.html index 0da7bae7..f7433698 100644 --- a/2019/07/21/spring-file-upload/index.html +++ b/2019/07/21/spring-file-upload/index.html @@ -63,4 +63,4 @@

    파일 업로드

    예외처리라는 것을 생각하면서 개발해야한다고 느끼게 되었다. NPE 같은 사소한 로직에서의 예외처리부터 파일 업로드시 서버의 메모리를 생각할수 있는 시야. 이런게 경험이 아닐까 싶다. 또한 (잘 돌아가니까) 환경설정 값을 수정하지 않고 배포하는 것보단 가급적 어떤 설정값들에 의해서 어플리케이션이 돌아가는지 특히, 스프링 같은 프레임워크의 도움을 받는다면 해당 프레임워크의 설정값들을 수정하며 성능에 이득을 취할 부분들은 없는지 꼼꼼하게 개발하는 습관을 길러야 할 것 같다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/08/04/apache-load-balancing/index.html b/2019/08/04/apache-load-balancing/index.html index 7713b635..f5616c20 100644 --- a/2019/08/04/apache-load-balancing/index.html +++ b/2019/08/04/apache-load-balancing/index.html @@ -104,4 +104,4 @@ https://tomcat.apache.org/connectors-doc/reference/workers.html https://tomcat.apache.org/connectors-doc/common_howto/loadbalancers.html

    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/09/08/network-monitor-by-packetbeat/index.html b/2019/09/08/network-monitor-by-packetbeat/index.html index ff6b05bd..cea76e85 100644 --- a/2019/09/08/network-monitor-by-packetbeat/index.html +++ b/2019/09/08/network-monitor-by-packetbeat/index.html @@ -98,4 +98,4 @@
    /images/network-monitor-by-packetbeat/packetbeat_config.jpg
    좌측이 기본, 우측이 불필요 데이터 제외하고 나서의 수집 상태

    사실 위 설정값은 페이스북 한국 Elasticsearch 유저그룹에 문의해서 알게된 내용이다. 역시 커뮤니티 파워, 집단지성의 힘을 다시한번 느낄 수 있었다. (모르면 물어보자! + 문제에 대해 좀더 잘 검색하도록 노력하자!)

    마치며

    Packetbeat 을 사용하면서 가장 좋았던 점은 기존 로직과는 전혀 무관하게 작동하는 점이 가장 좋았다. 이러한 점은 어느 상황에서도 서비스 코드 디펜던시가 없어 자유롭게 활용이 가능하다는 뜻으로 해석을 해보곤 한다.

    /images/network-monitor-by-packetbeat/angry.jpg
    마냥 좋다고 운영환경에 무작정 도입하면 이런 따사로운 눈빛을 받을 수 있으니 참고
    이미지 출처 : https://namu.wiki/w/%EB%82%98%EB%8A%94%20%EC%9E%90%EC%97%B0%EC%9D%B8%EC%9D%B4%EB%8B%A4

    필자는 최근 운영환경에도 packetbeat를 적용해서 outbound 트래픽을 모니터링 하고 문제가 있는 엔드포인트에 대해 자동으로 점검을 하는 시스템을 만들려고 하고 있는데, 네트워크 패킷을 전부 까보며(?) 아무래도 cpu 성능에 지장을 줄수밖에 없는 오픈소스 모듈이다보니 다양한 테스트를 통해 서비스 운영에 영향이 없도록 설정값들을 튜닝해 가며 적용해봐야 할 것 같다. (무작정 좋다고 적용하다 오히려 큰 화를 부를 수 있다…)

    내가 맛있어 하는 음식이 남들도 맛있으리란 법 없듯, 소개팅에 나가기전 준비한 멘트가 전부 먹히리라는 법 없듯… 모든 상황에는 튜닝은 필수다. 그 튜닝을 얼마나 잘, 그리고 센스있게 하냐가 포인트!


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/09/29/woowabros-spring-batch/index.html b/2019/09/29/woowabros-spring-batch/index.html index b39c4586..1a465502 100644 --- a/2019/09/29/woowabros-spring-batch/index.html +++ b/2019/09/29/woowabros-spring-batch/index.html @@ -27,4 +27,4 @@ ​라는 질문에 @ConditionalOnProperty 어노테이션을 활용하게되면 해당 Job 에서 필요한 bean 만 띄울수 있다고 하셨다. 필자가 운영하고 있는 스프링 배치 버전이 3.x 이기도 하고 멀티 모듈로 구성되어 있으며 (batch가 단독 컴포넌트가 아님…) 필요한 bean만을 지정하기에는 스파게티 코드가 될게 뻔한 상황인것 같아 질문의 답변에서 해법을 찾기에는 조금 힘들었지만 또 언제나 그랬듯 이러한 상황에서 해결방법을 찾아야 하는게 개발자의 숙명 아니겠는가. 좀더 고민해봐야할 부분인것 같다.

    마치며

    스프링 배치에 대한 기본개념과 관리도구를 활용해서 생생한 현장감과 함께 배치 어플리케이션의 운영 노하우를 들을 수 있어서 너무 좋았던 세미나였다. 이번에도 역시나 내가 고민하고 있던 문제는 누군가 이미 고민했던 문제라는것, 그리고 그러한 고민의 해결방법을 공유함에 있어 생겨나는 가치에 대해 다시한번 온몸으로 뜨거운 열정을 느낄수 있었던 날로 기억에 남을 것 같다.

    /images/woowabros-spring-batch/think.gif
    충분하면 만족해야만 할까?
    출처 : https://vryjam.com/gif.php?id=ODWEBD0bmRGzTq5

    다만, 이제까지 A라는 구조로 구성된 어플리케이션에 단순 기능 추가만 할게 아니라 정말 A라는 구조가 최선일까, A의 구조보다 보다 더 효율적이고 유연한 B 나 C 의 구조는 없을까 하는 이러한 고민을 계속 하려는 자세를 가져야 겠구나 하는 생각을 해본다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/10/13/batch-nondisruptive-deploy/index.html b/2019/10/13/batch-nondisruptive-deploy/index.html index 09795bb9..0e53a6ac 100644 --- a/2019/10/13/batch-nondisruptive-deploy/index.html +++ b/2019/10/13/batch-nondisruptive-deploy/index.html @@ -77,4 +77,4 @@

    # 마치며

    jar파일이 실행되고 JVM에 올라가게 되면 jar파일을 삭제한다거나 위치를 이동시켜도 에러가 나거나 하지는 않지만 코드 내에서 상대경로같은 설정들이 있기 때문에 폴더 전체를 심볼릭 링크로 연결하고 그 안에서 실행되도록 수정하였다. 앞서 이야기 했지만 이러한 설계는 어디까지나 필자가 운영하고 있는 상황에 맞춘것이기 때문에 이를 어떻게 잘 활용하는가가 이번 포스팅에 주요 핵심이 될 수 있을것 같다. 항상 배포 할때마다 예전에 그렇게 해왔기 때문에 라는 핑계로 Job이 돌고있으면 기다렸다가 배포해야만 했던 필자 자신이 부끄러워진다. 시도조차 안해보고 그런가보다 하고 적응만 하려 하거나, 불편하지만 안불편한척 하는 그런 태도를 버려야 하지 않을까 하는 반성을 해보는 시간이 되었다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/10/27/a-reason-for-writing/index.html b/2019/10/27/a-reason-for-writing/index.html index e4ec2209..83395739 100644 --- a/2019/10/27/a-reason-for-writing/index.html +++ b/2019/10/27/a-reason-for-writing/index.html @@ -24,4 +24,4 @@

    신입시절. 배워야 할 것도 회사 업무도 많아 허우적대던 때가 있었다. 그렇게 하루에 3~4시간 자며 정신없이 하루를 보내던 날 문득 동기 형이 “개발자는 기술 블로그를 해야 돼!“라는 전혀 이해가 안 되는 말을 해온다. 이렇게 바빠 죽겠는데 블로그에 글까지 쓰라고? 말이 되는 소릴 하라며 반박하다 못내 이기는 척 하나 둘 글을 쓰기 시작했고, 다른 유명 블로거처럼 엄청나진 않지만 하루에 1,000~2,000명 정도 들어오며 점점 성장해 가는 나만의 기술 블로그가 되었다.

    /images/a-reason-for-writing/blog_graph.jpg
    미약하지만 처음보다는 성장하고 있는 블로그 PV(Page View)

    또한 필자의 개발자 경력(?)을 돌이켜 보자면 기술 블로그를 하기 전과 하고 난 후로 나뉠 만큼 기술 블로그는 개인적으로 엄청난 영향력이 되었다.

    이 기회를 빌어 동기 형에게 감사의 인사를 전하고 싶다. 형. 보고 있죠? ;]

    이번 포스팅은 꼭 “블로그를 하자” 라기 보다 “글을 왜 써야 하고 어떻게 써야 하는지"에 대해 이야기해보고자 한다. 처음 이 글을 쓰려고 마음먹었을 땐 개발자라는 직군에 국한되지 않고 누구에게나 적용될 정도의 범용적인 글을 쓰려 했으나 “S"의 조언으로 독자(타깃)을 최대한 개발자에 맞춰 써보고자 한다. thanks to “S”

    사실 조금만 검색을 해보면 특히 개발자에게 글쓰기가 얼마나 중요한지 찾아볼 수 있을 정도로 다양한 글들에서 “개발자가 왜 글을 써야 하는가"에 대한 내용이 언급이 되곤 했었다. 글을 쓰지 않던 개발자. 하지만 지금은 글쓰기가 정말 중요하다고 느끼며 적어도 2주에 하나 이상의 글을 쓰려는 현업 개발자의 시선에서 정리를 해보고자 한다. 그리고 마침 멘토링 해주고 있는 분께도 글 쓰는것에 대한 중요성을 알려주고 싶었고, 팀 내에도 공유를 하고 싶어 겸사겸사.

    왜 글을 써야 할까?

    비로소 내 것이 되기 위한 과정

    프로그래밍 언어를 처음 배울때 꼭 만나는 문구 Hello World를 출력하시오. 이게 의미하는 의미가 무엇일까? 정말 새로운 세계를 알려주려 하는 것 일까?(그럴수도 있다…) 우리가 살아가며 “배움"이라는 과정은 대부분 비슷하겠지만 특히 IT 기술은 책을 다 읽었다든지, 동영상 강의를 다 들었다고 해서 내 것이 되었다고 말하기는 어려울 것 같다. 직접 키보드를 두드려 가며 거기서 얻을 수 있는 또 다른 “인사이트” 가 생길 수도 있기 때문이다.

    다른 예로, 운영하던 시스템이나 서비스에서 장애를 맞았다고 가정해보자. 하지만 우리는 늘 그래왔듯 어떻게든 장애를 해결할 것이다. 이러한 상황에서 분명 “문제의 원인"이 있었을 테고 “해결 과정"이 있기 마련인데 이곳에서도 “인사이트"가 분명 있을 것이다.

    이러한 “인사이트"를 글로 적다 보면 그냥 “아~ 그렇구나, 그랬었지” 하는 머릿속에서의 기억보다는 훨씬 더 오래 남을 것이고 혹여 글에서 정리를 잘못해 다른 사람들의 피드백이 있다면 더할 나위 없이 좋은 효과라고 생각이 된다. (이것이 바로 공유의 힘!)

    더불어 글을 쓸 때 올바른 정보에 기반하여 쓰는 습관이 중요한데 그러다 보면 원래 쓰려고 했던 내용보다 더 깊게 알아가는 과정 속에서 또 다른 배움을 얻을 수 있는 반강제적 기회가 생길 수 있다. 누가 시키지 않았어도 배운 것에 대한 활용을 하고 싶은 생각이 들고 이를 또 글로 쓰고. 긍정적인 순환 속에 생겨나는 작은 발자국일지라도 성장해가는 자신을 느낄 수 있을 것이다.

    몸이 기억하는 정리하는 습관

    개발을 하다 보면 정말 간단한 “CRUD”(Create, Read, Update, Delete) 부터 시작해서 엄청나게 복잡한 도메인 지식에 기반하여 개발을 해야 하는 상황이 생긴다. 그럴 때면 머릿속으로 정리하는 것보다 그림이나 글을 써가면서 정리하는 게 좋다는 건 굳이 말하지 않아도 아는 사실. 글을 쓰다 보면 기승전결의 정리 방법과 목적이 무엇이고 근거가 무엇인지에 대해 구분하는 스킬이 늘어나는 것 같다.(적어도 필자는 기술 블로그를 운영하면서 정리하는 스킬이 그전보다 엄청나게 늘어났다고 자부한다.)

    /images/a-reason-for-writing/ink.jpg
    중국 속담중에 하나, 머릿속에 박혀 나오질 않는다.

    구조가 보기 어렵게 꼬여버린 스파게티 코드나 기능(스펙)이 너무 복잡한 도메인 지식도 글을 쓰며 갈고닦은 “정리 스킬"이 있다면 보다 깔끔한 코드로, 복잡하지만 간결한 스펙으로 정리하는 데 도움이 될 수 있다. 이러한 스킬은 비단 개발할 때나 스펙 정리할 때 뿐만 아니라 상대방과의 이야기를 할 때나 어떠한 계획을 세울 때. 고민이 생겼을 때 등 정말 다양한 곳에서 사용할 수 있는 정말 “나만의 무기"가 될 수 있다.

    나를 브랜딩하는 수단 (a.k.a 기술블로그)

    특히 이 글을 읽고 있는 독자가 학생이시라면 “글쓰기”, 나아가서는 “기술 블로그"를 강력 추천하고 싶다. (그렇다고 학생이 아니라면 늦었다는 소리는 아니다. 지금 당장 시작하자.)

    /images/a-reason-for-writing/park.jpg
    늦었으니 지금당장 시작하라는 소리일꺼다. 그쵸 명수형?
    출처 : http://blog.besunny.com/?p=6111

    자신이 어떤 생각을 가지고 어떤 기술에 관심을 가지며 어떤 문제 해결을 해왔는지에 대해 나만의 개발 히스토리로 한눈에 볼 수 있는 수단이 된다고 생각하기 때문이다. 참, 요즘 채용시에 Github 계정이나 기술 블로그를 제출해야 하는 곳이 많이 생길 정도로 기술 블로그에 대한 관심이 부쩍 늘어난 것 같다. (적어도 필자가 취업할 때보다는… 아. 옛날이여)

    필자는 기술 블로그를 운영하면서 집필, 추천평 등 전혀 예상하지 못한 경험을 할 수 있었다. (그중에 한 것도 있고 거절한 것도 있지만…) 그에 발표를 할 수 있었던 좋은 기회도 생겼고, 개인 메일로 이직 제안이나 기술 문의 등 “회사"라는 명찰을 떼고 외부에서 오롯이 나 혼자 일어설 수 있는 힘이 조금씩 생겨나고 있는것 같다. (그렇다고 이직 의사가 있다는 건 전~혀 아니니 오해는 말자. 회사님 사랑해요.)

    취업이나 이직을 할 때. 나에 대해 누군가에게 알리는 순간이 있을 때 구구절절 이런저런 기술들을 할 줄 알고 이런저런 경험을 해봤어요라고 말하는 것도 방법이 될수 있지만 우아하게 기술 블로그 링크하나 딱! 전달해 보는건 어떨까? 뭔가 더 있어 보이지 않을까?

    글을 쓸때 중요한 핵심 6가지

    그래서 너가 말하고 싶은게 뭔데?

    글을 쓰다 보면 이야기하고 싶은 게 많아서(잘 쓰고 싶어서) 결론보다는 그 결론을 말하기 위한 보충 설명이나 근거를 먼저 말하곤 한다. 하지만 글을 읽는 독자 입장에서는 정답(=결론)이 가장 궁금한데 그것이 글의 말미에 있다면 자칫 글의 퀄리티가 아무리 좋더라도 지루한(?) 과정을 거치는 수고가 필요할 수밖에 없다. 가급적 글의 무게중심은 서두에 두는 게 “글"이라는 목적에 부합하는 것 같다. 결론을 앞에서 이야기하고 근거를 이야기한 후 마지막에 한 번 더 결론을 이야기하는 것도 하나의 방법이 될 수 있겠다.

    그래도 뚜렷한 결론이 있다면 다행이다. 결론마저 없는 글은 독자로 하여금 왜 글을 썼는지 모를 느낌을 안겨줄 수 있다.(최악의 경우 읽다가 중단하게 된다…ㅜㅜ) 글쓰기에 있어 결론도 중요하지만 이 글을 쓰는 목적이 명확해야 설령 목표가 글 뒤에 배치되었다고 해도 끝까지 읽을 수 있는 힘이 생기지 않을까?

    /images/a-reason-for-writing/kimchi.jpg
    반전에 반전을 거듭하며 결론을 도무지 알수없는 레파토리는 김치싸대기를 던지던 아침 드라마가 어울린다.
    출처 : https://m.post.naver.com/viewer/postView.nhn?volumeNo=14289808&memberNo=12508720

    누가 읽게 되는 글인가?

    글을 쓰는 사람(필자)이 있으면 글을 읽는 사람(독자)이 있기 마련. 대부분의 글들은 필자가 독자를 “설득"하기 위한 내용이 주를 이룬다. 독자가 한정적이라면. 예컨대, 주간 보고를 쓴다고 가정했을 때 독자는 오롯이 팀장님이 된다. 이런 경우 주저리주저리 쓰거나 다시 한번 묻게 되는 문장들보다는 팀장님이 정말 궁금해할 내용을 적어주는 게 좋다. 한 번 더 안 물어볼 수 있게 작성한 글을 팀장님의 위치에서 다시 한번 읽어보는 것도 하나의 방법이 될 수 있다.

    만약 독자의 스펙트럼이 넓거나 기술 블로그처럼 불특정 다수라면 가장 지식이 없는 사람에게 쓰는 것처럼 글을 써보자. 가끔 너무 쉽고 자세히 써서 당신이 아마추어처럼 보일 것 같다는 우려를 할 수도 있다. 하지만 지금 글을 쓰는 당신이 적어도 글을 안 쓰고 읽기만 하는 독자보다는 가장 프로에 가깝다.

    독자가 다 알 거라는 생각은 하지 말자. 최대한 쉽게. 처음 보는 사람도 보고 따라 하거나 이해가 되도록 눈높이를 낮춰서 쓰는 습관을 길러보자. 무려 당신의 글을 시간을 할애하면서까지 읽어주는데 최대한 친절해야 하지 않을까?

    앵무새가 되지 말자.

    링크만 복붙하거나 소위 말해 펌 글, 정작 내용은 없고 코드만 덩그러니 있거나 단순히 “글쓰기"를 위해 쓰는 글들은 오히려 안 쓰는게 좋다.

    글에는 자신만의 생각이 녹아있어야 한다고 생각한다. 그렇지 않고서는 따라쟁이 앵무새와 다를 게 없다. 어떠한 오픈소스를 도입하는 과정을 글로 썼다고 생각해보자. Step By Step으로 따라 할 수 있게 작성한 글일지라도 최소한 마지막에는 자신만의 생각이 정리되어 있어야 글을 쓰는 자신도, 글을 읽는 독자도 “마무리"가 될 수 있기 때문이다. 왜 오픈소스를 도입하게 되었고, 도입하는 과정에서의 문제, 도입하고 나서의 장점과 단점 등 이야기할 거리는 무궁무진하다.

    글쓰기에도 호흡이 중요

    TV나 인터넷 영상들을 보고 있노라면 편집의 기술이 엄청나게 발전된 것을 체감할 수 있다. 혹시 체감하지 못했다면 화면의 전환이나 자막 등 너무 자연스러워서일 수 있다. 글쓰기에서도 이러한 전환이나 문장의 흐름, 호흡은 정말 중요하다.

    이러한 글쓰기에서의 호흡은 문장 쪼개기, 단락 구분하기, 적절한 그림 및 표 활용 등 독자가 읽을 때 지루하지 않을 정도의 말 그대로 “숨 쉴 수 있는 타이밍"을 제공해야 한다. 읽을 때 집중이 잘 안되거나 어디까지 읽었지 하며 흐름이 끊긴 경우를 경험해 봤을 거라 생각이 든다. 사실 이 부분은 필자도 잘 안되긴 하지만 이번 포스팅처럼 말하고자 하는 메인 키워드 단위로 나눈다거나 약간의 위트를 더하기 위한 짤 같은 것도 이러한 “호흡"의 기술이라 생각한다.

    퇴고. 글쓰기의 가장 중요한 단계

    지금 이 글을 쓰는 순간에도 퇴고를 10번 이상 하는 것 같다. 필자가 생각하는 퇴고라 함은 쓴 글의 처음부터 끝까지 읽어보며 맞춤법이나 띄어쓰기 교정, 실제로 소리 내어 읽어보며 숨이 차거나 집중이 흐려지진 않은지 하는 일련의 과정을 말한다.

    퇴고를 꼭 몇번 해야 한다는 정해진 규칙은 없지만 최소 3번은 하는 것 같다. 그러면서 더 중요한 것을 위로 올리고 불필요하게 글자 수만 늘린 건 없는지. 글의 목적과는 거리가 있는 문장은 없는지 등 우리가 서비스를 출시하기 위해 개발 환경에서 테스트를 하고 QA 단계를 거쳐 최종 운영환경에 릴리즈 하는것 처럼.

    글쓰기는 말하고자 하는 것을 “텍스트"로 전달하는 아주 기본적이며 제한적인 수단이기 때문에 몇 번이고 읽어보면서 고칠 수 있는 부분은 최대한 고치자. 그러면서 글을 썼던 자신을 되돌아보며 무슨 생각으로 이런 글을 썼나 돌아보는 기회도 되고.

    나만의 글쓰기 플랫폼을 찾자.

    정말 다양한 글쓰기 플랫폼이 있다. Github, 네이버 블로그, 티스토리, 워드프레스 등 서버호스팅 비용 없이도 무료로 제공해주는 곳들인데 각 플랫폼 마다의 장단점이 있으니 자신에게 맞는 곳을 찾아서 글을 써보자. 특히 Github 블로그는 정말 다양한 방법으로 블로그를 만들 수 있고 테마 또한 무궁무진하며 웹에 대한 지식이 있다면 얼마든지 커스터마이징이 가능하다.

    블로그를 만들었으면 검색에 잘 되도록 SEO 설정을 해두고 RSS를 만들어 국내 기술블로그를 모아둔 awesome-devblog에 자신의 블로그 정보에 대해 PullRequest를 날려보자. 그러면 필자가 만든 기술블로그 구독서비스에서 여러 사람들에게 매일 오전 10시에 친절하게, 그것도 무료로 홍보를 해주기 때문이다. (갑 분 서비스 홍보, 후원좀…)

    GA(Google Analytics)를 붙여 어디서 유입되고 얼마나 들어오는지 보는 재미도 쏠쏠하다. 필자도 처음엔 많아야 10명(그게 전부 필자였다는건 비밀)이었지만 점점 방문자수가 늘어나니 글을 좀더 재미있고 잘 써야겠다는 사명감과 책임감도 생겨서 초창기에 썼던 글과 요즘의 글을 비교를 해보면 글의 퀄리티가 훨씬 늘어난것 같다.

    마치며

    /images/a-reason-for-writing/cyworld.jpg
    무엇을 말하려는지의 글쓴이의 목적은 충분히 전달되었다. 오글거림도 함께.
    출처 : http://m.news.zum.com/articles/25408896

    우리는 사실 어렸을때부터 글쓰기를 해왔다. 어렸을적 그림일기부터 시작하여 사랑하는 사람에게 손편지를 쓰고 싸이월드에 흑역사를 만들었던 시절들. 개발자가 된, 혹은 이제 개발자가 되려는 사람들이 있다면 그냥 글이 아닌 자신이 가지고 있는 기술에 대한 글을 써보는건 어떨까. Stack Overflow Driven Development (SODD) 라는 말이 있듯이 개발은 사실 엄청난 성능과 최적의 알고리즘을 요하는게 아니라면 개발자 간의 경쟁력은 일반적인 개발실력 이외엔 시간과 경험의 차이인것 같다. 여기에 글쓰기 연습을 하며 보다 논리적이고 정리하는 습관을 기른다면 이또한 남들과는 다른 나만의 무기가 될수 있지 않을까 하는 생각을 해본다.

    이 글을 읽는 독자분들 중 자신만의 기술블로그가 없다면 지금 당장이라도 시작하라고 권하고 싶다. 첫 시작은 어렵겠지만 자신만의 스타일로 “글쓰는 개발자"가 되는데 건투를 빈다.


    # 참고

    좋은 기술 블로그를 만들어 나가기 위한 8가지 제언

    강원국의 글쓰기 : 남과 다른 글은 어떻게 쓰는가


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2019/12/29/review-2019/index.html b/2019/12/29/review-2019/index.html index 01bfa7de..5f559832 100644 --- a/2019/12/29/review-2019/index.html +++ b/2019/12/29/review-2019/index.html @@ -17,4 +17,4 @@  6 minutes 

    “회고"는 비단 개발 블로그 뿐만 아니라 어떠한 과정의 마지막에는 꼭 해야할 중요한 시간인 것 같다. 앞만보고 달려가자! 닥공! 라는 말이 있지만 사실 이 말이 성립되기 위해선 지난 과거에 대한 정리와 반성 그리고 무엇을 하려고 했는데 어떤 이유로 못했는지와 그 동안의 나 자신을 바라볼 수 있는 이 “회고” 시간이 필요하다. 벌써 2019년도 마무리가 되어간다. 작년보다 더 정신없이 달려온 올해. 내년엔 올해보다 더 멋지고 힘차게 출발하기 위해 필자의 한 해를 돌아보고자 한다.

    그렇다면 회고는 어떻게 하는게 가장 좋을까? 무작정 타임라인 기반으로 1월엔 뭐했고 2월엔 뭐했고… 이 방법이 틀린건 아니지만 타임라인 기반으로 정리를 한 뒤 키워드별로 다시 정리하는 방식이 가장 맞을것 같다는 생각이다. 무엇을 했고, 뭐가 좋았고 어떤건 아쉬웠고. 그래서 내년엔 어떻게 할 것이고. 각자의 회고 방식에는 차이가 있겠지만 회고를 하는 이유, 그리고 회고라는 목표 중에 공통점은 “뒤를 돌아보고, 앞을 보기위한 힘을 찾는것” 이 아닐까 싶다.

    /images/review-2019/back_no_hae.png
    내년 회고를 할때는 흑백이 아닌 컬러 사진을 넣을 수 있는 분위기가 될까?…
    출처 : http://www.nanum.com/site/poet_walk/820914

    회사는 성장의 공간이 아닌것을 깨닳는 순간.

    (이야기에 앞서 필자는 현재 서비스 개발자임을 밝힌다.)

    내년이 되면 컴퓨터쟁이가 된지 벌써 8년차. 매년 성장의 그래프를 그려보면 작년까지만 해도 우상향이었다. (그래프의 기울기는 매년 달랐지만) 허나 올해는 기울기가 0 이거나 오히려 마이너스가 된 것 같은 느낌이다. 왜일까.

    /images/review-2019/height.jpg
    키는 왜 더이상 성장을 안할까? (쓰읍…)
    출처 : http://www.guro1318.or.kr/bbs/board.php?bo_table=data&wr_id=1723

    회사를 다니다 보면 아주 일반적으로 “시키는 일"을 하곤 한다. 주어진 업무를 정해진 기간 안에 스펙에 맞춰 개발하는. 아주 극단적으로 나쁘게 말하면 “도구"로 전락되어버릴 수도 있는 시간들. (개발자가 도구가 된다는 말은 너무나도 듣기 싫은 말중에 하나.) 흔히 말하는 CRUD(Create, Read, Update, Delete) 성의 개발 업무를 하곤 한다. 하지만 꼭 성과에 align(더 좋은 한국말을 찾고 싶은데…) 하는 일 말고도 허드렛일(일종의 서스테이닝?)을 할 경우도 있는데 그게 만약 재미없는 일이라면 어떨까?

    필자는 그렇게 “시키는 일만 하며 재미없는 회사생활” 보다 “재미있게 개발하며 성장을 할 수 있는 회사생활” 이라는 기준을 가지고 한 해를 지내온 것 같다. 즉, “시키는 일"이 아닌 “시키지도 않은 일"을 찾아서 해가며. 예컨대, 처음에 잡았던 서비스 구조가 사용자가 많아지고 요구사항이 많아짐에 따라 복잡하고 성능을 저해하는 상황을 발견하고 미리 구조개선을 통해 성능과 효율이라는 두마리의 토끼를 잡는다거나. 지난 외부 세미나에서 듣고 인사이트를 얻어 팀내에도 적용해본 배치 무중단 배포 기능. 팀 내 코드리뷰의 활성화와 수동으로 해야할 업무들을 메신저 봇을 활용하여 자동화 한다거나. 서비스 지표 대시보드를 만들어 한눈에 서비스 상황을 볼 수 있게 별도의 개발 페이지를 만들어 보는 등. 다양한 업무 내/외 적으로 일을 찾아가며 + 필자의 개인 시간을 할애해 가면서 정말 재미있게 보내온 것 같다.

    하지만 뒤를 돌아보면 “성장 했는가?” 라는 질문이 있다면 “그렇게 하고있는것 같아서 신나게 해왔는데 돌아보니 막상 뭘했나 하는 느낌이 든다” 라고 말할 수 있을 정도로 여러가지를 많이 하며 다양한 “경험"을 얻긴 했지만 실질적인 “성장"은 아쉽지만 부족한 한 해 였던것 같다.

    회사가 원하는, 연차에 맞는 업무 역량과 개발 팀에서의 위치를 충족시키기엔 회사 안에서 성장하기엔 한계가 있다고 판단이 들었다. (이 생각이 왜 이제서야 들었을까.) 오픈소스나 새로운 언어를 회사 밖에서 혼자서 공부 하던지 여러명이서 스터디를 통해 습득을 해야하고 토이프로젝트 또한 회사와 별도로 진행하며 개발 스킬을 늘려야 할것 같다. 그 이유는 회사에서의 성장이 결국 나의 성과로 잡힐 수는 없는데 괜시리 기대를 하게 되기도 하고 특히 서비스를 운영하는 팀에서는 요즘 핫 하다는 개발 방법론이나 솔루션을 도입하기에는 다소 무리가 있기 때문이다. (물론 회사일도 하면서 성장을 할 수 있는 상황이라면 금상첨화. 이를 찾는건 정말 어려운 일 같다.)

    내년에는 좀더 회사 밖에서 새로운 지식도 쌓으려 노력하고, 외부 활동도 찾아가며 주니어도 시니어도 아닌 “매너리즘에 빠질 애매한 연차"를 슬기롭게 극복하려 노력해봐야 겠다.

    개발 커리어 쌓기. 꾸준함이 정답!

    작년보단 줄어들었지만 다양한 외부활동을 해왔다. 지금의 연차에 어울리진 않지만 한번도 제대로된 해커톤을 해보지 않아 GDG에서 주최했던 해커톤에 참여를 하며 마지막에 결과물에 대해 발표도 해보고, 필자의 토이프로젝트인 기술블로그 구독서비스 에 대한 일련의 개발 히스토리에 대해서 발표를 할 수 있었던 좋은 기회가 있었다. 또한 팀 분들께 글쓰기에 대한 인사이트를 전달하고자 지난 포스팅 에 대한 내용을 간추려 발표를 하기도 하였다. (TMI : Deview 에서도 발표를 하려 지원을 했지만 아쉽게도 사내 탈락을 하고 ㅠ…) 발표는 글쓰기를 넘어 사람들 앞에서 라이브로 이야기하는 엄청난 활동인 것 같다. 내년에도 기회가 된다면 이번엔 좀 준비를 잘해서 여유로운 발표를 해보고 싶다. (그렇게 하기 위해서는 먼저 나 자신을 디벨롭 해야겠지?)

    /images/review-2019/gdg.jpeg
    앞이 안보이던 발표. 아 물론 내 눈앞.
    출처 : https://lalwr.blogspot.com/2019/07/toy-story-side-project-by-gdg-campus.html

    블로그 포스팅은 작년 수준으로 작성한 것 같다. 더 많이 쓰려고 했는데… 이점은 이 포스팅을 통해 반성을 해본다. “글또” 라는 모임에도 참여를 하며 적어도 2주에 글 하나는 써야지 했지만 올해 하반기에 개인적인 큰 이벤트도 있었고, 단순히 글 개수만을 채우기 위한 포스팅은 하기 싫었기 때문이다. (이거봐, 또 변명일색. 정신차려 태태태!) 하루에 한시간, 아니 30분만 투자하면 조금이라도 작성할 수 있는데 왜 이렇게 힘들어 했는지. 조금 더 신경써서 고퀄리티 기술블로그 포스팅을 해보려고 노력해야겠다. (왜 개발자가 바쁜데 글까지 써야하는 이유는 지난 포스팅을 참고)

    운이 좋아 서평도 쓰게 되었다. 어떻게 필자를 알고 연락을 주셨는지 출판사에서 페이스북 메신저로 연락이 와서 쓰게 되었다. 전문적인 기술서적은 아니었지만 프로그래머로써의 꼭 한번즈음은 읽어볼만한 책에 대한 서평이었다. 처음으로 서평을 써보게 되어서 상당히 재밌었고, 서점이나 인터넷 책 구매 사이트에 필자 이름이 있다는 것에 감동의 연속이었다. 지금도 가끔씩 책 쓸 생각이 있냐는 연락이 종종 오지만, 내가 그럴 능력이 될까 싶다가도. 한번즈음 도전해보고 싶은. 글쓰기는 필자 삶을 바꿔놨다고 해도 과언이 아닐 정도로 정말 좋은 영역인것 같다.

    필자의 토이프로젝트인 기술블로그 구독서비스 에 구독하는 사람이 어느덧 2,300여명을 넘어섰다. 어떻게 알고 다들 구독하시는지. 덕분에 메일 발송속도는 처음과는 현저하게 느려졌고 (사용자가 많아짐에 따라 구조개선을 해야하는건 당연한 이야기), 이제는 무언가 다른 기능을 추가해야하지 않을까 싶은 생각이 든다. 현재는 장님 코끼리 만지듯 python + flask 로 개발되었는데 내년엔 java 기반으로 바꾸면서 성능개선 + 기타 다른 기능을 만들어 볼까 한다. 더불어 한달에 약 3만원가량 AWS 서버비용이 나가고 있는데 후원을 받는것도 한계가 있고. 비지니스 모델을 찾거나, 사용자가 만명을 넘어서도 비용없이 돌아가는 구조를 생각해 봐야겠다. (1년이면 약 3~40만원, 무시 못할 비용이다…후..후원좀…)

    /images/review-2019/ddb.jpg
    구독자 수 그래프, 뭔가 방법을 찾아야 한다.

    핑계와 타협이 많았던 올해. 내년엔 어떤 도전을 할까?

    유독 올해는 작년, 제작년보다 필자 자신과 타협을 많이 했던 것 같다. 너무 바빠서라는 부끄러운 핑계부터 시작하여, 밥먹듯 야근하며 일 열심히 했으니까 라는 말도 안되는 타협까지. 우선 건강부터 챙겨야 겠다. 컴퓨터쟁이의 고질병인 거북목과 라운드숄더. 몸짱까진 아니더라도 늙어서도 코딩을 하려면 지금부터 몸관리를 해야하지 않을까 싶다.

    앞서 이야기 한 것처럼 회사 밖에서의 나를 찾아보고자 한다. 그에 토이프로젝트 2.0 도 출시해보고, 새로운 언어, 새로운 오픈소스도 공부해보며 기술블로그도 열심히 포스팅해야지.

    작년에는 “Coder 가 아닌 Programmer 가 되고 싶다.” 며 그럴싸한 계획이 있었는데 돌이켜 보면 그렇게 지낸것 같다. 단순히 도구가 되는 개발자가 아니라 단순 반복적인 일이나 허드렛일을 하면서도 그속에서 성장 포인트를 찾으려 애를 쓰는. 이 부분은 내년에도 유지하는 것으로.

    목표를 뚜렷하게 잡는 일도 중요하지만, 적어도 내년엔 올해보다는 더 성장한 내가 되었으면 하고, 뒤 돌아봤을 때 부끄러움이 없는 내가 되었으면 좋겠다는 말로 올해 회고를 마무리 하고자 한다.

    고생했다 태태태. 내년에도 잘 달려주길.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/01/19/spring-boot-maven-multi-module/index.html b/2020/01/19/spring-boot-maven-multi-module/index.html index 0f48fb84..d626acd0 100644 --- a/2020/01/19/spring-boot-maven-multi-module/index.html +++ b/2020/01/19/spring-boot-maven-multi-module/index.html @@ -149,4 +149,4 @@ [INFO] ------------------------------------------------------------------------

    본문 최 하단에 해당 소스가 업로드 된 Github에서 확인이 가능하겠지만, (“도서관” 이라는 목적에는 안맞지만…) 정수를 더하고 빼는 유틸을 Core에 만들고 이를 Api에 있는 컨트롤러에서 사용하도록 만들어 보았다. (어디까지나 모듈에서 멀티모듈로 되어있는 다른 모듈에 접근이 가능한지를 보기 위함이라… 예시가 우아하진 않다.)

    # 마치며

    언제부터인가 단순 로직개발보다 구조관점에서 바라보는 연습을 하곤한다. 아무리 알고리즘이 잘 작성되고 우아한 코드일지라도 구조가 개발 생산성 측면과 유지보수 측면에서 분리하면 아무 소용 없는것 같다. 위에서도 이야기 했듯이 멀티모듈이 무조건적인 정답은 아니지만 시스템을 구성하는데 있어 다양한 선택지를 알고있는 여유를 갖는것도 좋아보인다.

    Github 예제 소스


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/02/09/jupyter-install/index.html b/2020/02/09/jupyter-install/index.html index 23cb2a60..f13061d0 100644 --- a/2020/02/09/jupyter-install/index.html +++ b/2020/02/09/jupyter-install/index.html @@ -117,4 +117,4 @@

    주피터 활용팁

    IDE처럼 엄청난 기능을 제공하진 않지만 외부에서 누구나 간단히 접속하여 파이썬 코딩을 할 수 있는 상태가 되었다. 폴더 기능도 제공하니 각자의 환경(폴더)을 만들어서 코드를 작성할 수 있다. 여기서는 “notebook” 이라는 개념으로 불리우는데 파이썬 파일을 만들고 언제나 그랬듯 hello world 를 출력한뒤 Shift+Enter 을 누르면 바로 결과물이 나오는 것을 확인할 수 있다.

    /images/jupyter-install/download_notebook.jpg
    위 메뉴에서 다양한 포맷으로 다운을 받을 수 있다.

    자동완성은 “Tab”, 어느정도 시간이 지나면 자동으로 저장이 되고, File → Download as → Notebook(.ipynb) 로 추출을 한뒤 gist 에도 업로드가 가능하다. 아주 이쁘게. (gist 에 올려진 주피터 노트북 결과물 : 링크)

    더 자세한 내용은 주피터 도큐먼트를 참고하자. 링크

    마치며

    이로써 팀원들이 파이썬을 가지고 놀아볼 수 있는(?) 운동장이 만들어 졌다. 우리는 개발자니까. 환경이 없으면 직접 만들면 되니까. 개발자로 살아가면서 이런 부분이 참 매력적인 것 같다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/03/08/spring-rest-docs-in-spring-boot/index.html b/2020/03/08/spring-rest-docs-in-spring-boot/index.html index 04420bc9..98a0ba01 100644 --- a/2020/03/08/spring-rest-docs-in-spring-boot/index.html +++ b/2020/03/08/spring-rest-docs-in-spring-boot/index.html @@ -204,4 +204,4 @@ }

    (1) spring profile 이 release 일 경우 일부러 FORBIDDEN 처리를 해준다.

    이렇게 되면 개발환경에서만 접근이 가능하고 운영환경에서는 접근이 불가능한, 테스트 케이스를 성공한 동기화 + 자동화 된 API 문서를 만들 수 있게 되었다.

    마치며

    언제나 그렇듯, 초기 설정은 실제 비즈니스 로직 개발보다 훨씬 공수가 더 드는 건 어쩔 수없다. 하지만 약간의 노력으로 안정되고 자동화된 개발 프로세스를 구축한다면 그 작은 날갯짓이 나중엔 큰 바람을 일으킬 수 있지 않을까 하는 기대를 해본다.

    참, 위에서 만든 코드는 Github 에 있으니 참고 바란다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/03/22/better-rest-template-1-retryable/index.html b/2020/03/22/better-rest-template-1-retryable/index.html index 146e2972..3019237e 100644 --- a/2020/03/22/better-rest-template-1-retryable/index.html +++ b/2020/03/22/better-rest-template-1-retryable/index.html @@ -108,4 +108,4 @@ 이러한 “재시도” 말고도 요청하고자 하는 곳의 서버의 상태가 안좋을 때 서버에러가 아닌 다른 명시적인 에러를 반환할 수 있는 방법이 다양할 것 같다. 모든것엔 정답이 없는 것 처럼. 제목에서 알 수 있듯이 다음 “2부” 에서는 “Retry"가 아닌 “Circuit Breaker"를 사용하여 “재시도"의 방법보다 조금 다른 측면에서 조금 더 괜찮은 방법으로 RestTemplate 를 사용해 보고자 한다.

    위에서 사용한 코드는 필자의 Github Repo에서 확인이 가능하다.

    참고 url


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/03/26/7-years-of-development-1st-day-of-manager/index.html b/2020/03/26/7-years-of-development-1st-day-of-manager/index.html index f0f24ebb..bd3bcc26 100644 --- a/2020/03/26/7-years-of-development-1st-day-of-manager/index.html +++ b/2020/03/26/7-years-of-development-1st-day-of-manager/index.html @@ -18,4 +18,4 @@

    개발자로서의 커리어는 정말 다양하지만 필자가 보고 들은 경험을 아주 일반화 시켜 정리해 보자면 다음과 같다.

    처음엔 전공/비전공을 불문하고 신입으로 개발을 시작하여 다양한 개발 경험을 하게 된다. 사수에게 혼나기도 해보고 또는 혼내줄 사수가 없어 혼자 끙끙 밤도 새보고, 다크서클과 거북목을 겸비한 이른바 “삽질"을 하며 고통의 시절을 보내고 나면 어느덧 승진(진급)을 하며 일정 규모의 “팀장(혹은 관리자)“이 된다. 그게 자의든 타의든. 개발자는 다소 “기술"이라는 특수성을 가지고 있지만 어느 직군이든 간에 이러한 커리어 패스의 흐름은 매우 비슷하게 흘러가는 것 같다. 적어도 필자가 보고 들은 것만 보면 말이다. (예외 케이스는 항상 있지만…)

    하루는 팀장님과의 면담 중에 “이제는 마냥 눈앞에 있는 개발만 할 것이 아니다. 기술을 좀 더 깊게 들여다보는 자리와 사람을 관리하며 주어진 과제를 진행하는 자리, 둘 중 선택해야 하는 시기가 온 것 같다. 더 높고 더 멀리, 그리고 더 넓게 볼 줄 알아야 한다.“라는 말씀을 듣게 된다. 어느덧 “그 시점"이 다가온 것이다. 개인적으로 필자는 팀장님이 말씀하신 두 가지 중 전자에 좀 더 가깝게 다가가고 싶다. 그만큼 오래오래 “실무 개발"을 하고 싶고, 또 그만큼 개발이 재밌기 때문이다. 아직도 눈앞의 문제를 해결하기 위해 개발하며 시간 가는 줄 모를 만큼 밤을 새우는 게 재미있는 걸 보면…

    /images/7-years-of-development-1st-day-of-manager/chiken.jpg
    요리하는 걸 좋아하지만 이상하게 치킨집은 하고 싶지 않다.
    출처 : https://catapult.tistory.com/entry/%EC%B9%98%ED%82%A8%EC%A7%91%EC%9D%B4%EB%82%98-%EC%B0%A8%EB%A0%A4%EC%95%BC%EC%A7%80

    어느 날 SNS 피드에 개발 관련된 소식들을 받아보다가 개발 7년차. 매니저 1일차라는 제목의 책을 보게 된다. 뭐야, 이거 내 이야기 아니야? 하며 귀신에 홀린 듯 사서 읽어보려는 찰나, 마침 한빛미디어 에서 주최하는 나는 리뷰어다 라는 이벤트를 발견하게 된다. 결국 리뷰어에 당첨이 되고 운 좋게 해당 책을 받아볼 수 있었다. (이 책을 읽게 해준 한빛미디어 측에게 이 글로나마 감사의 인사를 전하고 싶다.)

    /images/7-years-of-development-1st-day-of-manager/book.jpg
    필자의 SNS를 장식했던 ‘개발 7년차, 매니저 1일차’

    이번 포스팅에서는 우선 책에 대한 리뷰를 간단히 적어보고 거기에 필자의 생각을 조금 더 얹어보고 싶다. 필자를 두고 만들어진 책 같아서 아직도 책 표지만 봐도 신기하고 설렌다. 일단 책 표지나 제목이 맘에 든 건 감출 수 없는 사실이다.

    신입 혹은 주니어 개발자가 읽어봐도 좋을 책.

    제목만 보면 이제 갓 팀장 혹은 매니저를 하게 되는 사람에게만 해당되는 책으로 보인다. 표지 상단에 “개발만 해왔던 내가, 어느 날 갑자기 ‘팀’을 맡았다!” 적혀있기도 했으니까. 하지만 책을 읽다 보면 꼭 그렇지마는 않다. 멘토링을 할 때엔 멘토와 멘티 각자의 위치에서 어떤 자세로 서로를 맞이해야 하는 방법에 대해서도 알려주기도 하고 무작정 눈앞에 있는 기능 개발만을 하며 안갯속을 걷는 주니어 개발자가 미리 미래를 경험해보는 좋은 사례를 들어 알려주고 있기 때문이다.

    꼭 누군가 혹은 무언가를 “관리"하는 입장이 아닌 “팀"이라는 공동체 사회, 특히 개발 팀에서 팀원들과 협력하는 방법론을 살펴보고 있고, 경력이 낮으면 안 보이는 부분들까지 마치 멀리 있는 것을 대신 망원경으로 보여주는 느낌이 들었다. 앞부분에는 “이 책을 읽는 방법"이라며 상황별로 읽는 챕터를 가이드 해주고 있지만 사실 어느 하나 중요하지 않을 내용이 없어서 처음부터 무언가에 홀린 듯 읽을 수밖에 없었고 선배님이 앞서 지나간 길을 올바르게 지나갈 수 있도록 가이드 해주는 느낌으로 중간중간 사례가 있어서 현업에 있어서 그런지 좀 더 쉽게 읽힐 수 있었다.

    다 읽고서야 알아차린 번역서(?)라는 사실.

    어떠한 XX 기술 서적에서는 Method를 ‘방법’, Overriding 을 ‘과적’이라고 번역한 책들이 있는가 반면, 이 책은 읽는 내내 국내 어떤 분이 쓰신 거라 생각하고 읽어내려 갔지만 다 읽고 보니 외국에 어느 CTO가 쓴 책을 옮겨서 다시 써진 책이었다. 그만큼 전혀 특유의 번역 느낌(?)은 없었고 오히려 한국 문화에 맞춰 다시 써진 건 아닐까 싶을 정도로 너무 술술 잘 읽혔다.

    더불어 책 중간중간에 이 바닥(?)에서 유명하신 분들이 기고해 주신 소중한 경험담과 생각들을 덤으로 읽어볼 수 있어서 너무 좋았고 챕터가 끝날 때 즈음이면 생각해 볼 만한 질문을 던지면서 무작정 읽지 말고 깊게 생각하고 읽으라고 하는 것만 같은 저자의 목소리를 들을 수가 있어 좋았다.

    기타.

    특이한 건, 책 맨 뒤에 보면 키워드를 다시 찾아서 읽어볼 수 있도록 “찾아보기” 코너가 있어서 언제든지 위기 상황(?)에서 가이드처럼 활용해 볼 만한 부분인 것 같아 좋았고, 시간이 지나고 정말 “관리자"가 된다면 다시 한번 처음부터 정독을 하며 보다 나은 “관리자"가 되어보고 싶은 맘도 들었다.

    /images/7-years-of-development-1st-day-of-manager/book_point.jpg
    정곡을 찌르는 문구들, 사실 이것 말고도 무궁무진하다.

    기억에 남는 매니저.

    짧은 개발자 경력 중에 필자가 만나보았던 “매니저” 중 그래도 괜찮았다고 생각나는 분은 세분 정도다.

    • C : 마이크로 매니징의 끝판왕. 신입시절인 필자가 Java 코딩을 할 때 StringBuilder 을 쓰는지 StringBuffer을 쓰는지까지 확인하거나 SpringFramework의 일부 모듈 코드를 A4로 출력해서 보는 것을 추천하신 분. 어떻게 보면 정말 토나오게(?) 힘들었지만 지나고 보면 그러한 관심도 요즘은 가뭄에 콩 나듯 있을까 하기에 나름 뜨거운 정이 있으셨던 분으로 기억한다.
    • J : 필자에게 관심이 있는 듯 없는듯하면서 가끔 지나가다 뒤통수를 치는 듯한 몸 쪽 깊숙한 멘트로 성장하는데 엄청난 원동력이 되어주신 분. 회사 업무 그 이상을 주문하고 필자가 스스로 개발/개선 포인트를 찾아서 하는 방법을 알려주신 분.
    • S : 아, 이 분은 정말 천재구나 할 정도로 높이 그리고 멀리 보는데 일가견이 있으신 분. 필자가 개발하는 데 어려움을 겪고 있으면 키워드 몇 개를 던져주면서 감을 주지 않고 감을 따는 방법을 알려주신 분.

    물론 다른 분들도 필자에게 영향력이 있던 분들이지만, 필자가 생각하는 바라직한 “매니저"의 역할은 팀이 목표에 방해요소를 최대한 줄이고 팀원들의 성장을 도와주며 비로소 나아가고자 하는 방향을 명확하고 신뢰 있는 말과 행동이라 생각한다.

    /images/7-years-of-development-1st-day-of-manager/boss_leader.jpg
    워낙에 유명한 짤이라 다른 미사여구가 필요 없지 않을까 싶다.
    출처 : https://twitter.com/hazaraouad/status/451603771869900800

    마치며

    “매니저"라는 안 좋은 인식을 벗어나게 해줄 내용들이 정말 많이 있고 필자 또한 “오랫동안 개발만 하고 싶어"라는 생각을 조금 달리해볼 수 있는 안경을 쓰게 해준 것 같아 좋았던 책이다. 더불어, 멘토링 하던 시절이 생각나게 하는 책이다. 멘토로써 준비를 하고 필자 자신에게, 그리고 멘티에게 보다 더 좋은 촉진제 역할이 되었더라면 하는 아쉬움이 남는 멘토링. 다음에 기회가 되면 조금 더 “준비"를 해서 이 책에 나와있는 “좋은 매니저"의 가이드를 기반으로 비록 작은 날갯짓이지만 멀리 보면 팀에 도움이 되는 그런 사람이 되고 싶게 만드는 책으로 오래 기억에 남을 것 같다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/03/29/better-rest-template-2-netflix-hystrix/index.html b/2020/03/29/better-rest-template-2-netflix-hystrix/index.html index 79c9ae70..e56f9c70 100644 --- a/2020/03/29/better-rest-template-2-netflix-hystrix/index.html +++ b/2020/03/29/better-rest-template-2-netflix-hystrix/index.html @@ -208,4 +208,4 @@

    SpringBoot에서 제공하는 actuator 를 활용하여 정보를 받도록 해주고, application.properties 설정에서도 Hystrix 관련된 정보를 받아볼 수 있게 아래처럼 추가해주자.

    management.endpoints.web.exposure.include=hystrix.stream
     

    그럼 끝이다. (응? 이게 끝이라고?) 그렇다. 필자도 아주 놀랬는데 생각해보니 모니터링을 위해 별도의 코드가 들어가는 자체가 이상한 부분같다. 아주 심플하게 모듈과 설정만 추가해주면 모니터링이 가능하다. 그럼 진짜 모니터링을 해보자. 일부러 여러번 호출해서 서킷브레이커를 발동시키면 모니터링 페이지에서는 어떤식으로 나오는지 확인해보자. 우선 이렇게 설정한뒤 실행을 하면 /hystrix로 접근이 가능하고 귀엽지만 뭔가 놀랜 표정의 곰돌이가 반기는 것을 확인할 수 있다. 그다음 url 에 http://localhost:8080/actuator/hystrix.stream 를 입력후 “Monitor Stream"을 클릭하면 아래와 같은 화면을 볼 수 있다.

    /images/better-rest-template-2-netflix-hystrix/hystrix.jpg
    곰돌이가 조금 화난것 같다. (코딩좀 잘하라고?)

    뭔가 로딩중인것 같은데 올바른 요청 /index?key=taetaetae 을 해보면 그래프가 바뀌고 잘못된 요청 /index?key=taekwan 을 여러번 해보다가 잠시 멈추고 를 반복해보면 서킷브레이커가 open 되었다가 다시 close 된것을 확인할 수 있다.

    /images/better-rest-template-2-netflix-hystrix/monitor_execute.gif
    에러가 발생하면 open, 설정한 시간이 지나고 정상 응답이 되면 close

    마치며

    물론 위에서 설정한 내용은 서비스에 적용하기도 부끄러울만큼 아주 극단적이고 다양한 상황이 전혀 고려되지 않은 설정값이다. 현 시스템에 맞춰 설정값을 커스터마이징 하며 최적의 설정값을 찾아야 할 것이다. 또한 무조건 “설정한 값에 의해서 서킷브레이커가 잘 동작 하겠지” 라고 믿는것(?)보다 모니터링을 추가로 설정해서 실제로 언제 서킷브레이커가 작동을 하는지 확인을 해봐야 할 것 같다. 나아가서 이 모니터링 페이지가 있다고 해서 주식 차트 보는것 마냥 계속 보고 있을수는 없는일. 모니터링 페이지를 봐야할 시점이 오게 된다면 자동으로 알림을 받도록 해서 필요할 때만 모니터링을 할 수 있도록 해야 할 것 같다. (이상하게 주식으로 시작해서 주식으로 끝나는 것 같은 느낌은 뭐지…)

    물론 이번에도 위에서 사용한 코드는 필자의 Github Repo에서 확인이 가능하다.

    참고 url


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/04/06/spring-boot-filter/index.html b/2020/04/06/spring-boot-filter/index.html index 720aca9f..4caca625 100644 --- a/2020/04/06/spring-boot-filter/index.html +++ b/2020/04/06/spring-boot-filter/index.html @@ -147,4 +147,4 @@

    정답은 스프링 부트를 사용하다 보면 가장 처음으로 만나는 “@ComponentScan"와 “@Component"에 있다. “@SpringBootApplication"는 여러 어노테이션의 묶음이고 그 안에는 “@ComponentScan"가 있어서 빈들을 자동으로 등록해주는 역할을 하게 되는데 필터에 “@Component"가 설정되어 있어 자동으로 등록이 되었고, 두번째 방법인 “@WebFilter + @ServletComponentScan” 조합으로 한번 더 등록되어버린 것이다. 즉, 동일한 필터가 두번 등록된 상황.

    “/test” 에서 한번 로깅된건 “@Component” 에 의해 등록된 필터로 인해 urlPattern 이 적용되지 않았으니 한번 로깅이 되고, urlPattern 이 적용된 필터에서는 urlPattern에 맞지 않으니 로깅이 안되는건 당연. 그 다음 “/filtered/test” 은 “@Component” 에 의해 등록된 필터로 한번 로깅, 그다음 “@WebFilter"로 등록된 필터에서 urlPattern에 맞는 url 이다보니 로깅이 되서 총 두번 로깅이 되게 된다.

    즉, 모든 url에 필터를 적용 할 것이라면 “@ComponentScan + @Component” 조합으로 해도 될 것 같고, 명시적으로 특정 urlPattern 에만 필터를 적용한다거나 필터의 다양한 설정 (우선순위, 필터이름 등) 을 하게 되는 경우엔 위에서 알려준 “FilterRegistrationBean” 이나 “@WebFilter + @ServletComponentScan"을 사용해서 상황에 맞도록 설정하는게 중요할 것 같다.

    마치며

    좀 알고 쓰자. 실수는 두번하면 실력이다. 다음번엔 절대 실수 안해야지.

    왜 저렇게 무턱대고 설정했는지 부끄럽기 짝이 없지만 함께 디버깅을 해주며 문제를 해결하는데 도움을 준 black9p 님 덕분에 이렇게 필터 적용방법에 대해 정리를 할 수 있어서 한편으론 다행이라 생각이 든다.

    이번에도 위에서 사용한 코드는 필자의 Github Repo 에서 확인이 가능하다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/06/21/a-good-developer-in-terms-of-culture/index.html b/2020/06/21/a-good-developer-in-terms-of-culture/index.html index 99253a1f..739809ad 100644 --- a/2020/06/21/a-good-developer-in-terms-of-culture/index.html +++ b/2020/06/21/a-good-developer-in-terms-of-culture/index.html @@ -21,4 +21,4 @@ Kakao | 코드 리뷰, 어디까지 해봤니? Jandi | 코드리뷰, 이렇게 하고 있습니다.

    공유

     무언가를 공유한다는 건 정말 나 잘했어요~ 내가 최고예요~ 하는 ‘자랑’이 목적일까? 필자가 생각하는 공유의 목적은, 자신이 했던 부분들을 ‘다시 정리’함으로써 내 것으로 만드는 과정이 되고 이를 여러 사람들에게 공유함으로써 생각을 나누며 함께 고민한다는 부분이 가장 큰 것 같다. 거기에서 나오는 시시콜콜한 의견들은 공유했던 내용을 더욱 올바른 길로 성장시켜줄 수 있고, 공유라는 작은 날갯짓이 큰 바람을 일으킬 수도 있기에. 다시 말하지만 공유는 자기 자신을 돌아보기에 훌륭한 도구이다.

     어떠한 문제로 운영하고 있는 서비스가 장애를 맞았다고 가정해보자. 관련 담당자는 부랴부랴 장애를 수습하기 바쁠 테고 시간이 지나 다시 원상복구를 하기 마련이다. 장애를 복구해서 끝났다고 생각하면? 안타깝지만 그걸로 끝인 거다. 무엇 때문에 장애가 났는지 장애 원인을 파악하고, 동일하거나 비슷한 문제에 대해 방지하기 위한 수단은 무엇이며, 이러한 장애가 발생했을 때 어떻게 처리했는지에 대해 공유가 이루어진다면 함께 일하는 조직원들은 적어도 그러한 문제에 대해 경각심을 느끼고 더 조심히 꼼꼼하게 개발할 수 있을 것이다. (공유를 받고 스팸처리한다면… 할많하않…)

     신입이던 10년 차 개발자이던 개발을 하다 새로운 기술이나 어려웠던 부분을 해결했던 경험을 공유한다고 가정해보자. 공유를 하는 사람은 소가 뒷걸음치다 얼떨결에 쥐를 잡는 것처럼 되는 게 아니라 제대로 정리를 할 수 있는 기회가 될 것이고, 공유를 받는 팀원들은 가만히 있어도 공유 내용을 간접경험해 볼 수 있는 정말 좋은 기회가 될 수 있다.

     무엇을 공유해야 하지 모를 땐, 아주 사소하게라도 오늘 알게 되었던 새로운 지식을 짤막하게라도 적어보는 습관을 길렀으면 한다. 나아가 팀에서 운영하는 서비스의 기술 부채를 파악하고 개선하여 공유를 하거나, 외부에서 들은 좋은 내용들을 팀 내에 도입한다거나. 다들 SODD 를 한 번쯤은 해봤을 테니 하루에 하나 이상은 새로운 사실을 (혹은 알고 있었는데 제대로 숙지하고 있지 못하는 부분) 알게 될 테니… 무엇을 공유할지 모르는 게 아니라 공유한다는 습관이 부족한 건 아닐까.

    개발 관점에서의 시야

     회사는 언제나 바쁘다. 사업의 성공을 위해 하나의 팀에 속한 설계, 기획, 디자인, 개발, QA 등 다양한 직군들은 공동의 목표를 안고 열심히 달린다. 모든 직군들은 최종 결과물을 만들기 위해 사업에 필요한 여러 가지 복잡한 스펙들을 구현하기 바쁘고, 그러다 목표로 했던 일정에 맞추어 서비스를 릴리스 하는데 성공한다. 그렇게 출시를 하고 나면 이제 두발 뻗고 기다리기만 하면 될까? 아니다. 2차 3차를 넘어 또 다른 스펙들이 무섭게도 들어온다. (서비스 오픈 축하 회식조차 못하고…ㅠㅠ)

     가장 이상적인 모습은 모든 직군들 이 일정과 스펙 협의가 끝나고 안정적으로 충분한 테스트를 거친 다음 서비스 릴리스가 돼야 하지만. 아쉽게도 서비스 릴리스 일정은 이상하게도 거꾸로 들어온다. 즉, ‘X 월 Y 일에 출시하겠습니다.‘라고… 그러한 악순환은 결국 최 말단(?)인 개발자들에겐 숨 막히는 야근으로 변질되고 어찌어찌해서 개발은 하게 되지만, 하나의 스펙을 구현하기에 급급한 코드. 서비스의 스케일이 커졌을 때 확장하기 어려운 구조. 넘쳐나는 중복 코드와. 예상하지 못한 문제들까지. 이러한 ‘기술 부채’는 점점 커지고 무서워서 코드를 건드리지 못하다 결국 하나둘 팀을 떠나게 되는 안타까운 모습이 발생한다. 이러한 부분들은 도대체 언제 해결할 수 있을까? 그리고 누구의 탓일까? 한편으론 ‘한두 달만 서비스 유지만 하고 기술 부채 점검 좀 하겠습니다.‘라는 도발적인 목표를 제시하고 싶으나 과연 그런다고 해결이 될까?

     아무리 바빠도, 개발자는 개발 관점에서의 시야를 놓쳐서는 안 된다. 여기서 말하는 개발 관점에서의 시야는 모니터링, 중복 코드, 알림 (에러, 시스템, 기타 모니터링 지표 등), 구조/설계, CI/CD, 자동화 등 기능 개발 이외의 다양한 부분들. 이러한 부분을 리더, 혹은 일부 팀원만 관심을 갖는다면 개선이 될 거라는 기대는 너무 이기적인 생각이다.(누군가 하겠지 or 개발할 시간도 없는데! 이런 문화가 팽배한 조직은 멀리 가지 못할 것 같다.) 모두가 함께 코드와 개발적인 요소들에 대해 관심을 갖고 개선의 의지가 있어야 그 개발팀은 건강하게 성장하고 오래 있고 싶거나 외부에서 오고 싶은 팀이 될 수밖에 없을 것 같다. (물론, 자기가 한 게 아니라 신경을 끄겠다는 사람들이 있다면… 정말 묻고 싶다. 왜 이 ‘팀’에 있는 거냐고.)

    어떻게 하면 좋을까?

     문화적인 측면에서 위에서 이야기한 것 말고도 정말 다양한 부분들이 많다. 애자 일부터 시작해서 DevOps, SRE, 팀 컨벤션 / 개발 규칙 등 개발 문화는 엄청난 시간 복잡도를 요하는 알고리즘과는 또 다른 측면에서 상당히 중요하다고 볼 수 있을 것 같다. 그렇다면 어떻게 하면 개발 문화를 좋은 방향으로 바꿀 수 있을까?

     사실 위 임백준 님의 페이스북 글을 보고 뒤통수를 맞은 느낌이 들어 이 포스팅을 쓰기 시작하게 되었다. 한때 ‘여기는 도저히 있을 곳이 아니야’, ‘이 조직의 문화에 점점 지쳐간다’라며 이직을 생각해 보았던 필자 자신이 부끄러울 정도로. 물론 자신이 팀의 문화를 바꾸기 위한 위치(?)가 아니라면 (혹은 영향력이 없다면) 문화를 바꾸는데 힘들 수 있겠다고 말할 수 있겠지만 꼭 팀의 리더나 연차가 어느 정도 있어야지만 팀의 문화를 바꿀 수 있을까? 아니다. 위에서 이야기했던 부분들을 조금씩 ‘꾸준하게’ 해 나가면서 영향력을 펼친다면 언젠가는 그 팀의 문화가 바뀔 거라 자부한다. 물론 그 팀에 오랫동안 있던 분들(나쁘게 말하면 고인 물…)의 의견이 강하다면 그들을 설득하는 방법부터 바꿔봐야 한다. ‘레거시는 과거의 최선이었다’라는 명언은 무시할 수 없듯이 각 팀에 ‘맞춤형’ 문화를 만들어 나가야 한다.

     이러한 ‘문화’ 적인 측면에서는 한 사람의 노력만으로는 절대 바뀔 수가 없다. 어떤 문화가 좋은 문화라는 정답은 없지만 적어도 현재에 안주하려 하고 변화를 싫어하는 모습들은 팀의 성장을 방해할 수밖에 없지 않을까? 회사와 팀 그리고 개인의 성장을 도모하는 문화 속에서 즐거운 개발을 할 수 있기를 바라본다.

     우선 이 글을 읽는 여러분의 ‘팀’이 가지고 있는 다른 팀과 다른 문화가 있는가?부터 생각해보자. 없다면, 사소한 것부터 만들어 나가야 하고 있다면 과연 그 문화가 모두의 성장과 발전에 도움이 되는 문화인지 점검하는 과정이 필요할 것이다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/06/28/a-good-developer-in-terms-of-self-development/index.html b/2020/06/28/a-good-developer-in-terms-of-self-development/index.html index 2fbb3cc3..17004871 100644 --- a/2020/06/28/a-good-developer-in-terms-of-self-development/index.html +++ b/2020/06/28/a-good-developer-in-terms-of-self-development/index.html @@ -15,4 +15,4 @@  7 minutes 

     학창 시절엔 ‘선생님’께서 정해놓으신 커리큘럼에 따라가기만 하면 큰 문제 없이 지식을 학습할 수 있었다. 거기에 주기적으로 치르는 시험을 통해 ‘점수’라는 평가 기준으로 얼마나 잘 성장했나를 검사하기도 한다. 졸업 후 어렵게 어렵게 취업에 성공을 하여 ‘신입 개발자’라는 배지를 달고 회사에 첫 출근. 그렇게 n 년이 지난 지금과 라떼 시절(?)을 비교해 보며 과연 ‘학습’에 대한 열정 그래프가 아직도 우상향 중인가? 하는 질문엔 일단 단전부터 올라오는 깊은 한숨과 함게 이상하게도 앞이 캄캄해진다.

    /images/a-good-developer-in-terms-of-self-development/latte.jpg
    우리는 모두 라떼 시절을 가지고 있다.
    출처 : https://www.dogdrip.net/212294087

     배워야 할게 너무 많다. 아니 그보다 배운 것을 이제 활용해야지 싶으면 또 새로운 기술이 등장한다. 그렇게 매너리즘에 빠지고. 거기다 회사일이 바쁘다는 핑계로 자기계발을 멈추다 보면 남들보다 뒤처진다는 생각에 괜히 자괴감이 들어 우울해 지곤 한다. (코로나 블루 때문만은 아니겠지…) 그 가운데 회사에는 정말 좋은 선배님들도 많고 멘토-멘티 관계를 잘 활용하면 충분히, 잘, 올바른 길로 성장할 수 있을 것이라 생각한다. 하지만 그렇게 누군가에게 ‘의존’만 하다 그 대상이 없어진다든지 심지어 그런 대상조차 없을 경우에는 어떻게 해야 할까? 점점 기술은 발전하고 배워야 할 것들은 홍수처럼 넘쳐흐르고 있는 가운데 ‘회사원’에서 나아가 ‘개발자’로써 성장을 하기 위해서는 어떠한 방법이 있을까?

     이번 포스팅에서는 개발자로 살아가면서 성장하기 위한즉, 자기계발의 ‘방법’에 대해 이야기해보려 한다. 이것이 정답이다 하는 은 탄환을 소개하려는 것은 아니다. 특히 개발자로서의 생을 마감(?) 할 때까지는 계속 배워야 하는 숙명과도 같은 직업이기에 첫 단추를 잘 끼워서 갑작스러운 기술의 변화에 일희일비 하지 않고 스펀지처럼 무엇이든 흡수하는. 말랑말랑한 정신을 갖기 위함이라고나 할까.

    블로그

     개발자가 글도 써야 하나?라는 질문에는 필자가 예전에 정리해둔 개발하기 바쁜데 글까지 쓰라고? (글쓰는 개발자가 되자.)라는 글을 참고해봐도 좋을 것 같다. 해당 포스팅에서 수차례 강조하였지만 그만큼 개발자에게는 특히나 글쓰기가 중요하고 필요하다. 글을 꼭 ‘잘’써야 한다는 부담을 가질 필요는 없다. (필자도 그렇게 잘 쓰는 편은 아니다…) 다만 무언가를 기록하고 정리하고 자신만의 기준에 맞추어 재 정리하는 습관을 기르다 보면 이러한 생각들이 개발을 할 때에도 도움이 상당히 되었기 때문이다.

    /images/a-good-developer-in-terms-of-self-development/exception.gif
    개발을 하다보면 꼼꼼하게 체크해야할 예외가 너무 많다.
    출처 : https://gfycat.com/ko/menacingeducatedatlasmoth

     복잡한 구조가 필요로 하는 개발을 해야 한다고 가정해보자. 연동하는 시스템도 많고 정말 다양한 요구 사항을 하나의 시스템에서 구현을 해야 할 경우 보통 개발을 하기에 앞서 ‘설계’라는 단계를 거치기 마련이다. 그때 글쓰기를 했을 때의 습관(스킬?)을 적용해 보면 요구 사항들 중에 중요한 feature 기준으로 정리를 하게 되고, 각 이해관계자들에게 정리한 부분을 공유하며 예외 상황을 보다 빠르게 확인할 수도 있다. 심지어 코드 레벨에서도 지난밤에 야식으로 먹은 라면 면발처럼 꼬여있는 부분들을 보다 개발하기 편하고 유지 보수가 용이하게 구조를 변경하는 ‘정리’의 습관 또한 글쓰기를 통해서 수련을 할 수 있다. 이러한 ‘꼼꼼함’을 기르는 데에는 글쓰기만 한 게 없다고 생각한다.

     우리는 다양한 개발 언어로 코딩을 하곤 한다. 왜 읽기좋은 코드가 좋은 코드라는 책이 있듯이 결국 코딩 또한 커뮤니케이션이 일종이라 생각한다. 내가 생각하는 로직을 개발 언어로 코딩을 해야 하는 상황이면, 결국 내가 생각하는 로직이 명료하고 정리가 잘 된 상태에서야 코드 또한 소위 ‘읽기 좋은 코드’가 되지 않을까 싶다.

     블로그를 시작할 때 어디서부터 시작해야 하나 막막하다면, 오늘의 배운 내용 (개발자들 사이에서 유행처럼 번지고 있는 TIL에 대해서 정리해 보는 것부터 추천한다. 경력이 1년 차여도 10년 차여도 개발을 하다 보면 새로운 것을 발견하기 마련이다. 그렇게 조금씩 적절한 블로그 플랫폼에 정리를 해 나가다 보면 어느새 자신만의 개발 히스토리가 만들어지고, 나아가 글쓰기가 전해주는 긍정적인 효과를 만끽하리라 자부한다.

    토이프로젝트

     우리는 개발자이다. 맘만 먹으면 생각하고 있는 동작을 얼마든지 만들 수 있는 능력을 가진 대단하면서도 신기한 사람들이다. 그러나, 회사에서 주어진 스펙을 개발하다 보면 이미 만들어진 개발 환경(일명 레거시)에 스펙을 위한 기능만을 개발하다 보니 정작 아무것도 없는 상황에서 시작하려면 머리가 하얘지기 마련이다. 더불어, 회사에서 추구하는 개발 방법론과 주어진 스킬 트리에 맞춤형(?) 개발자가 되다 보니 새로운 기술을 습득하는데 상당한 기술적 장벽이 생기면서 자칫 ‘기술적 고립’이 될 수도 있는 처지에 빠질 수도 있다.

     이렇게 위험한 상황을 조금이나마 벗어나기 위해서는 단언컨대 ‘토이 프로젝트’를 시작하는 것이 가장 좋다고 생각한다. 어떠한 기능을 어떠한 기술로 만들 것인지. 이런 것도 해볼까 저런 것도 해볼까. 마치 어렸을 적 레고 블록이라는 장난감으로 여러 가지를 만들었던 것처럼 밑바닥부터 새롭게, 그리고 자유롭게 만들어 나가면서 정말 회사에서 배우지 못한 다양한 기술들을 뼈저리게(?) 배울 수 있는 기회이기 때문이다. 요즘 핫한 개발 방법론이라든지, 새로운 언어, 새로운 기술 set을 접목시켜 봄으로써 회사라는 명찰을 떼고 나 자신이 개발자로써 어떠한 기술을 사용할 수 있는지 확인 또한 가능하다.

     여기서 중요한 점은, 그냥 읽어보고 따라 하기만 하는 것보다 그걸 활용해서 실제 결과물을 만들어 보는 것까지 가 중요한 포인트 같다. 이론은 누구나 대충 어림잡아 알고 있다. 하지만 실제로 해보는 건 하지 않은 것과 엄청난 차이가 있다는 걸 명심하자.

     꼭 회사 밖에서 찾을 필요는 없다. 팀 내에서 반복적이고 귀찮은 작업들을 자동화 시켜 본다든지, 아니면 바깥에서 들은 기술들을 우리 팀에 접목시켜본다든지. 내가 주체가 되어 무언가를 진행한다는 그 자체가 중요하고 거기서 기술적인 인사이트를 찾고 나만의 것으로 만드는 과정이 핵심 포인트라 생각한다. 필자는 회사 내부에서도 언제부터인가 시키지도 않는 스펙 개발 이외의 것을 시도하려고 부단히 노력 중이다. 일단 무언가를 만들어 본다가 가장 중요하다. ( 참고 : 어려운 것을 쉽게 배우는 방법 : 슈퍼파워를 장착하기 위한 3단계 학습법 )

     이제는 약 3천여 명이 구독하고 있는 필자의 첫 토이 프로젝트인 기술블로그 구독서비스개발 후기를 읽어보는 것도 좋을 것 같다. 벌써 만든 지 2년이 다 되어 가는데 기술적인 인사이트뿐만 아니라 ‘서비스’라는 것에 대한 또 다른 시각을 넓혀주는 좋은 계기가 되었기 때문이다. (어서 또 다른 것을 만들어 봐야 하는데 … )

    배우기 위한 노력

     스터디를 하는 방법은 다양하다. 오프라인으로 마음 맞는 사람들끼리 모여서 정해진 규칙에 따라 스터디를 하거나, 나 홀로 인터넷 강의를 들으면서 정해진 커리큘럼대로 배우거나, 그게 아니면 적당한 책을 구입해서 읽거나. 이 외에도 수많은 방법으로 스터디를 하곤 하는데 여기서 이야기하고자 하는 건 스터디의 방법이 아니라 무언가를 배우기 위한 ‘노력’을 꾸준히 해야 한다는 걸 말하고 싶다. 일반적으로 회사에 출근을 하면 업무에 치여서 팀 메신저에 ‘왜 벌써 6시에요?‘라는 소리가 나올 정도로 시간 가는 줄 모르고 일한다. 그러다 퇴근을 하면 피곤에 절어 쉬거나 개인적인 여가활동을 하다 보면 어느덧 자야 하는 시간. 그럼 도대체 언제 개발 공부를 해야 할까?

     사람마다의 추구하는 행복의 가치관이 다 다르고 훌륭한 개발자로서의 모습 또한 다 다른 만큼 이 부분에 있어서는 정답은 없다. 하지만 개발자로써 학습능력을 꾸준하게 기르기 위해서는 업무시간 외적으로 어느 정도는 개발 공부를 하기 위해 시간을 할애를 해야 한다고 생각한다. 예컨대, 필자는 하루에 최소 한 시간은 회사 업무 외적으로 개발 공부를 하는데 시간을 쏟으려 한다. (하지만 잘 지켜지지 않는 게 함정…) 그렇게 하기 위해서는 꾸준한 운동으로 건강한 몸이 뒷받침되어야 가능하기에 야근을 하든 안 하든 퇴근 후 운동과 개발 공부는 어떤 일이 있어도 (잠을 줄여서라도) 꼭 하려고 하고 있다. 어쩔 땐 그러한 ‘공부를 해야 한다’라는 생각들이 필자를 오히려 구속(?) 시키는 느낌도 받지만 그럴 때면 (위에서 말했던 것처럼) 무언가를 만들어 보며 좀 더 ‘재미있게’ 마인드를 유지하려고 노력 중이다. (이러한 글을 쓰는 것도 어떻게 보면 마인드 컨트롤 방법 중 하나라 볼 수 있다.)

    /images/a-good-developer-in-terms-of-self-development/c++win.gif
    상황에 따라 맞는 기술이 있다.
    출처 : https://gfycat.com/ko/tightwholebrontosaurus

     만약, JAVA 라는 언어에 대해 완벽히 안다고 가정해보자. 그럼 10년 20년 그 지식으로 평생 먹고 살수 있을까? 기술은 시대의 변화에 맞춰 바뀌기 마련이며 그러한 변화를 싫어하다보면 우물안의 개구리가 되는건 시간문제라 생각한다. 개발자는 기술의 변화에 민감하게 반응해야 하고 그러한 부분들을 너그럽게 수용할줄 알아야 하며 그렇게 하기 위해서는 자신에게 맞는 방법을 찾아서 흘러 넘치는 변화의 밑물에 노를 저을줄도 알아야 한다 한다.

    나를 정리하는 시간

     앞서 이야기 했던 부분들은 결국은 ‘악셀을 밟고 앞으로 전진!‘같은 성격의 이야기라면 이번엔 악셀에서 잠시 발을 떼고 정차 후 점검을 하는 관점으로 이야기를 해 보고자 한다. 장거리 운전을 할때는 워셔액은 충분한지, 타이어 공기압은 괜찮은지 점검하는 것처럼 말이다.

     필자가 학부시절 연구실을 다닐때 한 선배에게 들은 말이 아직도 생각난다. 본인은 (대학생시절) 한달에 한번씩 이력서를 업데이트 한다고… 그러다 보면 변화가 있었는지 한눈에 알 수 있고, 부족한 부분이 무엇인지 점검이 가능하다는 이야기. 얼마전에 이력서 작성법에 대해 아주 좋은 정리글을 보았다. (개발자 이력서 작성하기 (feat. 이력서 공개)) 이처럼 이력서는 이직할때만 사용하는게 아니라 상시 나를 돌아볼수도 있는 수단이라 생각이 들기 때문에 자신만의 방식으로 이력서를 업데이트 하는것도 좋은 방법이라 생각이 든다. (물론 필자도 링크드인만 몇줄 적은게 다 이지만… 이참에 정리한번 해봐야겠다.)

     자신만의 기술 스택을 정리하는 것 또한 방법이 될 수 있다. 쿠버네티스가 요즘 뜨고 있다고? 머신러닝이 대세라고? 하며 요즘 뜨는 기술들만 따라 하는 자세보다 자신이 생각하는 기본기를 탄탄히 다지면서 각자의 호흡, 각자의 속도를 유지하며 꾸준하게 기술 스택을 만들어 나가는 게 올바른 방법이라 생각이 든다. 우리는 1~2년 짧게 개발만 하는 것이 아니라 오랫동안 마라톤처럼 달려야 하기 때문에 탄탄한 기본기를 다지는 자신만의 방법이 필요한 때이다.

    /images/a-good-developer-in-terms-of-self-development/black9p.jpg
    e.g. black9p 님의 노션을 활용한 개인 기술스택 정리
    https://black9p.github.io

    마치며

     적어도 ‘개발자’ 라면, 그리고 좀 더 괜찮은 ‘개발자’로써 오랫동안 개발을 하고 싶다면 ‘자기계발’은 뗄래야 뗄 수 없는 필연적인 키워드이기 때문에 속도는 늦더라도 꾸준히 지속하는 게 중요하다고 생각한다. ‘자기계발’이라는 키워드로 이야기를 하다 보면 점점 ‘꼰대’가 되는 것만 같아 아쉽지만, 다~ 잘 되고자 하는 (또 꼰대 말투) 부분들이니 너무 노여워하지는 않았으면 한다. :)


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/07/12/toy-projects-second-year-review/index.html b/2020/07/12/toy-projects-second-year-review/index.html index 9bfca183..00930ceb 100644 --- a/2020/07/12/toy-projects-second-year-review/index.html +++ b/2020/07/12/toy-projects-second-year-review/index.html @@ -21,4 +21,4 @@  실무에서는 java로 웹서비스를 개발하다 보니 다른 언어를 배울 기회가 없었는데 이 토이 프로젝트를 하면서 처음으로 파이썬이라는 것을 알게 되었고, 물리 장비(혹은 VM) 위에서 운영되는 정통적인 웹서비스만 운영하다 이 기회를 통해 AWS를 접해볼 수 있었고, 사용자가 하나둘 늘어남에 따라 제한적인 자원 내에서 효율적인 성능을 내기 위한 고민을 하게 되고. 실무에서 배우지 못한 값진 경험들을 할 수 있어서 너무 좋았다. ※ 참고

    마치며

     핑계지만 서비스를 좀 더 디벨롭 해야 하는데 못하고 있다. 회사 바쁜 일만 어느 정도 끝나면 처음부터 다시 설계하여 보다 안정적인 서비스를 만들어 보고 싶다. 나아가 지금은 ‘돈 잃는’ 서비스를 운영 중인데 비즈니스 모델을 고민해서 ‘돈 버는’ 서비스로 바꿀 수 있을지… 가 가장 고민 포인트다. 조언이나 제안은 언제든지 환영이다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/09/07/github-pullrequest-build/index.html b/2020/09/07/github-pullrequest-build/index.html index 963baacb..edd5f8d6 100644 --- a/2020/09/07/github-pullrequest-build/index.html +++ b/2020/09/07/github-pullrequest-build/index.html @@ -23,4 +23,4 @@  4 minutes 

     git 은 분산 버전 관리 시스템 중 가장 잘 알려져 있다고 해도 과언이 아닐 정도로 대부분의 시스템에서 사용되고 있는 것 같다. 이를 웹서비스에서 보다 편하게 사용할 수 있도록 한 시스템이 Github. Github 을 사용하는 이유 중에 가장 큰 이유를 하나만 이야기해보자면 바로 온라인상에서 코드 리뷰를 할 수 있는 pullRequest라는 기능 때문이 아닐까 조심스럽게 생각을 해본다.

     pullRequest는 work branch에서 작업한 내용을 base branch로 merge 전 꼭 코드 리뷰가 아니더라도 작업한 내용에 대해서 다양한 검사를 자동화할 수 있는 강력한 기능들이 많다. 이러한 자동화는 CI(지속적 통합) 관점에서 매우 중요한데 코드에 대해 체크해야 할 부분들(빌드, 테스트, 정적 분석 등)을 “알아서” 해준다면 작업자는 오롯이 비즈니스 로직 개발에 대해서만 신경 쓸 수 있으니 생산성 절약 측면에서 엄청난 효과를 볼 수 있다.

    /images/github-pullrequest-build/car.gif
    내가 하는일에만 집중할 수 있게!
    출처 : https://www.clien.net/service/board/park/10453442

    이번 포스팅에서는 그중에서도 아주 간단한 설정만으로 work branch의 빌드 상태를 검사해 볼 수 있는 Jenkins의 Github Pull Request Builder를 설치 및 활용해 보고자 한다.

    사실 최근 팀에서 CI 서버를 이전해야 했었다. 머릿속에서는 어떻게 하면 되겠지 싶었지만 막상 해보려니 Jenkins 버전업도 되었고 뭐부터 해야 할지 허둥대는 필자가 부끄러웠다. 이참에 정리를 해보며 다시 한번 리마인드 하는 시간을 가져보고자 한다. (이래서 기억보다 기록이 중요하다.)

    준비물

     전체적인 흐름은 아래 그림처럼 흘러가기 때문에 당연히 서버에 Jenkins 가 설치되어 있어야 한다. Jenkins 설치는 필자의 포스팅(Jenkins 설치 치트키)를 참고해 보는 것도 좋을 것 같다.

    /images/github-pullrequest-build/programmer-github-jenkins.jpg
    전체적인 흐름

     참고로 필자는 GitHub Enterprise 버전에서 사용했는데 일반 Github에서도 동일한 방법으로 사용 가능하다.

    Github과 Jenkins의 연동을 위한 2가지 설정

     Github 과 Jenkins 가 통신이 되도록 설정해 줘야 한다. 그래야 Github의 코드를 받아서 Jenkins 가 빌드를 하고 그 빌드 결과를 다시 Github에 리포트가 가능해지기 때문이다. 먼저 첫 번째로 ssh 설정으로 Github의 코드를 가져오도록 ssh 설정을 해두자. ssh 설정하는 방법은 필자의 포스팅(Github과 Jenkins 연동하기)편을 확인해보면 될 것 같다.

     그다음으로 아래에서 이야기할 GitHub Pull Request Builder라는 Jenkins plugin 이 빌드가 끝난 뒤에 결과를 리포팅 해줄 수 있는 인증 토큰을 발급받아두자. Github > Settings > Developer settings > Personal access tokens 화면에서 키를 생성하고 만들어진 키를 저장해 둔다. (이 키는 보안에 유의해야 하고, 화면 경고(?)에서도 볼 수 있듯이 키는 생성 시 한 번밖에 볼 수 없기 때문에 미리 저장해 둬야 한다.)

    /images/github-pullrequest-build/github-access-token.jpg
    인증토큰을 미리 받아두자.

    Jenkins 설정

     Jenkins > 관리 > pluginManager에 들어가 GitHub Pull Request Builder를 검색 후 설치해 준다. 그러고 나서 Jenkins > 관리 > 환경설정에 들어가 보면 아래와 같이 GitHub Pull Request Builder 항목이 생긴 것을 확인할 수 있고 위에서 설정한 인증토큰을 아래처럼 등록 후 저장을 한다.

    /images/github-pullrequest-build/add-github-access-token.jpg
    credentials 을 위에서 발급받은 인증토큰으로 등록해준다.

     Jenkins job을 하나 만들고 pullRequest 가 발생했을 때 자동으로 실행될 수 있도록 설정을 해준다. 먼저 General 탭에 Github project에 Github url 을 적어주고

    /images/github-pullrequest-build/jenkins-general.jpg

     소스 코드 관리 탭에서 ssh 주소를 적고 위에서 미리 설정한 ssh 키로 credentials 값을 넣어준다. 전에도 이야기했지만 이 부분에서 오류가 발생하면 빨간색 글씨로 오류 내용이 나오고 아래 화면처럼 오류가 없다면 아무것도 안 나온다. Refspec 에 +refs/pull/*:refs/remotes/origin/pr/* 라고 적어주고 브랜치 설정은 파라미터로 받아와서 pullRequest를 발생시킨 브랜치를 빌드 할 수 있도록 ${sha1} 라고 적어주자.

    /images/github-pullrequest-build/jenkins-sourceCode.jpg

     앞서 이야기했듯이 (제목처럼) pullReqeust를 등록하면 자동으로 빌드가 돌아가게 해야 한다. 그러기 위해서는 이 Jenkins job 을 위에서 설치한 GitHub Pull Request Builder 플러그인으로 빌드를 유발해야 한다. 아래 화면처럼 GitHub Pull Request Builder 항목을 체크하고 Use github hooks for build triggering에 체크를 해줘서 해당 Github Repository에 webHook 이 등록되게 해주자. 또한 Admin list에서 pullRequest 등록 시 허용할 사용자의 id를 적어준다.

    /images/github-pullrequest-build/jenkins-buildTrigger.jpg

     위에서 등록한 설정으로 인해 해당 Github Repository에 webHook이 자동으로 등록된 것을 확인할 수 있다.

    /images/github-pullrequest-build/jenkins-webhook.jpg

    테스트

     자, 그럼 이제 설정을 끝냈으니 실제로 pullRequest를 등록하면 어떤 일이 발생하는지 알아보자. 등록을 하자마자 자동으로 아래처럼 빌드가 돌아가는 것을 볼 수 있고

    /images/github-pullrequest-build/pullRequest-build-pending.jpg

     Details를 누르면 해당 Jenkins job으로 이동되게 되는데 열심히 빌드가 되는 걸 볼 수 있다. 시간이 지나고 빌드가 완료 된 다음 pullRequest를 보면 빌드가 성공되었다는 표시를 볼 수 있다.

    /images/github-pullrequest-build/pullRequest-successful.jpg

     빌드가 실패하면 merge를 하지 못하게 하는 옵션도 있다. base branch를 보호하는 옵션인데, 아래 화면처럼 빌드 가 실패하면 merge 버튼이 활성화되지 못하도록 해두고

    /images/github-pullrequest-build/github-branch-protection.jpg

     임의로 빌드를 실패하게 하면 아래처럼 merge버튼이 비활성화되는 걸 볼 수 있다.

    /images/github-pullrequest-build/github-build-fail.jpg

    마치며

     위에서 설명한 기능을 잘 활용하면 정말 무궁무진하게 활용이 가능하다. 필자가 운영하는 컴포넌트는 이런저런 이유로 빌드가 오래 걸리는데 계속 기다리는 시간조차 유의미한 시간에 사용하고 싶어 빌드가 끝나면 메신저로 빌드 결과를 알려주도록 하였다. 또한 이 빌드 트리거를 잘 활용하면 정적 분석을 한다든지 주요 기능 테스트를 해서 보다 코드의 안정성을 올리고 개발 생산성 또한 올릴 수 있는 좋은 방법이라 생각한다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/2020/10/04/a-good-developer-in-terms-of-log-and-monitoring/index.html b/2020/10/04/a-good-developer-in-terms-of-log-and-monitoring/index.html index de9d86d9..f2bfaca5 100644 --- a/2020/10/04/a-good-developer-in-terms-of-log-and-monitoring/index.html +++ b/2020/10/04/a-good-developer-in-terms-of-log-and-monitoring/index.html @@ -30,4 +30,4 @@ }

    로그가 가져다 주는 또 다른 세상

     로그는 또 다른 데이터가 될 수 있다. 글 목록을 보여주는 웹페이지가 있다고 가정해보자. 이때 사용자들이 어떤 글을 더 많이 읽는지 ‘클릭 지표’에 대한 로그를 남겨 둔다면 ‘인기글’ 같은 또 다른 웹 페이지가 나올 수 있을 것 같다. 만약 그 페이지가 회원만 읽을 수 있는 페이지라면 ‘20대 남성이 월요일 오후에 많이 읽는 글’ 같이 회원의 정보를 조합하여 새로운 데이터를 만들 수 있게 된다. 이러한 데이터들은 보다 더 좋은 서비스를 할 수 있게 도와줄 수 있는 밑거름이 되고 그 바탕은 로그라는 걸 명심하자.

     시스템의 다양한 메트릭(Metric) 을 수집하고 이를 대시보드화하여 시스템 상태를 파악하는 데 도 도움을 줄 수 있다. 엄청난 트래픽이 예상되는 이벤트를 진행한다고 가정해보자. 이럴 때 실시간으로 로그를 수집해서 미리 구성해둔 모니터링 시스템이 없다면 무엇을 봐야 할지도 모르고 문제가 어디서 발생하는지조차 모르기 때문에 ‘서버 다운’이라는 최악의 상황까지 발생할 수 있다. 애플리케이션을 만들면 언제라도 상태를 한눈에 파악할 수 있는 모니터링 대시보드로써 문제가 발생했을 때 문제점을 빨리 파악하고 대응을 할 수 있는 최소한의 장치를 마련해 두는 연습을 해두자.

    /images/a-good-developer-in-terms-of-Log-and-Monitoring/monitoring_dashboard.jpg
    구글에서 검색해보면 정말 다양한 형태로 모니터링 대시보드를 구성하는 모습을 볼 수 있다.

    환상의 조합, 모니터링과 ‘알림’

     로그를 기가 막히게 남겨두고, 모니터링 대시보드도 누가 봐도 한눈에 서비스의 상태를 볼 수 있게 정말 우아하게 만들어 두었다고 가정해보자. 그렇다면 이러한 로그와 모니터링 대시보드를 눈으로 보고 있어야 할까? 퇴근은 언제 하며 잠도 안 자고 봐야 한단 말인가? 다행스럽게도 일반적인 로그에서는 로그 레벨이라는 게 존재한다. ERROR, WARN부터 INFO, DEBUG 등 이름에서도 유추할 수 있듯이 각 레벨이 의미하는 상황에 따라 레벨을 지정하여 운영할 수 있다. 예컨대 운영환경에서는 ERROR만 남긴다거나, 개발 환경에서는 DEBUG 레벨까지 남기는 설정을 할 수 있다.

    /images/a-good-developer-in-terms-of-Log-and-Monitoring/alert.gif
    알림은 개발자의 시간을 단축해준다.
    출처 : https://gifer.com/en/SzNQ

     로그 시스템에서는 알림 기능을 제공하고 있다. (제공하지 않는 경우 직접 구현을 해야 할 수도 있다.) 그래서 지정한 주기 내에서 지정한 횟수로 로그가 발생하면 이를 감지하여 시스템 관리자에게 메신저나 문자 등으로 알림을 발송해 주는 시스템이 필요하다. 단, 이러한 알림이 너무 잦거나 알림 발송의 기준이 너무 추상적이라면 ‘알림’에 대한 인식이 둔해질 수 있기 때문에 정말 필요한 알림만 발송될 수 있게 해둬야 한다. 반대로, 알림을 받고는 있지만 지금 당장 대응하지 않을 이슈라면 알림을 받지 않는 게 정상이다. 그렇기에 앞서 이야기 한 로그 레벨 설정이 정말 중요하다. (이 로그가 정말 ERROR 레벨인가? WARN이나 INFO는 아닐까?)

    마치며

     개발을 할 때 변수의 자료형이 몇 바이트이고 이를 얼마나 사용하기 때문에 메모리를 얼마나 사용하고 cpu는 몇 core이니까 얼마나 자원을 사용하고 가비지 컬렉션이 차지하는 용량은 … 이렇게 개발 단계부터 디테일하게 개발하진 않는다. (물론 엄청난 성능을 요하는 core 모듈 개발이라면 모를까…) 보통은 기능 개발을 끝내고선 로그와 시스템 지표를 확인하고 그다음에 튜닝을 하는 방식으로 하게 된다. 요즘엔 애플리케이션의 기반이 되는 서버(혹은 클라이언트)의 성능이 좋기 때문에 더욱더 개발을 끝난 뒤에 성능 테스트의 결과에 따라 서버를 증설할지 로직을 튜닝할지 결정하게 되는데 여기에서도 가장 핵심은 ‘로그’ 와 ‘모니터링’이다.

     문제가 발생하면 가장 먼저 해야 할 게 무엇일까? 선임/동료 개발자에게 물어보기일까? 아님 restart(재부팅)? 입이 닳도록 아깝지 않을 정도로 ‘로그’를 먼저 봐야 한다고 말하고 싶다. 만약 재부팅을 하더라도 문제 되고 있는 현재 시스템 상태의 로그를 남겨두고 (java에서는 heap/thread dump 등) 재부팅을 한다거나 하는 습관. 개발을 아무리 잘해도, 테스트 코드 작성을 아무리 잘해도 ‘로그’와 ‘모니터링’을 빼놓고선 서비스 운영을 논할 수 없기에 꼭 다양한 연습으로 습관화하는 게 필요할 것 같다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/404.html b/404.html index 694e8bc6..dc224666 100644 --- a/404.html +++ b/404.html @@ -1,3 +1,3 @@ 404 Page not found - 👨‍💻꿈꾸는 태태태의 공간

    The page you're looking for doesn't exist. Sorry.  -

    \ No newline at end of file +

    \ No newline at end of file diff --git a/categories/blog/index.html b/categories/blog/index.html index 80aa537a..01f6571f 100644 --- a/categories/blog/index.html +++ b/categories/blog/index.html @@ -5,4 +5,4 @@ 07-09

    2016

    \ No newline at end of file +09-18
    \ No newline at end of file diff --git a/categories/essay/index.html b/categories/essay/index.html index 13bf51ea..2fbb417f 100644 --- a/categories/essay/index.html +++ b/categories/essay/index.html @@ -1,9 +1,10 @@ -essay - Category - 👨‍💻꿈꾸는 태태태의 공간

     essay

    2023

    그런 개발자로 괜찮은가 - '환경' 편 +essay - Category - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-21
    \ No newline at end of file diff --git a/categories/essay/index.xml b/categories/essay/index.xml index e73967e0..7ea6b905 100644 --- a/categories/essay/index.xml +++ b/categories/essay/index.xml @@ -1,4 +1,14 @@ -essay - Category - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/categories/essay/essay - Category - 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 23 Jul 2023 10:39:22 +0900그런 개발자로 괜찮은가 - '환경' 편https://taetaetae.github.io/posts/a-good-developer-in-terms-of-surroundings/Sun, 23 Jul 2023 10:39:22 +0900Authorhttps://taetaetae.github.io/posts/a-good-developer-in-terms-of-surroundings/ +essay - Category - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/categories/essay/essay - Category - 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 07 Jan 2024 00:16:21 +0900그런 개발자로 괜찮은가 - '그룹 스터디' 편https://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/Sun, 07 Jan 2024 00:16:21 +0900Authorhttps://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/ + + 다양한 방식으로 스터디를 해왔다. 정말 많은 것을 배웠던 스터디도 있는가 반면에 지나고 보면 시간이 아까울 정도의 스터디도 있었던 것 같다. 직접 만들어 보기도 했고 참여도 해봤던 것 같다. 이런저런 경험들 끝에 작년 중순에 직접 만들었던 스터디 멤버와는 어느덧 반년을 넘어가고 있는데 바쁜 회사 생활을 하면서도 이제까지 지속할 수 있었던 노하우를 공유해 보고자 한다. +그룹 스터디 방식 인원  다 그런 건 아니지만 기존 회사 분들과 스터디를 할 때면 아무래도 원래 알던 사이라 바빠서 준비를 못 해오거나 불참을 하는 경우에 “그럴 수도 있지”, “괜찮아” 하며 관대해졌던 것 같다. 또는 다양한 의견을 듣자며 10명 이상 진행을 했던 것 같다. 그렇다 보니 스터디 진행에 집중도가 떨어질 수밖에 없었고 모였을 때 이야기하던 사람들만 이야기한다든지, 중도 하차하는 경험도 많았다. +블라인드 글에 첨부한 스터디 참여 설문" 블라인드 글에 첨부한 스터디 참여 설문  이번 스터디는 직접 ‘블라인드’라는 익명 커뮤니티를 통해 인원을 모았다. 작년 중순쯤 자바 백엔드 관련된 주제를 스터디 하겠다며 나와 비슷한 연차분들 위주로 모으겠다고 글을 작성했더니 신기하게도 3~40명 되는 분들이나 지원하셨고 그중 오프라인 모임을 고려해서 나 포함 6명 만으로 구성을 하였다.(뭔가 서류 전형 인사담당자가 된 느낌;;) 작은 규모 그리고 새로운 분들과 하게 되니 집중도가 오르는 경험을 할 수 있었고 무엇보다 6명 모두 다른 회사라 각 회사를 대표하는 것 같은 느낌이 들어 스터디 참여에 몰입이나 책임감이 더욱 올랐던 것 같다. 또한 한 주제에 대해 각 회사에서의 경험들을 이야기하다 보니 완전히 다른 시각을 얻을 수 있다는 장점도 있었다. + 별거 아닐 수도 있지만(또는 오해가 될 수도 있지만) 남녀 성비, 그리고 나이대(연차)를 최대한 맞추고 싶었다. 그래야 분위기가 적당히 딱딱하지도, 부드럽지도 않을 것 같았기 때문이다. 지금은 여자 한 분 나머지 남자분들이라 초반에 걱정도 되었지만 생각보다 분위기가 잘 흘러가서 다행이라 생각을 한다. +주제와 목표 배워야 할게 한도 끝도 없는 개발자 세상스터디 목표에 따라 집중해야 할 범위를 좁히자!" 배워야 할게 한도 끝도 없는 개발자 세상 +스터디 목표에 따라 집중해야 할 범위를 좁히자!  처음부터 모니터 받침으로 하기 좋을만한 두꺼운 책은 피했던 것 같다. 가볍게, 스터디원들끼리의 친밀도부터 올려야 한다는 생각으로 너무 딥 다이브 한 기술적인 내용보다는 누구나 한마디 정도 할 수 있을만한 가벼운 책부터 시작했다. 그러면서 최대한 참여도를 올리는데 집중했던 것 같다. + 어디까지나 “공부"를 하기 위한 모임이긴 하지만 이 또한 사람과 사람 사이의 “관계"가 중요하다고 생각했기에 모였을 때 바로 스터디 이야기를 하는 것보다 부드러운 아이스브레이킹을 자주 해왔다. 또한 너무 루즈 해지지 않게 1달~1달 반 정도로 끝날 수 있을만한 주제를 선정했다. 아무래도 한 주제가 2~3달 걸리다 보면 집중도가 떨어지는 경험이 많았기 때문이다. 책 한 권을 다 읽었다는 기간을 짧게 가져가면서 작은 성취의 효과를 최대한 활용하고 있다. 이번 회차가 벌써 네 번째인걸 보면 그래도 나름 잘 선택한 방법이라 생각이 든다. + 한 회차가 끝날 즈음엔 다음 스터디는 무엇을 할 것인지에 대해 이야기를 하고 다수가 동의하는 주제를 선정한다. 또한 매 회차가 끝날 때마다 어쩌면 어색할 수 있는 이야기지만 스터디 참여를 그만 둘지에 대해 의사를 분명히 물어본다. (그런데 신기하게도 지금 스터디 모임은 이런 이야기를 하기도 전에 스터디 하고 싶은 주제를 먼저 말씀해주시는 편이라, 어쩌면 스스로 사람 운이 좋다는 생각도 해본다.) + 그저 하나의 책을 읽기로 끝나는 “책 읽기 모임” 이 아닌 만큼 책을 기반으로 하는 스터디 모임일지라도 목표를 분명하게 잡는다. 여기서 목표는 개인마다 다를 수 있다. 가령 스터디 시간에 나왔던 내용을 각자의 팀에 공유 및 반영을 해본다든지, 스터디 내용에 대해 주도적으로 이야기를 하며 다른 분들의 지식을 훔쳐보겠다든지(?]]>그런 개발자로 괜찮은가 - '환경' 편https://taetaetae.github.io/posts/a-good-developer-in-terms-of-surroundings/Sun, 23 Jul 2023 10:39:22 +0900Authorhttps://taetaetae.github.io/posts/a-good-developer-in-terms-of-surroundings/ (필자의 과거 경험을 미루어) 개발자로서 회사에서 일을 하다 보면 가끔 CRUD(Create, Read, Update, Delete) API를 찍어내는 기계(?)가 되는 느낌을 받을 때가 있다. 일정은 촉박한데 사람은 부족하고, 기술 부채가 복리로 늘어나는 게 눈에 훤히 보이지만 개선할 시간이나 여유조차 없어 자신도 모르게 점점 “돌아가게만” 개발하는 상황들. 기술적인 고민을 할 시간은 점점 없어지고, 코드를 설계하는 측면이나 테스트 코드, 책임과 관심 같은 생각들은 하지 못한 채 편의만 추구하며 코드를 작성한다. 그러다 이직을 해야겠다 마음먹고 이력서를 작성할 때나 연말 평가를 위해 한 해 무엇을 했는지 돌아보면 회사일은 불철주야 정말 열심히 했지만 회사를 벗어나 개발자로써 본인 스스로를 위한 건 회사일 대비 아주 극소수에 불과하는 삶이 계속된다. 코딩하는 로봇은 되지 말자.출처 : https://sdtimes.com/ai/ai-enabled-tools-might-completely-change-development-one-day/" 코딩하는 로봇은 되지 말자. diff --git a/categories/index.html b/categories/index.html index e3112cbe..81ce3400 100644 --- a/categories/index.html +++ b/categories/index.html @@ -1,2 +1,2 @@ -All Categories - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +All Categories - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file diff --git a/categories/index.xml b/categories/index.xml index 6236a40d..0a778f8d 100644 --- a/categories/index.xml +++ b/categories/index.xml @@ -1 +1 @@ -Categories - Category - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/categories/Categories - Category - 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 31 Dec 2023 15:26:10 +0900reviewhttps://taetaetae.github.io/categories/review/Sun, 31 Dec 2023 15:26:10 +0900Authorhttps://taetaetae.github.io/categories/review/essayhttps://taetaetae.github.io/categories/essay/Sun, 23 Jul 2023 10:39:22 +0900Authorhttps://taetaetae.github.io/categories/essay/Techhttps://taetaetae.github.io/categories/tech/Sun, 04 Apr 2021 18:54:00 +0900Authorhttps://taetaetae.github.io/categories/tech/bloghttps://taetaetae.github.io/categories/blog/Sun, 27 Oct 2019 13:51:16 +0000Authorhttps://taetaetae.github.io/categories/blog/ \ No newline at end of file +Categories - Category - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/categories/Categories - Category - 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 07 Jan 2024 00:16:21 +0900essayhttps://taetaetae.github.io/categories/essay/Sun, 07 Jan 2024 00:16:21 +0900Authorhttps://taetaetae.github.io/categories/essay/reviewhttps://taetaetae.github.io/categories/review/Sun, 31 Dec 2023 15:26:10 +0900Authorhttps://taetaetae.github.io/categories/review/Techhttps://taetaetae.github.io/categories/tech/Sun, 04 Apr 2021 18:54:00 +0900Authorhttps://taetaetae.github.io/categories/tech/bloghttps://taetaetae.github.io/categories/blog/Sun, 27 Oct 2019 13:51:16 +0000Authorhttps://taetaetae.github.io/categories/blog/ \ No newline at end of file diff --git a/categories/review/index.html b/categories/review/index.html index 70d7601a..a76d2987 100644 --- a/categories/review/index.html +++ b/categories/review/index.html @@ -9,4 +9,4 @@ 03-26

    2019

    \ No newline at end of file +07-07
    \ No newline at end of file diff --git a/categories/review/page/2/index.html b/categories/review/page/2/index.html index b44b5686..19dcbddb 100644 --- a/categories/review/page/2/index.html +++ b/categories/review/page/2/index.html @@ -9,4 +9,4 @@ 10-14

    2017

    2016

    \ No newline at end of file +12-31
    \ No newline at end of file diff --git a/categories/tech/index.html b/categories/tech/index.html index 34fcc35b..d532bc7c 100644 --- a/categories/tech/index.html +++ b/categories/tech/index.html @@ -9,4 +9,4 @@ 12-20
    \ No newline at end of file +09-07
    \ No newline at end of file diff --git a/categories/tech/page/2/index.html b/categories/tech/page/2/index.html index 183ff315..a816355c 100644 --- a/categories/tech/page/2/index.html +++ b/categories/tech/page/2/index.html @@ -9,4 +9,4 @@ 10-13
    \ No newline at end of file +07-21
    \ No newline at end of file diff --git a/categories/tech/page/3/index.html b/categories/tech/page/3/index.html index 466d7d3a..89fac5d8 100644 --- a/categories/tech/page/3/index.html +++ b/categories/tech/page/3/index.html @@ -9,4 +9,4 @@ 01-10

    2018

    \ No newline at end of file +12-02
    \ No newline at end of file diff --git a/categories/tech/page/4/index.html b/categories/tech/page/4/index.html index 5ef83d96..de63c22b 100644 --- a/categories/tech/page/4/index.html +++ b/categories/tech/page/4/index.html @@ -9,4 +9,4 @@ 06-27
    \ No newline at end of file +04-10
    \ No newline at end of file diff --git a/categories/tech/page/5/index.html b/categories/tech/page/5/index.html index 3f019b4c..d7376d2d 100644 --- a/categories/tech/page/5/index.html +++ b/categories/tech/page/5/index.html @@ -9,4 +9,4 @@ 01-25

    2017

    \ No newline at end of file +08-28
    \ No newline at end of file diff --git a/categories/tech/page/6/index.html b/categories/tech/page/6/index.html index eb030c8c..bd6e9845 100644 --- a/categories/tech/page/6/index.html +++ b/categories/tech/page/6/index.html @@ -9,4 +9,4 @@ 02-27
    \ No newline at end of file +01-10
    \ No newline at end of file diff --git a/categories/tech/page/7/index.html b/categories/tech/page/7/index.html index e9a2ab04..a7f298a6 100644 --- a/categories/tech/page/7/index.html +++ b/categories/tech/page/7/index.html @@ -6,4 +6,4 @@ 10-08
    \ No newline at end of file +09-18
    \ No newline at end of file diff --git a/images/.DS_Store b/images/.DS_Store index 67697cc4..4adf2f27 100644 Binary files a/images/.DS_Store and b/images/.DS_Store differ diff --git a/images/a-good-developer-in-terms-of-group-study/blind.png b/images/a-good-developer-in-terms-of-group-study/blind.png new file mode 100644 index 00000000..9f4468b1 Binary files /dev/null and b/images/a-good-developer-in-terms-of-group-study/blind.png differ diff --git a/images/a-good-developer-in-terms-of-group-study/logo.png b/images/a-good-developer-in-terms-of-group-study/logo.png new file mode 100644 index 00000000..44955509 Binary files /dev/null and b/images/a-good-developer-in-terms-of-group-study/logo.png differ diff --git a/images/a-good-developer-in-terms-of-group-study/roadmap.png b/images/a-good-developer-in-terms-of-group-study/roadmap.png new file mode 100644 index 00000000..865165da Binary files /dev/null and b/images/a-good-developer-in-terms-of-group-study/roadmap.png differ diff --git a/images/a-good-developer-in-terms-of-group-study/roulette.gif b/images/a-good-developer-in-terms-of-group-study/roulette.gif new file mode 100644 index 00000000..183cd473 Binary files /dev/null and b/images/a-good-developer-in-terms-of-group-study/roulette.gif differ diff --git a/images/a-good-developer-in-terms-of-group-study/study.jpeg b/images/a-good-developer-in-terms-of-group-study/study.jpeg new file mode 100644 index 00000000..6e82b985 Binary files /dev/null and b/images/a-good-developer-in-terms-of-group-study/study.jpeg differ diff --git a/index.html b/index.html index 55255405..18cd33bd 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,13 @@ -👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    초보 시니어 개발자의 2023 리뷰

    언제부터인가 새해가 되면 그 해의 키워드를 선정하고 해시태그처럼 달고 다니며 한 해를 보내온 것 같다. 작년의 키워드는 “한계”. 한정된 시간 속에서 하고 싶은 것도 많고 해야 할 것도 많은 나로서는 중요도에 따라 어쩔 수 없이 무언가를 포기하게 되는 순간들이 찾아왔다. 그럴 때마다 늘 어쩔 수 없다는 자기 가면을 쓴 채 정말 하고 싶던, 꼭 해야 할 것들임에도 불구하고 다음에 해야지 하고 넘어갔던 적이 많았다. +👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    그런 개발자로 괜찮은가 - '그룹 스터디' 편

    다양한 방식으로 스터디를 해왔다. 정말 많은 것을 배웠던 스터디도 있는가 반면에 지나고 보면 시간이 아까울 정도의 스터디도 있었던 것 같다. 직접 만들어 보기도 했고 참여도 해봤던 것 같다. 이런저런 경험들 끝에 작년 중순에 직접 만들었던 스터디 멤버와는 어느덧 반년을 넘어가고 있는데 바쁜 회사 생활을 하면서도 이제까지 지속할 수 있었던 노하우를 공유해 보고자 한다. +그룹 스터디 방식 인원  다 그런 건 아니지만 기존 회사 분들과 스터디를 할 때면 아무래도 원래 알던 사이라 바빠서 준비를 못 해오거나 불참을 하는 경우에 “그럴 수도 있지”, “괜찮아” 하며 관대해졌던 것 같다. 또는 다양한 의견을 듣자며 10명 이상 진행을 했던 것 같다. 그렇다 보니 스터디 진행에 집중도가 떨어질 수밖에 없었고 모였을 때 이야기하던 사람들만 이야기한다든지, 중도 하차하는 경험도 많았다. +블라인드 글에 첨부한 스터디 참여 설문" 블라인드 글에 첨부한 스터디 참여 설문  이번 스터디는 직접 ‘블라인드’라는 익명 커뮤니티를 통해 인원을 모았다. 작년 중순쯤 자바 백엔드 관련된 주제를 스터디 하겠다며 나와 비슷한 연차분들 위주로 모으겠다고 글을 작성했더니 신기하게도 3~40명 되는 분들이나 지원하셨고 그중 오프라인 모임을 고려해서 나 포함 6명 만으로 구성을 하였다.(뭔가 서류 전형 인사담당자가 된 느낌;;) 작은 규모 그리고 새로운 분들과 하게 되니 집중도가 오르는 경험을 할 수 있었고 무엇보다 6명 모두 다른 회사라 각 회사를 대표하는 것 같은 느낌이 들어 스터디 참여에 몰입이나 책임감이 더욱 올랐던 것 같다. 또한 한 주제에 대해 각 회사에서의 경험들을 이야기하다 보니 완전히 다른 시각을 얻을 수 있다는 장점도 있었다. + 별거 아닐 수도 있지만(또는 오해가 될 수도 있지만) 남녀 성비, 그리고 나이대(연차)를 최대한 맞추고 싶었다. 그래야 분위기가 적당히 딱딱하지도, 부드럽지도 않을 것 같았기 때문이다. 지금은 여자 한 분 나머지 남자분들이라 초반에 걱정도 되었지만 생각보다 분위기가 잘 흘러가서 다행이라 생각을 한다. +주제와 목표 배워야 할게 한도 끝도 없는 개발자 세상스터디 목표에 따라 집중해야 할 범위를 좁히자!" 배워야 할게 한도 끝도 없는 개발자 세상 +스터디 목표에 따라 집중해야 할 범위를 좁히자!  처음부터 모니터 받침으로 하기 좋을만한 두꺼운 책은 피했던 것 같다. 가볍게, 스터디원들끼리의 친밀도부터 올려야 한다는 생각으로 너무 딥 다이브 한 기술적인 내용보다는 누구나 한마디 정도 할 수 있을만한 가벼운 책부터 시작했다. 그러면서 최대한 참여도를 올리는데 집중했던 것 같다. + 어디까지나 “공부"를 하기 위한 모임이긴 하지만 이 또한 사람과 사람 사이의 “관계"가 중요하다고 생각했기에 모였을 때 바로 스터디 이야기를 하는 것보다 부드러운 아이스브레이킹을 자주 해왔다. 또한 너무 루즈 해지지 않게 1달~1달 반 정도로 끝날 수 있을만한 주제를 선정했다. 아무래도 한 주제가 2~3달 걸리다 보면 집중도가 떨어지는 경험이 많았기 때문이다. 책 한 권을 다 읽었다는 기간을 짧게 가져가면서 작은 성취의 효과를 최대한 활용하고 있다. 이번 회차가 벌써 네 번째인걸 보면 그래도 나름 잘 선택한 방법이라 생각이 든다. + 한 회차가 끝날 즈음엔 다음 스터디는 무엇을 할 것인지에 대해 이야기를 하고 다수가 동의하는 주제를 선정한다. 또한 매 회차가 끝날 때마다 어쩌면 어색할 수 있는 이야기지만 스터디 참여를 그만 둘지에 대해 의사를 분명히 물어본다. (그런데 신기하게도 지금 스터디 모임은 이런 이야기를 하기도 전에 스터디 하고 싶은 주제를 먼저 말씀해주시는 편이라, 어쩌면 스스로 사람 운이 좋다는 생각도 해본다.) + 그저 하나의 책을 읽기로 끝나는 “책 읽기 모임” 이 아닌 만큼 책을 기반으로 하는 스터디 모임일지라도 목표를 분명하게 잡는다. 여기서 목표는 개인마다 다를 수 있다. 가령 스터디 시간에 나왔던 내용을 각자의 팀에 공유 및 반영을 해본다든지, 스터디 내용에 대해 주도적으로 이야기를 하며 다른 분들의 지식을 훔쳐보겠다든지(?

    초보 시니어 개발자의 2023 리뷰

    언제부터인가 새해가 되면 그 해의 키워드를 선정하고 해시태그처럼 달고 다니며 한 해를 보내온 것 같다. 작년의 키워드는 “한계”. 한정된 시간 속에서 하고 싶은 것도 많고 해야 할 것도 많은 나로서는 중요도에 따라 어쩔 수 없이 무언가를 포기하게 되는 순간들이 찾아왔다. 그럴 때마다 늘 어쩔 수 없다는 자기 가면을 쓴 채 정말 하고 싶던, 꼭 해야 할 것들임에도 불구하고 다음에 해야지 하고 넘어갔던 적이 많았다.  그렇게 시간을 보내니 아쉬움이 남게 되었고 잠을 줄여서라도 할 것 들을 하자며 나를 극한으로 몰아붙여보자는 의미로 작년의 키워드를 “한계"라고 정했고 정말 많은 것들을 경험할 수 있었다. 그렇게 나를 몰아붙이는 삶을 살다 보니 말 그대로 그저 “여러 가지만 했던” 한 해로 기억된다. (아마 그래서 작년 리뷰가 없던 이유일지도…?)  작년의 “한계"라는 키워드를 통해 잠은 죽어서 자야지 하는 마음으로 불타는 열정을 연습했다면 올해는 같은 시간을 쓰더라도 제대로 쓰고 싶은 마음에 많은 것들을 배우자는 의미로 “배움"이라는 키워드를 선정하게 되었다. 개발자로 살아온 지 올해로 11년 차가 되는 해 이기도 하고 이제는 “시니어 개발자"라는 수식어가 붙다 보니 더욱 시간을 허투루 보낼 수가 없다는 생각이 들었다. 그렇게 “배움"이라는 키워드를 가지고 한 해를 지나와보니 정말 많은 것들을 경험 그 이상으로 배울 수 있었고 그에 대한 한 해의 리뷰를 해보고자 한다. 회사원으로써의 노력  부여받은 일은 기본이고 그 이상을 스스로 찾아서 해야 하며, 구성원 모두가 함께 성장할 수 있는 분위기를 이끌어 나가야 하는 일당백 ‘시니어 개발자’로써 회사 생활을 해왔던 것 같다. (쓰고 보니 이력서에서나 볼법한 문장이지만;;) 특히 후배 개발자분들이 잘 성장할 수 있는 환경을 조성하고 그러한 과정들이 결국 서비스가 나아가고자 하는 방향에 보탬이 될 수 있도록 서포트 하는 것에 집중을 해왔다. @@ -68,11 +76,4 @@  그렇다면 멘티는 멘토를 어떻게 찾아야 할까? 함께 일하는 선배 동료가 있다면 정중하게 도움을 요청하는 것도 나쁘지 않다 본다. 단, 무작정 “저의 멘토가 되어주세요.“라는 것보다 자신이 가지고 있는 고민거리를 털어놓으며 조금씩 친분을 쌓아간다면 아무래도 경험이 많은 선배이기에 고민의 범위를 조금이라도 줄여줄 수 있지 않을까. 혹여 주변에 선배 동료가 없다면 온/오프라인 커뮤니티 활동을 하면서 찾는 것도 방법이다. 메신저를 통해 다가가거나 메일로 정중하게 고민을 요약해서 보내놓으면 당장은 아니더라도 가까운 시일 내에 응답이 오기 마련이다. (적어도 괜찮은 선배라면.)  여기서 말하는 ‘선배’의 정의는 단순 나이가 많아서가 아닌 자신보다 경험이 많은 사람을 의미한다. 그렇기에 자신보다 나이가 적은 사람이 멘토가 될 수도 있다고 생각한다.  -왜 멘토링을 해야할까?  ‘경험’이 정말 중요하고 홍수같이 쏟아지는 신기술을 온몸으로 받아내야 하는 우리 개발자들은 특히나 멘토링이 필요하다고 생각한다. 어떠한 기능을 만들어 내야 하는 상황이라 생각해 보자. 아주 일반적으로는 기능 개발에만 집중하다 보니 서비스 릴리즈시 검토해야 할 부분들을 생각하지 못하는 경우가 있다.

    Elastic Stack으로 코로나19 대시보드 만들기 - 2부 : 대시보드

    지난 포스팅에서는 데이터를 수급하며 전처리 과정을 거쳤고, Filebeat와 Logstash를 거쳐 Elasticsearch에 인덱싱 하는 것까지 알아보았다. 앞선 포스팅에서 이야기했지만 단순하게 데이터를 시각화 도구를 이용해서 대시보드를 만드는 게 아니라 데이터가 추가되면 만들어둔 대시보드에 자동으로 반영되는 흐름을 만들고 싶었다. 마침 파이프라인을 이틀 전에 만들었기 때문에 그동안의 빠진 데이터를 추가해야 하는 상황이다. 이 경우 Filebeat-Logstash-Elasticsearch 가 실행 중이라면 앞서 작성했던 파이썬 스크립트만 한번 실행해 주면 이틀 치 데이터가 파이프라인을 거쳐 Elasticsearch로 인덱싱이 된다. 즉, 별도로 데이터를 가져와서 재 가공하고 추가하는 다소 까다로운 작업이 미리 만들어둔 파이프라인 덕분에 한 번의 스크립트 실행으로 손쉽게 처리가 됨을 알 수 있다. - 이제는 쌓여있는 데이터를 가지고 시각화를 해볼 차례이다. ElasticStack에서는 Kibana라는 강력한 시각화 도구를 제공하는데 이번 포스팅에서는 Kibana를 이용해서 대시보드를 만드는 방법에 대해 알아보려 한다. -Visualize  Elasticsearch에 인덱싱 되어있는 데이터들은 기본으로 제공되는 REST API를 통해서 조회할 수 있고 JSON 형태로 결과가 나오기 때문에 이를 가지고 다양하게 시각화를 할 수도 있다. 하지만 Kibana에서는 데이터를 조회하고 UI로 표현하는 일련의 모든 행위를 클릭 몇 번으로 할 수 있게 해주기 때문에 전문가가 아니더라도 조금만 만져보면 누구나 만들 수 있다. -New Visualizaion!!" New Visualizaion!!  버전업이 되면서 비쥬얼라이즈를 만드는 첫 화면 또한 변화가 생겼다. 기존에는 어떤 유형의 비쥬얼라이즈를 선택할 것인지에 대해 선택하는 화면부터 나왔는데 만드는 걸 보다 편리하게 도와주는 Lens, TSVB 같은 기능들이 먼저 반겨준다. 이 기능을 통해서 만드는 방법도 괜찮지만 보다 명시적으로 만들고 싶으니 하단에 Aggregation based을 선택해서 원하는 비쥬얼라이즈의 타입을 선택해 보자. 이후 생성되어 있는 인덱스를 선택하면 본격적으로 비쥬얼라이즈를 그릴 수 있는 화면이 나오는데 대시보드 화면 기준으로 만들어야 할 항목별로 살펴보자. -전체 수 ." .  확진자, 사망자, 격리 해제의 총합을 표현하려 한다. 이렇게 ‘숫자’를 표현하려 하는 경우 Metric을 활용하곤 한다. 우측에서 Aggregation 방법을 ‘sum’으로 설정하고 필드는 유형별로 각각 선택해 주자. 아래 ‘Add’버튼을 눌러 확진, 사망, 격리 해제 수를 모두 표시한 다음 저장을 눌러준다. Label을 지정하지 않으면 어떤 형태로 Aggregation을 했는지를 Label 영역에 보여주는데 그게 보기 싫다면 원하는 텍스트로 지정해 주는 것도 방법이다. -최근 수 ." .  확진자, 사망자, 격리 해제의 ‘최근 데이터’를 보여주는 게 목적이다. 이 경우 Aggregation을 Top Hit으로 선택하면 필드를 선택할 수 있게 되는데 하루의 데이터가 총 18 row이기 때문에 (서울, 부산, …, 제주, 검역) 18 row 을 전부 더한 값이 하루 기준의 합계가 된다. 여기서 정렬을 날짜 기준 내림차순으로 해줘야 가장 최근 데이터의 합계가 되는 점도 신경 써야 한다. -각 타입별 합계 ." .  지역별로 타입별 수를 보기 위해 Pie 타입으로 선택하여 진행한다. 타입별(예로 들어 확진이면 confirmed)로 합계를 구하기 위해 Aggregation을 ‘sum’으로 설정하면 빈 원이 나오지만 각 지역별로 차트를 잘라서 봐야 하기에 하단의 Buckets의 Add를 누르고 regieon의 필드를 Terms Aggregation 한다. 18 row의 데이터가 전부 보여야 하기에 정렬 개수를 늘리고 option 탭에서 보는 취향에 알맞게 설정값들을 바꿔준다. -타입별 추이 ." .  확진, 사망, 격리 해제 중에 사망을 제외하고 나머지 둘은 데이터의 크기가 크고 변화량이 비슷하기 때문에 x축은 시간으로 설정해두고 사망은 막대로, 나머지 둘은 라인으로 한 화면에서 표현하면 이 3가지 데이터를 한눈에 보기 좋을 것 같았다. Vertical bar 을 선택하고 x축(Buckets > X-axis)은 데이터 타입인 convert_date로 설정한다. 다음으로 사망은 매일 몇 명 사망했는지 뚜렷하게 보기 위해 그냥 sum으로, 나머지 둘은 누적 합계가 더 의미 있어 보일 것 같아 Cumulative Sum으로 Aggregation을 한다.
    \ No newline at end of file +왜 멘토링을 해야할까?  ‘경험’이 정말 중요하고 홍수같이 쏟아지는 신기술을 온몸으로 받아내야 하는 우리 개발자들은 특히나 멘토링이 필요하다고 생각한다. 어떠한 기능을 만들어 내야 하는 상황이라 생각해 보자. 아주 일반적으로는 기능 개발에만 집중하다 보니 서비스 릴리즈시 검토해야 할 부분들을 생각하지 못하는 경우가 있다.
    \ No newline at end of file diff --git a/index.xml b/index.xml index 9fabd81f..f98c850a 100644 --- a/index.xml +++ b/index.xml @@ -1,4 +1,14 @@ -👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.io https://taetaetae.github.io/images/profile.pngenSun, 31 Dec 2023 15:26:10 +0900초보 시니어 개발자의 2023 리뷰https://taetaetae.github.io/posts/review-2023/Sun, 31 Dec 2023 15:26:10 +0900Authorhttps://taetaetae.github.io/posts/review-2023/ +👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.io https://taetaetae.github.io/images/profile.pngenSun, 07 Jan 2024 00:16:21 +0900그런 개발자로 괜찮은가 - '그룹 스터디' 편https://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/Sun, 07 Jan 2024 00:16:21 +0900Authorhttps://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/ + + 다양한 방식으로 스터디를 해왔다. 정말 많은 것을 배웠던 스터디도 있는가 반면에 지나고 보면 시간이 아까울 정도의 스터디도 있었던 것 같다. 직접 만들어 보기도 했고 참여도 해봤던 것 같다. 이런저런 경험들 끝에 작년 중순에 직접 만들었던 스터디 멤버와는 어느덧 반년을 넘어가고 있는데 바쁜 회사 생활을 하면서도 이제까지 지속할 수 있었던 노하우를 공유해 보고자 한다. +그룹 스터디 방식 인원  다 그런 건 아니지만 기존 회사 분들과 스터디를 할 때면 아무래도 원래 알던 사이라 바빠서 준비를 못 해오거나 불참을 하는 경우에 “그럴 수도 있지”, “괜찮아” 하며 관대해졌던 것 같다. 또는 다양한 의견을 듣자며 10명 이상 진행을 했던 것 같다. 그렇다 보니 스터디 진행에 집중도가 떨어질 수밖에 없었고 모였을 때 이야기하던 사람들만 이야기한다든지, 중도 하차하는 경험도 많았다. +블라인드 글에 첨부한 스터디 참여 설문" 블라인드 글에 첨부한 스터디 참여 설문  이번 스터디는 직접 ‘블라인드’라는 익명 커뮤니티를 통해 인원을 모았다. 작년 중순쯤 자바 백엔드 관련된 주제를 스터디 하겠다며 나와 비슷한 연차분들 위주로 모으겠다고 글을 작성했더니 신기하게도 3~40명 되는 분들이나 지원하셨고 그중 오프라인 모임을 고려해서 나 포함 6명 만으로 구성을 하였다.(뭔가 서류 전형 인사담당자가 된 느낌;;) 작은 규모 그리고 새로운 분들과 하게 되니 집중도가 오르는 경험을 할 수 있었고 무엇보다 6명 모두 다른 회사라 각 회사를 대표하는 것 같은 느낌이 들어 스터디 참여에 몰입이나 책임감이 더욱 올랐던 것 같다. 또한 한 주제에 대해 각 회사에서의 경험들을 이야기하다 보니 완전히 다른 시각을 얻을 수 있다는 장점도 있었다. + 별거 아닐 수도 있지만(또는 오해가 될 수도 있지만) 남녀 성비, 그리고 나이대(연차)를 최대한 맞추고 싶었다. 그래야 분위기가 적당히 딱딱하지도, 부드럽지도 않을 것 같았기 때문이다. 지금은 여자 한 분 나머지 남자분들이라 초반에 걱정도 되었지만 생각보다 분위기가 잘 흘러가서 다행이라 생각을 한다. +주제와 목표 배워야 할게 한도 끝도 없는 개발자 세상스터디 목표에 따라 집중해야 할 범위를 좁히자!" 배워야 할게 한도 끝도 없는 개발자 세상 +스터디 목표에 따라 집중해야 할 범위를 좁히자!  처음부터 모니터 받침으로 하기 좋을만한 두꺼운 책은 피했던 것 같다. 가볍게, 스터디원들끼리의 친밀도부터 올려야 한다는 생각으로 너무 딥 다이브 한 기술적인 내용보다는 누구나 한마디 정도 할 수 있을만한 가벼운 책부터 시작했다. 그러면서 최대한 참여도를 올리는데 집중했던 것 같다. + 어디까지나 “공부"를 하기 위한 모임이긴 하지만 이 또한 사람과 사람 사이의 “관계"가 중요하다고 생각했기에 모였을 때 바로 스터디 이야기를 하는 것보다 부드러운 아이스브레이킹을 자주 해왔다. 또한 너무 루즈 해지지 않게 1달~1달 반 정도로 끝날 수 있을만한 주제를 선정했다. 아무래도 한 주제가 2~3달 걸리다 보면 집중도가 떨어지는 경험이 많았기 때문이다. 책 한 권을 다 읽었다는 기간을 짧게 가져가면서 작은 성취의 효과를 최대한 활용하고 있다. 이번 회차가 벌써 네 번째인걸 보면 그래도 나름 잘 선택한 방법이라 생각이 든다. + 한 회차가 끝날 즈음엔 다음 스터디는 무엇을 할 것인지에 대해 이야기를 하고 다수가 동의하는 주제를 선정한다. 또한 매 회차가 끝날 때마다 어쩌면 어색할 수 있는 이야기지만 스터디 참여를 그만 둘지에 대해 의사를 분명히 물어본다. (그런데 신기하게도 지금 스터디 모임은 이런 이야기를 하기도 전에 스터디 하고 싶은 주제를 먼저 말씀해주시는 편이라, 어쩌면 스스로 사람 운이 좋다는 생각도 해본다.) + 그저 하나의 책을 읽기로 끝나는 “책 읽기 모임” 이 아닌 만큼 책을 기반으로 하는 스터디 모임일지라도 목표를 분명하게 잡는다. 여기서 목표는 개인마다 다를 수 있다. 가령 스터디 시간에 나왔던 내용을 각자의 팀에 공유 및 반영을 해본다든지, 스터디 내용에 대해 주도적으로 이야기를 하며 다른 분들의 지식을 훔쳐보겠다든지(?]]>초보 시니어 개발자의 2023 리뷰https://taetaetae.github.io/posts/review-2023/Sun, 31 Dec 2023 15:26:10 +0900Authorhttps://taetaetae.github.io/posts/review-2023/ 언제부터인가 새해가 되면 그 해의 키워드를 선정하고 해시태그처럼 달고 다니며 한 해를 보내온 것 같다. 작년의 키워드는 “한계”. 한정된 시간 속에서 하고 싶은 것도 많고 해야 할 것도 많은 나로서는 중요도에 따라 어쩔 수 없이 무언가를 포기하게 되는 순간들이 찾아왔다. 그럴 때마다 늘 어쩔 수 없다는 자기 가면을 쓴 채 정말 하고 싶던, 꼭 해야 할 것들임에도 불구하고 다음에 해야지 하고 넘어갔던 적이 많았다.  그렇게 시간을 보내니 아쉬움이 남게 되었고 잠을 줄여서라도 할 것 들을 하자며 나를 극한으로 몰아붙여보자는 의미로 작년의 키워드를 “한계"라고 정했고 정말 많은 것들을 경험할 수 있었다. 그렇게 나를 몰아붙이는 삶을 살다 보니 말 그대로 그저 “여러 가지만 했던” 한 해로 기억된다. (아마 그래서 작년 리뷰가 없던 이유일지도…?) @@ -85,13 +95,4 @@ https://api.telegram.org/bot{token}/getUpdates e.g. https://api.telegram.org/bot  그렇다면 멘티는 멘토를 어떻게 찾아야 할까? 함께 일하는 선배 동료가 있다면 정중하게 도움을 요청하는 것도 나쁘지 않다 본다. 단, 무작정 “저의 멘토가 되어주세요.“라는 것보다 자신이 가지고 있는 고민거리를 털어놓으며 조금씩 친분을 쌓아간다면 아무래도 경험이 많은 선배이기에 고민의 범위를 조금이라도 줄여줄 수 있지 않을까. 혹여 주변에 선배 동료가 없다면 온/오프라인 커뮤니티 활동을 하면서 찾는 것도 방법이다. 메신저를 통해 다가가거나 메일로 정중하게 고민을 요약해서 보내놓으면 당장은 아니더라도 가까운 시일 내에 응답이 오기 마련이다. (적어도 괜찮은 선배라면.)  여기서 말하는 ‘선배’의 정의는 단순 나이가 많아서가 아닌 자신보다 경험이 많은 사람을 의미한다. 그렇기에 자신보다 나이가 적은 사람이 멘토가 될 수도 있다고 생각한다.  -왜 멘토링을 해야할까?  ‘경험’이 정말 중요하고 홍수같이 쏟아지는 신기술을 온몸으로 받아내야 하는 우리 개발자들은 특히나 멘토링이 필요하다고 생각한다. 어떠한 기능을 만들어 내야 하는 상황이라 생각해 보자. 아주 일반적으로는 기능 개발에만 집중하다 보니 서비스 릴리즈시 검토해야 할 부분들을 생각하지 못하는 경우가 있다.]]>Elastic Stack으로 코로나19 대시보드 만들기 - 2부 : 대시보드https://taetaetae.github.io/posts/make-dashboards-from-elasticstack-2/Wed, 17 Feb 2021 16:53:49 +0900Authorhttps://taetaetae.github.io/posts/make-dashboards-from-elasticstack-2/ - - 지난 포스팅에서는 데이터를 수급하며 전처리 과정을 거쳤고, Filebeat와 Logstash를 거쳐 Elasticsearch에 인덱싱 하는 것까지 알아보았다. 앞선 포스팅에서 이야기했지만 단순하게 데이터를 시각화 도구를 이용해서 대시보드를 만드는 게 아니라 데이터가 추가되면 만들어둔 대시보드에 자동으로 반영되는 흐름을 만들고 싶었다. 마침 파이프라인을 이틀 전에 만들었기 때문에 그동안의 빠진 데이터를 추가해야 하는 상황이다. 이 경우 Filebeat-Logstash-Elasticsearch 가 실행 중이라면 앞서 작성했던 파이썬 스크립트만 한번 실행해 주면 이틀 치 데이터가 파이프라인을 거쳐 Elasticsearch로 인덱싱이 된다. 즉, 별도로 데이터를 가져와서 재 가공하고 추가하는 다소 까다로운 작업이 미리 만들어둔 파이프라인 덕분에 한 번의 스크립트 실행으로 손쉽게 처리가 됨을 알 수 있다. - 이제는 쌓여있는 데이터를 가지고 시각화를 해볼 차례이다. ElasticStack에서는 Kibana라는 강력한 시각화 도구를 제공하는데 이번 포스팅에서는 Kibana를 이용해서 대시보드를 만드는 방법에 대해 알아보려 한다. -Visualize  Elasticsearch에 인덱싱 되어있는 데이터들은 기본으로 제공되는 REST API를 통해서 조회할 수 있고 JSON 형태로 결과가 나오기 때문에 이를 가지고 다양하게 시각화를 할 수도 있다. 하지만 Kibana에서는 데이터를 조회하고 UI로 표현하는 일련의 모든 행위를 클릭 몇 번으로 할 수 있게 해주기 때문에 전문가가 아니더라도 조금만 만져보면 누구나 만들 수 있다. -New Visualizaion!!" New Visualizaion!!  버전업이 되면서 비쥬얼라이즈를 만드는 첫 화면 또한 변화가 생겼다. 기존에는 어떤 유형의 비쥬얼라이즈를 선택할 것인지에 대해 선택하는 화면부터 나왔는데 만드는 걸 보다 편리하게 도와주는 Lens, TSVB 같은 기능들이 먼저 반겨준다. 이 기능을 통해서 만드는 방법도 괜찮지만 보다 명시적으로 만들고 싶으니 하단에 Aggregation based을 선택해서 원하는 비쥬얼라이즈의 타입을 선택해 보자. 이후 생성되어 있는 인덱스를 선택하면 본격적으로 비쥬얼라이즈를 그릴 수 있는 화면이 나오는데 대시보드 화면 기준으로 만들어야 할 항목별로 살펴보자. -전체 수 ." .  확진자, 사망자, 격리 해제의 총합을 표현하려 한다. 이렇게 ‘숫자’를 표현하려 하는 경우 Metric을 활용하곤 한다. 우측에서 Aggregation 방법을 ‘sum’으로 설정하고 필드는 유형별로 각각 선택해 주자. 아래 ‘Add’버튼을 눌러 확진, 사망, 격리 해제 수를 모두 표시한 다음 저장을 눌러준다. Label을 지정하지 않으면 어떤 형태로 Aggregation을 했는지를 Label 영역에 보여주는데 그게 보기 싫다면 원하는 텍스트로 지정해 주는 것도 방법이다. -최근 수 ." .  확진자, 사망자, 격리 해제의 ‘최근 데이터’를 보여주는 게 목적이다. 이 경우 Aggregation을 Top Hit으로 선택하면 필드를 선택할 수 있게 되는데 하루의 데이터가 총 18 row이기 때문에 (서울, 부산, …, 제주, 검역) 18 row 을 전부 더한 값이 하루 기준의 합계가 된다. 여기서 정렬을 날짜 기준 내림차순으로 해줘야 가장 최근 데이터의 합계가 되는 점도 신경 써야 한다. -각 타입별 합계 ." .  지역별로 타입별 수를 보기 위해 Pie 타입으로 선택하여 진행한다. 타입별(예로 들어 확진이면 confirmed)로 합계를 구하기 위해 Aggregation을 ‘sum’으로 설정하면 빈 원이 나오지만 각 지역별로 차트를 잘라서 봐야 하기에 하단의 Buckets의 Add를 누르고 regieon의 필드를 Terms Aggregation 한다. 18 row의 데이터가 전부 보여야 하기에 정렬 개수를 늘리고 option 탭에서 보는 취향에 알맞게 설정값들을 바꿔준다. -타입별 추이 ." .  확진, 사망, 격리 해제 중에 사망을 제외하고 나머지 둘은 데이터의 크기가 크고 변화량이 비슷하기 때문에 x축은 시간으로 설정해두고 사망은 막대로, 나머지 둘은 라인으로 한 화면에서 표현하면 이 3가지 데이터를 한눈에 보기 좋을 것 같았다. Vertical bar 을 선택하고 x축(Buckets > X-axis)은 데이터 타입인 convert_date로 설정한다. 다음으로 사망은 매일 몇 명 사망했는지 뚜렷하게 보기 위해 그냥 sum으로, 나머지 둘은 누적 합계가 더 의미 있어 보일 것 같아 Cumulative Sum으로 Aggregation을 한다.]]> \ No newline at end of file +왜 멘토링을 해야할까?  ‘경험’이 정말 중요하고 홍수같이 쏟아지는 신기술을 온몸으로 받아내야 하는 우리 개발자들은 특히나 멘토링이 필요하다고 생각한다. 어떠한 기능을 만들어 내야 하는 상황이라 생각해 보자. 아주 일반적으로는 기능 개발에만 집중하다 보니 서비스 릴리즈시 검토해야 할 부분들을 생각하지 못하는 경우가 있다.]]> \ No newline at end of file diff --git a/page/10/index.html b/page/10/index.html index 6910995c..b5fa006d 100644 --- a/page/10/index.html +++ b/page/10/index.html @@ -1,5 +1,7 @@ -👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    Spring Transactional 설정 및 주요속성

    지난번에는 트랜잭션의 설정값에 대해 알아본 바 있다. [ Spring Transaction 옵션 ] 이번 포스팅에서는 실제로 스프링 환경에서 어떤식으로 설정해야 @Transactional 어노테이션을 사용할수 있는지, 그리고 어떤 속성들이 있는지에 대해 알아보고자 한다.설정 기존 xml방식에서는 다음과 같이 설정을 한다. +👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    자바 8 Date

    이제까지 내 기억으로는 Date 관련 클래스를 아래처럼 점차 바꿔써온걸로 기억이 난다. java.util.Date > java.util.Calendar > org.joda.time 그런데 java 8 버전에서 기존에 있었던 문제들을 개선해서 나왔다고 한다. (네이버 HellowWorld 포스팅 참고) JSR-310 이라는 표준명세로. +지금부터는 JAVA 8 에서 제공하는 API로 날짜 연산을 어떻게 하는지에 대해 알아보고자 한다. (물론 수많은 날짜 연산 방법을이 있지만 자주 쓰이는 부분들 위주로 정리해보자.) +Date > String (format) LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); String > Date (format) LocalDateTime.parse("2017-01-01 12:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 날짜/시간 증감 LocalDateTime localDateTime = LocalDateTime.of(2017, 1, 1, 10, 0, 0); localDateTime.plusDays(1); // 일 localDateTime.plusMonths(1); // 월 localDateTime.plusHours(1); // 시간 localDateTime.plusWeeks(1); // 주 localDateTime.minusYears(1); // 년 localDateTime.minusMinutes(1); // 분 더 다양한 내용들은 아래 URL 에서 확인이 가능하다. https://docs.oracle.com/javase/tutorial/datetime/iso/overview.html

    Spring Transactional 설정 및 주요속성

    지난번에는 트랜잭션의 설정값에 대해 알아본 바 있다. [ Spring Transaction 옵션 ] 이번 포스팅에서는 실제로 스프링 환경에서 어떤식으로 설정해야 @Transactional 어노테이션을 사용할수 있는지, 그리고 어떤 속성들이 있는지에 대해 알아보고자 한다.설정 기존 xml방식에서는 다음과 같이 설정을 한다. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> 혹, JavaConfig 방식으로 설정하기 위해서는 다음과 같이 설정한다. @EnableTransactionManagement public class AppConfig { ... @Bean public PlatformTransactionManager transactionManager() throws URISyntaxException, GeneralSecurityException, ParseException, IOException { return new DataSourceTransactionManager(dataSource()); } } 위와같이 설정을 해주면 트랜잭션을 설정하고자 하는 곳 어디서든 @Transactional 어노테이션을 지정해서 적용이 가능하다. public class UserService{ @Transactional public boolean insertUser(User user){ ... } } 주요속성 @Transactional 어노테이션의 주요속성은 다음과 같다. @@ -71,4 +73,4 @@ # Deployment deploy: type: git repo: https://github.com/taetaetae/taetaetae.github.io branch: master 그 다음 hexo 에서 github로 배포할수있는 플러그인을 설치해준다. $ npm install hexo-deployer-git --save 이제 설정한 github에 배포를 하면 끝! $ hexo deploy 1분~3분 뒤에 도메인을 접속하여 정상적으로 페이지가 나오는지 확인하고, github에 파일들이 push가 잘 되었는지를 확인한다. -향후 관리 hexo 정보 저장 나중에 다른 PC에서도 블로그를 포스팅 할 경우가 있으니 hexo를 이용하여 포스팅 한 환경 자체를 저장 해야할 필요가 생겼다. 따라서 만들었던 폴더 또한 github에 업로드를 해놓는게 좋을것 같다 (지극히 개인적인 생각) git command 설명은 따로 정리하지 않겠다.

    첫번째 포스팅

    시작은 언제든지 새롭고 떨리고 가슴벅차는 순간이다. 과연 이 블로그를 잘 운영할수 있을런지.. 제대로 한번 관리 해보고, 나만의 공간으로 꾸며보자!
    \ No newline at end of file +향후 관리 hexo 정보 저장 나중에 다른 PC에서도 블로그를 포스팅 할 경우가 있으니 hexo를 이용하여 포스팅 한 환경 자체를 저장 해야할 필요가 생겼다. 따라서 만들었던 폴더 또한 github에 업로드를 해놓는게 좋을것 같다 (지극히 개인적인 생각) git command 설명은 따로 정리하지 않겠다.
    \ No newline at end of file diff --git a/page/11/index.html b/page/11/index.html new file mode 100644 index 00000000..2a623b58 --- /dev/null +++ b/page/11/index.html @@ -0,0 +1,2 @@ +👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    첫번째 포스팅

    시작은 언제든지 새롭고 떨리고 가슴벅차는 순간이다. 과연 이 블로그를 잘 운영할수 있을런지.. 제대로 한번 관리 해보고, 나만의 공간으로 꾸며보자!
    \ No newline at end of file diff --git a/page/2/index.html b/page/2/index.html index 504f9eaf..e0aea9e0 100644 --- a/page/2/index.html +++ b/page/2/index.html @@ -1,5 +1,12 @@ -👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    Elastic Stack으로 코로나19 대시보드 만들기 - 1부 : 파이프라인 구성

     얼마 전에 필자의 블로그를 보고 어느 교육 기관에서 ElasticStack에 대한 강의 요청이 들어왔다. 사실 관련 기술에 대해 지식이 아주 깊고 해박한 게 아니라서 약간의 반감부터 들었지만 ElasticStack을 전혀 모르는 사람들 기준으로 어떻게 돌아가는지에 대해서만 간단하게 소개하는 정도로 하면 된다고 하여 조심스럽지만 떨리는 마음으로 열심히 준비를 하기 시작했다. 그런데, 이런저런 이유로 갑자기 강의를 할 수 없게 되었고 그간 준비했던 내용들이 너무 아쉽지만 아무 소용이 없게 되어버렸다. 그냥 중단하기엔 아쉬운 마음이 너무 커서 준비했던 내용 중에 ‘데이터를 가지고 대시보드를 만드는 부분’은 누군가에겐 도움이 될까 싶어 블로그에 정리를 해보려 한다. +👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    Elastic Stack으로 코로나19 대시보드 만들기 - 2부 : 대시보드

    지난 포스팅에서는 데이터를 수급하며 전처리 과정을 거쳤고, Filebeat와 Logstash를 거쳐 Elasticsearch에 인덱싱 하는 것까지 알아보았다. 앞선 포스팅에서 이야기했지만 단순하게 데이터를 시각화 도구를 이용해서 대시보드를 만드는 게 아니라 데이터가 추가되면 만들어둔 대시보드에 자동으로 반영되는 흐름을 만들고 싶었다. 마침 파이프라인을 이틀 전에 만들었기 때문에 그동안의 빠진 데이터를 추가해야 하는 상황이다. 이 경우 Filebeat-Logstash-Elasticsearch 가 실행 중이라면 앞서 작성했던 파이썬 스크립트만 한번 실행해 주면 이틀 치 데이터가 파이프라인을 거쳐 Elasticsearch로 인덱싱이 된다. 즉, 별도로 데이터를 가져와서 재 가공하고 추가하는 다소 까다로운 작업이 미리 만들어둔 파이프라인 덕분에 한 번의 스크립트 실행으로 손쉽게 처리가 됨을 알 수 있다. + 이제는 쌓여있는 데이터를 가지고 시각화를 해볼 차례이다. ElasticStack에서는 Kibana라는 강력한 시각화 도구를 제공하는데 이번 포스팅에서는 Kibana를 이용해서 대시보드를 만드는 방법에 대해 알아보려 한다. +Visualize  Elasticsearch에 인덱싱 되어있는 데이터들은 기본으로 제공되는 REST API를 통해서 조회할 수 있고 JSON 형태로 결과가 나오기 때문에 이를 가지고 다양하게 시각화를 할 수도 있다. 하지만 Kibana에서는 데이터를 조회하고 UI로 표현하는 일련의 모든 행위를 클릭 몇 번으로 할 수 있게 해주기 때문에 전문가가 아니더라도 조금만 만져보면 누구나 만들 수 있다. +New Visualizaion!!" New Visualizaion!!  버전업이 되면서 비쥬얼라이즈를 만드는 첫 화면 또한 변화가 생겼다. 기존에는 어떤 유형의 비쥬얼라이즈를 선택할 것인지에 대해 선택하는 화면부터 나왔는데 만드는 걸 보다 편리하게 도와주는 Lens, TSVB 같은 기능들이 먼저 반겨준다. 이 기능을 통해서 만드는 방법도 괜찮지만 보다 명시적으로 만들고 싶으니 하단에 Aggregation based을 선택해서 원하는 비쥬얼라이즈의 타입을 선택해 보자. 이후 생성되어 있는 인덱스를 선택하면 본격적으로 비쥬얼라이즈를 그릴 수 있는 화면이 나오는데 대시보드 화면 기준으로 만들어야 할 항목별로 살펴보자. +전체 수 ." .  확진자, 사망자, 격리 해제의 총합을 표현하려 한다. 이렇게 ‘숫자’를 표현하려 하는 경우 Metric을 활용하곤 한다. 우측에서 Aggregation 방법을 ‘sum’으로 설정하고 필드는 유형별로 각각 선택해 주자. 아래 ‘Add’버튼을 눌러 확진, 사망, 격리 해제 수를 모두 표시한 다음 저장을 눌러준다. Label을 지정하지 않으면 어떤 형태로 Aggregation을 했는지를 Label 영역에 보여주는데 그게 보기 싫다면 원하는 텍스트로 지정해 주는 것도 방법이다. +최근 수 ." .  확진자, 사망자, 격리 해제의 ‘최근 데이터’를 보여주는 게 목적이다. 이 경우 Aggregation을 Top Hit으로 선택하면 필드를 선택할 수 있게 되는데 하루의 데이터가 총 18 row이기 때문에 (서울, 부산, …, 제주, 검역) 18 row 을 전부 더한 값이 하루 기준의 합계가 된다. 여기서 정렬을 날짜 기준 내림차순으로 해줘야 가장 최근 데이터의 합계가 되는 점도 신경 써야 한다. +각 타입별 합계 ." .  지역별로 타입별 수를 보기 위해 Pie 타입으로 선택하여 진행한다. 타입별(예로 들어 확진이면 confirmed)로 합계를 구하기 위해 Aggregation을 ‘sum’으로 설정하면 빈 원이 나오지만 각 지역별로 차트를 잘라서 봐야 하기에 하단의 Buckets의 Add를 누르고 regieon의 필드를 Terms Aggregation 한다. 18 row의 데이터가 전부 보여야 하기에 정렬 개수를 늘리고 option 탭에서 보는 취향에 알맞게 설정값들을 바꿔준다. +타입별 추이 ." .  확진, 사망, 격리 해제 중에 사망을 제외하고 나머지 둘은 데이터의 크기가 크고 변화량이 비슷하기 때문에 x축은 시간으로 설정해두고 사망은 막대로, 나머지 둘은 라인으로 한 화면에서 표현하면 이 3가지 데이터를 한눈에 보기 좋을 것 같았다. Vertical bar 을 선택하고 x축(Buckets > X-axis)은 데이터 타입인 convert_date로 설정한다. 다음으로 사망은 매일 몇 명 사망했는지 뚜렷하게 보기 위해 그냥 sum으로, 나머지 둘은 누적 합계가 더 의미 있어 보일 것 같아 Cumulative Sum으로 Aggregation을 한다.

    Elastic Stack으로 코로나19 대시보드 만들기 - 1부 : 파이프라인 구성

     얼마 전에 필자의 블로그를 보고 어느 교육 기관에서 ElasticStack에 대한 강의 요청이 들어왔다. 사실 관련 기술에 대해 지식이 아주 깊고 해박한 게 아니라서 약간의 반감부터 들었지만 ElasticStack을 전혀 모르는 사람들 기준으로 어떻게 돌아가는지에 대해서만 간단하게 소개하는 정도로 하면 된다고 하여 조심스럽지만 떨리는 마음으로 열심히 준비를 하기 시작했다. 그런데, 이런저런 이유로 갑자기 강의를 할 수 없게 되었고 그간 준비했던 내용들이 너무 아쉽지만 아무 소용이 없게 되어버렸다. 그냥 중단하기엔 아쉬운 마음이 너무 커서 준비했던 내용 중에 ‘데이터를 가지고 대시보드를 만드는 부분’은 누군가에겐 도움이 될까 싶어 블로그에 정리를 해보려 한다. 강의를 준비한 올해 1월 중순엔 Elasticsearch 버전이 7.10.2이었는데 블로그를 쓰고 있는 지금은 벌써 7.11으로 버전 업 되었다. 내가 아는 오픈소스 중에 버전업이 가장 빠른데 그렇다고 기능이 확 바뀌거나 습득하기 어렵게 바뀌진 않았다. 그만큼 사용자가 무엇을 원하는지 명확히 알고 작은 단위로 조금씩 바뀌어 가는 모습이 꽤 인상적이다.  작년 초부터 코로나19 바이러스가 전 세계적으로 퍼지기 시작했고 아직까지도 진행 중이다. 나도 전염되는 건 아닐까 하는 두려움에 어디에서 얼마나 발생했는지를 확인하기 어렵던 시절 우리나라의 뛰어난 개발자들은 누가 시키지도 않았는데 정말 감사하게도 그 현황을 한눈에 볼 수 있도록 여러 유형으로 코로나19 바이러스 대시보드를 만들기 시작한다. 그 덕분에 좀 더 현황을 보기에 편해졌고 더욱 조심하게 되는 계기가 되었다고 생각한다. 이제는 포털사이트나 각종 매체를 통해 손쉽게 코로나19 바이러스의 현황을 볼 수 있지만 이러한 데이터를 가지고 검색엔진이지만 대시보드를 구축하는데 훌륭한 기능을 가지고 있는 ElasticStack을 활용해서 ‘나만의 대시보드’를 만드는 걸 정리해보고자 한다. 본 포스팅의 일회성으로 데이터를 가지고 대시보드를 만드는 것에서 끝나는 게 아니라 지속적으로 데이터가 업데이트된다는 가정하에 전반적인 “파이프라인"을 구축한 뒤 대시보드를 만들어 두고 데이터만 갱신하면 자동으로 대시보드 또한 업데이트되는 것을 목적으로 한다. 전체 흐름" 전체 흐름 글을 모두 작성하고 보니 양이 생각보다 길어져서 데이터를 조회하고 필터링하여 Elasticsearch에 인덱싱 하는 대시보드를 만들기 위한 일종의 “데이터 파이프라인"을 구성하는 부분과 만들어진 데이터 기반으로 Kibana의 다양한 기능을 활용하여 대시보드를 만드는 2개의 포스팅으로 나누어 정리해보겠다. @@ -83,14 +90,4 @@ 필자가 꿈나무 시절때 나누었던 조직장님과의 대화 내용" 필자가 꿈나무 시절때 나누었던 조직장님과의 대화 내용  아직까지도 기억에 남아있는 예전 조직 장님과의 대화. 일단 로그는 최대한 많이 (과하게) 남겨야 한다고 생각한다. 그다음 불필요한 로그들은 제거하거나 레벨을 낮추는 등 상황에 맞도록 커스터마이징이 필요하다. 경험을 해보면 알겠지만 운영환경에 애플리케이션을 배포하고 서비스를 운영하다 보면 개발 환경에서 만나기 어렵거나 경험해보지 못한 상황이 발생하곤 한다. 이럴 때 상황에 맞는 로그들이 있다면 미리 남겨둔 로그를 통해 더 효과적으로 상황을 파악할 수 있다. 트래픽의 정보(request url, parameter, UA, remote ip 등)를 남겨서 외부에서 호출하는 형태를 분석하는데 활용할 수도 있고, 애플리케이션에서 외부로 호출을 하고 난 뒤에 받는 응답에 대해서 로그를 남겨두면 외부 통신의 오류를 파악하는 데 도움이 될 수 있다. 어떤 로그를 남겨야 하는가에 대한 고민은 운영하는 애플리케이션이 어떤 행동을 하는가에 관점을 두고 고민해보면 좀 더 쉽게 찾을 수 있을 것이라 생각한다.  로그를 남기는 방법 또한 다양하다. 시스템 로컬에 파일로 남기거나 특정 로그 서버를 설정하여 여러 대의 서버 로그를 한곳에서 볼 수도 있다. 다만 로그를 ‘남기는’ 것 또한 하나의 비용에 포함되기 때문에 애플리케이션의 기능에 최대한 영향이 가지 않도록 최대한 빠른 시간 내에 처리가 되도록 해야 한다. (혹은 비동기로 남기거나 등)  로그를 남기는 이유 중 가장 큰 이유는 ‘나중에 보기 위해서’이다. 그만큼 한번 로그를 남길 때에도 보기 좋게 남겨야 한다. 예컨대, 아래에 적어놓은 로그 방식의 경우 작은 차이지만 나중에 볼 때 꽤 큰 차이를 유발한다.  -안좋은 예 try { ... } catch (Exception e){ log.Error(e); // 어떤 상황이지..? } 보다 조금 더 좋은 예 try { ... } catch (Exception e){ log.Error("url : " + url + ", parameter : " + parameter + ", remote ip : " + remoteIp, e); // 로그는 가급적 자세하게 ! } 로그가 가져다 주는 또 다른 세상  로그는 또 다른 데이터가 될 수 있다.

    빌드/테스트는 내가 해줄게. 너는 코딩에 집중해 (by GitHub Pull Request Builder)

    git 은 분산 버전 관리 시스템 중 가장 잘 알려져 있다고 해도 과언이 아닐 정도로 대부분의 시스템에서 사용되고 있는 것 같다. 이를 웹서비스에서 보다 편하게 사용할 수 있도록 한 시스템이 Github. Github 을 사용하는 이유 중에 가장 큰 이유를 하나만 이야기해보자면 바로 온라인상에서 코드 리뷰를 할 수 있는 pullRequest라는 기능 때문이 아닐까 조심스럽게 생각을 해본다. - pullRequest는 work branch에서 작업한 내용을 base branch로 merge 전 꼭 코드 리뷰가 아니더라도 작업한 내용에 대해서 다양한 검사를 자동화할 수 있는 강력한 기능들이 많다. 이러한 자동화는 CI(지속적 통합) 관점에서 매우 중요한데 코드에 대해 체크해야 할 부분들(빌드, 테스트, 정적 분석 등)을 “알아서” 해준다면 작업자는 오롯이 비즈니스 로직 개발에 대해서만 신경 쓸 수 있으니 생산성 절약 측면에서 엄청난 효과를 볼 수 있다. -내가 하는일에만 집중할 수 있게! 출처 : https://www.clien.net/service/board/park/10453442" 내가 하는일에만 집중할 수 있게! 출처 : https://www.clien.net/service/board/park/10453442 이번 포스팅에서는 그중에서도 아주 간단한 설정만으로 work branch의 빌드 상태를 검사해 볼 수 있는 Jenkins의 Github Pull Request Builder를 설치 및 활용해 보고자 한다. -사실 최근 팀에서 CI 서버를 이전해야 했었다. 머릿속에서는 어떻게 하면 되겠지 싶었지만 막상 해보려니 Jenkins 버전업도 되었고 뭐부터 해야 할지 허둥대는 필자가 부끄러웠다. 이참에 정리를 해보며 다시 한번 리마인드 하는 시간을 가져보고자 한다. (이래서 기억보다 기록이 중요하다.) -준비물  전체적인 흐름은 아래 그림처럼 흘러가기 때문에 당연히 서버에 Jenkins 가 설치되어 있어야 한다. Jenkins 설치는 필자의 포스팅(Jenkins 설치 치트키)를 참고해 보는 것도 좋을 것 같다. -전체적인 흐름" 전체적인 흐름  참고로 필자는 GitHub Enterprise 버전에서 사용했는데 일반 Github에서도 동일한 방법으로 사용 가능하다. -Github과 Jenkins의 연동을 위한 2가지 설정  Github 과 Jenkins 가 통신이 되도록 설정해 줘야 한다. 그래야 Github의 코드를 받아서 Jenkins 가 빌드를 하고 그 빌드 결과를 다시 Github에 리포트가 가능해지기 때문이다. 먼저 첫 번째로 ssh 설정으로 Github의 코드를 가져오도록 ssh 설정을 해두자. ssh 설정하는 방법은 필자의 포스팅(Github과 Jenkins 연동하기)편을 확인해보면 될 것 같다. - 그다음으로 아래에서 이야기할 GitHub Pull Request Builder라는 Jenkins plugin 이 빌드가 끝난 뒤에 결과를 리포팅 해줄 수 있는 인증 토큰을 발급받아두자. Github > Settings > Developer settings > Personal access tokens 화면에서 키를 생성하고 만들어진 키를 저장해 둔다. (이 키는 보안에 유의해야 하고, 화면 경고(?)에서도 볼 수 있듯이 키는 생성 시 한 번밖에 볼 수 없기 때문에 미리 저장해 둬야 한다.) -인증토큰을 미리 받아두자." 인증토큰을 미리 받아두자. Jenkins 설정  Jenkins > 관리 > pluginManager에 들어가 GitHub Pull Request Builder를 검색 후 설치해 준다. 그러고 나서 Jenkins > 관리 > 환경설정에 들어가 보면 아래와 같이 GitHub Pull Request Builder 항목이 생긴 것을 확인할 수 있고 위에서 설정한 인증토큰을 아래처럼 등록 후 저장을 한다. -credentials 을 위에서 발급받은 인증토큰으로 등록해준다." credentials 을 위에서 발급받은 인증토큰으로 등록해준다.  Jenkins job을 하나 만들고 pullRequest 가 발생했을 때 자동으로 실행될 수 있도록 설정을 해준다. 먼저 General 탭에 Github project에 Github url 을 적어주고 - 소스 코드 관리 탭에서 ssh 주소를 적고 위에서 미리 설정한 ssh 키로 credentials 값을 넣어준다. 전에도 이야기했지만 이 부분에서 오류가 발생하면 빨간색 글씨로 오류 내용이 나오고 아래 화면처럼 오류가 없다면 아무것도 안 나온다. Refspec 에 +refs/pull/*:refs/remotes/origin/pr/* 라고 적어주고 브랜치 설정은 파라미터로 받아와서 pullRequest를 발생시킨 브랜치를 빌드 할 수 있도록 ${sha1} 라고 적어주자.
    \ No newline at end of file +안좋은 예 try { ... } catch (Exception e){ log.Error(e); // 어떤 상황이지..? } 보다 조금 더 좋은 예 try { ... } catch (Exception e){ log.Error("url : " + url + ", parameter : " + parameter + ", remote ip : " + remoteIp, e); // 로그는 가급적 자세하게 ! } 로그가 가져다 주는 또 다른 세상  로그는 또 다른 데이터가 될 수 있다.
    \ No newline at end of file diff --git a/page/3/index.html b/page/3/index.html index c10ccee7..c4a6c6f0 100644 --- a/page/3/index.html +++ b/page/3/index.html @@ -1,5 +1,15 @@ -👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    벌써 2년 (feat. 토이프로젝트 회고,가치,수입)

    정확히 2018년 07월 12일 필자의 첫 토이 프로젝트인 ‘기술 블로그 구독 서비스’를 오픈하게 된다. 얼마나 많이 구독(가입) 하겠어 하는 생각이 부끄러울 만큼 6개월이 지나 구독자 수는 1,000명을 넘기고 1년이 지나 2,000명.어느덧 달력을 보니 오늘이 정확하게 토이 프로젝트를 서비스한지 벌써 2년이 되는 날. 구독자 수는 어느덧 3,000명을 넘어선다. 뭔가 뿌듯하면서도 서비스를 좀 더 디벨롭 하지 못한 필자 자신을 돌아보니 괜히 마음이 무거워지고. +👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    빌드/테스트는 내가 해줄게. 너는 코딩에 집중해 (by GitHub Pull Request Builder)

    git 은 분산 버전 관리 시스템 중 가장 잘 알려져 있다고 해도 과언이 아닐 정도로 대부분의 시스템에서 사용되고 있는 것 같다. 이를 웹서비스에서 보다 편하게 사용할 수 있도록 한 시스템이 Github. Github 을 사용하는 이유 중에 가장 큰 이유를 하나만 이야기해보자면 바로 온라인상에서 코드 리뷰를 할 수 있는 pullRequest라는 기능 때문이 아닐까 조심스럽게 생각을 해본다. + pullRequest는 work branch에서 작업한 내용을 base branch로 merge 전 꼭 코드 리뷰가 아니더라도 작업한 내용에 대해서 다양한 검사를 자동화할 수 있는 강력한 기능들이 많다. 이러한 자동화는 CI(지속적 통합) 관점에서 매우 중요한데 코드에 대해 체크해야 할 부분들(빌드, 테스트, 정적 분석 등)을 “알아서” 해준다면 작업자는 오롯이 비즈니스 로직 개발에 대해서만 신경 쓸 수 있으니 생산성 절약 측면에서 엄청난 효과를 볼 수 있다. +내가 하는일에만 집중할 수 있게! 출처 : https://www.clien.net/service/board/park/10453442" 내가 하는일에만 집중할 수 있게! 출처 : https://www.clien.net/service/board/park/10453442 이번 포스팅에서는 그중에서도 아주 간단한 설정만으로 work branch의 빌드 상태를 검사해 볼 수 있는 Jenkins의 Github Pull Request Builder를 설치 및 활용해 보고자 한다. +사실 최근 팀에서 CI 서버를 이전해야 했었다. 머릿속에서는 어떻게 하면 되겠지 싶었지만 막상 해보려니 Jenkins 버전업도 되었고 뭐부터 해야 할지 허둥대는 필자가 부끄러웠다. 이참에 정리를 해보며 다시 한번 리마인드 하는 시간을 가져보고자 한다. (이래서 기억보다 기록이 중요하다.) +준비물  전체적인 흐름은 아래 그림처럼 흘러가기 때문에 당연히 서버에 Jenkins 가 설치되어 있어야 한다. Jenkins 설치는 필자의 포스팅(Jenkins 설치 치트키)를 참고해 보는 것도 좋을 것 같다. +전체적인 흐름" 전체적인 흐름  참고로 필자는 GitHub Enterprise 버전에서 사용했는데 일반 Github에서도 동일한 방법으로 사용 가능하다. +Github과 Jenkins의 연동을 위한 2가지 설정  Github 과 Jenkins 가 통신이 되도록 설정해 줘야 한다. 그래야 Github의 코드를 받아서 Jenkins 가 빌드를 하고 그 빌드 결과를 다시 Github에 리포트가 가능해지기 때문이다. 먼저 첫 번째로 ssh 설정으로 Github의 코드를 가져오도록 ssh 설정을 해두자. ssh 설정하는 방법은 필자의 포스팅(Github과 Jenkins 연동하기)편을 확인해보면 될 것 같다. + 그다음으로 아래에서 이야기할 GitHub Pull Request Builder라는 Jenkins plugin 이 빌드가 끝난 뒤에 결과를 리포팅 해줄 수 있는 인증 토큰을 발급받아두자. Github > Settings > Developer settings > Personal access tokens 화면에서 키를 생성하고 만들어진 키를 저장해 둔다. (이 키는 보안에 유의해야 하고, 화면 경고(?)에서도 볼 수 있듯이 키는 생성 시 한 번밖에 볼 수 없기 때문에 미리 저장해 둬야 한다.) +인증토큰을 미리 받아두자." 인증토큰을 미리 받아두자. Jenkins 설정  Jenkins > 관리 > pluginManager에 들어가 GitHub Pull Request Builder를 검색 후 설치해 준다. 그러고 나서 Jenkins > 관리 > 환경설정에 들어가 보면 아래와 같이 GitHub Pull Request Builder 항목이 생긴 것을 확인할 수 있고 위에서 설정한 인증토큰을 아래처럼 등록 후 저장을 한다. +credentials 을 위에서 발급받은 인증토큰으로 등록해준다." credentials 을 위에서 발급받은 인증토큰으로 등록해준다.  Jenkins job을 하나 만들고 pullRequest 가 발생했을 때 자동으로 실행될 수 있도록 설정을 해준다. 먼저 General 탭에 Github project에 Github url 을 적어주고 + 소스 코드 관리 탭에서 ssh 주소를 적고 위에서 미리 설정한 ssh 키로 credentials 값을 넣어준다. 전에도 이야기했지만 이 부분에서 오류가 발생하면 빨간색 글씨로 오류 내용이 나오고 아래 화면처럼 오류가 없다면 아무것도 안 나온다. Refspec 에 +refs/pull/*:refs/remotes/origin/pr/* 라고 적어주고 브랜치 설정은 파라미터로 받아와서 pullRequest를 발생시킨 브랜치를 빌드 할 수 있도록 ${sha1} 라고 적어주자.

    벌써 2년 (feat. 토이프로젝트 회고,가치,수입)

    정확히 2018년 07월 12일 필자의 첫 토이 프로젝트인 ‘기술 블로그 구독 서비스’를 오픈하게 된다. 얼마나 많이 구독(가입) 하겠어 하는 생각이 부끄러울 만큼 6개월이 지나 구독자 수는 1,000명을 넘기고 1년이 지나 2,000명.어느덧 달력을 보니 오늘이 정확하게 토이 프로젝트를 서비스한지 벌써 2년이 되는 날. 구독자 수는 어느덧 3,000명을 넘어선다. 뭔가 뿌듯하면서도 서비스를 좀 더 디벨롭 하지 못한 필자 자신을 돌아보니 괜히 마음이 무거워지고. 뭔가 해야하는데… 괜히 눈치만 보이네…출처 : http://egloos.zum.com/nievess/v/657827" 뭔가 해야하는데… 괜히 눈치만 보이네… 출처 : http://egloos.zum.com/nievess/v/657827  지난 2년 동안을 돌이켜보며 서비스를 어떻게 운영해 왔는지, 그리고 토이 프로젝트가 필자에게 어떤 영향을 주었는지 되돌아보며 셀프 리뷰를 해 보고자 한다. 서비스 자체 평가 심플한 기능  말 그대로 토이 프로젝트이기 때문에 기능 또한 아주 간단하다. awesome-devblog에서 제공하는 개인/단체 블로그들의 포스팅을 조회하여 어제 작성된 글들만 모아 발송한다. 거기에 주간 많이 클릭된 포스팅을 모아서 한 번 더 발송하는 기능까지. 추가적인 기능을 더 디벨롭 해야 하는데 아이디어가 없어서 인지 디벨롭 할 힘이 안 나서 인지 유지만 하고 있는 상태다. @@ -66,17 +76,4 @@ 아나콘다 설치 (덤으로 설치되는 주피터) 우선 아나콘다를 설치하자. 아나콘다는 Anaconda(이전: Continuum Analytics)라는 곳에서 만든 파이썬 배포판으로, 수백 개의 파이썬 패키지를 포함하고 있다고 한다. 즉, 아나콘다를 설치하고 만들어진 가상환경에서 파이썬 개발을 하면 다양한 모듈이 이미 설치되어 있기 때문에 편리하다는 이야기. 출처 : https://www.anaconda.com/" 출처 : https://www.anaconda.com/ 더불어 시스템에 기본으로 설치되어 있는 파이썬을 건드리면 여러 복잡한 문제가 발생할 수 있기에. 아나콘다를 활용하여 파이썬 3을 사용하는 가상환경을 만들어 보자. 설치는 아주 간단하다. 아나콘다 설치파일을 다운받고 이를 실행하면 끝. (user 레벨이 root 면 sudo 명령어를 생략해도 된다.) $ wget https://repo.anaconda.com/archive/Anaconda3-2019.10-Linux-x86_64.sh $ sudo bash Anaconda3-2019.10-Linux-x86_64.sh Welcome to Anaconda3 2019.10 In order to continue the installation process, please review the license agreement. Please, press ENTER to continue >>> =================================== Anaconda End User License Agreement =================================== Copyright 2015, Anaconda, Inc. ~~~ 중략 ~~~ Do you accept the license terms? [yes|no] [no] >>> yes # yes!! Anaconda3 will now be installed into this location: /root/anaconda3 - Press ENTER to confirm the location - Press CTRL-C to abort the installation - Or specify a different location below [/root/anaconda3] >>> /home/anaconda3 # 설치될 경로를 설정해주고 기본 설정값에 설치하려면 그냥 엔터 ~~~뭐가 엄청 설치된다. 물 한잔 먹고 오자.~~~ installation finished. Do you wish the installer to initialize Anaconda3 by running conda init? [yes|no] [no] >>> yes # yes!! 이렇게 되면 설치는 끝. 환경변수를 설정해서 기본 파이썬 환경을 아나콘다에 의해 설정되도록 맞춰주자. -sudo vi .bashrc __conda_setup="$('/home/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" if [ $? -eq 0 ]; then eval "$__conda_setup" else if [ -f "/home/anaconda3/etc/profile.

    스프링 부트로 멀티모듈 셋팅하기

    서비스를 처음 만들기 시작할때면 각 직군별로 생각하는 포인트가 다양하다. 설계, 기획, 디자인, 개발. 여기서 개발은 프로젝트 셋팅을 어떻게 해야하지? 하는 고민을 하기 마련이다. 아주 간단하게 하나의 모듈로 모든 기능을 담당하도록 만들 수 있지만 기능별로 모듈을 나눠서 셋팅하는게 관리측면에서 장점이라 생각한다.예를 들어보자. 도서관의 들어온 책 정보를 외부에 제공하는 “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.
    \ No newline at end of file +sudo vi .bashrc __conda_setup="$('/home/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" if [ $? -eq 0 ]; then eval "$__conda_setup" else if [ -f "/home/anaconda3/etc/profile.
    \ No newline at end of file diff --git a/page/4/index.html b/page/4/index.html index aabd5cf7..bac744bc 100644 --- a/page/4/index.html +++ b/page/4/index.html @@ -1,5 +1,18 @@ -👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    조금은 무거운 2019 회고

    “회고"는 비단 개발 블로그 뿐만 아니라 어떠한 과정의 마지막에는 꼭 해야할 중요한 시간인 것 같다. 앞만보고 달려가자! 닥공! 라는 말이 있지만 사실 이 말이 성립되기 위해선 지난 과거에 대한 정리와 반성 그리고 무엇을 하려고 했는데 어떤 이유로 못했는지와 그 동안의 나 자신을 바라볼 수 있는 이 “회고” 시간이 필요하다. 벌써 2019년도 마무리가 되어간다. 작년보다 더 정신없이 달려온 올해. 내년엔 올해보다 더 멋지고 힘차게 출발하기 위해 필자의 한 해를 돌아보고자 한다. +👨‍💻꿈꾸는 태태태의 공간
    /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 이거나 오히려 마이너스가 된 것 같은 느낌이다. 왜일까. @@ -72,10 +85,4 @@ 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.

    D.light 투게더톤 참가후기

    회사일을 하다 보면 시키는 대로 혹은 팀의 목표에 부합하기 위해 어쩔 수 없이 해야 하는 일을 하게 된다. 그러한 일이 재미있고 결과물에 대한 만족도가 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.
    \ No newline at end of file +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.
    \ No newline at end of file diff --git a/page/5/index.html b/page/5/index.html index 87ca2a6a..9348c784 100644 --- a/page/5/index.html +++ b/page/5/index.html @@ -1,5 +1,11 @@ -👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    자바, 성능, 모니터링 테크세미나 정리 및 후기 (by 우아한 형제들)

    실무에서 자바 기반으로 개발을 하고 서비스를 운영을 하다보면 처음엔 아무런 문제가 없다가 사용자가 몰리는 등 이벤트성으로 트래픽이 많아질 경우 꼭 문제가 생기기 마련이다. 그럴때면 뒤늦게 부랴부랴 원인을 찾고 개선하기 바빠지게 된다. (아마 윗분들에게 혼나면서?ㅠㅠ) 평소에 이런 성능문제를 개선하고 미리 모니터링 할수있는 부분에 대해 관심을 갖고 있었던 찰나, 우아한 형제들에서 5월 우아한 테크 세미나를 한다기에 부랴부랴 장문의 글로 신청을 하였고 운이 좋아 당첨이 되었다. 한창 회사에서 새로운 서비스 출시, 그리고 잠을 줄여가며 별도로 진행하고 있던 토이프로젝트 등 여러가지로 바쁜 시기였지만 특히 예전부터 뵙고싶던 이상민님께서 직접 강의를 해주신다기에 피곤한 심신을 이끌고 세미나에 참석하였고 그 후기를 적어보고자 한다. +👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    D.light 투게더톤 참가후기

    회사일을 하다 보면 시키는 대로 혹은 팀의 목표에 부합하기 위해 어쩔 수 없이 해야 하는 일을 하게 된다. 그러한 일이 재미있고 결과물에 대한 만족도가 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.

    자바, 성능, 모니터링 테크세미나 정리 및 후기 (by 우아한 형제들)

    실무에서 자바 기반으로 개발을 하고 서비스를 운영을 하다보면 처음엔 아무런 문제가 없다가 사용자가 몰리는 등 이벤트성으로 트래픽이 많아질 경우 꼭 문제가 생기기 마련이다. 그럴때면 뒤늦게 부랴부랴 원인을 찾고 개선하기 바빠지게 된다. (아마 윗분들에게 혼나면서?ㅠㅠ) 평소에 이런 성능문제를 개선하고 미리 모니터링 할수있는 부분에 대해 관심을 갖고 있었던 찰나, 우아한 형제들에서 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 라는 하나의 문장으로 정리를 해주셨다. 아무리 이쁜 디자인과 어렵고 복잡한 기능이 있을지라도 성능이 뒷받침 안된다면 대용량 트래픽 상황에서는 무의미해지기 때문이라고 생각한다. @@ -65,11 +71,4 @@ @Configuration @EnableWebMvc @EnableAspectJAutoProxy @ComponentScan public class HelloWorldConfiguration { @Bean(name="HelloWorld") public ViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } } 이렇게 한뒤 tomcat으로 최대/최소 메모리를 256m으로 설정후 해당 모듈을 띄워준다. 그다음 메모리 상태를 보기 위해 tomcat에 pinpoint를 연동하고 마지막으로 호출테스트를 위해 nGrinder을 설정해준다. 특별한 설정은 없고 위 컨트롤러의 url (/random) 을 여러번 호출하도록 하였다. nGrinder을 설정하는대에는 이 블로그 포스팅을 참고해서 설정하였다. 자, 이제 테스트를 시작해보자. (마치 수술 집도하는것 같은 기분으로…간호사~ 칼!) nGrinder nGrinder의 기본 스크립트에서 url만 해당 서버로 호출되도록 바꿔주고 총 가상 사용자는 2,000으로 시간은 5분으로 설정후에 테스트 시작을 하였더니 다음과 같은 그래프를 볼수 있었다. TPS가 불안정해지다가 어느시점부터 낮아지는것을 확인할 수 있다. 이게 서비스 였다면 사용자가 접속하는데 불편을 느꼈을꺼라 추측을 해본다. 또한 아주 간단한 random string 을 리턴하는 페이지 임에도 불구하고 에러 응답이 적지 않은것을 확인할 수 있었다. -pinpoint 메모리 상태는 어떤지 확인하기 위해 pinpoint를 확인해보면 다음과 같은 그래프를 볼수 있었다. 보기만해도 심장이 벌렁벌렁(?) 뛸 정도로 무서운 그림이다. 실제로 서비스에 (이정도까진 아니였지만) 비슷한 상황이 발생했었다. 메모리가 테스트를 점점 하면 할수록 올라가다가 fullGC가 발생하더니 대나무 숲에 있는 대나무마냥 fullGC가 빼곡히 발생하였다. (이러니… 페이지 접근에 지연이 생긴것 같다.

    천만 명의 사용자에게 1분 내로 알림 보내기 (병렬프로세스의 최적화)

    만약 1번부터 10번까지 번호표가 있는 사람들 총 열명에게 혼자서 동일한 내용의 메일을 보낸다고 가정해보자. 그리고 메일 발송시 한번에 한명에게만 보내야 하는 제한사항이 있을때 과연 당신은 어떤식으로 보내겠는가? 이어서 읽지말고 한번 생각해보자.아무것도 고려하지 않고 단순하게 생각한다면 1번 보내고 > 2번 보내고 … 9번 보내고 > 10번 보내는 방법이 먼저 떠오르게 된다. (for loop 1 to 10 … ) 하지만 보내야 할 사람들이 많아져서 백명, 천명 많게는 천만명에게 보내야 할 경우 방금과 같은 순차적인 방법을 사용하면 너무 늦게 발송된다는건 코드를 작성하지 않아도 알 수있는 문제… 그렇다면 어떤 방법으로 보내야 보다 빨리 보낼수 있을까? 이번 포스팅에서는 필자가 운영하고 있는 서비스에서 기존에 있던 병렬프로세스를 어떤식으로 최적화 했는지, 그래서 결국 얼마나 빨라졌는지에 대한 과정을 정리해 보고자 한다. 비단 메일 발송이나 앱 푸시 등 특정 도메인에 국한되지는 않고 전반적인 프로세스에 대해 이해를 한다면 다른 곳에서도 비슷한 방법으로 활용할 수 있을꺼라 기대 해본다. -상황파악 및 목표 (원할한 이해를 돕기 위하여) 먼저 필자가 운영하고있는 서비스를 간략히 소개부터 해야겠다. (그렇다고 필자 혼자 다 하는건 아님^^;…) 셀럽의 방송이 시작되면 구독한 사용자에게 각 모바일 기기에 설치되어있는 앱으로 알림을 보내어 예정에 없던 깜짝 라이브 방송이나 VOD 영상 오픈을 보다 빠르게 확인할 수 있도록 제공하고 있다. 여기서, 알림이 늦게 발송되면 셀럽은 방송을 시작하고 팬들이 들어오기까지 기다려야 한다거나 반대로 팬들은 방송 시작하고 뒤늦게 방송을 보게되는 불편함이 생기게 된다. 그리고 중복으로 알림이 발송되거나 특정 사용자들에게 발송이 누락되면 안 되는 등 “알림” 이란 기능은 서비스에 있어서 중요한 기능 중에 하나라고 할수 있다. -여기서 “발송 시간"은 처음 발송작업 시작부터 마지막 사용자에 대해 사내 발송 플랫폼으로 발송 요청을 하기까지의 시간을 의미 -그리고 “채널” 이라는 샐럽단위의 그룹이 있는데 영상과 채널의 관계는 1:N이다. 즉, 하나의 영상을 여러 채널에 연결시킬수 있어서 하나의 영상에 대해 여러 채널들에게 연결을 시켜놓으면 채널을 구독하고있는 각각의 사용자에게 모두 알림을 발송 할수가 있게 된다. -우선, 알람이 사용자에게 전달되기까지의 큰 흐름은 다음과 같다. -알림 프로세스" 알림 프로세스 서비스에서 보낼 대상과 보낼 정보를 조합하여 사내 푸시 발송 플랫폼인 사내 발송 플랫폼에게 전달을 하면 플랫폼에 따라 발송이 되고 최종적으로는 사용자의 모바일 기기에 노출이 됨 간단하게 “병렬로 발송하면 되지 않을까?“라는 필자의 생각이 부끄러워질 정도로 이미 redis, rabbitMQ 를 활용해서 아래 그림처럼 병렬 프로세스로 구성되어 있었다. -기존 구조" 기존 구조 라이브가 시작되거나 VOD가 오픈될 경우 api가 호출이 되고 다시 배치 서버에게 영상의 고유번호를 전달 전달받은 영상의 고유번호를 rabbitMQ의 수신자 조회 Queue에 produce 수신자 조회 Queue의 consumer인 수신자 조회 모듈에서 영상의 고유번호를 consume 후 아래 작업을 진행 3-1. 영상:채널 은 1:N 구조이기 때문에 여러 채널의 사용자들에게 알림을 발송할 수 있고, 영상에 연결된 채널들의 user를 db에서 가져온다. 3-2. 가져온 user를 (중복으로 알림이 발송되지 않기 위해) java set에 담고 모든 채널을 조회했다면 redis에 sorted set으로 담는다. 3-3. 적당한 크기로 분할하고 이 분할정보를 발송 Queue에 produce 발송 모듈에서 분할 정보를 consume 하고 아래 작업을 진행 (병렬처리) 4-1. redis 에서 user 모음을 가져오고 4-2. 조회한 user에 해당하는 deviceId를 db에서 가져옴 deviceId와 컨텐츠 정보를 활용하여 적절한 payload를 구성 후 사내 발송 플랫폼 에게 전달 기존 구조에서 발송 시간은 서비스에서 구독자 수가 가장 많은 채널 기준으로 약 1.1천만 명에게 최종 11분 정도 소요되고 있었다. (맨 처음에 이야기 한 순차적인 방법이였다면… 훨씬더 오래 걸렸을꺼라 예상해본다…) -기존에 구성하셨던 분들도 수많은 시행착오와 고민을 하시며 구성하셨을 텐데 더 이상 어떻게 더 빠르게 보낼 수 있을까 하는 부담감과 자칫 알림이 잘못 발송되기라도 한다면(장애가 발생한다면) 그 수많은 사용자들의 불만 화살 과녁이 필자가 되어야 한다는 압박감이 개선 시작 전부터 머릿속을 휘감고 있었던 찰나에
    \ No newline at end of file +pinpoint 메모리 상태는 어떤지 확인하기 위해 pinpoint를 확인해보면 다음과 같은 그래프를 볼수 있었다. 보기만해도 심장이 벌렁벌렁(?) 뛸 정도로 무서운 그림이다. 실제로 서비스에 (이정도까진 아니였지만) 비슷한 상황이 발생했었다. 메모리가 테스트를 점점 하면 할수록 올라가다가 fullGC가 발생하더니 대나무 숲에 있는 대나무마냥 fullGC가 빼곡히 발생하였다. (이러니… 페이지 접근에 지연이 생긴것 같다.
    \ No newline at end of file diff --git a/page/6/index.html b/page/6/index.html index a38b6449..153015de 100644 --- a/page/6/index.html +++ b/page/6/index.html @@ -1,5 +1,12 @@ -👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    2018 회고 - Coder가 아닌 Programmer로

    매사에 행동하는 모든것들의 끝자락에서는 그동안 잘한것과 못한것을 다시 생각하며 잘한것은 보다 더 잘할수 있도록 하고 못한것은 왜 못했는지 그리고 어떻게 하면 못한 부분을 고칠수 있을지에 대한 시간을 갖으려고 노력해왔다. 그게 개발이 되었든 게임이 되었든 연인과의 데이트가 되었든 뭐든지. 이러한 시간들은 필자에게 큰 인사이트를 얻을 수 있게 되었고 지난 한해를 돌이켜 보자면 개인적으로 계획한 전부를 다 이뤄내지는 못했지만 나름의 많은 경험과 성과를 달성했다고 생각해본다. 이제 몇시간 뒤면 올해가 끝나고 새로운 한 해가 시작되는 이 시점에 개발자로써의 회고를 해보며 2018년 정리 및 2019년 목표를 다짐해보자. +👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    천만 명의 사용자에게 1분 내로 알림 보내기 (병렬프로세스의 최적화)

    만약 1번부터 10번까지 번호표가 있는 사람들 총 열명에게 혼자서 동일한 내용의 메일을 보낸다고 가정해보자. 그리고 메일 발송시 한번에 한명에게만 보내야 하는 제한사항이 있을때 과연 당신은 어떤식으로 보내겠는가? 이어서 읽지말고 한번 생각해보자.아무것도 고려하지 않고 단순하게 생각한다면 1번 보내고 > 2번 보내고 … 9번 보내고 > 10번 보내는 방법이 먼저 떠오르게 된다. (for loop 1 to 10 … ) 하지만 보내야 할 사람들이 많아져서 백명, 천명 많게는 천만명에게 보내야 할 경우 방금과 같은 순차적인 방법을 사용하면 너무 늦게 발송된다는건 코드를 작성하지 않아도 알 수있는 문제… 그렇다면 어떤 방법으로 보내야 보다 빨리 보낼수 있을까? 이번 포스팅에서는 필자가 운영하고 있는 서비스에서 기존에 있던 병렬프로세스를 어떤식으로 최적화 했는지, 그래서 결국 얼마나 빨라졌는지에 대한 과정을 정리해 보고자 한다. 비단 메일 발송이나 앱 푸시 등 특정 도메인에 국한되지는 않고 전반적인 프로세스에 대해 이해를 한다면 다른 곳에서도 비슷한 방법으로 활용할 수 있을꺼라 기대 해본다. +상황파악 및 목표 (원할한 이해를 돕기 위하여) 먼저 필자가 운영하고있는 서비스를 간략히 소개부터 해야겠다. (그렇다고 필자 혼자 다 하는건 아님^^;…) 셀럽의 방송이 시작되면 구독한 사용자에게 각 모바일 기기에 설치되어있는 앱으로 알림을 보내어 예정에 없던 깜짝 라이브 방송이나 VOD 영상 오픈을 보다 빠르게 확인할 수 있도록 제공하고 있다. 여기서, 알림이 늦게 발송되면 셀럽은 방송을 시작하고 팬들이 들어오기까지 기다려야 한다거나 반대로 팬들은 방송 시작하고 뒤늦게 방송을 보게되는 불편함이 생기게 된다. 그리고 중복으로 알림이 발송되거나 특정 사용자들에게 발송이 누락되면 안 되는 등 “알림” 이란 기능은 서비스에 있어서 중요한 기능 중에 하나라고 할수 있다. +여기서 “발송 시간"은 처음 발송작업 시작부터 마지막 사용자에 대해 사내 발송 플랫폼으로 발송 요청을 하기까지의 시간을 의미 +그리고 “채널” 이라는 샐럽단위의 그룹이 있는데 영상과 채널의 관계는 1:N이다. 즉, 하나의 영상을 여러 채널에 연결시킬수 있어서 하나의 영상에 대해 여러 채널들에게 연결을 시켜놓으면 채널을 구독하고있는 각각의 사용자에게 모두 알림을 발송 할수가 있게 된다. +우선, 알람이 사용자에게 전달되기까지의 큰 흐름은 다음과 같다. +알림 프로세스" 알림 프로세스 서비스에서 보낼 대상과 보낼 정보를 조합하여 사내 푸시 발송 플랫폼인 사내 발송 플랫폼에게 전달을 하면 플랫폼에 따라 발송이 되고 최종적으로는 사용자의 모바일 기기에 노출이 됨 간단하게 “병렬로 발송하면 되지 않을까?“라는 필자의 생각이 부끄러워질 정도로 이미 redis, rabbitMQ 를 활용해서 아래 그림처럼 병렬 프로세스로 구성되어 있었다. +기존 구조" 기존 구조 라이브가 시작되거나 VOD가 오픈될 경우 api가 호출이 되고 다시 배치 서버에게 영상의 고유번호를 전달 전달받은 영상의 고유번호를 rabbitMQ의 수신자 조회 Queue에 produce 수신자 조회 Queue의 consumer인 수신자 조회 모듈에서 영상의 고유번호를 consume 후 아래 작업을 진행 3-1. 영상:채널 은 1:N 구조이기 때문에 여러 채널의 사용자들에게 알림을 발송할 수 있고, 영상에 연결된 채널들의 user를 db에서 가져온다. 3-2. 가져온 user를 (중복으로 알림이 발송되지 않기 위해) java set에 담고 모든 채널을 조회했다면 redis에 sorted set으로 담는다. 3-3. 적당한 크기로 분할하고 이 분할정보를 발송 Queue에 produce 발송 모듈에서 분할 정보를 consume 하고 아래 작업을 진행 (병렬처리) 4-1. redis 에서 user 모음을 가져오고 4-2. 조회한 user에 해당하는 deviceId를 db에서 가져옴 deviceId와 컨텐츠 정보를 활용하여 적절한 payload를 구성 후 사내 발송 플랫폼 에게 전달 기존 구조에서 발송 시간은 서비스에서 구독자 수가 가장 많은 채널 기준으로 약 1.1천만 명에게 최종 11분 정도 소요되고 있었다. (맨 처음에 이야기 한 순차적인 방법이였다면… 훨씬더 오래 걸렸을꺼라 예상해본다…) +기존에 구성하셨던 분들도 수많은 시행착오와 고민을 하시며 구성하셨을 텐데 더 이상 어떻게 더 빠르게 보낼 수 있을까 하는 부담감과 자칫 알림이 잘못 발송되기라도 한다면(장애가 발생한다면) 그 수많은 사용자들의 불만 화살 과녁이 필자가 되어야 한다는 압박감이 개선 시작 전부터 머릿속을 휘감고 있었던 찰나에

    2018 회고 - Coder가 아닌 Programmer로

    매사에 행동하는 모든것들의 끝자락에서는 그동안 잘한것과 못한것을 다시 생각하며 잘한것은 보다 더 잘할수 있도록 하고 못한것은 왜 못했는지 그리고 어떻게 하면 못한 부분을 고칠수 있을지에 대한 시간을 갖으려고 노력해왔다. 그게 개발이 되었든 게임이 되었든 연인과의 데이트가 되었든 뭐든지. 이러한 시간들은 필자에게 큰 인사이트를 얻을 수 있게 되었고 지난 한해를 돌이켜 보자면 개인적으로 계획한 전부를 다 이뤄내지는 못했지만 나름의 많은 경험과 성과를 달성했다고 생각해본다. 이제 몇시간 뒤면 올해가 끝나고 새로운 한 해가 시작되는 이 시점에 개발자로써의 회고를 해보며 2018년 정리 및 2019년 목표를 다짐해보자. 글쓰는 개발자가 되자. 개인 블로그 운영 아주 오래전, 동기 형을 통해 개발자가 글을 써야하는 중요성에 대해 절실하게 배우게 되었고 그때부터 블로그를 운영하기 시작하였다. 그 동기형의 말에 조금 더 내 생각을 첨가하자면 글을 쓰다보면 누군가 내 글을 본다는 마음에 내가 알고있는 지식을 보다 더 깊게 공부하게 되고 그것들이 모여 내 개발 히스토리가 만들어 지며 포트폴리오 등 다양하게 활용할 수 있기에 블로그를 운영하는건 정말 좋은 선택지 였던것 같다. 실제로 그냥 구글링 해서 알게된 것과는 또 다른 배움이 있었기 때문이다. 회사 일 그리고 개인 공부를 하면서 적어도 한달에 한가지 이상은 배우게 되기 때문에 올해 초 한달에 한개 이상의 글을 쓰기로 결심하였다.(그 달의 글이 없다면 뭔가 놀았거나(?) 미친듯이 바빴거나 아니면 게을렀거나…) 블로그에 글을 쓴 내역을 그래프로 시각화 해보면 아래처럼 총 23개의 글을 작성하였고 월 평균 1.9개의 글을 작성하게 된것을 볼수 있다. 9월달엔 팀 옮기자마자 엄청 바빴고, 11월엔 그 바쁜게 결실을 맺는 시간… 이라 핑계를… (나중에 블로깅 예정, 병렬 프로그래밍 관련) 월별 글 작성수" 월별 글 작성수 위 결과만을 두고 봤을땐 많으면 많고 적으면 적다고 할 수 있는 결과지만 개인적으로는 자투리 시간을 활용해서 그간 배웠던것, 그리고 경험했지만 내것으로 만들지 못하고 보기만 하며 넘어간것들에 대해 귀찮지만 시간을 투자하고 정리했더라면 더 많은 글을 썼을것 같다는 조금 아쉬운 결과라고 생각이 든다. @@ -62,12 +69,4 @@ 데이터 사용을 허락해주신 천사같으신분…" 데이터 사용을 허락해주신 천사같으신분… 이 자리를 빌어 데이터를 사용할수 있도록 허락해주신분 께 감사인사를 표합니다. 홈페이지를 만들기 위해서는 이제껏 삼겹살에 소주처럼(응?) Java에 Spring을 사용해 왔었지만 이번엔 좀 다른 방식을 사용하고 싶었다. 물론 삼겹살에 맥주, 치킨에 소주를 먹어도 되긴 하지만…" 물론 삼겹살에 맥주, 치킨에 소주를 먹어도 되긴 하지만… 최근에 Flask라는 python기반 웹 프레임워크를 만져본 경험이 있어서 이렇다할 고민없이 빠른 결정을 할수 있었다. 또한 DB는 mysql 이나 기타 memory DB를 사용할까 했지만 이또한 심플하게 파일을 활용하는 sqlite3 을 사용하고자 하였다. -웹서버_최종_수정_파이널_진짜_확정 Flask를 활용하기 위해서는 당연히 웹서버가 필요했다. 처음엔 awesome-devblog에서도 사용하고 있던 https://www.heroku.com/ 를 이용해서 해보려 했으나 매일 구독자들에게 메일을 보내는 등 스케쥴러 기능같은건 구현하기 힘들었고 인스턴트 어플리케이션을 등록하는 형태라 사용자의 메일을 입력받고 저장하는 로직을 만들기는 어려워 보였다. (필자가 heroku를 너무 수박 겉핥기식으로 봐서 일수도 있다…) 좀더 찾아보니 https://www.pythonanywhere.com/ 라는 제한적이지만 무료 서비스가 있었는데 웹콘솔도 지원하고 상당히 매력있어 보여서 이거다! 하며 개발을 시작을 했으나 (나름 도메인까지 그럴싸하게 만들었지만… http://dailydevblog.pythonanywhere.com/ ) 세상에 공짜는 없다는 말을 실감하며 앞서 말했던 요구사항을 완벽하게 구현할 수 없는 상황이였다.(request 제한, 스케쥴러 등록 개수 제한 등 보다 여러기능을 사용하기 위해서는 돈을 내고 써야…) 마지막 희망으로 언제샀는지 서랍속 깊이 자고있던 라즈베리 파이를 꺼내서 공유기 DDNS설정을 하고 라즈베리안을 설치하며 웹서버를 위한 셋팅을 시도해보았으나 언제나 그렇듯 (시험공부 하기전에 책상 정리하고 괜히 방청소까지 하다가 피곤해서 자버리는듯한 느낌) 배보다 배꼽이 클것같아 이또한 진행하다가 중단하게 된다. 결국 AWS에서 1년동안은 무료로 사용할수 있는 Free Tier 라는걸 발견하고 이참에 나도한번 사용해보자라는 마음을 가지고 과금되지 않게 조심조심 셋팅을 할수 있었다.

    2018 오픈소스개발자이야기 후기

    Facebook그룹들을 눈팅하다(?) OSS개발자 포럼에서 오픈소스 개발자이야기라는 주제로 세미나를 주최한다는 공지를 보게되었다. 언제부턴가 트랜드에 뒤쳐지지 않으려는 몸부림중 세미나같은 외부 개발 행사에 참여해보자는 마음으로 공지를 보자마자 홀린듯이 신청을 하게 되었고세미나를 듣고 감흥이 가시기 전에 후기를 적고자 한다.(시간이 지나면 잊어버릴것만같은, 보고 들은 생생한 그 무언가를 얻었기에…) -비가오는 주말이였지만 많이 배우고 오자는 설레임을 갖고 서울 광화문 근처에 있는 한국마이크로소프트로 가게되었다. 말로만 듣던 MS사 로고를 보고 사람들이 하나둘씩 모이는걸 보니 뭔가 배울수 있겠구나 하는 기대감이 생겼다. 사실 오픈소스를 사용만 해본 입장이라 실제 오픈소스에 기여하시는 분들은 어떤 생각들을 갖고 계시는지가 가장 궁금했고 개발자인 나도 언젠간 오픈소스에 기여할수있지 않을까 하는 생각을 하며 발표를 들었다. -# 회색지대 : 이상과 현실 - 오픈소스 저작권 / 신정규 님 오픈소스는 아무리 말그대로 Open이지만 오픈소스마다 다양한 저작권을 갖고있고 서로 쟁취하려는 싸움이 많이 발생한다고 한다. 그러다보니 어떠한 프로그램을 만들고 오픈소스화 시킬때도 라이센스의 종류를 잘 결정해야 추후 불이익을 당하는 상황을 모면할수 있다고 한다. 특허와 라이센스는 같은 말이면서도 다른데 아래 표처럼 각 상황에 따라 다른 부분을 확인할수 있었다. -특허 라이센스 권리발생 출원, 심사, 등록 창작과 동시 발생 권리내용 독점배타적 실시권 인격권/재산권 효력범위 아이디어의 동일성 표현의 실질적 유사성 첫 시간이기도 하였고 아무래도 주제가 끝장토론을 해도 안끝날 주제였던지라 정해진 시간을 넘길정도로 이야기를 많이 해주셨다. 특히 오픈소스 관련된 이야기는 사례를 이야기 해야 재밌다고 하셨는데 시간관계상 몇가지만 말씀해주셨다. -링크가 맞는지는 모르겠으나 첨부해본다. 엘림넷 vs 하이온넷 사건 EFM Networks 오라클 VS 구글 오픈소스 개발에 대해 단순하게 누구나 수정할수 있는 환경 이라고만 생각을 하고있다가 이런 복잡한 라이센스 문제가 나오니 약간 어려웠지만, 오픈소스의 생태계를 알고 발을 들이기 위해서는 어느정도의 히스토리는 알아야 겠다고 느끼게 되었다. -Elastic 에서 Remote 로 일하기 / 김종민 님 그전부터 Elastic 제품들을 실무에서도 사용해 왔었기에 개인적으로 오늘 발표중에 가장 궁금했었고, 관심이 있던 시간이였다. 발표에 앞서 어떻게 Elastic에 들어가게 되셨고 회사 소개를 간단히 해주셨는데 생각보다 어마어마한 회사다고 느낄수 있었다.(800여명중 한국엔 9명 / 네덜란드 출신 스타트업 인데 본사는 캘리포니아 마운틴뷰에 있고 등등) 원격근무는 편하고 비용이 절약되는 장점이 있으나 동료들간의 유대감형성이 힘들거나 회의시 집중이 힘든 단점도 있다는 점을 말씀해 주셨다. 시간관계상 몇가지 링크들을 소개해주셨는데 나중에 봐볼 생각이다. -침대에서 회사까지 1분 [마소 392호] 리모트 워크의 중심에 서보다 원격 툴로는 다음과 같이 사용한다고 한다. -github : 슬랙연동, 개발뿐 아니라 운영/기획/이벤트 공유시 활용 Google Apps Slack : 봇 활용 (다양한 종류의 봇, 상황마다 특정 알림을 준다.) salesforce : CRM 툴 zoom : 화상회의 200명 동시콜 가능, 회의가 끝나면 녹음/녹화/스크립팅까지 가능하다고 한다 (wow) pinboard : 근태/인사 관리용 앱 jira는 사용 잘 안함 나중에 팀 내 Slack 봇으로 여러가지 다양한 자동화를 구성할수 있을것 같다는 생각이 들었다. -오픈소스 생태계 일원으로서의 개발자 / 변정훈 님 사회자분이 “아웃사이더님"이라고 하시길래 설마 했다. 뭐가 잘 안되면 구글링을 하게되는데 내가 자주 보던 블로그를 운영하셨던 분이 내눈앞에 ㄷㄷ… 언제부터 해야지~가 아니고 개발하다보니 어느새 오픈소스에 참여하고 있었다고 한다. 또한 참여하는게 아니고 이미 오픈소스 생태계속에서 살고있는 우리들이라 말씀하시고, 오픈소스 Contribution 방법으로는 사용/홍보/번역/리포팅/문서화/코드제출 등 다양하게 있으니 어렵게 생각하지 말자 라고 하셨다. 오픈소스에서 배울수 있는점은 커뮤니케이션의 방법, 협업의 방법과 중요성, 테스트코드의 중요성, 지속적 통합/지속적 배포, 코드의 품질관리 라고 한다. 점점 발표를 들으면서 오픈소스에 대한 생각이 바뀌고 있는 내 자신을 느낄수 있었다.
    \ No newline at end of file +웹서버_최종_수정_파이널_진짜_확정 Flask를 활용하기 위해서는 당연히 웹서버가 필요했다. 처음엔 awesome-devblog에서도 사용하고 있던 https://www.heroku.com/ 를 이용해서 해보려 했으나 매일 구독자들에게 메일을 보내는 등 스케쥴러 기능같은건 구현하기 힘들었고 인스턴트 어플리케이션을 등록하는 형태라 사용자의 메일을 입력받고 저장하는 로직을 만들기는 어려워 보였다. (필자가 heroku를 너무 수박 겉핥기식으로 봐서 일수도 있다…) 좀더 찾아보니 https://www.pythonanywhere.com/ 라는 제한적이지만 무료 서비스가 있었는데 웹콘솔도 지원하고 상당히 매력있어 보여서 이거다! 하며 개발을 시작을 했으나 (나름 도메인까지 그럴싸하게 만들었지만… http://dailydevblog.pythonanywhere.com/ ) 세상에 공짜는 없다는 말을 실감하며 앞서 말했던 요구사항을 완벽하게 구현할 수 없는 상황이였다.(request 제한, 스케쥴러 등록 개수 제한 등 보다 여러기능을 사용하기 위해서는 돈을 내고 써야…) 마지막 희망으로 언제샀는지 서랍속 깊이 자고있던 라즈베리 파이를 꺼내서 공유기 DDNS설정을 하고 라즈베리안을 설치하며 웹서버를 위한 셋팅을 시도해보았으나 언제나 그렇듯 (시험공부 하기전에 책상 정리하고 괜히 방청소까지 하다가 피곤해서 자버리는듯한 느낌) 배보다 배꼽이 클것같아 이또한 진행하다가 중단하게 된다. 결국 AWS에서 1년동안은 무료로 사용할수 있는 Free Tier 라는걸 발견하고 이참에 나도한번 사용해보자라는 마음을 가지고 과금되지 않게 조심조심 셋팅을 할수 있었다.
    \ No newline at end of file diff --git a/page/7/index.html b/page/7/index.html index d586e015..02fd8125 100644 --- a/page/7/index.html +++ b/page/7/index.html @@ -1,5 +1,13 @@ -👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    초간단 API서버 만들기 - 2부 (Python + Flask + Nginx)

    지난포스팅에 이어 이번엔 Flask와 Nginx를 연동하는 방법을 정리해보고자 한다. Apache로 연동했는데 왜 또 Nginx로 연동하는걸 정리하지(?)하며 의문이 들수 있는데 다른 포스팅을 봐도 Apache + Flask 조합보다 Nginx + Flask 조합이 더 많고 지난 포스팅에서도 알수있었듯이 (Apache VS Nginx) 둘중 어느것이 좋다고 할수도 없고 각 상황에서 연동하는 방법을 알고 있다면 이 또한 나만의 무기가 될것같아 Nginx를 연동하는 방법을 정리해보려 한다. +👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    2018 오픈소스개발자이야기 후기

    Facebook그룹들을 눈팅하다(?) OSS개발자 포럼에서 오픈소스 개발자이야기라는 주제로 세미나를 주최한다는 공지를 보게되었다. 언제부턴가 트랜드에 뒤쳐지지 않으려는 몸부림중 세미나같은 외부 개발 행사에 참여해보자는 마음으로 공지를 보자마자 홀린듯이 신청을 하게 되었고세미나를 듣고 감흥이 가시기 전에 후기를 적고자 한다.(시간이 지나면 잊어버릴것만같은, 보고 들은 생생한 그 무언가를 얻었기에…) +비가오는 주말이였지만 많이 배우고 오자는 설레임을 갖고 서울 광화문 근처에 있는 한국마이크로소프트로 가게되었다. 말로만 듣던 MS사 로고를 보고 사람들이 하나둘씩 모이는걸 보니 뭔가 배울수 있겠구나 하는 기대감이 생겼다. 사실 오픈소스를 사용만 해본 입장이라 실제 오픈소스에 기여하시는 분들은 어떤 생각들을 갖고 계시는지가 가장 궁금했고 개발자인 나도 언젠간 오픈소스에 기여할수있지 않을까 하는 생각을 하며 발표를 들었다. +# 회색지대 : 이상과 현실 - 오픈소스 저작권 / 신정규 님 오픈소스는 아무리 말그대로 Open이지만 오픈소스마다 다양한 저작권을 갖고있고 서로 쟁취하려는 싸움이 많이 발생한다고 한다. 그러다보니 어떠한 프로그램을 만들고 오픈소스화 시킬때도 라이센스의 종류를 잘 결정해야 추후 불이익을 당하는 상황을 모면할수 있다고 한다. 특허와 라이센스는 같은 말이면서도 다른데 아래 표처럼 각 상황에 따라 다른 부분을 확인할수 있었다. +특허 라이센스 권리발생 출원, 심사, 등록 창작과 동시 발생 권리내용 독점배타적 실시권 인격권/재산권 효력범위 아이디어의 동일성 표현의 실질적 유사성 첫 시간이기도 하였고 아무래도 주제가 끝장토론을 해도 안끝날 주제였던지라 정해진 시간을 넘길정도로 이야기를 많이 해주셨다. 특히 오픈소스 관련된 이야기는 사례를 이야기 해야 재밌다고 하셨는데 시간관계상 몇가지만 말씀해주셨다. +링크가 맞는지는 모르겠으나 첨부해본다. 엘림넷 vs 하이온넷 사건 EFM Networks 오라클 VS 구글 오픈소스 개발에 대해 단순하게 누구나 수정할수 있는 환경 이라고만 생각을 하고있다가 이런 복잡한 라이센스 문제가 나오니 약간 어려웠지만, 오픈소스의 생태계를 알고 발을 들이기 위해서는 어느정도의 히스토리는 알아야 겠다고 느끼게 되었다. +Elastic 에서 Remote 로 일하기 / 김종민 님 그전부터 Elastic 제품들을 실무에서도 사용해 왔었기에 개인적으로 오늘 발표중에 가장 궁금했었고, 관심이 있던 시간이였다. 발표에 앞서 어떻게 Elastic에 들어가게 되셨고 회사 소개를 간단히 해주셨는데 생각보다 어마어마한 회사다고 느낄수 있었다.(800여명중 한국엔 9명 / 네덜란드 출신 스타트업 인데 본사는 캘리포니아 마운틴뷰에 있고 등등) 원격근무는 편하고 비용이 절약되는 장점이 있으나 동료들간의 유대감형성이 힘들거나 회의시 집중이 힘든 단점도 있다는 점을 말씀해 주셨다. 시간관계상 몇가지 링크들을 소개해주셨는데 나중에 봐볼 생각이다. +침대에서 회사까지 1분 [마소 392호] 리모트 워크의 중심에 서보다 원격 툴로는 다음과 같이 사용한다고 한다. +github : 슬랙연동, 개발뿐 아니라 운영/기획/이벤트 공유시 활용 Google Apps Slack : 봇 활용 (다양한 종류의 봇, 상황마다 특정 알림을 준다.) salesforce : CRM 툴 zoom : 화상회의 200명 동시콜 가능, 회의가 끝나면 녹음/녹화/스크립팅까지 가능하다고 한다 (wow) pinboard : 근태/인사 관리용 앱 jira는 사용 잘 안함 나중에 팀 내 Slack 봇으로 여러가지 다양한 자동화를 구성할수 있을것 같다는 생각이 들었다. +오픈소스 생태계 일원으로서의 개발자 / 변정훈 님 사회자분이 “아웃사이더님"이라고 하시길래 설마 했다. 뭐가 잘 안되면 구글링을 하게되는데 내가 자주 보던 블로그를 운영하셨던 분이 내눈앞에 ㄷㄷ… 언제부터 해야지~가 아니고 개발하다보니 어느새 오픈소스에 참여하고 있었다고 한다. 또한 참여하는게 아니고 이미 오픈소스 생태계속에서 살고있는 우리들이라 말씀하시고, 오픈소스 Contribution 방법으로는 사용/홍보/번역/리포팅/문서화/코드제출 등 다양하게 있으니 어렵게 생각하지 말자 라고 하셨다. 오픈소스에서 배울수 있는점은 커뮤니케이션의 방법, 협업의 방법과 중요성, 테스트코드의 중요성, 지속적 통합/지속적 배포, 코드의 품질관리 라고 한다. 점점 발표를 들으면서 오픈소스에 대한 생각이 바뀌고 있는 내 자신을 느낄수 있었다.

    초간단 API서버 만들기 - 2부 (Python + Flask + Nginx)

    지난포스팅에 이어 이번엔 Flask와 Nginx를 연동하는 방법을 정리해보고자 한다. Apache로 연동했는데 왜 또 Nginx로 연동하는걸 정리하지(?)하며 의문이 들수 있는데 다른 포스팅을 봐도 Apache + Flask 조합보다 Nginx + Flask 조합이 더 많고 지난 포스팅에서도 알수있었듯이 (Apache VS Nginx) 둘중 어느것이 좋다고 할수도 없고 각 상황에서 연동하는 방법을 알고 있다면 이 또한 나만의 무기가 될것같아 Nginx를 연동하는 방법을 정리해보려 한다. 1부에서 왜 Flask인가, Flask의 장점에 대해 정리를 했으니 이번 포스팅에서는 별도로 작성하진 않는다. Nginx 설치 ( https://nginx.org/en/ ) 역시 소스설치를 한다. - 다운을 받고 $ https://nginx.org/download/nginx-1.14.0.tar.gz - 압축을 푼 다음 $ tar -zxvf nginx-1.14.0.tar.gz - 폴더로 이동해서 $ cd nginx-1.14.0 - 설치할 디렉토리를 설정하고 $ ./configure --prefix=/~~~/apps/nginx - make 파일을 만들고 $ make - 설치를 진행한다. $ make install 이렇게 하면 일단 Nginx는 설치가 되었다. @@ -77,10 +85,4 @@ SonarQube 메인화면" SonarQube 메인화면 SonarQube Scanner 설치 소스를 연동시켜 정적분석을 하기 위해서는 SonarQube Scanner 라는게 필요하다고 한다. 아래 url에서 다운받아 적절한 곳에 압축을 풀어두자. https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner $ wget https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.0.3.778-linux.zip $ unzip sonar-scanner-cli-3.0.3.778-linux.zip # jenkins 설치 및 SonarQube 연동 jenkins 설치는 간단하니 별도 언급은 안하고 넘어가…려고 했으나, 하나부터 열까지 정리한다는 마음으로~ https://jenkins.io/download/ 에서 최신버전을 tomcat/webapps/ 아래에 다운받고 server.xml 을 적절하게 수정해준다. $ wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war $ vi tomcat/conf/server.xml <Connector port="19001" protocol="HTTP/1.1" # 포트 변경 <Context path="/jenkins" debug="0" privileged="true" docBase="jenkins.war" /> #추가 # tomcat/bin/startup.sh jenkins 설치를 완료 한 후 필요한 플러그인을 추가로 설치해준다. -Python Plugin GitHub Pull Request Builder GitHub plugin 접속 : 서버IP:19001 (참고로 한 서버에서 다 설치하다보니 port 충돌을 신경쓰게되었다. ) 처음 jenkins를 실행하면 이런저런 설정을 하는데 특별한 설정 변경없이 next버튼을 연신 눌러면 설치가 완료 되고, SonarQube를 사용하기 위해 SonarQube Scanner for Jenkins라는 플러그인을 설치해주자.

    Github의 WebHook을 이용하여 자동 Jenkins Job 실행

    PullRequest가 발생하면 알림을 받고싶다거나, 내가 관리하는 레파지토리에 댓글이 달릴때마다 또는 이슈가 생성될때마다 정보를 저장하고 싶다거나. 종합해보면 Github에서 이벤트가 발생할때 어떤 동작을 해야 할 경우 Github에서 제공하는 Webhook 을 사용하여 목적을 달성할 수 있다. 아 당연한 이야기이지만 언급하고 넘어갈께 있다면, Github에서 Jenkins Job을 호출하기 위해서는 Jenkins가 외부에 공개되어 있어야 한다. (내부사설망이나 private 한 설정이 되어있다면 호출이 안되어 Webhook기능을 사용할 수 없다.) -Jenkins Security 설정 Jenkins Job을 외부에서 URL로 실행을 하기 위해서는 아래 설정이 꼭 필요하다. (이 설정을 몰라서 수많은 삽질을 했다.) CSRF Protection 설정 체크를 풀어줘야 한다. 이렇게 되면 외부에서 Job에 대한 트리거링이 가능해 진다. -Jenkins > Configure Global Security" Jenkins > Configure Global Security Jenkins Job 설정 Github 에서 Webhook에 의해 Jenkins Job을 실행하게 될텐데, 그때 정보들이 payload라는 파라미터와 함께 POST 형식으로 호출이 되기 때문에 미리 Job에서 받는 준비(?)를 해둬야 한다. 설정은 간단하게 다음과 같이 Job 파라미터 설정을 해주면 된다. -Jenkins > 해당 Job > configure" Jenkins > 해당 Job > configure Github Webhook 설정 이제 Github Repository 의 Hook 설정만 하면 끝이난다. 해당 Repository > Settings > Hooks 설정에 들어가서 Add webhook을 선택하여 Webhook을 등록해준다. URL은 {jenkins URL}/jenkins/job/{job name}/buildWithParameters식으로 설정해주고 Content Type 은 application/x-www-form-urlencoded으로 선택한다. 언제 Webhook을 트리거링 시킬꺼냐는 옵션에서는 원하는 설정에 맞추면 되겠지만 나는 pullRequest가 등록 될때만 미리 만들어 놓은 Jenkins Job을 실행시킬 계획이였으니 Let me select individual events.을 설정하고 Pull Request에 체크를 해준다. 아래 그림처럼 말이다. -해당 Repositroy > Settings > Hooks" 해당 Repositroy > Settings > Hooks 이렇게 등록하고 다시 들어가서 맨 아랫 부분Recent Deliveries을 보면 ping test 가 이루어져 정상적으로 응답을 받은것을 확인할수가 있다. -Webhook 등록 결과" Webhook 등록 결과 이렇게 설정을 다 한 뒤 PullRequest를 발생시키면 Jenkins 해당 Job에서는 파라미터를 받으며 실행이 된것을 확인할수가 있다. -Jenkins Job 실행 결과" Jenkins Job 실행 결과 끝~
    \ No newline at end of file +Python Plugin GitHub Pull Request Builder GitHub plugin 접속 : 서버IP:19001 (참고로 한 서버에서 다 설치하다보니 port 충돌을 신경쓰게되었다. ) 처음 jenkins를 실행하면 이런저런 설정을 하는데 특별한 설정 변경없이 next버튼을 연신 눌러면 설치가 완료 되고, SonarQube를 사용하기 위해 SonarQube Scanner for Jenkins라는 플러그인을 설치해주자.
    \ No newline at end of file diff --git a/page/8/index.html b/page/8/index.html index 0262e997..2f785314 100644 --- a/page/8/index.html +++ b/page/8/index.html @@ -1,5 +1,11 @@ -👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    Github과 Jenkins 연동하기

    Jenkins에서 Github의 소스를 가져와서 빌드를 하는 등 Github과 Jenkins와 연동을 시켜줘야하는 상황에서, 별도의 선행 작업이 필요하다. 다른 여러 방법이 있을수 있는데 여기서는 SSH로 연동하는 방법을 알아보고자 한다.우선 Jenkins가 설치되어있는 서버에서 인증키를 생성하자. +👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    Github의 WebHook을 이용하여 자동 Jenkins Job 실행

    PullRequest가 발생하면 알림을 받고싶다거나, 내가 관리하는 레파지토리에 댓글이 달릴때마다 또는 이슈가 생성될때마다 정보를 저장하고 싶다거나. 종합해보면 Github에서 이벤트가 발생할때 어떤 동작을 해야 할 경우 Github에서 제공하는 Webhook 을 사용하여 목적을 달성할 수 있다. 아 당연한 이야기이지만 언급하고 넘어갈께 있다면, Github에서 Jenkins Job을 호출하기 위해서는 Jenkins가 외부에 공개되어 있어야 한다. (내부사설망이나 private 한 설정이 되어있다면 호출이 안되어 Webhook기능을 사용할 수 없다.) +Jenkins Security 설정 Jenkins Job을 외부에서 URL로 실행을 하기 위해서는 아래 설정이 꼭 필요하다. (이 설정을 몰라서 수많은 삽질을 했다.) CSRF Protection 설정 체크를 풀어줘야 한다. 이렇게 되면 외부에서 Job에 대한 트리거링이 가능해 진다. +Jenkins > Configure Global Security" Jenkins > Configure Global Security Jenkins Job 설정 Github 에서 Webhook에 의해 Jenkins Job을 실행하게 될텐데, 그때 정보들이 payload라는 파라미터와 함께 POST 형식으로 호출이 되기 때문에 미리 Job에서 받는 준비(?)를 해둬야 한다. 설정은 간단하게 다음과 같이 Job 파라미터 설정을 해주면 된다. +Jenkins > 해당 Job > configure" Jenkins > 해당 Job > configure Github Webhook 설정 이제 Github Repository 의 Hook 설정만 하면 끝이난다. 해당 Repository > Settings > Hooks 설정에 들어가서 Add webhook을 선택하여 Webhook을 등록해준다. URL은 {jenkins URL}/jenkins/job/{job name}/buildWithParameters식으로 설정해주고 Content Type 은 application/x-www-form-urlencoded으로 선택한다. 언제 Webhook을 트리거링 시킬꺼냐는 옵션에서는 원하는 설정에 맞추면 되겠지만 나는 pullRequest가 등록 될때만 미리 만들어 놓은 Jenkins Job을 실행시킬 계획이였으니 Let me select individual events.을 설정하고 Pull Request에 체크를 해준다. 아래 그림처럼 말이다. +해당 Repositroy > Settings > Hooks" 해당 Repositroy > Settings > Hooks 이렇게 등록하고 다시 들어가서 맨 아랫 부분Recent Deliveries을 보면 ping test 가 이루어져 정상적으로 응답을 받은것을 확인할수가 있다. +Webhook 등록 결과" Webhook 등록 결과 이렇게 설정을 다 한 뒤 PullRequest를 발생시키면 Jenkins 해당 Job에서는 파라미터를 받으며 실행이 된것을 확인할수가 있다. +Jenkins Job 실행 결과" Jenkins Job 실행 결과 끝~

    Github과 Jenkins 연동하기

    Jenkins에서 Github의 소스를 가져와서 빌드를 하는 등 Github과 Jenkins와 연동을 시켜줘야하는 상황에서, 별도의 선행 작업이 필요하다. 다른 여러 방법이 있을수 있는데 여기서는 SSH로 연동하는 방법을 알아보고자 한다.우선 Jenkins가 설치되어있는 서버에서 인증키를 생성하자. $ ssh-keygen -t rsa -f id_rsa Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in id_rsa. Your public key has been saved in id_rsa.pub. The key fingerprint is: SHA256:~~~~~ ~~~@~~~~~ The key's randomart image is: +---[RSA 2048]----+ | o*+**=*=**+ | | o B=o+o++o | | E+.o+ + oo .| | oo. * o ...| | .+ S = o | | . + o . | | . . . | | . | | | +----[SHA256]-----+ $ ls id_rsa id_rsa.pub 개인키(id_rsa)는 젠킨스에 설정해준다. (처음부터 끝까지 복사, 첫줄 마지막줄 빼면 안된다… ) 젠킨스에 SSH 개인키 설정" 젠킨스에 SSH 개인키 설정 그 다음 공개키(id_rsa.pub)는 Github에 설정을 해준다. Github에 SSH 공개키 설정" Github에 SSH 공개키 설정 이렇게 한뒤 Jenkins 에서 임의로 job을 생성하고 job 설정 > 소스코드 관리 에서 git 부분에 아래처럼 테스트를 해서 정상적으로 연동이 된것을 확인한다. Credentials 값을 위에서 설정한 개인키로 설정하고, repo 주소를 SSH용으로 적었을때 에러가 안나오면 성공한것이다. @@ -48,5 +54,4 @@ https://hexo.io/themes/index.html 기존에는 hueman이라는 테마를 사용하고 있었는데 (링크), 오랜만에 블로그를 다시(?) 시작하는 느낌을 내보고 싶었고 보다 더 심플하고 유행에 안탈것 같은(순전히 필자 생각) 테마를 찾아보다 tranquilpeak이라는 테마를 선택하게 되었다. 공식홈페이지 : https://github.com/LouisBarranqueiro/hexo-theme-tranquilpeak 샘플사이트 : http://louisbarranqueiro.github.io/hexo-theme-tranquilpeak/ 우선 간략하게 설치과정을 나열해보면 다음과 같다. themes 폴더내에 테마파일을 받은후 압축 해제 테마 폴더 이름을 변경 _config.yml 파일 내에 테마 설정 부분 변경 ( theme: tranquilpeak ) hexo clean → hexo generate → hexo server(or hexo deploy) 이렇게 하면 아주 간단하게 테마가 변경이 된다. 혹여나(필자처럼) 기존 테마를 커스터마이징 하고 싶을 경우는 별도의 과정이 추가로 필요하다. 기존에는 css나 js만 변경하면 간단히 수정되었는데 이 테마는 약간의 빌드(?)를 필요로 한다. 따라서 css나 js등 html 요소들을 수정하였다면 다음과 같은 과정이 필요하다.(테마폴더 최상위에서) -npm install bower install css 나 js 변경 grunt build hexo clean → hexo generate → hexo server(or hexo deploy) 나같은 경우는 테마에 적용된 폰트를 바꾸기 위해 블로그 를 참조하였다. (해당 아티클에다 댓글폭탄을 ㅎㅎ;;)

    다시 시작하자

    마지막 포스팅을 한지 벌써 3개월이 지났다. 그렇게 바빴던것도 아니고 블로그포스팅을 할 시간이 안난것도 아닌데 어느덧 다시 정신차리고 블로그를 포스팅 하려고보니 3개월이라는 시간이 흘러버렸네챗바퀴같은 일상, 느즈막히 일어나서 회사출근하고 정신없이 일하다가 퇴근, 그리고 늦게까지 잠못이루다 또 다음날이면 느즈막히 일어나고… 뭔가 변화가 필요하다. -매일 일기쓰기 : 일기라고 해봤자 거창한건 아니고 딱 3개월만 써보자. 오늘 뭐했는지. 자기전에 딱 10분이면 좋을듯 아침에 일찍 일어나기 : 월수금 수영에 화목 배드민턴. 주말에도 일찍일어나고. 일찍일어나면 먹이도 더 먹는다고 하지 않았던가 달력활용하기 : 운동하는것도 그렇지만, 달력을 자주 보면서 빼먹지 말아야 할 중요한 날들은 반드시 메모하고 기억하자 기타 : 책좀 많이 읽고 운동도 꾸준히 해야겠다. 물론 기술블로그 포스팅도 잊지말고. 첫술에 배부르랴. 하나둘씩 퍼즐 맞춰나가듯 해보다보면 내 자신이 바뀌어 있겠지.
    \ No newline at end of file +npm install bower install css 나 js 변경 grunt build hexo clean → hexo generate → hexo server(or hexo deploy) 나같은 경우는 테마에 적용된 폰트를 바꾸기 위해 블로그 를 참조하였다. (해당 아티클에다 댓글폭탄을 ㅎㅎ;;)
    \ No newline at end of file diff --git a/page/9/index.html b/page/9/index.html index fb3e8cc1..19f52e66 100644 --- a/page/9/index.html +++ b/page/9/index.html @@ -1,5 +1,6 @@ -👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    mybatis insert/update 쿼리실행후 결과 가져오기

    Select문이 아닌 다른 SQL Query(insert, update 등) 를 실행하고서 결과를 봐야하는 상황이 생긴다. 정확히 잘 수행되었나에 대한 확인. 어떻게 쿼리가 잘 수행되었나를 확인하는 방법은 다음과 같다. ※ 참고 url : http://www.mybatis.org/mybatis-3/ko/sqlmap-xml.html +👨‍💻꿈꾸는 태태태의 공간
    /images/profile.png

    다시 시작하자

    마지막 포스팅을 한지 벌써 3개월이 지났다. 그렇게 바빴던것도 아니고 블로그포스팅을 할 시간이 안난것도 아닌데 어느덧 다시 정신차리고 블로그를 포스팅 하려고보니 3개월이라는 시간이 흘러버렸네챗바퀴같은 일상, 느즈막히 일어나서 회사출근하고 정신없이 일하다가 퇴근, 그리고 늦게까지 잠못이루다 또 다음날이면 느즈막히 일어나고… 뭔가 변화가 필요하다. +매일 일기쓰기 : 일기라고 해봤자 거창한건 아니고 딱 3개월만 써보자. 오늘 뭐했는지. 자기전에 딱 10분이면 좋을듯 아침에 일찍 일어나기 : 월수금 수영에 화목 배드민턴. 주말에도 일찍일어나고. 일찍일어나면 먹이도 더 먹는다고 하지 않았던가 달력활용하기 : 운동하는것도 그렇지만, 달력을 자주 보면서 빼먹지 말아야 할 중요한 날들은 반드시 메모하고 기억하자 기타 : 책좀 많이 읽고 운동도 꾸준히 해야겠다. 물론 기술블로그 포스팅도 잊지말고. 첫술에 배부르랴. 하나둘씩 퍼즐 맞춰나가듯 해보다보면 내 자신이 바뀌어 있겠지.

    mybatis insert/update 쿼리실행후 결과 가져오기

    Select문이 아닌 다른 SQL Query(insert, update 등) 를 실행하고서 결과를 봐야하는 상황이 생긴다. 정확히 잘 수행되었나에 대한 확인. 어떻게 쿼리가 잘 수행되었나를 확인하는 방법은 다음과 같다. ※ 참고 url : http://www.mybatis.org/mybatis-3/ko/sqlmap-xml.html useGeneratedKeys, keyProperty 옵션 사용하는 데이터베이스가 자동생성키를 지원한다면(mySql 같은) 해당옵션을 이용해 결과를 리턴 받을수 있다. 예로들어 파라미터로 아래 모델객체를 넘긴다고 가정하고 public Student { int id; String name; String email; Date regist_date; } 아래 mybatis 구문으로 insert를 시도하게되면, 파라미터로 넘긴 Student 객체의 id값에 insert 했을때의 key값(id)이 들어오게 된다. Student student = new Student(); student.setName('bla'); student.setEmail('bla@naver.com'); mapper.insertStudents(student); // 쿼리실행 student.getId(); // 추출 가능 <insert id="insertStudents" useGeneratedKeys="true" keyProperty="id" parameterType="Student"> insert into Students ( name, email ) values ( #{name}, #{email} ) </insert> selectKey 옵션 Oracle 같은 경우는 Auto Increment 가 없고 Sequence를 사용해야만 하기 때문에 위 옵션을 사용할수가 없다. 하지만 다른 우회적인(?) 방법으로 위와같은 효과를 볼수가 있다. 파라미터의 모델이나 java구문은 위와 동일하고 xml 쿼리 부분만 아래와 같이 설정해주면 된다. @@ -42,6 +43,4 @@ # logback 설정파일 일반적으로 logback.xml 이라는 이름으로 만들어 src/main/resources/아래에 위치하게 된다. Spring-Boot 환경에서는 logback-spring.xml 이라는 이름으로 설정해야 하는데 logback.xml로 설정하면 스프링부트가 설정하기 전에 로그백 관련한 설정을 하기 때문에 제어할 수가 없게 된다. ( 공식사이트 메뉴얼 : https://logback.qos.ch/documentation.html ) <?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> <!-- 변수 지정 --> <property name="LOG_DIR" value="/logs" /> <property name="LOG_PATH_NAME" value="${LOG_DIR}/data.log" /> <!-- FILE Appender --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH_NAME}</file> <!-- 일자별로 로그파일 적용하기 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH_NAME}.%d{yyyyMMdd}</fileNamePattern> <maxHistory>60</maxHistory> <!-- 일자별 백업파일의 보관기간 --> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%F]%M\(%L\) : %m%n</pattern> </encoder> </appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%F]%M\(%L\) : %m%n</pattern> </layout> </appender> <!-- TRACE > DEBUG > INFO > WARN > ERROR, 대소문자 구분 안함 --> <!-- profile 을 읽어서 appender 을 설정할수 있다.(phase별 파일을 안만들어도 되는 좋은 기능) --> <springProfile name="local"> <root level="DEBUG"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> </springProfile> <springProfile name="real"> <root level="INFO"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> </springProfile> </configuration> java 코딩에서의 로깅 실제 사용은 다음과 같이 LoggerFactory를 이용해서 사용하거나 Lombok어노테이션을 활용하면 심플하게 사용이 가능하다. LoggerFactory 사용 import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Foo { static final Logger logger = LoggerFactory.getLogger(Foo.class); public void test() { logger.debug("ID : {}", "foo"); } } Lombok 어노테이션 사용 import lombok.extern.slf4j.Slf4j; @Slf4j public class Foo { public void test() { log.debug("ID : {}", "foo"); } } 마치며 일반적인 웹 어플리케이션에서는 WAS에서 로깅을 따로 관리하고 있기 때문에 file 로 로깅을 할 필요는 없을것 같다.(일반 jar 형태에서는 파일 로깅이 필요 할수도…) -참고사이트 http://yookeun.github.io/java/2015/11/10/log4jtologback/ http://java.ihoney.pe.kr/397 https://logback.qos.ch/

    자바 8 Date

    이제까지 내 기억으로는 Date 관련 클래스를 아래처럼 점차 바꿔써온걸로 기억이 난다. java.util.Date > java.util.Calendar > org.joda.time 그런데 java 8 버전에서 기존에 있었던 문제들을 개선해서 나왔다고 한다. (네이버 HellowWorld 포스팅 참고) JSR-310 이라는 표준명세로. -지금부터는 JAVA 8 에서 제공하는 API로 날짜 연산을 어떻게 하는지에 대해 알아보고자 한다. (물론 수많은 날짜 연산 방법을이 있지만 자주 쓰이는 부분들 위주로 정리해보자.) -Date > String (format) LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); String > Date (format) LocalDateTime.parse("2017-01-01 12:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 날짜/시간 증감 LocalDateTime localDateTime = LocalDateTime.of(2017, 1, 1, 10, 0, 0); localDateTime.plusDays(1); // 일 localDateTime.plusMonths(1); // 월 localDateTime.plusHours(1); // 시간 localDateTime.plusWeeks(1); // 주 localDateTime.minusYears(1); // 년 localDateTime.minusMinutes(1); // 분 더 다양한 내용들은 아래 URL 에서 확인이 가능하다. https://docs.oracle.com/javase/tutorial/datetime/iso/overview.html
    \ No newline at end of file +참고사이트 http://yookeun.github.io/java/2015/11/10/log4jtologback/ http://java.ihoney.pe.kr/397 https://logback.qos.ch/
    \ No newline at end of file diff --git a/posts/a-combination-of-swagger-and-spring-restdocs/index.html b/posts/a-combination-of-swagger-and-spring-restdocs/index.html index 5874dfa9..21a43f3c 100644 --- a/posts/a-combination-of-swagger-and-spring-restdocs/index.html +++ b/posts/a-combination-of-swagger-and-spring-restdocs/index.html @@ -153,4 +153,4 @@ swaggerapi/swagger-ui

    도커에 익숙하지 않는 독자들을 위해 (그중에 필자도 포함…) 명령어를 분석해보면 다음과 같다.

    구문설명
    -d백그라운드 모드로 실행
    -p 80:8000포트 바인딩. 외부에서 80으로 접속하면 내부 8080으로 바인딩 시킨다.
    -e URLS_PRIMARY_NAME=SpringRestdocs첫번째 보여질 URL 이름의 환경변수
    -e URLS=””Swagger UI 에서 보여줄 API 정의 문서 환경변수. 여러개인 경우 JSON 배열형식으로 표현한다.
    -v /home/data:/usr/share/nginx/html/docs/볼륨 바인딩. 로컬의 /home/data 를 도커 내부의 /usr/share/nginx/html/docs/ 으로 바인딩 시킨다.
    swaggerapi/swagger-ui해당 이미지를 띄운다.

    도커에 대한 보다 자세한 설명은 도커 공식문서를 보는게 좋고 Swagger UI 의 옵션에 대한 내용 역시 Swagger UI 공식문서를 참조하는게 좋을것 같다.

     이렇게 띄우고 나면 어떤 모습일까? 백문이 불여일타. 실행해보고 화면을 살펴보자.

    /images/a-combination-of-swagger-and-spring-restdocs/swagger-ui.png
    여러 API 문서를 한곳에서!

    좌측은 처음 접속했을 때의 화면. 위에서 설정한 대로 SpringRestdocs로 만들어진 API 문서가 먼저 보이고 SpringRestdocs에서 만들어졌던 내용들이 그대로 Swagger UI에서도 동일하게 볼 수 있다. 우측 상단에 셀렉트 박스에서 Swagger로 만들어진 API 문서를 선택해보면 당연히 얼마 전에 만들었던 Swagger로 만든 API 문서를 확인할 수 있다.

    마치며 

     이렇게 되면 SpringRestdocs의 장점인 테스트를 통과한 검증된 API의 문서 와 Swagger의 장점인 Web UI에서 테스트 가능 한 두마리 토끼를 다 잡은 결과를 만들 수 있었다. 또한 필자가 고민했던 MSA 환경에서 여러 곳에 흩어진 API 문서를 한곳에서 모으는 효과까지. 일석삼조의 효과를 경험할 수 있어서 너무 좋았다.

     더불어 Swagger 와 SpringRestdocs는 약간 라이벌처럼 각자의 장단점이 있다 정도로만 생각했는데 이 둘을 상황에 맞춰 조합을 하니 오히려 시너지효과를 얻을 수 있던 점 또한 너무 좋았다.

     고민은 누구나 하지만 결국 끈기 있게 파고들어 해결했는가가 더 중요하다는 점을 다시 한번 느낄 수 있었다.

    ‘꿩 먹고 알 먹고 둥지 털어 불 때고’, ‘도랑 치고 가재 잡고 발 담그고 물 구경 하고’, ‘마당 쓸고 동전 줍고’, ‘누이 좋고 매부 좋고’, ‘님도 보고 뽕도 따고’. ‘포스팅하고 내 것으로 만들고’


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/a-good-developer-in-terms-of-employment/index.html b/posts/a-good-developer-in-terms-of-employment/index.html index be790302..95ec90c8 100644 --- a/posts/a-good-developer-in-terms-of-employment/index.html +++ b/posts/a-good-developer-in-terms-of-employment/index.html @@ -19,4 +19,4 @@  8 minutes 

     몇 달 전부터 좋은 기회가 생겨 이제 막 개발자의 길로 들어서는 분들과 다양한 색깔들로 이야기를 나누고 있다. 과거 필자가 막 취업을 했을 때의 온도와는 확연하게 다르지만 확실하게 이야기할 수 있는 건, 이미 개발자라는 직업으로 10년 가까이 지내보니 무엇이 중요하고 어떤 것들은 자신을 갉아먹는 존재라는 게 뻔히 보인다는 점이다. 하지만 그 어느 누구도 처음 시작점에서는 당연히 힘들어할 수밖에 없는데 그 과정을 무작정 싫어만 한다거나 그 힘듦을 못 견디고 포기 또는 잘못된 선택(일단 어디라도 붙으면 무조건 가자는 식의)을 하게 되는 점이 너무 안타깝다. 만약 어떠한 ‘공식’처럼 중요한 것만 바라보고 필요 없는 것들은 하지 않는 식으로 하면 개발자라는 직업을 갖는 직장인의 삶은 과연 행복할까? 아니 그게 가능하긴 할까?

     이런저런 과정을 거쳐서 취업에 성공했다고 가정해 보자. 과연 우리가 꿈꾸던 아름답고 멋진 개발자 라이프가 보장이 될까? (물론 사람마다 회사마다 다르지만) 야근은 밥 먹기 일쑤고 모르는 거 투성에 매번 실수하거나 혼나고 좌절의 연속. 드디어 취업했다!라는 외침이 온 데 간 데 사라지고 스트레스가 반복되어 결국 퇴사를 생각하거나 정신 차려보니 나도 모르게 CRUD (create, read, update, delete) 찍어내는 기계가 되어버리곤 한다. 무엇이 문제일까? 이런 생활을 기대하고 취업한 건 아닐 텐데 말이다.

    /images/a-good-developer-in-terms-of-employment/news.jpg
    개발자 전성시대, 이대로 좋은가
    출처 : https://news.nate.com/view/20210226n37680

     이번 포스팅에서는 이제 막 ‘개발자’라는 직업을 가지려는 분들이나 직장인으로서 시작은 했는데 어떠한 이유로 지친다거나 매너리즘에 빠진 분들께 조금이나마 도움이 될까 하여 필자의 생각을 정리해 보고자 한다. 왜 본인이 수많은 직업 중에 하필 ‘개발자’를 선택했는지, 그리고 취업을 하고자 할 때 생각해 봐야 할 몇 가지들에 대해 이야기해보자.

    왜 하필 ‘개발자’인가

     한국 고용정보원이 2020년 발간한 「한국 직업사전 통합본 제5판」에 따르면 2019년 12월 기준으로 우리나라 직업의 종류는 16,891개라고 한다. 산업이 발달됨에 따라 다양한 직업들이 생겨나기에 지금은 훨씬 더 많을 것으로 예상된다. 그런데, 이 수많은 직업들 중에 왜 하필 우리는 ‘개발자’라는 직업을 선택하려는 걸까? 관련 전공을 나와서? 요즘 인기 있는 직업이라서? 한 번쯤은 아니, 꼭 이런 생각을 며칠에서 몇 달 동안 깊게 고민해 봤으면 좋겠다. 왜 나는 개발자로써 살아가려 하는 것인지에 대해서 말이다.

     이력서 혹은 자기소개서에 ‘입사 포부’라는 문항이 자주 나타난다. 그곳에는 본인이 개발자가 되어야만 하는 이유에 대해 다양한 미사여구를 붙여가며 작성하기 마련인데 그렇게 ‘보여주기식’내용 말고 정말 내가 개발이 ‘재밌는지에’ 대해 반문을 해보는 과정이 필요하다. 개발을 하는 과정 속에서 나는 어느 상황에서 재미를 느끼는지. 새로운 기술을 배울 때, 몇 날 며칠 동안 삽질을 하다 해결을 했을 때, 내가 개발한 애플리케이션을 누군가 사용할 때 등등. 찾아보면 다양한 시점에서 우리는 개발을 하며 재미를 느낄 때가 있다.

     눈치를 챘을 수도 있지만 필자가 말하고 싶은 건, 개발자라는 직업을 선택하려면 개발이 재미있어야 된다는 말이다. 반문을 해보자. 그럼 만약에 개발이 재미없다면 어떨까? 개발자로써 살아갈 수 없는 것일까? 일반화하긴 싫지만 개발이 재미가 없으면 개발자로써 살아가기에 너무 힘들 것 같다. 검정 화면에 영어로 된 글자들을 만져가며 홀로 고독하게 자신과의 싸움을 하는 시간들의 연속일 텐데 재미라도 있지 않다면, 더군다나 그게 하루의 절반 이상을 할애하는 ‘직업’이라면 오래 유지하는데 힘들지 않을까?

    /images/a-good-developer-in-terms-of-employment/ebs.jpeg
    그래도 오늘이 몇일인지는 알고 하자.
    출처 : https://bbs.ruliweb.com/community/board/300143/read/49006211

     당장 개발이 재미없어도 좋다. 태어날 때부터 개발이 재밌어서 돌잡이 때 기계식 키보드를 잡는 사람은 없듯 누구나 약간의 호기심에서 개발을 시작하기 마련인데 여기서 중요한 점은 개발의 재미를 본인만의 호흡으로 찾는 습관을 들여야 한다는 것이다. 예컨대, 필자는 회사에서 이런저런 이유로 개발이 재미 없어지거나 쳐다도 보기 싫을 상황이 생기면 무언가를 만들어 보거나(=토이 프로젝트) 모르는 부분이 생겼다면 깊게 파고 들어 어떻게든 해결하려고 노력하는 과정을 어딘가에 정리하며(=기술 블로그) 무너지지 않으려 개발의 재미를 유지하려 애써온 것 같다. 이 글을 읽고 있는 당신은 어떤 상황에서 개발의 재미를 느끼는가. 본인만의 호흡을 찾아서 개발이 재미있도록 습관을 길러보는 건 어떨까.

    엄청난 삽질과 고통의 연속. 그래도 할 것인가

     예전에 한창 유행처럼 번졌던 ‘내가 생각하는 프로그래머의 삶.txt’ 이라는 내용을 잠깐 살펴보자.

    판교 한복판 복층 오피스텔, 아침 9시 기상, 탄력근무제라 10시에 출근할 계획
    잉글리스 토스트와 베이컨 & 서니사이드업 에그, 간단한 식사
    전동 스쿠터를 타고 출근, 5분 만에 회사 도착
    회사 카페에서 커피 한 잔 주문(직원은 무료)
    커피를 마시며, 회사 내부망에 접속
    2인 1조로 일하는데 1명은 유럽으로 휴가 중이라는 공지
    새로운 이슈가 생겼는지 느낌표 알림을 클릭하니 버전 업된 환경이 구형 시스템과 새로운 충돌을 일으킨 모양, 간단히 3줄 고쳐주니 잘 돌아감.
    회사 내부 시스템은 빌드부터 테스트, 최종 시스템에 로드까지 원클릭 전자동이라 단지 푸시 한 번만 해주면 끝.
    어느덧 점심시간 회사 식당에서 유기농 식단으로 간단하게 식사한 후 정자역까지 산책
    오후는 회사 업무와 상관없는 사이드 프로젝트 진행 이번에 회사에서 따로 개발 지원금을 받은 상태라 동료들과 열심히 개선 작업 중
    오후 4시 퇴근, 헬스장으로 향해 운동
    띠리링 폰. 월급이 입금되었다는 문자, ‘월 급여 9,879,800원'
    집에 도착해 와인 한 잔과 함께 크롬 실행
    ‘프로그래밍 갤러리’ 접속
    ※ 출처 : 프로그래밍 갤러리

     위 내용이 100% 거짓이라는 말은 못 하겠지만 엄청난 슈퍼 개발자가 다니는 상위 0.0001%의 회사임에는 틀림없다. 다시 말하면 현실과는 너무 괴리감이 있다는 이야기. 위 내용을 필자의 생활에 대입을 해보자면,

    어제 새벽까지 일을 해서인지 퉁퉁 부은 얼굴로 부스스하게 회사에 출근하고
    김밥에 우유를 먹으며 쌓여있는 메일함을 읽다 보니 옆 팀원이 점심 먹으러 가자고 한다.
    커피를 마실 여유조차 없이 자리에 앉아 버그와 싸움을 하고
    점심에 먹었던 라멘 면발처럼 스파게티 코드들은 아프다며 tc fail의 연속이고
    회의는 또 왜 이렇게 많은지 이제 좀 여유가 생기니 저녁 먹을 시간.
    10분만 더, 5분만 더 하며 코드를 만지작거리다 정신 차려보니 사무실의 등대가 되어있는 내 자리.
    지하철 막차를 타고 집으로 돌아와 한숨을 돌리고 침대에 누워보지만
    아까 만지던 코드를 좀 더 잘 짜고 싶은 맘에 VPN으로 접속하여 쪼금만 봐야지 하다가
    끝끝내 해결을 하고는 기분 좋은 마음에 잠자리에 들려고 보니 새벽 1시 반.
    띠리링 폰. 자려고 하니 이제는 서버가 아프다며 알림 문자를 보내온다. (cpu 사용률이 90% 이상입니다.)
    다시 VPN 접속
    ※ 출처 : 필자.

    어떤 부분은 과장이 섞여있을지 모르겠지만 말하고자 하는 건 개발자의 삶은 마냥 장밋빛이 아니라는 점이다.

     개발자라는 직업을 갖고 살아가려면, 적어도 1~2년 ‘체험’할게 아니라면 이러한 고통의 연속은 필연적으로 만날 수밖에 없고 내가 원래 이렇게 삽질을 잘했었나 싶을 정도로 지구 내핵까지 삽질을 하는 경우가 비일비재할 것이다. 필자는 스마트폰이 이제 막 나오는 시절부터 개발을 시작했는데 요즘엔 AI며 머신러닝이며 등등 배워야 할 내용이 홍수처럼 많아져서 매일 공부를 해야 한다는 압박이 있을 수밖에 없고, 아주 초창기 개발 멤버로 시작해도 겪는 문제지만 레거시(legacy)와의 싸움은 아무리 해봐도 정답이 없을 정도로 어렵다. 그럼에도 불구하고 오랫동안 개발을 하고 있는 필자를 포함한 대부분의 사람들의 공통점은 (또 말하지만) 그렇게 개발이 재밌다는 점이다.

    /images/a-good-developer-in-terms-of-employment/insta.jpg
    솔직히 저때 좀 재밌었음
    출처 : 필자 instagram

     필자는 다시 태어나도(?) 개발자로써 일을 할 것인가에 대한 물음이 있다면 1초도 망설이지 않고 ‘예’라고 답변을 할 것 같다. 이야기하고자 하는 건, 요즘 뉴스나 겉으로 보이는 개발자의 멋지고 아름다운(?) 모습만 바라보고 뛰어들지 말고 정녕 자신이 얼마나 개발에 대해 생각을 하고 있는지. 어떠한 상황이 오더라도 흔들리지 않는 ‘신념’이 있어야 한다는 점이다. 그렇게 하기 위해서는 차곡차곡 개발자로서의 마음을 쌓아올려야 한다. 첫술에 당연히 배부를 수 없고 혹여 배부르다 해도 금방 고꾸라질 마련일 테니까 말이다.

    버려야 할 첫 번째 단어 ‘조급함’

     취업을 준비하는 분들과 이야기를 하다 보면 가장 많이 나오는 이야기가 ‘조급함’이다. 물론 개인적인 상황으로 인해 돈을 빨리 벌어야 한다거나, 나이가 남들보다 많아서 일단 취업부터 하고 보자는 식으로 방향타를 잡곤 하는데 지금 당장 눈앞에 보이는 상황들은 해결이 될지 모르겠지만 자칫 그 선택이 잘못되어 돌이킬 수 없는 상황으로 변질되는 경우가 많다.

     그러한 상황을 이해 못하는 건 아니지만 적어도 10년 ~ 20년 정도를 바라보고 개발자로써 뛰어든다고 가정했을 때, 전체에 비하면 지금의 시간은 너무 작은 순간들이다. 다양한 방법으로의 시간을 투자하여 노력을 하면 충분히 더 좋은(?) 기회나 회사로의 취업이 가능하다고 확신한다. 그래서 여러 곳의 회사에 취업문을 두드리다 한 곳에서 최종 합격까지 왔다고 해도 계속 다른 회사들도 두드려 보다 어느 정도 괜찮은 회사를 본인이 ‘선택’하는 상황을 만들어야 될 것 같다. 회사의 사업 성장성이나 규모, 배울 수 있는 곳인지, 처우 등 다양한 관점으로 첫 회사를 선택해야지 그렇지 않고 눈앞의 상황에 ‘묻지 마 결정’을 해버린다면 첫 단추가 꼬이는 순간도 생길 수 있을 것 같아서이다.

     취업을 떠나 인생에서 ‘조급함’은 본인의 부분을 갉아먹는 안 좋은 마음이라 생각한다. 조금 더 여유를 가지고 넓게 바라보고 선택해도 돌이켜 보면 그렇게 조급하지 않아도 될 선택이었다고 느낄 때가 생각보다 많기 때문이다.

    버려야 할 두 번째 단어 ‘비교’

     나 홀로 취업을 준비하거나 교육기관 또는 스터디를 통해 취업을 준비하다 보면 아무래도 주변이 신경 쓰이게 마련이다. 누구는 본인보다 그렇게 개발 실력이 좋아 보이지 않았는데 본인은 탈락한 A 회사에 최종 합격했다거나, 누구는 본인이 떨어진 코딩 테스트를 합격했다거나, 본인은 어려워하는 기술들을 누구는 능수능란하게 써가며 이야기한다거나 등등. 그런데 여기서 묻고 싶은 점. 과연 본인은 그 어느 누구보다도 단 1도 잘하는 게 없는가. 혹시 어떤 누군가는 당신을 부러워하고 있진 않을까.

     위에서 이야기했던 ‘조급함’에 1+1처럼 따라다니는 게 ‘비교’인 것 같다. 잘 안될 때는 본인 자체의 어떠한 이유가 있거나 아니면 운이 좋지 않았거나 했을 텐데 유독 다른 사람과 비교를 하며 본인 자신을 깎아내리곤 한다. 하지만 그래봤자 힘들어지는 건 본인뿐 그 누구도 본인을 다른 사람과 비교하며 깎아내리지 않았다. 남들이 좋은 회사나 좋은 처우를 받고 간다 해도 부러워할 필요가 전혀 없다. 그건 남의 인생이지 본인의 인생이 아니기 때문. 너무 뻔한 이야기일지 모르겠지만 남들과 본인 자신을 비교하지 말고 묵묵하게 호흡 챙기면서 가다 보면 반드시 좋은 성과가 있을 거라 자부한다.

     개발자로써 취업을 했다고 해도 끝나는 게 아니다. 개발자라는 직업은 은퇴할 때까지 기술을 배워야 하는 직업임에는 틀림없다. 그만큼 마라톤처럼 오랫동안 견뎌낼 수밖에 없는 직업인데 바로 앞에 결과들에 대해 일희일비 하기엔 우리들의 인생이 너무 아깝지 않을까. 어떠한 경로를 통해서 이 글을 읽고 있는 독자분들은 좀 더 좋은 개발자가 되어보겠다는 마음이 조금이나마 있다고 생각이 든다. 하지만 이런 고민하나 없이 하루살이처럼 지내는 개발자들도 많다. 누가 옳고 누가 틀린 건 없다. 그저 다른 것뿐이다.

    마치며

     필자도 신입 시절에 Spring 코드를 A4로 전부 출력해서 보라는 어떤 사수 님의 잔소리에 극심한 스트레스를 받곤 했었다. 하지만 지금 돌이켜 보면 그렇게 필자를 챙겨준 사람이 없을 정도의 시절을 살아가는 것 같다. 힘들면 누군가에게 기대도 된다. 다만 이 글에서 필자가 이야기하고 싶은 건 정말 개발자를 하려면 선배 개발자들의 목소리를 듣고 내 것으로 만드는 과정이 필요하고, 거기에 왜 내가 개발자를 하려고 하는가라는 거시적인 관점에서 고민해 볼 필요가 있다는 점이다.

     가령, 그러한 고민을 하고 ‘아! 나는 개발자 하면 안 되겠다.‘라는 결론으로 도달할 수도 있겠지만 그게 꼭 나쁜 건 아니다. 모든 선택은 본인의 책임이 따르고 후회만 하지 않으면 그걸로 ok. 개발자는 이러이러한 고통이 따르니 하지 말라는 게 아니라 ‘직업’은 가급적 본인이 ‘재미’를 느낄 수 있는 것을 해야 오래 할 수 있고 나아가 행복할 수 있을 거라 생각이 들기 때문이다.

    /images/a-good-developer-in-terms-of-employment/취뽀부적.jpg
    가보자고
    출처 : https://www.instagram.com/gosimperson

     이제 개발자로 시작하려는 모든 분들께. 목이 터져라 이야기하고 싶은 그 한마디. 제발 좀 개발을 재미있게 했으면 좋겠다. Good Lock!


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/a-good-developer-in-terms-of-group-study/index.html b/posts/a-good-developer-in-terms-of-group-study/index.html new file mode 100644 index 00000000..e8282e90 --- /dev/null +++ b/posts/a-good-developer-in-terms-of-group-study/index.html @@ -0,0 +1,21 @@ +그런 개발자로 괜찮은가 - '그룹 스터디' 편 - 👨‍💻꿈꾸는 태태태의 공간

    Contents

    그런 개발자로 괜찮은가 - '그룹 스터디' 편

     다양한 방식으로 스터디를 해왔다. 정말 많은 것을 배웠던 스터디도 있는가 반면에 지나고 보면 시간이 아까울 정도의 스터디도 있었던 것 같다. 직접 만들어 보기도 했고 참여도 해봤던 것 같다. 이런저런 경험들 끝에 작년 중순에 직접 만들었던 스터디 멤버와는 어느덧 반년을 넘어가고 있는데 바쁜 회사 생활을 하면서도 이제까지 지속할 수 있었던 노하우를 공유해 보고자 한다.

    그룹 스터디 방식

    인원

     다 그런 건 아니지만 기존 회사 분들과 스터디를 할 때면 아무래도 원래 알던 사이라 바빠서 준비를 못 해오거나 불참을 하는 경우에 “그럴 수도 있지”, “괜찮아” 하며 관대해졌던 것 같다. 또는 다양한 의견을 듣자며 10명 이상 진행을 했던 것 같다. 그렇다 보니 스터디 진행에 집중도가 떨어질 수밖에 없었고 모였을 때 이야기하던 사람들만 이야기한다든지, 중도 하차하는 경험도 많았다.

    /images/a-good-developer-in-terms-of-group-study/blind.png
    블라인드 글에 첨부한 스터디 참여 설문

     이번 스터디는 직접 ‘블라인드’라는 익명 커뮤니티를 통해 인원을 모았다. 작년 중순쯤 자바 백엔드 관련된 주제를 스터디 하겠다며 나와 비슷한 연차분들 위주로 모으겠다고 글을 작성했더니 신기하게도 3~40명 되는 분들이나 지원하셨고 그중 오프라인 모임을 고려해서 나 포함 6명 만으로 구성을 하였다.(뭔가 서류 전형 인사담당자가 된 느낌;;) 작은 규모 그리고 새로운 분들과 하게 되니 집중도가 오르는 경험을 할 수 있었고 무엇보다 6명 모두 다른 회사라 각 회사를 대표하는 것 같은 느낌이 들어 스터디 참여에 몰입이나 책임감이 더욱 올랐던 것 같다. 또한 한 주제에 대해 각 회사에서의 경험들을 이야기하다 보니 완전히 다른 시각을 얻을 수 있다는 장점도 있었다.

     별거 아닐 수도 있지만(또는 오해가 될 수도 있지만) 남녀 성비, 그리고 나이대(연차)를 최대한 맞추고 싶었다. 그래야 분위기가 적당히 딱딱하지도, 부드럽지도 않을 것 같았기 때문이다. 지금은 여자 한 분 나머지 남자분들이라 초반에 걱정도 되었지만 생각보다 분위기가 잘 흘러가서 다행이라 생각을 한다.

    주제와 목표

    /images/a-good-developer-in-terms-of-group-study/roadmap.png
    배워야 할게 한도 끝도 없는 개발자 세상
    스터디 목표에 따라 집중해야 할 범위를 좁히자!

     처음부터 모니터 받침으로 하기 좋을만한 두꺼운 책은 피했던 것 같다. 가볍게, 스터디원들끼리의 친밀도부터 올려야 한다는 생각으로 너무 딥 다이브 한 기술적인 내용보다는 누구나 한마디 정도 할 수 있을만한 가벼운 책부터 시작했다. 그러면서 최대한 참여도를 올리는데 집중했던 것 같다.

     어디까지나 “공부"를 하기 위한 모임이긴 하지만 이 또한 사람과 사람 사이의 “관계"가 중요하다고 생각했기에 모였을 때 바로 스터디 이야기를 하는 것보다 부드러운 아이스브레이킹을 자주 해왔다. 또한 너무 루즈 해지지 않게 1달~1달 반 정도로 끝날 수 있을만한 주제를 선정했다. 아무래도 한 주제가 2~3달 걸리다 보면 집중도가 떨어지는 경험이 많았기 때문이다. 책 한 권을 다 읽었다는 기간을 짧게 가져가면서 작은 성취의 효과를 최대한 활용하고 있다. 이번 회차가 벌써 네 번째인걸 보면 그래도 나름 잘 선택한 방법이라 생각이 든다.

     한 회차가 끝날 즈음엔 다음 스터디는 무엇을 할 것인지에 대해 이야기를 하고 다수가 동의하는 주제를 선정한다. 또한 매 회차가 끝날 때마다 어쩌면 어색할 수 있는 이야기지만 스터디 참여를 그만 둘지에 대해 의사를 분명히 물어본다. (그런데 신기하게도 지금 스터디 모임은 이런 이야기를 하기도 전에 스터디 하고 싶은 주제를 먼저 말씀해주시는 편이라, 어쩌면 스스로 사람 운이 좋다는 생각도 해본다.)

     그저 하나의 책을 읽기로 끝나는 “책 읽기 모임” 이 아닌 만큼 책을 기반으로 하는 스터디 모임일지라도 목표를 분명하게 잡는다. 여기서 목표는 개인마다 다를 수 있다. 가령 스터디 시간에 나왔던 내용을 각자의 팀에 공유 및 반영을 해본다든지, 스터디 내용에 대해 주도적으로 이야기를 하며 다른 분들의 지식을 훔쳐보겠다든지(?). 책 읽는 것으로 끝나면 안 되고 가능하다면 해당 내용을 실제로 경험하는 사이클까지 만드는 게 더 중요하지 않을까 생각을 해본다.

    최소한의 강제

     앞서 “그럴 수도 있지”, “괜찮아"라며 이해하고 넘어가는 상황을 최대한 피하기 위해 최소한의 강제 장치를 마련했다. 한 회차 시작 전에 각자 최소한의 책임감을 부여하기 위한 용도로 예치금을 걷는다. 혹시 중도 하차할 경우 다시 돌려주지 않겠다는 무서운(?) 공지와 함께. 일주일에 한 번씩 만나는 당일 무작위로 선정해 발표 형식으로 진행을 하는데 만약 준비를 못 해왔다거나 개인 사정으로 참여가 어려울 경우(그 사정이 어떤 사정이라도 무관) 벌금을 걷기로 했다. 물론 다음 스케줄을 매주에 정하는데 모두의 합의가 이뤄지면 변경하며 진행할 수 있지만 정해진 일정에 진행을 할 수 없게 되면 다른 사람들에게 다양한 피해를 주기 때문에 벌금이라는 최소한의 강제를 만들었다. 이렇게 모인 돈으로는 한 회차가 끝날 때 모여서 식사 비용으로 사용할 수 있어 일석이조의 효과를 누렸다.

     스터디를 하기 전에 혹시 너무 한 사람만 이야기하는 걸 방지하기 위해 그날의 호스트가 사회(?)를 잘 봐야 한다는 의무감을 줘야겠다 했었는데 지금의 스터디는 자연스럽게 모두가 다 참여하게 되는 분위기가 만들어졌고 가끔 온라인으로 모였을 때는 오디오가 겹치는 상황을 최대한 방지하기 위해 “손들기” 기능을 활용하여 race condition을 최대한 회피하고자 하였다.

    기타 여러 장치들

    /images/a-good-developer-in-terms-of-group-study/roulette.gif
    스터디 중에 가장 쫄깃한 순간 : 발표자 선정
    출처 : https://quasarzone.com/bbs/qb_humor/views/558834

     스터디 시작 전에 미리 발표할 영역과 담당 인원을 정하게 되면 본인이 담당이 아닌 영역일 땐 스터디의 집중도가 떨어지는 경험을 많이 해왔다. 그래서 모두 해당 영역에 대해 요약/정리를 하여 발표 준비를 해오고 스터디 당일 실시간으로 무작위 룰렛을 돌려 발표자를 선정하는 방식으로 진행했다. (사용하는 무작위 선정 툴 : 네이버 사다리, 룰렛) 정확히는, 발표자를 뽑는다기 보다 오늘 스터디를 진행하는 “호스트"에 더 가깝다. 선정된 호스트는 해당 영역에 대해 발표 또는 리뷰를 하고 토론을 진행한다. 무작위 그리고 토론이라는 장치가 긴장감을 주게 되고 이는 집중도를 올리는데 효과적이라고 생각한다.

     다들 바쁜 직장인들이다 보니 매주 모이는 게 현실적으로 어려운 경우도 있다. 처음엔 열정이라는 명목하에 잘 진행돼가다도 스터디의 내용이 어려워질 때면 집중도가 흐려질 수밖에 없다. 그래서 온라인 모임과 오프라인 모임을 적절하게 분배하고 한 달에 한 번 정도는 쉬는 “방학” 기간을 가지기도 한다. 그때는 개인 일정을 소화하거나 스터디 간에 못 따라 간 부분이 있다면 보충학습을 개별적을 갖기도 한다.

     앞서 이야기 한 것처럼 학습도 중요하지만 관계 또한 그만큼 중요하다고 생각하기에 평소에 단톡방을 활용하여 잡담도 나누고 각 회사/팀에서 가지고 있는 고민거리에 대해서 스스럼없이 주고받으며 어색함을 최대한 낮추는 노력을 통해 조금이나마 유대감을 형성하기도 한다.

    앞으로의 계획

     사실 이렇게 오랫동안 유지가 될 줄은 몰랐다. 신기하게도 구성원분들의 조합이 좋아서인지 오랫동안 지속될 수 있었던 것 같고 그러면서 매 스터디마다 회사에서 얻을 수 없었던 꽤 큰 인사이트를 얻기도 했다. 지난 약 6개월 동안 3번의 스터디를 해보니 단순히 책 읽는 것을 넘어서 서로 사례를 이야기하는 과정에서 배우는 게 더 많았던 것으로 기억되어 올해부터는 스터디 과정을 어딘가에 기록하고자 한다. 이를 바탕으로 스터디 팀 기술 블로그를 만들어 공유하면서 또 다른 인사이트를 얻는 장치로써 활용할 수 있을 것 같고 단순하게 책을 읽는 것을 넘어서 논의하는 시간을 더 많이 가져가며 집단지성의 힘과 기록의 힘, 거기에 공유의 힘까지 더해 스터디의 효과를 극한으로 끌어 올려보고자 한다.

    마치며

    /images/a-good-developer-in-terms-of-group-study/study.jpeg
    사람 살려
    출처 : https://www.fnnews.com/news/201112141617440705

     바빠 죽겠는데 사람들끼리 스터디를 어떻게 할 수 있느냐고 누군가 묻는다면 질문 속에 답이 있다고 말하고 싶다. 즉, 바빠 죽겠으니 혼자 무언가를 공부하는데 꾸준하게 지속하기 어려우니 다른 사람들과 규칙을 만들어 가면서라도 스터디를 진행하고 있다.(그렇지 않고서는 도태되는 불안함을 이겨내기 힘들기에)

     스터디는 참여하는 방식과 직접 만들어 이끄는 방식이 있다. 참여하는 방식은 다른 고민은 스터디를 운영하는 사람이 하게 되니 스터디 주제에만 집중할 수 있다는 장점이 있는가 반면 직접 만들게 되면 반대로 고민할 부분들이 더 많아질 수밖에 없지만 그만큼 최소한의 책임감이 생겨 더 적극적으로 스터디를 진행할 수 있게 된다는 장점이 있다. 그래서 가급적이면 스터디를 직접 만들어서 진행해 보는 것을 추천한다. 물론 성향에 따라 오히려 역효과가 날 수도 있지만.

     또 언젠가 스터디를 하게 된다면, 그리고 내가 직접 스터디를 만들게 된다면 앞서 말했던 방식으로 스터디를 진행해 볼 생각이다. 그리고 이러한 인연이 계속 지속되어 함께 성장하는 기쁨을 나누고 싶다. 이 글을 빌미 삼아 함께 스터디를 진행하고 있는 Team JSON 상하차 스터디원분들께 감사의 인사를 전한다.


    Buy me a coffeeBuy me a coffee +
    \ No newline at end of file diff --git a/posts/a-good-developer-in-terms-of-mentoring/index.html b/posts/a-good-developer-in-terms-of-mentoring/index.html index ab8c69dd..8ce1bb56 100644 --- a/posts/a-good-developer-in-terms-of-mentoring/index.html +++ b/posts/a-good-developer-in-terms-of-mentoring/index.html @@ -25,4 +25,4 @@  사전적 의미로 멘토는 조력자 역할을 하고 멘티는 그 조력을 받는 사람을 일컫는다. 어떤 인연이 되어 멘토-멘티 관계가 맺어졌다고 해보자. 그러면 멘토의 위치, 멘티의 위치에서는 각각 서로에게 어떻게 다가가고 어떤 점을 조심하며 멘토링을 이어나가야 서로에게 도움이 되는 건강한 관계가 유지될 수 있을까?

     멘티는 도움을 ‘요청’하는 입장이기 때문에 요청하고자 하는 핵심을 간결하게 전달해야 하고 자신을 위해 소중한 시간을 할애해 주는 멘토를 위해 최대한 조심스럽게 다가가야 한다고 생각한다. 그렇다고 무조건 자세를 낮추기만 하라는 이야기는 아니지만 (계약된 관계가 아니라면) 멘토는 멘티의 요청에 응답해야 할 의무는 없기 때문이다. 더불어 멘티가 멘토에게 먼저 다가가는 자세를 갖는다면 멘토 입장에서는 그런 멘티의 노력이 이뻐 보일 수밖에 없으니 하나를 물어보지만 열 가지를 알려주려 할 것이다. 마지막으로 가장 중요하게 생각하는 부분은 ‘피드백’을 받으려는 노력이다. ‘멘토님이 이렇게 해보라 해서 이렇게까지 해보았다’, ‘이렇게 해보았더니 이게 잘 안되더라’라는 식의 대화 속에서 혹시 잘못된 방향으로 가고 있을 경우 바로잡을 수 있는 기회가 생기기 때문이다.

     멘토는 멘티가 나무에 열린 감을 먹고 싶어 할 경우 직접 감을 따서 줄 수도 있지만 그렇게 되면 매번 감을 달라고 하는 불상사(?)가 발생할 수도 있다. 즉, 감을 직접 짜서 주는 게 아니라 감을 따는 방법에 대해 우회적으로 다양한 방안을 제시해 주는 게 좋다. 또한 다양한 방안을 제시하기 전에 주먹구구식으로 알고 있던 지식이 있었다면 이번 기회에 자세히 살펴보고 고민을 해보고 알려주는 것도 좋을 것 같다. 그렇다 보면 멘토와 멘티 모두 성장하는 선순환 문화가 자연스럽게 생겨날 수밖에 없다고 생각한다. 간혹 멘티의 물음은 너무 쉬우면서도 하찮을 수도 있다. 하지만 우리들은 모두 개구리 올챙이 시절이 있었기에 할 수 있는 선에서 최대한의 친절을 베풀어 멘토-멘티 관계가 어색히 지지 않도록 멘토로써도 주의를 가져야 할 것 같다. 더불어 멘토링을 어색해하는 멘티를 위해 먼저 다가가서 조언을 해주는 방법도 꽤 괜찮은 방법 같다. 나쁘게 보면 ‘오지라퍼’, ‘라떼 is 홀드’ 가 될 수 있지만 그런 조언을 해주며 본인 또한 다시 다잡는 기회로 만들 수 있기 때문이다. 물론 멘티가 쓸모없는 조언이라고 받아들이면 어쩔 수 없지만 멘토링은 멘토-멘티 모두 노력해야 하는 ‘관계’라는 점을 명심해야 한다.

    /images/a-good-developer-in-terms-of-mentoring/rest.jpg
    서로에게 필요가 되는 멘토링이 필요하다.
    출처 : https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=96613362

    마치며

      사실 필자는 신입사원부터 이렇다 할 사수나 멘토가 없었고 정말 나 홀로 시간을 보내왔다. 그렇다 보니 ‘멘토링’에 대한 갈증이 누구보다 컸고 어느덧 중니어(?)가 되다 보니 멘토링을 하고 있지 않은 주니어 분들이 안타깝기만 했기에 이렇게 ‘멘토링’에 대한 글까지 쓰게 된 것 같다. 누구를 가르친다는 것, 혹은 누구에게 가르침을 부탁하며 배운다는 것은 서로에게 시너지 효과를 낼 수 있는 좋은 관계인 것 같다.

     추가로, 필자가 멘토링에 대해 깊은 생각을 하게 된 책을 공유하고자 한다. 프로그래머의 길, 멘토에게 묻다라는 책인데 이 책은 필자가 어떤 서비스를 혼자서 맡으며 전전긍긍하고 있을 때 같은 조직 선배 개발자분께서 ‘혼자서 애쓰지 마!‘라며 추천해 주셔서 읽게 되었다. 물론 선배, 멘토의 말이 모두 정답은 아니지만 생각의 범위를 늘려주는 데는 누군가의 조언만큼 큰 효과가 없다고 생각한다. 멘토링을 왜 해야 하는지, 왜 혼자가 아닌 누군가의 조언을 들으며 프로그래머로써 어떻게 성장해야 하는지 궁금하다면 이 책을 읽어보는 것도 좋을 것 같다.

     멘토, 멘티 모두가 함께 성장하는 건강한 개발 문화를 위해 혹시 멘토링을 하고 있지 않다면 이 기회에 멘토, 멘티가 되어 보는 건 어떨까.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/a-good-developer-in-terms-of-resume/index.html b/posts/a-good-developer-in-terms-of-resume/index.html index 0605431c..30e2cd31 100644 --- a/posts/a-good-developer-in-terms-of-resume/index.html +++ b/posts/a-good-developer-in-terms-of-resume/index.html @@ -27,4 +27,4 @@  이력서는 언제 쓰게 되는 걸까? 아주 일반적으로. 신입(학생)의 경우 대학을 졸업할 즈음 취업하고 싶은 회사로 지원하기 위해 작성하고, 경력(회사원)의 경우 이직을 마음먹고 가고자 하는 회사가 뚜렷하게 결정이 되면 그때 작성하게 되는 것 같다. 회사마다 정해진 형식이 있는 곳이라면 그 형식에 맞추어 작성하고 그렇지 않다면 나만의 기준에 맞추어 작성하게 되는 ‘이력서’.

     회사에 입사하고 정신없이 지내다 보면 이직을 생각하기 전까지는 ‘이력서’라는 존재를 자칫 잊어버리기 쉽다. 또한 구태여 시간을 할애하면서까지 써야 한다는 마음조차 잘 들지 않는다. 실제로 텅 빈 책상 앞에 앉아 하얀 A4지와 펜 한 자루만 가지고 써봐야지 하고 시작하면 내가 이제까지 뭘 해왔나 하며 잘 써지지 않기도 하고.

    /images/a-good-developer-in-terms-of-resume/mung.png
    이력서에 뭘 써야 할까.
    출처 : https://epsem.tistory.com/243

     그런 개발자로 괜찮은가 시리즈인 이번 포스팅에서는 개발자에게 있어 ‘이력서’란 무엇이고 언제, 왜 그리고 어떻게 써야 하는지에 대해 이야기해보고자 한다. 정보의 바다, 홍수처럼 쏟아지는 기술의 변화를 IT 최전방에서 온몸으로 맞서 싸우는 우리 개발자들에게 ‘회사’보다는 ‘나 자신’을 위해 하루를 살아갈 수 있는 ‘힘’이 되었으면 하는 마음으로.

    들어가기 앞서, 본 포스팅은 이직을 권유하는 내용은 절대 아님을 밝힌다. 오히려 이력서 작성을 통해 현재의 직장에서 본인에게 더욱 집중하고 회사와 함께 성장했으면 하는 바람이다.

    개발자에게 이력서란?

     우선 이력서란 무엇일까? 사전적 의미를 먼저 살펴보자. 위키백과에 따르면 “취직을 위한 면접의 기회를 얻기 위해 회사 등 조직에 제출하는 개인의 신상정보, 학력, 경력 등을 시간 순으로 요약 혹은 나열한 문서"라 나와있다. 여기에 추가로 우리 개발자들은 본인이 사용할 수 있는 ‘기술’이나 특정한 ‘경험’을 적으며 자신이 가지고 있는 기술적 가치에 대해 어필하는 경우가 대부분이다.

     사전적 의미로 보면 ‘내 정보’를 잘 요약해서 취업하고자 하는 ‘회사’에 전달하는 수단으로도 이해할 수도 있을 것 같다. 즉, 누군가에게 본인을 정보(혹은 실력)를 정리해서 알리는 수단 중에 하나로 볼 수 있는데, 과연 이 이력서에는 ‘알린다’라는 의미만 담겨있을까?

     필자가 생각하는 이력서의 정의는 ‘나를 알리는 수단’ 보다 ‘나를 가장 잘 아는 거울’이라 생각한다. 특히 개발자에게는 더욱더. 무엇을 개발해왔고 어떤 기술을 써 왔으며 어떤 경험이 있는지 어느 곳에 작성을 하지 않으면 더듬더듬 기억으로 나 자신을 알기엔 요즘은 봐야 할 정보가 많은 세상이 되어버렸기 때문이다.

    왜 써야 할까?

     앞서 이력서를 ‘나를 가장 잘 아는 거울’이라고 말했다. 거울을 보고 얼굴에 뭐가 묻었으면 닦거나 옷차림이 별로라면 고쳐보는 등 ‘거울’은 나를 가장 잘 볼 수 있는 도구 중에 가장 좋은 물건이라 생각한다. 그런 의미에서 이력서는 단순하게 ‘Java 개발 N 연차’ 가 아닌 그동안 무엇을 해왔고 어떤 경험과 기술을 사용해 왔는지 정리를 하며 나 자신을 돌아볼 수 있는 훌륭한 도구라 생각한다.

     개발자 생활(정확히 말하면 회사 생활)을 하다 보면 개인 사업을 제외하고 회사가 추구하는 비즈니스의 목표를 위해 자의적이 아닌 타의적으로 임무를 할당받아 진행하는 경우가 대부분이다. 그러다 보면 소위 말하는 ‘찍어내기식 개발’을 하는 경우도 많고, 문제를 만날 경우 다양한 삽질로 해결은 하지만 제대로 이해하지 못한 채 일정에 치여 넘어가는 경우들도 있다. 그렇게 시간이 지나고 연말이 되어 한 해를 돌아보면 업무를 일정에 맞추어 진행하는 데는 성공하였지만 정작 본인에게 남은 건 장시간 컴퓨터 앞에 앉아 생긴 거북목과 점점 짙어져가는 다크서클뿐이다.

    /images/a-good-developer-in-terms-of-resume/why.jpg
    왜 되지?
    출처 : https://www.clien.net/service/board/park/4533074

     이력서를 써야 하는 이유를 크게 두 가지로 꼽자면, 첫 번째로는 나를 알리는 수단(Personal branding)으로 활용할 수 있다는 점에서다. 잘 정리한 자신의 이력서를 공개해놓으면 취업의 기회가 생길 수도 있고 인적 네트워킹이 되어 생각하지 못한 ‘기회’를 얻을 수도 있기 때문이다. 두 번째로는 앞서 이야기 한 ‘나 자신을 돌아보기 위함’이다. 멀리 가려면 앞만 보지 말고 뒤도 돌아볼 줄 알아야 한다는 말도 있지 않은가. 이력서를 쓰다 보면 무엇을 해냈고, 어떤 걸 할 수 있고, 그런데 무엇이 부족한지 (자괴감이 들기도 하지만) ‘팩트’로 볼 수 있기에 보다 나 자신에게 집중할 수 있다는 점에서 꼭 이력서를 써봐야 한다고 이야기하고 싶다.

    언제 써야 할까?

     신입이든 경력이든 연차를 막론하고 이력서를 써야 하는 시점은 크게 두 가지로 압축된다. 어느 회사에 취업을 할 경우는 당연히 써야 하는 것이니 제외하고 이야기를 해보자. 우선 어떠한 업무를 진행했거나 도전을 하고서 ‘마무리가 되었을 시점’이 있을 것 같다. 그때면 보통 그간 고생했으니 좀 쉬자!라는 마인드로 시간을 보낼 수도 있지만 자신이 알게 모르게 배웠던 지식들이나 성과들에 대해 가장 최신의 기억이 있는 시점이기 때문에 시간이 지나 작성을 하는 것보다 더 신선하고 뚜렷한 내용들이 이력서에 작성될 수 있는 좋은 시점이다.

     다음으로는 자신이 정한 기간에 맞추어 주기적으로 작성을 해봐야 한다고 생각한다. 이는 위에서 이야기했던 어떠한 이벤트가 있을 때 작성한다는 시점과는 별도로 분기 혹은 반기 즈음으로 자신만의 기간을 정하고 그동안 무엇을 했는지에 대해 돌이켜 보는 것이다. 이력서에 작성할 내용이 많은 시점도 있겠지만 그 반대로 작성할 내용이 없는 경우가 생겨날 것이다. 꼭 이력서에 계속 추가를 하는 것이 정답은 아니지만 자칫 정신없이 시간을 보냈다는 의미로 볼 수도 있기에 자신이 세웠던 목표를 다잡는 시간으로 만들 수 있다. 

    어떻게 써야 할까?

     문서를 작성하는 목적은 누군가에게 보여주기 위함이 가장 큰 것 같다. 이력서도 마찬가지. 누군가에게 나의 이력을 보여주는 (혹은 훗날 자신이 다시 보게 될) 문서인 만큼 열심히 쓰는 것도 좋지만 ‘잘’써야 하는데 어떻게 하면 ‘잘’쓸 수 있을까?

     필자는 이력서를 잘 쓰는 방법 중에 가장 중요한 건 ‘심플’해야 한다고 생각한다. 나 이것도 했고 저것도 했고 주절주절 일기를 쓰는 게 아니라 정말 중요한 꼭지(Point)를 찾고 간결하고 명료한 문장으로 한눈에 들어올 수 있도록 구성이 필요하다. 우선 자신을 알리는즉, 이 이력서를 보게 되는 사람에게 가벼운 인사말과 나 자신을 소개하는 몇 가지 포인트로 서두를 구성한다.

     그다음으로는 크게 ‘업무 경험’(Work Experience)과 ‘업무 외 경험’(Other Experience) 그리고 사용할 수 있는 ‘기술’(Skill)의 항목을 기준으로 정리해 나가보자. 여기서 중요한 점은 가급적 수치와 참고 링크를 걸어두는 걸 추천해본다. 개발자는 코드로 말하는 직업이다. 나아가서 그 코드들은 ‘좋은 소프트웨어를 개발했다’로 이야기가 되는 것이 아닌 각 소프트웨어만의 고유 수치가 나오기 마련이기에 이러한 부분들을 적어주면 보다 신뢰감이 증가할 것 같다. 물론 가장 좋은 건 문서를 읽는 흐름상 도표 혹은 이미지를 첨부하는 게 좋지만 개인적으로는 개발자의 이력서엔 어울리지 않는 모습 같다고 생각이 든다. (정답은 없지만 막상 넣어보니 난잡해 보였다;;)

     이력서 포맷에 관련된 내용은 필자보다 다른 분들의 아티클이 훨씬 정리가 잘 되어 있기에 링크로 대체해본다. 일반 문서파일로 이력서를 작성하는 것도 좋지만 개인적으로 외부 호스팅을 이용해 공개할 범위를 적절히 정해서 url로 접근할 수 있도록 하는 것도 좋아 보였다. 그렇게 하면 모르는 사람에게도 공개한다는 부분이 오히려 자극으로 다가와서 더 잘 써야지 하는 마음이 들었기 때문이다. (블로그를 쓰는 이유와 동일.) 그런 의미에서 필자의 이력서도 스무스하게 공개를 해본다.

    마치며

     2021년 새해가 밝고 올해는 00을 해 내야지! 하며 호기롭게 다짐을 한 게 어제 같은데 정신 차려보니 벌써 2월이다. (12월이 아닌 게 다행일지도 모르겠다.) 현실에 안주하고 매너리즘에 빠질 때 즈음 오래 묵혀둔 이력서를 다시 꺼내들어보자. ‘아~ 그땐 그랬지!‘하며 자신을 자랑스럽게 여길지도 모르겠지만 대부분 ‘정신없이 달려왔는데 한 게 아무것도 없네…‘하며 한숨이 절로 나오는 경우가 많다. (적어도 필자는 그랬다…)

    /images/a-good-developer-in-terms-of-resume/gd.jpg
    힘을 내요 권 사원.
    출처 : http://news.tf.co.kr/read/life/1131950.htm

     이력서를 다시 써보며 나 자신이 개발자로써 혹은 회사원으로써 잘 성장하고 있는지 앞으로 나아갈 힘을 찾아보자. 회사를 위해 미친 듯이 야근하며 열심히 달려왔지만 돌아보면 온전히 나 자신을 위해서 열심히 달린 적이 있던가. 나 자신이 성장을 해야 팀이 성장하고, 나아가 비즈니스가 성공하여 결국 회사 또한 성장한다고 생각한다. 이력서를 나를 돌아보는 도구로 활용하며 보다 더 나 자신을 위해 힘쓰는 시간들을 보내보는 건 어떨까.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/a-good-developer-in-terms-of-surroundings/index.html b/posts/a-good-developer-in-terms-of-surroundings/index.html index 1e184801..3991b50b 100644 --- a/posts/a-good-developer-in-terms-of-surroundings/index.html +++ b/posts/a-good-developer-in-terms-of-surroundings/index.html @@ -17,4 +17,4 @@  7 minutes 

     (필자의 과거 경험을 미루어) 개발자로서 회사에서 일을 하다 보면 가끔 CRUD(Create, Read, Update, Delete) API를 찍어내는 기계(?)가 되는 느낌을 받을 때가 있다. 일정은 촉박한데 사람은 부족하고, 기술 부채가 복리로 늘어나는 게 눈에 훤히 보이지만 개선할 시간이나 여유조차 없어 자신도 모르게 점점 “돌아가게만” 개발하는 상황들. 기술적인 고민을 할 시간은 점점 없어지고, 코드를 설계하는 측면이나 테스트 코드, 책임과 관심 같은 생각들은 하지 못한 채 편의만 추구하며 코드를 작성한다. 그러다 이직을 해야겠다 마음먹고 이력서를 작성할 때나 연말 평가를 위해 한 해 무엇을 했는지 돌아보면 회사일은 불철주야 정말 열심히 했지만 회사를 벗어나 개발자로써 본인 스스로를 위한 건 회사일 대비 아주 극소수에 불과하는 삶이 계속된다.

    /images/a-good-developer-in-terms-of-surroundings/coding-machine-developer.jpg
    코딩하는 로봇은 되지 말자.
    출처 : https://sdtimes.com/ai/ai-enabled-tools-might-completely-change-development-one-day/

     개인이 스스로 진행하는 프리랜서나 사업가를 제외하고 선 대부분 회사라는 집단에 소속되어 살아간다. 그러한 회사의 가장 중요한 목표는 돈을 벌기 위한 사업을 하는 것이다. 회사에서는 직원들에게 어느 정도의 처우는 보장해 줄 순 있지만 개개인의 인생을 책임져주진 않는 게 현실이다. 그걸 알면서도 지금 다니고 있는 회사에서 성장을 하지 못한다며 이직을 준비하거나 어쩌면 나를 위한 게 아닌 회사를 위한 일만 해오고 있는 건 아닌가 스스로를 되돌아보게 된다.

     개발자로써 지금의 삶이 너무 행복하고 만족스럽다면 이 글을 읽지 않아도 좋다. (어쩌면 우물 안 개구리로 살아가고 있는 건 아닌지 묻고 싶다. 물론 그 우물마저 따뜻하다면 패스하는 것으로.) 오랜만에 쓰는 이 글에서는 회사라는 의존을 벗어나 스스로 우뚝 설수 있는 ‘환경을 바꾸는 이야기’를 하려 한다. 몸짱이 되기 위해 헬스장을 가고 그것도 모자라 비싼 PT를 끊는다거나, 허리가 좋지 않아 스탠딩 책상으로 바꾸는 것처럼 개발자로 살아가면서 내가 제어할 수 있는 ‘환경’을 바꾸면서 앞서 이야기 한 ‘본인 스스로를 위해 성장하는 시간’을 만들었으면 하는 바람이다.

    시간관리

     하루를 시작하면 세상 모든 사람들에게 공평하게 주어지는 게 바로 시간이다. 누구나 24시간을 쓰는데 어떻게 쓰는지는 본인이 선택하기에 달린 문제다. 밤늦게까지 컴퓨터 앞에 앉아 공부를 하고 출근이 늦는답시고 아침 늦게 일어나는 선택, 퇴근하고 집에 오면 피곤해서 아무것도 하기 싫어 TV나 SNS를 하다 잠에 드는 선택, 회사에서 하는 개발은 어느 정도 할 줄 아는 수준까지 되었으니 굳이 다른 개발 공부는 하지 않아도 된다는 선택. 여기서 중요한 건 선택이 다를 뿐이지 잘못된 선택은 없다. 선택에 대해 책임을 질수 있다면 그것으로 OK. 하지만 시간이 부족하다는 핑계를 대고 있다면 시간관리부터 잘 할 필요가 분명히 있다.

    /images/a-good-developer-in-terms-of-surroundings/time.jpeg
    가만히 놔도 흘러가는 시간
    출처 : https://www.bobaedream.co.kr/view?code=strange&No=1515814/

     필자는 하고 싶은 게 너무나 많다. 그와 비슷한 양으로 꼭 해야 하는 것도 많다. 그렇기에 매월 1일이 되면 메모장에 한 달의 청사진을 그려본다. 정확하게 그릴 수 있는 것도 있지만 추상적으로 적는 경우도 많다. 그러고는 매주 일요일 저녁이 되면 다음 일주일에 대해 좀 더 자세한 계획을 작성하고, 매일 저녁이 되면 내일의 하루를 미리 정리해 본다. 시간 단위로 작성하는 경우도 있고 계획 중에 우선순위를 점검하며 빠짐없이 시간을 알차게 보내려고 애를 쓰는 연습 중이다.

     MBTI의 맨 마지막 문자가 대문자 J라서 그런지 계획하는 걸 선호하지만 막상 계획대로 시간을 보내다 보면 그래도 시간이 부족한 경우가 많다. 제한된 시간 내에서 최대한 시간을 확보해 보려 여러 가지 노력을 해봤다. 저녁 늦게까지 책상 앞에 앉아서 시간을 확보하기도 해봤지만 늦게 자게 되니 다음날의 체력에 지장을 줄 수밖에 없던 구조였다. 반대로 아침에 일찍 일어나는 건 워낙에 아침잠이 많은 체질이라 너무나도 힘들었지만 시간을 확보할 수 있다는 희망 아래 ‘미라클 모닝’을 시작하게 되었다.

     미라클 모닝은 그저 아침 일찍 새벽에 일어나기만 하는 것으로 정의하기엔 다소 무리가 있다. 정확히는 아침에 시간을 확보해서 하고자 하는 무언가를 한다는 것에 목표가 있다고 생각한다. 5시에 일어나고 출근을 9시에 한다면 약 4시간이라는 시간을 확보가 가능하다. (물론 최소 5~6시간을 자기 위해 일찍 잠에 들려는 노력도 포함하여…) 확보된 시간 동안에는 개발자로 살아가며 부족할 수밖에 없는 인문학적 소양을 기르기 위해 기술서적이 아닌 책이나 신문 기사를 읽기도 하고, 직업의 특성상 오랫동안 책상에 앉아 있어야만 하기에 점점 떨어져가는 체력을 올리려 헬스나 조깅을 하기도 한다. 아주 가끔 못다 한 회사일을 하는 경우도 있고 평소에 궁금해하던 기술을 살펴보는데 시간을 사용하기도 한다. 그러면서 슬쩍 창문 밖을 보면 아직 해가 뜨지 않았는데도 출근버스를 타기 위해 졸린 눈 비벼가며 기다리는 사람들, 몇 시에 일어나셨는지 거리를 깨끗이 청소하고 계시는 청소 미화원분들, 나이가 꽤 있어 보이시는 분들인데도 새벽같이 운동하는 모습을 보고 열심히 살자며 하루를 다짐하기도 한다. 사람마다 다를 순 있다고 생각되지만 시간을 확보하고 하루를 시작할 때 동기부여를 얻는다는 점에서 미라클 모닝은 필자에게 꽤 많은 변화를 주고 있다.

    /images/a-good-developer-in-terms-of-surroundings/instagram.jpeg
    가장 가치가 높은 그것. ‘시간'
    출처 : 필자 인스타그램 스토리

    커뮤니티와 스터디

     꼭 회사를 다니고 있는 사람뿐만 아니라 취업을 준비하는 분들에게도 추천하는 것 중 하나가 바로 커뮤니티다. 이미 꽤 여러 가지 온라인/오프라인 커뮤니티들이 많아 조금만 노력하면 쉽게 찾아볼 수 있어 그러한 환경에 본인을 위치 시키는 것만으로도 꽤 많은 긍정적인 변화를 얻을 수 있다고 생각한다. 여기서 말하는 커뮤니티는 특정 기술에 대해 이야기하는 모임이나 컨퍼런스, 세미나 같은 것을 의미한다. 같은 목적을 가지고 있는 사람들끼리 모여있다 보니 모르고 있던 부분이나 알았는데 잘못 알고 있던 기술적 지식들에 대해 대해 반강제적으로(?) 접할 수 있고, 기회가 된다면 그러한 환경에서 발표를 한다거나 토론을 하며 새로운 인적 네트워크를 만들어 갈 수도 있다. 아래는 필자가 알고 있는 커뮤니티의 일부이다. 이 외에도 찾아보면 무궁무진하다.

     다 그런 건 아니지만 회사에서 함께 일하는 동료들이 자신이 관심 있어 하는 기술에 관심이 부족할 수 있다. 앞서 이야기 한 것처럼 회사는 개발 공부를 하는 학원이 아니기에 각자의 관심사가 다른 건 잘못되거나 이상한 게 전혀 아니다. 그렇기에 회사에서는 회사원으로써 주어진 임무에 최선을 다하고 회사 밖에서 찾아보는 것도 방법이 된다. 커뮤니티를 통해 관심이 있던 기술에 대해 여러 가지 방안으로 활동을 할 수도 있고 마음 맞는 사람들끼리 스터디를 할 수도 있다. 회사 안에서 스터디를 하는 것보다 회사 밖에서 스터디를 하게 되면 아무래도 회사의 이름을 걸고 하는 것 같은 괜한 압박이 스터디를 더 긴장감 있게 도와주기도 하고 그러한 스터디가 없다면 직접 만들어 사람을 모아서 스터디를 운영하는 방법도 있다. 몇 달 전에 사람들을 모집하여 자바/백엔드 관련된 스터디를 시작했는데 벌써 2회차가 진행 중이다. 이름하여 “JSON 상하차 스터디”. 생각보다 많은 배움을 얻기도 하고 회사별로 다르게 사용하는 기술 컨벤션에 대해 공유를 받을 수 있는 점이 가장 좋은 것 같다. (직접 사람들을 모집하고 운영하는 괜한 책임감에 더 잘 해보려는 환경이 만들어진 건 덤~)

    /images/a-good-developer-in-terms-of-surroundings/java-study.jpeg
    서로 다른 5개 회사분들과 함께 하는 JSON 상하차 스터디

    개발 슈퍼파워 3종 세트 : 토이 프로젝트 + 기술 블로그 + 이력서

     다른 글에서 여러 번 이야기했지만 그럼에도 불구하고 이번 글의 주제인 ‘환경’을 바꾸는 것에 가장 좋은 무기인 슈퍼파워 3종 세트를 이야기하지 않을 수가 없다. 인터넷 강의나 책을 통해 개발 지식을 배울 때는 다 알고 다 할 것 같지만 막상 처음부터 무언가를 만들어 보려면 또 새로운 것이 기술인 것 같다. 작게라도 무언가를 만들어 본다는 그 자체가 엄청난 ‘환경’의 변화라 생각을 해본다. 그렇게 무언가를 만들어 보면서 어디서도 얻지 못한 본인만의 소중한 경험을 얻을 수 있고, 이러한 내용들을 블로그에 적으며 무언가를 구현하려 했거나 문제를 해결하는 과정을 자세히 적다 보면 정확한 내용을 적는 과정 속에서 강제로 지식을 학습하게 되는 효과를 얻을 수 있다. 이렇게 기술 블로그라는 강제로 공부하게 되는 장치를 마련해 두고 하나둘씩 본인만의 기술 성장 스토리를 만들어 가는 것도 본인에게 적지 않은 ‘환경’의 변화이기 때문이다. 마지막으로 스스로를 잘 표현하는 거울과도 같은 이력서를 주기적으로 업데이트를 해 간다면 그야말로 성장할 수 있는 환경을 구축했으니 실행에 옮기기만 하면 되지 않을까 하는 생각을 해본다.

    • 토이 프로젝트 : 작은 것부터 살을 붙여나간다는 생각으로 시작
    • 기술 블로그 : 정답형 블로그(A는 B)가 아니라 본인의 개발 이야기가 담긴 내용으로 구성
    • 이력서 : 3단계(상황-과정-결과) 기준으로 최대한 자세히, 그러나 최대한 요약하는 게 중요

    마치며

    /images/a-good-developer-in-terms-of-surroundings/clean.gif
    환경을 바꾸자!
    출처 : https://gifer.com/en/8vSl

     나에게 딱 맞는 회사를 고르기란 꽤 어려운 부분이 있다. 우선 면접에 합격을 해야 하고 그 뒤에 함께 하는 동료들과의 케미 등 여러 가지 부분들이 잘 맞아야 하는데 사실 이런 부분은 본인이 바꾸지 못하는, 이미 결정된 부분에 있어 선택할 수밖에 없는 영역인 것 같다. 물론, 물 한 방울 없는 사막에 가도 화초를 심어 꽃을 피울 수 있는 사람이 된다면 다른 이야기가 될 수 있겠지만 일반적으로 환경에 적응을 하며 살아가곤 한다.

     취업을 하여 개발자로 살아가고 있던지 취업을 하기 전이라면 내가 컨트롤할 수 있는 영역에서 환경부터 바꿔보는 건 어떨까? 어질러진 책상에서 공부를 하는 것보다 깔끔하고 정돈된 책상에서 공부하는 게 더 집중도 잘 되는 것처럼 변화된 환경 속에 자신을 위치시키는 것 자체가 꽤 유의미하다고 생각을 해본다. 잘 생각해 보면 대부분 본인 스스로에게 답이 있다. 좀 더 괜찮은 개발자가 되기 위해 다른 것에 탓하지 말고 우선 환경부터 바꿔보자.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/blog-reorganization-by-hugo/index.html b/posts/blog-reorganization-by-hugo/index.html index c36568fd..5633e4d6 100644 --- a/posts/blog-reorganization-by-hugo/index.html +++ b/posts/blog-reorganization-by-hugo/index.html @@ -78,4 +78,4 @@

      이렇게 하고 repository에 push를 해보면 Github Action 이 실행되면서 gh-pages 브랜치에 빌드 된 내용을 push 해준 걸 확인할 수 있다. 그다음 repository settings > GitHub Pages에서 branch를 master가 아닌 gh-pages로 변경해 주면 끝!

    /images/blog-reorganization-by-hugo/hugo_deploy_flow.jpg
    블로그 작성부터 배포까지의 흐름이 한방에!

    마이그레이션 (hexo to hugo)

     엄청난 노가다의 시간들이었다. hexo 나 hugo 둘 다 markdown 문법으로 인식(?) 하고 생성되는 구조였지만 hexo의 테마 특성에 맞춘 문법, 그 반대인 hugo의 테마 특성에 맞춘 문법이 약간씩 달라서 모든 글을 한 번씩 보면서 체크해야 하는 수고를 들여야 했다.

     더불어 hexo는 “글 제목"이라고 새 글을 생성하면 yyyy/mm/dd/글 제목 형식의 url로 표시가 된다. 하지만 hugo는 바로 /글 제목처럼 표현되는 부분 때문에 이대로 두었다가는 검색엔진이나 다른 곳에 기존 링크가 걸려있을 경우 없는 페이지로 랜딩 될 수밖에 없었다. 결국 과거 링크들을 살려야 해서 어쩔 수 없이 url을 과거의 url로 세팅해 줘야만 했다. (Docs)

     마지막으로 문단의 길이나 이미지 사이즈 등 hugo 테마에 적용되며 이상해 보이는 부분들을 수작업으로 하다 보니 실무 서비스에서 마이그레이션 작업을 하는 것과 같은 느낌이 들었다. 물론 기술 블로그의 기반 언어나 프레임워크가 짧은 주기로 변경될 일은 크게 없지만 새로 글을 작성할 때에도 이런 부분들을 염두에 두고 작성해야겠다고 생각하게 되었다.

    무엇이 좋아졌나?

     우선 글 작성-배포-관리 측면에서 Github Actions으로 한 번에 자동화가 되니 훨씬 편리하였다. 그리고 글 작성할 때도 hugo의 liveReload 기능이 있어 내용이 변경될 때마다 (파일이 수정될 때마다) 서버에 바로 반영이 되니 작성하면서 생성되는 html 을 바로 볼 수 있다는 장점이 있었다. (hexo를 이용할 땐 글을 어느 정도 쓰고 서버 재시작, 다시 반복해야만 했다. 지금은 관련 기능이 있는진 모르겠지만…)

    /images/blog-reorganization-by-hugo/automation_build_deploy.jpg
    commit/push 만 하면 알아서 빌드/배포를 해준다!

     전체적인 레이아웃이 이뻐진 건 기본이고 (우상단에 동그라미를 누르면 요즘 핫한 다크 모드가 된다. ^오^) 프론트 성능도 기존 대비 수치를 따져보진 않았지만 체감상 좋아진 것 같다. 가장 중요한 이번 기술 블로그 개편의 목적인 글을 쓰고 싶게 만드는 환경이 구축되었다는 점이다.

    마치며

    /images/blog-reorganization-by-hugo/NoThanksButWereBusy.png
    출처 : https://www.astroarch.com/tvp_strategy/no-thanks-busy-pay-back-technical-debt-40188/

     위 그림을 보면 네모난 바퀴를 사람들이 끌고 있고 누군가 동그란 바퀴를 제안하고 있다. 하지만 수레를 끄는 사람들은 바쁘다는 핑계로 그 의견을 무시하고 수레를 끌고 가고 있다. 과연 바쁘면 얼마나 바쁘다고. 필자 또한 그러한 생각에 현실과 타협하는 나 자신을 벗어던지고 새롭게 다시 시작하기 위해 누가 시키지도 않은 블로그 개편을 하게 되었다. 이 글을 읽는 여러분들들 중 기술 블로그를 운영하는데 바쁘다는 핑계로 잘 못쓴다거나, 기술 블로그를 시작해야지 하면서 다음으로 미루기만을 반복하지는 않는지 생각해봤으면 한다. 그렇다면 아주 조금씩 시작해보는 건 어떨까?

     길다면 긴 개편 작업이 끝났다. 그동안 이런저런 이유로 블로그 포스팅을 소홀하게 했었는데 이번을 계기로 좀 더 나를 위해 열심히 작성해보자고 다짐을 해본다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/index.html b/posts/index.html index c96ea00e..2afb89c3 100644 --- a/posts/index.html +++ b/posts/index.html @@ -1,5 +1,6 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간

    All Posts

    2023

    초보 시니어 개발자의 2023 리뷰 +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-01
    \ No newline at end of file diff --git a/posts/index.xml b/posts/index.xml index d34f5b02..4e958bd6 100644 --- a/posts/index.xml +++ b/posts/index.xml @@ -1,4 +1,14 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/posts/All Posts | 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 31 Dec 2023 15:26:10 +0900초보 시니어 개발자의 2023 리뷰https://taetaetae.github.io/posts/review-2023/Sun, 31 Dec 2023 15:26:10 +0900Authorhttps://taetaetae.github.io/posts/review-2023/ +All Posts - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/posts/All Posts | 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 07 Jan 2024 00:16:21 +0900그런 개발자로 괜찮은가 - '그룹 스터디' 편https://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/Sun, 07 Jan 2024 00:16:21 +0900Authorhttps://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/ + + 다양한 방식으로 스터디를 해왔다. 정말 많은 것을 배웠던 스터디도 있는가 반면에 지나고 보면 시간이 아까울 정도의 스터디도 있었던 것 같다. 직접 만들어 보기도 했고 참여도 해봤던 것 같다. 이런저런 경험들 끝에 작년 중순에 직접 만들었던 스터디 멤버와는 어느덧 반년을 넘어가고 있는데 바쁜 회사 생활을 하면서도 이제까지 지속할 수 있었던 노하우를 공유해 보고자 한다. +그룹 스터디 방식 인원  다 그런 건 아니지만 기존 회사 분들과 스터디를 할 때면 아무래도 원래 알던 사이라 바빠서 준비를 못 해오거나 불참을 하는 경우에 “그럴 수도 있지”, “괜찮아” 하며 관대해졌던 것 같다. 또는 다양한 의견을 듣자며 10명 이상 진행을 했던 것 같다. 그렇다 보니 스터디 진행에 집중도가 떨어질 수밖에 없었고 모였을 때 이야기하던 사람들만 이야기한다든지, 중도 하차하는 경험도 많았다. +블라인드 글에 첨부한 스터디 참여 설문" 블라인드 글에 첨부한 스터디 참여 설문  이번 스터디는 직접 ‘블라인드’라는 익명 커뮤니티를 통해 인원을 모았다. 작년 중순쯤 자바 백엔드 관련된 주제를 스터디 하겠다며 나와 비슷한 연차분들 위주로 모으겠다고 글을 작성했더니 신기하게도 3~40명 되는 분들이나 지원하셨고 그중 오프라인 모임을 고려해서 나 포함 6명 만으로 구성을 하였다.(뭔가 서류 전형 인사담당자가 된 느낌;;) 작은 규모 그리고 새로운 분들과 하게 되니 집중도가 오르는 경험을 할 수 있었고 무엇보다 6명 모두 다른 회사라 각 회사를 대표하는 것 같은 느낌이 들어 스터디 참여에 몰입이나 책임감이 더욱 올랐던 것 같다. 또한 한 주제에 대해 각 회사에서의 경험들을 이야기하다 보니 완전히 다른 시각을 얻을 수 있다는 장점도 있었다. + 별거 아닐 수도 있지만(또는 오해가 될 수도 있지만) 남녀 성비, 그리고 나이대(연차)를 최대한 맞추고 싶었다. 그래야 분위기가 적당히 딱딱하지도, 부드럽지도 않을 것 같았기 때문이다. 지금은 여자 한 분 나머지 남자분들이라 초반에 걱정도 되었지만 생각보다 분위기가 잘 흘러가서 다행이라 생각을 한다. +주제와 목표 배워야 할게 한도 끝도 없는 개발자 세상스터디 목표에 따라 집중해야 할 범위를 좁히자!" 배워야 할게 한도 끝도 없는 개발자 세상 +스터디 목표에 따라 집중해야 할 범위를 좁히자!  처음부터 모니터 받침으로 하기 좋을만한 두꺼운 책은 피했던 것 같다. 가볍게, 스터디원들끼리의 친밀도부터 올려야 한다는 생각으로 너무 딥 다이브 한 기술적인 내용보다는 누구나 한마디 정도 할 수 있을만한 가벼운 책부터 시작했다. 그러면서 최대한 참여도를 올리는데 집중했던 것 같다. + 어디까지나 “공부"를 하기 위한 모임이긴 하지만 이 또한 사람과 사람 사이의 “관계"가 중요하다고 생각했기에 모였을 때 바로 스터디 이야기를 하는 것보다 부드러운 아이스브레이킹을 자주 해왔다. 또한 너무 루즈 해지지 않게 1달~1달 반 정도로 끝날 수 있을만한 주제를 선정했다. 아무래도 한 주제가 2~3달 걸리다 보면 집중도가 떨어지는 경험이 많았기 때문이다. 책 한 권을 다 읽었다는 기간을 짧게 가져가면서 작은 성취의 효과를 최대한 활용하고 있다. 이번 회차가 벌써 네 번째인걸 보면 그래도 나름 잘 선택한 방법이라 생각이 든다. + 한 회차가 끝날 즈음엔 다음 스터디는 무엇을 할 것인지에 대해 이야기를 하고 다수가 동의하는 주제를 선정한다. 또한 매 회차가 끝날 때마다 어쩌면 어색할 수 있는 이야기지만 스터디 참여를 그만 둘지에 대해 의사를 분명히 물어본다. (그런데 신기하게도 지금 스터디 모임은 이런 이야기를 하기도 전에 스터디 하고 싶은 주제를 먼저 말씀해주시는 편이라, 어쩌면 스스로 사람 운이 좋다는 생각도 해본다.) + 그저 하나의 책을 읽기로 끝나는 “책 읽기 모임” 이 아닌 만큼 책을 기반으로 하는 스터디 모임일지라도 목표를 분명하게 잡는다. 여기서 목표는 개인마다 다를 수 있다. 가령 스터디 시간에 나왔던 내용을 각자의 팀에 공유 및 반영을 해본다든지, 스터디 내용에 대해 주도적으로 이야기를 하며 다른 분들의 지식을 훔쳐보겠다든지(?]]>초보 시니어 개발자의 2023 리뷰https://taetaetae.github.io/posts/review-2023/Sun, 31 Dec 2023 15:26:10 +0900Authorhttps://taetaetae.github.io/posts/review-2023/ 언제부터인가 새해가 되면 그 해의 키워드를 선정하고 해시태그처럼 달고 다니며 한 해를 보내온 것 같다. 작년의 키워드는 “한계”. 한정된 시간 속에서 하고 싶은 것도 많고 해야 할 것도 많은 나로서는 중요도에 따라 어쩔 수 없이 무언가를 포기하게 되는 순간들이 찾아왔다. 그럴 때마다 늘 어쩔 수 없다는 자기 가면을 쓴 채 정말 하고 싶던, 꼭 해야 할 것들임에도 불구하고 다음에 해야지 하고 넘어갔던 적이 많았다.  그렇게 시간을 보내니 아쉬움이 남게 되었고 잠을 줄여서라도 할 것 들을 하자며 나를 극한으로 몰아붙여보자는 의미로 작년의 키워드를 “한계"라고 정했고 정말 많은 것들을 경험할 수 있었다. 그렇게 나를 몰아붙이는 삶을 살다 보니 말 그대로 그저 “여러 가지만 했던” 한 해로 기억된다. (아마 그래서 작년 리뷰가 없던 이유일지도…?) @@ -85,13 +95,4 @@ https://api.telegram.org/bot{token}/getUpdates e.g. https://api.telegram.org/bot  그렇다면 멘티는 멘토를 어떻게 찾아야 할까? 함께 일하는 선배 동료가 있다면 정중하게 도움을 요청하는 것도 나쁘지 않다 본다. 단, 무작정 “저의 멘토가 되어주세요.“라는 것보다 자신이 가지고 있는 고민거리를 털어놓으며 조금씩 친분을 쌓아간다면 아무래도 경험이 많은 선배이기에 고민의 범위를 조금이라도 줄여줄 수 있지 않을까. 혹여 주변에 선배 동료가 없다면 온/오프라인 커뮤니티 활동을 하면서 찾는 것도 방법이다. 메신저를 통해 다가가거나 메일로 정중하게 고민을 요약해서 보내놓으면 당장은 아니더라도 가까운 시일 내에 응답이 오기 마련이다. (적어도 괜찮은 선배라면.)  여기서 말하는 ‘선배’의 정의는 단순 나이가 많아서가 아닌 자신보다 경험이 많은 사람을 의미한다. 그렇기에 자신보다 나이가 적은 사람이 멘토가 될 수도 있다고 생각한다.  -왜 멘토링을 해야할까?  ‘경험’이 정말 중요하고 홍수같이 쏟아지는 신기술을 온몸으로 받아내야 하는 우리 개발자들은 특히나 멘토링이 필요하다고 생각한다. 어떠한 기능을 만들어 내야 하는 상황이라 생각해 보자. 아주 일반적으로는 기능 개발에만 집중하다 보니 서비스 릴리즈시 검토해야 할 부분들을 생각하지 못하는 경우가 있다.]]>Elastic Stack으로 코로나19 대시보드 만들기 - 2부 : 대시보드https://taetaetae.github.io/posts/make-dashboards-from-elasticstack-2/Wed, 17 Feb 2021 16:53:49 +0900Authorhttps://taetaetae.github.io/posts/make-dashboards-from-elasticstack-2/ - - 지난 포스팅에서는 데이터를 수급하며 전처리 과정을 거쳤고, Filebeat와 Logstash를 거쳐 Elasticsearch에 인덱싱 하는 것까지 알아보았다. 앞선 포스팅에서 이야기했지만 단순하게 데이터를 시각화 도구를 이용해서 대시보드를 만드는 게 아니라 데이터가 추가되면 만들어둔 대시보드에 자동으로 반영되는 흐름을 만들고 싶었다. 마침 파이프라인을 이틀 전에 만들었기 때문에 그동안의 빠진 데이터를 추가해야 하는 상황이다. 이 경우 Filebeat-Logstash-Elasticsearch 가 실행 중이라면 앞서 작성했던 파이썬 스크립트만 한번 실행해 주면 이틀 치 데이터가 파이프라인을 거쳐 Elasticsearch로 인덱싱이 된다. 즉, 별도로 데이터를 가져와서 재 가공하고 추가하는 다소 까다로운 작업이 미리 만들어둔 파이프라인 덕분에 한 번의 스크립트 실행으로 손쉽게 처리가 됨을 알 수 있다. - 이제는 쌓여있는 데이터를 가지고 시각화를 해볼 차례이다. ElasticStack에서는 Kibana라는 강력한 시각화 도구를 제공하는데 이번 포스팅에서는 Kibana를 이용해서 대시보드를 만드는 방법에 대해 알아보려 한다. -Visualize  Elasticsearch에 인덱싱 되어있는 데이터들은 기본으로 제공되는 REST API를 통해서 조회할 수 있고 JSON 형태로 결과가 나오기 때문에 이를 가지고 다양하게 시각화를 할 수도 있다. 하지만 Kibana에서는 데이터를 조회하고 UI로 표현하는 일련의 모든 행위를 클릭 몇 번으로 할 수 있게 해주기 때문에 전문가가 아니더라도 조금만 만져보면 누구나 만들 수 있다. -New Visualizaion!!" New Visualizaion!!  버전업이 되면서 비쥬얼라이즈를 만드는 첫 화면 또한 변화가 생겼다. 기존에는 어떤 유형의 비쥬얼라이즈를 선택할 것인지에 대해 선택하는 화면부터 나왔는데 만드는 걸 보다 편리하게 도와주는 Lens, TSVB 같은 기능들이 먼저 반겨준다. 이 기능을 통해서 만드는 방법도 괜찮지만 보다 명시적으로 만들고 싶으니 하단에 Aggregation based을 선택해서 원하는 비쥬얼라이즈의 타입을 선택해 보자. 이후 생성되어 있는 인덱스를 선택하면 본격적으로 비쥬얼라이즈를 그릴 수 있는 화면이 나오는데 대시보드 화면 기준으로 만들어야 할 항목별로 살펴보자. -전체 수 ." .  확진자, 사망자, 격리 해제의 총합을 표현하려 한다. 이렇게 ‘숫자’를 표현하려 하는 경우 Metric을 활용하곤 한다. 우측에서 Aggregation 방법을 ‘sum’으로 설정하고 필드는 유형별로 각각 선택해 주자. 아래 ‘Add’버튼을 눌러 확진, 사망, 격리 해제 수를 모두 표시한 다음 저장을 눌러준다. Label을 지정하지 않으면 어떤 형태로 Aggregation을 했는지를 Label 영역에 보여주는데 그게 보기 싫다면 원하는 텍스트로 지정해 주는 것도 방법이다. -최근 수 ." .  확진자, 사망자, 격리 해제의 ‘최근 데이터’를 보여주는 게 목적이다. 이 경우 Aggregation을 Top Hit으로 선택하면 필드를 선택할 수 있게 되는데 하루의 데이터가 총 18 row이기 때문에 (서울, 부산, …, 제주, 검역) 18 row 을 전부 더한 값이 하루 기준의 합계가 된다. 여기서 정렬을 날짜 기준 내림차순으로 해줘야 가장 최근 데이터의 합계가 되는 점도 신경 써야 한다. -각 타입별 합계 ." .  지역별로 타입별 수를 보기 위해 Pie 타입으로 선택하여 진행한다. 타입별(예로 들어 확진이면 confirmed)로 합계를 구하기 위해 Aggregation을 ‘sum’으로 설정하면 빈 원이 나오지만 각 지역별로 차트를 잘라서 봐야 하기에 하단의 Buckets의 Add를 누르고 regieon의 필드를 Terms Aggregation 한다. 18 row의 데이터가 전부 보여야 하기에 정렬 개수를 늘리고 option 탭에서 보는 취향에 알맞게 설정값들을 바꿔준다. -타입별 추이 ." .  확진, 사망, 격리 해제 중에 사망을 제외하고 나머지 둘은 데이터의 크기가 크고 변화량이 비슷하기 때문에 x축은 시간으로 설정해두고 사망은 막대로, 나머지 둘은 라인으로 한 화면에서 표현하면 이 3가지 데이터를 한눈에 보기 좋을 것 같았다. Vertical bar 을 선택하고 x축(Buckets > X-axis)은 데이터 타입인 convert_date로 설정한다. 다음으로 사망은 매일 몇 명 사망했는지 뚜렷하게 보기 위해 그냥 sum으로, 나머지 둘은 누적 합계가 더 의미 있어 보일 것 같아 Cumulative Sum으로 Aggregation을 한다.]]> \ No newline at end of file +왜 멘토링을 해야할까?  ‘경험’이 정말 중요하고 홍수같이 쏟아지는 신기술을 온몸으로 받아내야 하는 우리 개발자들은 특히나 멘토링이 필요하다고 생각한다. 어떠한 기능을 만들어 내야 하는 상황이라 생각해 보자. 아주 일반적으로는 기능 개발에만 집중하다 보니 서비스 릴리즈시 검토해야 할 부분들을 생각하지 못하는 경우가 있다.]]> \ No newline at end of file diff --git a/posts/jenkins-job-parallel-processing-by-pipeline/index.html b/posts/jenkins-job-parallel-processing-by-pipeline/index.html index f4b251ef..85c4f90f 100644 --- a/posts/jenkins-job-parallel-processing-by-pipeline/index.html +++ b/posts/jenkins-job-parallel-processing-by-pipeline/index.html @@ -175,4 +175,4 @@

    개선 결과

     예시로 들었던 상황에서 얼마나 개선이 되었을까? 기존에 하나의 Job에서 순차적으로 진행하게 했을 경우 44초가 걸렸는데, Jenkins Pipeline 을 사용하여 Job을 병렬로 실행하게 하였더니 21초가 걸렸다. 즉, 44초에서 21초. 약 53%의 개선을 할 수 있게 되었다. 또한 아래 그림처럼 도중에 실패가 발생했을 경우 Pipeline 자체가 실패를 하게 되고 실행 중이던 다른 Job들도 중단이 되기 때문에 병렬 프로세스의 컨트롤 또한 간단하면서도 강력하게 할 수 있게 되었다.

    /images/jenkins-job-parallel-processing-by-pipeline/pipeline-fail.jpg
    실패가 발생하자 다른 Job들도 중단된것을 볼 수 있다.

    마치며

     사실 이 글을 작성하면서도 단순하게 Thread로 돌려버리면 되지 않을까라는 의문이 들었지만 보다 효율적인 기능이 있다면 실제로 테스트를 해보고 비교를 하며 검토를 해보는 것도 좋은 방법이 될 것 같았고, 나아가 늘 하던 방법만 고수하지 않고 새로운 것에 눈을 돌려보는 자세도 필요하다고 생각을 해본다. 위에서 들었던 예시는 아주 극단적인 예시지만 이러한 Jenkins Pipiline이라는 방법을 알고 있다면 이 또한 나만의 무기가 되어 다른 상황에서도 다양하게 활용해볼 수 있지 않을까 하는 기대를 해본다. (무려, groovy script 또한 이번에 처음 써보는… )


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/kafka-service-utilization-study-case-review/index.html b/posts/kafka-service-utilization-study-case-review/index.html index 731d2934..e2a12aff 100644 --- a/posts/kafka-service-utilization-study-case-review/index.html +++ b/posts/kafka-service-utilization-study-case-review/index.html @@ -17,4 +17,4 @@  5 minutes 

     필자는 오프라인에서 진행하는 밋업이나 콘퍼런스 가는 것을 좋아한다. 발표하는 내용을 전부다 이해해서 듣고 온다는 건 거짓말이겠지만 간혹 들었던 내용을 팀 내에 적용해 본다거나 몰랐던 내용에 대해 알게 되는 경우가 많았다. 특히, 질문을 꼭 하는 편인데 질문을 하려고 하면 좀 더 집중해서 듣게 되거나 질문한 세션의 내용은 꽤 오랫동안 기억에 남게 되니 개발자 행사에 참석하면 꼭 질문을 하자는 게 필자 자신과의 약속 중에 하나이기도 하다.

     한동안 코로나로 모든 개발자 행사가 온라인으로 진행하는 등 오프라인 행사는 눈을 씻고 찾기란 하늘에 별 따기였다. 오프라인 행사에 참여하면 나름의 개발력(?)을 얻을 수 있었는데 오프라인 행사 자체를 하지 않아 괜히 기운이 빠지던 요 몇 년이었지 않았나 싶다. 그러다 페이스북 KAFKA 한국 사용자 모임에서 공지가 올라왔고 세션들을 보아하니 하나도 알아듣지 못할(?) 엄청나게 고차원의 내용이 아닌 그럭저럭 이해할 만한 내용으로 준비되어 있었고, 무엇보다 회사와 가까워서 설레는 마음으로 신청을 하였다. 오래전에도 한번 밋업에 참석한 적이 있었는데 나름 진행도 매끄러웠고 좋았던 기억들뿐이라 한 치의 망설임 없이 신청하게 되었다.

    /images/kafka-service-utilization-study-case-review/ezic_bridge.png
    신입사원때 자주 오가던 다리…

     오전 근무만 하고 판교 테크노벨리에 있는 유명한 다리인 이직의 다리를 건너 SKT/SKP 판교 사옥 1층으로 걸어간다. 판교에 올 일이 잘 없는 게 올 때마다 느끼는 건 정말 IT 회사가 많다는 것. 뭔가 이직을 하려고 마음을 먹지 않아도 괜히 마음이 바운스 거리는 건 기분탓 일까 싶다.

    밋업의 분위기

     이런 행사에 가면 맨 앞에 자리를 잡곤 해서 처음엔 몰랐는데 행사 진행 중간에 보니 사회자분 이야기로는 약 90여 명 정도가 왔다고 했다. 오프라인 행사라 그런 건지, 판교 직장인분들의 접근성이 좋아서인지, 아님 정말 KAFKA의 인기(?)가 좋아서 인지는 모르겠지만 예상보다 꽤 많이 와서 조금 놀랬다. 입구에 커피와 쿠키가 제공되었고 개발자 노트북에 덕지덕지 붙일 수 있는 개발자 스티커도 받을 수 있었다.

     이번에는 데보션(Devocen) 이라는 곳에서 후원을 받아 진행한다고 했다. 처음에 데보션이 뭐 하는 곳인지에 대한 간략한 소개와 나중에 추첨을 하기 위해 앱을 설치하라는 귀여운 홍보도 있었다. SK 내/외부 우수 인재가 모여 전문 기술 지식/정보를 등록/축적 하고 공유 교류를 하며 전파 및 확산에 집중을 한다고 한다. 테크 세미나가 월 1회 있다고 하니 종종 들어와 봐야 겠다는 생각을 해본다.

     카프카 모임을 이끄시는 고승범 님도 오셨다. 예전 밋업에서도 뵙긴 했지만 최근에 카프카 관련 책도 새롭게 내시고 그룹도 운영 중이신 분이다. 나는 과연 저러한 열정이 있었나? 있을 수 있나? 라는 생각을 잠시 해본다.

    발표 요약

     하나부터 열까지 받아쓰기 수준으로 적진 못했지만 그래도 메모장에 남아있는 기록들을 정리 및 요약해 본다. 오랜만의 오프라인 행사라 들떠서인지 잘못된 기록이 있을 수 있음을 알린다 ^^;

    Kafka MirrorMaker로 카오스 엔지니어링 맛보기 / 황한희 님

    • Kafka MirrorMaker? - 카프카 클러스터를 대상으로 데이터를 mirroring 하는 기능 (토픽 데이터 동기화)
    • 활용방식 : fan-out, aggregation, active-active, acitve-passive
    • 카오스 엔지니어링 : 운영환경에서도 갑작스러운 장애를 견딜 수 있는 시스템을 구축하기 위해 시스템을 실험하는 분야, 장애를 미리 경험
    • Chaos Monkey
      • 넷플릭스 개발팀의 운영 원칙으로부터 시작해 현재는 가장 대표적인 카오스 테스팅 도구
      • 마치 무기를 든 원숭이를 데이터 센터에 풀어 놓은것 같다는 의미에서 출발
    • Pumba
      • 컨테이너 환경에서 제공되는 카오스 엔지니어링 도구
      • 영화 라이온킹에 등장하는 멧돼지인 품바의 멍청하고 산만하다는 특징에서 영감을 받음
      • 비교적 단순한 테스팅을 할 때 유용한 도구
    • 카오스 엔지니어링 파이프라인
      • 안정화 정의 : 기술적인 이슈나 아닌 비즈니스 관점의 지표를 안정된 상태의 지표로 설정
      • 이벤트 선정 : 발생 가능성이 있는 이벤트 선정
      • 실행 : 카오스 엔지니어링 수행 , 실제로 이벤트를 발생시켜보고 가설을 시험
      • 분석

     이번에도 어김없이 질문을 했다. 아무래도 실 서비스의 접근을 해야 할 텐데 부담은 없을지, 성능에 영향은 없을지가 가장 궁금했다. 답변으로는 pub/sub 이 하나 더 발생하는 것이기 때문에 성능에 큰 영향은 없을 것이라고 답변을 받았다. 과연 그럴까? 라는 생각을 잠깐 해보고 팀 내에서 카오스 엔지니어링을 도입하게 되면 개발 환경부터 테스트 해봐야지 하는 생각을 해봤다.

     카오스 엔지니어링 이라는 그럴듯한 이름으로 테스트를 하진 않았지만 실 서비스 도입 전에 별도의 환경(real/stage)에서 테스트를 하고는 있다. 그렇지만 지금 이야기 하고 있는 건 실 서비스의 모든 데이터를 동일하게 받고(dump) 정의된 테스트 파이프라인에 따라 계획적으로 진행하는 걸 이야기 하는 것 같았다. 민방위 훈련(?) 같은 장애를 발생시키는 테스트를 하지만 과연 제대로 하고 있나? 싶은 생각도 들었고 나중에 카오스 엔지니어링을 도입해 보는 것도 좋겠다는 생각도 들었다.

    취준생이 경험한 커뮤니티의 가치 / 김경민

     이번 세션은 어떠한 기술을 전파한다기 보다 세션 제목 그대로 취업 준비생이 경험한 커뮤니티의 가치에 대한 느낌을 전달해 주셨다. (호랑이 담배 필적 생각도 나고 ㅎㅎ) 처음엔 단순하게 유튜브 알고리즘을 배워보자(만들어보자?)로 시작했는데 커뮤니티에 참여하며 끊임없이 공부할 수 있는 기회를 얻었다는 것에 너무 신난 표정으로 발표하시는 게 인상적이었다. 신기한 게 많다고 하셨는데 그 느낌.. RG..RG.. 더군다나 이끌어 줄 사람이 있어서 좋았다고 하셨다. 역시 커뮤니티는 개발자에게 꼭 필요한 도구이자 없어서는 안될 존재인 건 확실한 것 같다.

    KakfaAdminclienet API를 이용한 Kakfa Managing 서비스 개발 / 이상헌, 이진환

    • kafkaAdminClient? : Kafka Object의 정보를 조회하고 매니징하는데 사용할수 있는 class이고, 이를 통해 kafka cluster의 내부 옵션을 설정 가능
    • 왜 사용하는가? kafka cluster의 내부 옵션 설정/변경 관련된 내용을 자동화
    • code dependency : kakfa-clients

     야후에서 만든 kafka-manager와 무엇이 다른가..라고 질문을 하고 싶었지만 뭔가 상태에 따라 매니징을 자동화하는 툴을 만들 때 보다 괜찮은 방법이 될 수도 있겠구나 생각이 들었다.

    pub/sub기능을 활용하여 로컬 캐시 동기화하기 / 조한서

    • 로컬캐시의 문제점을 해결하기 (동기화)
    • 캐시(Cache)란?
      • 데이터를 미리 저장해서 빠른 응답을 기대
      • hit : 저장한 데이터를 요청했을때
      • 더 많은 요청과 더 빠르게 시스템을 운영할수 있다.
    • Local Cache vs Global(remote) Cache
      • local : Speed(속도) ⬆, Consistency(일관성) ⬇/ 읽기요청이 쓰기 요청보다 많을때 적합
      • global : Speed ⬇, Consistency ⬆
    • 문제점 : 데이터가 업데이트 되는 순간 인스턴스마다 다른 캐시 정보를 가지고 있고 조회시 업데이트가 되었지만 이전 데이터를 조회할 가능성이 있다.
      • 해결방법
        • 인스턴스마다 각각 업데이트
        • pub/sub 기능 활용 ← 소개 방안
        • expire time을 짧게
    • 데이터 변경시 kafka로 pub하고 다른 인스턴스 에서는 sub하여 반영
      • set만 kafka 로 pub/sub으로 발행
      • get은 로컬캐시를 이용
      • 로컬캐시의 동기화가 목적 (리모트 캐시는 x)

     다른 분께서 질문도 하셨고 필자도 의문을 가진 ‘어느 상황에서 사용되는가, 문제점은 없는가’라는 질문에는 역시나 No Silver Bullet. 상황에 따라 좋은 대안이 될 수도 안될 수도 있다고 정리가 되었다. 캐시 관련 되서는 차라리 expire time을 적당히 짧게 가져가는 게 리소스 측면에서 효율적이지 않을까 생각을 해봤다.

    마무리

    /images/kafka-service-utilization-study-case-review/kakfa_meetup.png
    찍힌 사진이 무슨 대감처럼 나왔네… + get 한 카프카 책!

     사실, 필자도 사람인지라 경품을 받고 싶어 굳이 빈 백팩을 메고 갔지만 빙빙 돌아가는 룰렛은 다른 분의 이름을 호명하기 바빴고, 그렇지만 질문을 해서 책을 받기도 했지만 무엇보다 너무 오랜만에 오프라인 개발자 행사에 와보니 뭔가 닫혀있던 생각들이 환기되는 기분도 받았고 녹아 없어져 버린 열정도 다시 찾을 수 있겠다는 희망도 얻어 가는 것 같았다. 다음에 또 와야징.

    그나저나, 너…무 오랜만의 포스팅이라 부끄럽기도 하고 그렇다. TMI이지만 요즘엔 블로그 보단 커리어리라는 서비스에서 활동(?)을 하다 보니 개발자에게 그렇게도 중요하다고 이야기 하는 블로그를 등한시 한 것 같은데, 이 포스팅을 시작으로 다시 블로그를 종종 써보도록 노력 해야겠다;;


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/make-dashboards-from-elasticstack-1/index.html b/posts/make-dashboards-from-elasticstack-1/index.html index 3593056f..ae26069d 100644 --- a/posts/make-dashboards-from-elasticstack-1/index.html +++ b/posts/make-dashboards-from-elasticstack-1/index.html @@ -192,4 +192,4 @@

    이제 Filebeat를 실행시키면 Filebeat에서 csv 파일을 읽고 → Logstash에서 데이터를 필터링한 다음 Elasticsearch로 보내면 → Elasticsearch에 인덱싱이 되고 → 연동된 Kibana에서 데이터가 들어온 것을 확인 가능하다.

    sudo ./filebeat -e -c filebeat.yml
     

    결과

     Kibana에서 보면 아래 화면과 같이 데이터가 잘 들어온 것을 확인할 수 있다.

    /images/make-dashboards-from-elasticstack-1/discover.png
    Kibana > Discover

     csv는 하루에 한 번 업데이트가 되니 Filebeat - Lostash - Elasticsearch가 실행 중이라 가정할 때 위에서 작성한 파이썬 스크립트를 실행하게 되면 csv 기준 한 줄이 추가된다. 그러면 추가된 하루의 데이터를 구성한 파이프라인을 통해 Elasticsearch에 자동으로 인덱싱 된다. 즉, 위에서 목표로 했던 것처럼 일회성의 대시보드가 아닌 데이터의 수급을 계속 받아 코로나19 바이러스가 종식될 때까지 사용할 수 있는 파이프라인이 구성된 것이다. 다음 편에서는 이렇게 구성한 데이터를 가지고 Kibana의 다양한 기능을 통해 대시보드를 만들어 볼 계획이다. (하루빨리 코로나19 바이러스가 세상에서 사라지기를 바라며…)


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/make-dashboards-from-elasticstack-2/index.html b/posts/make-dashboards-from-elasticstack-2/index.html index 5891e05d..2609d486 100644 --- a/posts/make-dashboards-from-elasticstack-2/index.html +++ b/posts/make-dashboards-from-elasticstack-2/index.html @@ -17,4 +17,4 @@  4 minutes 

     지난 포스팅에서는 데이터를 수급하며 전처리 과정을 거쳤고, Filebeat와 Logstash를 거쳐 Elasticsearch에 인덱싱 하는 것까지 알아보았다. 앞선 포스팅에서 이야기했지만 단순하게 데이터를 시각화 도구를 이용해서 대시보드를 만드는 게 아니라 데이터가 추가되면 만들어둔 대시보드에 자동으로 반영되는 흐름을 만들고 싶었다. 마침 파이프라인을 이틀 전에 만들었기 때문에 그동안의 빠진 데이터를 추가해야 하는 상황이다. 이 경우 Filebeat-Logstash-Elasticsearch 가 실행 중이라면 앞서 작성했던 파이썬 스크립트만 한번 실행해 주면 이틀 치 데이터가 파이프라인을 거쳐 Elasticsearch로 인덱싱이 된다. 즉, 별도로 데이터를 가져와서 재 가공하고 추가하는 다소 까다로운 작업이 미리 만들어둔 파이프라인 덕분에 한 번의 스크립트 실행으로 손쉽게 처리가 됨을 알 수 있다.

     이제는 쌓여있는 데이터를 가지고 시각화를 해볼 차례이다. ElasticStack에서는 Kibana라는 강력한 시각화 도구를 제공하는데 이번 포스팅에서는 Kibana를 이용해서 대시보드를 만드는 방법에 대해 알아보려 한다.

    Visualize

     Elasticsearch에 인덱싱 되어있는 데이터들은 기본으로 제공되는 REST API를 통해서 조회할 수 있고 JSON 형태로 결과가 나오기 때문에 이를 가지고 다양하게 시각화를 할 수도 있다. 하지만 Kibana에서는 데이터를 조회하고 UI로 표현하는 일련의 모든 행위를 클릭 몇 번으로 할 수 있게 해주기 때문에 전문가가 아니더라도 조금만 만져보면 누구나 만들 수 있다.

    /images/make-dashboards-from-elasticstack-2/visualize-main.jpg
    New Visualizaion!!

     버전업이 되면서 비쥬얼라이즈를 만드는 첫 화면 또한 변화가 생겼다. 기존에는 어떤 유형의 비쥬얼라이즈를 선택할 것인지에 대해 선택하는 화면부터 나왔는데 만드는 걸 보다 편리하게 도와주는 Lens, TSVB 같은 기능들이 먼저 반겨준다. 이 기능을 통해서 만드는 방법도 괜찮지만 보다 명시적으로 만들고 싶으니 하단에 Aggregation based을 선택해서 원하는 비쥬얼라이즈의 타입을 선택해 보자. 이후 생성되어 있는 인덱스를 선택하면 본격적으로 비쥬얼라이즈를 그릴 수 있는 화면이 나오는데 대시보드 화면 기준으로 만들어야 할 항목별로 살펴보자.

    전체 수

    /images/make-dashboards-from-elasticstack-2/1.jpg
    .

     확진자, 사망자, 격리 해제의 총합을 표현하려 한다. 이렇게 ‘숫자’를 표현하려 하는 경우 Metric을 활용하곤 한다. 우측에서 Aggregation 방법을 ‘sum’으로 설정하고 필드는 유형별로 각각 선택해 주자. 아래 ‘Add’버튼을 눌러 확진, 사망, 격리 해제 수를 모두 표시한 다음 저장을 눌러준다. Label을 지정하지 않으면 어떤 형태로 Aggregation을 했는지를 Label 영역에 보여주는데 그게 보기 싫다면 원하는 텍스트로 지정해 주는 것도 방법이다.

    최근 수

    /images/make-dashboards-from-elasticstack-2/2.jpg
    .

     확진자, 사망자, 격리 해제의 ‘최근 데이터’를 보여주는 게 목적이다. 이 경우 Aggregation을 Top Hit으로 선택하면 필드를 선택할 수 있게 되는데 하루의 데이터가 총 18 row이기 때문에 (서울, 부산, …, 제주, 검역) 18 row 을 전부 더한 값이 하루 기준의 합계가 된다. 여기서 정렬을 날짜 기준 내림차순으로 해줘야 가장 최근 데이터의 합계가 되는 점도 신경 써야 한다.

    각 타입별 합계

    /images/make-dashboards-from-elasticstack-2/3.jpg
    .

     지역별로 타입별 수를 보기 위해 Pie 타입으로 선택하여 진행한다. 타입별(예로 들어 확진이면 confirmed)로 합계를 구하기 위해 Aggregation을 ‘sum’으로 설정하면 빈 원이 나오지만 각 지역별로 차트를 잘라서 봐야 하기에 하단의 Buckets의 Add를 누르고 regieon의 필드를 Terms Aggregation 한다. 18 row의 데이터가 전부 보여야 하기에 정렬 개수를 늘리고 option 탭에서 보는 취향에 알맞게 설정값들을 바꿔준다.

    타입별 추이

    /images/make-dashboards-from-elasticstack-2/4.jpg
    .

     확진, 사망, 격리 해제 중에 사망을 제외하고 나머지 둘은 데이터의 크기가 크고 변화량이 비슷하기 때문에 x축은 시간으로 설정해두고 사망은 막대로, 나머지 둘은 라인으로 한 화면에서 표현하면 이 3가지 데이터를 한눈에 보기 좋을 것 같았다. Vertical bar 을 선택하고 x축(Buckets > X-axis)은 데이터 타입인 convert_date로 설정한다. 다음으로 사망은 매일 몇 명 사망했는지 뚜렷하게 보기 위해 그냥 sum으로, 나머지 둘은 누적 합계가 더 의미 있어 보일 것 같아 Cumulative Sum으로 Aggregation을 한다. 한 화면에서 3가지의 데이터를 보여주기엔 다소 y 축의 크기가 맞지 않으므로 확진, 격리 해제를 별도의 y 축(Y-axes)으로 ‘Metrics & axes’탭에서 설정해 준다. 다음으로 각 항목의 범례를 위로 표시하여 보다 보기 편하게 배치한다.

    확진자 추이

    /images/make-dashboards-from-elasticstack-2/5.jpg
    .

     시간의 흐름에 따라 확진자가 얼마나 늘었는지, 더불어 그 안에서도 어떤 지역에서 많이 발생했는지를 한눈에 보고자 한다. 위와 동일하게 Vertical bar을 선택하고 x축에는 시간의 흐름을 보기 위해 convert_date을 가지고 Date Histogram Aggregation을 설정한다. 다음으로 y 축은 확진자 수를 sum 하고 (max를 해도 무방, 하루에 데이터가 하나기에 큰 의미가 없다.) 마지막으로 지역별로 하루의 막대를 쪼개야 하기에 Buckets를 추가로 만들어 regieon 기준으로 Terms Aggregation 을 한다. 그렇게 해놓고 보면 코로나19 바이러스가 처음 발생했을 때 대구에서 많이 발생한 것을 확인할 수 있고 그 이후에는 대부분 인구 분포가 많은 지역 순서로 확진자가 발생한 것을 알 수 있다.

    Dashboard

     하나의 대시보드는 미리 만들어둔 비쥬얼라이즈를 조합하여 만들어진다. 각 비쥬얼라이즈의 크기나 위치 또한 자유롭게 설정할 수 있는 것이 가장 큰 장점이라 생각한다. 그럼 위에서 만들었던 비쥬얼라이즈를 가지고 배치를 해보자. ‘Add from libray’을 누르면 위에서 만든 비쥬얼라이즈를 선택하는 화면이 뜨고 크기를 조절하고 적절하게 위치를 조정해서 입맛에 맞는 대시보드를 만들어 보자.

    /images/make-dashboards-from-elasticstack-2/6.jpg
    우측에서 비쥬얼라이즈를 선택!
    /images/make-dashboards-from-elasticstack-2/8.jpg
    대구는 처음에 확진자가 많이 발생했고 지금은 그에 비해 적다.
    /images/make-dashboards-from-elasticstack-2/9.jpg
    조회 날짜를 조정해서 볼 수 있다.

     Kibana로 만든 대시보드가 정말 강력한 부분이 이 상태에서 특정 지역의 상태를 보고 싶을 경우 범례에 있는 지역을 선택만 하면 손쉽게 화면이 바뀐다는 점이다. 또한 조회시간을 조절하여 집중으로 볼 수도 있다. 이러한 기능을 처음부터 다 만들어야지 생각을 하면 배보다 배꼽이 커지는 건 당연한 소리인 것 같다.

    마치며

     필자는 이러한 기능을 활용하여 실무에서 데이터의 전체 흐름을 한눈에 볼 수 있는 대시보드도 만들어 보았고, 날짜나 필드를 조합하여 데이터를 조회해야 하는 어드민을 직접 구현하지 않고 위와 비슷한 구성으로 만들어 개발 공수를 엄청나게 절약한 경험이 있다. ‘ElasticStack이 짱이에요’ 라는 말을 하고 싶은 건 아니다. 다양한 오픈소스를 적절하게 활용하면 적은 공수로 엄청난 효과를 누릴 수 있다는 장점이 있음을 말하고 싶다. 우리가 하고자 하는 건 데이터 분석이지 데이터를 어떻게 저장하고 시각화를 어떻게 해야 하는 건 둘째 문제 아니던가.

    /images/make-dashboards-from-elasticstack-2/7.jpg
    아직 위험하다!

    끝으로, 코로나19 바이러스가 하루빨리 종식되기를 간절히 바라며 어디 나가지 말고 집에서 필자처럼 대시보드를 만들고 추이를 지켜보는 건 어떨까…


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/openapi-and-swagger-ui-in-spring-boot/index.html b/posts/openapi-and-swagger-ui-in-spring-boot/index.html index 4900eed7..b745ff3e 100644 --- a/posts/openapi-and-swagger-ui-in-spring-boot/index.html +++ b/posts/openapi-and-swagger-ui-in-spring-boot/index.html @@ -132,4 +132,4 @@ docker run -d -p 80:8080 -e SWAGGER_JSON=/mnt/api.json -v /home/test:/mnt swaggerapi/swagger-ui

     앞서 json 을 /home/test하위에 api.json이라는 파일로 만들어두고 이미지를 띄운 뒤 서버의 80 port로 접근을 해보면 아래와 같이 앞서 직접 서버를 띄워서 했던 것처럼 동일하게 보인다. (wow)

    /images/openapi-and-swagger-ui-in-spring-boot/swagger-ui-docker.png
    한 곳으로 모을수 있다는 큰 장점이 있다.

    마치며

     사실 Swagger를 SpringBoot에 적용하기까지만 포스팅하려다 SwaggerUI까지 해보게 되었다. 새로운 기술이 있으면 감으로만 수박 겉핥기 식으로 보는 것보다 직접 내가 해보았는지가 정말 중요한 것 같다. SpringRestDocs 보다 훨씬 빠르고 가벼운 설정으로 문서화가 가능했지만 테스트 코드 없이 검증되지 않은 API 문서가 만들어진다는 불안함은 감출 수 없었다. 이게 정답이다 할 건 아니지만 둘 다 각자의 장점이 뚜렷하기 때문에 상황에 따라 잘 선택해서 사용해야 하겠다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/page/10/index.html b/posts/page/10/index.html index c6c67cfc..3483fd4c 100644 --- a/posts/page/10/index.html +++ b/posts/page/10/index.html @@ -1,5 +1,6 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간

    All Posts

    2017

    Spring Transactional 설정 및 주요속성 +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +09-18
    \ No newline at end of file diff --git a/posts/page/11/index.html b/posts/page/11/index.html new file mode 100644 index 00000000..61eceba6 --- /dev/null +++ b/posts/page/11/index.html @@ -0,0 +1,3 @@ +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file diff --git a/posts/page/2/index.html b/posts/page/2/index.html index c5f7940b..376543f5 100644 --- a/posts/page/2/index.html +++ b/posts/page/2/index.html @@ -1,5 +1,6 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간

    All Posts

    2021

    Elastic Stack으로 코로나19 대시보드 만들기 - 1부 : 파이프라인 구성 +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +10-04
    \ No newline at end of file diff --git a/posts/page/3/index.html b/posts/page/3/index.html index f5f5fe23..bbc85e4a 100644 --- a/posts/page/3/index.html +++ b/posts/page/3/index.html @@ -1,5 +1,6 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간

    All Posts

    2020

    벌써 2년 (feat. 토이프로젝트 회고,가치,수입) +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-09
    \ No newline at end of file diff --git a/posts/page/4/index.html b/posts/page/4/index.html index fa20379e..bc7bd198 100644 --- a/posts/page/4/index.html +++ b/posts/page/4/index.html @@ -1,5 +1,6 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간

    All Posts

    2019

    조금은 무거운 2019 회고 +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-30
    \ No newline at end of file diff --git a/posts/page/5/index.html b/posts/page/5/index.html index e88a8ff0..f946ee37 100644 --- a/posts/page/5/index.html +++ b/posts/page/5/index.html @@ -1,5 +1,6 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간

    All Posts

    2019

    자바, 성능, 모니터링 테크세미나 정리 및 후기 (by 우아한 형제들) +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-10
    \ No newline at end of file diff --git a/posts/page/6/index.html b/posts/page/6/index.html index cf7d9e20..a3505826 100644 --- a/posts/page/6/index.html +++ b/posts/page/6/index.html @@ -1,5 +1,6 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간

    All Posts

    2018

    2018 회고 - Coder가 아닌 Programmer로 +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +08-05
    \ No newline at end of file diff --git a/posts/page/7/index.html b/posts/page/7/index.html index 4061302b..1e28fd0a 100644 --- a/posts/page/7/index.html +++ b/posts/page/7/index.html @@ -1,5 +1,6 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간

    All Posts

    2018

    초간단 API서버 만들기 - 2부 (Python + Flask + Nginx) +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-08
    \ No newline at end of file diff --git a/posts/page/8/index.html b/posts/page/8/index.html index a5b068b9..30dce2df 100644 --- a/posts/page/8/index.html +++ b/posts/page/8/index.html @@ -1,5 +1,6 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간

    All Posts

    2018

    Github과 Jenkins 연동하기 +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +08-27
    \ No newline at end of file diff --git a/posts/page/9/index.html b/posts/page/9/index.html index 065895cf..e9495d5d 100644 --- a/posts/page/9/index.html +++ b/posts/page/9/index.html @@ -1,5 +1,6 @@ -All Posts - 👨‍💻꿈꾸는 태태태의 공간

    All Posts

    2017

    mybatis insert/update 쿼리실행후 결과 가져오기 +All Posts - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-19
    \ No newline at end of file diff --git a/posts/public-offering-notice-1/index.html b/posts/public-offering-notice-1/index.html index 600b91e3..a956e8ff 100644 --- a/posts/public-offering-notice-1/index.html +++ b/posts/public-offering-notice-1/index.html @@ -43,4 +43,4 @@ }

    마치며

     여기까지 토이 프로젝트에 대해 다양한 시각으로 설계를 해보았고 공모주 관련 데이터를 크롤링을 통해 가져왔다. 다음 포스팅에서는 가져온 이 데이터를 텔레그램 API를 사용해서 텔레그램 채널에 보내는 걸 정리해 보고자 한다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/public-offering-notice-2/index.html b/posts/public-offering-notice-2/index.html index f3de86f5..b173cf5a 100644 --- a/posts/public-offering-notice-2/index.html +++ b/posts/public-offering-notice-2/index.html @@ -52,4 +52,4 @@ }

     실제로 사용자들이 알림을 받고 클릭을 한 내역을 보면 어떤 공모주에 더 관심이 가는지 혹은 무슨 요일에 더 알림을 보는지 등 서비스를 만들려고 했던 목적 이상의 데이터를 얻을 수 있게 된다.

    /images/public-offering-notice-2/bitly.jpg
    bitly 대시보드 화면. 실제 사용자들의 액션(?) 데이터

    마치며

     최종 결과물은 아래 화면처럼 데이터를 획득하고 (크롤링) 텔레그램의 봇 api와 bitly의 API를 활용해서 메시지를 채널로 전송하는 데까지 성공하였다. 이제 남은 건 해당 애플리케이션을 서버에 업로드하고 이를 주기적으로 호출하는 방법만 찾으면 끝!

    /images/public-offering-notice-2/result.jpg
    이 화면은 지난 3월 22일에 실제로 서비스 된 화면이다. 자세히 보면 계획했던 오전 8시가 아닌데 이 비하인드는 다음 포스트에 작성하도록 하겠다.

     여기까지만 보면 큰 어려움이 없었고 만들기 전에 생각했던 흐름대로 만들었기 때문에 이제 다음 스탭만 진행하면 모든 게 끝날 거라 기대를 했다. 하지만 서버를 선정(?) 하고 그것을 주기적으로 호출하는 방법을 찾는데 예상치 못한 어려움을 만났고 나름 꽤 많은 시간을 삽질해야만 했다.

     To Be Contunue…

    


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/public-offering-notice-3/index.html b/posts/public-offering-notice-3/index.html index b419f8ee..de483605 100644 --- a/posts/public-offering-notice-3/index.html +++ b/posts/public-offering-notice-3/index.html @@ -17,4 +17,4 @@  4 minutes 

     공모주 알리미라는 토이 프로젝트 개발기의 마지막 포스팅이다. 토이 프로젝트를 왜 시작하게 되었고 어떻게 설계하게 되었으며 데이터는 어떤 식으로 수집하고 그 데이터를 어떤 방법으로 사용자들에게 알림을 보내기까지 알아보았다. 이제는 이러한 일련의 ‘파이프라인’을 자동화해야 할 시간이다. 사람이 직접 수동으로 로컬 컴퓨터에서 위 파이프라인을 실행하는 것이 아니라 별도의 서버에 해당 애플리케이션이 등록되어 있고 이를 어떤 무언가에 의해 트리거링을 해주는 방식으로 말이다.

    서버 선정

     1부에서 이야기했던 것처럼 heroku라는 PaaS(Platform as a service)를 사용하면 될 것 같았다. 무료 플랜으로도 설계했던 서비스 내용을 모두 소화 가능했기 때문이다. 앞서 만든 Spring Boot Application 을 heroku에 배포를 해보자.

     heroku에서 새로운 ‘App’을 생성한다. 아래에서 보여주고 있는 화면대로 App name을 지정하고 만들기만 하면 끝. 그러면 배포 방법이 여러 가지가 나오는데 heroku에서 제공하는 CLI를 사용하는 방법, 그리고 Github 과 연동하거나, 컨테이너 레지스트리를 활용하는 방법 총 3가지가 있다. 여기서 필자는 Github을 활용해서 연동하는 방법을 소개해 보고자 한다.

    /images/public-offering-notice-3/1.jpg
    heroku 에서 app을 생성하자.

     로컬에서 만든 애플리케이션을 Github에 push 하면 Github Repository 가 생기고 작업 파일들이 정상적으로 업로드된 것을 확인할 수 있다. 그다음 heroku에서 만들었던 App 페이지에서 Deploy 탭을 클릭하면 아래와 같이 3가지 방법으로 Deploy를 할 수 있다고 나오고, 이 중에 “Connect to Github"을 선택하면 Github 과 연동할 수 있는 버튼이 생기고 이를 누르면 자동으로 본인의 Github 내 Repository를 등록할 수 있도록 화면이 바뀐다.

    /images/public-offering-notice-3/2.jpg
    heroku 와 github 연동

     그다음 위에서 Github에 push 했던 Repository 이름을 적고 검색하면 조회가 되고 ‘Connect’를 누르면 자동으로 연결이 된 것을 확인할 수 있다. 연동된 Repository 브랜치에 코드가 푸시 되면 자동으로 heroku에 배포가 되도록 자동화 설정도 가능하고 그 아래에 보면 브랜치를 선택해서 배포를 수동으로 할 수 있기도 하다. 수동으로 푸시를 눌러보면 이런저런 빌드 로그가 나오고 최종적으로 배포가 되어 {Appname}.herokuapp.com 을 접속해보면 서버에 배포가 되어있는 것을 확인할 수 있다.

    /images/public-offering-notice-3/3.jpg
    수동으로 배포를 해보자.

     heroku에서는 이렇게 몇 번의 클릭만으로 간단하게 애플리케이션을 배포할 수 있는 기능을 제공하고 있고 서버 내 로그도 아래 화면처럼 보여주고 있기 때문에 쉽고 간단하게 서버를 구성하고 싶은 사용자들에게 매력적으로 보이는 것 같다. 단, 무료 플랜의 제한사항들을 자세히 살펴보고 사용할 것을 추천한다.

    /images/public-offering-notice-3/4.jpg
    서버 로그도 볼 수 있다!

    호출 테스트, 문제의 시작

     앞서 만들었던 텔레그램 채널에는 아무도 가입을 하지 않았기에 배포한 heroku web endpoint를 호출하면 텔레그램 봇을 통해 알림이 오는 걸 테스트하고 싶었다. 그런데 아무리 호출을 해도 서버는 타임아웃이라는 에러 응답을 뱉기 일쑤였고, 로직이 문제인지 한참을 리팩토링하며 원인을 파악하는데 꽤 오랜 시간을 삽질하였다. 왜 타임아웃이 발생할까? heroku는 web에서 바로 실행할 수 있는 console 페이지를 제공하고 있었다. 그래서 ‘크롤링을 하기 위한 페이지’와 ‘구글’을 비교하기 위해 단순하게 curl 해서 가져오는 테스트를 해보니 아래처럼 확연히 결과가 달랐다. 결국은 heroku 와 크롤링 하는 서버 간의 네트워크 타임아웃이 문제였던 것.

    /images/public-offering-notice-3/5.jpg
    오류가 나고 원인을 찾는 과정이 가장 어려운 것 같다. 어플리케이션의 문제가 아닌 네트워크 자체의 문제

    그래서 어떻게 해결 했나?

     heroku에서 타임아웃이 발생하는 문제를 해결하려 여러 구글링을 통해 찾아봤지만 방법을 찾을 수 없어서 결국 heroku를 사용하는 것을 포기하고 다른 방법을 찾아봐야만 했다. 앞서 이야기했지만 토이 프로젝트를 무료로 운영하고 싶었기 때문에 이런저런 방법을 찾다 보니 AWS 와 비슷하게 Google에서도 GCP라는 서비스를 알게 되었다. 이곳에서도 1년 동안은 무료이지만 이후 AWS처럼 과금이 드는 문제가 아쉬워서 좀 더 찾아보니 아주 작은 서버에 특정 조건을 맞춘다면 평생 무료로 사용이 가능하다는 걸 알게 되었고 이를 사용하기로 마음먹는다. (참고 사이트 : https://nhj12311.tistory.com/317)

    /images/public-offering-notice-3/6.jpg
    GCP에 가입하고 인스턴스를 생성하면 web에서도 접근 가능한 SSH 환경이 제공된다.

     GCP에 가입을 하고 무료 서버(?)를 발급받아서 각종 세팅 (java, crontab, timezone 등) 을 한 다음 실행을 시켜보니 아무런 문제 없이 잘 돌아갔고, GCP는 heroku 와는 다르게 가상 서버에 직접 접속이 가능했기에 web endpoint로의 호출이 아닌 crontab을 활용해서 로컬에서 직접 호출하도록 하였다. 앞서 이슈가 되었던 heroku처럼의 타임아웃 문제는 전혀 없었고 텔레그램으로 봇 알림도 잘 오는 것을 확인할 수 있었다.

    마치며

    /images/public-offering-notice-3/gadget.jpg
    나와라 만능 팔!
    출처 : https://m.blog.naver.com/maifunnyday/220155296568
     머릿속으로 생각만 하는 것과 실제로 경험해보면서 얻은 돈 주고도 살수 없는 소중한 경험들. 거기에 heroku 나 bitly, gcp 등 들어만 봤지 해보진 않았던 경험들도 얻을 수 있어서 나만의 무기가 하나 둘 생겨난 기분이 들어 매우 좋았다. (heroku + telegram로 더 멋진 것을 만들어 볼 계획이다.) 더불어 지금 만든 ‘공모주 알리미’를 확장시켜서 단순히 한번 만들고 끝나는 게 아니라 다양한 기능들도 추가해서 토이 프로젝트 본연의 목적, 그리고 이런 걸 만들 수 있다는 자신감(?)을 점점 쌓아 올릴 생각이다.

     끝으로, 공모주에 관심을 갖는 독자가 있다면 그동안 필자가 만들었던 공모주 알리미 가입을 해보는 것도 좋을 것 같다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/review-2020/index.html b/posts/review-2020/index.html index 43a7f5be..b4eefc26 100644 --- a/posts/review-2020/index.html +++ b/posts/review-2020/index.html @@ -18,4 +18,4 @@

     그 어느 때보다도 정신없이 달려온 2020년. 하고 싶은 것도 많았고 큰 꿈을 꾸기도 했지만 현실의 벽 앞에 크게 좌절도 해보기도 하고. 갑작스러운 세상의 변화에 적응하랴 정신적으로 육체적으로 너무 많이 힘들었던 올해. 돌아보면 참 후회가 되지만 한편으론 시련과 좌절 속에서 여러 가지를 배웠던 그런 한 해를 보낸 것 같다.

     필자는 내년이 되면 이제 어느덧 개발자 생활을 한 지 9년 차가 된다. 보통 주니어라 함은 단순하게 이제 막 취업한 신입 또는 3~5년 차를 말하고 시니어는 연봉이 X 원을 넘거나 n 연차를 넘을 경우를 말하는 것 같다. 물론 각 회사마다 이 둘을 정의하는 기준이 다르겠지만. 그런데 필자는 주니어도 시니어도 아닌 그 사이에서 애매~한 연차. 중니어. 과연 나는 무엇을 해야 할까? 무엇을 해야 연차에 맞는 역할(?)이라고 할 수 있을까? 그리고 그건 누구에게 배워야 하고 누가 가르쳐 주기나 할까?

     매년 회고를 써왔다. 그럼에 연말이 되어서 연례행사처럼 작성하는 게 아닌 나에게 정말 필요한 방향으로 회고를 작성하려 한다. 단순하게 이런저런 일들이 있었고 ‘어쩔 수 없었네~’ 읊조리는 무의미한 회고보다 현실적으로 나 자신을 위해 변화해야 할 게 있으면 굵고 길게 계획을 세워보는 방향으로 해보고 싶다.

    등장, 코로나-19

    /images/review-2020/corona19.jpg
    나가지 말라면 나가지 마! 밥 먹지 마! 모이지 마!
    출처 : salihgonenli

     세상이 변했다. 작년까지만 해도 미세먼지가 심하면 마스크를 쓰고 나가곤 했지만 코로나-19라는 전염병이 전 세계에 퍼지며 이제는 마스크 없이 살 수 없는 세상이 되었다. 늘 사무실에 나가 팀 동료분들과 이야기를 하며 밥도 먹고 회의도 하며 업무를 진행했지만 재택근무를 한지 어느덧 반년이 훌쩍 지났다.

     처음엔 집에서 편하게 일을 할 수 있어서 좋았다. 그러나 IT 회사에 근무하고 있지만 아직도 버벅거리고 어색한 화상회의와 더딘 업무 진행으로 인해 점점 시간이 지날수록 답답함은 극을 달했다. 출/퇴근 시간 등 업무이외에 필요한 시간이 사라지며 오히려 업무에 집중하는 시간은 많아졌다. 그에 반해 피로도는 집중한 업무시간에 비례하며 늘어났기에 나무늘보처럼 늘어지는 시간들 또한 많았던 것 같다. 지나고 보면 그러한 시간들을 잘 계획하고 움직였더라면 뭐라도 배우거나 달성했을 시간들인 것 같아서 약간 아쉬움이 남는다. 내년엔 계획하는 시간의 비중을 좀 더 늘리는 것으로.

     아무쪼록 코로나-19 바이러스가 없어지고 다시 예전으로 돌아갔으면 좋겠다. 그에 마스크 잘 쓰고 손 잘 씻고 사람 많이 모이는 곳은 피해야 하는 건 우리가 할 수 있는 해야 할 가장 큰일이겠지.

    회사생활

    서비스 전면 개편

     팀에 투입한 이후 가장 큰 규모로 서비스 전면 개편을 진행하였다. 거의 올해 내내 했다고 봐도 무방할 정도. 업무의 양도 많았고 스펙 또한 복잡하였지만 가장 크게 배울 수 있었던 부분은 모놀리틱 서비스에서 마이크로 서비스로의 아키텍처 변화를 시도했다는 점. 그리고 일반적인 Request - Response 식의 1차원적인 흐름에서 이벤트라는 행위를 기준으로 모든 프로세스가 영향을 받는 구조를 적용하며 고민했다는 점에서 여러 가지 인사이트를 얻을 수 있었다. 아무래도 중니어다 보니 주어진 기능을 개발만 하는 것보단 좀 더 높은 곳의 설계 관점에서 고민하는 연습을 하려고 했던 것 같은데 아직 부족한 것 같다.

     올해도 개발 문화를 개선하려는 노력도 하였다. CI를 재설치하고 다양한 개선을 통해 빌드 속도를 몇 배로 늘리기도 하였고, 단순/반복적인 업무들은 각종 봇들을 개발하여 업무 생산성을 올리기도 하였다. Sentry를 서버 레벨에 적용하여 무분별하게 발생하는 에러들을 그룹핑하여 우선순위에 따라 에러를 해결할 수 있는 구조를 만들기도 하였고, 소나큐브와 jacoco를 적용하여 코드 커버리지를 도식화하며 현재 모듈의 상태를 보여주기도 해보았다. 개발 문화의 개선은 겉으로 드러나진 않지만 잠재적인 문제들을 해결하는 데 가장 큰 효과를 준다고 믿기 때문에.

    /images/blog-reorganization-by-hugo/NoThanksButWereBusy.png
    우리는 안바쁜 날이 없다.
    출처 : https://www.astroarch.com/tvp_strategy/no-thanks-busy-pay-back-technical-debt-40188/

     다만 바쁘다는 이유로 이런저런 기술 부채를 해결하지 못한 채 한 해를 넘긴 게 가슴에 짐으로 남았다. 최근에 읽었던 클린 애자일 에서 나오는 내용들로 내년에는 좀 더 안정적인 서비스를 위해 적용해볼 만한 부분들을 제안해 보려 한다. 개발자라면 안바빴던 날이 있던가.

    애매한 파트장

     팀이 바빠지면서 몇 명씩 짝을 이루어 파트라는 단위로 나뉘어 개발을 진행하였다. 그에 필자는 두 분과 함께 하며 업무를 진행하고 업무현황을 체크하고 진행하는 역할을 맡았다. 파트장이라기엔 뭔가 애매한 역할. 그래도 무언가를 해보겠다며 호기롭게 매일 스크럼도 진행하고 가끔 각각 면담도 하면서 일이 되게 할 수 있도록 여러 가지 고민과 실행을 해왔다. 조금이라도 경험이 그분들보단 많았기에 상황마다 어떤 식으로 업무를 진행해야 하는지에 대해 약간의 조언(팁)을 드리기도 하였고, 업무가 너무 바빠지자 내가 자처해서 그분들의 업무를 할당받아 진행해보기도 하였다.(지금 생각해 보면 엄청나게 바보 같은 행동..)

     군 시절 그래도 리더라는 경험을 해보았기에 그들이 내게 원하는 것. 그리고 내가 해주어야 하는 것을 놓치지 않으려 노력했던 것 같다. 하지만 ‘나를 따르라’라며 진두지휘했던 그 시절과는 상황이 전혀 달랐고 필자 또한 주어진 업무의 양이 상당히 많았기에 썩 그렇게 만족할만한 파트 리더 역할은 못한 것 같다. (물론 함께 했던 분들 또한 그렇게 느끼실 것 같은…)

    퇴사

     결과적으로는 퇴사하지는 않았다. 하지만 입사 이래로 “퇴사 버튼” 위에 마우스 커서를 올려놓았기에. 정말 너무 힘들었다. 가끔 징징대며 힘듦을 토로하기는 하지만 이 정도까지는 아니었기에. 과연 중니어는 무엇을 해야 할까? 사실 올해 회고의 가장 핵심 키워드라 볼 수 있다. 초당 작성하는 코드의 양이 많으면 될까? 아니면 개발을 하지 않고 서비스 도메인을 잘 이해하며 함께 하는 팀원들이 잘 할 수 있도록 말 그대로 리딩만 잘 하면 될까? 그도 아니라면 무엇을 해야 한단 말인가? 그도 아니라면 퇴사를 마음먹은 주된 이유가 과연 코로나-19 때문일까?

    /images/review-2020/goodbye.gif
    나도 언젠간 이 짤을 쓰는 날이 오겠지…
    출처 : https://dingdo.tistory.com/146

     필자가 생각하는 중니어의 역할은, 우선 주어진 업무를 충실히 하는 건 기본이고 (이건 주니어에 대한 기대수준에도 포함) 팀원들이 바빠서 자칫 챙기지 못한 기술 부채나 시스템 관점에서 개선해야 할 부분을 ‘개인 시간’을 할애하며 묵묵히 개선해 나가는 것이라 생각한다. 근데 이것도 아니라면?

     야근이라는 의미는 또 무엇일까? 주어진 시간에 주어진 업무를 해결하지 못해서 추가시간을 할애하며 하는 것일까? 그렇다면 야근을 하면 비효율적으로 일하는 것일까? 조금 더 꼼꼼하게 테스트하고 고민하며 안정적인 서비스를 위해 시키지도 않는 본인의 추가시간을 투자하는 것은 아닐까? (그렇다고 야근을 좋아하는 건 아니지만, 최근 몇 개월간 필자의 야근 그래프를 보면 거의 최근 비트코인 가격 그래프와 흡사하다.)

     여러 가지 이유들로 퇴사를 결심하였지만 과연 퇴사가 정답일까 싶은 생각들이 지친 필자의 마음을 어르고 달래주어 퇴사를 하지는 않았다. 하지만 어느 조직에서 있던(어느 회사에서 있던) 본인의 가치관과 조직의 목표와 다르다면 깊게 고민을 해볼 필요가 있다. 만약 조직이 오로지 겉으로 드러나는 신규 기능에만 집중하고 그것이 기술 부채를 개선하는 활동보다 높이 평가될 경우 과연 문제가 많은 코드와 시스템을 보고도 눈 가린 채 신규 기능만 더하는 게 과연 맞는 일인 건지. 마침 필자와 비슷한 고민을 하는 누군가가 블라인드에 글을 올렸는데 답글이 너무 와닿아 이곳에 적어본다.

    블라인드 내용

    절을 바꾸려 하지 말고, 다른 절로 옮기세요.

    당장 옮길 수 없다면 무리 안 가는 선에서만 솔선수범하시고요.

    개발에 대한 열정은 화력도 중요하지만 보온도 중요합니다.

    타오르고 싶은 마음을 잠깐 보류해뒀다가 포기하지 않고 나중에 다시 꺼내드는 것도 능력이에요.

    아니면 회사의 방식에 그대로 녹아드는 것도 방법입니다.

    개발자 라기보다는 도메인 지식이 충만한 회사원이 되는 거죠.

    안되는 걸 억지로 되게 하려고 해봐야 몸과 마음만 다치거든요.

    차라리 되는 걸 더 잘하려고 노력하는 게 더 생산적일지도 모르겠습니다.

    자기계발

    블로그

     지금 쓰고 있는 회고까지 하면 18개. 딱 작년 보다 1개 덜 쓰게 되었다. 바빠서 못 썼다는 건 핑계니까 접어두고, 돌이켜 보면 ‘간절하지 못했다’라는 표현이 어울리는 것 같다. 이런저런 핑계들을 벗 삼아 자꾸 나 자신과 타협했던 시간들이 블로그 포스팅 개수만 봐도 뻔히 보인다. 그동안 배운 것들도 경험하며 삽질한 시간들도 많았는데… 아래 접속자 수 그래프를 보면 뭔가 정체기인 것 같아 마음이 아프다. 좀 더 분발하자 태태태.

    /images/review-2020/ga.jpg
    월간 블로그 접속자 수

     그럼에도 불구하고 그런 개발자로 괜찮은가 라는 시리즈를 써왔던 것 같다. 아직도 담고 싶은 주제가 너무 많은데 회사원이 아닌 개발자로써 가져야 할 마음가짐을 좀 더 정리해보고 싶다. 시리즈를 연재 한다는 게 쉬운 일은 아니지만 개발자로써 매 순간 느끼는 부분들이 많기에 이것들을 머릿속에 남겨두긴 힘들어서라도 정리가 필요한 것 같다.

     회사에서 운영하는 서비스도 개편하는 시국에 나는 뭐하고 있나 싶어 블로그를 개설한지 언 4년여 만에 블로그 개편을 하였다. hexo라는 프레임 워크에서 hugo라는 프레임워크로 변경을 하였는데 성능이나 UI들이 아직까진 만족스럽다. github 블로그의 장점 중에 하나인 자유로운 커스터마이징 덕분에 내 입맛에 맞게 UI를 조정할 수 있다는 것 또한 매우 매력적이다.

    Daily Dev Blog

     파이썬이라는 언어를 배우고 ‘한번 만들어 보자’하며 만들었던 토이 프로젝트인 기술 블로그 구독 서비스. 벌써 2년이 지났고 구독자 수는 어느덧 4천 명을 향해 달려가고 있다.

     gitter.im서비스를 이용해서 준 실시간으로 서비스에 대한 피드백을 받고 대응을 해왔다. 대부분 자신의 블로그가 메일에 포함이 안된다는 내용이 많았는데 블로그 시스템마다 다 상이해서 상황에 따라 코드를 수정하거나 가이드를 드리는 방식으로 답변을 해왔다.

     필자의 서비스를 Clone(?) 한 서비스도 나타났다. 이게 엄청난 아이디어나 특허권이 있는 건 아니지만 메일의 내용이나 방식들이 너무 비슷해서 약간 당황했다. 그런데 얼마 전부터 서비스가 안 되는 것 같긴 하다. (무언가 문제가 생겼을까 오히려 궁금하기까지도…)

     이제는 서버의 한계가 찾아와 오전 10시에 메일 발송이 힘들어지는 경우가 가끔 발생하고 있고, 서버 유지 비용 또한 나름의 지출이라 무시 못 할 지경. 그럼에도 메일 상단에 있는 후원 버튼으로 몇몇 분들이 감사한 후원을 해주셨는데 물론 서버 비용을 대체할 정도의 금액은 아니었지만 정말 기분이 좋았다. 뭔가 특단의 조치가 필요한 시점 같다.

    /images/review-2020/ddb.jpg
    기술블로그 구독서비스 사용자 추이

     다이어트를 하려면 나 다이어트한다고 SNS에 올리면서 동기부여를 받는 사람처럼, 필자도 서비스 개선을 하기 위해 이곳에 몇 개 적어두고자 한다. 안 그러면 계속 미룰 것 같아서.

    • 언어/프레임워크 변경 : Python > Java
    • 필터링 기능 추가
    • 빌드/배포 자동화

    새벽 5시

     재택으로 인해 오전 9시에 일어나는 필자를 보고 S가 문득 나의 하루는 4시 30분에 시작된다라는 책을 읽어보라고 권유를 했다. 아무 생각 없이 ‘그래, 아침에 좀 일찍 일어나 볼까’ 하는 마음으로 읽었는데 신세계를 경험하곤 매일 새벽 5시에 일어나기 시작한 지 벌써 한 달이 되어간다. 이 책에서는 무조건 아침 일찍 일어나는 것만을 이야기하진 않는다. 전날 어떻게 잠에 드는가, 아침에 일어나 어떤 행동들을 하고, 왜 아침에 일찍 일어나야 하는가에 대한 내용이 저자의 경험을 토대로 적나라하게 적혀있는 책이다. 꽤 신선한 충격을 받고 매번 눈팅만 하던 페이스북 그룹 얼또 - Early 또라이 - 일찍 일어나는 또라이가 세상을 바꾼다에도 일어나서 할 일과 해낸 일들을 댓글로 적어가며 하루를 시작하고 있다.

     어느덧 책도 일주일에 한 권은 읽게 되었고, 시간 없다는 핑계가 무색할 정도로 시간적인 여유가 많이 생겼다. 블로그도, 개발 공부도, 운동도. 보다 잘 계획해서 나만의 후회 없는 시간들을 가꾸어 나가야겠다고 다짐해본다.

    활동

     코로나로 인해 외부 활동을 거의 하지 못했다. 그 와중에 회사에서 필자를 보고 글을 써보지 않겠냐는 권유에 주말 이틀을 꼬박 지새우며 개발자로서 서비스를 개발/운영하는 경험과 느낌을 회사 공식 블로그에 기고할 수 있는 좋은 기회도 있었다. 그래도 매번 블로그로 글 쓰는 연습을 해서인지 단 두 번의 퇴고 끝에 글을 작성할 수 있었다. 

     필자의 블로그를 봐서였을까. 어떻게 알고 강의와 집필 제안이 올해 꽤 들어왔다. 욕심 같아서는 “네! 할래요"라고 하고 싶었지만 회사 내규에 안 맞는 부분도 있었고 내가 강의를? 글을? 뭘 안다고? 하는 마음에 몇 차례 요청이 있었지만 아쉽게도 진행하지 못하였다. 나중에 기회가 되면 좀 긴 일정으로 도전해보고 싶은 마음은 있지만 상황이 허락할지는 잘 모르겠다.

    /images/review-2020/mento.jpg
    다른 멘토분이 필자의 블로그를 언급해 주셔서 매우 놀랐다.

     운이 좋아 2021년도 신입사원 멘토가 되었다. 아직 뚜렷하게 무언가를 진행을 하진 않았지만 언택트 시대이다 보니 신입사원분들께 전할 이야기들을 카메라 앞에서 촬영도 해보고 꽤 즐거운 경험이었다. 내년에 진행하게 되면 많은 것을 배울 수 있을 것 같다. 왜 누군가를 가르치려면 배우는 사람보다 가르치는 사람이 더 많이 배운다고 하지 않던가.

    2021년, 🐮

     회사 친한 형과 함께 코로나가 약간 잠잠해질 즈음 근처에서 술을 마시며 “그런 개발자로 괜찮은가” 시리즈와 비슷한 내용으로 이야기한 적이 있다. 그러다 그 형 입에서 나온 이야기는 아직까지도 많은 울림을 주었고, 매번 곱씹을 때마다 소화 안되는데 까스활명수 먹는 느낌이 든다.

    회사 친한 형과의 대화

    이렇게 불평불만 만 토로하는 거 보기 싫다고 작년에 네가 그랬는데 이젠 네가 그러고 있는 거 아냐?

    불평불만만 하지 말고 행동을 해 행동을.

    개발자에서 회사원 되는 거 한순간이다. 명심해. 

     내년에는 어떤 변화와 이벤트들이 있을지는 모르지만 우선 나부터 바뀌는 걸 노력해봐야겠다. 그래도 안된다면. 그다음을 준비하는 것으로.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/review-2021/index.html b/posts/review-2021/index.html index d4ebf0c5..f4aa1dbb 100644 --- a/posts/review-2021/index.html +++ b/posts/review-2021/index.html @@ -13,4 +13,4 @@  5 minutes 

     미래의 시간을 계획하는 것도 중요하지만 과거의 시간을 돌아보고 더하거나 빼는 시간이 더 중요하다고 느끼는 시간인 ‘회고’. 올해도 어김없이 필자의 2021년을 돌아보며 회고 글을 쓰려 했지만 이런저런 일들로 한 해를 넘기고야 만다. 연말이 지나고 새해가 시작되었지만 무슨 일이 있어도 매년 회고는 꼭 하자는 나와의 약속을 지키려 2021년을 되돌아보고 크나큰 이벤트들의 연속이 될 것만 같은 2022년을 위해 더할 건 더하고 뺄 건 빼는 리뷰를 해보고자 한다.

    여러 가지 작은 도전들

     재택근무가 장기화되면서 시간을 좀 더 알차게 사용할 수 있었고, 그에 생각하지도 못한 다양한 경험들을 할 수 있게 되었다. 먼저 찾아보기도 하거나 필자의 블로그나 다른 경로를 통해 오히려 연락이 왔던 ‘멘토링’은 많은 것을 생각하게 해주는 경험이 되었다. BE, FE, 머신러닝, DevOps 등 분야를 막론하고 이제 막 개발자로써 취업전선에 뛰어드려 하는 예비 개발자부터 한참 개발을 시작하고 있는 이른바 주니어 개발자까지 다양한 분들을 zoom이나 gather-town 같은 온라인 플랫폼에서 만나게 되었고, 그들의 고민을 함께 이해하려 노력하며 선배 개발자로써 조금이나마 도움이 되는 부분들에 대해 이야기해주는 활동들을 해왔다.

    /images/review-2021/tyler.jpg
    10년후에 만나요 :D

     물론 필자를 완벽하게 잘 성장한 (또는 본보기의 대상이 될만한) 개발자라고 말하기는 매우 어렵지만 그들보다는 다양한 경험들을 먼저 해본 선배 입장에서 노하우나 방향성에 대해 이해하기 쉽게 최대한 풀어 설명하려 했다. 이러한 점을 누구는 대수롭지 않게 여긴 적도 있지만 누군가는 XX 기업에 취업을 했다거나 며칠간 복잡하고 힘들었던 고민이 해결이 되었다는 소리를 들었을 땐 아, 멘토링 하길 잘했다는 생각이 들게 되었고 더불어 이제는 점점 누군가와 함께 공동의 목표를 이루기 위한 위치에서 있다 보니 이런 점을 연습할 수 있는 기회가 된 것 같아 너무 좋았다. 무엇보다 멘토링을 하면서 필자도 대충 알고 있던 개발 지식에 대해 (제대로 알려주기 위해) 공부하게 되는 기회가 되었고 이런저런 상담을 하며 느낀 그들의 열정을 조금이나마 간접경험하며 얼마 전부터 잃어버린 내 열정도 찾으려는 동기부여도 되기도 하였다.

     코로나가 장기화되고 개발자로써 할 수 있는 건 없을까 하며 Elastic Stack 을 활용하여 코로나19 대시보드 만들기라는 포스팅을 올리게 되었고 그에 힘입어 나만의 데이터 분석 플랫폼 엘라스틱서치라는 책에 베타 리딩을 하기도 하였다. 작년부터 책을 써보는 건 어떻겠냐는 요청이 아주 가끔 들어오지만 베타 리딩을 하면서 책을 출간하는 게 얼마나 어려운 건지 다시 한번 깨닫게 되었고 기회가 된다면 내 이름으로 된 책을 써보고 싶은 생각도 들었다.

     공모주 청약을 가끔 하면서 누군가 알려주면 좋을 텐데 하는 생각으로 공모주 알리미 라는 토이 프로젝트를 만들었다. 기술 블로그 구독 서비스를 운영하고 있는 AWS ec2 서버에 메모리가 조금 남아 배치 형식으로 만들어서 텔레그램으로 정보를 알려주는 서비스인데 생각보다 수요가 많아서 깜짝 놀랐다. 보다 대중적인(?) 메신저인 카카오톡으로 운영하고 싶었지만 메시지를 보낼 때마다 비용이 발생해서 (아무리 토이 프로젝트라 해도…) 차마 엄두가 나질 않아 카카오톡 채널만 만들고 텔레그램 링크를 연결해두었다. 지금은 아예 손도 안대는 서비스이지만 잘 돌아가고 있는 걸 보면 자동화의 힘은 정말 대단하다는 걸 다시금 느껴본다.

    /images/review-2021/kakao.jpg
    카카오채널 가입자에게 메세지를 보낼 수 있음 좋을텐데…

    라이프 사이클의 변화

     문득 이렇게 재미있는 개발을 언제까지 할 수 있을까 하는 생각을 하게 된 적이 있다. 개발을 오랫동안 할 수 있는 방법이 무엇이 있을까 하는 생각의 끝에는 결국 “든든한 자산"과 “생각의 패러다임 전환”, 그리고 “건강"이라는 결론에 도달하게 되었다. 개발 업무 기기를 산다거나 신기술 학습을 위해 투자하기 위해서는 결국 돈이 필요하다고 느껴졌고, 공대생의 고립된(?) 가치관에서 다양한 인문학적인 관점들이 가미된다면 개발에도 훨씬 도움이 될 거라 생각이 들었다. 마지막으로 하루의 절반 이상을 의자에 앉아 컴퓨터만 바라보는 불쌍한 개발자의 삶이기에 건강관리는 빠져서는 안 될 중요한 부분이라 하루 시간 계획을 다시 정비했어야 했다. 마치 시간표대로 움직였던 학창 시절처럼.

     그렇게 자연스레 미라클 모닝을 하게 되며 오전 6시에 기상을 하게 되었고, 새벽의 고요함 속에서 경제 공부와 각종 뉴스레터를 보며 하루를 시작한다. 업무에 집중해야 하는 일과 시간에는 오로지 업무에만 집중하고 퇴근을 한 뒤 헬스를 하고서 저녁 12시 전에는 잠에 들어 수면시간을 6시간 확보하는 다람쥐 쳇바퀴 같은 삶. 자투리 시간에는 가보지 않은 세상을 가장 간단하고 가장 깔끔하며 가장 함축적으로 정리된 한 권의 책을 읽으면서 부족한 지식을 채우려 노력하는 중이다. 처음엔 너무 답답하고 재미없기 딱이었지만 막상 생활화되다 보니 오히려 건강하고 장점이 더 많은 라이프 사이클로 변화되고 있는 것 같아서 다행이라 생각한다.

    고장 나려는 개발자

     여러 가지 크고 작은 이슈들로 인해 조직 이동을 하게 되었다. 새로운 조직에서 담당하게 된 서비스의 성격은 이전에 담당했던 서비스와 비슷했지만 사뭇 다른 조직 분위기 속에서 시키지도 않은 일들을 해가며 열정을 불태우기 바빴다. 필자가 중요하게 생각하는 기술 부채 개선이나 단순 반복적인 업무에 대한 자동화, 각종 시스템/서비스 오류에 대한 알림 개선 등 서비스 기능 개발만큼이나 중요하지만 누군가 나서서 하기 싫은 일들을 야근을 해서라도 도맡아서 하려 했다. 그 때문이었을까. 조직에서 요구하는 필자의 스탠스(stance)와 필자가 취하려는 스탠스가 다른 부분에서 오는 힘듦이 참 견디기 힘들었다. 그러다 결국 고장 나려는 개발자로 몇 개월을 그냥 훌쩍 보내버린 것만 같아 너무 아쉽고 슬펐다.

    ※ 스탠스(stance) : 자세…라고 하기엔 뭔가 적당한 단어가 아닌듯하여..

     시니어니까(난 아직 중니어 같은데…) 다른 사람들을 이끌며 빠르게 업무 파악부터 하길 원하는 조직의 시선. 기술 부채같이 보기에 불편한 부분이 있으면 가만 놔두지 못하는 성격으로 직접 팔 걷어붙이고 나서려는 필자. 어떤 게 맞고 어떤 게 틀렸다고 속단하기에는 다소 무리가 있는 문제지만 어쨌거나 저쨌거나 조직에 ‘속해있는’ 조직원으로써, 그리고 회사라는 공간의 목적이 ‘성장(growth)‘보다는 ‘일(work)‘이 먼저일 수밖에 없기 때문에 여러 가지 다양한 생각의 무리들을 견주며 결국 나 자산이 고장 나지 않도록 다시 기름칠을 해야 하구나 하는 생각이 들었다.

    2022년, 🐯

     이제 올해 입사 일자가 지나면 10년 차(만 9년) 개발자가 된다. 10년 차라는 키워드만 보면 부끄럽기 짝이 없지만 단순히 눈앞에 있는 빨간 망토가 좋아 보인다고 돌진하는 황소처럼 개발만 할 것이 아니라 좀 더 높고 넓은 시선으로 다양한 관점을 고민해 볼 때가 온 거라 생각이 든다. 마치 성장통처럼. 개발자 인생 30년이라 하면 이제 겨우 3분의 1이 지난 시점에서 벌써부터 뭐가 맞다 틀리다 하며 괜히 힘을 뺄 이유는 없어 보이고. 다만, 다른 직군과는 달리 평생 공부하며 성장해야 하는 개발자인 만큼 올해에도 개발을 즐겁고 재미있게 할 수 있도록 다양한 시도를 통해 계속 도전하는 삶을 유지하는 게 맞아 보인다. 여기서 좌절하거나 포기하기엔 내 열정이나 마음에 너무 부끄러울 것 같아서.

    그러고 보니, 블로그를 너무 안썼네. 올해는 좀 다양한 시도를 블로그에 녹여보는 호흡을 가져야겠다.

     필자를 포함한 내가 아는 모든 개발자분들. 새해에는 호랑이 기운으로 버그와 장애 없는 즐거운 개발 라이프가 되길 바라본다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/posts/review-2023/index.html b/posts/review-2023/index.html index 56859306..9d078f3f 100644 --- a/posts/review-2023/index.html +++ b/posts/review-2023/index.html @@ -12,8 +12,9 @@  가끔은 팀 내에 쌈닭(?)이 되어 돌아만 가게 하던 일을 개발자로써 확장성과 유지 보수성을 위해 개선해 보자는 자세를 취해 보기도 했고 함께 일하는 주니어 분들께 하기 싫었지만 (그 시절 나를 보는 것만 같았던) 좀 더 올바른 개발자로서의 성장을 하는 바람으로 쓴소리를 몇 번 건넨 것 같다. 지나고 보면 좋은 게 좋다는 식으로 넘어가도 될법했나 싶지만 우리는 그저 코딩만 하는 기계가 아니기에. 누군가는 이런 생각과 말을 해야 하지 않을까 하는 이상한 책임감의 모자를 써보기도 했었다. IDC장애 대비 Jenkins 이중화 구성Active IDC 장애시 Standby IDC 에서 Jenkins 운용이 가능하다." IDC장애 대비 Jenkins 이중화 구성 Active IDC 장애시 Standby IDC 에서 Jenkins 운용이 가능하다. 사내 기술공유 행사 발표" 사내 기술공유 행사 발표  기술적 기억으로는 젠킨스 IDC 이중화를 위해(master-slave가 아닌) 스스로 꽤 장기간에 걸친 시행착오를 통해 젠킨스 클러스터를 IDC간 이중화 구성하기도 하였고 인원 대비 업무량이 많다 보니 늘어만 가는 기술 부채를 개선하고자 자체적으로 ‘기술/프로세스 개선 TF’를 구성해서 개발팀에서 챙겨야 할 부분들을 놓치지 않기 위한 장치들을 만들었다. 여러 output 중에 하나로 팀 내 주니어 분과 함께 하반기 사내 기술 공유 행사에서 “그런 배포 프로세스로 괜찮은가(feat. Github Action)“라는 제목으로 배포 자동화 사례를 사내 오픈소스화(Github Action Marketplace) 하여 발표하기도 하였다. -나름 열정스러운 모임 이름" 나름 열정스러운 모임 이름  사내 독서모임에서 모임장을 자처하여 인문학 독서 소모임을 만들고 10여명 정도의 사람들과 함께 진행을 해보기도 하였고, 같은 서비스를 만들고 있는 다양한 사람들끼리 한 달에 한 번씩 모여 식사 자리를 가졌던 미식회 모임을 운영해 보기도 하였다. 개발과는 관련이 없을 수도 있지만 여러 모임을 운영해 보면서 “관계” 그리고 “조직 운영"에 대한 부분을 간접적으로나마 느껴볼 수 있었던 것 좋은 경험으로 기억될 것 같다.">
    \ No newline at end of file diff --git a/posts/review-the-book-clean-agile/index.html b/posts/review-the-book-clean-agile/index.html index 69309d02..12e8a1d1 100644 --- a/posts/review-the-book-clean-agile/index.html +++ b/posts/review-the-book-clean-agile/index.html @@ -27,4 +27,4 @@ 

    • 오래된 메시지지만, 옳은 메시지다. 이 메시지는 작은 일을 하는 작은 소프트웨어 팀이 겪는 작은 문제에 대한 작은 해결책을 알려준다.

    • 당신은 코드의 변경을 두려워하고, 두려움 때문에 무능력해진다. 결과가 두려워서 필요한 코드 정리를 하지 못한다. 자신이 만든 이 코드를 완전히 통제할 수 없을 정도로 놔두었기 때문에 코드를 개선하는 일을 두려워하게 된다. 정말 무책임하다.

    • 소프트웨어(Software)는 합성어다. ‘웨어(ware)‘는 ‘제품(product)‘을 의미한다. ‘소프트(soft)‘는 바꾸기 쉽다는 뜻이다. 따라서 소프트웨어는 바꾸기 쉬운 제품이다.

    • 빌드를 깨 먹는 사람이 지켜야 하는 간단한 규칙을 하나 만들었습니다. 빌드를 깨먹은 날에는 “빌드를 깨 먹었어요"라고 적혀있는 티셔츠를 입어야 합니다. 참고로 이 티셔츠는 절대 빨지 않습니다.

    • 마감 일정의 압박이 심해지면 지속적 빌드를 깨진 채로 방치하는 팀이 더러 있다. 이건 자살행위다. 지속적 빌드 서버에서 쏟아지는 실패 메일에 지친 나머지 실패하는 테스트를 아예 빼버린다. ‘나중에’ 다시 추가하고 고칠 거라고 다짐했을 것이다. 덕분에 빌드 서버가 다시 성공 메일을 보내기 시작하고, 모두 안도의 한숨을 내쉴 것이다. 빌드가 통과했다. 그리고 ‘나중에’ 고치기로 하고 치워둔 실패하던 테스트 무더기는 모두가 잊어버린다. 결국 망가져 있는 시스템이 배포된다.

      끝으로, 이 책을 소개해준 asuraiv 님도 책 리뷰를 적었다고 하니 도움이 될것 같아 블로그 링크를 남겨 본다.


    Buy me a coffeeBuy me a coffee
    \ No newline at end of file +
    \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 7ba2a90d..f5bb25ac 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://taetaetae.github.io/tags/archives-2023/2023-12-31T15:26:10+09:00weekly1https://taetaetae.github.io/categories/2023-12-31T15:26:10+09:00weekly1https://taetaetae.github.io/posts/2023-12-31T15:26:10+09:00weekly1https://taetaetae.github.io/categories/review/2023-12-31T15:26:10+09:00weekly1https://taetaetae.github.io/tags/2023-12-31T15:26:10+09:00weekly1https://taetaetae.github.io/posts/review-2023/2023-12-31T15:26:10+09:00weekly1https://taetaetae.github.io/2023-12-31T15:26:10+09:00weekly1https://taetaetae.github.io/tags/a-good-developer/2023-07-23T10:39:22+09:00weekly1https://taetaetae.github.io/tags/curtule/2023-07-23T10:39:22+09:00weekly1https://taetaetae.github.io/categories/essay/2023-07-23T10:39:22+09:00weekly1https://taetaetae.github.io/posts/a-good-developer-in-terms-of-surroundings/2023-07-23T10:39:22+09:00weekly1https://taetaetae.github.io/tags/kafka/2023-02-19T23:39:22+09:00weekly1https://taetaetae.github.io/posts/kafka-service-utilization-study-case-review/2023-02-19T23:39:22+09:00weekly1https://taetaetae.github.io/tags/archives-2021/2022-01-02T21:45:40+09:00weekly1https://taetaetae.github.io/posts/review-2021/2022-01-02T21:45:40+09:00weekly1https://taetaetae.github.io/tags/employment/2021-10-24T16:07:11+09:00weekly1https://taetaetae.github.io/posts/a-good-developer-in-terms-of-employment/2021-10-24T16:07:11+09:00weekly1https://taetaetae.github.io/tags/gcp/2021-04-04T18:54:00+09:00weekly1https://taetaetae.github.io/tags/heroku/2021-04-04T18:54:00+09:00weekly1https://taetaetae.github.io/tags/public-offering-notice/2021-04-04T18:54:00+09:00weekly1https://taetaetae.github.io/categories/tech/2021-04-04T18:54:00+09:00weekly1https://taetaetae.github.io/posts/public-offering-notice-3/2021-04-04T18:54:00+09:00weekly1https://taetaetae.github.io/tags/bitly/2021-03-28T11:41:33+09:00weekly1https://taetaetae.github.io/tags/telegram/2021-03-28T11:41:33+09:00weekly1https://taetaetae.github.io/posts/public-offering-notice-2/2021-03-28T11:41:33+09:00weekly1https://taetaetae.github.io/tags/crawling/2021-03-21T19:13:49+09:00weekly1https://taetaetae.github.io/tags/jsoup/2021-03-21T19:13:49+09:00weekly1https://taetaetae.github.io/posts/public-offering-notice-1/2021-03-21T19:13:49+09:00weekly1https://taetaetae.github.io/tags/mentoring/2021-03-01T15:12:26+09:00weekly1https://taetaetae.github.io/posts/a-good-developer-in-terms-of-mentoring/2021-03-01T15:12:26+09:00weekly1https://taetaetae.github.io/tags/dashboard/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/posts/make-dashboards-from-elasticstack-2/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/tags/elasticsearch/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/tags/filebeat/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/tags/kibana/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/tags/logstash/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/posts/make-dashboards-from-elasticstack-1/2021-02-15T17:50:12+09:00weekly1https://taetaetae.github.io/tags/resume/2021-01-31T18:14:37+09:00weekly1https://taetaetae.github.io/posts/a-good-developer-in-terms-of-resume/2021-01-31T18:14:37+09:00weekly1https://taetaetae.github.io/tags/archives-2020/2020-12-31T13:31:01+09:00weekly1https://taetaetae.github.io/posts/review-2020/2020-12-31T13:31:01+09:00weekly1https://taetaetae.github.io/tags/agile/2020-12-27T17:06:19+09:00weekly1https://taetaetae.github.io/tags/book/2020-12-27T17:06:19+09:00weekly1https://taetaetae.github.io/tags/robert-c.-martin/2020-12-27T17:06:19+09:00weekly1https://taetaetae.github.io/tags/uncle-bob/2020-12-27T17:06:19+09:00weekly1https://taetaetae.github.io/posts/review-the-book-clean-agile/2020-12-27T17:06:19+09:00weekly1https://taetaetae.github.io/tags/openapi/2020-12-22T10:41:40+09:00weekly1https://taetaetae.github.io/tags/spring-rest-docs/2020-12-22T10:41:40+09:00weekly1https://taetaetae.github.io/tags/swagger/2020-12-22T10:41:40+09:00weekly1https://taetaetae.github.io/tags/swagger-ui/2020-12-22T10:41:40+09:00weekly1https://taetaetae.github.io/posts/a-combination-of-swagger-and-spring-restdocs/2020-12-22T10:41:40+09:00weekly1https://taetaetae.github.io/posts/openapi-and-swagger-ui-in-spring-boot/2020-12-20T11:42:40+09:00weekly1https://taetaetae.github.io/tags/jenkins/2020-12-06T20:19:47+09:00weekly1https://taetaetae.github.io/posts/jenkins-job-parallel-processing-by-pipeline/2020-12-06T20:19:47+09:00weekly1https://taetaetae.github.io/tags/pipeline/2020-12-06T20:19:47+09:00weekly1https://taetaetae.github.io/tags/blog/2020-11-29T18:12:15+09:00weekly1https://taetaetae.github.io/tags/github-actions/2020-11-29T18:12:15+09:00weekly1https://taetaetae.github.io/tags/hugo/2020-11-29T18:12:15+09:00weekly1https://taetaetae.github.io/posts/blog-reorganization-by-hugo/2020-11-29T18:12:15+09:00weekly1https://taetaetae.github.io/tags/log/2020-10-04T15:39:15+00:00weekly1https://taetaetae.github.io/tags/monitoring/2020-10-04T15:39:15+00:00weekly1https://taetaetae.github.io/2020/10/04/a-good-developer-in-terms-of-log-and-monitoring/2020-10-04T15:39:15+00:00weekly1https://taetaetae.github.io/tags/ci/2020-09-07T10:09:56+00:00weekly1https://taetaetae.github.io/tags/github/2020-09-07T10:09:56+00:00weekly1https://taetaetae.github.io/tags/pullrequest/2020-09-07T10:09:56+00:00weekly1https://taetaetae.github.io/2020/09/07/github-pullrequest-build/2020-09-07T10:09:56+00:00weekly1https://taetaetae.github.io/2020/07/12/toy-projects-second-year-review/2020-07-12T19:55:02+00:00weekly1https://taetaetae.github.io/tags/self-development/2020-06-28T20:51:03+00:00weekly1https://taetaetae.github.io/2020/06/28/a-good-developer-in-terms-of-self-development/2020-06-28T20:51:03+00:00weekly1https://taetaetae.github.io/2020/06/21/a-good-developer-in-terms-of-culture/2020-06-21T17:22:09+00:00weekly1https://taetaetae.github.io/tags/filter/2020-04-06T23:59:36+00:00weekly1https://taetaetae.github.io/tags/spring-boot/2020-04-06T23:59:36+00:00weekly1https://taetaetae.github.io/2020/04/06/spring-boot-filter/2020-04-06T23:59:36+00:00weekly1https://taetaetae.github.io/tags/circuit-breaker/2020-03-29T23:09:16+00:00weekly1https://taetaetae.github.io/tags/hystrix/2020-03-29T23:09:16+00:00weekly1https://taetaetae.github.io/tags/netflix/2020-03-29T23:09:16+00:00weekly1https://taetaetae.github.io/2020/03/29/better-rest-template-2-netflix-hystrix/2020-03-29T23:09:16+00:00weekly1https://taetaetae.github.io/2020/03/26/7-years-of-development-1st-day-of-manager/2020-03-26T23:37:17+00:00weekly1https://taetaetae.github.io/tags/retryable/2020-03-22T15:30:35+00:00weekly1https://taetaetae.github.io/2020/03/22/better-rest-template-1-retryable/2020-03-22T15:30:35+00:00weekly1https://taetaetae.github.io/2020/03/08/spring-rest-docs-in-spring-boot/2020-03-08T23:16:59+00:00weekly1https://taetaetae.github.io/tags/jupyter/2020-02-09T20:06:15+00:00weekly1https://taetaetae.github.io/2020/02/09/jupyter-install/2020-02-09T20:06:15+00:00weekly1https://taetaetae.github.io/tags/python/2020-02-09T20:06:15+00:00weekly1https://taetaetae.github.io/tags/maven/2020-01-19T10:29:03+00:00weekly1https://taetaetae.github.io/tags/module/2020-01-19T10:29:03+00:00weekly1https://taetaetae.github.io/tags/structure/2020-01-19T10:29:03+00:00weekly1https://taetaetae.github.io/2020/01/19/spring-boot-maven-multi-module/2020-01-19T10:29:03+00:00weekly1https://taetaetae.github.io/tags/archives-2019/2019-12-29T22:22:03+00:00weekly1https://taetaetae.github.io/tags/review/2019-12-29T22:22:03+00:00weekly1https://taetaetae.github.io/2019/12/29/review-2019/2019-12-29T22:22:03+00:00weekly1https://taetaetae.github.io/categories/blog/2019-10-27T13:51:16+00:00weekly1https://taetaetae.github.io/tags/writing/2019-10-27T13:51:16+00:00weekly1https://taetaetae.github.io/2019/10/27/a-reason-for-writing/2019-10-27T13:51:16+00:00weekly1https://taetaetae.github.io/tags/batch/2019-10-13T15:46:12+00:00weekly1https://taetaetae.github.io/tags/linux/2019-10-13T15:46:12+00:00weekly1https://taetaetae.github.io/2019/10/13/batch-nondisruptive-deploy/2019-10-13T15:46:12+00:00weekly1https://taetaetae.github.io/tags/spring/2019-09-29T17:55:50+00:00weekly1https://taetaetae.github.io/2019/09/29/woowabros-spring-batch/2019-09-29T17:55:50+00:00weekly1https://taetaetae.github.io/tags/network/2019-09-08T18:11:34+00:00weekly1https://taetaetae.github.io/tags/packetbeat/2019-09-08T18:11:34+00:00weekly1https://taetaetae.github.io/2019/09/08/network-monitor-by-packetbeat/2019-09-08T18:11:34+00:00weekly1https://taetaetae.github.io/tags/apache/2019-08-04T19:50:43+00:00weekly1https://taetaetae.github.io/tags/load-balance/2019-08-04T19:50:43+00:00weekly1https://taetaetae.github.io/tags/tomcat/2019-08-04T19:50:43+00:00weekly1https://taetaetae.github.io/2019/08/04/apache-load-balancing/2019-08-04T19:50:43+00:00weekly1https://taetaetae.github.io/tags/fileupload/2019-07-21T22:09:58+00:00weekly1https://taetaetae.github.io/2019/07/21/spring-file-upload/2019-07-21T22:09:58+00:00weekly1https://taetaetae.github.io/2019/07/07/review-first-half-2019/2019-07-07T17:52:20+00:00weekly1https://taetaetae.github.io/tags/%EA%B8%80%EB%98%90/2019-07-07T17:52:20+00:00weekly1https://taetaetae.github.io/tags/aop/2019-06-30T18:39:47+00:00weekly1https://taetaetae.github.io/tags/httpservletrequestwrapper/2019-06-30T18:39:47+00:00weekly1https://taetaetae.github.io/tags/logging/2019-06-30T18:39:47+00:00weekly1https://taetaetae.github.io/2019/06/30/controller-common-logging/2019-06-30T18:39:47+00:00weekly1https://taetaetae.github.io/2019/05/19/d-light-togetherthon-2019/2019-05-19T22:46:03+00:00weekly1https://taetaetae.github.io/tags/gdg/2019-05-19T22:46:03+00:00weekly1https://taetaetae.github.io/tags/hackathon/2019-05-19T22:46:03+00:00weekly1https://taetaetae.github.io/tags/java/2019-05-12T20:04:01+00:00weekly1https://taetaetae.github.io/tags/performance/2019-05-12T20:04:01+00:00weekly1https://taetaetae.github.io/2019/05/12/got-of-java-seminar/2019-05-12T20:04:01+00:00weekly1https://taetaetae.github.io/tags/mybatis/2019-04-21T22:47:04+00:00weekly1https://taetaetae.github.io/tags/mysql/2019-04-21T22:47:04+00:00weekly1https://taetaetae.github.io/2019/04/21/spring-boot-mybatis-mysql-xml/2019-04-21T22:47:04+00:00weekly1https://taetaetae.github.io/tags/aws/2019-04-14T17:39:03+00:00weekly1https://taetaetae.github.io/2019/04/14/aws-freetier-create-and-ssh-access/2019-04-14T17:39:03+00:00weekly1https://taetaetae.github.io/tags/ec2/2019-04-14T17:39:03+00:00weekly1https://taetaetae.github.io/tags/putty/2019-04-14T17:39:03+00:00weekly1https://taetaetae.github.io/2019/03/31/kafka-meetup-2019/2019-03-31T01:49:30+00:00weekly1https://taetaetae.github.io/tags/write/2019-03-24T21:43:14+00:00weekly1https://taetaetae.github.io/tags/write-the-docs/2019-03-24T21:43:14+00:00weekly1https://taetaetae.github.io/2019/03/24/write-the-docs-seoul-2019-review/2019-03-24T21:43:14+00:00weekly1https://taetaetae.github.io/2019/03/17/jenkins-upgrade-master-slave/2019-03-17T18:23:03+00:00weekly1https://taetaetae.github.io/2019/02/17/daily-dev-blog-3/2019-02-17T01:17:27+00:00weekly1https://taetaetae.github.io/2019/02/10/access-log-to-elastic-stack/2019-02-10T14:37:31+00:00weekly1https://taetaetae.github.io/tags/heap-dump/2019-01-10T18:39:47+00:00weekly1https://taetaetae.github.io/tags/out-of-memory/2019-01-10T18:39:47+00:00weekly1https://taetaetae.github.io/tags/redirect/2019-01-10T18:39:47+00:00weekly1https://taetaetae.github.io/2019/01/10/spring-redirect-oom/2019-01-10T18:39:47+00:00weekly1https://taetaetae.github.io/tags/parallel-precess/2019-01-02T12:43:44+00:00weekly1https://taetaetae.github.io/tags/rabbitmq/2019-01-02T12:43:44+00:00weekly1https://taetaetae.github.io/tags/redis/2019-01-02T12:43:44+00:00weekly1https://taetaetae.github.io/2019/01/02/faster-parallel-processes/2019-01-02T12:43:44+00:00weekly1https://taetaetae.github.io/2018/12/31/review-2018/2018-12-31T21:33:29+00:00weekly1https://taetaetae.github.io/tags/archives-2018/2018-12-31T21:33:29+00:00weekly1https://taetaetae.github.io/2018/12/13/elastic-meetup-201812/2018-12-13T22:27:02+00:00weekly1https://taetaetae.github.io/2018/12/02/jenkins-install/2018-12-02T04:37:59+00:00weekly1https://taetaetae.github.io/2018/12/02/python-buffer/2018-12-02T01:40:11+00:00weekly1https://taetaetae.github.io/tags/deview/2018-10-14T18:26:26+00:00weekly1https://taetaetae.github.io/2018/10/14/deview-2018/2018-10-14T18:26:26+00:00weekly1https://taetaetae.github.io/2018/08/28/pycon-2018/2018-08-28T23:43:16+00:00weekly1https://taetaetae.github.io/tags/pycon/2018-08-28T23:43:16+00:00weekly1https://taetaetae.github.io/tags/cloneutils/2018-08-21T18:02:47+00:00weekly1https://taetaetae.github.io/tags/java-deep-copy/2018-08-21T18:02:47+00:00weekly1https://taetaetae.github.io/2018/08/21/how-to-use-cloneutils/2018-08-21T18:02:47+00:00weekly1https://taetaetae.github.io/2018/08/09/daily-dev-blog-2/2018-08-09T20:37:26+00:00weekly1https://taetaetae.github.io/tags/flask/2018-08-05T10:27:21+00:00weekly1https://taetaetae.github.io/2018/08/05/daily-dev-blog-1/2018-08-05T10:27:21+00:00weekly1https://taetaetae.github.io/2018/07/01/open-source-software-develpoer-story-review/2018-07-01T10:00:00+00:00weekly1https://taetaetae.github.io/tags/open-source-software/2018-07-01T10:00:00+00:00weekly1https://taetaetae.github.io/tags/oss/2018-07-01T10:00:00+00:00weekly1https://taetaetae.github.io/tags/nginx/2018-07-01T02:00:00+00:00weekly1https://taetaetae.github.io/tags/web-server/2018-07-01T02:00:00+00:00weekly1https://taetaetae.github.io/2018/07/01/simple-web-server-flask-nginx/2018-07-01T02:00:00+00:00weekly1https://taetaetae.github.io/2018/06/29/simple-web-server-flask-apache/2018-06-29T23:00:00+00:00weekly1https://taetaetae.github.io/2018/06/27/apache-vs-nginx/2018-06-27T17:17:33+00:00weekly1https://taetaetae.github.io/tags/event-driven/2018-06-27T17:17:33+00:00weekly1https://taetaetae.github.io/tags/prefork-mpm/2018-06-27T17:17:33+00:00weekly1https://taetaetae.github.io/tags/worker-mpm/2018-06-27T17:17:33+00:00weekly1https://taetaetae.github.io/tags/anomaly-detection/2018-05-31T17:03:41+00:00weekly1https://taetaetae.github.io/tags/facebook/2018-05-31T17:03:41+00:00weekly1https://taetaetae.github.io/tags/prophet/2018-05-31T17:03:41+00:00weekly1https://taetaetae.github.io/2018/05/31/anomaly-detection/2018-05-31T17:03:41+00:00weekly1https://taetaetae.github.io/tags/408/2018-04-29T17:39:36+00:00weekly1https://taetaetae.github.io/2018/04/29/apache-408-response-code/2018-04-29T17:39:36+00:00weekly1https://taetaetae.github.io/tags/apache-access-log/2018-04-10T23:20:19+00:00weekly1https://taetaetae.github.io/tags/elasitcsearch/2018-04-10T23:20:19+00:00weekly1https://taetaetae.github.io/tags/user-agent/2018-04-10T23:20:19+00:00weekly1https://taetaetae.github.io/2018/04/10/apache-access-log-user-agent/2018-04-10T23:20:19+00:00weekly1https://taetaetae.github.io/tags/gzip/2018-04-01T17:58:11+00:00weekly1https://taetaetae.github.io/2018/04/01/apache-gzip/2018-04-01T17:58:11+00:00weekly1https://taetaetae.github.io/tags/mod_deflate/2018-04-01T17:58:11+00:00weekly1https://taetaetae.github.io/tags/restclientexception/2018-03-17T19:19:39+00:00weekly1https://taetaetae.github.io/2018/03/17/rest-client-exception/2018-03-17T19:19:39+00:00weekly1https://taetaetae.github.io/tags/resttemplate/2018-03-17T19:19:39+00:00weekly1https://taetaetae.github.io/tags/integration/2018-02-08T20:10:54+00:00weekly1https://taetaetae.github.io/tags/sonarqube/2018-02-08T20:10:54+00:00weekly1https://taetaetae.github.io/2018/02/08/jenkins-sonar-github-integration/2018-02-08T20:10:54+00:00weekly1https://taetaetae.github.io/2018/02/08/github-web-hook-jenkins-job-excute/2018-02-08T17:10:54+00:00weekly1https://taetaetae.github.io/tags/webhook/2018-02-08T17:10:54+00:00weekly1https://taetaetae.github.io/2018/02/08/github-with-jenkins/2018-02-08T17:10:21+00:00weekly1https://taetaetae.github.io/tags/chromedriver/2018-02-01T14:52:10+00:00weekly1https://taetaetae.github.io/2018/02/01/linux-selenium/2018-02-01T14:52:10+00:00weekly1https://taetaetae.github.io/tags/selenium/2018-02-01T14:52:10+00:00weekly1https://taetaetae.github.io/tags/access-log/2018-01-25T21:18:35+00:00weekly1https://taetaetae.github.io/2018/01/25/apache-access-log-to-es/2018-01-25T21:18:35+00:00weekly1https://taetaetae.github.io/2018/01/08/python-2-to-3/2018-01-08T13:44:50+00:00weekly1https://taetaetae.github.io/tags/archives-2017/2017-12-14T12:02:45+00:00weekly1https://taetaetae.github.io/2017/12/14/elastic-on-tour/2017-12-14T12:02:45+00:00weekly1https://taetaetae.github.io/2017/11/02/what-is-kafka/2017-11-02T21:30:13+00:00weekly1https://taetaetae.github.io/2017/10/16/deview-2017-review/2017-10-16T17:29:55+00:00weekly1https://taetaetae.github.io/2017/08/28/apache-keep-alive/2017-08-28T19:56:40+00:00weekly1https://taetaetae.github.io/tags/keepalive/2017-08-28T19:56:40+00:00weekly1https://taetaetae.github.io/tags/hexo/2017-08-27T17:52:56+00:00weekly1https://taetaetae.github.io/2017/08/27/hexo-themes-tranquilpeak/2017-08-27T17:52:56+00:00weekly1https://taetaetae.github.io/tags/tranquilpeak/2017-08-27T17:52:56+00:00weekly1https://taetaetae.github.io/2017/07/09/refresh/2017-07-09T17:16:23+00:00weekly1https://taetaetae.github.io/2017/04/04/mybatis-use-generated-keys/2017-04-04T11:41:28+00:00weekly1https://taetaetae.github.io/tags/oracle/2017-04-04T11:41:28+00:00weekly1https://taetaetae.github.io/tags/date/2017-03-23T11:16:05+00:00weekly1https://taetaetae.github.io/2017/03/23/oracle-mybatis-date/2017-03-23T11:16:05+00:00weekly1https://taetaetae.github.io/tags/modelattribute/2017-03-12T18:03:01+00:00weekly1https://taetaetae.github.io/tags/reqeustparam/2017-03-12T18:03:01+00:00weekly1https://taetaetae.github.io/tags/requestbody/2017-03-12T18:03:01+00:00weekly1https://taetaetae.github.io/tags/spring-command-%EA%B0%9D%EC%B2%B4/2017-03-12T18:03:01+00:00weekly1https://taetaetae.github.io/2017/03/12/spring-parameter/2017-03-12T18:03:01+00:00weekly1https://taetaetae.github.io/2017/03/08/a-quarter-of-this-year/2017-03-08T13:44:21+00:00weekly1https://taetaetae.github.io/2017/03/02/github-api/2017-03-02T11:18:05+00:00weekly1https://taetaetae.github.io/tags/jq/2017-02-28T17:50:44+00:00weekly1https://taetaetae.github.io/tags/json/2017-02-28T17:50:44+00:00weekly1https://taetaetae.github.io/2017/02/28/shell-script-json/2017-02-28T17:50:44+00:00weekly1https://taetaetae.github.io/tags/eclipse/2017-02-27T14:37:27+00:00weekly1https://taetaetae.github.io/2017/02/27/spring-boot-eclipse/2017-02-27T14:37:27+00:00weekly1https://taetaetae.github.io/tags/lombok/2017-02-22T17:48:42+00:00weekly1https://taetaetae.github.io/2017/02/22/lombok/2017-02-22T17:48:42+00:00weekly1https://taetaetae.github.io/tags/logback/2017-02-19T15:10:45+00:00weekly1https://taetaetae.github.io/2017/02/19/logback/2017-02-19T15:10:45+00:00weekly1https://taetaetae.github.io/2017/01/10/java8-date/2017-01-10T20:55:33+00:00weekly1https://taetaetae.github.io/2017/01/08/transactional-setting-and-property/2017-01-08T17:19:30+00:00weekly1https://taetaetae.github.io/tags/transaction/2017-01-08T17:19:30+00:00weekly1https://taetaetae.github.io/2017/01/07/spring4-json/2017-01-07T15:47:59+00:00weekly1https://taetaetae.github.io/tags/jsp/2017-01-04T18:36:17+00:00weekly1https://taetaetae.github.io/2017/01/04/20170104/2017-01-04T18:36:17+00:00weekly1https://taetaetae.github.io/2017/01/01/hello-2017/2017-01-01T15:49:31+00:00weekly1https://taetaetae.github.io/2016/12/31/adieu-2016/2016-12-31T16:59:43+00:00weekly1https://taetaetae.github.io/tags/archives-2016/2016-12-31T16:59:43+00:00weekly1https://taetaetae.github.io/2016/10/08/20161008/2016-10-08T18:04:19+00:00weekly1https://taetaetae.github.io/tags/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4/2016-10-06T17:03:48+00:00weekly1https://taetaetae.github.io/2016/10/06/20161006/2016-10-06T17:03:48+00:00weekly1https://taetaetae.github.io/tags/%EC%8B%B1%EA%B8%80%ED%86%A4/2016-10-06T17:03:48+00:00weekly1https://taetaetae.github.io/2016/09/23/20160923/2016-09-23T10:26:53+00:00weekly1https://taetaetae.github.io/2016/09/18/hexo_github_blog/2016-09-18T15:38:34+00:00weekly1https://taetaetae.github.io/2016/09/18/first/2016-09-18T00:34:23+00:00weekly1 \ No newline at end of file +https://taetaetae.github.io/tags/a-good-developer/2024-01-07T00:16:21+09:00weekly1https://taetaetae.github.io/tags/archives-2024/2024-01-07T00:16:21+09:00weekly1https://taetaetae.github.io/categories/2024-01-07T00:16:21+09:00weekly1https://taetaetae.github.io/categories/essay/2024-01-07T00:16:21+09:00weekly1https://taetaetae.github.io/posts/2024-01-07T00:16:21+09:00weekly1https://taetaetae.github.io/tags/study/2024-01-07T00:16:21+09:00weekly1https://taetaetae.github.io/tags/2024-01-07T00:16:21+09:00weekly1https://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/2024-01-07T00:16:21+09:00weekly1https://taetaetae.github.io/2024-01-07T00:16:21+09:00weekly1https://taetaetae.github.io/tags/archives-2023/2023-12-31T15:26:10+09:00weekly1https://taetaetae.github.io/categories/review/2023-12-31T15:26:10+09:00weekly1https://taetaetae.github.io/posts/review-2023/2023-12-31T15:26:10+09:00weekly1https://taetaetae.github.io/tags/curtule/2023-07-23T10:39:22+09:00weekly1https://taetaetae.github.io/posts/a-good-developer-in-terms-of-surroundings/2023-07-23T10:39:22+09:00weekly1https://taetaetae.github.io/tags/kafka/2023-02-19T23:39:22+09:00weekly1https://taetaetae.github.io/posts/kafka-service-utilization-study-case-review/2023-02-19T23:39:22+09:00weekly1https://taetaetae.github.io/tags/archives-2021/2022-01-02T21:45:40+09:00weekly1https://taetaetae.github.io/posts/review-2021/2022-01-02T21:45:40+09:00weekly1https://taetaetae.github.io/tags/employment/2021-10-24T16:07:11+09:00weekly1https://taetaetae.github.io/posts/a-good-developer-in-terms-of-employment/2021-10-24T16:07:11+09:00weekly1https://taetaetae.github.io/tags/gcp/2021-04-04T18:54:00+09:00weekly1https://taetaetae.github.io/tags/heroku/2021-04-04T18:54:00+09:00weekly1https://taetaetae.github.io/tags/public-offering-notice/2021-04-04T18:54:00+09:00weekly1https://taetaetae.github.io/categories/tech/2021-04-04T18:54:00+09:00weekly1https://taetaetae.github.io/posts/public-offering-notice-3/2021-04-04T18:54:00+09:00weekly1https://taetaetae.github.io/tags/bitly/2021-03-28T11:41:33+09:00weekly1https://taetaetae.github.io/tags/telegram/2021-03-28T11:41:33+09:00weekly1https://taetaetae.github.io/posts/public-offering-notice-2/2021-03-28T11:41:33+09:00weekly1https://taetaetae.github.io/tags/crawling/2021-03-21T19:13:49+09:00weekly1https://taetaetae.github.io/tags/jsoup/2021-03-21T19:13:49+09:00weekly1https://taetaetae.github.io/posts/public-offering-notice-1/2021-03-21T19:13:49+09:00weekly1https://taetaetae.github.io/tags/mentoring/2021-03-01T15:12:26+09:00weekly1https://taetaetae.github.io/posts/a-good-developer-in-terms-of-mentoring/2021-03-01T15:12:26+09:00weekly1https://taetaetae.github.io/tags/dashboard/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/posts/make-dashboards-from-elasticstack-2/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/tags/elasticsearch/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/tags/filebeat/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/tags/kibana/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/tags/logstash/2021-02-17T16:53:49+09:00weekly1https://taetaetae.github.io/posts/make-dashboards-from-elasticstack-1/2021-02-15T17:50:12+09:00weekly1https://taetaetae.github.io/tags/resume/2021-01-31T18:14:37+09:00weekly1https://taetaetae.github.io/posts/a-good-developer-in-terms-of-resume/2021-01-31T18:14:37+09:00weekly1https://taetaetae.github.io/tags/archives-2020/2020-12-31T13:31:01+09:00weekly1https://taetaetae.github.io/posts/review-2020/2020-12-31T13:31:01+09:00weekly1https://taetaetae.github.io/tags/agile/2020-12-27T17:06:19+09:00weekly1https://taetaetae.github.io/tags/book/2020-12-27T17:06:19+09:00weekly1https://taetaetae.github.io/tags/robert-c.-martin/2020-12-27T17:06:19+09:00weekly1https://taetaetae.github.io/tags/uncle-bob/2020-12-27T17:06:19+09:00weekly1https://taetaetae.github.io/posts/review-the-book-clean-agile/2020-12-27T17:06:19+09:00weekly1https://taetaetae.github.io/tags/openapi/2020-12-22T10:41:40+09:00weekly1https://taetaetae.github.io/tags/spring-rest-docs/2020-12-22T10:41:40+09:00weekly1https://taetaetae.github.io/tags/swagger/2020-12-22T10:41:40+09:00weekly1https://taetaetae.github.io/tags/swagger-ui/2020-12-22T10:41:40+09:00weekly1https://taetaetae.github.io/posts/a-combination-of-swagger-and-spring-restdocs/2020-12-22T10:41:40+09:00weekly1https://taetaetae.github.io/posts/openapi-and-swagger-ui-in-spring-boot/2020-12-20T11:42:40+09:00weekly1https://taetaetae.github.io/tags/jenkins/2020-12-06T20:19:47+09:00weekly1https://taetaetae.github.io/posts/jenkins-job-parallel-processing-by-pipeline/2020-12-06T20:19:47+09:00weekly1https://taetaetae.github.io/tags/pipeline/2020-12-06T20:19:47+09:00weekly1https://taetaetae.github.io/tags/blog/2020-11-29T18:12:15+09:00weekly1https://taetaetae.github.io/tags/github-actions/2020-11-29T18:12:15+09:00weekly1https://taetaetae.github.io/tags/hugo/2020-11-29T18:12:15+09:00weekly1https://taetaetae.github.io/posts/blog-reorganization-by-hugo/2020-11-29T18:12:15+09:00weekly1https://taetaetae.github.io/tags/log/2020-10-04T15:39:15+00:00weekly1https://taetaetae.github.io/tags/monitoring/2020-10-04T15:39:15+00:00weekly1https://taetaetae.github.io/2020/10/04/a-good-developer-in-terms-of-log-and-monitoring/2020-10-04T15:39:15+00:00weekly1https://taetaetae.github.io/tags/ci/2020-09-07T10:09:56+00:00weekly1https://taetaetae.github.io/tags/github/2020-09-07T10:09:56+00:00weekly1https://taetaetae.github.io/tags/pullrequest/2020-09-07T10:09:56+00:00weekly1https://taetaetae.github.io/2020/09/07/github-pullrequest-build/2020-09-07T10:09:56+00:00weekly1https://taetaetae.github.io/2020/07/12/toy-projects-second-year-review/2020-07-12T19:55:02+00:00weekly1https://taetaetae.github.io/tags/self-development/2020-06-28T20:51:03+00:00weekly1https://taetaetae.github.io/2020/06/28/a-good-developer-in-terms-of-self-development/2020-06-28T20:51:03+00:00weekly1https://taetaetae.github.io/2020/06/21/a-good-developer-in-terms-of-culture/2020-06-21T17:22:09+00:00weekly1https://taetaetae.github.io/tags/filter/2020-04-06T23:59:36+00:00weekly1https://taetaetae.github.io/tags/spring-boot/2020-04-06T23:59:36+00:00weekly1https://taetaetae.github.io/2020/04/06/spring-boot-filter/2020-04-06T23:59:36+00:00weekly1https://taetaetae.github.io/tags/circuit-breaker/2020-03-29T23:09:16+00:00weekly1https://taetaetae.github.io/tags/hystrix/2020-03-29T23:09:16+00:00weekly1https://taetaetae.github.io/tags/netflix/2020-03-29T23:09:16+00:00weekly1https://taetaetae.github.io/2020/03/29/better-rest-template-2-netflix-hystrix/2020-03-29T23:09:16+00:00weekly1https://taetaetae.github.io/2020/03/26/7-years-of-development-1st-day-of-manager/2020-03-26T23:37:17+00:00weekly1https://taetaetae.github.io/tags/retryable/2020-03-22T15:30:35+00:00weekly1https://taetaetae.github.io/2020/03/22/better-rest-template-1-retryable/2020-03-22T15:30:35+00:00weekly1https://taetaetae.github.io/2020/03/08/spring-rest-docs-in-spring-boot/2020-03-08T23:16:59+00:00weekly1https://taetaetae.github.io/tags/jupyter/2020-02-09T20:06:15+00:00weekly1https://taetaetae.github.io/2020/02/09/jupyter-install/2020-02-09T20:06:15+00:00weekly1https://taetaetae.github.io/tags/python/2020-02-09T20:06:15+00:00weekly1https://taetaetae.github.io/tags/maven/2020-01-19T10:29:03+00:00weekly1https://taetaetae.github.io/tags/module/2020-01-19T10:29:03+00:00weekly1https://taetaetae.github.io/tags/structure/2020-01-19T10:29:03+00:00weekly1https://taetaetae.github.io/2020/01/19/spring-boot-maven-multi-module/2020-01-19T10:29:03+00:00weekly1https://taetaetae.github.io/tags/archives-2019/2019-12-29T22:22:03+00:00weekly1https://taetaetae.github.io/tags/review/2019-12-29T22:22:03+00:00weekly1https://taetaetae.github.io/2019/12/29/review-2019/2019-12-29T22:22:03+00:00weekly1https://taetaetae.github.io/categories/blog/2019-10-27T13:51:16+00:00weekly1https://taetaetae.github.io/tags/writing/2019-10-27T13:51:16+00:00weekly1https://taetaetae.github.io/2019/10/27/a-reason-for-writing/2019-10-27T13:51:16+00:00weekly1https://taetaetae.github.io/tags/batch/2019-10-13T15:46:12+00:00weekly1https://taetaetae.github.io/tags/linux/2019-10-13T15:46:12+00:00weekly1https://taetaetae.github.io/2019/10/13/batch-nondisruptive-deploy/2019-10-13T15:46:12+00:00weekly1https://taetaetae.github.io/tags/spring/2019-09-29T17:55:50+00:00weekly1https://taetaetae.github.io/2019/09/29/woowabros-spring-batch/2019-09-29T17:55:50+00:00weekly1https://taetaetae.github.io/tags/network/2019-09-08T18:11:34+00:00weekly1https://taetaetae.github.io/tags/packetbeat/2019-09-08T18:11:34+00:00weekly1https://taetaetae.github.io/2019/09/08/network-monitor-by-packetbeat/2019-09-08T18:11:34+00:00weekly1https://taetaetae.github.io/tags/apache/2019-08-04T19:50:43+00:00weekly1https://taetaetae.github.io/tags/load-balance/2019-08-04T19:50:43+00:00weekly1https://taetaetae.github.io/tags/tomcat/2019-08-04T19:50:43+00:00weekly1https://taetaetae.github.io/2019/08/04/apache-load-balancing/2019-08-04T19:50:43+00:00weekly1https://taetaetae.github.io/tags/fileupload/2019-07-21T22:09:58+00:00weekly1https://taetaetae.github.io/2019/07/21/spring-file-upload/2019-07-21T22:09:58+00:00weekly1https://taetaetae.github.io/2019/07/07/review-first-half-2019/2019-07-07T17:52:20+00:00weekly1https://taetaetae.github.io/tags/%EA%B8%80%EB%98%90/2019-07-07T17:52:20+00:00weekly1https://taetaetae.github.io/tags/aop/2019-06-30T18:39:47+00:00weekly1https://taetaetae.github.io/tags/httpservletrequestwrapper/2019-06-30T18:39:47+00:00weekly1https://taetaetae.github.io/tags/logging/2019-06-30T18:39:47+00:00weekly1https://taetaetae.github.io/2019/06/30/controller-common-logging/2019-06-30T18:39:47+00:00weekly1https://taetaetae.github.io/2019/05/19/d-light-togetherthon-2019/2019-05-19T22:46:03+00:00weekly1https://taetaetae.github.io/tags/gdg/2019-05-19T22:46:03+00:00weekly1https://taetaetae.github.io/tags/hackathon/2019-05-19T22:46:03+00:00weekly1https://taetaetae.github.io/tags/java/2019-05-12T20:04:01+00:00weekly1https://taetaetae.github.io/tags/performance/2019-05-12T20:04:01+00:00weekly1https://taetaetae.github.io/2019/05/12/got-of-java-seminar/2019-05-12T20:04:01+00:00weekly1https://taetaetae.github.io/tags/mybatis/2019-04-21T22:47:04+00:00weekly1https://taetaetae.github.io/tags/mysql/2019-04-21T22:47:04+00:00weekly1https://taetaetae.github.io/2019/04/21/spring-boot-mybatis-mysql-xml/2019-04-21T22:47:04+00:00weekly1https://taetaetae.github.io/tags/aws/2019-04-14T17:39:03+00:00weekly1https://taetaetae.github.io/2019/04/14/aws-freetier-create-and-ssh-access/2019-04-14T17:39:03+00:00weekly1https://taetaetae.github.io/tags/ec2/2019-04-14T17:39:03+00:00weekly1https://taetaetae.github.io/tags/putty/2019-04-14T17:39:03+00:00weekly1https://taetaetae.github.io/2019/03/31/kafka-meetup-2019/2019-03-31T01:49:30+00:00weekly1https://taetaetae.github.io/tags/write/2019-03-24T21:43:14+00:00weekly1https://taetaetae.github.io/tags/write-the-docs/2019-03-24T21:43:14+00:00weekly1https://taetaetae.github.io/2019/03/24/write-the-docs-seoul-2019-review/2019-03-24T21:43:14+00:00weekly1https://taetaetae.github.io/2019/03/17/jenkins-upgrade-master-slave/2019-03-17T18:23:03+00:00weekly1https://taetaetae.github.io/2019/02/17/daily-dev-blog-3/2019-02-17T01:17:27+00:00weekly1https://taetaetae.github.io/2019/02/10/access-log-to-elastic-stack/2019-02-10T14:37:31+00:00weekly1https://taetaetae.github.io/tags/heap-dump/2019-01-10T18:39:47+00:00weekly1https://taetaetae.github.io/tags/out-of-memory/2019-01-10T18:39:47+00:00weekly1https://taetaetae.github.io/tags/redirect/2019-01-10T18:39:47+00:00weekly1https://taetaetae.github.io/2019/01/10/spring-redirect-oom/2019-01-10T18:39:47+00:00weekly1https://taetaetae.github.io/tags/parallel-precess/2019-01-02T12:43:44+00:00weekly1https://taetaetae.github.io/tags/rabbitmq/2019-01-02T12:43:44+00:00weekly1https://taetaetae.github.io/tags/redis/2019-01-02T12:43:44+00:00weekly1https://taetaetae.github.io/2019/01/02/faster-parallel-processes/2019-01-02T12:43:44+00:00weekly1https://taetaetae.github.io/2018/12/31/review-2018/2018-12-31T21:33:29+00:00weekly1https://taetaetae.github.io/tags/archives-2018/2018-12-31T21:33:29+00:00weekly1https://taetaetae.github.io/2018/12/13/elastic-meetup-201812/2018-12-13T22:27:02+00:00weekly1https://taetaetae.github.io/2018/12/02/jenkins-install/2018-12-02T04:37:59+00:00weekly1https://taetaetae.github.io/2018/12/02/python-buffer/2018-12-02T01:40:11+00:00weekly1https://taetaetae.github.io/tags/deview/2018-10-14T18:26:26+00:00weekly1https://taetaetae.github.io/2018/10/14/deview-2018/2018-10-14T18:26:26+00:00weekly1https://taetaetae.github.io/2018/08/28/pycon-2018/2018-08-28T23:43:16+00:00weekly1https://taetaetae.github.io/tags/pycon/2018-08-28T23:43:16+00:00weekly1https://taetaetae.github.io/tags/cloneutils/2018-08-21T18:02:47+00:00weekly1https://taetaetae.github.io/tags/java-deep-copy/2018-08-21T18:02:47+00:00weekly1https://taetaetae.github.io/2018/08/21/how-to-use-cloneutils/2018-08-21T18:02:47+00:00weekly1https://taetaetae.github.io/2018/08/09/daily-dev-blog-2/2018-08-09T20:37:26+00:00weekly1https://taetaetae.github.io/tags/flask/2018-08-05T10:27:21+00:00weekly1https://taetaetae.github.io/2018/08/05/daily-dev-blog-1/2018-08-05T10:27:21+00:00weekly1https://taetaetae.github.io/2018/07/01/open-source-software-develpoer-story-review/2018-07-01T10:00:00+00:00weekly1https://taetaetae.github.io/tags/open-source-software/2018-07-01T10:00:00+00:00weekly1https://taetaetae.github.io/tags/oss/2018-07-01T10:00:00+00:00weekly1https://taetaetae.github.io/tags/nginx/2018-07-01T02:00:00+00:00weekly1https://taetaetae.github.io/tags/web-server/2018-07-01T02:00:00+00:00weekly1https://taetaetae.github.io/2018/07/01/simple-web-server-flask-nginx/2018-07-01T02:00:00+00:00weekly1https://taetaetae.github.io/2018/06/29/simple-web-server-flask-apache/2018-06-29T23:00:00+00:00weekly1https://taetaetae.github.io/2018/06/27/apache-vs-nginx/2018-06-27T17:17:33+00:00weekly1https://taetaetae.github.io/tags/event-driven/2018-06-27T17:17:33+00:00weekly1https://taetaetae.github.io/tags/prefork-mpm/2018-06-27T17:17:33+00:00weekly1https://taetaetae.github.io/tags/worker-mpm/2018-06-27T17:17:33+00:00weekly1https://taetaetae.github.io/tags/anomaly-detection/2018-05-31T17:03:41+00:00weekly1https://taetaetae.github.io/tags/facebook/2018-05-31T17:03:41+00:00weekly1https://taetaetae.github.io/tags/prophet/2018-05-31T17:03:41+00:00weekly1https://taetaetae.github.io/2018/05/31/anomaly-detection/2018-05-31T17:03:41+00:00weekly1https://taetaetae.github.io/tags/408/2018-04-29T17:39:36+00:00weekly1https://taetaetae.github.io/2018/04/29/apache-408-response-code/2018-04-29T17:39:36+00:00weekly1https://taetaetae.github.io/tags/apache-access-log/2018-04-10T23:20:19+00:00weekly1https://taetaetae.github.io/tags/elasitcsearch/2018-04-10T23:20:19+00:00weekly1https://taetaetae.github.io/tags/user-agent/2018-04-10T23:20:19+00:00weekly1https://taetaetae.github.io/2018/04/10/apache-access-log-user-agent/2018-04-10T23:20:19+00:00weekly1https://taetaetae.github.io/tags/gzip/2018-04-01T17:58:11+00:00weekly1https://taetaetae.github.io/2018/04/01/apache-gzip/2018-04-01T17:58:11+00:00weekly1https://taetaetae.github.io/tags/mod_deflate/2018-04-01T17:58:11+00:00weekly1https://taetaetae.github.io/tags/restclientexception/2018-03-17T19:19:39+00:00weekly1https://taetaetae.github.io/2018/03/17/rest-client-exception/2018-03-17T19:19:39+00:00weekly1https://taetaetae.github.io/tags/resttemplate/2018-03-17T19:19:39+00:00weekly1https://taetaetae.github.io/tags/integration/2018-02-08T20:10:54+00:00weekly1https://taetaetae.github.io/tags/sonarqube/2018-02-08T20:10:54+00:00weekly1https://taetaetae.github.io/2018/02/08/jenkins-sonar-github-integration/2018-02-08T20:10:54+00:00weekly1https://taetaetae.github.io/2018/02/08/github-web-hook-jenkins-job-excute/2018-02-08T17:10:54+00:00weekly1https://taetaetae.github.io/tags/webhook/2018-02-08T17:10:54+00:00weekly1https://taetaetae.github.io/2018/02/08/github-with-jenkins/2018-02-08T17:10:21+00:00weekly1https://taetaetae.github.io/tags/chromedriver/2018-02-01T14:52:10+00:00weekly1https://taetaetae.github.io/2018/02/01/linux-selenium/2018-02-01T14:52:10+00:00weekly1https://taetaetae.github.io/tags/selenium/2018-02-01T14:52:10+00:00weekly1https://taetaetae.github.io/tags/access-log/2018-01-25T21:18:35+00:00weekly1https://taetaetae.github.io/2018/01/25/apache-access-log-to-es/2018-01-25T21:18:35+00:00weekly1https://taetaetae.github.io/2018/01/08/python-2-to-3/2018-01-08T13:44:50+00:00weekly1https://taetaetae.github.io/tags/archives-2017/2017-12-14T12:02:45+00:00weekly1https://taetaetae.github.io/2017/12/14/elastic-on-tour/2017-12-14T12:02:45+00:00weekly1https://taetaetae.github.io/2017/11/02/what-is-kafka/2017-11-02T21:30:13+00:00weekly1https://taetaetae.github.io/2017/10/16/deview-2017-review/2017-10-16T17:29:55+00:00weekly1https://taetaetae.github.io/2017/08/28/apache-keep-alive/2017-08-28T19:56:40+00:00weekly1https://taetaetae.github.io/tags/keepalive/2017-08-28T19:56:40+00:00weekly1https://taetaetae.github.io/tags/hexo/2017-08-27T17:52:56+00:00weekly1https://taetaetae.github.io/2017/08/27/hexo-themes-tranquilpeak/2017-08-27T17:52:56+00:00weekly1https://taetaetae.github.io/tags/tranquilpeak/2017-08-27T17:52:56+00:00weekly1https://taetaetae.github.io/2017/07/09/refresh/2017-07-09T17:16:23+00:00weekly1https://taetaetae.github.io/2017/04/04/mybatis-use-generated-keys/2017-04-04T11:41:28+00:00weekly1https://taetaetae.github.io/tags/oracle/2017-04-04T11:41:28+00:00weekly1https://taetaetae.github.io/tags/date/2017-03-23T11:16:05+00:00weekly1https://taetaetae.github.io/2017/03/23/oracle-mybatis-date/2017-03-23T11:16:05+00:00weekly1https://taetaetae.github.io/tags/modelattribute/2017-03-12T18:03:01+00:00weekly1https://taetaetae.github.io/tags/reqeustparam/2017-03-12T18:03:01+00:00weekly1https://taetaetae.github.io/tags/requestbody/2017-03-12T18:03:01+00:00weekly1https://taetaetae.github.io/tags/spring-command-%EA%B0%9D%EC%B2%B4/2017-03-12T18:03:01+00:00weekly1https://taetaetae.github.io/2017/03/12/spring-parameter/2017-03-12T18:03:01+00:00weekly1https://taetaetae.github.io/2017/03/08/a-quarter-of-this-year/2017-03-08T13:44:21+00:00weekly1https://taetaetae.github.io/2017/03/02/github-api/2017-03-02T11:18:05+00:00weekly1https://taetaetae.github.io/tags/jq/2017-02-28T17:50:44+00:00weekly1https://taetaetae.github.io/tags/json/2017-02-28T17:50:44+00:00weekly1https://taetaetae.github.io/2017/02/28/shell-script-json/2017-02-28T17:50:44+00:00weekly1https://taetaetae.github.io/tags/eclipse/2017-02-27T14:37:27+00:00weekly1https://taetaetae.github.io/2017/02/27/spring-boot-eclipse/2017-02-27T14:37:27+00:00weekly1https://taetaetae.github.io/tags/lombok/2017-02-22T17:48:42+00:00weekly1https://taetaetae.github.io/2017/02/22/lombok/2017-02-22T17:48:42+00:00weekly1https://taetaetae.github.io/tags/logback/2017-02-19T15:10:45+00:00weekly1https://taetaetae.github.io/2017/02/19/logback/2017-02-19T15:10:45+00:00weekly1https://taetaetae.github.io/2017/01/10/java8-date/2017-01-10T20:55:33+00:00weekly1https://taetaetae.github.io/2017/01/08/transactional-setting-and-property/2017-01-08T17:19:30+00:00weekly1https://taetaetae.github.io/tags/transaction/2017-01-08T17:19:30+00:00weekly1https://taetaetae.github.io/2017/01/07/spring4-json/2017-01-07T15:47:59+00:00weekly1https://taetaetae.github.io/tags/jsp/2017-01-04T18:36:17+00:00weekly1https://taetaetae.github.io/2017/01/04/20170104/2017-01-04T18:36:17+00:00weekly1https://taetaetae.github.io/2017/01/01/hello-2017/2017-01-01T15:49:31+00:00weekly1https://taetaetae.github.io/2016/12/31/adieu-2016/2016-12-31T16:59:43+00:00weekly1https://taetaetae.github.io/tags/archives-2016/2016-12-31T16:59:43+00:00weekly1https://taetaetae.github.io/2016/10/08/20161008/2016-10-08T18:04:19+00:00weekly1https://taetaetae.github.io/tags/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4/2016-10-06T17:03:48+00:00weekly1https://taetaetae.github.io/2016/10/06/20161006/2016-10-06T17:03:48+00:00weekly1https://taetaetae.github.io/tags/%EC%8B%B1%EA%B8%80%ED%86%A4/2016-10-06T17:03:48+00:00weekly1https://taetaetae.github.io/2016/09/23/20160923/2016-09-23T10:26:53+00:00weekly1https://taetaetae.github.io/2016/09/18/hexo_github_blog/2016-09-18T15:38:34+00:00weekly1https://taetaetae.github.io/2016/09/18/first/2016-09-18T00:34:23+00:00weekly1 \ No newline at end of file diff --git a/tags/408/index.html b/tags/408/index.html index c4073bcd..96829b23 100644 --- a/tags/408/index.html +++ b/tags/408/index.html @@ -1,3 +1,3 @@ 408 - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-29
    \ No newline at end of file diff --git a/tags/a-good-developer/index.html b/tags/a-good-developer/index.html index fa03c41f..15042a05 100644 --- a/tags/a-good-developer/index.html +++ b/tags/a-good-developer/index.html @@ -1,9 +1,10 @@ -a-good-developer - Tag - 👨‍💻꿈꾸는 태태태의 공간

     a-good-developer

    2023

    그런 개발자로 괜찮은가 - '환경' 편 +a-good-developer - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-21
    \ No newline at end of file diff --git a/tags/a-good-developer/index.xml b/tags/a-good-developer/index.xml index a55d7916..7c41e92c 100644 --- a/tags/a-good-developer/index.xml +++ b/tags/a-good-developer/index.xml @@ -1,4 +1,14 @@ -a-good-developer - Tag - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/tags/a-good-developer/a-good-developer - Tag - 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 23 Jul 2023 10:39:22 +0900그런 개발자로 괜찮은가 - '환경' 편https://taetaetae.github.io/posts/a-good-developer-in-terms-of-surroundings/Sun, 23 Jul 2023 10:39:22 +0900Authorhttps://taetaetae.github.io/posts/a-good-developer-in-terms-of-surroundings/ +a-good-developer - Tag - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/tags/a-good-developer/a-good-developer - Tag - 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 07 Jan 2024 00:16:21 +0900그런 개발자로 괜찮은가 - '그룹 스터디' 편https://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/Sun, 07 Jan 2024 00:16:21 +0900Authorhttps://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/ + + 다양한 방식으로 스터디를 해왔다. 정말 많은 것을 배웠던 스터디도 있는가 반면에 지나고 보면 시간이 아까울 정도의 스터디도 있었던 것 같다. 직접 만들어 보기도 했고 참여도 해봤던 것 같다. 이런저런 경험들 끝에 작년 중순에 직접 만들었던 스터디 멤버와는 어느덧 반년을 넘어가고 있는데 바쁜 회사 생활을 하면서도 이제까지 지속할 수 있었던 노하우를 공유해 보고자 한다. +그룹 스터디 방식 인원  다 그런 건 아니지만 기존 회사 분들과 스터디를 할 때면 아무래도 원래 알던 사이라 바빠서 준비를 못 해오거나 불참을 하는 경우에 “그럴 수도 있지”, “괜찮아” 하며 관대해졌던 것 같다. 또는 다양한 의견을 듣자며 10명 이상 진행을 했던 것 같다. 그렇다 보니 스터디 진행에 집중도가 떨어질 수밖에 없었고 모였을 때 이야기하던 사람들만 이야기한다든지, 중도 하차하는 경험도 많았다. +블라인드 글에 첨부한 스터디 참여 설문" 블라인드 글에 첨부한 스터디 참여 설문  이번 스터디는 직접 ‘블라인드’라는 익명 커뮤니티를 통해 인원을 모았다. 작년 중순쯤 자바 백엔드 관련된 주제를 스터디 하겠다며 나와 비슷한 연차분들 위주로 모으겠다고 글을 작성했더니 신기하게도 3~40명 되는 분들이나 지원하셨고 그중 오프라인 모임을 고려해서 나 포함 6명 만으로 구성을 하였다.(뭔가 서류 전형 인사담당자가 된 느낌;;) 작은 규모 그리고 새로운 분들과 하게 되니 집중도가 오르는 경험을 할 수 있었고 무엇보다 6명 모두 다른 회사라 각 회사를 대표하는 것 같은 느낌이 들어 스터디 참여에 몰입이나 책임감이 더욱 올랐던 것 같다. 또한 한 주제에 대해 각 회사에서의 경험들을 이야기하다 보니 완전히 다른 시각을 얻을 수 있다는 장점도 있었다. + 별거 아닐 수도 있지만(또는 오해가 될 수도 있지만) 남녀 성비, 그리고 나이대(연차)를 최대한 맞추고 싶었다. 그래야 분위기가 적당히 딱딱하지도, 부드럽지도 않을 것 같았기 때문이다. 지금은 여자 한 분 나머지 남자분들이라 초반에 걱정도 되었지만 생각보다 분위기가 잘 흘러가서 다행이라 생각을 한다. +주제와 목표 배워야 할게 한도 끝도 없는 개발자 세상스터디 목표에 따라 집중해야 할 범위를 좁히자!" 배워야 할게 한도 끝도 없는 개발자 세상 +스터디 목표에 따라 집중해야 할 범위를 좁히자!  처음부터 모니터 받침으로 하기 좋을만한 두꺼운 책은 피했던 것 같다. 가볍게, 스터디원들끼리의 친밀도부터 올려야 한다는 생각으로 너무 딥 다이브 한 기술적인 내용보다는 누구나 한마디 정도 할 수 있을만한 가벼운 책부터 시작했다. 그러면서 최대한 참여도를 올리는데 집중했던 것 같다. + 어디까지나 “공부"를 하기 위한 모임이긴 하지만 이 또한 사람과 사람 사이의 “관계"가 중요하다고 생각했기에 모였을 때 바로 스터디 이야기를 하는 것보다 부드러운 아이스브레이킹을 자주 해왔다. 또한 너무 루즈 해지지 않게 1달~1달 반 정도로 끝날 수 있을만한 주제를 선정했다. 아무래도 한 주제가 2~3달 걸리다 보면 집중도가 떨어지는 경험이 많았기 때문이다. 책 한 권을 다 읽었다는 기간을 짧게 가져가면서 작은 성취의 효과를 최대한 활용하고 있다. 이번 회차가 벌써 네 번째인걸 보면 그래도 나름 잘 선택한 방법이라 생각이 든다. + 한 회차가 끝날 즈음엔 다음 스터디는 무엇을 할 것인지에 대해 이야기를 하고 다수가 동의하는 주제를 선정한다. 또한 매 회차가 끝날 때마다 어쩌면 어색할 수 있는 이야기지만 스터디 참여를 그만 둘지에 대해 의사를 분명히 물어본다. (그런데 신기하게도 지금 스터디 모임은 이런 이야기를 하기도 전에 스터디 하고 싶은 주제를 먼저 말씀해주시는 편이라, 어쩌면 스스로 사람 운이 좋다는 생각도 해본다.) + 그저 하나의 책을 읽기로 끝나는 “책 읽기 모임” 이 아닌 만큼 책을 기반으로 하는 스터디 모임일지라도 목표를 분명하게 잡는다. 여기서 목표는 개인마다 다를 수 있다. 가령 스터디 시간에 나왔던 내용을 각자의 팀에 공유 및 반영을 해본다든지, 스터디 내용에 대해 주도적으로 이야기를 하며 다른 분들의 지식을 훔쳐보겠다든지(?]]>그런 개발자로 괜찮은가 - '환경' 편https://taetaetae.github.io/posts/a-good-developer-in-terms-of-surroundings/Sun, 23 Jul 2023 10:39:22 +0900Authorhttps://taetaetae.github.io/posts/a-good-developer-in-terms-of-surroundings/ (필자의 과거 경험을 미루어) 개발자로서 회사에서 일을 하다 보면 가끔 CRUD(Create, Read, Update, Delete) API를 찍어내는 기계(?)가 되는 느낌을 받을 때가 있다. 일정은 촉박한데 사람은 부족하고, 기술 부채가 복리로 늘어나는 게 눈에 훤히 보이지만 개선할 시간이나 여유조차 없어 자신도 모르게 점점 “돌아가게만” 개발하는 상황들. 기술적인 고민을 할 시간은 점점 없어지고, 코드를 설계하는 측면이나 테스트 코드, 책임과 관심 같은 생각들은 하지 못한 채 편의만 추구하며 코드를 작성한다. 그러다 이직을 해야겠다 마음먹고 이력서를 작성할 때나 연말 평가를 위해 한 해 무엇을 했는지 돌아보면 회사일은 불철주야 정말 열심히 했지만 회사를 벗어나 개발자로써 본인 스스로를 위한 건 회사일 대비 아주 극소수에 불과하는 삶이 계속된다. 코딩하는 로봇은 되지 말자.출처 : https://sdtimes.com/ai/ai-enabled-tools-might-completely-change-development-one-day/" 코딩하는 로봇은 되지 말자. diff --git a/tags/access-log/index.html b/tags/access-log/index.html index d41f2e8b..3253edec 100644 --- a/tags/access-log/index.html +++ b/tags/access-log/index.html @@ -1,3 +1,3 @@ access log - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-25
    \ No newline at end of file diff --git a/tags/agile/index.html b/tags/agile/index.html index 49171f4b..19c8879b 100644 --- a/tags/agile/index.html +++ b/tags/agile/index.html @@ -1,3 +1,3 @@ agile - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +12-27
    \ No newline at end of file diff --git a/tags/anomaly-detection/index.html b/tags/anomaly-detection/index.html index 179913fb..6d927fdc 100644 --- a/tags/anomaly-detection/index.html +++ b/tags/anomaly-detection/index.html @@ -1,3 +1,3 @@ anomaly detection - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +05-31
    \ No newline at end of file diff --git a/tags/aop/index.html b/tags/aop/index.html index 5634ffd1..d49ca32d 100644 --- a/tags/aop/index.html +++ b/tags/aop/index.html @@ -1,3 +1,3 @@ AOP - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-30
    \ No newline at end of file diff --git a/tags/apache-access-log/index.html b/tags/apache-access-log/index.html index ac6420af..2f35047d 100644 --- a/tags/apache-access-log/index.html +++ b/tags/apache-access-log/index.html @@ -1,3 +1,3 @@ apache access log - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-10
    \ No newline at end of file diff --git a/tags/apache/index.html b/tags/apache/index.html index b604cda7..9e52e0a3 100644 --- a/tags/apache/index.html +++ b/tags/apache/index.html @@ -5,4 +5,4 @@ 06-29

    2017

    \ No newline at end of file +08-28
    \ No newline at end of file diff --git a/tags/archives-2016/index.html b/tags/archives-2016/index.html index 04d37138..fe7e6a66 100644 --- a/tags/archives-2016/index.html +++ b/tags/archives-2016/index.html @@ -5,4 +5,4 @@ 10-06
    \ No newline at end of file +09-18
    \ No newline at end of file diff --git a/tags/archives-2017/index.html b/tags/archives-2017/index.html index 36c29733..e3eaebe6 100644 --- a/tags/archives-2017/index.html +++ b/tags/archives-2017/index.html @@ -9,4 +9,4 @@ 04-04
    \ No newline at end of file +03-08
    \ No newline at end of file diff --git a/tags/archives-2017/page/2/index.html b/tags/archives-2017/page/2/index.html index 73e4888e..48137dfc 100644 --- a/tags/archives-2017/page/2/index.html +++ b/tags/archives-2017/page/2/index.html @@ -9,4 +9,4 @@ 01-08
    \ No newline at end of file +01-01
    \ No newline at end of file diff --git a/tags/archives-2018/index.html b/tags/archives-2018/index.html index e2a9e154..c4554b80 100644 --- a/tags/archives-2018/index.html +++ b/tags/archives-2018/index.html @@ -9,4 +9,4 @@ 08-21
    \ No newline at end of file +07-01
    \ No newline at end of file diff --git a/tags/archives-2018/page/2/index.html b/tags/archives-2018/page/2/index.html index 0db63dc7..0be8f9fc 100644 --- a/tags/archives-2018/page/2/index.html +++ b/tags/archives-2018/page/2/index.html @@ -9,4 +9,4 @@ 04-01
    \ No newline at end of file +02-08
    \ No newline at end of file diff --git a/tags/archives-2018/page/3/index.html b/tags/archives-2018/page/3/index.html index 6fd91a42..10e484bc 100644 --- a/tags/archives-2018/page/3/index.html +++ b/tags/archives-2018/page/3/index.html @@ -3,4 +3,4 @@ 02-08
    \ No newline at end of file +01-08
    \ No newline at end of file diff --git a/tags/archives-2019/index.html b/tags/archives-2019/index.html index 99eb8519..10f1b35b 100644 --- a/tags/archives-2019/index.html +++ b/tags/archives-2019/index.html @@ -9,4 +9,4 @@ 07-21
    \ No newline at end of file +05-19
    \ No newline at end of file diff --git a/tags/archives-2019/page/2/index.html b/tags/archives-2019/page/2/index.html index 3ba2cda3..59146bf3 100644 --- a/tags/archives-2019/page/2/index.html +++ b/tags/archives-2019/page/2/index.html @@ -8,4 +8,4 @@ 03-17
    \ No newline at end of file +01-02
    \ No newline at end of file diff --git a/tags/archives-2020/index.html b/tags/archives-2020/index.html index 859c7d09..0da13d00 100644 --- a/tags/archives-2020/index.html +++ b/tags/archives-2020/index.html @@ -9,4 +9,4 @@ 10-04
    \ No newline at end of file +06-28
    \ No newline at end of file diff --git a/tags/archives-2020/page/2/index.html b/tags/archives-2020/page/2/index.html index b56ccb06..007ee618 100644 --- a/tags/archives-2020/page/2/index.html +++ b/tags/archives-2020/page/2/index.html @@ -7,4 +7,4 @@ 03-22
    \ No newline at end of file +01-19
    \ No newline at end of file diff --git a/tags/archives-2021/index.html b/tags/archives-2021/index.html index 327ae5a5..9881afd0 100644 --- a/tags/archives-2021/index.html +++ b/tags/archives-2021/index.html @@ -8,4 +8,4 @@ 03-01
    \ No newline at end of file +01-31
    \ No newline at end of file diff --git a/tags/archives-2023/index.html b/tags/archives-2023/index.html index 56a93c5b..dcfe89e9 100644 --- a/tags/archives-2023/index.html +++ b/tags/archives-2023/index.html @@ -2,4 +2,4 @@
    \ No newline at end of file +02-19
    \ No newline at end of file diff --git a/tags/archives-2024/index.html b/tags/archives-2024/index.html new file mode 100644 index 00000000..50423912 --- /dev/null +++ b/tags/archives-2024/index.html @@ -0,0 +1,3 @@ +archives-2024 - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file diff --git a/tags/archives-2024/index.xml b/tags/archives-2024/index.xml new file mode 100644 index 00000000..2f2fda15 --- /dev/null +++ b/tags/archives-2024/index.xml @@ -0,0 +1,11 @@ +archives-2024 - Tag - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/tags/archives-2024/archives-2024 - Tag - 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 07 Jan 2024 00:16:21 +0900그런 개발자로 괜찮은가 - '그룹 스터디' 편https://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/Sun, 07 Jan 2024 00:16:21 +0900Authorhttps://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/ + + 다양한 방식으로 스터디를 해왔다. 정말 많은 것을 배웠던 스터디도 있는가 반면에 지나고 보면 시간이 아까울 정도의 스터디도 있었던 것 같다. 직접 만들어 보기도 했고 참여도 해봤던 것 같다. 이런저런 경험들 끝에 작년 중순에 직접 만들었던 스터디 멤버와는 어느덧 반년을 넘어가고 있는데 바쁜 회사 생활을 하면서도 이제까지 지속할 수 있었던 노하우를 공유해 보고자 한다. +그룹 스터디 방식 인원  다 그런 건 아니지만 기존 회사 분들과 스터디를 할 때면 아무래도 원래 알던 사이라 바빠서 준비를 못 해오거나 불참을 하는 경우에 “그럴 수도 있지”, “괜찮아” 하며 관대해졌던 것 같다. 또는 다양한 의견을 듣자며 10명 이상 진행을 했던 것 같다. 그렇다 보니 스터디 진행에 집중도가 떨어질 수밖에 없었고 모였을 때 이야기하던 사람들만 이야기한다든지, 중도 하차하는 경험도 많았다. +블라인드 글에 첨부한 스터디 참여 설문" 블라인드 글에 첨부한 스터디 참여 설문  이번 스터디는 직접 ‘블라인드’라는 익명 커뮤니티를 통해 인원을 모았다. 작년 중순쯤 자바 백엔드 관련된 주제를 스터디 하겠다며 나와 비슷한 연차분들 위주로 모으겠다고 글을 작성했더니 신기하게도 3~40명 되는 분들이나 지원하셨고 그중 오프라인 모임을 고려해서 나 포함 6명 만으로 구성을 하였다.(뭔가 서류 전형 인사담당자가 된 느낌;;) 작은 규모 그리고 새로운 분들과 하게 되니 집중도가 오르는 경험을 할 수 있었고 무엇보다 6명 모두 다른 회사라 각 회사를 대표하는 것 같은 느낌이 들어 스터디 참여에 몰입이나 책임감이 더욱 올랐던 것 같다. 또한 한 주제에 대해 각 회사에서의 경험들을 이야기하다 보니 완전히 다른 시각을 얻을 수 있다는 장점도 있었다. + 별거 아닐 수도 있지만(또는 오해가 될 수도 있지만) 남녀 성비, 그리고 나이대(연차)를 최대한 맞추고 싶었다. 그래야 분위기가 적당히 딱딱하지도, 부드럽지도 않을 것 같았기 때문이다. 지금은 여자 한 분 나머지 남자분들이라 초반에 걱정도 되었지만 생각보다 분위기가 잘 흘러가서 다행이라 생각을 한다. +주제와 목표 배워야 할게 한도 끝도 없는 개발자 세상스터디 목표에 따라 집중해야 할 범위를 좁히자!" 배워야 할게 한도 끝도 없는 개발자 세상 +스터디 목표에 따라 집중해야 할 범위를 좁히자!  처음부터 모니터 받침으로 하기 좋을만한 두꺼운 책은 피했던 것 같다. 가볍게, 스터디원들끼리의 친밀도부터 올려야 한다는 생각으로 너무 딥 다이브 한 기술적인 내용보다는 누구나 한마디 정도 할 수 있을만한 가벼운 책부터 시작했다. 그러면서 최대한 참여도를 올리는데 집중했던 것 같다. + 어디까지나 “공부"를 하기 위한 모임이긴 하지만 이 또한 사람과 사람 사이의 “관계"가 중요하다고 생각했기에 모였을 때 바로 스터디 이야기를 하는 것보다 부드러운 아이스브레이킹을 자주 해왔다. 또한 너무 루즈 해지지 않게 1달~1달 반 정도로 끝날 수 있을만한 주제를 선정했다. 아무래도 한 주제가 2~3달 걸리다 보면 집중도가 떨어지는 경험이 많았기 때문이다. 책 한 권을 다 읽었다는 기간을 짧게 가져가면서 작은 성취의 효과를 최대한 활용하고 있다. 이번 회차가 벌써 네 번째인걸 보면 그래도 나름 잘 선택한 방법이라 생각이 든다. + 한 회차가 끝날 즈음엔 다음 스터디는 무엇을 할 것인지에 대해 이야기를 하고 다수가 동의하는 주제를 선정한다. 또한 매 회차가 끝날 때마다 어쩌면 어색할 수 있는 이야기지만 스터디 참여를 그만 둘지에 대해 의사를 분명히 물어본다. (그런데 신기하게도 지금 스터디 모임은 이런 이야기를 하기도 전에 스터디 하고 싶은 주제를 먼저 말씀해주시는 편이라, 어쩌면 스스로 사람 운이 좋다는 생각도 해본다.) + 그저 하나의 책을 읽기로 끝나는 “책 읽기 모임” 이 아닌 만큼 책을 기반으로 하는 스터디 모임일지라도 목표를 분명하게 잡는다. 여기서 목표는 개인마다 다를 수 있다. 가령 스터디 시간에 나왔던 내용을 각자의 팀에 공유 및 반영을 해본다든지, 스터디 내용에 대해 주도적으로 이야기를 하며 다른 분들의 지식을 훔쳐보겠다든지(?]]> \ No newline at end of file diff --git a/tags/archives-2024/page/1/index.html b/tags/archives-2024/page/1/index.html new file mode 100644 index 00000000..3c367891 --- /dev/null +++ b/tags/archives-2024/page/1/index.html @@ -0,0 +1 @@ +https://taetaetae.github.io/tags/archives-2024/ \ No newline at end of file diff --git a/tags/aws/index.html b/tags/aws/index.html index 78eab8ed..181c3371 100644 --- a/tags/aws/index.html +++ b/tags/aws/index.html @@ -1,4 +1,4 @@ aws - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +08-05
    \ No newline at end of file diff --git a/tags/batch/index.html b/tags/batch/index.html index 5bea4026..6480d9ef 100644 --- a/tags/batch/index.html +++ b/tags/batch/index.html @@ -1,4 +1,4 @@ batch - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +09-29
    \ No newline at end of file diff --git a/tags/bitly/index.html b/tags/bitly/index.html index 9b9249fc..1e61b02e 100644 --- a/tags/bitly/index.html +++ b/tags/bitly/index.html @@ -1,3 +1,3 @@ bitly - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-28
    \ No newline at end of file diff --git a/tags/blog/index.html b/tags/blog/index.html index f78552b0..5d7ddb96 100644 --- a/tags/blog/index.html +++ b/tags/blog/index.html @@ -2,4 +2,4 @@
    \ No newline at end of file +03-24
    \ No newline at end of file diff --git a/tags/book/index.html b/tags/book/index.html index 110d50cc..5584ea74 100644 --- a/tags/book/index.html +++ b/tags/book/index.html @@ -1,4 +1,4 @@ book - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-26
    \ No newline at end of file diff --git a/tags/chromedriver/index.html b/tags/chromedriver/index.html index a8c8d7fa..f1f4c3c4 100644 --- a/tags/chromedriver/index.html +++ b/tags/chromedriver/index.html @@ -1,3 +1,3 @@ chromedriver - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-01
    \ No newline at end of file diff --git a/tags/ci/index.html b/tags/ci/index.html index 6e8a2d36..9e81dbf2 100644 --- a/tags/ci/index.html +++ b/tags/ci/index.html @@ -1,3 +1,3 @@ ci - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +09-07
    \ No newline at end of file diff --git a/tags/circuit-breaker/index.html b/tags/circuit-breaker/index.html index 6d8f494b..4cef2030 100644 --- a/tags/circuit-breaker/index.html +++ b/tags/circuit-breaker/index.html @@ -1,3 +1,3 @@ circuit breaker - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-29
    \ No newline at end of file diff --git a/tags/cloneutils/index.html b/tags/cloneutils/index.html index 1ee41cf5..e6945d21 100644 --- a/tags/cloneutils/index.html +++ b/tags/cloneutils/index.html @@ -1,3 +1,3 @@ cloneUtils - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +08-21
    \ No newline at end of file diff --git a/tags/crawling/index.html b/tags/crawling/index.html index 04154b9a..06e0deb3 100644 --- a/tags/crawling/index.html +++ b/tags/crawling/index.html @@ -1,3 +1,3 @@ crawling - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-21
    \ No newline at end of file diff --git a/tags/curtule/index.html b/tags/curtule/index.html index 60cf5842..bcc7c573 100644 --- a/tags/curtule/index.html +++ b/tags/curtule/index.html @@ -1,4 +1,4 @@ curtule - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-21
    \ No newline at end of file diff --git a/tags/dashboard/index.html b/tags/dashboard/index.html index 0dcf0bc4..651130f1 100644 --- a/tags/dashboard/index.html +++ b/tags/dashboard/index.html @@ -1,4 +1,4 @@ dashboard - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-15
    \ No newline at end of file diff --git a/tags/date/index.html b/tags/date/index.html index c61a2e6d..6a202fbe 100644 --- a/tags/date/index.html +++ b/tags/date/index.html @@ -1,4 +1,4 @@ date - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-10
    \ No newline at end of file diff --git a/tags/deview/index.html b/tags/deview/index.html index 28671a69..07631ac0 100644 --- a/tags/deview/index.html +++ b/tags/deview/index.html @@ -1,4 +1,4 @@ deview - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +10-16
    \ No newline at end of file diff --git a/tags/ec2/index.html b/tags/ec2/index.html index 56ce9857..a532609b 100644 --- a/tags/ec2/index.html +++ b/tags/ec2/index.html @@ -1,3 +1,3 @@ ec2 - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-14
    \ No newline at end of file diff --git a/tags/eclipse/index.html b/tags/eclipse/index.html index a761391c..21e9adc8 100644 --- a/tags/eclipse/index.html +++ b/tags/eclipse/index.html @@ -1,3 +1,3 @@ eclipse - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-27
    \ No newline at end of file diff --git a/tags/elasitcsearch/index.html b/tags/elasitcsearch/index.html index ea72e54b..a4b4364d 100644 --- a/tags/elasitcsearch/index.html +++ b/tags/elasitcsearch/index.html @@ -1,3 +1,3 @@ Elasitcsearch - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-10
    \ No newline at end of file diff --git a/tags/elasticsearch/index.html b/tags/elasticsearch/index.html index 46707f4b..6a625050 100644 --- a/tags/elasticsearch/index.html +++ b/tags/elasticsearch/index.html @@ -6,4 +6,4 @@ 12-13

    2017

    \ No newline at end of file +12-14
    \ No newline at end of file diff --git a/tags/employment/index.html b/tags/employment/index.html index b76b3619..fe1129bb 100644 --- a/tags/employment/index.html +++ b/tags/employment/index.html @@ -1,3 +1,3 @@ employment - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +10-24
    \ No newline at end of file diff --git a/tags/event-driven/index.html b/tags/event-driven/index.html index a0028115..03c09c2b 100644 --- a/tags/event-driven/index.html +++ b/tags/event-driven/index.html @@ -1,3 +1,3 @@ Event Driven - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-27
    \ No newline at end of file diff --git a/tags/facebook/index.html b/tags/facebook/index.html index b11456dc..4f4b085a 100644 --- a/tags/facebook/index.html +++ b/tags/facebook/index.html @@ -1,3 +1,3 @@ facebook - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +05-31
    \ No newline at end of file diff --git a/tags/filebeat/index.html b/tags/filebeat/index.html index 0c1679e7..81d7a1e4 100644 --- a/tags/filebeat/index.html +++ b/tags/filebeat/index.html @@ -2,4 +2,4 @@
    \ No newline at end of file +02-10
    \ No newline at end of file diff --git a/tags/fileupload/index.html b/tags/fileupload/index.html index 5545f856..21f2cabc 100644 --- a/tags/fileupload/index.html +++ b/tags/fileupload/index.html @@ -1,3 +1,3 @@ fileupload - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +07-21
    \ No newline at end of file diff --git a/tags/filter/index.html b/tags/filter/index.html index 775d8fd7..0b7d2fd7 100644 --- a/tags/filter/index.html +++ b/tags/filter/index.html @@ -1,4 +1,4 @@ Filter - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-30
    \ No newline at end of file diff --git a/tags/flask/index.html b/tags/flask/index.html index bb0ff907..1b941464 100644 --- a/tags/flask/index.html +++ b/tags/flask/index.html @@ -2,4 +2,4 @@
    \ No newline at end of file +06-29
    \ No newline at end of file diff --git a/tags/gcp/index.html b/tags/gcp/index.html index b683e988..8c3f6a62 100644 --- a/tags/gcp/index.html +++ b/tags/gcp/index.html @@ -1,3 +1,3 @@ gcp - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-04
    \ No newline at end of file diff --git a/tags/gdg/index.html b/tags/gdg/index.html index 7f19de08..4f3b16c3 100644 --- a/tags/gdg/index.html +++ b/tags/gdg/index.html @@ -1,3 +1,3 @@ gdg - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +05-19
    \ No newline at end of file diff --git a/tags/github-actions/index.html b/tags/github-actions/index.html index 5b3a4894..ce09215b 100644 --- a/tags/github-actions/index.html +++ b/tags/github-actions/index.html @@ -1,3 +1,3 @@ github-actions - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +11-29
    \ No newline at end of file diff --git a/tags/github/index.html b/tags/github/index.html index d7817dda..3851f549 100644 --- a/tags/github/index.html +++ b/tags/github/index.html @@ -4,4 +4,4 @@ 02-08

    2017

    \ No newline at end of file +03-02
    \ No newline at end of file diff --git a/tags/gzip/index.html b/tags/gzip/index.html index a5bf5d0c..c227d4f3 100644 --- a/tags/gzip/index.html +++ b/tags/gzip/index.html @@ -1,3 +1,3 @@ gzip - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-01
    \ No newline at end of file diff --git a/tags/hackathon/index.html b/tags/hackathon/index.html index bb4db620..7285c5d9 100644 --- a/tags/hackathon/index.html +++ b/tags/hackathon/index.html @@ -1,3 +1,3 @@ hackathon - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +05-19
    \ No newline at end of file diff --git a/tags/heap-dump/index.html b/tags/heap-dump/index.html index 7c83be89..10c21860 100644 --- a/tags/heap-dump/index.html +++ b/tags/heap-dump/index.html @@ -1,3 +1,3 @@ heap dump - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-10
    \ No newline at end of file diff --git a/tags/heroku/index.html b/tags/heroku/index.html index 163591cf..60cb4b59 100644 --- a/tags/heroku/index.html +++ b/tags/heroku/index.html @@ -1,3 +1,3 @@ heroku - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-04
    \ No newline at end of file diff --git a/tags/hexo/index.html b/tags/hexo/index.html index d7231268..7fd95cb7 100644 --- a/tags/hexo/index.html +++ b/tags/hexo/index.html @@ -2,4 +2,4 @@
    \ No newline at end of file +09-18
    \ No newline at end of file diff --git a/tags/httpservletrequestwrapper/index.html b/tags/httpservletrequestwrapper/index.html index eb6bc43f..ce113cf9 100644 --- a/tags/httpservletrequestwrapper/index.html +++ b/tags/httpservletrequestwrapper/index.html @@ -1,3 +1,3 @@ HttpServletRequestWrapper - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-30
    \ No newline at end of file diff --git a/tags/hugo/index.html b/tags/hugo/index.html index c26c6948..495aead3 100644 --- a/tags/hugo/index.html +++ b/tags/hugo/index.html @@ -1,3 +1,3 @@ hugo - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +11-29
    \ No newline at end of file diff --git a/tags/hystrix/index.html b/tags/hystrix/index.html index 950ae602..f6c7ce58 100644 --- a/tags/hystrix/index.html +++ b/tags/hystrix/index.html @@ -1,3 +1,3 @@ Hystrix - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-29
    \ No newline at end of file diff --git a/tags/index.html b/tags/index.html index de25fbd4..b1459474 100644 --- a/tags/index.html +++ b/tags/index.html @@ -1,2 +1,2 @@ -All Tags - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +All Tags - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file diff --git a/tags/index.xml b/tags/index.xml index bbbafcb7..e048659f 100644 --- a/tags/index.xml +++ b/tags/index.xml @@ -1 +1 @@ -Tags - Tag - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/tags/Tags - Tag - 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 31 Dec 2023 15:26:10 +0900archives-2023https://taetaetae.github.io/tags/archives-2023/Sun, 31 Dec 2023 15:26:10 +0900Authorhttps://taetaetae.github.io/tags/archives-2023/a-good-developerhttps://taetaetae.github.io/tags/a-good-developer/Sun, 23 Jul 2023 10:39:22 +0900Authorhttps://taetaetae.github.io/tags/a-good-developer/curtulehttps://taetaetae.github.io/tags/curtule/Sun, 23 Jul 2023 10:39:22 +0900Authorhttps://taetaetae.github.io/tags/curtule/kafkahttps://taetaetae.github.io/tags/kafka/Sun, 19 Feb 2023 23:39:22 +0900Authorhttps://taetaetae.github.io/tags/kafka/archives-2021https://taetaetae.github.io/tags/archives-2021/Sun, 02 Jan 2022 21:45:40 +0900Authorhttps://taetaetae.github.io/tags/archives-2021/employmenthttps://taetaetae.github.io/tags/employment/Sun, 24 Oct 2021 16:07:11 +0900Authorhttps://taetaetae.github.io/tags/employment/gcphttps://taetaetae.github.io/tags/gcp/Sun, 04 Apr 2021 18:54:00 +0900Authorhttps://taetaetae.github.io/tags/gcp/herokuhttps://taetaetae.github.io/tags/heroku/Sun, 04 Apr 2021 18:54:00 +0900Authorhttps://taetaetae.github.io/tags/heroku/public-offering-noticehttps://taetaetae.github.io/tags/public-offering-notice/Sun, 04 Apr 2021 18:54:00 +0900Authorhttps://taetaetae.github.io/tags/public-offering-notice/bitlyhttps://taetaetae.github.io/tags/bitly/Sun, 28 Mar 2021 11:41:33 +0900Authorhttps://taetaetae.github.io/tags/bitly/ \ No newline at end of file +Tags - Tag - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/tags/Tags - Tag - 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 07 Jan 2024 00:16:21 +0900a-good-developerhttps://taetaetae.github.io/tags/a-good-developer/Sun, 07 Jan 2024 00:16:21 +0900Authorhttps://taetaetae.github.io/tags/a-good-developer/archives-2024https://taetaetae.github.io/tags/archives-2024/Sun, 07 Jan 2024 00:16:21 +0900Authorhttps://taetaetae.github.io/tags/archives-2024/studyhttps://taetaetae.github.io/tags/study/Sun, 07 Jan 2024 00:16:21 +0900Authorhttps://taetaetae.github.io/tags/study/archives-2023https://taetaetae.github.io/tags/archives-2023/Sun, 31 Dec 2023 15:26:10 +0900Authorhttps://taetaetae.github.io/tags/archives-2023/curtulehttps://taetaetae.github.io/tags/curtule/Sun, 23 Jul 2023 10:39:22 +0900Authorhttps://taetaetae.github.io/tags/curtule/kafkahttps://taetaetae.github.io/tags/kafka/Sun, 19 Feb 2023 23:39:22 +0900Authorhttps://taetaetae.github.io/tags/kafka/archives-2021https://taetaetae.github.io/tags/archives-2021/Sun, 02 Jan 2022 21:45:40 +0900Authorhttps://taetaetae.github.io/tags/archives-2021/employmenthttps://taetaetae.github.io/tags/employment/Sun, 24 Oct 2021 16:07:11 +0900Authorhttps://taetaetae.github.io/tags/employment/gcphttps://taetaetae.github.io/tags/gcp/Sun, 04 Apr 2021 18:54:00 +0900Authorhttps://taetaetae.github.io/tags/gcp/herokuhttps://taetaetae.github.io/tags/heroku/Sun, 04 Apr 2021 18:54:00 +0900Authorhttps://taetaetae.github.io/tags/heroku/ \ No newline at end of file diff --git a/tags/integration/index.html b/tags/integration/index.html index 25c2f6d1..2295cdd6 100644 --- a/tags/integration/index.html +++ b/tags/integration/index.html @@ -1,3 +1,3 @@ integration - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-08
    \ No newline at end of file diff --git a/tags/java-deep-copy/index.html b/tags/java-deep-copy/index.html index 8adebac7..f7932115 100644 --- a/tags/java-deep-copy/index.html +++ b/tags/java-deep-copy/index.html @@ -1,3 +1,3 @@ java deep copy - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +08-21
    \ No newline at end of file diff --git a/tags/java/index.html b/tags/java/index.html index cf95bbba..bbca05a2 100644 --- a/tags/java/index.html +++ b/tags/java/index.html @@ -3,4 +3,4 @@ 05-12

    2017

    \ No newline at end of file +01-10
    \ No newline at end of file diff --git a/tags/jenkins/index.html b/tags/jenkins/index.html index 7e651633..cbedc6c0 100644 --- a/tags/jenkins/index.html +++ b/tags/jenkins/index.html @@ -9,4 +9,4 @@ 12-02
    \ No newline at end of file +02-08
    \ No newline at end of file diff --git a/tags/jq/index.html b/tags/jq/index.html index 0c99a78d..a6db2b5e 100644 --- a/tags/jq/index.html +++ b/tags/jq/index.html @@ -1,3 +1,3 @@ jq - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-28
    \ No newline at end of file diff --git a/tags/json/index.html b/tags/json/index.html index 2bc57f63..9f87ceca 100644 --- a/tags/json/index.html +++ b/tags/json/index.html @@ -1,4 +1,4 @@ json - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-07
    \ No newline at end of file diff --git a/tags/jsoup/index.html b/tags/jsoup/index.html index bfd416fb..acf5cde1 100644 --- a/tags/jsoup/index.html +++ b/tags/jsoup/index.html @@ -1,3 +1,3 @@ jsoup - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-21
    \ No newline at end of file diff --git a/tags/jsp/index.html b/tags/jsp/index.html index efceb9eb..ff94d2f9 100644 --- a/tags/jsp/index.html +++ b/tags/jsp/index.html @@ -1,3 +1,3 @@ jsp - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-04
    \ No newline at end of file diff --git a/tags/jupyter/index.html b/tags/jupyter/index.html index 260d114c..049c39ac 100644 --- a/tags/jupyter/index.html +++ b/tags/jupyter/index.html @@ -1,3 +1,3 @@ jupyter - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-09
    \ No newline at end of file diff --git a/tags/kafka/index.html b/tags/kafka/index.html index 5eeb75f4..d79f5dbb 100644 --- a/tags/kafka/index.html +++ b/tags/kafka/index.html @@ -3,4 +3,4 @@ 02-19

    2019

    2018

    2017

    \ No newline at end of file +11-02
    \ No newline at end of file diff --git a/tags/keepalive/index.html b/tags/keepalive/index.html index 6ec94c81..4ac107eb 100644 --- a/tags/keepalive/index.html +++ b/tags/keepalive/index.html @@ -1,3 +1,3 @@ keepAlive - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +08-28
    \ No newline at end of file diff --git a/tags/kibana/index.html b/tags/kibana/index.html index 663ee7eb..b4dc6da6 100644 --- a/tags/kibana/index.html +++ b/tags/kibana/index.html @@ -3,4 +3,4 @@ 02-17

    2019

    2018

    \ No newline at end of file +04-10
    \ No newline at end of file diff --git a/tags/linux/index.html b/tags/linux/index.html index 5c9a83f2..7d127310 100644 --- a/tags/linux/index.html +++ b/tags/linux/index.html @@ -2,4 +2,4 @@
    \ No newline at end of file +02-28
    \ No newline at end of file diff --git a/tags/load-balance/index.html b/tags/load-balance/index.html index b22c6193..8c741b56 100644 --- a/tags/load-balance/index.html +++ b/tags/load-balance/index.html @@ -1,3 +1,3 @@ Load Balance - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +08-04
    \ No newline at end of file diff --git a/tags/log/index.html b/tags/log/index.html index 37839f0e..00f21127 100644 --- a/tags/log/index.html +++ b/tags/log/index.html @@ -1,3 +1,3 @@ log - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +10-04
    \ No newline at end of file diff --git a/tags/logback/index.html b/tags/logback/index.html index 84a52a92..53db3a9c 100644 --- a/tags/logback/index.html +++ b/tags/logback/index.html @@ -1,3 +1,3 @@ logback - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-19
    \ No newline at end of file diff --git a/tags/logging/index.html b/tags/logging/index.html index 2d08ae34..eeb5ad0c 100644 --- a/tags/logging/index.html +++ b/tags/logging/index.html @@ -1,3 +1,3 @@ logging - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-30
    \ No newline at end of file diff --git a/tags/logstash/index.html b/tags/logstash/index.html index fdacdcb6..acdd2250 100644 --- a/tags/logstash/index.html +++ b/tags/logstash/index.html @@ -4,4 +4,4 @@ 02-15

    2019

    2018

    \ No newline at end of file +01-25
    \ No newline at end of file diff --git a/tags/lombok/index.html b/tags/lombok/index.html index c34ee62a..b37dcf16 100644 --- a/tags/lombok/index.html +++ b/tags/lombok/index.html @@ -1,3 +1,3 @@ lombok - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-22
    \ No newline at end of file diff --git a/tags/maven/index.html b/tags/maven/index.html index 1133236e..de98f658 100644 --- a/tags/maven/index.html +++ b/tags/maven/index.html @@ -1,3 +1,3 @@ maven - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-19
    \ No newline at end of file diff --git a/tags/mentoring/index.html b/tags/mentoring/index.html index 7952ad0e..53d50786 100644 --- a/tags/mentoring/index.html +++ b/tags/mentoring/index.html @@ -1,3 +1,3 @@ mentoring - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-01
    \ No newline at end of file diff --git a/tags/mod_deflate/index.html b/tags/mod_deflate/index.html index b36810e4..707779c0 100644 --- a/tags/mod_deflate/index.html +++ b/tags/mod_deflate/index.html @@ -1,3 +1,3 @@ mod_deflate - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-01
    \ No newline at end of file diff --git a/tags/modelattribute/index.html b/tags/modelattribute/index.html index bdc9aa2b..217faa77 100644 --- a/tags/modelattribute/index.html +++ b/tags/modelattribute/index.html @@ -1,3 +1,3 @@ ModelAttribute - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-12
    \ No newline at end of file diff --git a/tags/module/index.html b/tags/module/index.html index 4a7e121a..b2fc74d1 100644 --- a/tags/module/index.html +++ b/tags/module/index.html @@ -1,3 +1,3 @@ module - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-19
    \ No newline at end of file diff --git a/tags/monitoring/index.html b/tags/monitoring/index.html index 7deb96a7..ab761ab8 100644 --- a/tags/monitoring/index.html +++ b/tags/monitoring/index.html @@ -1,4 +1,4 @@ monitoring - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +05-12
    \ No newline at end of file diff --git a/tags/mybatis/index.html b/tags/mybatis/index.html index aca99487..8597151a 100644 --- a/tags/mybatis/index.html +++ b/tags/mybatis/index.html @@ -2,4 +2,4 @@
    \ No newline at end of file +03-23
    \ No newline at end of file diff --git a/tags/mysql/index.html b/tags/mysql/index.html index 41fc6b93..98f308c0 100644 --- a/tags/mysql/index.html +++ b/tags/mysql/index.html @@ -1,3 +1,3 @@ mysql - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-21
    \ No newline at end of file diff --git a/tags/netflix/index.html b/tags/netflix/index.html index 7a4e09e7..bca0ae52 100644 --- a/tags/netflix/index.html +++ b/tags/netflix/index.html @@ -1,3 +1,3 @@ Netflix - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-29
    \ No newline at end of file diff --git a/tags/network/index.html b/tags/network/index.html index 9434f067..bc7e37a0 100644 --- a/tags/network/index.html +++ b/tags/network/index.html @@ -1,3 +1,3 @@ network - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +09-08
    \ No newline at end of file diff --git a/tags/nginx/index.html b/tags/nginx/index.html index ca7a6a4d..1ec0d402 100644 --- a/tags/nginx/index.html +++ b/tags/nginx/index.html @@ -1,4 +1,4 @@ nginx - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-27
    \ No newline at end of file diff --git a/tags/open-source-software/index.html b/tags/open-source-software/index.html index 63211013..e7b78b73 100644 --- a/tags/open-source-software/index.html +++ b/tags/open-source-software/index.html @@ -1,3 +1,3 @@ open source software - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +07-01
    \ No newline at end of file diff --git a/tags/openapi/index.html b/tags/openapi/index.html index 17aaa32c..e10103d3 100644 --- a/tags/openapi/index.html +++ b/tags/openapi/index.html @@ -1,4 +1,4 @@ OpenAPI - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +12-20
    \ No newline at end of file diff --git a/tags/oracle/index.html b/tags/oracle/index.html index 3946fc82..3a59b286 100644 --- a/tags/oracle/index.html +++ b/tags/oracle/index.html @@ -1,4 +1,4 @@ oracle - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-23
    \ No newline at end of file diff --git a/tags/oss/index.html b/tags/oss/index.html index e687fd0c..3abc517a 100644 --- a/tags/oss/index.html +++ b/tags/oss/index.html @@ -1,3 +1,3 @@ oss - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +07-01
    \ No newline at end of file diff --git a/tags/out-of-memory/index.html b/tags/out-of-memory/index.html index bab6f50a..bdd03202 100644 --- a/tags/out-of-memory/index.html +++ b/tags/out-of-memory/index.html @@ -1,3 +1,3 @@ out of memory - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-10
    \ No newline at end of file diff --git a/tags/packetbeat/index.html b/tags/packetbeat/index.html index ba711c25..ff30c39c 100644 --- a/tags/packetbeat/index.html +++ b/tags/packetbeat/index.html @@ -1,3 +1,3 @@ packetbeat - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +09-08
    \ No newline at end of file diff --git a/tags/parallel-precess/index.html b/tags/parallel-precess/index.html index e0c7f1f2..65854f7b 100644 --- a/tags/parallel-precess/index.html +++ b/tags/parallel-precess/index.html @@ -1,3 +1,3 @@ parallel precess - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-02
    \ No newline at end of file diff --git a/tags/performance/index.html b/tags/performance/index.html index e2a88dab..61a5b9e1 100644 --- a/tags/performance/index.html +++ b/tags/performance/index.html @@ -1,3 +1,3 @@ performance - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +05-12
    \ No newline at end of file diff --git a/tags/pipeline/index.html b/tags/pipeline/index.html index d3f8b9e6..5afae130 100644 --- a/tags/pipeline/index.html +++ b/tags/pipeline/index.html @@ -1,3 +1,3 @@ pipeline - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +12-06
    \ No newline at end of file diff --git a/tags/prefork-mpm/index.html b/tags/prefork-mpm/index.html index d010cb73..58298850 100644 --- a/tags/prefork-mpm/index.html +++ b/tags/prefork-mpm/index.html @@ -1,3 +1,3 @@ Prefork MPM - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-27
    \ No newline at end of file diff --git a/tags/prophet/index.html b/tags/prophet/index.html index 90076a32..5ce812d9 100644 --- a/tags/prophet/index.html +++ b/tags/prophet/index.html @@ -1,3 +1,3 @@ prophet - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +05-31
    \ No newline at end of file diff --git a/tags/public-offering-notice/index.html b/tags/public-offering-notice/index.html index e0d3cdf3..abffdcb5 100644 --- a/tags/public-offering-notice/index.html +++ b/tags/public-offering-notice/index.html @@ -2,4 +2,4 @@
    \ No newline at end of file +03-21
    \ No newline at end of file diff --git a/tags/pullrequest/index.html b/tags/pullrequest/index.html index 69fd3008..1560d996 100644 --- a/tags/pullrequest/index.html +++ b/tags/pullrequest/index.html @@ -1,3 +1,3 @@ pullRequest - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +09-07
    \ No newline at end of file diff --git a/tags/putty/index.html b/tags/putty/index.html index c2c7987b..20201de9 100644 --- a/tags/putty/index.html +++ b/tags/putty/index.html @@ -1,3 +1,3 @@ putty - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-14
    \ No newline at end of file diff --git a/tags/pycon/index.html b/tags/pycon/index.html index edee3ce3..bba96d2e 100644 --- a/tags/pycon/index.html +++ b/tags/pycon/index.html @@ -1,3 +1,3 @@ pycon - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +08-28
    \ No newline at end of file diff --git a/tags/python/index.html b/tags/python/index.html index 63046cd0..52568b5b 100644 --- a/tags/python/index.html +++ b/tags/python/index.html @@ -7,4 +7,4 @@ 06-29
    \ No newline at end of file +01-08
    \ No newline at end of file diff --git a/tags/rabbitmq/index.html b/tags/rabbitmq/index.html index c4c6994e..e34a72a3 100644 --- a/tags/rabbitmq/index.html +++ b/tags/rabbitmq/index.html @@ -1,3 +1,3 @@ rabbitMQ - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-02
    \ No newline at end of file diff --git a/tags/redirect/index.html b/tags/redirect/index.html index 700f4f57..e4536f26 100644 --- a/tags/redirect/index.html +++ b/tags/redirect/index.html @@ -1,3 +1,3 @@ redirect - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-10
    \ No newline at end of file diff --git a/tags/redis/index.html b/tags/redis/index.html index d947cdd3..28185186 100644 --- a/tags/redis/index.html +++ b/tags/redis/index.html @@ -1,3 +1,3 @@ redis - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-02
    \ No newline at end of file diff --git a/tags/reqeustparam/index.html b/tags/reqeustparam/index.html index 985eafc5..ecd8bd98 100644 --- a/tags/reqeustparam/index.html +++ b/tags/reqeustparam/index.html @@ -1,3 +1,3 @@ ReqeustParam - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-12
    \ No newline at end of file diff --git a/tags/requestbody/index.html b/tags/requestbody/index.html index 1f082c58..f9a757d3 100644 --- a/tags/requestbody/index.html +++ b/tags/requestbody/index.html @@ -1,3 +1,3 @@ RequestBody - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-12
    \ No newline at end of file diff --git a/tags/restclientexception/index.html b/tags/restclientexception/index.html index 417d9c8b..bdbf3832 100644 --- a/tags/restclientexception/index.html +++ b/tags/restclientexception/index.html @@ -1,3 +1,3 @@ RestClientException - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-17
    \ No newline at end of file diff --git a/tags/resttemplate/index.html b/tags/resttemplate/index.html index 8ca9975d..221dee0b 100644 --- a/tags/resttemplate/index.html +++ b/tags/resttemplate/index.html @@ -1,3 +1,3 @@ RestTemplate - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-17
    \ No newline at end of file diff --git a/tags/resume/index.html b/tags/resume/index.html index 64562309..7dc5018c 100644 --- a/tags/resume/index.html +++ b/tags/resume/index.html @@ -1,3 +1,3 @@ resume - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-31
    \ No newline at end of file diff --git a/tags/retryable/index.html b/tags/retryable/index.html index 13f38404..207ec0ba 100644 --- a/tags/retryable/index.html +++ b/tags/retryable/index.html @@ -1,3 +1,3 @@ retryable - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-22
    \ No newline at end of file diff --git a/tags/review/index.html b/tags/review/index.html index 8fa94c8c..6afaa0b6 100644 --- a/tags/review/index.html +++ b/tags/review/index.html @@ -4,4 +4,4 @@ 07-07

    2018

    2016

    \ No newline at end of file +12-31
    \ No newline at end of file diff --git a/tags/robert-c.-martin/index.html b/tags/robert-c.-martin/index.html index 68e0cb8d..60dc3820 100644 --- a/tags/robert-c.-martin/index.html +++ b/tags/robert-c.-martin/index.html @@ -1,3 +1,3 @@ robert c. martin - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +12-27
    \ No newline at end of file diff --git a/tags/selenium/index.html b/tags/selenium/index.html index fe3986b2..919e7d4f 100644 --- a/tags/selenium/index.html +++ b/tags/selenium/index.html @@ -1,3 +1,3 @@ selenium - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-01
    \ No newline at end of file diff --git a/tags/self-development/index.html b/tags/self-development/index.html index 8e329482..f72a10a3 100644 --- a/tags/self-development/index.html +++ b/tags/self-development/index.html @@ -1,3 +1,3 @@ self-development - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-28
    \ No newline at end of file diff --git a/tags/sonarqube/index.html b/tags/sonarqube/index.html index d917bb09..f894f9f6 100644 --- a/tags/sonarqube/index.html +++ b/tags/sonarqube/index.html @@ -1,3 +1,3 @@ SonarQube - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-08
    \ No newline at end of file diff --git a/tags/spring-boot/index.html b/tags/spring-boot/index.html index b2a662c4..614f4b0d 100644 --- a/tags/spring-boot/index.html +++ b/tags/spring-boot/index.html @@ -6,4 +6,4 @@ 03-08

    2019

    2017

    \ No newline at end of file +02-27
    \ No newline at end of file diff --git "a/tags/spring-command-\352\260\235\354\262\264/index.html" "b/tags/spring-command-\352\260\235\354\262\264/index.html" index 0be2b803..01e56196 100644 --- "a/tags/spring-command-\352\260\235\354\262\264/index.html" +++ "b/tags/spring-command-\352\260\235\354\262\264/index.html" @@ -1,3 +1,3 @@ spring command 객체 - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-12
    \ No newline at end of file diff --git a/tags/spring-rest-docs/index.html b/tags/spring-rest-docs/index.html index 8bca99e9..d74e3e73 100644 --- a/tags/spring-rest-docs/index.html +++ b/tags/spring-rest-docs/index.html @@ -1,4 +1,4 @@ spring-rest-docs - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-08
    \ No newline at end of file diff --git a/tags/spring/index.html b/tags/spring/index.html index 47e1ec0d..1f4982c2 100644 --- a/tags/spring/index.html +++ b/tags/spring/index.html @@ -6,4 +6,4 @@ 01-10

    2017

    \ No newline at end of file +01-07
    \ No newline at end of file diff --git a/tags/structure/index.html b/tags/structure/index.html index 79afe746..4999f97d 100644 --- a/tags/structure/index.html +++ b/tags/structure/index.html @@ -1,3 +1,3 @@ structure - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +01-19
    \ No newline at end of file diff --git a/tags/study/index.html b/tags/study/index.html new file mode 100644 index 00000000..5a455289 --- /dev/null +++ b/tags/study/index.html @@ -0,0 +1,3 @@ +study - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file diff --git a/tags/study/index.xml b/tags/study/index.xml new file mode 100644 index 00000000..b646eb07 --- /dev/null +++ b/tags/study/index.xml @@ -0,0 +1,11 @@ +study - Tag - 👨‍💻꿈꾸는 태태태의 공간https://taetaetae.github.io/tags/study/study - Tag - 👨‍💻꿈꾸는 태태태의 공간Hugo -- gohugo.ioenSun, 07 Jan 2024 00:16:21 +0900그런 개발자로 괜찮은가 - '그룹 스터디' 편https://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/Sun, 07 Jan 2024 00:16:21 +0900Authorhttps://taetaetae.github.io/posts/a-good-developer-in-terms-of-group-study/ + + 다양한 방식으로 스터디를 해왔다. 정말 많은 것을 배웠던 스터디도 있는가 반면에 지나고 보면 시간이 아까울 정도의 스터디도 있었던 것 같다. 직접 만들어 보기도 했고 참여도 해봤던 것 같다. 이런저런 경험들 끝에 작년 중순에 직접 만들었던 스터디 멤버와는 어느덧 반년을 넘어가고 있는데 바쁜 회사 생활을 하면서도 이제까지 지속할 수 있었던 노하우를 공유해 보고자 한다. +그룹 스터디 방식 인원  다 그런 건 아니지만 기존 회사 분들과 스터디를 할 때면 아무래도 원래 알던 사이라 바빠서 준비를 못 해오거나 불참을 하는 경우에 “그럴 수도 있지”, “괜찮아” 하며 관대해졌던 것 같다. 또는 다양한 의견을 듣자며 10명 이상 진행을 했던 것 같다. 그렇다 보니 스터디 진행에 집중도가 떨어질 수밖에 없었고 모였을 때 이야기하던 사람들만 이야기한다든지, 중도 하차하는 경험도 많았다. +블라인드 글에 첨부한 스터디 참여 설문" 블라인드 글에 첨부한 스터디 참여 설문  이번 스터디는 직접 ‘블라인드’라는 익명 커뮤니티를 통해 인원을 모았다. 작년 중순쯤 자바 백엔드 관련된 주제를 스터디 하겠다며 나와 비슷한 연차분들 위주로 모으겠다고 글을 작성했더니 신기하게도 3~40명 되는 분들이나 지원하셨고 그중 오프라인 모임을 고려해서 나 포함 6명 만으로 구성을 하였다.(뭔가 서류 전형 인사담당자가 된 느낌;;) 작은 규모 그리고 새로운 분들과 하게 되니 집중도가 오르는 경험을 할 수 있었고 무엇보다 6명 모두 다른 회사라 각 회사를 대표하는 것 같은 느낌이 들어 스터디 참여에 몰입이나 책임감이 더욱 올랐던 것 같다. 또한 한 주제에 대해 각 회사에서의 경험들을 이야기하다 보니 완전히 다른 시각을 얻을 수 있다는 장점도 있었다. + 별거 아닐 수도 있지만(또는 오해가 될 수도 있지만) 남녀 성비, 그리고 나이대(연차)를 최대한 맞추고 싶었다. 그래야 분위기가 적당히 딱딱하지도, 부드럽지도 않을 것 같았기 때문이다. 지금은 여자 한 분 나머지 남자분들이라 초반에 걱정도 되었지만 생각보다 분위기가 잘 흘러가서 다행이라 생각을 한다. +주제와 목표 배워야 할게 한도 끝도 없는 개발자 세상스터디 목표에 따라 집중해야 할 범위를 좁히자!" 배워야 할게 한도 끝도 없는 개발자 세상 +스터디 목표에 따라 집중해야 할 범위를 좁히자!  처음부터 모니터 받침으로 하기 좋을만한 두꺼운 책은 피했던 것 같다. 가볍게, 스터디원들끼리의 친밀도부터 올려야 한다는 생각으로 너무 딥 다이브 한 기술적인 내용보다는 누구나 한마디 정도 할 수 있을만한 가벼운 책부터 시작했다. 그러면서 최대한 참여도를 올리는데 집중했던 것 같다. + 어디까지나 “공부"를 하기 위한 모임이긴 하지만 이 또한 사람과 사람 사이의 “관계"가 중요하다고 생각했기에 모였을 때 바로 스터디 이야기를 하는 것보다 부드러운 아이스브레이킹을 자주 해왔다. 또한 너무 루즈 해지지 않게 1달~1달 반 정도로 끝날 수 있을만한 주제를 선정했다. 아무래도 한 주제가 2~3달 걸리다 보면 집중도가 떨어지는 경험이 많았기 때문이다. 책 한 권을 다 읽었다는 기간을 짧게 가져가면서 작은 성취의 효과를 최대한 활용하고 있다. 이번 회차가 벌써 네 번째인걸 보면 그래도 나름 잘 선택한 방법이라 생각이 든다. + 한 회차가 끝날 즈음엔 다음 스터디는 무엇을 할 것인지에 대해 이야기를 하고 다수가 동의하는 주제를 선정한다. 또한 매 회차가 끝날 때마다 어쩌면 어색할 수 있는 이야기지만 스터디 참여를 그만 둘지에 대해 의사를 분명히 물어본다. (그런데 신기하게도 지금 스터디 모임은 이런 이야기를 하기도 전에 스터디 하고 싶은 주제를 먼저 말씀해주시는 편이라, 어쩌면 스스로 사람 운이 좋다는 생각도 해본다.) + 그저 하나의 책을 읽기로 끝나는 “책 읽기 모임” 이 아닌 만큼 책을 기반으로 하는 스터디 모임일지라도 목표를 분명하게 잡는다. 여기서 목표는 개인마다 다를 수 있다. 가령 스터디 시간에 나왔던 내용을 각자의 팀에 공유 및 반영을 해본다든지, 스터디 내용에 대해 주도적으로 이야기를 하며 다른 분들의 지식을 훔쳐보겠다든지(?]]> \ No newline at end of file diff --git a/tags/study/page/1/index.html b/tags/study/page/1/index.html new file mode 100644 index 00000000..c0a6d360 --- /dev/null +++ b/tags/study/page/1/index.html @@ -0,0 +1 @@ +https://taetaetae.github.io/tags/study/ \ No newline at end of file diff --git a/tags/swagger-ui/index.html b/tags/swagger-ui/index.html index 308702a5..208ce740 100644 --- a/tags/swagger-ui/index.html +++ b/tags/swagger-ui/index.html @@ -1,4 +1,4 @@ Swagger-ui - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +12-20
    \ No newline at end of file diff --git a/tags/swagger/index.html b/tags/swagger/index.html index f8255c4a..f1b27091 100644 --- a/tags/swagger/index.html +++ b/tags/swagger/index.html @@ -1,4 +1,4 @@ Swagger - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +12-20
    \ No newline at end of file diff --git a/tags/telegram/index.html b/tags/telegram/index.html index 2074ba77..b86ae456 100644 --- a/tags/telegram/index.html +++ b/tags/telegram/index.html @@ -1,3 +1,3 @@ telegram - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-28
    \ No newline at end of file diff --git a/tags/tomcat/index.html b/tags/tomcat/index.html index 748ac583..2a652e6b 100644 --- a/tags/tomcat/index.html +++ b/tags/tomcat/index.html @@ -1,3 +1,3 @@ tomcat - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +08-04
    \ No newline at end of file diff --git a/tags/tranquilpeak/index.html b/tags/tranquilpeak/index.html index e4df74a1..07515dab 100644 --- a/tags/tranquilpeak/index.html +++ b/tags/tranquilpeak/index.html @@ -1,3 +1,3 @@ tranquilpeak - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +08-27
    \ No newline at end of file diff --git a/tags/transaction/index.html b/tags/transaction/index.html index 1fc4b6f6..bf3598c2 100644 --- a/tags/transaction/index.html +++ b/tags/transaction/index.html @@ -1,4 +1,4 @@ Transaction - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +10-08
    \ No newline at end of file diff --git a/tags/uncle-bob/index.html b/tags/uncle-bob/index.html index 7f40a692..d635b09d 100644 --- a/tags/uncle-bob/index.html +++ b/tags/uncle-bob/index.html @@ -1,3 +1,3 @@ uncle bob - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +12-27
    \ No newline at end of file diff --git a/tags/user-agent/index.html b/tags/user-agent/index.html index e6fa4dd8..c8734e67 100644 --- a/tags/user-agent/index.html +++ b/tags/user-agent/index.html @@ -1,3 +1,3 @@ user-agent - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +04-10
    \ No newline at end of file diff --git a/tags/web-server/index.html b/tags/web-server/index.html index bada6355..9af50e31 100644 --- a/tags/web-server/index.html +++ b/tags/web-server/index.html @@ -2,4 +2,4 @@
    \ No newline at end of file +06-27
    \ No newline at end of file diff --git a/tags/webhook/index.html b/tags/webhook/index.html index fd7e0c42..9b24e3c9 100644 --- a/tags/webhook/index.html +++ b/tags/webhook/index.html @@ -1,3 +1,3 @@ Webhook - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +02-08
    \ No newline at end of file diff --git a/tags/worker-mpm/index.html b/tags/worker-mpm/index.html index d8438eee..103fe938 100644 --- a/tags/worker-mpm/index.html +++ b/tags/worker-mpm/index.html @@ -1,3 +1,3 @@ Worker MPM - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +06-27
    \ No newline at end of file diff --git a/tags/write-the-docs/index.html b/tags/write-the-docs/index.html index c38c0b31..c1b01864 100644 --- a/tags/write-the-docs/index.html +++ b/tags/write-the-docs/index.html @@ -1,3 +1,3 @@ write the docs - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-24
    \ No newline at end of file diff --git a/tags/write/index.html b/tags/write/index.html index c14fdd7c..ee52e550 100644 --- a/tags/write/index.html +++ b/tags/write/index.html @@ -1,3 +1,3 @@ write - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +03-24
    \ No newline at end of file diff --git a/tags/writing/index.html b/tags/writing/index.html index 1a45c8dc..205e5818 100644 --- a/tags/writing/index.html +++ b/tags/writing/index.html @@ -1,3 +1,3 @@ writing - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +10-27
    \ No newline at end of file diff --git "a/tags/\352\270\200\353\230\220/index.html" "b/tags/\352\270\200\353\230\220/index.html" index be85d1c0..3e9c0fc9 100644 --- "a/tags/\352\270\200\353\230\220/index.html" +++ "b/tags/\352\270\200\353\230\220/index.html" @@ -1,3 +1,3 @@ 글또 - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +07-07
    \ No newline at end of file diff --git "a/tags/\353\224\224\354\236\220\354\235\270\355\214\250\355\204\264/index.html" "b/tags/\353\224\224\354\236\220\354\235\270\355\214\250\355\204\264/index.html" index 756327d3..38229ff0 100644 --- "a/tags/\353\224\224\354\236\220\354\235\270\355\214\250\355\204\264/index.html" +++ "b/tags/\353\224\224\354\236\220\354\235\270\355\214\250\355\204\264/index.html" @@ -1,3 +1,3 @@ 디자인패턴 - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +10-06
    \ No newline at end of file diff --git "a/tags/\354\213\261\352\270\200\355\206\244/index.html" "b/tags/\354\213\261\352\270\200\355\206\244/index.html" index 0fd1d197..201d2062 100644 --- "a/tags/\354\213\261\352\270\200\355\206\244/index.html" +++ "b/tags/\354\213\261\352\270\200\355\206\244/index.html" @@ -1,3 +1,3 @@ 싱글톤 - Tag - 👨‍💻꿈꾸는 태태태의 공간
    \ No newline at end of file +10-06
    \ No newline at end of file