Maven vs Gradle

스프링 기반의 프로젝트를 시작하면서 Maven을 처음 접했다.

Ant를 사용한적도 없었고 의존성 관리와 빌드 스크립트에 대한 지식도 없었기에 이런게 있나보다 하고 사용했었다.

Maven 책을 한권 보고나서야 프로젝트 구성, 빌드툴이 무었인지 이해할 수 있었고, 편리한 의존성 관리에 감사하며 부족함을 느끼지 못했다.

하지만 프로젝트의 단위가 커지면서 빌드와 테스트에 소요되는 시간이 길어졌고,

여러 모듈에서 설정을 상속받기 시작하면서 Gradle이라는 녀석이 계속 눈에 뛰었다.

Gradle이 Maven의 단점을 보완해주고 사용해본 사람들이 좋다고들 하니 Maven이랑 비교해서 얼마나 좋은지 알아보려 한다.

Maven

Apache의 이름 아래 2004년 출시

Ant를 사용하던 개발자들의 불편함을 해소 + 부가기능 추가

Maven은 무엇인가?

  • 빌드를 쉽게 (Making the build process easy)
  • pom.xml을 이용한 정형화된 빌드 시스템 (Providing a uniform build system)
  • 뛰어난 프로젝트 정보 제공 (Providing quality project information_
    • Change log document created directly from source control
    • Cross referenced sources
    • Mailing lists
    • Dependency list
    • Unit test reports including coverage
  • 개발 가이드 라인 제공 (Providing guidelines for best practices development)
    • Keeping your test source code in a separate, but parallel source tree
    • Using test case naming conventions to locate and execute tests
    • Have test cases setup their environment and don’t rely on customizing the build for test preparation.
  • 새로운 기능을 쉽게 설치할 수 있고 업데이트할 수 있음 (Allowing transparent migration to new features)

Gradle

Ant와 Maven의 장점을 모아모아 2012년 출시

Android OS의 빌드 도구로 채택 됨

Gradle이란 무엇인가?

  • Ant처럼 유연한 범용 빌드 도구 (A very flexible general purpose build tool like Ant.)
  • Maven을 사용할 수 있는 변환 가능 컨벤션 프레임 워크 (Switchable, build-by-convention frameworks a la Maven. But we never lock you in!)
  • 멀티 프로젝트에 사용하기 좋음 (Very powerful support for multi-project builds.)
  • Apache Ivy에 기반한 강력한 의존성 관리 (Very powerful dependency management (based on Apache Ivy))
  • Maven과 Ivy 레파지토리 완전 지원 (Full support for your existing Maven or Ivy repository infrastructure.)
  • 원격 저장소나, pom, ivy 파일 없이 연결되는 의존성 관리 지원
    (Support for transitive dependency management without the need for remote repositories or pom.xml and ivy.xml files.)
  • 그루비 문법 사용 (Groovy build scripts.)
  • 빌드를 설명하는 풍부한 도메인 모델 (A rich domain model for describing your build.)

Maven VS Gradle

Maven에는 gradle과 비교 문서가 없지만, gradle에는 비교문서가 존재. (비교에 자신있는 모습 ..ㅋ)

Gradle이 시기적으로 늦게 나온만큼 사용성, 성능 등 비교적 뛰어난 스펙을 가지고있다.

Gradle이 Maven보다 좋은점

  • Build라는 동적인 요소를 XML로 정의하기에는 어려운 부분이 많다.
    • 설정 내용이 길어지고 가독성 떨어짐
    • 의존관계가 복잡한 프로젝트 설정하기에 부적절
    • 상속구조를 이용한 멀티 모듈 구현
    • 특정 설정을 소수의 모듈에서 공유하기 위해서는 부모 프로젝트를 생성하여 상속하게 해야 함 (상속의 단점 생김)
  • Gradle은 Groovy를 사용하기 때문에, 동적인 빌드는 Groovy 스크립트로 플러그인을 호출하거나 직접 코드를 짜면 된다.
    • Configuration Injection 방식을 사용해서 공통 모듈을 상속해서 사용하는 단점을 커버했다.
    • 설정 주입 시 프로젝트의 조건을 체크할 수 있어서 프로젝트별로 주입되는 설정을 다르게 할 수 있다.

 

Gradle vs Maven: Performance Comparison

  • 600명의 엔지니어가 1년동안 1분걸리는 빌드를 매주 42번 빌드를 진행할 때 들어가는 비용은
    600 engineers * $1.42/minutes * 42 builds/week * 44 work weeks/year = $1,600,000/year
    이때 빌드 속도가 90% 빨라진다면?
  • Gradle은 메이븐 보다 최대 100배 빠르다.
  • 어떻게?
    • the Gradle Daemon is a long-lived process that keeps build information “hot” in memory
    • incremental task inputs and outputs for various types of tasks makes it unnecessary to run clean ever again
    • incremental compilation analyzes the dependencies between your sources and classes and recompiles only those which are affected by changes
    • the build cache fetches results from a cache when switching branches or running a clean build and the same output has already been produced somewhere else in the organization.
    • Gradle’s smart classpath analyzer avoids unnecessary compilation when the binary interface of a library hasn’t changed
    • better modelling of dependencies using the Java Library plugin reduces the size of the compile classpath which has a large, positive impact on performance

예제

스프링부트를 이용하여 같은 기능과 라이브러리 의존성을 가지는 Maven, Gradle 프로젝트를 생성해 보았다. (Java 1.8, Spring Boot 1.5.4)

  1. 스크립트 길이와 가독성 면에서 Gradle(groovy)이  앞선다.
  2. 빌드와 테스트 실행 결과 Gradle이 더 빠르다. (Gradle이 캐시를 사용하기 때문에 테스트 반복 시 차이가 더 커진다.)
  3. 의존성이 늘어날 수록 성능과 스크립트 품질의 차이가 심해질 것이다.
Maven
<?
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>demo-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>demo-maven</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


</project>
Gradle
buildscript {
ext {
springBootVersion = '1.5.4.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
mavenCentral()
}


dependencies {
compile('org.springframework.boot:spring-boot-starter')
testCompile('org.springframework.boot:spring-boot-starter-test')
}

결론

지금 시점에서 Gradle을 사용하지 않을 이유는 '익숙함' 뿐인 것 같다.

Gradle이 출시되었을 때에는 Maven이 지원하는 Scope를 지원하지 않았고 성능면에서도 앞설것이 없었다.

Ant의 유연한 구조적 장점과 Maven의 편리한 의존성 관리 기능을 합쳐놓은 것만으로도 많은 인기를 얻었던 Gradle은 버전이 올라가며 성능이라는 장점까지 더해지면서 대세가 되었다.

 

물론 그동안 사용해왔던 Maven과 이제는 익숙해진 XML을 버리고 Gradle과 Groovy문법을 배우는 것은 적지않은 비용이 든다.

특히 협업을 하는 경우, 프로젝트 구성과 빌드만을 위해 모든 팀원이 Groovy 문법을 익여야 한다는 사실은 Gradle를 사용하는데 큰 걸림돌이 된다.

실제로 여전히 Maven의 사용률은 Gradle을 앞서고 있으며 구글 트랜드 지수도 Maven이 Gradle을 앞선다.

 

협업과 러닝커브를 고려하여 여전이 Maven를 사용하는 팀이 많고 부족함 없이 잘 사용하고 있지만,

앞서 요약했듯 프로젝트의 빌드타임이 비용문제로 이어질 경우 Gradle을 사용해야 할 것 같다.

리드미컬?하게 테스트를 진행하고 민첩한? 지속적 배포를 생각하고 있다면 새로움 배움이 필요하더라도 Gradle을 사용해보자. 아자.

 

출처

Nginx는 컴파일된 바이너리를 제공하지 않는다.

apt-get이나 yum을 통해 설치하면 설정 관리나, 이중화같은 작업이 어렵기 때문에 컴파일 설치를 선호하는 편이다.

2017년 6월 23일 기준 최신 Stable version인 nginx-1.12.0 버전 설치 스크립트를 아래 작성했다.

 

설치 기준 위치는 /home/username/apps/ 로 한다.

 

1. NGINX 다운로드

cd /home/username/apps/
wget https://nginx.org/download/nginx-1.12.0.tar.gz
tar -xvf nginx-1.12.0.tar.gz
rm nginx-1.12.0.tar.gz

2. PCRE 다운로드

cd /home/username/apps/nginx-1.12.0
wget http://downloads.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz
tar -zxf pcre-8.37.tar.gz

3. zlib 다운로드

cd /home/username/apps/nginx-1.12.0
wget http://zlib.net/zlib-1.2.11.tar.gz
tar -zxf zlib-1.2.11.tar.gz

4. OpenSSL 다운로드

cd /home/username/apps/nginx-1.12.0
wget http://www.openssl.org/source/openssl-1.0.2f.tar.gz
tar -zxf openssl-1.0.2f.tar.gz

5. NGINX 설치

cd /home/username/apps/nginx-1.12.0
./configure --prefix=/home/username/apps/nginx --with-zlib=./zlib-1.2.11 --with-pcre=./pcre-8.37 --with-openssl=./openssl-1.0.2f --with-http_ssl_module --with-http_stub_status_module
make install
cd /home/username/apps/
rm -rf nginx-1.12.0

6. 실행권한 설정

cd /home/username/apps/nginx/sbin
sudo chown root nginx
sudo chmod +s nginx

7. 실행 및 테스트

cd /home/username/apps/nginx/sbin
./nginx //시작
//포트 80 이 사용중이면, /home/username/apps/nginx/conf/nginx.conf 에서 liten 80 을 변경해주면 된다.

//자신의 서버 ip:prot 로 접근해보면 nginx index페이지 뜬것을 확인 할 수 있다. 

./nginx -s stop  //종료

 

HTML5 Video Tag

HTML5 HTML의 완전한 5번째 버전으로 월드 와이드 웹 (World Wide Web)의 핵심 마크업 언어이다. 2004년 7월 Web Hypertext Application Technology Working Group(WHATWG)에서 웹 애플리케이션 1.0이라는 이름으로 세부 명세 작업을 시작하였다.

HTML5는 HTML 4.01, XHTML 1.0, DOM 레벨 2 HTML에 대한 차기 표준 제안이다. 비디오, 오디오 등 다양한 부가기능과 최신 멀티미디어 콘텐츠를 액티브X 없이 브라우저에서 쉽게 볼 수 있게 하는 것을 목적으로 한다.
 W3C는 2014년 10월 28일 HTML5 표준안을 확정했다고 발표했다. - https://ko.wikipedia.org/wiki/HTML5

 

HTML4에서 5로 넘어오면서 audio, video, canvas라는 멀티미디어 관련 태그가 추가되었다.

W3C는 2004년 새로운 표준을 제안하였고, 단계적으로 HTML5를 지원하는 범위를 넓혀가던 2007년까지 HTML5에 대한 시선이 곱지만은 않았다.

이제는 레거시 시스템이 된 Silver Light와 Flash, Active X가 라이벌을 물리치고 평정한 시대였고, 브라우저가 HTML5를 랜더링하는 성능도 눈에 뛰게 부족했기 때문이었다.

 

하지만 HTML5가 있으면 모든 클라이언트 서비스(읽고, 쓰고, 보고, 듣는)를 지원할 수 있다는 희망이 생겨났고, 이를 증명하듯 수많은 웹앱이 태어났다. 스마트폰과 하드웨어의 발전이 계속되고 복잡한 웹생태계를 표준화하고자 하는 사람들의 열망이 모여 현재 Flash와 Silver Light, Actice X는 레거시를 넘어 웹생태계를 해치는 악의 축으로 밀려 나기 까지 했는데, 이러한 HTML5 내용 중 Video에 대해서 살펴보고자 한다.

 

Video element 는 Medeia element를 구현하고 있으며, 속성으로 src, poster, preload, autoplay, mediagroup, loop, muted, controls, width, height 속성을 가진다. DOM생성시 해당 옵션을 지정할 수 있으며 이름을 통해서 알 수 있듯이 플레이어가 지원해야할 기본적인 옵션들이다.

Video element의 DOM interface로는 width, height, videoWidth, videoHeight, poster가 있고, Media elemet에 current와 duration 같은 좀 더 상세한 interface가 있다.  상세내용은 아래에 첨부하였다.

 

W3C  Video 정의

Video Element

Content attributes

src
poster
preload
autoplay
mediagroup
loop
muted
controls
width
height

DOM interface
interface HTMLVideoElement : HTMLMediaElement {
           attribute unsigned long width;
           attribute unsigned long height;
  readonly attribute unsigned long videoWidth;
  readonly attribute unsigned long videoHeight;
           attribute DOMString poster;
};

Media elements (audio and video, in this specification) implement the following interface:

interface HTMLMediaElement : HTMLElement {

  // error state
  readonly attribute MediaError error;

  // network state
           attribute DOMString src;
  readonly attribute DOMString currentSrc;
  const unsigned short NETWORK_EMPTY = 0;
  const unsigned short NETWORK_IDLE = 1;
  const unsigned short NETWORK_LOADING = 2;
  const unsigned short NETWORK_NO_SOURCE = 3;
  readonly attribute unsigned short networkState;
           attribute DOMString preload;
  readonly attribute TimeRanges buffered;
  void load();
  DOMString canPlayType(in DOMString type);

  // ready state
  const unsigned short HAVE_NOTHING = 0;
  const unsigned short HAVE_METADATA = 1;
  const unsigned short HAVE_CURRENT_DATA = 2;
  const unsigned short HAVE_FUTURE_DATA = 3;
  const unsigned short HAVE_ENOUGH_DATA = 4;
  readonly attribute unsigned short readyState;
  readonly attribute boolean seeking;

  // playback state
           attribute double currentTime;
  readonly attribute double initialTime;
  readonly attribute double duration;
  readonly attribute Date startOffsetTime;
  readonly attribute boolean paused;
           attribute double defaultPlaybackRate;
           attribute double playbackRate;
  readonly attribute TimeRanges played;
  readonly attribute TimeRanges seekable;
  readonly attribute boolean ended;
           attribute boolean autoplay;
           attribute boolean loop;
  void play();
  void pause();

  // media controller
           attribute DOMString mediaGroup;
           attribute MediaController controller;

  // controls
           attribute boolean controls;
           attribute double volume;
           attribute boolean muted;
           attribute boolean defaultMuted;

  // tracks
  readonly attribute MultipleTrackList audioTracks;
  readonly attribute ExclusiveTrackList videoTracks;
  readonly attribute TextTrack[] textTracks;
  MutableTextTrack addTextTrack(in DOMString kind, in optional DOMString label, in optional DOMString language);
};

Youtube, Twitch, Pooq

실서비스 되고 있는 비디오 플레이어를 살펴보면, Html5 Video 태그로 플레이어 기본 기능을 구현한 것을 알 수 있다.

각종 버튼과, 광고노출과 같이 플레이어와 겹쳐서 보여지는 부분들은 DIV형태로 플레이어 위에 덧씌어져서 사용자에게 노출하고,

외부 Html요소를 이용하여 사용자로부터 전달되는 이벤트를 Video Eelement로 전달하는 방식으로 플레이어를 구현했다.

 

You Tube

 

Twitch

 

Pooq

 

Open Source

여러 종류의 Html5 Video Player 비교1, 비교2, 추천들이 있다.

다수의 Html5 Video Player 중에서 눈에 뛰는 두가지 오픈소스 플레이어를 소개한다.

 

두가지 플레이어 모두 플레이어 기본기능을 구현하고 있고, YouTube와 Vimeo완 연동이 가능하다.

또한 공통적으로 자막, 반응형, 스트리밍, 풀스크린, 다국어와 같은 사용자 편의기능을 포함하고있다.

 

Video.js의 Github Start는 16,549개다. Jquery가 45,000개 인것을 감안하면 엄청난 숫자이다.

사용자가 많은만큼 레퍼런스가 풍부하고, 대부분의 플러그인이 개발되어 있다.

커스터마이징이 필요없고, 하나의 솔루션처럼 Html5 Video Player가 필요하다면 가장 추천할만한 플레이어다.

 

Plyr의 Github Star는 9,469개다. 유명도에 비해 높은 Star 수를 보유하고 있으며,

경량화된 Html5 Video Player에 대한 개발자들의 요구를 반영하여 경량과, 커스터마이징에 초점을 맞추어 개발했다.

비교적 부족한 플러그인과 Owner가 육아에 돌입했다는 단점이 있지만 커스터마이징이 필수인 경우 가장 추천할만한 플레이어다. 

 

Video.js

  • 가장 사용자가 많은 Video Player Open Source (40만 사이트 이상)
  • HTML5와 Flash video까지 지원
  • 활발한 PR과 다수의 플러그인
  • js간 의존성이 높고, 파편화(좋은말로 모듈화) 됨
  • Apache License

Plyr

  • 경량, 커스터마이징에 초점을 맞춤
  • js 파일 하나, 10kb
  • 비교적 부족한 플러그인
  • Owner가 최근 육아에 전념함
  • MIT License

Solution

유료 솔루션 형태의 Html5 Video Player도 많이 있다.

유료형태의 솔루션은 HLS(스트리밍)지원과 광고 연동, 사용자 통계, DRM지원, Preview Thumbnail, 360 View, 고객지원과 같은 부가기능을 무기로 가격을 책정한다. 

하지만 Video.js 와 플러그인, hls.js와 같은 오픈소스들로 유료 기능들을 구현할 수 있기 때문에 플레이어만 판매하는 것을 넘어서 인코딩과 CDN, 그리고 스트리밍을 위한 서버를 함께 제공해주는 업체가 많다. 또는 플레이어를 무료로 풀고 고개지원에만 가격을 책정하는 업체도 있다.

자체적으로 스트리밍 서버와 CDN, 인코딩서버를 구축하기 힘든 경우 해당 업체를 사용하면 좋을것 같지만, 최근 AWS에서 워낙 친절한 솔루션을 내놓았기 때문에 개발자 관점에서 매력을 찾기는 어려울 것 같다.

OpenSource Issue (DRM, Streaming, Mobile, Ad)

오픈소스를 사용하여 Html5 Video Player를 구현할 때 어려운 점이 무엇일까 고민해보았다.

(유료 솔루션들이 해당 기능을 해결해주고 돈을 받는 것이기 때문에 유료 솔루션의 피처리스트들이 구현 시 어려운 점이었다.)

 

HLS Streaming : hls.js를 사용하면 된다.

DRM : hls.js를 사용하면 되지만, 스트리밍이 아닌경우 생각해봐야할 문제.

Mobile : 반응형 개발로 Web View 재생을 하면 되지만, 성능이 받쳐줄지는 미지수. 성능이슈라면 유료 솔루션도 어쩔수 없다.

Ad : 광고를 심는 시점과 고객 행동 데이터를 수집해야한다. 광고 노출기능은 Video.js에서 videojs-contrib-ads라는 플러그인 형태로 구현해 두었지만, 광고 전환율, 사용자당 클릭 퍼센트와 같은 통계데이터 수집은 따로 구현해야할 부분이다. 이 부분은 플레이어 자체의 기능이라기보다 서비스 플랫폼의 관점으로 바라봐야 할 것 같다.

+ Recent posts