3/24/2017

외적 동기와 내적 동기

 


내적 동기란, 활동 자체에서 오는 만족과 즐거움 때문에 행동을 수반하는 능동적인 힘을 의미하며 외적 동기란, 활동을 함으로써 받게 되는 칭찬이나 상 때문에 행동을 수반하게 하는 수동적인 힘을 의미합니다.

일반적으로 회사에서는 인센티브(성과급)을 매개체로 직원들이 성과를 내도록 외적 동기를 부여합니다. 하지만, 이 보다 더 중요한 것은 일 그자체에서 오는 내적 동기를 부여하는 것이라고 생각합니다. 자신에게 선택권이 있으며 관련 기술과 지식을 갖추고 목표를 향해 나아가고 있다라는 느낌을 받을 때 열정적으로 일하게 되며, 이것이 내적 동기를 부여하는 것이라고 생각됩니다.

3/10/2017

Best To-Do List 서비스

처음 사회 생활을 시작할 때 부터 업무 향상을 위해 여러 방법을 고민했었고, 그 중에 주로 사용해왔던 방법이 GTD(Getting Things Done) 였다. 얼마전까지 프로젝트내의 task관리 및 협업을 위해 아래에 언급된 서비스를 이용했다.

  • Task 관리: Trello, Asana
  • Communication: Slack, Glip

Task 관리 서비스들을 이용하면서 내가 느낀 사항들을 정리해보고자 한다. Trello와 Asana의 경우에는 UI가 직관적이다. 특히 Asana는 List 방식과 Beta 이긴 하지만, Trello와 같은 Kanban을 지원하기도 한다. 위 두 서비스를 사용하면서 느낀 부족한 점은

  • One level Task 관리: Trello와 Asana는 One level의 Task관리를 지원한다. 물론 하나의 Task내에서 Sub task를 생성할 수 있지만, 직관적으로 한눈에 파악하긴 어려웠다. Sub task까지 포함해서 Two level 이하의 Task 관리는 지원하지 않는다.
  • 직관적인 Kanban 이지만…, : Task를 생성할 때, 내가 해야 할 마우스 액션이 너무 귀찮았다. 물론 Asana의 List 방식에서는 큰 문제가 없었지만 Two level 이하는 지원하지 않기에…
  • Outliner의 부재 : 위의 두 서비스에서는 Outliner를 지원하지 않는다. 물론 당연한 이야기이다. Task관리는 두 서비스를 이용하면서 Outliner는 Workflowy를 이용하는 방법도 있지만, 점점 관리해야 하는 서비스가 늘어나는 느낌이 들었다.

Outliner 방식을 지원하면서 Task관리를 할 수 있는 서비스가 있을까? 그래서 찾아봤다.

Workflowy

Outlines내에서 Deep level의 depth를 지원한다. 그리고 가장 유명한 서비스이다. 하지만 Document를 분리하여 관리하는 기능 부재로 인해 고려 대상에서 제외하였다.

Checkvist

Outlines내에서 Deep level의 depth를 지원하지만, 세련된 UX/UI가 오히려 나에겐 부담으로 다가왔다. iOS application을 아직 지원하지 않는다.

Dynalist

Outlines내에서 Deep level의 depth 지원 및 Folder/Document 관리 기능, Google Calendar sync 기능등 부족함이 없었다. 다만, iOS application을 현재 개발중이고 Checkbox가 항상 보이는 부분이 UI를 clunky하게 만든다.

Moo.do

Multi-level을 지원하고, Document 관리 기능 (Folder는 미지원, 이 부분이 아쉽다.) Google Calendar sync 기능, Gmail 연동 기능, Google Drive 연동 기능 그리고 iOS application 지원까지… 그리고 Checkbox에 대한 처리가 마음에 든다. 현재로써는 부족함이 없어 보인다. 결론은 Dynalist와 Moo.do 두가지중에 고민중이다. Moo.do가 가장 완벽한 기능을 제공해주고 있긴 하지만, Dynalist가 Trello에 생성한 Roadmap 보드를 보니 발빠르게 지원을 해줄 것 같은 느낌과 Moo.do에 비해 화면에 집중할 수 있는 UI 구성등이 끌린다.

당분간, 계속 고민을 할 것 같다.

12/17/2016

MSA(Microservices Architecture)의 장점과 단점

 

마이크로 서비스는 대규모 소프트웨어 프로젝트를 마이크로 단위의 모듈로 분리하여 loosely-coupled한 구조로 만들고 API를 통해 서로 통신합니다.

지난 몇 년동안 마이크로 서비스에 대해서 많은 이야기가 있었습니다. 모듈형 아키텍처 스타일은 클라우드 기반 환경에 적합하며 인기가 높아지고 있습니다.

마이크로 서비스는 대형 소프트웨어 프로젝트의 기능들을 작고 독립적이며 느슨하게 결합 된 모듈로 분해하여 서비스를 제공하는 아키텍처 입니다.

각 개별 모듈은 개별적인 작업을 담당하며 간단하고 보편적으로 엑세스 할 수 있는 API를 통해 다른 모듈과 통신 합니다.

마이크로 서비스는 웹 기반의 복잡한 응용 프로그램을 설계하기 위한 또 다른 아키텍처입니다. 일반적으로 SOA(Service Oriented Architecture)와 비슷하게 바라보는 시각도 존재합니다만 엄연히 다른 아키텍처입니다.

그렇다면 SOA와 같은 기존 아키텍처의 문제점은 무엇일까요?

Java를 사용하여 기존 웹 프로그램을 만든다고 가정합시다. 가장 먼저 해야 할 일은 presentation layer (사용자 인터페이스)를 디자인을 하고 Business logic을 처리하는 Application layer와 구성 요소 간의 느슨한 결합을 가능하게 하는 Integration layer 그리고 마지막으로 데이터에 접근이가능하도록 Persistence layer를 디자인 하고 구현해야 합니다.

어플리케이션을 구동하기 위해 war or ear 패키지를 생성하고 이를 Tomcat or JBoss와 같은 Application server에 배포합니다. 모든 모듈이 war or ear로 패키징 되었기에 우리는 이것을 Monolithic이라고 부릅니다. 다시 말해서 별도의 구현 가능한 구성 요소가 존재해도 모두 하나의 지붕 아래에 패키징되어 있습니다. 아래의 그림을 참조하세요.


Monolithic 아키텍처: challenges

  • 어플리케이션이 커질 수록 코드도 방대해지고 로드시에 IDE에 과부하가 걸릴 수 있습니다. 이런 부분은 개발자의 생산성을 저하시키는 요인이 됩니다.
  • 하나의 war or ear에 모든 것을 포함하였기에 어플리케이션의 기술 스택을 변경하는 것을 주저하게 됩니다. 예를 들어서 일부 컴포넌트는 JVM내에서 동작하는 Groovy나 Scala와 같은 다른 언어를 사용하여 처리하려고 할 경우 이런 종류의 아키텍처를 사용하면 어떤 side-effect가 발생 할지 예측이 어려우므로 리펙토링을 해야 하지만 코드가 너무 방대해서 리펙토링을 하기가 어렵습니다.
  • 어플리케이션내의 특정 기능이 실패하면 전체 어플리케이션에 영향을 미칩니다. 그리고 퍼포먼스가 나쁜 특정 함수/메소드의 영향이 전체 어플리케이션에 고통을 주게 됩니다.
  • 이런 아키텍처에서의 scaling은 서버마다 동일한 war or ear을 배포하여 수행해야 합니다. 각각 서버는 동일한 리소스를 사용하게 되므로 이 것은 효율적인 방법이 아닙니다.
  • 어플리케이션이 커질수록 개발자는 작은 단위로 작업을 축소할 수 있어야 합니다. Monolithic은 모든 것이 하나로 묶여 있기 때문에 개발자가 독립적으로 모듈을 개발하고 배포 할 수 없습니다. 그리고 개발은 협업으로 진행되므로 다른 개발자에 의존성때문에 개발 시간이 길어지게 됩니다.

위의 언급한 내용을 염두하고 마이크로 서비스에 대해서 알아보겠습니다.

마이크로 서비스

아키텍처의 중요한 포인트는 바로 확장성입니다. 많은 사람들이 확장성을 얘기 할 때는 The Art of Scalability라는 책을 인용합니다. 이 책에서는 Scaling을 세 가지로 정의합니다.


X 축은 horizontal(수평) application scaling (Monolithic 아키텍처에서도 가능)을 나타내며, Z축은 비슷한 것들을 분할하여 어플리케이션을 스케일링함을 의미합니다. (Z축은 데이터를 분할하여 사용자의 요청에 따라 해당 샤드에 redirect하는 샤딩 개념으로 이해하면 됩니다.)

Y축이 가장 중요하고 우리가 눈여겨 봐야할 대상입니다. 이 축은 기능적인 분해(해체)를 의미합니다. Monolithic에 포함되어 있는 다양한 기능을 독립적인 서비스로 바라보는 전략을 취합니다. 따라서 모든 기능을 전체 어플리케이션에 배포하지 않고 각각 서비스를 독립적으로 배포 할 수 있습니다.

이렇게 하면 개발자의 생산성이 향상되고 기능 변경시 side-effect 걱정 없이 변경하고 배포 할 수 있는 유연성을 제공합니다.

예전 Monolithic 방식과 비교해보세요.


마이크로 서비스의 장점

벤더사 중심의 SOA에 비해서 마이크로서비스는 Amazon, Netflix, eBay와 같은 글로벌 서비스 플레이어가 사용할 만큼 강력합니다.

Improves fault isolation : 단일 모듈의 장애에 대해 전체 어플리케이션은 크게 영향을 받지 않습니다.

Eliminates long-term commitment to a single technology stack : 각 개별 서비스에서 새로운 기술 스택을 시험하고자 한다면 바로 시작할 수 있습니다. 의존 관계가 기존 Monolithic 아키텍처보다 적고 유연합니다.

기능 단위로 서비스가 되기에 새로 조인한 개발자가 기능을 더 쉽게 이해 할 수 있습니다.

마이크로 서비스의 배포 및 가상화

마이크로 서비스기반의 어플리케이션을 배포하는 가장 좋은 방법은 컨테이너 가상화를 이용하는 것입니다. (Docker)

AWS와 같은 IaaS업체의 VM을 이용하여 마이크로 서비스를 배포할 수 있지만 작은 단위의 마이크로 서비스는 VM의 리소스를 전부 활용 하지 못해 비용 효율성을 저하 시킬 수 있습니다. 따라서 컨테이너 기반으로 배포를 하는 것이 유리합니다.

OSGI(Open Service Gateway Initiative) 번들을 사용하여 코드를 배포 할 수도 있지만, 이 경우에는 management and isolation tradeoff와 관련된 단점이 존재합니다.

마이크로 서비스의 약점

아래는 마이크로 서비스 설계와 관련된 잠재적인 약점에 대한 부분입니다.

  • 분산 시스템 개발은 일반 개발보다 복잡합니다. 모든 것이 독립적인 서비스이기 때문에 각 모듈간의 인터페이스를 신중하게 처리 해야 합니다. 서비스중 하나가 응답하지 않게 될 경우에 대한 방어코드도 작성해야 합니다. 호출 대기 시간이 발생하게 되면 복잡한 상황이 발생할 수 있습니다.
  • Multiple Databases 및 트랜젝션 관리가 어려울 수 있습니다.
  • 마이크로 서비스 기반의 어플리케이션을 테스트하는 것은 번거로울 수 있습니다. 테스트를 시작하기 전에 의존성이 있는 서비스를 미리 확인해야 합니다.
  • 마이크로 서비스의 배포는 복잡 할 수 있습니다. 각 서비스 간의 조정이 필요 할 수 있습니다.

하지만, 이런 부분들은 자동화 도구를 사용하면 해결 할 수 있습니다.

끝으로, 마이크로 서비스는 벤더사 중심이 아닌 서비스사 중심의 아키텍처이고 이미 글로벌 플레이어에 의해 검증이 되어 있습니다.

하지만, 좋은 아키텍처도 상황과 사람에 의해 달라지게 됩니다.

마이크로 서비스 아키텍처를 경험했거나 경험할 계획이 있으신가요?

참조

  • http://cloudacademy.com/blog/microservices-architecture-challenge-advantage-drawback/

12/16/2016

Java class를 Python에서 사용하기

프로젝트내에서 만든 Java Util class를 Python에서 사용해야 하는 케이스가 발생했다. py4j, jnius, subprocess .., 등등의 방법이 있었다.

py4j

GatewayConnection 방식으로 진행하기에 내부적으로 socket을 사용함. Fault 발생 여지가 있어서 부적절하다고 판단

jnius

Java class를 수행전에 JVM을 start 해야하고 종료시 shutdown 해야 함. Fault 발생 여지가 있어서 부적절하다고 판단

subprocess

os command를 수행하는 방법, 별도의 package를 설치하지 않아도 되고, 위의 package에 비해 fault 발생 여지가 작다고 판단 아래는 샘플 코드 jar파일은 executable jar여야 한다.

python 2.7

import subprocess
def call(value):
cmd = ['java','-jar','{jar 파일 경로}','{arg}',value]
return subprocess.check_output(cmd,shell=False)
def main():
result = call("test")
print "result
if __name__ == "__main__":
main()

python 2.7/2.6

import subprocess
def call(value):
cmd = ['java','-jar','{jar 파일 경로}','{arg}',value]
fd_open = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=False).stdout
result = fd_open.read().strip()
fd_open.close()
return result
def main():
result = call("test")
print result
if __name__ == "__main__":
main()