hostid

System/Common 2012. 1. 18. 16:52

hostid 생성 방법 

1. hostid 명령은 보통 GNU coreutils에 구현되어 있습니다.
2. GNU coreutils의 hostid는 gethostid() 함수를 호출합니다. 이 함수는 UNIX 표준에 들어 있고 man페이지를 보면 자세한 설명이 있습니다.
3. gethostid() 함수는 보통 GNU libc에 구현되어 있습니다.
4. GNU libc의 gethostid()는 /etc/hostid를 읽고, 이 파일이 없으면 호스트의 IPv4주소를 16비트 왼쪽으로 시프트한 값과 오른쪽으로 시프트한 값의 논리합을 돌려줍니다.

따라서 그냥 IP 주소에 의해 결정된다고 보시면 됩니다. (GNU coreutils, GNU libc를 사용하고 /etc/hostid에 별도 설정이 없는 경우. 대개는 이 조건을 만족합니다.)



일반적인 유닉스의 경우 하드웨어 벤더에 종속적이므로 hostid가 의미가 있는데(상용 유닉스의 경우 IP랑 상관없이 hostid가 머신에 따라 틀린 걸로 알고 있습니다) 리눅스는 IP에 의해 결정되는 것이니 의미가 좀 없지요 -_-  

'System > Common' 카테고리의 다른 글

SPARC Enterprise  (0) 2012.01.19
후지쯔 PRIMEPOWER  (0) 2012.01.19
유닉스 CPU 독자개발 '득인가, 실인가'  (0) 2012.01.14
“IBM·HP 게섰거라“...오라클, 유닉스 3강  (0) 2012.01.14
IBM Power Systems  (0) 2012.01.13
Posted by linuxism
,
출처 -  http://javastudy.co.kr/docs/techtips/010530.html 

  JDC Tech Tips ::::: 테크 팁
 Java Network Launching Protocol (JNLP) and its reference implementation, Java Web Start

 자바 네트워크 구동 프로토콜(JNLP)과 참조 구현, 자바 웹 스타트
 
 

 

 

한 승 협[tedlovesmary@hotmail.com]
자바스터디 네트워크 
[http://javastudy.co.kr]
 

자바 프로그래밍 언어의 초창기에는 클라이언트 측 개발에 많이 강조되었다. 애플릿이나 코드의 안전한 다운로딩에 대한 자바의 지원은 웹상에서 기능을 전달하기에 이상적인 것 같았다. 그러나 실제로는 자바 프로그래밍 언어의 가장 큰 성공은 서버측에서 거둬오고 있다. 자바의 강력함과 유연함은 서버측 개발자의 사랑과 관심을 받아오고 있다. 반면에 클라이언트 측에서의 개발은 줄어들고 있다. 다루기 힘든 배치 문제가 애플릿의 사용을 제한하고 있고, 개발자들을 브라우져 기반의 "씬(thin)" 클라이언트로 가게끔 한다.
 

자바 네트워크 런칭 프로토콜(JNLP)은 이 모든 것을 바꿀 수 있다. 자바 커뮤니티 프로세스 JSR-56을 통해 개발된 JNLP는 클라이언트에 자바 기능을 배치하는데 있어 이전의 많은 문제를 해결한다. JNLP 클라이언트는 네트워크 상의 호스트 리소스로부터 프로그램을 실행시킬 수 있는 애플리케이션 혹은 서비스이다. 만약 JNLP과 함께 프로그램을 작성한다면 JNLP 클라이언트는 다음과 같은 것을 할 수 있다. 
 

  • 애플리케이션을 위한 자바 런타임 환경의 버젼을 탐지하거나 설치, 사용할 수 있다.
  • 브라우져나 데스크탑으로부터 애플리케이션을 실행 할 수 있다.
  • 가능할 때, 자동적으로 새 버젼의 애플리케이션을 다운로드할 수 있다.
  • 빠른 실행을 위해 애플리케이션에 의해 사용된 클래스를 캐쉬할 수 있다.
  • 애플릿이나 애플리케이션으로 모두 실행할 수 있다.
  • 필요하면 네이티브 라이브러리를 다운로드할 수 있다.
  • 안전한 방법으로 파일시스템 같은 로컬 리소스를 사용할 수 있다.
  • 자동적으로 위치하고 외부적으로 필요한 것을 로드할 수 있다.

썬마이크로시스템즈는 자바 웹 스타트라는 JNLP의 참조 구현을 제공하고 있다. JFC 스윙을 이용하는 간단한 애플리케이션을 배치하기 위해 JNLP를 사용해보자. 이것을 하기 위해서는 http://java.sun.com/products/javawebstart에서 자바 웹 스타트를 다운로드할 필요가 있다.

다음은 애플리케이션 소스다.

//File HelloJNLP.java

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;



public class HelloJNLP extends JFrame {

  public HelloJNLP() {

    super("Hello JNLP");

    String loadedFrom = this.getClass().getClassLoader().toString();

    JLabel jl = new JLabel("loaded by " + loadedFrom);

    JEditorPane jtp = new JEditorPane("text/plain", "Edit this text");

    getContentPane().add(jl, BorderLayout.NORTH);

    getContentPane().add(jtp, BorderLayout.CENTER);

  }



  public static void main(String [] args) {

    JFrame f = new HelloJNLP();

    f.setBounds(100,100,325,250);

    f.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

    f.setVisible(true);

    f.addWindowListener(new WindowAdapter() {

      public void windowClosed(WindowEvent e) {

        System.out.println("Shutting down...");

        System.exit(0);

      }

    });

  }

}

JNLP 핵심에 배치 목록(?)이 있다. 배치 목록은 .jnlp 확장자를 가지는 XML 파일이다( JNLP 스펙은 간단히 "JNLP 파일"이라고 부른다.). HelloJNLP 애플리케이션을 배치하기 위해서는 다음과 같은 JNLP 파일을 적어줘야 된다.

<?xml version="1.0" encoding="UTF-8"?>

<!-- file Hello.jnlp -->

<jnlp codebase="http://staff.develop.com/halloway/TechTips/May2001"

href="http://staff.develop.com/halloway/TechTips/May2001/Hello.jnlp">

	<information>

		<title>JDC TechTips - May 30, 2001</title>

		<vendor>Tech Tips Sample May 2001</vendor>

		<icon href="HelloJNLP.jpg"/>

	</information>

	<resources>

		<j2se version="1.2+"/>

		<jar href="HelloJNLP.jar"/>

	</resources>

	<application-desc main-class="HelloJNLP"/>

</jnlp>

이 목록 파일은 HelloJNLP 애플리케이션을 다운로드 하고 사용하기 위한 모든 정보를 담고 있다.

  • jnlp 요소의 codebase 속성은 애플리케이션 리소스들을 찾기 위한 최상위 URL을 나타낸다.
  • information 요소는 JNLP 사용자 인터페이스가 클라이언트에 표시할 정보를 나타낸다.
  • j2se 요소는 클라이언트가 반드시 1.2나 이후 버젼의 J2SEtm을 가지고 있어야 됨을 나타낸다. (이것은 브라우져에 설치된 VM이 뭐든간에 종종 충돌을 일으키는 애플릿 배치를 능가하는 큰 향상이다.)
  • jar 요소는 jnlp codebase로부터 상대적인 애플리케이션 JAR파일의 위치를 기술한다.
  • application-desc 요소는 실행시키기 위한 클래스를 나타낸다. 명령어 전달인자나 시스템 변수를 기술하기 위해 서브 요소를 추가할 수도 있다.

애플리케이션을 웹서버에 배치하려면, 다음 단계들을 실행할 필요가 있다.

  1. jnlp codebase안의 URL을 바꾸고 href를 해당 웹서버에 맞춰 적절한 URL로 설정해라. 
     
  2. JNLP 파일을 웹서버에 올려라. 
     
  3. HelloJNLP.java를 컴파일하고 jar로 묶어라. 그리고 웹서버에 올려라. 예를 들면,

    jar cvf HelloJNLP.jar HelloJNLP.class HelloJNLP$1.class

  4. HelloJNLP.jpg 아이콘 파일을 만들고 웹서버에 올려라. 이 파일을 사용해도 된다. http://staff.develop.com/halloway/TechTips/May2001/HelloJNLP.jpg
     
  5. 웹서버의 mine-type 연결에 .jnlp를 application/x-java-jnlp-file로 설정해라. 예를 들면, 아파치의 경우, 다음을 mime.types파일에 추가해라.

    application/x-java-jnlp-file jnlp

  6. 웹서버를 재시작해라.

클라이언트로부터 이 애플리케이션을 실행하기 위해서는 먼저 자바 웹 스타트 설치 여부를 확인해야 된다. 그런다음 간단히 브라우져에서 jnlp파일의 URL을 가리키기만 하면 된다. 자바 웹 스타트 클라이언트는 jnlp파일과 필요한 리소스들을 다운로드 하고 애플리케이션을 실행할 것이다. 에디터에 뿌려진 "Edit this text"라는 문자열을 보게 될 것이다. 만약 웹서버를 설정하는데 문제가 있거나 웹서버로 접근할 수 없다면,http://staff.develop.com/halloway/TechTips/May2001/Hello.jnlp에서 실행할 수도 있다.

HelloJNLP는 브라우져 안에서 애플릿으로 돌아가고 있는게 아니고 독립적인 애플리케이션이란 걸 알아둬라.

애플리케이션을 닫으면, HelloJNLP는 "Shutting down..." 메시지를 출력하기 위해 System.out을 사용한다. 그러나 콘솔은 보이지 않는다. console은 자바 웹 스타트가 디폴트로 "off" 해놓는 많은 설정 중에 하나이다. 이것은 다음처럼 바꿀 수 있는 설정 중 하나다.

  1. 자바 웹 스타트 설치 디렉토리에 javaws.cfg 파일을 고쳐라. "javaws.cfg.forceUpdate=true"라고 한 줄을 추가해라. 이렇게 하면 자바 웹 스타트가 애플리케이션을 실행하기 전에 새 버젼을 자동으로 확인한다. 
     
  2. 자바 웹 스타트 프로그램을 실행해라. File -> Preferences 에서 Advanced 탭으로 가서 "Show Java Console"을 선택해라. 또 "Log Output"를 선택하고 로그 출력 파일을 지정해라. 디버깅을 할 때나 System.out이나 System.err를 보고자 할 때 아주 유용하다.

HelloJNLP 애플리케이션은 에디터를 보여준다. 그러나 그 애플리케이션을 닫으면 에디터의 내용은 날아가 버린다. 클라이언트 하드드라이브에 에디터의 상태를 자동으로 저장하기 위해서 HelloJNLP에 다음 코드를 추가해라.

// HelloJNLP.java로 바뀐다.

import java.io.*;

import java.net.*;

import javax.jnlp.*;



  // 생성자를 이 새로운 버젼으로 대체해라.

  JEditorPane jtp;

  public HelloJNLP() {

    super("Hello JNLP, Second Version");

    String loadedFrom = this.getClass().getClassLoader().toString();

    JLabel jl = new JLabel("loaded by " + loadedFrom);

    jtp = new JEditorPane("text/plain", "Edit this text");

    readEditorContents();

    getContentPane().add(jl, BorderLayout.NORTH);

    getContentPane().add(jtp, BorderLayout.CENTER);



    addWindowListener(new WindowAdapter() {

        public void windowClosed(WindowEvent e) {

          System.out.println("Shutting down...");

          try {

            writeEditorContents();

          }

          catch (Exception ex) {

            System.out.println("Yoinks!");

            ex.printStackTrace();

          }

          System.exit(0);

        }

      });

  }



  //이 헬퍼 메소드들을 추가하라.

  private void writeEditorContents() throws

                UnavailableServiceException, IOException {

      System.out.println("writeEditorContents");

    PersistenceService ps = (PersistenceService)

      ServiceManager.lookup("javax.jnlp.PersistenceService");

    BasicService bs = (BasicService)

      ServiceManager.lookup("javax.jnlp.BasicService");

    URL baseURL = bs.getCodeBase();

    System.out.println("CodeBase was " + baseURL);

    URL editorURL = new URL(baseURL, "Editor");

    try {

      ps.create(editorURL, 1024);

    }

    catch (Exception e) {

      e.printStackTrace();

    }

    FileContents fc = ps.get(editorURL);

    DataOutputStream os = new DataOutputStream(

                                 fc.getOutputStream(false));

    String s = jtp.getText();

    os.writeUTF(s);

    os.flush();

    os.close();

  }



  private void readEditorContents() {

    try {

      PersistenceService ps = (PersistenceService)

        ServiceManager.lookup("javax.jnlp.PersistenceService");

      BasicService bs = (BasicService)

        ServiceManager.lookup("javax.jnlp.BasicService");

      URL baseURL = bs.getCodeBase();

      URL editorURL = new URL(baseURL, "Editor");

      FileContents fc = ps.get(editorURL);

      DataInputStream is = new DataInputStream(fc.getInputStream());

      jtp.setText(is.readUTF());

      is.close();

    }

    catch (Exception e) {

      e.printStackTrace();

    }

  }

JNLP API는 몇몇 공통적인 클라이언트 작업을 할 수 있도록 보안 샌드박스에 제약을 받지 않는 서비스 집합을 정의하고 있다. writeEditorContents 메소드에서 BasicService는 애플리케이션의 코드베이스를 찾아낸다. 그런다음, PersistenceService는 애플리케이션의 코드베이스로부터 상대적인 적당한 URL을 가지고 에디트 창의 내용을 로컬 하드에 캐쉬한다. PersistenceService에 의해 제공된 이름/값의 쌍은 브라우져의 쿠키와 비슷하다. 자바 웹 스타트는 그 쌍을 "머핀"이라고 부름으로써 예전부터 사용해 온 이 방식을 존중한다. 머핀은 큰 데이터의 저장공간으로는 적합하지 않고 클라이언트에다 작은 식별자를 임시 저장할 때 사용해야 한다. 그러면 이런 식별자들은 서버상에 존재하는 많은 정보를 찾는데 사용되어 질 수 있다.

바뀐 애플리케이션을 웹서버에 재배치해봐라. 그리고 URL로 클라이언트에서 그것을 다시 실행시켜봐라. 웹서버가 없다면 http://staff.develop.com/halloway/TechTips/May2001/Hello2.jnlp 에서 이 버젼을 실행해 볼 수도 있다. 자바 웹 스타트는 자동적으로 애플리케이션이 바뀐 것을 탐지해내고 새 버젼을 실행한다. 타이틀 바의 "Hello JNLP, Second Version"이라는 문자열을 보면 확인할 수 있다. 에디터의 창에 어떤 변화를 주고 프로그램을 닫아 봐라. 그리고 다시 실행시키면, 바뀐 내용을 볼 수 있을 것이다. (새 버젼을 처음 실행시키면, 아마 콘솔 출력으로 예외가 나올 수도 있다. 왜냐하면 readEditorContents이 처음에는 머핀을 못찾기 때문이다.)

JNLP 는 여기 보여진 것 보다 더 많은 서비스를 제공한다. 예를 들면,

  • 어떻게 애플리케이션이 다운로드 되는 가를 정교하게 제어할 수 있다.
  • JAR간에 의존성 관계에 대해 기술할 수 있다.
  • 네이티브 코드 인스톨러를 다운로드하고 실행할 수 있다.
  • 사인된 코드에 추가적인 허가를 줄 수 있다.
  • 특정 버젼의 애플리케이션이나 애플릿을 요청할 수 있다.

JNLP에 대해 더 알고 싶으면, http://java.sun.com/products/javawebstart/download-spec.html JNLP 스펙을 다운받자.

자바 웹 스타트에 대한 자세한 정보는 http://java.sun.com/products/javawebstart/ 를 방문하세요.

'Development > Java' 카테고리의 다른 글

JNDI와DBCP/DataSource의 사용법  (0) 2012.01.25
java 역어셈블러와 역컴파일러  (0) 2012.01.23
자바 데몬(daemon) 만들기  (0) 2012.01.18
Hotspot JVM의 Garbage Collector  (0) 2012.01.18
java - RMI  (0) 2012.01.17
Posted by linuxism
,
1. 데몬(daemon) 이란?
주기적인 서비스 요청을 처리하기 위해서 커널상에 백그라운드 모드로 실행되는 프로세스로, 메모리 관리 방법에 따라 단독 데몬과 xinetd로 분리된다.

  • 단독데몬
    항상 백그라운드 모드로 실행되고 메모리를 상대적으로 많이 소비한다. 그러나 서비스(응답속도)가 빠르다. httpd와 같은 웹서비스 데몬이 대표적.
  • xinetd(슈퍼데몬)
    요청이 있을때마다 xinetd가 서비스를 싱행시켜주므로 메모리 소비가 적다. 그러나 단독데몬에 비해 상대적으로 서비스 속도가 느리다.


2. 간단한 자바 데몬 만들기
nohup을 이용해서 java를 실행시킨다.

터미널이 종료될 때(쉘이 종료될 때) 프로세스가 죽는 이유는 해당 프로세스가 쉘의 자식 프로세스 이기 때문이다. 따라서, 부모 프로세스가 죽을대 던지는 SIGHUP을 자식 프로세스가 받게 된다.

nohup은 부모 프로세스가 죽을때 자식 프로세스에게 SIGHUP을 던지지 않는 프로세스를 말한다.

$ nohup java 클래스명 & 
 
사용하기 편한 장점은 있으나, 문제는 중지를 시킬수 없다. 즉, 해당 프로세스 ID를 찾아내 kill하는 수 밖에 없다. 물론 파일 체크 기법, 소켓을 이용한 제어 방법등을 사용할 수 있지만 스스로 구현해야 하는 번거로움이 있다.


3. apache commons daemon 이용하기
Java는 UNIX의 시그널 처리를 할수 없기때문에, 중지 신호(TERM signal)를 처리하기 위해서는 따로 구현을 해야한다. 이런 번거로움을 해결하기 위해 자카르타의 하위 프로젝트중의 commons daemon을 이용한다. commons daemon은 중지 신호를 받으면 미리 지정된 메소드를 실행한다.

UNIX용 Jsvc와 윈도우용 Procrun 있다.
여기서는 Jsvc를 이용해보도록 하겠다.


commons daemon을 다운로드해 압축을 해제하면 위 그림과 같다.
commons-daemon.jar 파일은 Java프로젝트 lib폴더에 복사해둔다.


bin폴더의 압축파일을 해제하면 jsvc-src라는 폴더가 나온다.
폴더의 내용은 위와 같다.
commons daemon을 사용하기 위해서는 바로 여기서 jsvc를 빌드해줘야 한다.
빌드환경은 다음과 같다.(리눅스에서 빌드해야한다.)

  • GNU AutoConf(at least 2.53)
  • ANSI-C compliant compiler(GCC is good)
  • GNU Make
  • A Java Platform 2 compliant SDK

여기서부터는 ubuntu 8.10 환경에서 진행하도록 한다.

먼저 JDK가 설치되어 있지 않다면 JDK를 설치한다.

 $ sudo apt-get install sun-java6-jdk

JDK가 설치되는 경로는 /usr/lib/jvm/java-6-sun 이다.

gcc 및 make 가 설치되있지 않다면 아래 명령를 이용해 한방에 설치한다.

 $ sudo apt-get install build-essential

AutoConf가 설치되있지 않다면 AutoConf를 설치한다.

 $ sudo apt-get install autoconf

Jsvc를 빌드하는 방법은 다음과 같다.

  • support/buildconf.sh
  • ./configure --with-java=/usr/lib/jvm/java-6-sun
  • make


빌드가 성공적으로 이루어졌다면 위 그림과 같이 jsvc가 만들어진것을 확인할 수 있다. 이후 이 파일을 가지고 Java 데몬을 실행한다.

Java 데몬을 만들려면 org.apache.commons.daemon.Daemon 인터페이스의 init, start, stop, destory 메소드를 구현해야 한다.

샘플 코드는 아래와 같다.
import org.apache.commons.daemon.Daemon;
import org.apache.commons.daemon.DaemonContext;

public class DaemonTest implements Daemon {

	Thread t = null;
	
	@Override
	public void init(DaemonContext arg0) throws Exception {
		System.err.println("daemonTest init");
		t = new DaemonThread();
	}

	@Override
	public void start() throws Exception {
		System.err.println("daemonTest start");
		t.start();
	}

	@Override
	public void stop() throws Exception {
		System.err.println("daemonTest stop");
		t.interrupt();
	}
	
	@Override
	public void destroy() {
		System.err.println("daemonTest destroy");
	}
}
public class DaemonThread extends Thread {

	@Override
	public void run() {
		while( Thread.interrupted() ) {
			System.err.println("run");
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
				return;
			}
		}
	}	
}
init에서 초기화, start에서 처리할 작업을 별도의 쓰레드로 생성해서 실행한다. start 메소드 호출후 반드시 return 되어야 데몬이 시그널 처리를 제대로 할 수 있다.
stop, destroy 는 중지 신호가 오면 차례되로 호출된다.

이제 실행/중지 스크립트를 작성한다.
Jsvc를 싱행하는데 필요한것은 실행하는 계정(user), JAVA_HOME(-home), 프로세스ID 파일(-pidfile), 출력지정(-outfile, -errfile), 클래스파일(-cp) 등이 있다.
#!/bin/sh
JAVA_HOME=/usr/lib/jvm/java-6-sun
DAEMON_HOME=/home/lyb1495/commons-daemon-1.0.1/bin/jsvc-src
DAEMON_USER=lyb1495
DAEMONTEST_HOME=/home/lyb1495/workspace/Daemon
PID_FILE=$DAEMONTEST_HOME/daemon_test.pid

CLASSPATH=\
$DAEMONTEST_HOME/bin:\
$DAEMONTEST_HOME/lib/commons-daemon.jar

case "$1" in

	start)
    #
    # Start Daemon
    #
    $DAEMON_HOME/jsvc \
    -user $DAEMON_USER \
    -home $JAVA_HOME \
    -wait 10 \
    -pidfile $PID_FILE \
-errfile '&1' \
    -cp $CLASSPATH \
    DaemonTest
    #
    # To get a verbose JVM
    #-verbose \
    # To get a debug of jsvc.
    #-debug \
    exit $?
    ;;

  stop)
    #
    # Stop PostMan
    #
    $DAEMON_HOME/jsvc \
    -stop \
    -pidfile $PID_FILE \
    DaemonTest
    exit $?
    ;;
#
  *)
    echo "Usage DaemonTest.sh start/stop"
    exit 1;;
esac
이제 Java 데몬을 실행하기 위한 모든 준비를 마쳤다.


위에서 작성한 스크립트 파일을 이용해 Java 데몬을 실핸한다.
정상적으로 데몬이 시작된다면 PID_FILE에 지정한 파일이 생성된것을 확인할 수 있다.


데몬을 중지하려면 start 대신 stop을 입력으로 스크립트를 실행하면 된다.

출처 - 
http://lyb1495.tistory.com/11 
Posted by linuxism
,