Skip to content

Instantly share code, notes, and snippets.

@sng2c
Last active December 17, 2015 04:39
Show Gist options
  • Save sng2c/5552479 to your computer and use it in GitHub Desktop.
Save sng2c/5552479 to your computer and use it in GitHub Desktop.

Perl 어플리케이션 배포하기

Abstraction

perl 어플리케이션을 개발하여 각 서버로 배포할 때, 모듈의존성을 해결하는 방법에 대해서 설명합니다.

CPAN

perl 스크립트를 작성할 때 CPAN (https://metacpan.org) 을 이용하면 방대한 양의 모듈, 상세한 문서, 다른 모듈을 기반으로 하여 높은 완성도를 이끌어 내는 perl만의 독특한 공유 문화 덕분에 손쉽게 복잡한 기능을 완벽하게 구현할 수 있습니다.

그러나 프레임웍 스택처럼 얽힌 모듈의 의존성 때문에 수십 대, 많게는 수백 대의 서버로 배포를 해야하는 우리 실정에는 부담인 것이 사실입니다.

하나의 예로 WWW::Mechanize 라는 강력한 웹 자동화 모듈의 경우에, LWP::UserAgent를 확장하였고, LWP::UserAgent는 HTTP::Request , MIME::Base64 등의 모듈을 기반으로 하고 있습니다. 각각의 모듈을 작성한 사람이 모두 다르고 고유의 목적을 위해 유지보수가 이루어 지므로, 디테일과 안정성에 있어서는 더 할 나위가 없지만, 그 장점이 의존성으로써 다시 발목을 잡게 됩니다.

의존성의 해결

보통 이런 문제를 해결하기 위해 이런 방법을 쓰셨을 겁니다.

  • 서버마다 같은 버전의 perl바이너리와 라이브러리를 통채로 sync
  • 서버마다 cpan명령으로 모듈을 빌드과정을 통해 설치
  • 해당모듈만 복사하여 라이브러리 디렉토리에 배포
  • 필요한 부분만 발췌해서 단일 파일로 작성

각각의 방법은 아래와 같은 문제가 발생합니다.

  • sync가 되지않는 다른 곳에서는 작동이 어렵습니다.
  • 소모적입니다. 만약 의존하는 라이브러리의 헤더파일이 없을 경우 일일이 빌드환경까지 맞춰줘야 합니다.
  • XS(c/c++연동) 라이브러리는 바이너리 파일까지 찾아서 배포해야 합니다.
  • 생산성과 안정성이 떨어집니다.

JAR == PAR

Java는 일찌감치 JAR를 도입하여, 클래스패스를 하나의 파일로 압축하여 배포하는 방법을 써왔습니다. perl에도 PAR이 있어서 하나의 파일로 압축하여 배포하는 것이 가능합니다.

PAR 의 특징

perl 문화의 특성 상 보통 모듈(또는 유틸리티)들은 이렇게도 쓰고 저렇게도 쓸 수 있게 만들어 지는 경우가 많습니다. 굉장히 다양한 경우를 염두에 두는데요. PAR도 그런 특징을 가지고 있습니다.

  • 모듈만 패키징
  • 스크립트+cpan모듈을 PAR로 패키징
  • 스크립트+cpan모듈+코어모듈을 PAR로 패키징
  • 멀티아키텍처 지원 ( 하나의 PAR로 linux, windows, mac 동시지원 )
  • PAR을 내부에 포함하고 자체 파싱기능이 있는 스크립트로 패키징 (실행시 perl 필요)
  • PAR을 내부에 포함하고 자체 파싱기능이 있는 바이너리(.exe등)로 패키징 (실행시 perl 불필요!)
  • http로 사설 PAR 리포지토리를 구성하고, 런타임에 원격으로 로딩하여 작동
  • perl 대신 PAR모듈을 기본기능으로 가진 parl 사용
  • 내용의 암호화

좀 많죠?

새로운 배포 시나리오

다음과 같은 시나리오로 perl스크립트를 배포한다고 가정해봅니다.

  1. 로컬에서 cpan 으로 모듈설치
  2. 스크립트 작성 및 테스트
  3. PAR로 패키징
  4. PAR파일하나만 배포해서 실행

간편하겠죠? "parl 과 스크립트+cpan모듈+코어모듈" 을 조합하면 되겠습니다.

parl 과 PAR

parl 은 perl바이너리 + PAR 입니다. parl 은 PAR 모듈을 설치하면, 설치되는 perl의 확장바이너리이구요. perl을 대신 할 수 있습니다. JAVA로 치면 perl은 java이고 parl은 java -jar 입니다.

아무 라이브러리도 사용하지 않는다면, parl 만 배포해서 스크립트를 실행하게 하면 됩니다.

PAR은 perl의 기본패키지인 코어모듈도 강제로 포함시킬 수 있습니다. 기본적으로 코어모듈들은 MAVEN의 provided 설정처럼 패키징에서는 제외되는데요. -B 옵션을 주면 관련된 모듈은 모두 포함합니다.

해봅시다.

perl의 업그레이드

보통 우리 서버에는 5.6 또는 5.8 대 버전이 깔려 있는데요. perl 소스를 받아서 직접 시스템에 root로 설치하기 보다는 perlbrew를 이용하는 것이 최근 추세입니다.

  1. http://perlbrew.pl/ 를 방문합니다.

  2. 쉘에서 curl -kL http://install.perlbrew.pl | bash 을 실행합니다.

    $ curl -kL http://install.perlbrew.pl | bash % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 315 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0 100 1022 100 1022 0 0 459 0 0:00:02 0:00:02 --:--:-- 1792

    Download the latest perlbrew

    Installing perlbrew

    perlbrew is installed: /perl5/perlbrew/bin/perlbrew perlbrew root (/perl5/perlbrew) is initialized. Append the following piece of code to the end of your ~/.bash_profile and start a new shell, perlbrew should be up and fully functional from there: source ~/perl5/perlbrew/etc/bashrc Simply run perlbrew for usage details. Happy brewing!

    Installing patchperl

    Done.

    $

  3. .bashrc 등에 source ~/perl5/perlbrew/etc/bashrc 를 최대한 아래쪽에 추가합니다. (/usr/bin/perl 보다 먼저 PATH가 잡혀야 하니..)

  4. source ~/.bashrc 하거나 쉘을 새로 엽니다.

  5. perlbrew available 를 실행하여 설치가능한 버전을 확인합니다.

    $ perlbrew available perl-5.17.11 perl-5.16.3 perl-5.14.4 perl-5.12.5 perl-5.10.1 perl-5.8.9 perl-5.6.2 perl5.005_04 perl5.004_05 perl5.003_07 $

  6. perlbrew install perl-5.16.3 을 실행하여 perl-5.16.3 버전을 설치합니다.

  7. 이후 빌드 과정은 자동으로 진행됩니다.

  8. perlbrew list 를 하면 현재 설치된 펄리스트가 나오고, 선택된 버전앞에는 * 이 표시됩니다.

    $ perlbrew list * perl-5.16.3 $

  9. perlbrew switch perl-5.16.3 을 실행하면 영구적으로 해당버전의 perl이 설정됩니다.

  10. perlbrew install-cpanm 을 실행하여 cpanminus 도 반드시 설치합니다.

만약 root 에서도 같은 버전의 perl을 쓰고 싶다면, root의 .bashrc에 source ~사용자계정/perl5/perlbrew/etc/bashrc 을 넣어주면 되겠죠? 자 최신버전의 perl을 깔끔하게 로컬계정에 설치했습니다.

PAR , PAR::Packer 의 설치

cpanm은 cpan과 달리 별다른 설정과정 없이 간편하게 모듈을 설치할 수 있습니다.

$ cpanm PAR::Packer
...
$

cpanm 으로 PAR::Packer를 설치하면 알아서 의존모듈들이 쭉 설치됩니다.

설치가 완료되면 par.pl과 parl, pp 등의 명령이 사용가능하게 됩니다.

스크립트의 작성과 패키징

JSON 모듈을 설치해서 사용해봅시다.

$ cpanm JSON

https://metacpan.org/module/MAKAMAKA/JSON-2.57/lib/JSON.pm JSON문서를 보고 사용법을 보면 됩니다.

perlbrew를 사용하므로 /usr/bin/perl 이 아니라 /usr/bin/env perl 을 사용합시다. 단 소스파일에 CR-LF 는 모두 제거해야 합니다. LF 만 남겨주세요. CR-LF가 첫줄에 들어있으면 /usr/bin/env perl<CR> 로 인식되어 오작동하게 됩니다.

json.pl

#!/usr/bin/env perl

use JSON;
my $obj = [ 'testData', { hashkey => 'value' }, [1,2,3] ];
print encode_json($obj);

실행하면

$ perl json.pl
["testData",{"hashkey":"value"},[1,2,3]]

과 같이 JSON으로 잘 출력할 겁니다.

pp 로 패키징합시다.

$ pp -p -B -o json.par json.pl
$ ls -lh
total xxxx
-rw-rw-r-- 1 sng2c sng2c 1.6M  5월 10 13:44 json.par
-rw-rw-r-- 1 sng2c sng2c  115  5월 10 13:42 json.pl
$ 

par이 만들어 졌습니다. -B는 코어모듈도 함께 패키징하는 옵션이고 -p 는 PAR로 만들겠다는 옵션입니다. (-p 를 지정하지 않으면 단일실행파일로 만들어지고 5메가가 넘게 됩니다.)

이제 실행해볼까요?

$ parl json.par 
["testData",{"hashkey":"value"},[1,2,3]]

우왕~ 잘되죠?

$ which parl
/home/sng2c/perl5/perlbrew/perls/perl-5.17.10/bin/parl

위와 같이 parl의 위치를 찾아서 각 서버에 parl 을 먼저 배포해놓고, 그 후에는 par파일만 배포하여 실행을 해주면 됩니다. 오예~>ㅁ<

자세한 추가 옵션들은

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment