일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Instrumentation
- 한글조사처리
- IPTV
- xlet
- 암호학
- Postman
- date
- Freemaker
- 이클립스 플러그인 개발
- 자바
- Callable
- StringUtils
- Executor
- RSA
- String
- ACAP
- mac
- PKCS#8
- 한글조사
- Java
- AES
- ORM
- Executors
- 자바 암호화
- JCE
- PKCS
- Log4J
- DAMO
- sha1
- Runnable
- Today
- Total
오늘은 어디로 갈까...
JPPF(Java Parallel Processing Framework) 본문
1. 소개
1.1 JPPF
- JPPF(Java Parallel Processing Framework)은 손쉽게 병렬 처리 프로그램을 만들수 있게 도와주는 프레임워크이다.
- 단순히 1대의 컴퓨터에서만 작동하는것이아니라, 네트워크로 연결된 수많은 컴퓨터를 사용하여 분산처리할 수 있게 도와준다.
- 한마디로 요약하면, 오픈 소스 그리드 컴퓨팅 플랫폼(open source Grid Computing platform)이라 할 수 있는것이다.
1.2 준비물
- Java 1.5 이상
- Apache Ant (실행 스크립트가 build.xml로 되어있다. 알아서 해결할 경우 필요없다.)
- JPFF driver and node binary package (http://sourceforge.net/project/showfiles.php?group_id=135654 에서 다운가능)
+ jppf-full-xxx.zip, jppf-driver-xxx.zip, jppf-node-xxx.zip을 다운 받자.
(jppf-full-xxx.zip 만 있어도 해결가능하지만 귀차니즘으로 인해 3개 다 받자)
1.3 Architecture
- JPPF는 3개의 레이어(Layer)로 구분할 수 있다.
* client layer : client가 작업(taks) 실행을 요청하는 부분이다.
* service layer : client로 부터 온 작업 실행 요청을 큐(queue)게 담은 후 사용 가능한 실행자(node)로 분배하는 부분이다. 간단히 말해서 서버 역할을 한다고 보면된다. JPPF Driver가 이 역할을 한다.
* execution layer : 실제적으로 작업을 실행하는 부분이다. JPPF Node가 이 역할을 한다.
- 즉, 사용자(client)가 작업 실행 요청을 하면, JPPF Driver로 요청이 넘어가고, JPPF Driver는 사용가능한 JPPF Node를 찾은후 작업들을 넘겨주고 응답 결과를 받는것이다.
- 1개의 JPPF Driver에는 n개의 JPPF Node가 연결될수 있고, JPPF Driver 끼리 peer to peer topology 를 지원한다.
- 멋진 그림이 있으니 참고바란다.(http://www.jppf.org/wiki/index.php?title=Architecture)
2. JPPF Driver, Node
- JPPF Driver, Node 를 실행하지 않고, Local Execution 모드로도 처리가 가능하지만, 원래 취지(?)에 알맞게 원격으로 처리하게 만들어보자.
2.1 JPPF Driver 실행
- 다운받은 jppf-driver-xxx.zip을 적당한 디렉토리에 풀자.
- 압축 푼 디렉토리에 보면 build.xml이 있을 것이다. ant로 실행하자.
2.2 JPPF Node 실행
- 다운받은 jppf-node-xxx.zip을 적당한 디렉토리에 풀자.
- 압축 푼 디렉토리에 보면 build.xml이 있을 것이다. ant로 실행하자.
- 뭐 컴퓨터가 빵빵하면, 여러개의 Node를 실행해보자. --;
3. JPPF Client 작업 환경 만들기
- 여기서는 이클립스를 이용해서 client를 실행하겠다.
- Java Project를 하나 만들자.
- 다운받은 jppf-full-xxx.zip을 적당한 디렉토리에 풀자.
- JPPF\build 디렉토리에 보면 jppf-client.jar, jppf-common.jar, jppf-common-node.jar 파일이 있는데, Java Project 하위에 lib 디렉토리를 만들어서 복사해주자.
- JPPF\lib 디렉토리에 보면 필요한 라이브러리들이 들어있다. commons-logging.jar, log4j.jar를 Java Project 하위의 lib 디렉토리에 복사해주자.
- Java Project 설정 정보에서 lib 디레토리에 있는 jar들을 클래스패스(classpath)에 추가해주자.
3. JPPF Task 만들기
- JPPF Driver, Node는 작동하고 있으니, 이제 작업(Task)를 만들어보자.
- 분산처리를 하기 위해서는 처리할 일(job)을 여러 작업(task)으로 나누어야한다. 자동으로 나눠주면 좋겠지만, 아직까지는 기술이 부족해서 사람이 직접 나눠줘야한다.
- 작업(Task)은 org.jppf.server.protocol.JPPFTask 추상클래스를 상속받아 만들면 된다. 기본적으로 쓰레드에서 사용하는 Runnable, Callable을 사용 할 수있고, 자체적으로 어노테이션(Annotation) 기능도 지원한다.
package test.jppf; import org.jppf.server.protocol.JPPFTask; public class HelloWorld extends JPPFTask { public void run() { String hello = "헬로우, 월드"; System.out.println(hello); setResult(hello); } }
- 뭐 별거 없다. JPPFTask 를 상속받아 run() 메소드를 구현하면 된다. 그런데 run() 메소드 어디서 많이 본거 같은데.... 그렇다 JPPFTask는 Runnable 인터페이스를 구현하고 있는것이다. 이 run() 메소는 Runnable 의 것이다.
- 조금 다른 점은 setResult(hello); 이다. 결과값을 담기 위해 JPPFTask 클래스에 구현되어 있는 놈이다.
4. JPPF Job 실행기 만들기
- 이제 만든 작업(task)을 실행해보자.
- 작업(task)를 처리할 일(job)에 추가한 다음 JPPFClient 의 submit() 메소드를 이용하면 실행할 수 있다.
package test.jppf; import java.io.*; import java.util.List; import org.jppf.client.*; import org.jppf.server.protocol.JPPFTask; public class HelloWorldRunner { public static void main(String[] args) { JPPFClient client = null; try { client = new JPPFClient(); JPPFJob job = new JPPFJob(); job.addTask(new HelloWorld()); Listresults = client.submit(job); for (JPPFTask task : results) { if (task.getException() != null) { System.out.println("처리 중 에러가 발생했습니다."); StringWriter sw = new StringWriter(); task.getException().printStackTrace(new PrintWriter(sw)); System.out.println(sw.toString()); } else { System.out.println("정상적으로 처리하였습니다."); System.out.println(String.valueOf(task.getResult())); } } } catch (Exception e) { e.printStackTrace(); } finally { if (client != null) { client.close(); } } System.exit(0); } }
- 아직 실행하지 말자. 설정 파일을 만들지 않았기 때문에 작동하지 않는다.
5. 설정 파일 만들기
- Java Project 하위에 config 디렉토리를 만든다. (귀찮으면 만들지 말고 src 아래에 파일을 만들면 된다.)
- log4j를 위해 적당한 log4j.xml 파일을 만들어주고, jppf 설정 파일인 jppf-client.properties를 만든다.
#------------------------------------------------------------------------------# # List of drivers this client may connect to # #------------------------------------------------------------------------------# jppf.drivers = HelloServer #------------------------------------------------------------------------------# # Host name, or ip address, of the host the JPPF driver is running on # #------------------------------------------------------------------------------# HelloServer.jppf.server.host = localhost #------------------------------------------------------------------------------# # port number for the class server that performs remote class loading # # default value is 11111; uncomment to specify a different value # #------------------------------------------------------------------------------# HelloServer.class.server.port = 11111 #------------------------------------------------------------------------------# # port number the clients / applications connect to # # default value is 11112; uncomment to specify a different value # #------------------------------------------------------------------------------# HelloServer.app.server.port = 11112 #------------------------------------------------------------------------------# # Enable local execution of tasks? Default value is false # #------------------------------------------------------------------------------# jppf.local.execution.enabled = false #------------------------------------------------------------------------------# # Number of threads to use for loacal execution # # The default value is the number of CPUs available to the JVM # #------------------------------------------------------------------------------# jppf.local.execution.threads = 2
- "jppf.drivers"는 사용할 서버명이고, 공백(" ")으로 구분해서 여러 서버를 설정할 수 있다. 그 아래 "서버명.jppf.server.host"로 서버 주소를, "서버명.class.server.port"으로 클래스 로딩에 사용할 포트를, "서버명.app.server.port"로 클라이언트 접속 포트를 설정할 수 있다. 그리고 여기는 생략됬지만, "서버명.node.server.port"로 노드(node)가 접속할 포트를 설정할 수도 있다.
- "jppf.local.execution.enabled"는 로컬 실행을 할것인지 설정하는것인데, 우리는 원격(?)으로 사용할것이므로 "false"로 설정한다.
6. 실행하기
- 실행하기 전에 몇가지 옵션을 추가해주어야한다.
- HelloWorldRunner.java 를 선택 후, Run As -> Run Configurations 가서 옵션을 추가해주자.
- VM arguments에 "-Djppf.config=jppf-client.properties"를 추가하자
- Advanced - Add Folders 를 선택해서 config 디렉토리를 클래스패스에 추가해주자
- Run 을 클릭해서 실행해보자. 문제가 없다면 다음과 같은 결과를 볼 수 있을것이다.
* 실행 결과
[client: driver-1 (xxx.yyy.10.107:11198)] ClassServerDelegate.init(): Attempting connection to the class server
[client: driver-1 (xxx.yyy.10.107:11198)] ClassServerDelegate.init(): Reconnected to the class server
[client: driver-1 (xxx.yyy.10.107:11198)] : Attempting connection to the JPPF task server
[client: driver-1 (xxx.yyy.10.107:11198)] : Reconnected to the JPPF task server
정상적으로 처리하였습니다.
헬로우, 월드
7. 기타
- addTask(new Annotated(), "첨자1"); @JPPFRunnable 어노테이션을 사용해서 해당 메소드를 실행 할 수 있다. (물론 첨자도 넘겨줄수 있다.)
- addTask("메소드명", new Pojo(), 첨자1, 첨자2); 형식으로 POJO의 메소드를 실행할 수 있다.
- addTask(new Runnable());
- addTask(new Callable());
- DataProvider 를 이용해서 데이터를 공유(?) 할 수 있다.
- 직렬화(serializable)가 안되는 클래스일 경우 XStream(http://xstream.codehaus.org/)을 이용해서 XML 형식으로 변환후 처리하는 방법도 존재한다.
8. 투덜투덜
- 아직 버그가 조금 존재하긴 하지만, 상당히 애쓴(?)흔적이 여기저기서 보인다. ClassLoader 기능도 구현되어있고, JMX도 지원하는 등 여러 멋진 기술을 볼 수 있어 행복하다. 단지 보안쪽이 조금 취약(?)해 보이지만, 뭐 이건 요즘 보안쪽을 공부하고 있는 부작용이라서 그런것일수도... 이런 프레임워크를 만들어봐야, 자바의 희노애락을 느낄 수 있는데, 매일 단순 노동이나 하고 있으니.... 흠흠, 그런데 이걸 사용할만한 곳이 있을까? 국내의 자바세계는, 자바의 처리속도보다 데이터베이스의 응답속도에 의해 성능이 결정되는 구조가 많은데... bruce force attack 용으로 쓸까나 ^^;
* 참고
http://www.jppf.org/