Skip to main content

· 8 min read

0. 준비

Jenkins에 있는 job을 remote trigger 할 일이 생겼다. 자동화를 해야 하기 때문에 적절히 trigger 될 수 있어야 한다. 여기에서 '적절히'는 trigger 되는 job이 후보군 중 일부에만 몰리는 일이 없어야 하며, 동시에 slot (Jenkins의 executor)이 비는 경우도 없어야 하고 가급적 빠르게 시작할 수 있어야 한다는 것을 의미한다.

1. 환경

현재 환경이 가지고 있는 조건들은 아래와 같다.

#1 : 거의 동일한 내용의 작업을 수행하는 job이 복수로 존재한다. (이름만 다른 job)

#2 : 각 job은 parameter를 받도록 되어있고, parameter의 조합은 항상 다르다.

#3 : 각 job은 master / slave 어디에서든 실행될 수 있어야 한다.

2. Executor / Build Queue 특징

2-1. Executor

Jenkins에서 job이 실제 실행될 때 위치하는 공간인 executor는 같은 이름의 job을 단 하나만 가질 수 있다. Executor의 내용을 json이나 xml로 뽑아보면 각 job이 가지고 있는 속성 중에 progress 라는게 있는 것을 확인할 수 있는데 job이 시작된지 얼마나 흘렀는지를 표시하는 값으로 보인다. (진행시간을 second 단위로 표시하는 것으로 추측됨)

2-2. Build Queue

Build Queue는 executor와는 조금 다르게 같은 이름의 job이라도 여러개 위치할 수 있다. 모든 job이 여러개 위치할 수 있는 것은 아니고 parameter가 다른 경우 같은 이름의 job이라도 다른 것으로 인식하는 것으로 보인다. Executor처럼 queue의 내용을 뽑아보면 executor의 progress 대신에 inQueueSince 라는 값으로 처음 queue에 들어온 시간을 저장해두고 있다.

3. 목표

내가 처한 환경에서는 job이 지속적으로 생성되는데(당연하지만), 한 개 job이 작업을 마치는데 시간이 몇분에서 길게는 한시간 이상 소요될 수 있기 때문에 필연적으로 job이 쌓일 것으로 예상된다. Executor는 동일한 이름의 job을 받아 들이지 않기 때문에 동일한 이름의 job을 trigger하게 되면 queue에 쌓이게 될 것이다. Executor가 비어있는데도 queue에 쌓이는 일을 막기 위해서 executor에 없는 job을 우선적으로 trigger 할 수 있어야 한다. Executor가 꽉 찬 경우에는 어쩔 수 없이 queue에 job이 등록될텐데 이 경우 가장 빨리 실행될 수 있을 것 같은 job을 고를 수 있어야 하고 그 job을 trigger 해야한다. 또 queue에는 동일한 이름의 job이 여러개 위치할 수 있기 때문에 복수의 job에 대해서도 고려되어야 한다.

4. Modeling

4-1. Sorting / Weight

전체 job list를 T라고 하자. Executor에 위치한 job list를 E, queue에 있는 list를 Q라고 했을 때 각각을 적당한 기준으로 sorting을 하면 우선순위를 매기기 편할 것이라고 생각했다. 그 기준이 애매할 수 있는데 감사하게도 Jenkins에는 위에 설명된 것처럼 적당한 값들을 저장하고 있다. E는 progress, Q는 inQueueSince를 기준으로 sorting 하기로 했다. Progress는 클수록 시간이 오래 흘렀음을 의미하므로 progress 값이 큰 job은 우선적으로 종료될 가능성이 높다. 그래서 E는 progress를 기준으로 내림차순 정렬하고 Q의 inQueueSince는 progress와 반대이기 때문에 오름차순으로 정렬한다. 이렇게 두 세트를 만들어 보면 정렬된 리스트 중 가장 앞에 위치한 job이 선택에 있어서 가장 높은 우선순위를 갖게 된다.

Executor에 없는 job이 항상 queue에 있는 job 보다는 우선순위가 높아야 하기 때문에 queue에서는 절대 넘을 수 없는 벽 같은 것을 만들어야 했다. 그래서 weight의 개념을 사용하기로 했는데, E와 W의 가중치를 각각 다르게 주되 그 차이를 각각 가질 수 있는 weight의 가용범위보다 크게 하면 벽처럼 사용가능할 것 같았다.

4-2. Model

위에서 정렬된 리스트 E, Q에서 순서대로 weight를 부여한다. 수식으로 만들어보면 아래처럼 되는데 Jw는 job의 가중치 총합계를 의미하고 아래첨자 i는 정렬된 리스트의 index 값 (낮을수록 우선순위 높음), executor와 queue를 분리하기 위한 기본 weight 값이다. Qc는 queue에 존재하는 동일한 job의 갯수이다.

Jw = Ei + (Qi + Wb) * Qc

여기에서 Wb를 결정하기 위해서는 Ei가 가질 수 있는 최대값을 알면 되는데 Ei의 최대값보다 Wb를 크게만 만들면 executor에 없는 job의 우선순위를 queue 보다 높일 수 있다. 고민 끝에 Wb를 적절한 값으로 선택할 수 있었는데 바로 executor의 Total Executor 값이다. Ei 값은 index이기 때문에 job의 갯수에 맞춰서 설정할 executor의 총합보다 클 수가 없기 때문이다. Queue에 복수로 존재하는 job의 경우에는 queue에 하나만 존재하는 job 들보다 우선순위가 확연이 떨어지는데 이것 역시도 절대 넘을 수 없는 경계를 만들 수 있어야 한다.

5. Case

위의 내용을 바탕으로 일단 간단한 경우만 그려보면 아래처럼 된다. 덕분에 복잡할 수 있는 구현을 비교적 단순하게 할 수 있었다. 여러 경우를 고려했을 때 아직은 문제가 없어보이지만 혹시 발견되면 수정할 예정이다.

· One min read

MySQL 관리도구 중에 많이 사용하던게 sqlyog 이었다.

원래 free 였는데 어느 순간 Webyog 이라는 이름의 페이지에서 상용으로 판매하기 시작했고 30일짜리 trial을 쓸 수 밖에 없는 상황이었다.

그렇게 이런저런 툴을 전전하다 알게 된 사실.

SQLyog이 community edition이 있단다.

Code google에서 호스팅하는 프로젝트로...

http://code.google.com/p/sqlyog/

 

신난다.

근데 맥용은 없는건가?

· 2 min read

Jenkins에서 시간값을 unix timestamp로 내주길래 (숫자 13자리) 기억이 가물거려 다시 찾아봤다.

Unix timestamp는 1970년 1월 1일을 시작으로 흐른 시간이며 단위는 seoncd이다.

32bit 환경에서는 10자리, 64bit에서는 20자리라고 하는데 Jenkins에서 13자리를 내 준 이유는 단위를 milli second로 잡았기 때문인 것 같다.

(Jenkins는 Java로 만들어졌고 java에서 timestamp를 처리하는 method 들의 기본단위가 milli second임)

변환은 Java native API에도 있고 참조 링크페이지에서도 가능하다. (참조 링크)

나의 경우엔 알아보기 쉽게 변환할 필요는 없고 가장 작은 값이 가장 오래된 거라고 판단하면 되겠다.

· 4 min read

Jenkins의 build queue를 살펴볼 일이 생겼다.

 

1. Build Queue

우선 Jenkins에서의 build queue는 수행될 job이 수행되기 전에 쌓이는 공간으로 여기서 대기하다가 job이 executor (slot)에 들어갈 수 있는 상태(executable)가 되면 executor로 이동된다.

Executor에 빈 slot이 없어서 실행되지 못하는 상황에 build queue에 job이 쌓이기도 하지만 동일한 이름의 job이 실행중인 경우 같은 job이 build trigger 된다면 이전에 실행중인 job이 종료될 때 까지 build queue에서 대기한다.

 

2. Build Queue를 사용하려는 이유

자동화에 Jenkins를 사용하고 있는데 remote로 build trigger를 하려다보니 무작정 job을 trigger 할 수 없다. 현재 build queue에 어떤 job이 있는지 executor에는 어떤 job 이 있어서 build 중인지를 확인하고 나서 적합한 job을 trigger 하는게 올바른 접근일 것이다.

 

3. Build Queue 접근

Jenkins에 authentication 설정이 걸려 있다고 해도 build queue api 접근은 가능하다. 이 페이지가 공식적으로 제공되고는 있는데 API에 대한 설명 같은게 없어서 일단은 구현하면서 대략의 구조를 살펴보게 되었는데, 제공되는 API는REST 방식으로 제공된다고 하는데  HTTP / get으로 간단히 접근할 수 있다.

 

4. Build Queue 구조

id

buildableStartMilliseconds

task (color, name, url)

inQueueSince

stuck

blocked

params

why

actions

┣━━━━ parameters (name, value)

┗━━━━ causes (shortDescription, userId, userName)

buildable

 

문서가 없어서 각 요소의 정확한 내용은 아직 알 수가 없지만 Jenkins developer group에 문의를 한 상태다. 이름과 얻어낸 값으로 예상한 내용은 아래와 같다.

[table nl='||']

Key, Type, Description, Note

id, Integer, Trigger된 job의 ID, 계속 변경되는 값으로 보임

buildableStartMilliseconds, Long, ?, 알 수 없음

task > color, String, 상태에 대한 이미지, 이전 상태 나타내는 이미지로 보임

task > name, String, Job의 이름, -

task > url, String, Job의 url, -

inQueueSince, Long, Build Queue에 쌓인 시간, -

stuck, Boolean, 막혔는지 여부, Build Queue에 쌓인 시간이 오래되면 true로 변경됨

blocked, Boolean, ?, stuck과의 차이를 알 수 없음

params, String, Trigger 될 때의 parameter, 줄바꿈된 문자열로 나열되어 활용 어려움

why, String, Build Queue에 쌓인 이유, 동일한 job이 실행중인지 등의 이유에 대한 설명

actions > parameters > name, String, Parameter의 name, -

actions > parameters > value, String, Parameter의 value, -

actions > causes > shortDescription, String, Job 실행에 대한 간단한 설명, -

actions > causes > userId, String, Job을 실행한 사용자의 ID, -

actions > causes > userName, String, Job을 실행한 사용자의 이름, -

buildable, Boolean, Build 가능 여부, -

[/table]

 

참고

actions의 parameters 항목의 경우 job에 parameter를 받는게 아니라면 값이 비어있는게 아니라 아예 생성되지 않는다.

이것은 parameter가 Jenkins 기본 기능이 아니라 parameterized plugin을 이용하는 거라 그런 것으로 생각된다.

· 4 min read

Jenkins는 동일한 job의 동시 실행 갯수를 제한한다.

 

1. Concurrent Build

아무런 조건이 없을 때 Job A가 실행중이라고 가정했을 때, 누군가에 의해서 혹은 remote로 Job A가 trigger 되면 Job A가 Build Queue로 올라간다.

그러므로 concurrent build의 갯수는 2개라고 할 수 있다. (정확히는 executor에 1, queue에 1)

그 이상이 trigger 되는 job은 cancel도 아니고 pending도 아닌 그냥 무시된다.

혹시 로그에는 있을지 모르겠으나 표면으로는 나타나지 않는다.

당연히 build number도 부여되지 않고, history에도 없다.

 

2. 문제

항상 문제가 생긴다. (푸는 게 우리의 일)

동일한 job을 여러개 실행해야 할 상황이 생겼다.

 

3. 상황 설명

Code review 및 기타 이유로 Gerrit을 사용할 예정이다.

Gerrit에서 trigger될 job이 있는데 관리의 편의성까지 고려했을 때 branch 마다 하나의 job을 배치하는게 최선이다.

Gerrit에서 trigger 횟수는 1시간에 수십회 이상이 될텐데 (branch로 나누더라도 마찬가지를 감안해야 함) Jenkins에서 그만큼을 소화할 수가 없다.

결국은 쌓이게 된다는 얘기다.

그리고 문제는 Jenkins에서는 기본적으로 concurrent build 횟수가 2로 제한된다는 사실이다.

나머지는?

결국 버려질 것 같았다.

큰 문제가 발생하는 것이다.

 

4. Hello (real) World

실제로 검토를 했다.

Job 수행시간을 충분히 늘려두고 job을 수없이 trigger 했다. (손으로도, remote로도)

일반적인 job의 경우 결과는 역시 동일했다.

혹시나 싶어 Gerrit에서 trigger 되도록 했다. 여러번.

믿을 수 없게 Build Queue에 쌓여가는 job을 목격할 수 있었다.

 

5. How?

StackOverflow에서 찾아보니 trick이 있었다.

실행될 job의 parameter를 다르게 던지는 것.

필요없어도 아무런 값이나 만들어 던지면 된다고 한다. (StackOverflow 원문 참조)

생각해보니 Gerrit에서 trigger 되는 job은 실제 parameter가 함꼐 오는데 그 값이 모두 다르다.

그래서 보통과는 다른 결과가 온 것이 아닌가 생각된다.

 

6. 회고

가만히 생각해보니 Jenkins의 concurrent build를 제한하는게 어이없지는 않다.

완전히 동일한 내용의 job을 무한정 돌릴 필요가 있을까?

하지만 parameter가 다르다면 job의 이름은 같더라도 다른 내용을 실행하게 될테니 다른 job처럼 인식하는게 올바른 방식일 것 같다.

 

걱정을 하나 덜었다.

· 4 min read

국내에서는 많이 사용하지 않는 Open source RDBMS인 PostgreSQL을 잠깐 사용해 볼 일이 생겼다.

설치는 어렵지 않았는데, 테이블 생성할 때 까지 몇가지 생소한게 있었다.

1. 접근 권한

PostgreSQL이 설치된 장비에서 관리도구로 접속하는건 문제가 없는데 다른 장비, PC에서 접속하는건 불가능했다.

이유는 pg_hba.conf 라는 설정파일에 존재하는 접근 권한이 기본은 다른 장비에 대해서는 막고 있기 때문이었는데 접속하려는 장비의 IP 대역이나 고정된 IP 값으로 풀어줘야 한다.

pg_hba.conf 파일 위치도 처음엔 몰라서 헤맸는데 설치 경로의 data directory 안에 존재한다.

OS X에서 설치했을 땐 data directory의 owner와 group이 PostgreSQL에서 관리되는 계정과 그룹이라 sudo 권한으로 vi 편집기로 수정해서 사용할 수 밖에 없었는데, 기본 제공되는 관리도구인 pgAdmin이 보여준 몇 가지 문제점 때문이기도 했다.

2. Auto increment

MySQL에서는 column 생성할 때 auto increment 속성 지정이 가능했던 것으로 기억한다. 속성을 지정하면 따로 값을 insert 하지 않아도 초기값부터 증분만큼 자동 증가하게 되어있는데 PostgreSQL은 아무리 뒤져도 그런 속성이나 혹시나 해서 찾아본 data type에도 존재하지 않았다.

PostgreSQL에서는 auto increment 하기 위한 sequence 라는 것을 먼저 정의하고 column 생성시 그 sequence를 nextval 이라는 내장 함수로 호출하도록 해야 한다.

 

결론

잠깐 살펴봤을 때 PostgreSQL은 전체적으로 관리나 DB 설계 측면에서 좀 더 세밀한 설정과 구축을 하도록 권유하는 느낌이다.

PostgreSQL과 MySQL의 장단점, 뭐가 좋으냐 나쁘냐를 두고 인터넷 여기저기에서 말이 많은데, 결국은 일정과 규모에 따라서 나에게 익숙하거나 trouble shooting에 필요할지 모를 reference가 많으냐 적으냐에 따라서 골라쓰면 되지 않을까? 라는 생각을 잠깐 해본다. DB만 전문적으로 하시는 분들은 뭣도 모르는 소리라고 할지 모르겠지만 나 같은 초보자야 뭐.

 

Updated : 2013-04-16

serial과 bigserial type은 true type은 아니고 각각 4byte와 8byte data 저장이 가능하다. PostgreSQL Document에 따르면 다른 RDBMS의 auto_increment와 유사한 속성을 가지는데 아래의 두 query가 동일한 의미를 갖는다고 되어있다.

CREATE TABLE tablename (
colname SERIAL
);


CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

 

댓글을 달아주신 분의 말씀처럼 auto_increment 대신 사용이 가능하다.

· 2 min read

이런 말도 안되는...

google의 모바일 광고 플랫폼인 admob을 iOS app에 적용하려고 sdk 다운받고 update도 안된 매뉴얼을 어찌어찌 찾아서 했더만 처음엔 ARC 관련 오류가 나타났다. (sdk에 포함된 소스 파일들이 예전 iOS sdk에 맞춰서 작성된 것들로 보임)

Flag 조정해서 해결했더니 말도 안되는 linker error.

요런 식으로 표시된다.

Apple Mach-O Linker (Id) Error

알아보니 최근 iPhone 5부터 chipset이 변경되다 보니 architecture도 바뀌었는데 admob에 포함되어 있는 라이브러리가 변경된 architecture에 대해 아직 반영하기 전이라고 한다.

타사 제품을 지원하는 거라 이해 안되는 면도 없지는 않지만 이럴거면 아예 내놓질 말던가. iPhone5가 나온지가 언젠데.

아무튼 admob sdk 업데이트 되기 전까지는 아래의 stack overflow 링크대로 쓸 수 밖에.

Analytics를 사용하지 않는다면 가능한 해법이다.

http://stackoverflow.com/questions/12352630/linker-errors-when-integrating-admob-sdk-into-ios-app

 

 

이렇게 해도 일부 Linker error가 해결되지 않아서 iAd 사용하는 것으로 변경했음. 젠장.

· 8 min read

나에게 필요할 것 같은 Jenkins Plugin을 찾아봤다.

주로 Job 생성, 관리, 설정을 간단하게 할 수 있는 것들인데 일부는 쓸모없거나 문제가 있는 것들도 보인다.

선별해서 사용할 예정인데, 이리저리 조사하고 써보니 Jenkins Plugin도 개발하고 개선할 것들이 꽤 될 것 같다.

[table nl="||"]

Category, Plugin, Description, Feature, Note

Job 생성, Job Import Plugin, 다른 Jenkins server에 있는 job을 선택적으로 import 할 수 있는 plugin, Remote job selection||Remote job import, 오류가 있으나 수정되지 않음||https://issues.jenkins-ci.org/browse/JENKINS-11185

Job 생성, Job Generator Plugin, Parameter를 넘겨 주면서 job 생성이 가능한 plugin, Generator parameter 전달 가능||Post build job에 parameter 전달 가능, Run Condition Plugin/Token Macro Plugin이 설치되어 있어야 함||특정 script를 몰라도 설정만으로 job 생성이 가능하지만 사용한다면 Job DSL Plugin이 더 간단할 것으로 보임

Job 생성, Job DSL Plugin, DSL script(Groovy)를 이용해서 job을 생성하는 job을 만들 수 있는 plugin, 생성할 job 정의하는 기능||Job 자동 생성, Tutorial 참조

Job 관리, Multijob Plugin, 여러개의 job을 묶어서 순차적으로 실행할 수 있는 plugin, Phase 구분||Phase 별 job 선택 가능||실패 조건 결정 가능||한 phase에 존재하는 복수의 job은 parallel로 실행됨, Parameterized plugin이 사전에 설치되어 있어야 함||Jenkins의 job이 너무 많은 경우 유용함

Job 관리, Nested View Plugin, Job을 폴더 형태로 관리할 수 있게 해주는 plugin, Subview 추가, View tab을 늘리면 가로로 추가되기만 하고 job이 늘어날 경우 보기가 어려워지는데 폴더 형태로 job을 정렬함으로써 job 갯수가 많은 경우 유용

Job 관리, Sectioned View Plugin, 화면을 section으로 구분해서 더 다양한 정보를 보여주기 위한 plugin, Test result/list view/job graph/text/view listing section 지원, Jenkins의 view 하나를 dashboard로 사용할 수 있을 것으로 보임||정적 분석이나 test 결과에 대한 정보 위주로 분석 툴이나 결과 data를 직접 활용하는 것이 효율적일 것으로 생각됨

Configuration, Config File Provider Plugin, 사전에 정의한 파일을 이용해 build에 이용할 수 있도록 해주는 plugin, Maven settings.xml / plain xml / Groovy / plain text는 향상된 수정기능 제공, -

Configuration, Managed Script Plugin, Config File Provider Plugin에서 script 파일을 추가할 수 있는 plugin, Batch / shell script 지원||Argument를 미리 정의해서 build job 설정시 argument를 설정해서 사용 가능, 미리 정의된 build script를 하나로 관리하기 용이

Configuration, Scriptler Plugin, Groovy script를 미리 작성해두고 job 실행시에 사용할 수 있도록 지원하는 plugin, Script 추가/수정/삭제||Github에 공유된 script 이용 가능||Script 보관하는 GIT repository 지원, Build 수행내용을 미리 Groovy로 작성한 후 일괄 적용하기 유용함

Master-slave, Copy To Slave Plugin, Build 전 master의 파일을 복사해 가거나 build 이후 slave에 있는 파일을 master로 옮겨올 수 있는 plugin, Copy할 파일 지정 가능||상대경로 지정 가능||Copy 제외목록 지정 가능, Custom workspace를 지정해서 복사할 파일의 경로로 이용하게 되면 job이 master에서 실행될지 slave에서 실행될지 모르기 때문에 파일 경로가 모호해지는 문제가 있음 (slave 실행시에도 custom workspace를 이용함)

Master-slave, Multi slave config plugin, 여러개의 slave를 추가/삭제/설정할 수 있는 plugin, 복수의 slave 생성/설정 가능, FS Root가 slave 마다 다른 경우에는 생성 후 개별적으로 설정해야 하는 불편함 있음

Master-slave, NodeLabel Parameter Plugin, Job 실행시 특정 node나 job을 지정해서 빌드할 수 있도록 지원하는 plugin, Node/Label 지정||Post build job도 node와 label로 지정 가능, Parameterized Trigger Plugin 필요||Build job을 여러개로 분리할 경우 수행된 slave에서만 계속되어야 하므로 필요할 수 있음

Master-slave, Slave Setup Plugin, Slave 연결시 master에 있는 script로 초기 설정 작업을 수행하도록 할 수 있는 plugin, Master의 script 경로 저장||Slave로 script 복사||Script 실행||실행될 slave의 label 지정, Slave 연결시에만 수행되는 작업임||Prepare script/setup script는 모두 상대경로를 지정해야 함||매번 초기화 작업이 필요하면 사용할 필요가 있지만 별도의 job으로 구성할 필요도 있음

Monitor, Monitoring, Jenkins가 사용하는 메모리 등의 상태에 대한 monitoring을 할 수 있는 plugin, CPU / memory 사용량||Http session / request 등에 대한 mean time||JavaMelody를 이용한 통계치를 보여주는 기능||http://jenkins\_url/monitoring 이라는 permanent link 제공, -

Monitor, Monitoring External Jobs, Jenkins 외부에서 실행된 job을 monitoring 할 수 있는 plugin, 외부 job monitoring, Linux에서 설치해야 하는 별도 package의 위치를 찾을 수 없음

Monitor, slave-status, Slave가 동작중인지와 메모리 사용량 등을 알려주는 plugin, Monitoring, 3141 Port를 기본으로 사용함||한 machine에서 여러개의 slave를 사용해서인지 monitoring page 로딩되지 않음||Nagios라는 monitoring tool을 설치해야만 할 수도 있으나 그래야만 한다면 사용하지 않음

Misc., Email Ext Plugin, Email 전송시 좀 더 세분화시켜서 email을 선별적으로 발송할 수 있는 plugin, Email notification trigger 선택 가능||Contents 지정 가능||수신자 지정 가능, 이용 하더라도 별도의 email sender 구현 필요성 있음

Misc., MySQL Database Plugin, MySQL driver plugin, -, Database plugin이 설치되어 있어야 함||Jenkins / plugin 개발용 plugin으로 보임

[/table]

· One min read

이건 대체 뭔가? 이런저런 조사를 하던 중에 툭 튀어나온 단어인데, 약자만으로는 내용을 알기가 어려웠다.

동의어들도 많고. ADSL, VDSL 할 때의 DSL도 검색이 되더라.

내가 살펴보고 있는 부분들은 script, groovy 등과 관련이 있는 것 같아서 좀 더 알아봤더니 Domain Specific Language 인 것 같다.

특정 도메인에만 국한된 작은 프로그램을 만들기 위한 언어라고 하는데, 어릴 때의 추억이 묻어있는 LOGO도 DSL에 포함되고 대학 때 관심이 많았던 VHDL도 그렇다고 한다.

· 2 min read

Jenkins를 여러개 띄워서 검토할 내용이 생겼다.

일반적으로 한 machine에 하나의 Jenkins만 올려서 사용하니 가용한 한 대의 테스트 서버와 다른 사람들의 PC까지 활용하면 어찌어찌 할 수 있겠다 싶었다.

하지만 접속해서 설정해줘야 하고 나 덕분에 다른 사람들은 불편함이 생기니 어떻게 내 PC에서만 Jenkins를 여러개 띄울 수 없나 고민하게 되었다.

처음엔 Jenkins는 필요한 각종 설정이나 plugin, job 정보들을 JENKINS_HOME으로 등록된 경로에서 관리하니 이 경로와 http port만 다르게하면 되지 않을까 생각해봤다.

그러나 결과는 Port 충돌.

Http port는 다르게 했으니 문제가 없었는데 내부적으로 사용하는 port들이 문제를 일으키는 것 같았다. 로그상으로는.

사용되는 Port를 보니 http port, ajp13 port, sshd port, tcp port (JNLP slave agent listener).

이 중에서 http와 ajp13 port가 설정이 가능하다. (Jenkins Wiki 참조)

그래서 임의로 master, slave1 이라 명명해서 각각 아래처럼 해보니 충돌없이 잘 된다.

Master

[bash]

java -jar -DJENKINS_HOME=D:/jenkins/master -jar jenkins.war --httpPort=7070

[/bash]

 

Slave1

[bash]

java -jar -DJENKINS_HOME=D:/jenkins/slave1 -jar jenkins.war --httpPort=7071 --ajp13Port=8109

[/bash]

 

Master는 ajp13 port로 8009를 사용한다. (Jenkins default)

근데 도대체 ajp13은 무얼까?

찾아보니 Apache Jakarta Project에 있는 Apache JServ Protocol version 1.3 이라고 한다. (AJPv13 참조)

 

참고로 Windows 7에서 처리했고, Jenkins version은 1.474였다.