스토리, 사진, 채용까지.
모두 한 곳에서 탐험하세요

쓱- 둘러보기만 해도 내가 다니는 모습이 상상되는 기업콘텐츠 꿀단지.

스토리

그들의 소통실험

취업 스토리

취업 성공하는 이력서와 자기소개서

...
영업 엘라

전자공학 전공자의 세일즈 매니저 합격 자료

9,980원
...
기획 미쉘

상담 심리학과 졸업생의 MD 합격키트

9,980원
...
마케팅 콜린

국어국문학과 졸업생의 콘텐츠 에디터 합격키트

9,980원
...
운영 스텔라

경영학과 졸업생의 CX/CS 합격 자료

15,980원
테마
스펙쌓기

마감 직전 대외활동

...
마감 O일전 ~ 25.04.26

[KG아이티뱅크] Git-Ops를 활용한 퍼블릭 클라우드 인프라 구축 및 운영 전문가 양성과정 1기

KG아이티뱅크
...
마감 O일전 ~ 25.04.26

[한국산업인력공단] 멕시코 제조업 및 물류업 중간관리직 양성과정

SARAM HR, 한•중남미협회
...
마감 O일전 ~ 25.04.27

✅ 피그마활용 UI/UX 웹디자인&웹퍼블리셔 국비지원 - 하이미디어아카데미 구로점

하이미디어아카데미 구로점
...
마감 O일전 ~ 25.04.27

AI플랫폼 '타이트사주' 콘텐츠 서포터즈 1기 모집

(주)사이버네틱스
스토리

사무실 FLEX

(주) 베이글코드 분위기 어때요?

(주) 베이글코드, 어떤 생각을 할까?

2020. 08. 09. 조회수 399

[베이글코드 인터뷰] DATA팀 명현기 님

Q. 간단한 자기소개 부탁합니다.안녕하세요, 저는 베이글코드 DATA 팀에서 10개월째 근무하고 있는 명현기 입니다.Q. DATA 팀은 무슨 일을 하나요?Data 팀에선 베이글코드 내 Data & AI와 관련된 모든 일을 진행합니다. 크게 Data Engineer 분들이 하는 일과 Data Scientist 분들이 하는 일로 나눠볼 수 있을 것 같아요. Data Engineer는 데이터를 관리하시고, Data Scientist는 데이터를 활용한다고 생각하시면 이해가 빠르실 것 같네요.“Data engineers are the plumbers building a data pipeline, while data scientists are the painters and storytellers, giving meaning to an otherwise static entity.”-David Bianco of Urthecast우선, Data Engineer 분들께서는 구체적으로 저희 앱에서 발생하는 모든 데이터와 Third Party들에서 가져오는 데이터의 파이프라인을 관리하시고, 최근에는 *Amundsen이라는 내부 데이터 탐색 플랫폼이나 내부 데이터 제공 툴들을 개발하시고 계십니다. 아, 그리고 실시간으로 데이터를 볼 수 있는 스트리밍 시스템도 구축하고 있어요.그리고 Data Scientist 분들께서는 이렇게 구축된 데이터가 다양한 의사결정에 활용될 수 있도록 가공하는 업무를 합니다. Production을 진행하시는 분들이나 슬롯 개발자 분들, User Acquisition 하시는 분들이 Data-Driven Decision을 할 수 있게끔 심혈을 기울여 지원해드리고 있습니다.이 밖에도, 최근에는 Growth/Alert/Modeling 쪽에 좀 더 초점을 맞춰 게임 내부 feature 분석이나 다양한 관점에서의 KPI 분석을 시행했고, AI와 관련된 프로젝트도 계획해 준비하고 있습니다.Q. 베이글코드에서 현기 님의 생활을 소개해주세요.Data 팀은 ‘스프린트’라고 하는 시간 단위로 업무를 진행함으로써 일에 대한 몰입과 집중을 돕고 효율성을 최대한으로 높이고 있어요. 그래서 2주의 스프린트 단위로 일과를 설명해 드리는 게 좋을 것 같아요.베이글코드는 시차출퇴근제를 시행하고 있어서 출근 시간을 선택할 수 있는데요, 저는 주로 9시에 출근해요. 출근 후 업무 진행 상황을 정리하고, 10시에 팀원들과 함께 스크럼을 진행하여 전일 진행한 업무와 오늘의 업무 계획을 공유하며 하루를 시작하게 됩니다.스프린트동안 저희 팀 외에 UA, CVS팀들처럼 다른 팀들과도 한 두 번 정도 회의를 하는데, 이 회의에서는 게임 내 유저의 활동들을 감지, 체크하는 analytic event의 설계나 보고 싶은 데이터 요청 등을 받고, 이를 반영하여 매주 진행되는 저희 팀 회의에서 우선순위대로 Sprint Planning을 진행하거나 Sprint Review를 진행합니다. 이런 회의들을 토대로 베이글코드의 성장을 위해 다양한 분석 아이디어를 내고 실제로 분석 또는 모델링을 진행합니다.Data 팀에선 회의가 많은 편인데도 불구하고, 각 회의가 매우 효율적으로 이루어져서 짧은 시간에 의미 있는 결론을 내고 이를 토대로 더욱 능률적으로 업무를 진행하고 있습니다.아, Data 팀 내부에서 스터디도 진행하고 있습니다! 팀에서 스터디를 원하는 분들끼리 격주 수요일마다 Data Science/Engineering의 두 분야로 나누어 책이나 글들을 읽고 있습니다. 현재는 딥러닝 관련 책을 읽고 내용에 대해 토의하고 있습니다. 퇴근하고 책에 나와 있는 코드들을 구현해보며 자기계발도 꾸준히 하고 있답니다.Q. 베이글코드의 “이것을” 자랑하고 싶다!무엇보다도 가장 자랑할 점은 사내 분위기가 정말 좋다는 점입니다. 실수를 해도 이에 대해 따지고 책임을 묻기보다는 시스템적인 보완책을 마련하는 데에 집중합니다. 직원분들 연령대도 대체적으로 낮은 편이라 더더욱 화기애애하고 으쌰으쌰 하는 것 같습니다.이런 분위기가 개인의 성장을 중시하는 회사의 가치와 시너지 효과를 일으키는 것 같습니다. Data 팀의 리더이신 주현 님은 팀원들이 새로운 제안을 제시하면 항상 열린 마음으로 들어주시고 시도해보라고 독려해주십니다. 스스로 새로운 일들을 해나가는 과정에서 중요한 것에 집중하고 최선의 결과물을 낼 수 있도록 적당한 타이밍에 조언을 제시해 주시고, 우선순위 조절이나 외부와의 커뮤니케이션 등을 도와주시면서 항상 많은 케어를 해주십니다. 이 자리를 빌려 정말 감사하다는 말씀을 전하고 싶네요.또한 베이글코드는 직원들의 행복한 회사 생활을 적극적으로 독려해주십니다. 특히 소모임이 활성화되어 가끔 보드게임을 함께 하기도 하고, 한 달에 한 번 정도 축구하는 모임도 있습니다. 최근 코로나 때문에 1월 이후 FC Bagelcode가 활동하지 못하고 있는데, 빨리 다시 모여서 공차고 싶네요. 이전 승준님 인터뷰에서 그랬듯 식대 무제한 지원, 게임비 지원, 각종 장비 지원, 회식비 인당 10만원(코로나 때문에 잠시 stop…) 은 뭐.. 말이 필요한가요? ㅎㅎQ. 지금까지의 근무기간 동안 성장했다고 느꼈나요? 성장했다면 어떤 방면에서 성장했다고 생각하시나요?아직 배울 것이 많은 신입이기 때문에, 지금 베이글코드에서 경험하고 있는 모든 것들이 저의 성장에 거름이 된다고 생각하고 있습니다. 물론 학교에서도 Kaggle같은 커뮤니티를 통해 데이터를 접하고 있었지만, 입사 후 베이글코드에 구축되어 있는 빅데이터를 접하고 다루는 것이 정말 값진 경험이 되었다고 생각합니다. 베이글코드에서 실제 데이터들을 이해하고 다루면서 학교에서 배웠던 것들을 실제로 적용해보면서 자연스럽게 데이터를 바라보는 관점이 달라지기도 했구요.Q. 마지막으로 한마디 해주신다면?이 인터뷰를 많은 분이 보실 텐데, 여러분들과 함께 베이글코드에서 글로벌하게 성장해나가고 싶네요. 제가 많은 경험을 통해 성장하고 배운 것처럼 베이글코드에 오시는 모든 분이 의미있는 시간을 보내실 거라 생각해요 :)부족한 인터뷰 끝까지 봐주셔서 감사합니다~
2020. 08. 09. 조회수 622

[베이글코드 인터뷰] 인턴 이승준 님

POSTECH SES(Summer Experience in Society)는 포스텍 학생들을 대상으로 실시하는 인턴십 프로그램이다. 베이글코드는 2019년부터 포스텍 SES 프로그램에 참여해서, 포스텍의 우수한 학생들과 함께 인턴 활동을 진행하고 있다. 어느덧 3개월간의 인턴쉽은 끝을 향해 달려가고 개강이 목전으로 다가온 8월 하순, 베이글코드 데이터팀에서 인턴을 하고 있는 이승준 님을 만났다.Q. 간단한 자기소개 부탁합니다.안녕하세요? 현재 베이글코드에서 3개월 동안 데이터 엔지니어로 일한 이승준입니다. 포스텍에서 컴퓨터공학을 전공하고 있고, 현재 3학년 1학기까지 마친 상태입니다.Q. 베이글코드 인턴을 지원하게 된 계기는 무엇인가요?SES라는 학교 프로그램을 통해 베이글코드 인턴으로 참여하게 되었습니다. SES는 학교에서 기업들과의 교류를 통해 학생들에게 인턴십 경험을 제공하는 프로그램인데, 대학교에 입학할 때부터 이 프로그램에 참가하고 싶었고, 이번 여름에 기회가 생겨 참가하게 되었습니다. SES 프로그램에 참가한 여러 기업들 중에서 인턴 기간 동안 실제 제품 개발에 기여를 할 수 있는 스타트업에 가고 싶었고, 특히나 제가 하고 싶었던 일이 데이터 관련 직무였기에 선택한 곳이 베이글코드입니다. 실제로 들어와서 일해 보니, 기대했던 것처럼 실제 제품에 적용되는 실무 경험을 해 볼 수 있었고, 제 능력을 십분 발휘할 수 있었습니다.Q. 그러면 인턴 기간 동안에는 무슨 일을 했나요?데이터 엔지니어링과 데이터 분석 업무를 함께 진행했습니다. 데이터 엔지니어링은 데이터를 모으고, 모인 데이터를 사용하기 쉽게 저장하고, 저장된 데이터를 보기 좋게 가공하는 업무를 하는 직군입니다. 기본적인 데이터 인프라가 이미 구성이 되어있어서, 데이터 파이프라인 위에서 ETL(Extract-Transform-Load) 프로세스를 만들거나 개선하는 일, 써드파티(Third-party) 데이터를 API를 통해 가지고 와서 저장 및 가공하는 업무를 주로 수행했습니다.데이터 분석 업무는 태블로라는 시각화 툴을 이용해 진행했는데, 유저 모니터링 관련 대시보드를 만들고 매일 업데이트 되도록 자동화하는 일을 했습니다.인턴 마지막 기간 동안에는 게임 추천 관련 업무를 진행하고 있는데, 남은 인턴 기간 내에 성과를 내기는 시간이 부족할 것 같습니다. 추천 시스템은 긴 시간을 가지고 작업해야 하는 주제라, 이런 주제가 있으니 경험해보고 가라는 배려인 것 같습니다.Q. 인턴 기간 동안 성장했다고 느꼈나요? 성장 했다면 어떤 방면에서 성장했다고 생각하시나요?인턴 기간 동안 현업에서 실제로 일을 하는 경험을 한 것이 가장 좋았습니다. 학교에서 혼자 코딩할 때와는 다르게 다른 팀 멤버들과 협업을 해야 했기 때문에, 코딩 컨벤션이나 성능 관련 부분에 대해서 더 많이 고민하고 코딩을 해야 했습니다. 학교에서는 돌아가는 코드만 짜도 문제가 없지만, 현업에서는 단순히 동작하는 코드를 작성하는 것 이상으로 시스템을 구성하고 있는 여러 가지 요소들을 고려해야 한다는 점을 느낄 수 있었습니다. 또한 베이글코드가 가지고 있는 방대한 데이터를 활용해 본 경험과 현업에서 사용하는 테크 스택들을 빠르게 습득해 볼 수 있는 기회가 되었다는 점도 정말 좋았습니다. 마지막으로, 인턴 기간 동안 어떻게 문제를 해결하는지 그 방법을 알게 되어 이제는 어디를 가더라도 한 사람 몫을 해낼 수 있다는 자신감이 생겼습니다. 커뮤니케이션 스킬도 늘게 된 것 같습니다.Q. 인턴십 프로그램이 이후 학교생활에 도움이 될 것 같나요?학교에 Software Design이라는 과목이 있는데, 8명이 한 팀을 이루어 프로젝트를 하는 것으로 악명이 높습니다. 인턴십 기간 동안의 경험을 통해 이제는 그 과목에서 리더가 된다고 해도 잘 해낼 수 있을 것 같다는 자신감이 생겼습니다.Q. 인턴 기간 동안 다닌 베이글코드라는 회사에 대해서 평가를 해보자면?인턴 기간 급여도 되게 만족스러웠고, 아침과 점심을 회사에서 제공해주는 것이 정말 좋았습니다. 식비가 제한이 없는데, 회사에 다니면서 그 점이 제일 좋았던 것 같습니다. 그리고 팀원분들이 전부 실력이 뛰어나신 분들이라 좋았습니다. 잘하는 동료들 곁에 있으니 처음 1~2주는 힘들었지만, 곁에 있으면서 배울 점이 많았고, 질문도 잘 받아주셨습니다. 팀원들처럼 되고 싶은 마음에 동기부여가 되어서 열심히 일을 할 수 있었던 것 같습니다.인턴 들어오기 전부터 데이터 관련 업무에서 최대한 넓은 범위의 일들을 하고 싶다고 말씀드렸었는데, 실제로 일을 분배할 때 데이터 관련 업무의 처음부터 끝까지 할 수 있도록 배려해주셨습니다. 특히나 실제 프로덕트의 데이터를 만져볼 수 있다는 점이 정말 좋았습니다. 인턴임에도 하고 싶은 것을 많이 할 수 있어서 매우 좋은 경험이었습니다.인턴 하기에 정말 좋은 회사인 것 같고, 기회가 된다면 다시 돌아오고 싶습니다.Q. 인턴 기간이 끝나고 다시 학교로 돌아가게 되는데, 앞으로의 계획을 말씀해주실 수 있나요?일단 학교로 돌아가서 수학과 복수전공을 하고 싶고, 그리고 분야는 정하지 못했지만, 석사까지 해보고 싶습니다. 예전부터 창업해보고 싶다는 막연한 생각이 있었는데, 베이글코드에 오고 나니까 “이런 회사를 창업해보는 것도 좋겠다”라는 생각을 했습니다. 게임 회사를 창업한다는 것의 매력을 느꼈습니다.Q. 어떤 점에서 매력을 느끼신 건가요?전 게임을 많이 해본 것은 아니지만, 게임은 사람들의 마음을 움직이는 세상의 축소판이라고 생각합니다. “콜 오브 듀티”를 하면 자신이 영화의 주인공이 될 수 있는 경험을 할 수 있고, “마운트 앤 블레이드”를 하면서 중세시대 기사가 되는 경험을 할 수 있는데, 이러한 경험을 제공하는 것이 게임이 줄 수 있는 가치 중 하나라고 생각합니다. 베이글코드에서 하는 소셜카지노라는 장르도, 라스베가스에 자주 가지 못하는 어르신들에게 모바일에서 라스베가스를 경험할 수 있게 하는 점이 되게 매력적이었습니다.Q. 생각이 정말 깊으신 것 같네요. 그런데 창업을 염두에 두고 계시면서 석사까지 하려는 이유는 무엇인가요?저는 수학을 정말 좋아하는데, 수학과 컴퓨터를 이용해서 무언가 새로운 것을 만들어보려면 석사까지는 공부해야 한다고 생각했습니다. 그런데 베이글코드에서 뛰어나신 분들을 많이 보니 꼭 학위가 필요한 건 아닐지도 모르겠다는 생각이 들기도 합니다.Q. 인턴십이나 베이글코드 관련해서 더 하고 싶은 말이 있다면?부서가 아예 다르다 보니 인턴십 기간 동안 기획 관련 업무를 해보지 못한 점이 조금 아쉽습니다. 그리고 밥을 잘 주는 게 제일 좋았습니다. 다른 팀은 모르겠지만, 베이글코드 데이터 팀에 오고 싶은 사람이 있다면 절대 주저할 이유가 없다고 생각합니다. 인턴 기간 동안 많은 도움을 준 데이터 팀 팀원들에게 다시 감사의 인사를 드립니다.
스펙쌓기

마감 직전 공모전

...
마감 O일전 ~ 25.04.27

2025 달서 전국 청소년 끼·흥 경연대회 참가자 모집

대구광역시 달서구 / 달서구청소년수련관
...
마감 O일전 ~ 25.04.27

더 안전한 김해, 교통안전 아이디어 공모전

김해서부경찰서
...
마감 O일전 ~ 25.04.27

제34회 부산진구 초중고생 그림그리기 및 문학백일장 대회

부산진구
...
마감 O일전 ~ 25.04.27

제30회 대덕백일장

대덕문화원

오늘의 스택 Slack 팔로우

직군에서 많이 쓰는 툴입니다. 직군 설정하기

Slack 쓰는 팀

Slack 활용기

2019. 05. 09. 조회수 3188

Node 서버로 Slack 메신저 자동화하기

Overview백엔드 업무를 하면 데이터 요청과 CS문의를 자주 받습니다. 날짜만 다를 뿐 같은 유형의 문의가 대부분이죠. 결국 반복적인 업무를 효율적으로 처리할 수 있는 방법을 고민했고, 사내 메신저로 사용하는 Slack의 몇 가지 API를 사용하기로 했습니다.1. 알림봇 만들기비즈니스 로직을 만들다 보면 정해진 시간에 맞춰 작업을 해야 하는 경우가 발생합니다. Slack 메신저에 로그온한 상태에서 스케줄러를 이용해 지정한 시간에 Slack 메세지를 전송해보겠습니다.1)Slack API 유저토큰 받기Slack API에 사용할 해당 계정의 토큰을 받아야 합니다. Slack 가입 절차 및 채널 생성은 생략하겠습니다.https://api.slack.com/custom-integrations/legacy-tokens 접속합니다.Legacy tokens 메뉴에서 아래로 스크롤을 내려 토큰 생성버튼을 누릅니다.계정 패스워드를 입력하여 확인하면 토큰을 생성할 수 있습니다.생성된 토큰을 복사하여 저장합니다.2)Node.js를 이용한 알림봇 구현2-1.Node.js 설치Node.js 다운로드 해당 사이트에서 운영체제 환경에 맞는 파일을 다운받아 설치2-2.프로젝트 생성해당 프로젝트 폴더로 이동 후 명령어 실행$ npm init --yes // package.json 파일 생성2-3.Slack 연동2-3-1. slack-node 모듈 설치$ npm install slack-node --save2-3-2. 유저토큰을 이용하여 해당채널에 메세지 전송const Slack = require('slack-node'); // 슬랙 모듈 사용 apiToken = "발급받은 유저토큰"; const slack = new Slack(apiToken); const send = async(message) => { slack.api('chat.postMessage', { username: 'dev-test', // 슬랙에 표시될 봇이름 text:message, channel:'#general' // 전송될 채널 및 유저 }, function(err, response){ console.log(response); }); } send('메세지 내용'); 지정한 채널에 메시지가 발송됩니다. 하지만 이와 같은 방법은 유저 토큰이 공개 코드에 노출되기 때문에 보안이 취약할 수 있습니다. 유저 토큰이 필요 없어도 해당 채널에 URL을 생성하는 WebHooks API를 이용하여 메시지를 전송해보겠습니다.3) Incoming WebHooks APIWebHooks는 유저 토큰 대신 Webhook URL을 생성해 HTTP 통신으로 Slack 메세지를 전송할 수 있습니다. 다양한 메시지 형식을 지원하고 게시할 사용자 이름 및 아이콘 등을 통합적으로 관리할 수 있는 장점을 가지고 있습니다.3-2. Webhook URL 생성하기Slack 해당채널에서 Add an app 클릭검색필터에 WebHooks 검색Incoming WebHooks 추가채널 선택 후 Incoming WebHooks 생성생성된 Webhook URL 복사하여 저장해당채널에 생성되었는지 확인봇이름 및 아이콘등 기본 설정 변경하여 저장curl 사용 예제$ curl -s -d "payload={'text':'메세지 내용'}" "Webhook URL"Webhook URL 사용 중인 모든 메시지는 통합적으로 기본 설정이 변경된 걸 확인할 수 있습니다.다양한 형식의 메세지를 전송해보겠습니다.const Slack = require('slack-node'); // 슬랙 모듈 사용 const webhookUri = "Webhook URL"; // Webhook URL const slack = new Slack(); slack.setWebhook(webhookUri); const send = async(message) => { slack.webhook({ text:"인터넷 검색 포털 사이트", attachments:[ { fallback:"링크주소: ", pretext:"링크주소: ", color:"#00FFFF", fields:[ { title:"알림", value:"해당링크를 클릭하여 검색해 보세요.", short:false } ] } ] }, function(err, response){ console.log(response); }); } 다양한 형태의 메시지를 전송할 수 있습니다.4) Schedule 연동이제 스케줄러를 이용하여 지정한 시간에 메세지를 전송해보겠습니다.4-1. node-schedule 모듈 설치node-schedule는 Node.js 작업 스케줄러 라이브러리입니다.$ npm install node-schedule --savenode-schedule 코드 작성const schedule = require('node-schedule'); // 스케줄러 모듈 사용 // rule-style 사용 var rule = new schedule.RecurrenceRule(); rule.dayOfWeek = new schedule.Range(3,4); rule.hour = 19; rule.minute = 50; schedule.scheduleJob(rule, function(){ console.log('rule 방식'); }); // cron-style 사용 schedule.scheduleJob('50 19 * * *', function(){ console.log('cron-style 방식'); }); 취향에 맞는 스타일로 사용하면 됩니다.5) 지정 시간에 메세지를 전송하는 알림봇을 작성해보겠습니다.const Slack = require('slack-node'); // 슬랙 모듈 사용 const schedule = require('node-schedule'); // 스케줄러 모듈 사용 const webhookUri = "Webhook URL"; // Webhook URL const slack = new Slack(); slack.setWebhook(webhookUri); const send = async(message) => { slack.webhook({ text:message, attachments:[ { fallback:"구글드라이브: ", pretext:"구글드라이브: ", color:"#00FFFF", fields:[ { title:"[알림]", value:"해당링크로 접속하여 작성해 주세요.", short:false } ] } ] }, function(err, response){ console.log(response); }); } schedule.scheduleJob('5 19 * * *', function(){ send('업무보고 보내셨나요?'); }); 업무보고 시간을 미리 알려주는 알림봇2. 대화봇 만들기업무 문서는 주로 구글 독스와 같은 온라인 문서로 관리하고 있습니다. 하지만 매번 구글 드라이브에서 문서를 찾는 건 정말 귀찮은 일입니다. 번거로운 건 딱 질색입니다. Slack API를 이용해 관련된 키워드를 입력하면 링크 주소를 바로 받을 수 있는 대화봇을 만들어 보겠습니다.1) Slack API Bots 토큰 받기Slack API에 사용될 Bots 토큰을 받아야 합니다.https://{App Name}.slack.com/apps 에 접속합니다.Bots 추가Bots Api 토큰을 복사해 저장합니다.설정한 봇이름으로 Apps 영역에 자동으로 추가됩니다.2) 구글독스 대화봇 코드 작성2-1. botkit 모듈 설치$ npm install botkit --save2-2. 코드 작성const botkit = require('botkit'); // 봇 모듈 사용 const Slack = require('slack-node'); // 슬랙 모듈 사용 const controller = botkit.slackbot({ debug: false, log: true }); const botScope = [ 'direct_message', 'direct_mention', 'mention' ]; controller.hears(['업무보고'], botScope, (bot, message) => { bot.reply(message, '업무보고 링크주소'); }); controller.hears(['가이드', 'guide', '튜토리얼'], botScope, (bot, message) => { bot.reply(message, '가이드 링크주소'); }); controller.hears(['api', '명세서'], botScope, (bot, message) => { bot.reply(message, 'api명세서 링크주소'); }); controller.hears(['일정', '일정관리'], botScope, (bot, message) => { bot.reply(message, '일정관리 링크주소'); }); controller.hears(['비품', '비품정리'], botScope, (bot, message) => { bot.reply(message, '비품관리 링크주소'); }); controller.spawn({ token: '발급받은 봇 토큰' }).startRTM(); 지정한 키워드를 입력하면 해당 링크가 수신 됩니다.3) 데이터문의 대화봇 코드 작성데이터 요청 시 결과 데이터를 보내주는 대화봇을 만들어 보겠습니다. 일단 먼저 데이터문의 전용 Bots을 생성합니다.3-1. Python 연동 요청한 데이터는 Mysql 데이터를 조회해서 전송합니다. 그러면 Mysql 을 연동해야겠죠? Node.js에서도 직접 mysql 연결할 수 있지만, 기존 프로젝트가 Python으로 구현되어 있어 Python을 실행해 필요한 데이터를 추출해보겠습니다.3-2. python-shell 모듈 설치Node.js에서 Python 실행가능하도록 모듈을 설치$ npm install python-shell --save3-3. Mysql Sample Table3-4. 회원테이블에 저장된 가입일시 기준으로 몇일전에 가입한 회원을 추출하여 전송하는 코드 작성해 보겠습니다.const botkit = require('botkit'); // 봇 모듈 사용 const Slack = require('slack-node'); // 슬랙 모듈 사용 const ps = require('python-shell'); // 파이썬 쉘 모듈 사용 // 몇일 전 날짜 구하기 function getDaysAgo(dayNo = 0) { let nowDate = new Date(); let tempDate = nowDate.getTime() - (dayNo * 24 * 60 * 60 * 1000); nowDate.setTime(tempDate); let getYear = nowDate.getFullYear(); let getMonth = nowDate.getMonth() + 1; let getDay = nowDate.getDate(); if (getMonth < 10 xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed> 3-5. Python 코드 작성 # -*- coding: utf-8 -*- import sys import pymysql // mysql 접속 db = pymysql.connect('hostname', user='', passwd='', db='', charset='utf8') cursor_db = db.cursor() exe_query = "SELECT MEMBER_NAME FROM MEMBER_INFO WHERE MEMBER_REGIST_DETE >= '{}' ORDER BY MEMBER_NO ASC ".format(sys.argv[1]) cursor_db.execute(exe_query) all_rows = cursor_db.fetchall() for idx, row in enumerate(all_rows): print(row[0])     지정한 며칠 전에 가입한 회원 이름이 전송됩니다.   로그도 정상적으로 출력됩니다. 3. Node.js 프로세스 관리를 위한 pm2 모듈 설치 Node.js 는 비동기 I/O를 지원하며 단일 스레드로 동작하는 서버입니다. 비동기식 방식이지만 처리하는 Event Loop는 단일 스레드로 이루어져 있어 처리 작업이 오래 걸리면 전체 서버에 영향을 줍니다. 그래서 pm2를 이용해 프로세스별로 상태를 관리해야 합니다. 1) pm2 모듈 설치$ npm install pm2 -g2) 자주사용하는 pm2 명령어 pm2 list -> 실행중인 프로세스 확인pm2 start {node 파일} -> 시작pm2 stop {id or App name} -> 중지pm2 delete {id or App name} -> 삭제pm2 show {id or App name} -> 상세정보pm2 restart {id or App name} -> 재시작pm2 kill -> pm2 종료pm2 logs {id} -> id 앱의 로그 확인 3) pm2 실행화면$ pm2 start bot.js   프로세스별로 앱 이름, 버전, 상태, cpu 및 memory 사용량이 표시됩니다.$ pm2 show 0   해당 프로세스의 상세 정보를 확인할 수 있습니다. Conclusion 지금까지 Node.js 로 유용한 Slack 메신져 API를 알아봤습니다. 반복적인 업무를 하나씩 줄이다 보면 분명 일의 능률을 높아집니다. 하지만 무분별한 자동화는 서버의 부하를 증가시키기 때문에 꼭 필요한지 확인하고 선택하길 바랍니다. 오늘은 여기까지 글곽정섭 과장 | R&D 개발1팀kwakjs@brandi.co.kr브랜디, 오직 예쁜 옷만  
2019. 01. 31. 조회수 3574

리디북스 서비스 장애 복구 후기

지난 8월 26일에는 약 21분간 리디북스 서비스 전체가 중단되는 장애가 있었습니다.사실 서버 스택 일부에만 영향을 주는 장애는 눈에 잘 띄지 않지만 꽤 흔하게 발생하는 일입니다. 기기 1대당 외부적인 요인으로 인한 장애가 평균 2년에 1번 발생한다고 가정하면, 서버가 100대 있을 때는 대략 1주일에 1번꼴로 장애가 발생하는 셈입니다.이런 형태의 장애는 서버 스택의 한 곳에서만 발생하므로, 이중화 혹은 클러스터링을 통해서 극복하곤 합니다. 또한 원인이 명확하므로 해당 기술에 대한 이해도가 높다면 비교적 빠른 시간 내에 복구가 가능합니다.그러나 이번에 리디북스가 경험한 장애는 달랐습니다. 현재 리디북스는 2개의 데이터센터와 클라우드에 인프라가 분산되어 있는데, 이 중에서 1차 데이터센터의 전원 공급에 문제가 생겨 특정 서버 랙에 있는 서버 17대가 동시에 내려간 것입니다. 즉, 소프트웨어나 머신의 물리적인 장애가 아닌, 데이터센터의 장애였습니다. AWS로 비유를 하자면 가용 영역(Availability Zone)의 장애라고 할 수 있겠습니다.원인에 대해이번 장애의 근본적인 원인은 데이터센터가 전원을 정상적으로 공급해주지 못한 것입니다. 물론 데이터센터 혹은 클라우드 서비스(IaaS)는 고객사에게 전원과 네트워크를 안정적으로 제공해주어야 하는 의무가 있습니다.하지만 이들 역시 천재지변이나 사람의 실수에 대한 대비가 100% 완벽할 수는 없습니다. 따라서 이러한 점을 사전에 고려하고 인프라를 설계하지 못한 것이 2차적인 원인입니다.이번 계기를 통해 데이터센터 이중화를 계획하게 되었고, 사용 중인 클라우드 역시 지역(Region) 전체에 장애가 생길 경우에 대한 대비가 되어있지 않아, 이번 계기로 복제 계획(Geo-Replication)을 세우게 되었습니다.구체적인 상황당시 전원이 차단되어 강제 종료된 서버들은 아래와 같습니다.데이터베이스 프록시 x 2메인 리버스 프록시 x 1읽기 분산용 MySQL 슬레이브 x 1서점용 웹 서버 x 3추천 알고리즘 API 서버 x 1알림센터 API 서버 x 2메인 스토리지 서버 x 2출판 플랫폼용 데이터베이스 x 2테스트 및 배치 작업용 서버 x 3그림으로 표현해 보자면, 대략 아래와 같은 상황에서… 아래와 같은 상황이 된 셈입니다.서버 스택의 여러곳에 순간적으로 장애가 발생한 상황공인 IP가 할당된 메인 프록시 서버 중 1대가 내려갔지만, 실제로는 아래와 같이 가상 IP로 구성을 한 상태였기 때문에 대기 중인(stand-by) 프록시가 동작하여 곧 서점에 장애 공지를 띄울 수 있었습니다.[이미지 출처: DigitalOcean™]공지 이후의 움직임우리는 데이터센터의 복구 시점을 명확히 알 수 없어서 신규 구축(provisioning)을 시작함과 동시에, 서버들의 물리적인 위치 이동을 고려하고 있었습니다. 그러나 다행히 10분이 지난 시점에서 전원 문제는 해결되었고, 서버들은 순차적으로 부팅이 완료되었습니다.일부 서버들은 부팅 과정에서 예상치 못한 지연이 발생하기도 하였지만, 모든 서버의 부팅이 완료된 이후에도 서비스는 완전히 정상으로 돌아오지 않았습니다. 당시 우리가 겪었던 문제와 해결책은 아래와 같습니다.A. 읽기 분산용 MariaDB 슬레이브의 복제 지연(replication lag) 문제슬레이브 서버의 부팅이 완료되자 데이터베이스 프록시(HAProxy)는 해당 서버를 정상으로 간주하여 라우팅 대상에 포함하게 되었고, 애플리케이션 서버들은 정상적으로 커넥션을 맺기 시작하였습니다. 하지만 해당 슬레이브는 수십 분간 마스터를 따라잡지 못한 상태였기 때문에 최신 데이터가 보여지지 않는 문제(stale data)가 있었습니다. 우리는 즉시 해당 슬레이브를 제거하였고 지연이 사라진 이후에 다시 서비스에 투입하였습니다.B. 읽기 분산용 슬레이브의 웜업(warm-up) 문제복제 지연은 사라졌지만 서버의 CPU 사용량이 크게 높은 상태가 한동안 유지되었고, 응답속도는 정상적인 슬레이브에 비해서 많이 느렸습니다. 왜냐하면 캐시가 비워진 상태에서 바로 서비스에 투입되어, 캐시 미스가 휘몰아치는 현상(cache stampede)이 발생하였기 때문입니다. 따라서 간단한 쿼리도 평소보다 오래 걸렸고, 그대로 둔다면 커넥션풀이 꽉 차는 현상이 발생할 것으로 예상되었습니다.곧 우리는 HAProxy로 해당 서버의 가중치를 10%로 낮추어 인입되는 쿼리의 양을 조절하였으며 응답속도는 정상 수치로 돌아오게 되었습니다. 이후 스크립트를 작성하여 수동으로 캐시를 채워나감과 동시에 점차 가중치를 높여 처리량을 정상화하였습니다.프로덕션에서 사용하는 서버는 innodb_buffer_pool 이 100G 이상으로 매우 크게 설정되어 있으며, 재시작 시 캐시가 날아가는 현상을 해결하기 위해 innodb_blocking_buffer_pool_restore 옵션을 적용하고 있습니다. 하지만 지금처럼 메모리를 덤프하지 못하고 비정상 종료가 된 상황에서는 해당되지 않았습니다.C. 인메모리 데이터의 보존 문제알림센터는 다양한 프로모션과 개인화된 정보를 전달해주는 공간입니다. 알림센터의 특징은 데이터의 영구 보존(persistency)이 필요하지 않고, 매일 수백만 건의 개인화된 메시지가 기록된다는 것입니다. 이러한 특징은 인-메모리 데이터베이스에 적합하므로 우리는 Redis를 마스터/슬레이브로 구성하여 저장소로 사용하고 있었습니다.어떠한 이유로든 Redis를 재시작해야 할 경우가 생기면, 메모리 상의 데이터가 날아가는 것을 방지하기 위해 주기적으로 스냅샷을 남기고 있습니다만, 이번에는 로그가 마지막까지 기록되지 못한 상태에서 메모리의 데이터가 날아가 버렸습니다.다행히 알림 발송과 관련된 메타정보는 모두 MariaDB에 기록하고 있으므로, 우리는 이를 기반으로 소실된 시점부터의 알림을 순차적으로 재발송할 수 있었습니다. 물론 모든 알림이 신규 상태로 간주되어 아이콘이 잘못 노출되는 문제가 있었지만, 고객님들은 너그럽게 이해해 주신 것 같습니다. 😅그래서 앞으로는?리디북스 DevOps 멤버들은 이번 데이터센터 장애를 통해 현재 인프라의 한계점을 실감하였고, 앞으로의 개선 방향에 대해 고민하게 되었습니다.몇 가지를 정리하면 다음과 같습니다.랙 단위로 장애가 발생할 수 있음을 인지하고 대비하자.같은 기능을 하는 서버를 하나의 랙이나 같은 가용 영역에 두지 말자.2차 데이터센터는 더 이상 옵션이 아닌 필수다.낙뢰나 지진으로 인해 데이터센터에 문제가 생길 수도 있다.긴급하게 프로비저닝이 필요한 상황에 대비하자.문서화가 되어 있더라도 경험이 없다면 동일한 구성에 많은 시간이 소요된다.모든 구성요소들에 대한 Ansible 스크립트를 작성하여두자.캐시 웜업 스크립트도 작성하여 두자.백엔드 구성요소들 간의 불필요한 의존 관계를 끊자.단 한 줄의 코드라도 참조하고 있다면 이는 독립적인 것이 아니다.언제나 서비스 지향적인 설계를 추구하자.Uptime을 관리하자.최대 180일을 기점으로 무조건 리부팅을 하자.재시작 과정에서 다양한 문제와 개선점이 발견될 것이다.커널 패치, 보안 패치를 할 수 있는 것은 덤이다.아래와 같은 긍정적인 면도 발견하였습니다.장애 상황이 실시간으로 Slack 채널을 통해 전파되었음진행 상황에 대해 모두가 동일한 수준으로 이해할 수 있었다.모니터링 연동(integration) 기능 때문에라도, Slack은 유료로 구매할만한 값어치가 충분하다.같은 기능을 하는 서버들이 다른 랙에 많이 분산되어 있었다.인프라가 확장될 때마다 빈 공간에 필요한 서버를 추가했을 뿐이지만, 자연스럽게 물리적인 위치가 분산되는 효과가 있었다.이 외에도 특정 클러스터를 구성하는 노드들을 분산하여 배치시키자.서버별로 오너쉽이 부여되어 있어서 빠르게 복구가 된 점여러 명의 백엔드 개발자들이 병렬적으로 복구를 진행할 수 있었다.마지막으로넷플릭스의 엔지니어들은 무질서한 원숭이(Chaos Monkey)라는 프로그램을 만들어서 운영한다고 합니다. 이 원숭이는 서비스 인스턴스들을 무작위로 중단시키는 역할을 합니다. 다소 황당하게 들리지만, 넷플릭스에는 일부 서비스에 장애가 발생하더라도 나머지 부분은 문제없이 운영되어야 한다는 원칙이 있으므로, 이를 수시로 시뮬레이션하는 과정을 통해 복구 능력을 높여둔다는 것입니다.실제로 이렇게 급진적인 아이디어를 실천할 수 있는 회사는 매우 드물 것입니다. 하지만, 우리는 이번 계기를 통해 무질서한 원숭이의 필요성을 절감하였고, 이로 인해 서버를 주기적으로 리셋하는 정책을 만들게 되었으며 모든 단일 장애점(SPoF)에 대한 대비를 시작하게 되었습니다.장애를 단순히 피해라고만 생각한다면, 서로를 비난하고 책임을 전가하는 상황이 펼쳐질 것입니다. 하지만 고객의 불편함과 맞바꾼 매우 비싼 경험이라고 생각한다면, 보다 튼튼하고 회복탄력적인 시스템을 갖추기 위해 노력하게 될 것입니다. 그러다 보면 언젠가는 데이터센터 전체에 문제가 생겨도 버틸 수 있는 모습으로 진화할 것이라고 생각합니다.#리디북스 #장애복구 #역경돌파 #개발 #개발후기 #개발자 #서버개발 #서버

기업문화 엿볼 때, 더팀스

로그인

/