스토리 홈

인터뷰

피드

뉴스

조회수 3927

PHP Codeigniter 환경에서 VUE 사용해보기

Overview이번에는 PHP Codeigniter 기반의 서비스에 VUE를 적용시키려고 고민했던 것들을 나누려고 합니다. VUE JS는 가상 DOM을 활용하여 실시간으로 반응 컴포넌트를 제작할 수 있는 프레임워크입니다. 또한, VUE-ROUTER 및 VUEX라는 컴페니언 라이브러리를 통해 url 라우팅 및 전역상태를 관리하기에도 탁월하죠. VUE와 다른 프레임워크와의 비교 부분은 여기를 참고해주세요. 브랜디의 관리자 서비스는 PHP Codeigniter 프레임워크로 제작되었습니다. 하지만 관리자 서비스의 규모가 점점 커지고 기능이 다양해지면서 “자주 사용하는 기능을 묶어 컴포넌트화하자!”라는 숙제가 남아 있었죠. 요즘 잠깐의 여유가 생겨 이때다 싶었습니다. 관리자 서비스에 VUE를 도입하기 위한 시도를 시작했는데요. 얼마 지나지 않아 문제점에 봉착했습니다. 바로 IE9.0…. 개발자의 숙적 IE가 또 한 번 발목을 잡았습니다. 임포트가 되지 않아….VUE를 좀 더 편리하게 사용하려면 JS의 모듈화가 필요했지만, ES2015에서는 import 혹은 require 구문을 지원하지 않아 불편하고, arrow 함수 또한 사용할 수 없습니다. 게다가 VUE의 JAX 탬플릿 구문을 사용할 수도 없었죠!! 뭔가 배보다 배꼽이 더 커질 것 같은 조짐이 보였습니다.결국 Webpack의 도움 없이 VUE를 적용하려던 시도는 여러 가지 난관을 만났고, Codeigniter 프로젝트 내부에서 Webpack을 사용하는 방법을 연구하기 시작했습니다. Webpack은 모듈 번들러입니다. Webpack의 메인 페이지를 방문하면 아래 네 개의 슬로건이 빙글빙글 돕니다.Bundle your scriptsBundle your imagesBundle your stylesBundle your assets아래의 이미지는 Webpack이 무엇을 하는 녀석인지 잘 설명해줍니다.Webpack은 실제로 번들러라고 광고하는것 처럼 Only Webpack 빌드만으로는 소스 파일들을 모아줍니다. 만약 webpack-dev-server로 실행하면 websocket을 통해 소스가 변경됐을 때 실시간으로 화면을 갱신해주는 개발 툴 제공 정도의 역할 밖에 없습니다. (…충분히 훌륭하잖아?)대부분의 기능은 엄청난 확장성을 가진 webpack의 설정으로 모듈로서 작동할 수 있죠. 예를 들면 Babel은 우리의 발목을 잡았던 IE를 위해 ES6로 작성된 js 문법을 IE에서 사용할 수 있는 ES5문법으로 너무나 쉽게 트랜스컴파일할 수 있습니다.하지만… 관리자 서비스는 위에서 언급했듯이 Codeigniter 기반입니다. 따라서 완벽히 VUE와 API서버를 분리하려면 로그인, 메뉴구성, 헤더, 푸터 등 PHP 기반으로 제작된 모든 기능들과 인증 등 기존 방식을 전부 새로 만들어야만 VUE를 온전히 사용할 수 있습니다.문제점들을 모두 해결하고 넘어가기엔 여유가 부족하기 때문에 조금씩 적용하자고 생각했습니다. 덕분에 webpack-dev-server의 실시간 소스 반영 기능을 포기해야만 했죠.(눈물) 우리의 서버는 node기반이 아닌 apache-php 기반이었기 때문입니다.자, 그럼 Codeigniter 프로잭트 하위에 웹팩을 포함시켜 Hello World까지 가는 짧은(?)여정을 시작해봅시다.Hello world로 가는 여정Node, npm 설치맥에서도 유사한 명령어로 제작할 수 있도록 CMD 위주로 진행하겠습니다. 먼저, 여기를 클릭해 Node를 설치합시다. 8.11.3 LTS버전으로 진행했습니다.맥에서는 Homebrew를 통해 간편하게~brew install node 설치 확인npm 잘 설치되었네요.web pack 폴더 생성 및 이동mkdir webpack cd webpack nom init으로 초기화npm init webpack, vue, babel 설치npm install -D webpack webpack-cli webpack-dev-server npm install -D vue-loader vue-template-compiler npm install -D babel-core babel-loader babel-preset-es2015 여기서 VUE는 설치하지 않습니다! 왜냐하면 VUE.js는 로딩만 하면 되고 필요하지 않습니다! (읭?) VUE는 Codeigniter view에서도 사용해야 하기 때문에 해당 view에서 import 해줍니다. 따라서 VUE 컴포넌트가 들어가는 시점에는 이미 전역에 vue.js 가 있습니다. 따라서 굳이 각 모듈마다 VUE를 import 했다가 webpack 설정에서 다시 vue.js를 제외할 필요는 없습니다.VUE와 template 태그를 로딩할 수 있는 로더도 설치하고, 트랜스컴파일을 위한 바벨, IE9를 지원하기 위한 es2015프리셋도 함께 설치합니다.webpack 빌드명령어 package.json의 script부분에 추가"scripts": { "build": "webpack --mode production", "build-dev": "webpack --mode development",   } 이제 VUE를 빌드할 명령어를 작성합니다. 위처럼 두 가지 명령어를 제작해두면, 추후 env를 통해 webpack.config.js를 분기시켜 원하는 환경으로 빌드할 수 있습니다. 또한 production 모드로 빌드할 땐 자동으로 옵티마이저 - uglify 내장 플러그인이 적용되어 익숙한 min.js형태로 빌드되며 development를 빌드할 땐 사람이 알아볼 수 있는 형태로 빌드되고, debugger 코드 또한 살아있습니다.weboack.config.js 작성const { VueLoaderPlugin } = require('vue-loader'); module.exports = {   entry: {     HelloWorld: './src/main.js'   },    module: {     rules: [       {         test: /\.vue$/,         loader: 'vue-loader',       },       {         test: /\.js$/,         loader: 'babel-loader',       }     ]   },    resolve: {     alias: {       'vue$':'vue/dist/vue.esm.js'     }   },    plugins: [     new VueLoaderPlugin()   ]  } webpack.config.js 가 없다면 생성한 후 위와 같이 작성합니다..babelrc 작성{     "presets": ["es2015"] } 테스트용 파일 작성1)main.js 작성import HelloWorld from './HelloWorld.vue' Vue.component('hello-world', HelloWorld); 2)HelloWorld.vue 작성 [removed] export default {   name: 'app',   data: () => {     return {       word1: 'Hello',       word2: 'World'     }   }  } [removed] 테스트 빌드npm run build-dev 빌드를 할 땐 기본적으로 ‘/dist/’ 하위에 소스코드가 떨어집니다. 자, 여기까지 진행하셨다면 폴더 구조는 다음과 같을 것입니다.지금까지 진행한 파일 모습입니다.뷰 컴포넌트가 잘 제작되고 등록되는지 확인하려면 기본 빌드 폴더인 dist 폴더에 Test.html을 작성해 브라우저로 열어봅시다.확인용 html 파일 작성<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>VUE Test</title>     <!-- VUE 플러그인 -->     [removed][removed] </head> <body>                     [removed][removed]     [removed]         new Vue({             el: '#vue'         })     [removed] </body> </html> 잘 나옵니다.정상적으로 VUE가 적용된 것을 확인합니다.코드이그나이터 설치이제 코드이그나이터 프로젝트 내부에서 VUE 컴포넌트를 출력해보기 위해 코드이그나이터 프로젝트를 생성합시다. 먼저 Codeigniter와 XAMPP를 다운로드 받습니다.Codeigniter 받으러 가기XAMPP 받으러 가기프로젝트 폴더 하위에 Codeigniter 프로젝트용 폴더를 생성합니다.mkdir codeigniter-with-vue-webpack cd codeigniter-with-vue-webpack 다운받은 Codeigniter를 해당 폴더에 압축 해제하면 Codeigniter 설치가 끝납니다.XAMPP 설치 및 DocumentRoot 변경XAMPP를 설치하고 DocumentRoot를 테스트 프로젝트 폴더로 설정한 뒤 아파치를 실행합니다.Codeigniter 프로젝트가 생성되었고, 서버 실행이 완료되었습니다. webpack 폴더를 Codeigniter 프로젝트 하위로 이동node-modules는 너무 크기 때문에 기본 파일만 복사하고, npm install로 설치합니다.Codeigniter에서 VUE를 사용하기 위한 webpack dist설정기존의 프로젝트에서 스크립트를 모아두는 폴더 하위로 빌드 결과 파일을 보내기 위하여 webpack 빌드 시 dist 폴더가 아닌 /application/scripts/vue/hello_world 하위로 빌드 결과 파일이 생성되도록 설정합니다.// 기존 module.exports = {   entry: {     HelloWorld: './src/main.js'   },    //... 생략 } // 변경후 module.exports = {   entry: {     '../../application/scripts/vue/hello_world/HelloWorld.js': './src/main.js'   },    //... 생략 } Codeigniter의 load->view 기능을 활용하여 파일 작성1)header.php// application/views/common/header.php <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>VUE Test</title>     <!-- VUE 플러그인 -->     [removed][removed] </head> 2)실제 view// application/views/vue/hello_world/vueTestPage.php <?php $this->load->view( 'common/header' ); ?> <body>                 [removed] [removed]     [removed]         new Vue({             el: '#vue'         })     [removed] </body> <?php $this->load->view( 'common/footer' ); ?> 3)footer.php// application/views/common/footer.php </html> 실제 프로젝트 구성과 유사하게 header, body, footer로 나누어 파일을 작성해봅니다. 실제로는 더 복잡하지만 이 정도만 나누겠습니다.Codeigniter 테스트용 컨트롤러 작성// application/controllers/Vue.php <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');   class Vue extends CI_Controller {      public function index()     {         $this->load->view('vue/vueTestPage');     }  } 정말 심플(?)한 테스트용 파일 작성이 모두 끝났습니다! 이제 잘 작동하는지 확인해볼까요?코드이그나이터에서 helloworld 출력짜잔이번엔 문제의 IE에서 확인해봅시다.IE9.0 환경에서 확인IE에서도 무사히 출력되는군요. 이제 코드이그나이터 환경의 프로젝트에서도 IE까지 지원하며 무사히 VUE를 사용할 수 있게 되었습니다! (시간이 없어서 가상머신에 IE9가 설치된 윈도우7까지 테스트하진 못했습니다!) 모든 작업이 완료한 후, 파일 폴더 구조는 아래와 같습니다.붉은 네모 부분이 실제로 제작하거나 수정한 파일들입니다.Conclusion여기까지가 Codeigniter 프래임워크 환경에서 webpack + vue를 사용하기 위한 웹팩의 설정 과정 및 테스트 결과였습니다. php 서버를 사용해야 하기 때문에 webpack-dev-server의 핫리로드 기능을 사용하지 못하는 건 매우 안타까운 일입니다. 하지만 짧은 시간에 신기술을 도입하면서도 수많은 리스크를 회피할 수 있다는 건 나쁘지 않은 선택이라 생각합니다.위의 웹팩설정을 조금만 활용한다면 다른 프레임워크 프로젝트에서도 무리없이 VUE를 사용할 수 있을 겁니다! 비슷한 고민을 하셨던 개발자님들… 집에 가기 전 말고 오전에 Webpack을 설치해보세요. 안 그러면 저처럼 집에 못갈 수도 있으니까요!참고.gitignore 작성, index.php 제거 등은 내용에 포함하지 않았으며, 아래의 링크로 자세히 알 수 있음.Codeigniter index.php 없애기글강원우 과장 | R&D 개발2팀[email protected]브랜디, 오직 예쁜 옷만 #브랜디 #개발자 #개발팀 #인사이트 #경험공유 #PHP
조회수 2409

하얗게 불태웠다. 트레바리 홈페이지 리라이팅 후기

1월부터 4월까지 한 시즌에 걸쳐 트레바리 홈페이지를 다시 구현하였다. 겉으로 보이는 UI/UX 디자인 개편을 넘어, DB 설계와 서버 및 웹 페이지 개발까지 새롭게 진행했다. 기존의 홈페이지를 완전히 버리고, 새로운 아키텍처를 가진 홈페이지를 구현하여 데이터를 이전하는 일이었다.4개월 동안 반응형 웹 사이트 1개, 크루/파트너 어드민 사이트 2개와 함께 서버까지 구현했다..지난 시즌 동안 홈페이지의 여러 기능들을 개선하면서 변화가 필요하다고 생각했다. 단순히 '남이 짜둔 코드가 별로예요'에서 나온 불편 때문만은 아니었다. 회사가 겪는 빠른 성장에 발맞춰 시스템이 뒷받침이 되어줘야 하는데 기존의 아키텍처로는 그러기가 어려웠다. 적은 트래픽에도 툭하면 죽는 서버 덕에 접속이 몰리는 멤버십 신청 기간 동안에는 서버 비용을 배로 늘려야 했고, 푸시 알림의 필요성으로 모바일 앱을 구현하고 싶어도 별도의 API 서버가 존재하지 않아서 시도하기 힘들었다. 결국 지난 시즌 말, 홈페이지를 새로운 아키텍처에서 다시 구현하겠다는 호기로운 결정을 내렸다.처음 시작할 때만 해도 아주 큰 어려움은 없겠거니 했다. 트레바리 입사 이전에 여러 프로젝트를 턴키로 수주받아 진행했던 경험이 있었기 때문이었다. 그러나 몇천 명, 많게는 몇만 명이 접속하는 운영 중인 서비스를 만들어 이전하는 일은 새 서비스를 만드는 일과는 또 다른 일이었다.게다가 이전 글에서 이야기했던 것처럼 트레바리에는 풀타임으로 일하는 개발자나 디자이너가 나 혼자이기 때문에 해야 하는 일이 절대적으로 많았다. 개발 맨 아랫단부터 웹 페이지의 디자인까지 기간 내에 해내는 것은 쉽지 않은 일이었다. 덕분에 매일이 도전이었던 4개월을 보냈고, 런칭 3주 전쯤에는 잠시 슬럼프를 겪기도 했다. 하지만 트레바리가 한 번은 꼭 겪어야 하는 과제였기에 꾸역꾸역 해내면서 런칭까지 왔다. 오늘은 그 이야기를 정리해보려고 한다.리라이팅왜, 무엇을 했나요?1. 과도한 서버 비용과 느린 속도홈페이지를 다시 만들어야겠다는 생각을 가장 많이 하게 된 이유는 비용과 속도였다. 동시 접속 유저 수가 천 명이 안 되는 서비스에서 월 100만 원가량의 서버 비용이 나왔고, 평균 페이지 로딩 속도가 3초를 넘어갔다.그동안 트레바리 홈페이지는 여러 프리랜서 개발자들이 거쳐가며 유지되느라 DB나 쿼리 구조에 대한 고민을 장기적으로 해볼 기회가 없었다. 요청받은 기능을 구현하기 위해 필요한 테이블을 그때그때 만들고, 활용할 데이터가 다른 테이블에 있다면 조인을 해서 불러왔다. 그 결과 대부분의 데이터 요청에 n+1 쿼리가 존재했고, 한 명의 유저가 한 번의 접속만으로도 수많은 쿼리 요청을 하는 상황이었다.최대한 기존의 홈페이지에서 이를 해결해보려고 노력했다. 처음 입사했을 때만 해도 10초 이상의 시간이 들었던 독서모임의 리스트 요청을 3초까지 줄이고, 접속자 수가 40%가 늘어났어도 서버 비용을 늘리지 않을 수 있었다. 그러나 상대적으로 빨라졌을 뿐 느린 편이라는 점은 변함이 없었다. 매 시즌 멤버 수가 30~40% 씩 증가하는 추세대로라면 다음 시즌에도 비슷한 비용을 유지할 수 있을 거란 보장 또한 없었다.여기서 더 개선하려면 DB 구조를 변경하고, 수많은 코드를 갈아엎어야 했다. 필요하다면 하면 되는 일이었지만 기존의 아키텍처인 레일즈 웹 애플리케이션을 유지한다면 당장의 퍼포먼스를 개선하더라도 언제까지 높은 퍼포먼스를 유지할 수 있을지 의문이었다. 성장에 따라 요구되는 시스템들을 다 지원해줄 수 있을지도 미지수였다. 언젠가 아키텍처를 변경해야 한다면 최대한 빠른 시일인 지금 하는 것이 효율적이라 판단했다.Heroku에서 관리하던 서버를 AWS의 EC2로 변경하면서 DB 또한 PostgresSQL에서 AWS 의 DynamoDB로 이전했다. RubyOnRails를 사용하여 단일 웹 애플리케이션으로 구현했던 홈페이지를 Typescript를 기반으로 프론트엔드와 백엔드를 나눴다. React로 사용하여 웹사이트를 구현하였고, Node.js로 GraphQL을 적용하여 서버를 구현하였다.덕분에 월 100만 원가량이 들던 비용을 월 30만 원까지 낮출 수 있었다. 속도는 이전보다는 빨라졌으나 기대만큼 빨라지지는 않아 캐싱 등을 적용하여 차츰 줄여나가고 있다. 변경한 현재 아키텍처로는 트래픽이 늘어나더라도 이전처럼 비용을 배로 늘리지 않아도 되었으며, 다양한 방법으로 속도를 개선하는 작업도 시도해 볼 수 있게 되었다.2. 기술 부채기술 부채가 쌓인 모습 (...)이미지 출처: 스마트스터디앞서 말했던 것처럼 기존 홈페이지는 여러 프리랜서 개발자들이 거쳐간 터라 뻔하게도 기술 부채가 쌓였다. 홈페이지와 관련된 문서는 없고, 크루들은 사용하는 기능들을 부분적으로만 알고 있었다. 그런 상황에서 몇 명의 크루들이 퇴사와 입사를 거치니 그나마 구전으로라도 유지되던 홈페이지 정보가 점점 사라졌다.홈페이지에 대해 궁금한 점이 생기면 직접 코드를 뒤적이며 파악해보는 수밖에 없었다. 그래서 모든 크루들이 유일한 개발자인 나에게 물어보는 것 말고는 홈페이지에 대해 알 수 있는 다른 방도가 없었다. 이 외에도 새로운 기능을 구현했더니 미처 파악하지 못한 곳에서 버그가 터진다거나, 안 쓰는 줄 알고 삭제한 코드가 사실 어디선가 제기능을 하고 있거나 하는 때도 잦았다.이런 기술 부채를 청산하려면 1) 대부분의 기능들을 파악하고 있는 담당자가 있고 2) 지원하는 기능들을 잘 정리한 문서가 필요했다. 1번은 직접 처음부터 리라이팅을 진행했으니 자연스레 해결되었으나, 다른 크루들도 많은 기능들에 대해 파악하고 있으면 더 효율적일 거라 생각했다. 그래서 새로 구현되는 기능이나 변경 사항에 대해서 매주 주간 회의 때 공유를 하고 있으며, 배포를 할 때마다 실시간으로 에버노트와 슬랙의 배포 노트 채널을 통해 배포 내용을 공유하고 있다. 이전에도 하고 있었으나 더 잘, 자주, 자세히 해야겠다고 새삼 깨달았고 노력 중에 있다.2번을 위해서는 홈페이지 기능 설명에 대한 문서를 작성하기 시작했다. 아직 가장 효율적인 포맷이 무엇인지는 찾지 못해서 방황하고 있지만 최대한 쉽고 자세하게 쓰는 방향으로 진행 중이다.사랑과 따뜻함이 넘치는 우리 크루들 3. 복잡하고 이유 없는 UI기존의 홈페이지는 의외로(?) 다양한 기능들이 있었지만 유저들이 모르거나 사용하지 않는 경우가 많았다. 대부분의 기능들과 인터페이스들이 중요도에 대한 고민 없이 '있으면 좋을 것 같다'는 이유로 덕지덕지 추가되었다. 게시판이나 다이어리 같은 메뉴들은 사용률이 채 5%가 안되지만 상단 메뉴에 자리 잡고 있었고, 북클럽 리스트의 페이지에는 딱 한 번만 읽으면 되는 설명글이 화면의 반을 차지하고 있었다.멤버들이 트레바리에서 가장 활발하게 누려줬으면 좋겠다고 생각하는 활동은 독서모임과 이벤트다. 내 클럽이 아닌 다른 다양한 클럽에도 참여해보고, 살면서 해보지 못한 경험들을 이벤트를 통해 체험해봤으면 좋겠다. 그런 고민으로 상단 메뉴에는 독서모임과 이벤트, 내 활동 정보를 볼 수 있는 마이페이지만 배치하였고 FAQ나 공지사항과 같은 자잘한 것들은 하단의 footer로 내리거나 일부 기능들을 임시적으로 지원하지 않기로 했다.리라이팅 전리라이팅 후직관적인 UI는 파트너 어드민에서도 절실하게 필요했다. 기존의 어드민 UI는 따로 교육이 필요할 정도로 복잡했기 때문이었다. 한 명의 파트너에게 자신이 관리하는 클럽 외의 모든 클럽 정보가 노출되었다. 클럽 정보에서도 봐야 할 정보와 보지 않아도 될 정보가 혼재되어 보이고 있었다. 파트너의 수는 점점 늘어나는데 그때마다 홈페이지까지 교육까지 따로 해야 하는 것은 리소스가 많이 드는 일이었다.파트너가 자신의 모임을 이끌기 위해 정말 필요한 일에만 집중할 수 있도록 신경 써서 구현했다. 모임에 참석하는 멤버 리스트, 모임에서 읽을 책과 발제문 등을 등록하고 수정하는 페이지, 출석 체크를 할 수 있는 기능만으로 구성했다. 항시 봐야 하는 매뉴얼과 FAQ는 따로 메뉴로 빼두었다.파트너 어드민의 모임 정보 설정 페이지 리라이팅 전과 후4. 데이터로 소통하는 회사트레바리는 점점 데이터로 소통하는 회사가 되고 싶다. 어떤 유저가 어디에서 불편을 겪고, 어떤 부분을 좋아하는지 알고 싶다. 사람들이 독서모임에 만족하면 홈페이지에서 어떻게 활동하는지, 혹여 만족하지 않았다면 그때는 또 어떻게 활동하는지 궁금하다. GA와 A/B 테스트 등의 방법들을 통해 데이터를 보며 이를 파악하고 싶다.기존 홈페이지는 전통적인 페이지 단위로 돌아가는 레일즈 웹 애플리케이션이었으므로 따로 제이쿼리 등을 사용해야지만 이를 구현할 수 있었다. 그래서 페이지 단위의 웹을 벗어나 React를 활용한 컴포넌트 단위의 웹 사이트를 구축했다. 장기적으로 계획적이고 세밀한 트래킹이 가능하도록 기반을 닦았다.또 기존의 홈페이지에서는 유저에게 오류 제보를 받아도 이를 확인해보는 것이 어려웠다. 그래서 지금의 시스템에는 Apollo engine과 Cloud watch를 이용하여 여러 로그들을 트래킹 하기 시작했다.리라이팅 런칭 2주 차,아쉬웠던 점들리라이팅 한 홈페이지를 런칭한 지 2주일이 지났다. 런칭 후에 한참을 정신없이 보내다가 이제야 조금 숨을 돌릴 수 있게 되어 이 글도 쓰기 시작했다. 런칭만 하면 마음이 편해질 거라 예상했는데 막상 다가오니 그렇지도 않았다. 더 바쁘고 정신없던 것은 물론이요, 아쉬운 점들만 눈에 밟혀서 마음이 무거웠다. 잘한 것보다 아쉬웠던 점들이 나를 더 성장하게 만들어 줄 것이라는 생각으로 스스로를 위로하여 어떤 것들이 아쉬운지도 정리해보았다.1. 트래픽이 몰리는 피크타임에 대한 대비 미흡배달의 민족이 식사 시간마다 트래픽이 몰리는 피크타임이 존재하듯, 트레바리도 독후감 마감 시간이라는 피크타임이 존재했다. 유저들이 모든 시간 대에 일정하게 접속하는 하는 것이 아닌 특정 시간에 몰아서 접속하는 것을 고려하여 그때의 속도를 잘 잡았어야 했다. 이를 미리 고려하여 캐시와 같은 여러 대비책들을 세워두었다면 유저들이 느린 홈페이지가 주는 불편을 덜 겪었을 거라고 생각한다.2. 치밀하지 못한 안내런칭 직후 오는 많은 문의들이 실제 오류가 아닌 제대로 된 안내가 없어 오류로 인지하는 경우였다. 예를 들어 기존에는 있었으나 사라진 주소와 같은 404 페이지 접근 시에는 안내 후 메인 페이지로 보내버리거나 하는 안내가 있었으면 많은 문의들을 대응하지 않아도 됐을 것이다.3. 운영 크루 업무 이해도 낮음리라이팅을 할 때 다른 크루들과 커뮤니케이션을 하는 일에 많은 리소스를 쏟지 않았었다. 다른 크루들의 업무에 대해 꽤 잘 이해하고 있다고 생각했기 때문이었다. 내가 생각하기에 필요할 것 같은 기능들만 어드민에 담았고, 그 결과로 크루들이 런칭 직후에 엄청난 불편과 수고로움을 겪게 만들었다.4. 조급함리라이팅을 진행하는 기간 동안 마음이 급해서 눈앞에 보이는 기능들을 빨리 쳐내는 것에 급급했다. 그러다 보니 각 기술에 대한 문서들을 꼼꼼하게 읽어내지 못해 놓친 부분이 많았다. 특히 한 번도 경험해본 적 없는 각종 브라우저와 브라우저 버전, PC와 모바일 대응 등에서 많이 놓쳤다. 평소 웹 표준 관련 문서를 잘 읽어두었다면 이런 실수는 덜하지 않았을까 생각했다. 또 틈틈이 작성했던 코드를 되돌아보고 개선하는 시간도 가졌어야 했는데 조급함 때문에 그러지 못했다. 이런 부분들은 개발자가 평소에 항시 주의해야 할 모습이라 생각했다.이번 리라이팅을 시작으로 트레바리가 온라인의 경험까지 멋진 서비스가 될 수 있기를 희망한다. 아직은 부족한 점이 많지만 사람들이 독서모임에 참석하기까지 겪는 온라인에서의 경험을 멋지게 만들고 싶다. 필요한 기능들을 적재적소에 구현하고, 말보다는 UI로 커뮤니케이션을 잘하는 개발자가 되기 위해 계속 노력할 것이다.지난 4개월 동안 참 힘든 시간도 많았다. 그럼에도 불구하고 크루들과 주변의 개발자분들에게 여러 도움을 받으면서 어려운 난관들을 헤쳐나갈 수 있었다. 홈페이지 변경이 아니어도 바쁜 일이 많은 시즌 시작 시기에 홈페이지 관련 문의가 쏟아졌다. 그런 상황에서 나를 탓하기보다는 오히려 걱정해주고 격려해주는 동료들이 있었다. 새삼스레 좋은 사람들과 함께하고 있다는 생각을 하며 일을 더 열심히, 잘 하는 것으로 보답하고 싶다고 생각했다.#트레바리 #기업문화 #조직문화 #CTO #스타트업CTO #CTO의일상 #인사이트
조회수 2658

8퍼센트 Test case 작성 가이드

8퍼센트에서 Python Django 코드에 대한 Test case 작성시 사용하는 가이드를 공유해보려고 합니다.클래스명일반적으로 TestCase 를 상속 받는 클래스일 경우 class 명의 마지막에 TestCase 를 붙입니다.예제: SimpleTestCase(TestCase)함수명테스트 함수명의 경우 test_ 로만 시작하면 동작하는데 문제가 없고 테스트 코드에까지 주석을 다는 것은 번거로우므로 함수명의 test_ 뒷부분을 한글로 하여 설명을 대신하도록 합니다.class IUPaginationMethodTestCase(TestCase): @classmethod def setUpTestData(cls): cls.request = Mock() cls.request.GET = {'page': 1, 'items_per_page': 1} cls.pagination = IUPagination(cls.request) def test_page_url_기본(self): expected = '?{}=1'.format(self.pagination.page_key) self.assertEqual(self.pagination.page_url(), expected) def test_page_url_쿼리스트링_없는경우_물음표_붙인다(self): expected = '/?{}=1'.format(self.pagination.page_key) self.pagination.url_prefix = '/' self.assertEqual(self.pagination.page_url(), expected) def test_page_url_쿼리스트링_있는경우_엠퍼센드로_붙인다(self): expected = '{}&{}=1'.format( self.pagination.url_prefix, self.pagination.page_key )) self.pagination.url_prefix = '?utm=source' self.assertEqual(self.pagination.page_url(), expected) factory_boyfixture 를 대신해서 가급적 factory_boy 를 사용합니다.signals 끄기factory boy로 모델 객체 생성시 signal 이 호출되는데 signal에 대한 테스트가 아니라면 대부분 실행할 필요가 없습니다.이 때 factory.django.mute_signals를 사용해서 끄면 됩니다.decorator, context manager 둘 다 사용 가능합니다.decorator@mute_signals(signals.post_save) def test_some_code(self): some = SomeFactory() context managerwith mute_signals(signals.post_save): some = SomeFactory() 참고 링크factory_boyDisabling signalssetUpTestData vs setUpfixture를 사용하면 fixture로 정의한 모델 객체가 모든 테스트 시작 전에 생성이 되는데 유사하게 setUp 에서 factory 생성을 하게 되면 매번 객체 생성을 하게 되므로 느립니다.테스트에서 read only 로만 사용하는 객체의 경우 class method인 setUpTestData 에서 생성하면 1번만 생성이 되므로 빨라집니다.가급적 setUp 에서 매번 객체를 생성하는 것을 지양하고 테스트 함수 내에서 필요한 객체만 생성하는 것이 효율적이고 빠릅니다.method mock메소드를 mock 하는 경우 unittest.mock.patch() 를 사용합니다.decorator보통 테스트 메소드에 대한 decorator 로 사용합니다.직접 호출class 내의 여러 테스트 메소드 혹은 모든 테스트 메소드에서 동일한 함수를 mock 하는 경우에는 start, stop 을 활용하면 편합니다.예제 코드from unittest import mock class MyTest(TestCase): def setUp(self): self.mock_method1 = mock.patch('package.module.method1').start() self.mock_method1 = mock.patch('package.module.method2').start() def tearDown(self): mock.patch.stopall() def test_something(self): something() self.assertTrue(self.mock_method1.called) 참고 링크: patch methods start and stoptimezonedatetime.datetime.now() datetime.datetime.strptime() 등을 사용해서 naive datetime 객체를 django 모델의 DateTimeField 에 할당할 필요가 있는 경우 반드시 django.utils.timezone.make_aware() 를 사용해서 time-zone-aware datetime 객체로 변환한 후에 합니다.참고 링크: Django timezone 문제 파헤치기freezegun특정 시점에서의 테스트가 필요한 경우 freezegun 을 사용해서 현재 시간값을 고정합니다.가급적 decorator 나 context manager 를 사용해서 특정 클래스나 메소드, 혹은 코드 블럭에만 적용하도록 하는 것이 좋습니다.decorator 예제from freezegun import freeze_time import datetime import unittest @freeze_time("2012-01-14") def test(): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) context manager 예제from freezegun import freeze_time def test(): assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) with freeze_time("2012-01-14"): assert datetime.datetime.now() == datetime.datetime(2012, 1, 14) assert datetime.datetime.now() != datetime.datetime(2012, 1, 14) 특정 테스트 케이스 전체에 적용을 하기 위해 start(), stop() 메소드를 사용하기도 하는데 이 경우 반드시 stop() 을 해주어야 다른 테스트 케이스의 시간 값에 영향을 주지 않습니다.예제from django.test import TestCase from freezegun import freeze_time class SomeTestCase(TestCase): def setUp(self): self.freezer = freeze_time("2016-01-05 00:00:00") self.freezer.start() def tearDown(self): self.freezer.stop() 참고 링크: freezegun맺음말Python Django 개발시 Test case 작성을 잘 하기 위한 8퍼센트 개발팀의 가이드를 공유해 보았습니다. Python Django 개발자들이 Test case 작성을 효율적으로 잘 해서 서비스의 안정성을 높이는데 도움이 되기를 기대해 봅니다.#8퍼센트 #에잇퍼센트 #Django #Python #장고 #파이썬 #개발 #개발자 #가이드 #꿀팁 #인사이트
조회수 6632

Elastalert로 로그 알람 구축하기

Elasticsearch로 로그를 수집하고 추세를 분석하기는 좋지만 실시간 알람을 받으려면 X-Pack Alerting 등을 이용해야 한다. 하지만 사용자 편의성 측면에서 개선할 점이 많다. 로깅 알람 전용이 아닌 다양한 용도로 커스터마이징해서 쓸 수 있게 설계한 탓일 수도 있다. 아무튼 대안을 살펴볼 필요가 있겠다 싶어서 Yelp가 공개한 Elastalert로 알람을(도) 적용해보았다.X-Pack Alerting과 비교했을 때 Yelp/elastalert의 장점은 명확하다. 무엇보다 시나리오별로 정해놓은 패턴에 따라 알람을 작성하면 일이 쉽게 끝난다. 여덟 가지 정도의 알람 타입이 있어서 상황에 맞는 템플릿을 가져다 쿼리만 살짝 고치면 된다.“Match where there are X events in Y time” (frequency type)“Match when the rate of events increases or decreases” (spike type)“Match when there are less than X events in Y time” (flatline type)“Match when a certain field matches a blacklist/whitelist” (blacklist and whitelist type)“Match on any event matching a given filter” (any type)“Match when a field has two different values within some time” (changetype)“Match when a never before seen term appears in a field” (new_term type)“Match when the number of unique values for a field is above or below a threshold (cardinality type)예를 들어 OutOfMemoryError라는 단어가 로그에 찍혔을 때 알람을 받고 싶다면 다음과 같이 Rule 파일을 준비한다.# Alert when the rate of events exceeds a threshold # (Required) # Rule name, must be unique name: OutOfMemoryError # (Required) # Type of alert. # the frequency rule type alerts when num_events events occur with timeframe time type: frequency # (Required) # Index to search, wildcard supported index: logstash-%Y.%m.%d* use_strftime_index: true # (Required, frequency specific) # Alert when this many documents matching the query occur within a timeframe num_events: 1 # (Required, frequency specific) # num_events must occur within this amount of time to trigger an alert timeframe: hours: 1 # (Required) # A list of Elasticsearch filters used for find events # These filters are joined with AND and nested in a filtered query # For more info: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html filter: - query_string: query: "message: OutOfMemoryError OR log: OutOfMemoryError" # (Required) # The alert is use when a match is found alert: - "slack"기본 템플릿을 가져다가 filter에 들어갈 쿼리만 다시 작성하면 일이 끝난다. 파이썬으로 작성한 간단한 소프트웨어라 사용하기도 쉽고 Docker로 만들기도 쉽다. pip install elastalert 그 외에 경험한 특이사항만 정리하고 이 글을 끝내려 한다.Elasticsearch의 플러그인으로 작동하는 X-Pack과 달리 ElastAlert는 독립 실행 애플리케이션이다. Kubernetes 같은 환경에서는 독립 실행 애플리케이션이 더 관리하기 쉽다.알람을 추가/삭제할 때마다 도커 빌드를 하기 힘든 환경이라면 RESTful API를 지원하는 X-Pack이 편할 것이다. back-end / elastalert 같이 RESTful API를 지원하는 ElastAlert 환경이 있긴 하지만 도커 배포환경에서는 여러 모로 한계가 있다. 도커를 올렸다 내렸다 하더라도 설정이 날아가지 않게 하려면 고민이 많아진다. node 애플리케이션과 Python 애플리케이션 둘을 하나의 도커 이미지로 제공하다 보니 다른 문제도 많다. 이런 식의 구성을 구현해봤다면 무슨 이야기인지 알 것이다.ElastAlerts는 Index Aliases를 지원하지 않는다. 물론 오픈소스이니 소스코드를 고쳐서 Pull Request를 보내면 될 일이다.X-Pack Alerting과 달리 알람 메시지를 정형화했다. 알람의 메시지 포맷을 조금 고칠 수는 있지만 기본적으로는 주어진 그대로 써야 한다. 간단하게 쓰기에는 낫고 그렇지 않다면 소스코드까지 손을 대야 한다.ElastAlert는 중복 알람 처리 등의 정책을 지정할 수 있다. 알람을 하루에 수백통 넘게 받아보면 이 기능이 왜 중요한지 알게 된다.문서에서 언급하듯 Elasticsearch 5.x와 함께 쓰려면 다음과 같이 버전을 명시하는 편이 좋다. pip install elasticsearch>=5.0.0 && pip install elastalert==0.1.8테스트 환경은 elastalert-test-rule 명령어를 제공하는 ElastAlert쪽이 더 낫다. 검색 쿼리를 제대로 작성했는지 알람 설정은 맞는지 확인하기가 쉬웠다.더 읽기ElastAlert: Alerting At Scale With Elasticsearch, Part 1ElastAlert: Alerting At Scale With Elasticsearch, Part 2Originally published at Andromeda Rabbit.#데일리 #데일리호텔 #개발 #개발자 #개발팀 #일지 #후기 #도입후기 #Elastalert #인사이트
조회수 1559

도도 파이터 제작기

안녕하세요. 도도 파이터의 개발과 시각 디자인을 각각 담당한 스포카 크리에이터 박준규, 박지선입니다.우선, 도도 파이터에 관심 가져주시고 참여해 주신 분들께 감사의 말씀을 드립니다. 도도 파이터는 저희의 당초 예상을 훨씬 뛰어넘는 71명의 제출로 마무리되었습니다. 많은 분의 참여 덕분에 이벤트를 무사히 마칠 수 있었다고 생각합니다.이 글에서는 도도 파이터의 기획 의도와 제작과정, 기술적인 디테일에 대해서 다루어 보려고 합니다.기획 의도저희는 파이콘 한국에 2015, 2016년에 이어 이번 2018년까지 총 세 차례 후원사로 참여하였습니다. 저희는 매번 코딩 컨테스트를 열고 있는데 2015년에는 코드 골프1, 2016년에 코드 난독화2이벤트를 개최했습니다. 저희는 지난 이벤트들을 통해 파이콘 참가자들에게 오락거리를 제공하면서 재능을 발굴할 수 있었습니다그동안 다른 후원사들도 여러 가지 훌륭한 코딩 컨테스트를 열었습니다. 저희들은 이에 고무되어 2018년 파이콘 한국 참가를 결정하면서 새로운 코딩 컨테스트 이벤트를 만들어 보기로 했습니다.저희는 이번 코딩 컨테스트의 목표를 아래 세 가지로 잡았습니다.바이럴 효과가 있을 것사람의 눈을 사로잡을 수 있어야 할 것접근성 있고 직관적인 규칙을 제공할 것위의 점들을 고려해 봤을 때 인공지능 대전 격투게임의 아이디어는 비교적 자연스럽게 도출되었다고 생각합니다.유저 대 유저가 직접 경쟁하는 방식은 코드 골프나 난독화처럼 주최 측이 취합해서 평가하는 방식보다 훨씬 버즈를 만들기 쉽습니다.대전 격투 게임이라는 틀은 30년 넘는 세월 동안 거의 그대로 유지되어 왔기 때문에 수많은 사람들에게 익숙합니다. 그리고 두 사람의 대결을 가장 직관적으로 표현할 수 있는 포맷입니다.게다가 저희는 귀여운 마스코트 캐릭터도 가지고 있습니다. 귀여운 마스코트 캐릭터들이 투닥투닥 싸우는 모습을 누가 그냥 지나칠 수 있을까요.익숙한 장르이기 때문에 게임의 규칙 역시 큰 틀을 잡는 데 어려움이 없습니다.이런저런 다른 후보들도 있었지만 이러한 이유로 격투 게임을 만들자는 합의에 다다랐습니다.게임 디자인하지만 격투 게임은 직관적으로 보이는 외양에 비해 파고들기 굉장히 복잡합니다. 현존하는 대전격투 게임들은 수많은 캐릭터가 등장하고 캐릭터별 성능 차이와 상성 관계가 존재하며 대응 전략도 전부 제각각이기 때문입니다. 저희는 이러한 요소를 전부 배제하기로 했습니다. 그런 것들이 대전격투 게임의 본질을 관통하는 특성은 아니기 때문입니다. 그것들을 전부 벗겨내면 남는 본질은 심리전입니다. 상대방의 플레이 전략을 파악한 뒤에 정보를 취합하여 액션을 취하는 것이 대전격투 게임의 알파이자 오메가입니다. 저희는 이 게임을 턴제로 설계했는데, 보통 실시간으로 이루어지는 대전격투 게임을 턴제로 설계해도 말이 되는 이유가 여기에 있다고 생각합니다. 턴제로 만들어도 대전격투 게임의 본질이 심리전이라는 대전제가 깨지지 않기 때문입니다. 저희는 인공지능 대전으로 심리전의 특징을 살릴 수 있을 거라 보았습니다.여러 가지 시스템을 고려했으나 게임 디자인은 최소화된 형태로 수렴했습니다.플레이어는 뒤 또는 앞으로 한 칸씩 움직일 수 있다.공격 방식은 펀치와 킥이 있는데, 펀치는 숙여서 피할 수 있고 킥은 점프해서 피할 수 있다.심리전이 성립하기 위해서는 최소한의 상성 관계가 만족되어야 합니다.상대방의 공격을 무조건 맞는 대신 받는 데미지를 절반으로 줄이는 방어 액션이 있다.때로는 리스크를 지지 않는 안전한 선택지도 제공하면 좋을 것입니다.그 외에 게임 디자인 과정에서 여러 가지 시행착오가 있었습니다.처음에는 캐릭터를 움직인다는 개념이 없었습니다. 두 캐릭터들이 같은 위치에 서서 싸운다기보다는 가위바위보를 하는 모양에 가까웠습니다. 그래서 캐릭터 이동 액션을 추가했습니다.그런데 스테이지 크기에 제한이 없었습니다. 플레이어가 무한히 뒤로 갈 수 있었는데 한 대 때린 뒤에 끝날 때까지 뒤로 도망가는 파훼가 불가능한 전략을 쓸 수 있었습니다. 스테이지 크기에 제한을 두는 방식으로 해결했습니다.원거리 공격, 대쉬, 필살기 등등 여러 가지 세부적인 시스템을 고려했으나 시스템이 지나치게 복잡해질 것 같았고 무엇보다 제때 밸런스를 조정할 자신이 없어서 포기했습니다.시스템을 이렇게 만들어 보니 상대가 근접하면 가만히 서서 공격만 하는 에이전트가 승리할 확률이 가장 높았습니다. 이를 방지하기 위해 최근 다섯 턴 간 취한 액션이 한 종류라면 데미지가 1/3, 두 종류라면 2/3만 들어가도록 페널티를 주었습니다.이 조치만으로는 방어/회피 없이 공격만 해도 이기는 문제를 해결하지는 못합니다. 따라서 방어/회피에 성공할수록 다음 번의 공격력이 강해지는 시스템을 추가하여 적극적으로 방어/회피를 하도록 유도하였습니다.저희는 데미지 계산 공식을 공개하는 것을 주저했는데, 구체적인 공식을 공개하면 제출물의 성향이 한쪽으로 쏠릴 것을 염려했기 때문입니다. 저희는 최대한 창의적인 솔루션이 많이 나오길 바랐습니다. 하지만 지금 돌이켜보면 구체적인 수치를 공개한다고 크게 바뀔 것이 있었나 싶기도 합니다.시각 디자인처음엔 격투 게임이라는 설정만 있었지만, 시각적으로 풍부하게 표현하기 위해 더 디테일한 기획이 필요했습니다. 그리하여 도도 파이터 만의 세계관을 만들어 풀어보기로 했습니다. 설정을 초반에 정하고 나니 캐릭터부터 모든 디자인이 술술 풀려갔습니다. 왜 게임을 만들 때 초반에 세계관과 시놉시스를 세세히 기획하는지 알겠더군요.원래 실제 도도새는 마다가스카르 동쪽에 있는 모리셔스 섬 해안가에 주로 서식한 것으로 추정된다고 합니다. 모리셔스 섬에 도도새가 모여 마을을 이루고 있는 모습을 상상했고, 그곳을 배경으로 도도 파이터가 펼쳐집니다.야자수, 뜨거운 햇빛, 맑은 바다. 그리고 자영업자가 많은 평화로운 도도 포인트 마을. 손님을 위해 더 좋은 매장을 운영하려면 체력은 필수. 각자의 방식으로 체력을 기르던 매장 사장님들이 최고의 체력왕을 고르기 위해 도도 파이터라는 대회를 개최하게 됩니다. 과연 체력왕 사장님은 누가 될까요?노을이 아름다운 모리셔스 섬에 숨겨진 도도 포인트 마을Lean하게 캐릭터 디자인하기짧은 시간 내 게임을 완성하기 위해서 그래픽 리소스 제작 비용을 줄여야 했습니다. (인력 서포트도 있었습니다3) 기존에 잘 정리되어 있는 디자인 리소스들은 이런 상황에서 특히나 빛을 발합니다. 파이터는 포포(도도새 캐릭터)로 한정하고 동작 디자인은 거의 통일하기로 했습니다. 또한, 게임 특성을 고려해 기존에 디자인되어 있던 반측면 조형만을 활용했습니다.다만 사용자간 구분이 필요하기에 각 캐릭터별 특색을 넣었습니다. 게임에 등장할 포포들은 매장 사장님이므로 격투게임에 등장하면 흥미로울 만한 업종에 계신(?) 포포만을 모셨습니다. 그리고 각 업종에 어울리는 패션 아이템과 구별되는 성격을 배합해서 총 3종의 캐릭터를 완성했습니다.도도 파이터 대회에 참가한 포포 사장님들스시 장인 포포: 철두철미한 성격으로 묵직하고 독특한 풍미의 시그니처 스시를 주 무기로 사용합니다.학원 원장 포포: 성실히 학생들을 지도하며 평소에 칠판 지우개로 팔근육을 단련해왔습니다.볼링장 사장 포포: 걱정이 많지만 볼링을 사랑하며 즐깁니다.도도 파이터에서 캐릭터는 총 9가지의 액션을 취할 수 있습니다. 기본 틀은 동일하지만 캐릭터별 특색을 넣는 것만으로도 단조로움을 없앨 수 있었습니다. 공격하는 무기는 잔인하기 보다는 귀엽고 웃긴 방향으로 해 산뜻한 분위기가 되도록 했습니다. 만약 스시 장인 포포가 칼을 들고 있었다면 게임 분위기가 살벌했을 것입니다.캐릭터들의 다양한 모습구현 상세서버서버는 아래의 소프트웨어 스택을 사용하여 구현하였습니다.파이썬 3.6Flask 웹 프레임워크PostgreSQL 데이터베이스SQLAlchemy 데이터베이스 라이브러리그 외에 설정 관리에는 settei, 데이터베이스 마이그레이션은 alembic 등 여러 오픈 소스 프로젝트를 사용하고 있습니다.이상은 스포카에서 사실상 표준으로 사용하고 있는 소프트웨어 스택이기 때문에 스포카 개발팀이 비교적 능숙하게 사용할 수 있습니다. 덕분에 3~4주 남짓한 짧은 기간 안에 완료할 수 있었습니다. 개발 당시의 급박한 상태가 그대로 드러나는 퀄리티긴 하지만, 소스 코드는 여기에서 받으실 수 있습니다. PR이나 버그 보고는 두손 두발 다 들고 환영합니다.프론트엔드게임의 프론트엔드는 Unity 엔진을 사용하여 개발하였습니다. Unity는 WebGL 타겟 빌드를 지원하는데, 이를 통해 웹 브라우저 위에서 실행가능한 WebAssembly 바이너리로 빌드할 수 있습니다.매칭 기록을 재생해주기만 하면 되는 간단한 부분이기 때문에 처음에는 런타임 바이너리 용량만 수 메가바이트에 달하는 거대한 게임 엔진을 쓰는 것이 내키지 않았습니다. HTML5 Canvas를 직접 써서 만들까 했지만, 생각보다 손이 많이 가고 제때 끝낼 자신이 없었습니다. 다행히 Unity로는 빠른 작업이 가능했고 절약한 시간만큼 애니메이션 효과와 시각적 완성도에 조금 더 시간을 투자할 수 있었습니다. 빌드 용량이 크긴 했지만, 결과적으로는 좋은 결정이었다고 생각합니다.배포 인프라도도 파이터는 Docker로 빌드되며, 스포카의 프로덕션 서비스에 사용되고 있는 AWS ECS 클러스터 위에 배포됩니다. 기존 인프라를 활용하여 추가적인 지출을 최소화할 수 있었습니다.지금에서야 말할 수 있는 사실이지만 도도 파이터는 파이콘 행사 중에도 미완성 상태였습니다. 여러분들이 도도 파이터에 참가하고 계신 와중에도 개발자는 부스 한구석에서 부리나케 작업을 하고 있었습니다. 급박한 과정에서 Docker와 ECS가 있었기에 빠른 배포가 가능했습니다.샌드박싱웹 앱 위에서 임의의 파이썬 코드를 실행을 허용하면 필연적으로 공격의 위협에 노출됩니다. 따라서 저희는 악의적인 코드가 실행되지 않도록 하는데 많은 노력을 했습니다.에이전트 스크립트는 메인 서버 프로세스와 격리되어 실행됩니다. 이때subprocess모듈을 사용합니다.스크립트는 바로 실행되지 않고 러너 안에서 실행됩니다.이때 러너에서는 스크립트가 다른 파일을 열지 못하도록__builtins__.open()함수를 지웁니다.러너 프로세스는 제한된 유저 권한으로 실행됩니다. 혹여나 다른 파일을 불러올 수 있는 가능성을 OS 레벨에서 차단합니다.보안상의 이유로 에이전트는 허용된 모듈만 불러올 수 있습니다. 러너에서는 스크립트의추상 구문 트리를 분석하여 허용되지 않은 모듈을 불러오는지를 검사합니다. 이때ast모듈을 사용합니다.러너가 참조하는 모듈을 에이전트 안에서 참조하지 못하도록sys.modules를 비웁니다.실수 또는 DoS로 스크립트가 무한 루프를 도는 상황을 방지하기 위하여 3초가 지나도 스크립트가 완료되지 않으면 프로세스를 강제로 종료하는 역할도 합니다.서버는 Docker 컨테이너 안에서 격리되어 실행됩니다. 만약 잘못된 코드로 인해서 서버가 죽는 상황이 생기면 ECS 클러스터가 자동으로 복원해 줍니다.가장 마지막으로, 모든 실행되는 코드는 기록을 남깁니다. 만에 하나 이 모든 보호 조치들을 우회한다고 하더라도 어떤 GitHub 아이디로 로그인해서 무슨 코드를 실행시켰는지 기록을 남겨서 사후에 추적할 수 있도록 하였습니다.느낀 점들무엇보다 대회 진행에 아쉬움이 진하게 남습니다. 참가자들을 여러 조로 나눈 것은 수시로 조를 배정하고 결승전 이전에 조별 우승자를 미리 선정하기 위함이었는데, 결과적으로 최종 제출 기한이 끝난 뒤에 조가 배정되고 결승 중계 현장에서 조별 우승자가 정해졌습니다. 이로 인해 결승 중계 진행이 많이 늘어졌던 것 같아서 아쉽습니다.참가자와의 소통을 위한 피드백 창구가 없었던 점 또한 아쉽습니다. 몇몇 참가자 분들께서는 직접 부스로 찾아오셔서 문의하시기도 했습니다. 생각하지 않은 것은 아니었는데 다른 시급한 작업이 우선이라 엄두를 내지 못했습니다.예상보다 참가자들이 많아서 결승전 중계 때는 시간이 많이 밀렸습니다. 플레이백 속도를 조절할 수 있는 기능을 넣었어야 했다는 아쉬움도 남네요.처음에 우려했던 밸런스가 붕괴하는 상황은 다행히 발견되지 않았습니다. 승리에 유리한 전략은 어느 정도 경향성이 있는 것으로 보이나 게임의 밸런스가 망가진 수준까진 아니라고 판단하고 있습니다.마치며여기까지가 장장 4주에 달하는 도도 파이터의 제작 후기였습니다. 후속 포스팅에서 이번 파이콘 한국 2018 세션에서 제출된 출품작들을 분석하고 어떤 참신한 코드가 있었는지를 알아보도록 하겠습니다. 읽어주셔서 감사합니다.특정 목적을 달성하는 프로그램을 가장 짧은 길이로 작성하여 겨루는 경쟁 게임입니다. ↩창의력을 동원하여 어떤 목적을 달성하는 코드를 가장 알아보기 어렵게 작성하는 경쟁 게임입니다. ↩디자인 서포트를 해주신 안정빈 디자이너에게도 감사를 표합니다. ↩#스포카 #기업문화 #조직문화 #개발자 #개발팀 #프로젝트 #후기 #일지
조회수 787

챗봇과 인공지능 머신러닝 - Part 2/2

지난 시간에 이어 오늘은 챗봇에게 지능을 주는 방법에 대해 알아본다. 공부를 해보시면 아시지만 공부란 어느정도 양이 많아지면 가속이 붙는다는 것을 학창시절에 경험 하셨을 것이다. 즉, 공부를 잘하는 사람은 조금만 해도 더 잘한다. 아무것도 아는게 없는 상황이라면 무조건 머리에 넣는 것도 방법이다. 물론 그 후에는 외운 지식의 의미에 대해 깊은 사고가 필요하지만.  챗봇한테도 이런 사람에 통하는 방식이 그대로 적용된다.지도학습은 규칙이나 사례를 구조화된 형식으로 표현하고 이를 컴퓨터에 입력해 놓는 방식이다. 단점은 한 분야의 지능을 다른 분야에 재사용할 수 없기 때문에 분야별로 다시 개발해야 한다는 데 있다. 아! 주입식 교육의 한계.한편, 자율학습은 인간의 뇌처럼 컴퓨터도 동일하게 데이터간의 연결 상태와 강도로 지식을 보유하도록 하는 방식이다. 이 방식의 대표적인 예가 인공 신경망(Artificial Neural Network)으로 스스로 학습할 수 있다는 점이 가장 큰 장점이다. 대량의 데이터에서 스스로 특징을 추출한다. 최근에는 딥러닝(Deep Learning)이라는 방법을 이용하여 자연어 인식, 영상인식, 음성 인식 등에서 과거엔 손도 못 대던 일을 하고 있다.인공신경망 활용을 위한 두 가지 조건인공신경망의 장점을 살리기 위해선 두 가지 큰 장벽을 넘어야 한다. 첫째는 자율학습 알고리즘을 개발하는 것이다. 둘째는 필요한 양질의 데이터를 대규모로 확보하는 것이다. 인공신경망 개발툴은 구글이나 마이크로소프트 등이 무료로 공개하고 있으므로 데이터 공학자, 프로그래밍 전문가, 응용수학자, 기획자 등과 함께 팀을 구성하면 개발을 시작할 수 있다. 그러나 실제에 있어서 가장 큰 난관은 두 번째로 지적한 대규모 데이터의 확보에 있다. 데이터를 가진 자가 승자라는 말이 있을 정도로 데이터가 중요하지만 이를 확보하는 것은 쉽지 않다. 학습 알고리즘이 있어도 데이터의 질이 떨어지거나 데이터의 수량이 적다면 자율학습이 제대로 될 수 없기 때문이다. 아! 머리에 든게 충분히 있어야 딥러닝이 가능하다.기술력보다는 기획력이 중요한 챗봇챗봇은 텍스트 형식의 글자를 통해 사람과 기계가 소통하는 방법이므로 앞에서 언급한 머신러닝 기술 중 자연어 처리(NLP)와 자연어 인식(NLU)이 필요해진다. 아! 정말 알아야 할 게 많다. 간단히 설명하면 NLP에는 형태소분석, 구문분석이 포함되고 NLU는 여기에 사용자 의도 해석과 실제 상황처리가 필요한 문맥이해까지 포함된다. 누구나 알다시피 조사, 접사 등이 발달한 한국어는 텍스트 처리가 영어에 비해 쉽지 않다고 한다. 로봇한테 사람처럼 말귀를 알아듣게 하는 작업이란 이렇게 어려운 일이다.실무에서의 챗봇 서비스는 기술력도 중요하지만 어떤 컨텐츠를 가지고 어떻게 서비스 할지에 대해 더 고민해야 한다. 역시 대화란 사람에 대한 이해가 중요한 만큼 초기단계에서 좋은 데이터 축적을 위해 규칙기반의 룰을 잘 선정하고 이를 머신러닝 기법과 잘 융합하는 유연성이 필요하다. 또 데이터 크기가 작을 때에는 딥러닝 보다 SVM(Support Vector Machine)류의 머신러닝이 더 좋은 성능을 보인다. 또 오버피팅 문제로 인해 학습 시 많은 데이터 사용이 꼭 성능증가로 이어지지도 않는다. 오히려 도메인 지식과 기획력 및 간단한 세션관리로도 좋은 품질의 챗봇을 만들 수 있다고 본다. 아울러 초기기술을 계속적으로 축적하면서 차근차근 지속적으로 업그레이드 해 나간다면 누구나 그 컨텐츠 영역에서 훌륭한 챗봇 친구를 얻을 것이다.맺는말이상으로 간단하게 챗봇에 대해 지극히 개인적인 의견을 올려봤다. 깊이 들어가면 한이 없는 분야지만 제 4차 산업혁명을 맞이하여 필연적으로 우리와 함께 살아갈 수밖에 없는 스마트폰 안에 있는 로봇인 챗봇에 대해 모든 사람들이 더욱더 관심을 가졌으면 한다.
조회수 3080

챗봇과 인공지능 머신러닝 ㅡ Part 1/2

스타워즈를 보신 분이라면 거기에 나오는 난쟁이 로봇 R2D2와 키다리 로봇 C3P0를 아실 것이다. 친근한 R2D2는 전자음을 조정해 인간과 대화를 하며 주로 말 잘하고 박식한 로봇인 C3P0가 통역을 해준다.이런 충실하면서 똑똑한 친구들이 옆에서 항상 나를 도와준다면 어떨까? 정말 좋을 것이다. 만약 매일 보는 스마트폰 안에서도 나의 질문에 답해주는 이런 고마운 친구들이 있다면 얼마나 좋을까? 이런 저런 생각을 하다보면 우리는 대화형 로봇의 필요성을 느낀다.챗봇(Chatbot)이란?챗봇의 정의는 “대화형 인터페이스 상에서 규칙 또는 지능으로 유저와 소통하는 서비스”이다. 이 말을 하나하나 풀어보자.먼저, 대화형 인터페이스란 뭐지? 어렵다. 쉽게 설명해 보자. 인터페이스는 사람과 컴퓨터를 연결하는 장치라고 한다. 역시 어렵다. 아! 그냥 스마트폰 앱으로 보면 된다. 그럼 소통한다는 말은 대화한다는 것이므로 스마트폰 앱에서 일방향이 아닌 양방향이 가능하다는 얘기다. 어! 이상하다. 양방향이라면 나의 말에 응대하는 로봇은 뭐로 움직이는 거지? 궁금하다. 누가 일정한 규칙으로 만들어 논건지 아니면 우리처럼 지능이 있는 건지. 지능이 있다면 그런 지능은 뭐지? 점차 우리는 자연스럽게 인공지능에 다가간다.인공지능(Artificial Intelligence)이라는 용어는 1956년 미국 다트머스의 한 학회에서 존 매카시가 처음 사용했다고 한다. 원래 인공지능은 소프트웨어인 정신을 말하고 로봇은 하드웨어인 육체를 말하는 것이지만 정신없이 육체가 존재할 수 없는 것처럼 로봇을 얘기하면 당연히 인공지능은 따라간다.학자들은 인공지능을 강(强)인공지능과 약(弱)인공지능으로 구분한다. 간단히 얘기하면 강인공지능이란 자의식이 있는 인간에 가까운 지능이고 약인공지능은 자의식이 없다. 자아가 없으며, 명령받은 일만을 수행한다. IBM의 왓슨(Watson), 작년에 인공지능의 붐을 가져온 구글의 알파고(Alpha-GO) 등은 모두 약인공지능이다. 이런 인공지능을 구현하는 기술은 무엇인가? 바로 기계한테 학습을 시키는 머신러닝(Machine Learning)이다.1959년 아서 사무엘은 머신러닝을 "기계가 일일이 코드로 명시하지 않은 동작을 데이터로 부터 학습하여 실행할 수 있도록 하는 알고리즘을 개발하는 연구 분야"라고 정의했다. 여기서 학습이란, 입력 값을 받아 결과 값을 내는 모델을 만드는 표현과 표현을 통해 주어진 업무가 얼마나 잘 수행됐는지 알아보는 평가, 그리고 평가에서 설정한 기준을 찾는 최적화로 구성된 일련의 과정을 말한다. 중요한건 우리가 시키지 않은 일도 학습에 의해 자율적으로 처리한다는 것이다. 정말 신기하지 않은가?이제 챗봇이 뭔지 감이 잡힌다. 스마트폰 앱상에 존재하는 로봇인데, 물론 육체는 화면의 아이콘으로 밖엔 안보이지만 인공지능을 가지고 머신러닝에 의해 동작을 하면서 우리와 대화를 하는 그분. 그렇다면 이제 남은 건 이분의 지능이 어느 정도인지 또 얼마나 일을 잘하는 지로 판가름 난다.우리는 평생 공부를 한다. 이제는 학교를 졸업하고 나서도 항상 배워야 한다. 학습이 없다면 지능도 없다. 학습은 일일이 지도받는 지도학습과 알아서 공부하는 자율학습이 있다. 알아서 공부하려면 먼저 머리에 지식이 많아야 한다. 역시 기계도 사람과 비슷하게 배운다.  다음시간엔 챗봇에게 학습을 시켜 지능을 가지게 하는 방법에 대해 알아본다.> Part 2에서 계속
조회수 2117

Kubernetes에 EBS 볼륨 붙이기

Kubernetes에서 컨테이너에 Persistent Volume을 붙이는 방법은 몇가지 있다. 여기서는 Kafka 서비스를 예로 삼아 주요 접근방법을 간단히 알아본다.Kubernetes v1.4.0를 기준으로 문서를 작성한다.Static말이 Static이지 수동 마운트를 뜻한다. 기본적으로 관리자가 EBS 볼륨을 만들고특정 Pod에 그 볼륨을 붙이는 작업을 한다. Volumes 문서에 나오는대로 하면 간단하다.apiVersion: v1 kind: Service metadata: name: kafka1 labels: app: kafka1 tier: backend spec: ports: # the port that this service should serve on — port: 9092 name: port targetPort: 9092 protocol: TCP selector: app: kafka1 tier: backend — - apiVersion: extensions/v1beta1 kind: Deployment metadata: name: kafka1 spec: replicas: 1 template: metadata: labels: app: kafka1 tier: backend spec: containers: — name: kafka1 image: wurstmeister/kafka imagePullPolicy: Always volumeMounts: — mountPath: “/kafka” name: kafka1volume ports: — containerPort: 9092 volumes: — name: kafka1volume awsElasticBlockStore: volumeID: vol-688d7099 fsType: ext4여기서 핵심은 다음의 두 줄 뿐이다.awsElasticBlockStore: volumeID: vol-688d7099Dynamic수동으로 볼륨을 붙이는 방법은 간단해서 좋다. 하지만 Autoscaling하는 서비스에 넣기에는 아무래도 무리다. 서비스가 뜰 때 요구사항에 맞는 볼륨을 스스로 만들어 붙이는 방법도 있다. Kubernetes Persistent Volumes를 참고해 작업해본다.우선 Kubernetes 생성할 EBS 볼륨의 사양을 정한다.# storages.yaml apiVersion: storage.k8s.io/v1beta1 kind: StorageClass metadata: name: default1a provisioner: kubernetes.io/aws-ebs parameters: type: gp2 zone: ap-northeast-1a iopsPerGB: “10” — - apiVersion: storage.k8s.io/v1beta1 kind: StorageClass metadata: name: default1c provisioner: kubernetes.io/aws-ebs parameters: type: gp2 zone: ap-northeast-1c iopsPerGB: “10”default1a를 선택하면 ap-northeast-1a Availablity Zone에 기가바이트당 IOPS는 10인 General SSD EBS 볼륨을 생성한다. 이제 다시 Kafka의 돌아가면apiVersion: v1 kind: Service metadata: name: kafka1 labels: app: kafka1 tier: backend spec: ports: # the port that this service should serve on — port: 9092 name: port targetPort: 9092 protocol: TCP selector: app: kafka1 tier: backend — - apiVersion: extensions/v1beta1 kind: Deployment metadata: name: kafka1 spec: replicas: 1 template: metadata: labels: app: kafka1 tier: backend spec: containers: — name: kafka1 image: wurstmeister/kafka imagePullPolicy: Always volumeMounts: — mountPath: “/kafka” name: kafka1volume ports: — containerPort: 9092 volumes: — name: kafka1volume persistentVolumeClaim: claimName: kafka1volumeclaim — - kind: PersistentVolumeClaim apiVersion: v1 metadata: name: kafka1volumeclaim annotations: volume.beta.kubernetes.io/storage-class: “default1a” spec: accessModes: — ReadWriteOnce resources: requests: storage: 300Gi이제 awsElasticBlockStore가 아닌 PersistentVolumeClaim을 통해 볼륨을 할당받는다. kafka1volumeclaim은 default1을 기준으로 스토리지 정책을 정하므로Availablity Zone: ap-northeast-1aIOPS: 기가바이트당 10General SSD300Gi 이상인 스토리지를 원한다는 요구사항을 기술한다. 위의 설정은 이러한 스토리지에 부합하는 EBS 볼륨을 생성하여 kafka1 Pod에 할당한다.분석Dynamic은 Autoscaling에는 적합하나 kubectl delete [service] 또는 kubectl delete [deployment] 등의 명령을 수행하여 서비스를 내렸다가 다시 올린 경우에 기존에 쓰던 볼륨을 마운트하지 않고 새 볼륨을 만드는 문제가 있다. 물론 delete를 하지 않고 서비스를 업데이트만 하는 경우에는 볼륨이 유지되지만 이래선 아무래도 문제의 소지가 많다.그래서 또다른 시나리오를 고민해볼 수는 있다. 짧게 설명하자면관리자가 Volumn Pool을 만들어놓고 Autoscaling 서비스가 이 풀 안에서 볼륨을 할당받게 한다. 이러면 앞서 본 두 가지 방식의 장점을 골고루 흡수할 수 있다.flocker 또는 glushterfs 같은 스토리지 관리 서비스를 활용해도 좋다. 하지만 배보다 배꼽이 큰 것 같은 느낌이 들지도 모르겠다.#데일리 #데일리호텔 #개발 #개발자 #개발팀 #인사이트 #꿀팁
조회수 1481

독서모임 스타트업에 개발자나 디자이너가 필요한가요?

트레바리는 독서모임을 운영하는 회사다. 멤버들이 책을 읽고, 독후감을 쓰고, 아지트에서 여러 사람들과 다양한 대화를 나눌 수 있도록 만들어준다. 아날로그적이려면 한없이 아날로그 할 수 있는 회사가 바로 트레바리다. 그러다 보니 트레바리의 첫 빌트인(?) 개발자 겸 디자이너인 나는 가끔 이런 질문을 받기도 한다. "트레바리에 개발자나 디자이너가 필요한가요?" 작년 11월과 12월, 개발과 디자인을 총동원해서 멤버십 신청 페이지의 UI/UX 개선 작업을 진행했다. 원래의 홈페이지보다 편하게 신청하도록 토스 결제를 연동하는 등 프로세스를 재편하였고, 판매할 프로덕트가 의도대로 보이도록 레이아웃을 다시 구성하였다. 컨텐츠의 가독성을 위해 컴포넌트들의 디자인도 깔끔하게 변경했다. 개선된 프로세스와 인터페이스라면 멤버십에 신청하는 사람들이 늘어날 거라고 확신했다. 홈페이지를 방문만 하고 멤버십에 신청하지 않은 이유는 '홈페이지가 불편하고 안 예뻐서'라고 생각했기 때문이었다.결론부터 말하자면 내 가설은 완전히 틀렸다. 개선된 홈페이지를 런칭했지만 방문 유저 대비 신청한 유저의 비율에는 큰 변화가 없었다. 다급히 주변에 조언을 구하기 시작했고 마켓컬리의 이지훈 님이 해주신 조언이 한참을 머릿속에 멤돌았다. "트레바리는 오프라인 경험이 메인이므로 홈페이지의 변화가 큰 효과가 없을 수 있음을 인정하고 시작해야 해요. 홈페이지는 광고를 보고 온 유저들이 독서모임에 가기 전까지 거쳐 가는 곳이에요."그렇다. 트레바리 홈페이지는 오프라인 독서모임에 참여하기 위한 건널목일 뿐이였다. 건널목이 아무리 좋다 한들 목적지가 탐탁지 않으면 사람들이 건너가지 않을 것이었다. 마찬가지로 홈페이지가 아무리 편하고 예뻐도 아지트에 와서 나누는 대화가 무의미하고 재미없다면 사람들이 트레바리를 찾지 않을 것이다.덕분에 트레바리 특성상 홈페이지를 위한 개발자나 디자이너 크루(=직원)가 필요한지 자문하게 되었다. 건널목 역할을 수행하는 홈페이지가 필요한 것이라면 이미 충분하다고 생각했다. 추가로 필요한 기능이 있다면 그때그때 적당한 프리랜서를 고용하는 게 합리적일 수도 있었다. 그렇다면 맨 위의 질문에 대한 대답은 "아니요. 필요 없어요. 프리랜서면 충분해요."가 되는 것이었다.내가 크루로서 잘 쓰일 수 있는 일은 무엇일까?얼핏 생각하기에 프리랜서면 충분해 보이지만 분명 내가 크루로서 잘 쓰일 수 있는 일이 있을 거라 생각했다. 그리고 그것을 오프라인 트레바리와 온라인 트레바리 사이에 간극이 있다는 점에서 찾았다.오프라인 트레바리는 꽤나 매력적이다. 한 시즌을 경험한 두 명의 멤버 중 한 명은 다음 시즌에도 멤버십을 신청한다. 물론 나머지 한 명까지 신청하게 만들게끔 개선할 부분들이 남아있지만 그래도 60%가 넘는 리텐션은 트레바리가 다시 올 만한 서비스라고 말해준다.온라인 트레바리는 사정이 다르다. 많은 사람이 방문하지만 금세 나가버린다. 지금의 트레바리 홈페이지는 트레바리가 뭐 하는 곳인지, 트레바리를 하면 어떤 사람이 될 수 있는지, 트레바리에서는 어떤 사람들을 만날 수 있는지 잘 알려주고 있지 않다. 미리 지인이나 미디어를 통해 트레바리의 매력을 알고 온 사람들만이 홈페이지를 샅샅이 뒤져본 후에나 어떤 곳인지를 엿볼 수 있다.이 불협화음을 잘 조율하는 일을 내가 잘 할 수 있겠다는 생각이 들었다. 나는 원래 작년 초까지 멤버였다가 트레바리 매력에 빠져 입사까지 하게 된 진성 유저였다. 덕분에 트레바리가 얼마나 좋은지, 어떻게 트레바리를 통해 예전보다 멋진 사람이 될 수 있는지, 트레바리에서 얼마나 좋은 사람들을 만날 수 있는지를 알고 있었다. 그리고 이것들을 동네방네 열심히 소문을 내고 싶은 사람이었다.트레바리 홈페이지가 오프라인 트레바리에 오기 위한 건널목이라면 건널목 입구에 삐까뻔쩍한 간판도 크게 달고, 안내판도 만들어 건널목 너머에 얼마나 멋진 곳이 있는지 넘어오고 싶게끔 기대감을 심어주고 싶다. 우리의 비전인 '세상을 더 지적으로 사람들을 더 친하게'처럼 내가 트레바리에 온다면 더 지적이고 멋진 사람이 될 수 있고, 사람들과 더 친하게 지낼 수 있음을 잘 설명해주고 싶었다. 사람은 자기가 정말 좋아하는 것을 설명할 때 지치지 않고 그 어느때보다 열심히 목소리를 높일 수 있다고 생각한다.물론 나 혼자서는 힘들 것이다. 그래서 다른 크루들과 같이 어떻게 잘 전달할 수 있을지 치열하게 고민해보기로 했다. 그 일례로 최근에 영훈님과 같이 사내 스터디를 시작했다. 이런 점들이 단순히 시키는 일만 해내는 프리랜서보다 훨씬 더 잘 쓰일 수 있는 크루로 만들어 줄 것이라고 믿는다. 아직 '그래서 구체적으로 어떻게?'까지는 고민을 끝마치지 못했지만, 드디어 어떤 방향으로 무슨 역할을 하는 사람인지를 결정하였다. 이 결정을 시작으로 올해는 '회사에 더 많은 기여를 할 수 있는 크루가 될 수 있지 않을까'하는 설렘과 '그러려면 훨씬 더 잘해야겠다'는 부담이 가득한 채로 일 년을 맞이하게 되었다.올 한 해 '세상을 더 지적으로 사람들을 더 친하게' 만들어줄 우리 크루들!#트레바리 #기업문화 #조직문화 #스타트업 #인사이트
조회수 2204

SaaS 와 On-Premises 장단점

와탭랩스는 SaaS 기반의 IT 모니터링 서비스로도 사용할 수 있지만 On-Premises 솔루션으로도 제공되기 때문에 고객과 대화할 때 SaaS와 On-Premises의 장단점에 대한 답을 드려야 할 때가 많습니다.어떻게 비교해야 할까. SaaS와 On-Premises를 비교하기 위해서는 도입 프로세스에서 운영까지의 지속되는 과정에서의 장단점들을 알아봐야 합니다. 많은 고객들이 SaaS를 설명드릴 때, TCO를 기반으로 하는 가격 비교를 하지만 이는 일부일 뿐입니다. Total cost of ownership (TCO) is a financial estimate intended to help buyers and owners determine the direct and indirect costs of a product or system. It is a management accounting concept that can be used in full cost accounting or even ecological economics where it includes social costs.----TCO시스템 또는 제품 구매시에 들어가는 모든 직간접 비용을 의미. 구매비용에서 운영비용은 물론 사회적 비용까지  모두 포함.왜 SaaS로 넘어가야 하나요?현대 조직은 효율적인 비용 구조에 대한 지속적인 압박을 받고 있습니다. 그렇기 때문에 많은 기업들이 IT 기반의 효율적인 기업 관리 시스템을 갖추어 나갔지만 역설적으로 IT 시스템들은 여전히 비싼 가격에 대규모 도입 방식을 사용해 왔습니다. 하지만 클라우드 시장이 만들어지면서 SaaS 시장이 빠르게 발전하고 있습니다. SaaS(Software-as-a- Service)는 공급자가 원격에서 솔루션을 제공하여 관리하는 인터넷 기반의 서비스를 의미합니다. 초기 SMB시장을 위주로 확장을 하던 SaaS 기반의 서비스는 이제 소규만을 위한 서비스가 아닙니다. 소규모 스타트업 뿐만이 아니라 많은 엔터프라이즈 기업들이 SaaS 서비스를 사용하고 있습니다. 낮은 도입 비용SaaS는 On-Premises 방식에 비해 도입 비용이 현저히 낮습니다. 기존 On-Premises의 비용의 많은 부분들이 채널, 컨설팅, 영업 관리 비용이 포함된 금액이였지만 SaaS 방식의 서비스들은 해당 솔루션 기능에 대한 비용만을 청구합니다. 더 이상 부가적인 비용 지출을 하지 않아도 됩니다. 또한 SaaS 기반의 서비스는 실무자가 직접 도입하고 사용해 볼 수 있기 때문에  POC없이 기업에 도입하고 구매 여부를 진행 할 수 있습니다.  POC (Proof Of Concept)기존에 시장에서 사용돼지 않던, 신기술을 프로젝트에 도입하기에 앞서, 검증하기 위한 목적으로 사용. 사업과 관계가 약간은 동떨어진 기술 검토를 위한 프로젝트고객사에서 하고, 업무는 아주 간단한 것을 수반. 신기술 여부는 중요치 않음낮은 TCOSaaS 솔루션은 유지보수 비용 부담이 없습니다. 업데이트에 요금을 부과하지 않으며 대규모 시스템 업데이트로 인한 부담도 존재하지 않습니다. 소프트웨어 구매시 발생하는 하드웨어 구매 비용으로부터 자유로우며 하드웨어를 유지 보수하거나 업데이트 해야 할 일도 없습니다. SaaS 솔루션은 구매비용(CAPEX) 운영비용(OPEX) 모두 절감할 수 있습니다. CAPEX미래의 이윤 창출을 위해 지출한 비용. 기업이 고정자산을 구매하거나, 유효수명이 당회계연도를 초과하는 기존의 고정자산 투자에 돈을사용할 때 발생.회사가 장비, 토지, 건물 등의 물질자산을 구입하거나 유지, 보수할 때 사용되는 비용.OPEX업무지출 또는 운영비용이라고도 하며 갖춰진 설비를 운영하는 데 드는 제반 비용을 의미. OPEX는 인건비, 재료비, 수선유지비와 같은 직접 비용과 제세공과금 등의 간접 비용으로 구성되어 있으며 통상 CAPEX와 함께 대조적으로 많이 쓰이는 용어.빠른 출시SaaS 솔루션은 이미 시장에 배포되는 과정에서 테스트가 완료되어 있습니다. 처음부터 적용하기가 쉬우며 업데이트도 번거롭지 않습니다. 기업은 최신 서비스를 바로 적용하여 더 높은 ROI를 만들어 낼 수 있습니다. 사용량 기반의 과금SaaS는 사용량 단위의 유동적인 과금이 가능합니다. 이는 반대로 대규모 도입후에 시스템이 줄어들게 되더라도 과금이 같이 줄어드는 장점을 가지고 있습니다. 낮은 위험도SaaS는 사용랑 기반의 과금과 쉬운 도입을 제공하기 때문에 On-Promises에 비해 솔루션 변경에 대한 위험도가 낮습니다. 솔루션 사용하기 위해 인프라스트럭처를 도입하지 않기  때문에 해지시에 사용하지 않는 인프라스트럭처가 존재할 위험에서도 빠져나갈 수 있습니다. SaaS 솔루션 도입시 고민해야 할 점SaaS 솔루션이 장점이 많은 구조이긴 하지만 아래와 같이 도입시 고민해야 하는 것들이 있습니다. 인터넷 의존성외부망을 열수 없는 환경에서는 사용할 수가 없습니다. 기업의 정책에 따라 기업의 인터넷 환경을 열수 없다면 SaaS 솔루션을 도입할 수 없습니다. 기업 내재화고객이 SI를 통해 자사를 위한 서비스를 요구하는 경우에 맞지 않습니다. 또는 데이터의 거주 위치에 대해 민감한 경우에도 문제가 될 수 있습니다. 클라우드가 대중화 되면서 데이터의 거주 위치는 실제로 의미가 없어지고 있습니다.On-Premises 솔루션을 도입하는 이유사내에 솔루션을 설치하는 On-Premises 방식은 IT 서비스와 함께 만들어진 방식이며 현재까지도 엔터프라이즈 규모의 기업들이 가장 좋아하는 방식입니다. 기업 내재화On-Premises 방식은 SI를 통한 기업 맞춤형 솔루션 제공이 가능합니다. 기업이 자사에 최적화된 방식으로 솔루션을 변경하여 사용함으로써 만족도를 높일 수 있습니다. 데이터 소유On-Premises 방식은 솔루션과 데이터가 모두 사내에 존재함니다. 외부망이 열려있지 않더라도 사내에서 데이터가 가공되고 처리되기 때문에 문제없이 사용할 수 있습니다.  On-Premises를 떠나는 이유클라우드의 도입과 함께 많은 엔터프라이즈 기업들이 아래의 이유로 On-Premises에서 SaaS로의 전환을 고민하고 있습니다. 비용On-premises의 높은 도입 비용에 대한 고민이 높아지고 있습니다. 특히 클라우드 생태계에서 노드락 라이센스는 의미가 없어지고 있습니다.노드락 라이선스별도의 라이선스 서버없이 해당 장비에서만 사용 가능한 라이선스입니다.플로팅 라이선스별도의 라이선스 서버를 구축하여 클라이언트 요청이 있을때 라이선스 서버에서 클라이언트로 라이선스를 할당하는 방식입니다.유지보수엔터프라이즈 기업은 자사의 수많은 솔루션들을 유지보수 하는 데 지쳐가고 있습니다. 솔루션 유지 보수 비용은 On-Premises 솔루션 가격에 포함되어 있는 경우도 있기 때문에 개개별로 관리하기도 어려운 부분이 있습니다. 점점 복잡해지는 IT 환경 속에서 기업은 유지보수에 대해 민감해지고 있습니다.On-Premises의 대안 Private SaaS SaaS와 On-Premises의 장점을 합친 방식으로 SaaS 솔루션 전체를 패키지로 제공하는 방식입니다. 와탭랩스의 경우 IT 모니터링 서비스 전체를 패키징하여 기업에 제공하고 있습니다. 엔터프라이즈 기업의 서비스 운영팀에 설치하고 기업 내부에서 서비스 방식으로 사용할 수 있습니다. 빌링까지 포함되어 있는 제품이기 때문에 사용량을 체크할 수 있으며 일반적으로는 년단위의 라이센스를 사용하게 됩니다.마무리SaaS와 On-Premises 솔루션을 비교한다면 SaaS가 미래의 솔루션이라고 할 수 있습니다. 하지만 Private 클라우드를 도입하고 외부에 망을 열지 않는 다면 On-Premises를 사용해야 합니다. 뿐만 아니라 와탭랩스의 경우처럼 SaaS 솔루션 전체를 On-Premises로 제공하는 기업들도 있기 때문에 On-Premises 시장도 줄어들지는 않을 것으로 예상되고 있습니다. #와탭랩스 #개발자 #개발팀 #인사이트 #경험공유 #일지
조회수 2183

비전공자를 위한개발자 되기 5 스텝

안녕하세요. 언제 어디서나 함께하는 코딩 교실 엘리스입니다 :)아이디어만 좋다면 뭐든 실현해볼 수 있는 시대! 지금은 '프로그래밍'이라는 강력한 무기를 통해 원하는 세계를 실현할 수 있는 잠재적 가능성이 폭발적인 때입니다. 그리고 그 기회는 비단 '개발자'라는 특정 직업에 국한하지 않더라도 각계 분야에 펼쳐져 있는데요. 이미 마케터, 기획자, 디자이너, 콘텐츠 창작자, 금융업계 종사자, 지리학자, 연구원 등 다양한 분야의 많은 사람들이 프로그래밍을 통해 각자의 영역과 세계 곳곳을 새로운 곳으로 만들고 있습니다.높은 급여와 삶의 질을 보장하고 나의 꿈을 펼칠 수 있는 탁월한 수단인 프로그래밍.프로그래밍을 업으로 삼고 있는 사람들의 시작은 어땠을까요?이 글에서는 소프트웨어 엔지니어가 되고자 이제 막 마음먹은 분들을 위해 프로그래머가 되기 위한 다섯 가지 짚고 넘어가면 좋을 팁들을 알려드릴게요.STEP 1. 개발 친화적인 환경 찾아가기서당개 삼 년이면 풍월을 읊는다컴퓨터 공학 전공자와 비전공자가 가지게 되는 가장 큰 차이는 무엇일까요? 개발에 대한 이론 지식? 개발 능력?물론 모든 게 상대적인 것이겠지만 일반적으로 한 가지 큰 차이가 있다면 바로 '환경'이라고 할 수 있을 듯합니다. 내 주변에 개발과 관련된 자원이 얼마나 풍부한가 하는 점입니다.전공자가 개발을 시작하고자 마음을 먹으면 주위에서 좋은 리소스를 쉽게 찾을 수 있습니다. 한편 비전공자는 개발 공부를 시작하려고 할 때 레퍼런스로 삼을만한 좋은 예가 없으니 망망대해에 홀로 떠있는 기분이 들 수밖에 없겠죠! 그렇다고 해서 반드시 컴퓨터 공학 전공에서부터 다시 시작하거나 고액의 학원에 다닐 필요는 없습니다. 먼저 개발과 관련된 인적, 물적 자원이 풍부한 곳으로 적극적으로 다가가보세요. 작은 환경의 변화가 큰 변화의 시작점이 될 수 있습니다.엘리스가 추천하는 방법!온라인 커뮤니티 활동하기 : 코딩과 관련된 페이스북 그룹에 가입하여 많은 정보를 접하고 질문도 하면서 활동해보세요. 나와 비슷한 상황인 사람을 만나 서로 도움을 주고받을 수도 있고, 내 롤모델이 될만한 훌륭한 개발자를 만나 공부의 동력이 될지도요!개발 동아리, 스터디 등에 참여하기★ 엘리스 코딩 클래스 활용하기 : PC로도, 모바일 앱으로도 언제 어디서든 프로그래밍을 위한 환경에 접속하세요! 엘리스에 로그인하는 것만으로 공부하기 위한 모든 리소스를 얻을 수 있을 뿐만 아니라 과목별 채팅방을 통해서 함께 공부하고 있는 수강생들, 과목 튜터와의 활발한 대화에 참여할 수 있습니다. STEP 2. 강력한 동기와 조력자 만들기하늘은 스스로 돕는 자를 돕는다컴퓨터 공학 전공자라고 하면 모두 다 개발을 잘할까요? 적어도 아주 조금은 더 잘할까요? 대답은 NO!아무리 많은 이론을 배웠다고 해도 직접 개발을 하지 않는다면 아무런 소용이 없겠지요. 이해도가 다르기 때문에 배움의 속도는 조금 다를 수도 있겠지만 이런 차이보다는 개인의 학습 의지와 동기가 얼마나 분명하냐가 더 중요합니다.막연하게 '개발자'라는 너무 먼 목표만 보고 달리는 것보다는 보다 가까이에 있고 달성하기 쉬운 분명한 목표를 단계별로 설정해보세요. 그리고 '즐거움'을 느낄 수 있는 수단을 찾아 목표 달성을 위한 집중력을 높이세요. 동시에 내가 어려움에 처하거나 헤매고 있을 때 도와줄 조력자가 있다면 금상첨화!Photo by Mimi Thian on Unsplash엘리스가 추천하는 방법!동기 부여를 위한 작은 목표 설정 : 지식 습득 및 학습과 관련된 목표로 그룹 스터디 참여, 부족한 부분의 프로그래밍 강의 완강, 책 한 권 떼기 등이 있을 수 있고, 더 적극적인 형태의 개발 경험을 위해 공모전, 경진 대회 등 기간과 보상이 정해져 있는 대외 활동 참가 및 수상도 좋은 목표가 될 수 있을 거예요.★ 엘리스 코딩 튜터 활용하기 : 엘리스에는 학습을 도와주는 튜터가 있습니다. 엘리스 튜터는 답을 알려주는 사람이 아니라 답을 찾는 법을 알려주는 길잡이입니다. 공부하다가 막힐 때, 길을 잃은 것 같을 때 엘리스 튜터를 멘토로 삼아 보세요! 구독 및 트랙 이용 시 담당 튜터가 배정되어 개인 채팅방을 통해 1:1 튜터링을 받을 수 있고, 클래스 수강 시 단체 채팅방을 통해 언제든 질문할 수 있습니다.STEP 3. 원하는 개발 분야 탐색해보기  콩 심은 데 콩 나고 팥 심은 데 팥 난다개발에는 아주 숱~한 다양한 분야가 있습니다. 그리고 그 분야에 따라 특성도, 익혀야 하는 언어와 기술도 천차만별인데요. 아래 몇 개의 개발 분야와 사용 언어 및 기술에 대해서 적었으니 참고해보세요. 그리고 이보다 더 다양한 개발의 세계를 탐색해보면서 흥미가 가는 분야가 있다면 구체적으로 검색하고 공부를 시작할 계획을 세워보세요.Photo by Victoriano Izquierdo on Unsplash잘 모르겠다 or 코알못이다파이썬은 분야를 막론하고 많은 분야에서 사용되며 익히기에 쉬워 처음 코딩을 시작하는 입문자에게 가장 적합한 언어 중 하나입니다. 개발 언어부터 접해보고 싶다면 파이썬 언어 학습에서 시작해보세요!웹 개발 '콩 심은 데 콩 나고~'라는 속담을 인용했지만, 사실 다양한 개발 영역의 많은 지식들이 서로 겹치는 부분도 있고, 어느 한 분야를 잘할 수 있을 때 다른 분야로 전향하거나 옮겨가는 일은 보다 수월할 수 있습니다. 개발의 시작을 보다 쉽게 하고 싶다면 웹 개발부터 접근해보세요. 공부할 수 있는 자원이 풍부하고 추후 다른 개발 분야로의 전향도 가능하기 때문이에요.프론트엔드프론트엔드 개발은 주로 웹 환경에서 사용자와 맞닿는 가시적인 부분을 개발하는 영역입니다. 사용자가 코드를 작성하지 않고도 컴퓨터에게 명령을 내리는 등의 의사소통을 그래픽적으로 쉽게 할 수 있도록 가시적으로 만들어주는 것이 바로 프론트엔드 개발자의 역할이라고 할 수 있는데요. 예를 들어 엘리스에 로그인하고 싶을 때 '로그인 버튼을 클릭'하여 쉽게 로그인할 수 있는 인터페이스도 프론트엔드에 해당합니다. * 익혀야 하는 기본기 : HTML, CSS, JavaScript* 좀 더 나아가서 : JavaScript의 프레임 워크인 React.js 또는 Vue.js 또는 Angular.js 백엔드/서버백엔드 개발은 웹 환경에서 보통 사용자에게는 보이지 않는 서버(컴퓨터) 단의 개발을 의미하며, 사용자가 웹 상에서 활동함으로 인해 쌓이는 데이터가 모이는 DB(Data Base)를 다루는 영역을 개발합니다.* 익혀야 하는 기본기데이터베이스에 대한 지식 : MariaDB, PostgreSQL, MongoDB 등. 서버 쪽의 언어- 금융, 제약 등 전통적인 대기업 : Java의 프레임 워크인 Spring을 많이 사용- 과거 많이 쓰이던 기술 : Php(학습 속도와 개발 속도가 빠르며 무료!)를 많이 사용- 요즘 떠오르는 기술 : Python 기반 프레임 워크인 Django 또는 Flask. JavaScript의 프레임 워크인 Node.js* 좀 더 나아가서 : 클라우드 컴퓨팅 기술 Amazon AWS 또는 Azure에 대한 지식데이터 사이언스 - 데이터 분석가21세기에 가장 각광받는 직업 중 하나로 떠오른 '데이터 사이언티스트'에 대해서 모두 다 한 번쯤은 들어보셨을 거예요. 데이터 사이언스 분야에도 아주 복잡하고 다양한 영역들이 존재하는데요. 통상 데이터 사이언스라고 하면 수학 및 통계에 대한 지식, 컴퓨터 공학에 대한 지식, 인공지능 및 머신러닝과 관련된 기술을 사용하게 됩니다. 너무 많아 보이나요? 아래에는 데이터 사이언스의 많은 영역 중에서도 '데이터 분석가'로서 꼭 알아야 하는 내용을 적었습니다.* 익혀야 하는 기본기수학적 지식 : 통계, 선형대수학분석을 위한 언어 : Python, R* 좀 더 나아가서 : 머신러닝 기술임베디드 개발계산기, 에어컨, 자동차 등의 기계가 일정 기능을 컴퓨터처럼 수행할 수 있도록 기계 내부의 하드웨어 시스템을 구축하는 것이 임베디드 개발입니다. 사물 인터넷(IoT, Internet of Things)이나 하드웨어 부품과 관련된 분야에 관심이 간다면 임베디드 개발에 대해서 좀 더 알아보세요!* 익혀야 하는 기본기임베디드 개발 언어- 가장 많이 사용하는 언어 : C언어 - 국내 전통적인 대기업 : Java- 수요가 많은 언어 : Python (임베디드 분야에서도 빠지지 않고 자주 사용하는 언어! 국내 채용 사이트에서 임베디드 관련 개발 스택으로 많이 요구.)* 좀 더 나아가서 : 무선 통신 기술에 대한 지식*(공통) 개발자라면 익히고 있어야 할 기본기 : Git을 사용한 버전 관리 방법엘리스가 추천하는 실습 기반 과목HTML/CSS | JavaScript | 모바일 웹 코딩Git과 Git 버전 관리 (6월 오픈 예정)Python 기초 I | Python 기초 IIC 언어 | C++Java 기초 및 심화인공지능/머신러닝 기초 | 프로그래밍 수학데이터 분석 | Numpy, Pandas | 크롤링 | Kaggle 문제R 기초 |  R 패키지 | R 데이터 분석STEP 4. 실습, 프로젝트 기반으로 공부하고 개발 경험 쌓기구슬이 서 말이어도 꿰어야 보배다책을 사고 인강을 결제해도 직접 만들어보면서 익히지 않으면 절대 내 것이 될 수 없는 것이 또 개발!처음 언어를 익히는 단계에서부터 실습 기반으로 직접 코딩하고 그 결과를 확인해보면서 학습하는 것이 중요해요! 필요한 공부를 실습 단위로 쪼개어 직접 구현해보면서 익히고, 좀 더 나아가서는 프로젝트 단위로 구현하면서 실전 기술을 습득해보세요. 또한 실무에서는 혼자 개발하는 것이 아니라 뭐든 '협업'해야 하기 때문에 혼자 하는 프로젝트 외에도 여러 사람들과 함께하는 그룹 프로젝트의 경험이 큰 도움이 될 거예요. 자기소개서, 포트폴리오, 면접 시에도 어떤 프로젝트에서 내가 맡은 부분은 어느 부분이었고 어떻게 주도적으로 이끌었는지가 관건이 될 수 있습니다.엘리스가 추천하는 방법!★ 온라인 코딩 실습으로 기본기 다지기 : 엘리스는 별도의 코딩 환경 세팅 없이 온라인에서 바로 코딩 문제를 풀고 내가 짠 코드의 결과를 확인할 수 있어서 실습 기반으로 학습하기에 탁월한 플랫폼입니다. :) KAIST, SKT, 삼성 SDS 등에서도 활용하는 검증된 플랫폼에서 코딩 실습으로 기본기를 다지세요!프로젝트 단위로 혼자서 만들어보기 : 프로그래밍 언어의 기본에 익숙해졌다면, 직접 A to Z를 구현하는 작은 프로젝트를 통해 실제 필요한 기술이 뭔지 파악해가며 실전 기술을 익혀보세요. 그룹 프로젝트에 참여해서 협업 경험을 통해 익히기 : 취업을 위해서 중요한 것 중 하나인 '협업'능력! 그룹 프로젝트에 참여하여 비단 개발 실력뿐만 아니라 실무에 필요한 다양한 역량 또한 길러보세요.STEP 5. 포트폴리오, 시험 준비하고 개발 직군에 지원하기시작이 반, 그 이상이다!아시겠지만 개발자가 되면 끝인 그런 일은 없겠죠. (어떤 직무에서도 마찬가지일 거예요.) 끊임없는 공부, 새로운 기술 연마, 리팩토링, 문서화, 코딩 공부 코딩 공부!그러니 완벽에서 시작해야 한다는 생각은 버리고 지금까지 최선을 다해온 결과물을 가지고서 개발 직군에 지원하세요. 실제 개발자로 일하게 되면 그 속에서 배우고 성장할 수 있는 자원이 훨씬 더 많아집니다!'자리가 사람을 만든다'라는 말이 괜한 말이 아니니, 더 큰 성장과 가능성이 있는 곳으로 가기 위한 준비와 지원을 주저 없이 해보시길 바라요!Photo by Green Chameleon on Unsplash엘리스가 추천하는 방법!나를 잘 보여줄 포트폴리오 만들기 : (사용한 언어 / 프레임 워크 / 앞의 것을 적용하여 프로젝트에서 내가 한 역할) 별로 정리해두고 내가 커밋한 코드와 함께 보여주기.   블로그 쓰기 : 거창한 것이 아니어도 좋으니 공부하면서 느꼈던 것, 새로 알게 된 지식들, 프로젝트하면서 고민했던 것들을 블로그로 정리해보세요. 내가 구현한 것들을 이미지를 통해서 가시적으로 보여줄 수 있다면 금상첨화!★ 엘리스에서 알고리즘 시험 준비하기 : 이미 많은 수강생 분들이 엘리스 알고리즘 과목을 통해서 코드를 발전시키고 알고리즘 시험 및 취업에 성공하고 있습니다. :) 대기업 입사를 준비하시는 분이라면 엘리스 알고리즘 과목들을 꼭 수강해보세요.이다음의 6번째 스텝은 무엇이 될까요? 아마도 1~5 스텝을 계속 반복해나가면서 익숙해지고, 다른 역할로 각각의 스텝에 참여하게 되는 일이 아닐까요.엘리스는 누구나 프로그래밍을 통해 원하는 일을 할 수 있도록 좋은 강의 콘텐츠와 서비스, 플랫폼으로 여러분의 다섯 스텝에 함께하고자 합니다. :) 막막한 초심자 분들에게 앞으로의 방향성을 그려보는 데에 조금이라도 도움이 되길 바라며 글을 발행합니다.그럼 엘리스에서 만나요! >> 엘리스 아카데미 바로가기* 이밖에 조언, 첨언, 질문 등을 댓글로 남겨주시면 이 글의 독자분들에게 큰 도움이 됩니다.
조회수 1362

레진 기술 블로그 - Kotlin의 빛과 그림자

핀터레스트의 안드로이드 개발팀이 코틀린을 도입하면서 겪은 어려움과 해결책을 소개한 The Case Against Kotlin을 foot번역하고 자의적으로 해석하고 요약했습니다. 저자 라이언 쿡(Ryan Cooke)은 현재 코틀린이 가트너의 하이프 사이클에서 “뻥튀기된 기대감의 산(Peak of Inflated Expectations)” 쯤에 있다고 말합니다. 레진시 개발동에서는 이미 코틀린을 부분적으로 도입했고, 현재는 범위를 넓혀가는 중인데요… 정말 괜찮은 걸까요?문제: 학습 곡선자바 개발자로서 문법에 익숙해지는 데 1주일 정도 걸립니다.코틀린을 이미 잘하는 사람이 없으면 베스트 프랙티스들을 찾아보면서 해야하는 데 시간이 듭니다.코틀린 사용을 가속화 시키는 데 팀 트레이닝을 계속 해야합니다. -> 기회비용 많이 듭니다.하기 싫어 하는 사람도 있고…혼자서 알아서 잘 배우는 사람도 있고…해결책: 학습 곡선코틀린은 아직 말년병장성숙한 언어가 아닙니다! 지금도 자라나고 있습니다! 그게 제일 무서워..책도 있고 인터넷 리소스도 있지만, 코틀린 신봉자가 하나 있어서 다 가르쳐주는 게 짱입니다.필자가 코틀린을 하고 싶었던 이유는 생산성인데요, 동료들 중에는 그렇게 느꼈던 사람들이 많지 않은 것 같습니다. 정착이 되면 보이겠죠.문제: 빌드 속도Gradle 빌드 속도는 보통 30초, 클린 빌드는 75초 까지 걸립니다.코틀린은 보통 빌드 속도의 25%, 클린 빌드의 40% 밖에 안나옵니다.해결책: 빌드 속도알아서 하셈 ㅋ코틀린 파일 하나 변환 -> 클린 빌드 시 조금 시간이 더 걸립니다. 파일을 많이 변환할수록 느려지긴 하지만 체감하긴 어렵습니다.보통 빌드할 때는 코틀린 파일 많아도 상관 없습니다.결론: 클린 빌드할 때 느려진다는 걸 체감할 겁니다.문제: 개발 안정성코틀린의 문법이나 특성이 문제가 아니라, 코드를 생산성 있게 작성하는 자신을 막는 새로운 문제들 때문이라고 생각합니다.사실 그냥 코틀린 배우기 싫은 거 같아요.예를 들면, 코틀린 애노테이션 프로세서 툴(kapt) 때문에 빌드가 안 되고, 무조건 클린 빌드로만 개발을 했던 적이 있습니다.이거… 코틀린 때문 아니야?!?!?! 하는 의심들 많았죠.고치느라 시간이 많이 흘렀습니다.또 어떤 문제가 튀어나올지에 대한 두려움이 커지네요.해결책: 개발 안정성그냥 IDE 나 언어의 stable 버전만 업데이트 하세요.안정된 버전들만 사용하면 그나마 힘든 일 없을거예요.정말?문제: 정적 분석FindBugs, PMD, Error Prone, Checkstyles and LintJava 는 이와 같은 툴들로 인해 Code Review에 쓸데없는 걸 줄이거나 룰을 적용할 수 있는데,코틀린에는… 이런 게 없… 분석을 위한 게 아직… 없습니다… 사람들이 알아서 다 찾아야 합니다.해결책: 정적 분석그냥 손가락빨고 기다려야 합니다. 아니면, 직접 만드세요!문제: 나 돌아갈래~돌아가기 쉽지 않습니다. 자바를 코틀린으로 옮기기에는 쉬운데, 반대는… 어렵습니다!코드가 깨지고, 변수명부터, 이런 저런 부분들을 다시 구현해야합니다.코틀린스럽거나, 코틀린의 고유한 기능들을 사용했다면, 여기서부터 헬이죠.해결책: 나 돌아갈래~되돌아오는 건 쉽지 않기 때문에 잘 생각해야 합니다.유닛 테스트가 정말 잘 된 파일들부터 바꾸세요.간단하고 재사용 가능한 잘 모듈화된 파일들을 먼저 바꾸세요.결론이 글은 고려해야 할 리스크에 대해서 나열했습니다.단점들은 구글과 젯브레인과 스택오버플로우가 차차 해결해 줄 겁니다.TL;DR 코틀린으로 작성하는 건 쉽지만, 되돌리기는 어렵습니다.그래서 말인데… 레진코믹스에서 코틀린 삽질을 함께 할 개발자를 모십니다!

기업문화 엿볼 때, 더팀스

로그인

/