top bar

글 목록

2015년 7월 29일 수요일

[WebDev] Apache 2 설치 기초

아파치는 두말 할 필요없는 웹서버다. 이런저런 설명을 생략하고 일단 설치해보자.

환경은 CentOS 6 이다.

설치



1) 다운로드
$ wget 'http://mirror.apache-kr.org//httpd/httpd-2.2.31.tar.gz'

2) 압축해제
$ tar -xvzf httpd-2.2.31.tar.gz

3) 컴파일
$ cd httpd-2.2.31
$ ./configure --prefix=APACHE_HOME --with-included-apr
$ make
'APACHE_HOME' 에는 설치할 경로를 입력하면 된다. 'make'로 소스를 컴파일 한다. 컴파일이 잘못된 설정으로 되었을 경우, 'make clean' 으로 초기화 할 수 있다.

4) 설치
$ make install

설정



설치가 되었으면, 'APACHE_HOME/conf/httpd.con' 파일을 열어본다. default 값으로 user와 group이 아래와 같이 설정되어있을 것이다.
#
# If you wish httpd to run as a different user or group, you must run
# httpd as root initially and it will switch.
#
# User/Group: The name (or #number) of the user/group to run httpd as.
# It is usually good practice to create a dedicated user and group for
# running httpd, as with most system services.
#
User deamon
Group deamon
사용자와 사용자그룹을 각 환경에 맞게 입력한다.

그리고 'APACHE_HOME/bin' 디렉토리로 이동하여 아래와 같이 httpd.conf 설정파일의 Syntax를 체크해본다
$ ./apachectl configtest
Syntax OK
설정 문법에 이상이없으면 실행한다. 이때 권한이 없다면 root계정으로 로그인하여 'sudo' 명령을 활용한다.
$ ./apachectl start
httpd 데몬이 제대로 올라갔는 지도 확인한다.
$ ps -ef | grep httpd
root      5121     1  0 14:03 ? 00:00:00 /home/asuraiv/apps/apache/bin/httpd -k start
asuraiv    5122  5121  0 14:03 ? 00:00:00 /home/asuraiv/apps/apache/bin/httpd -k start
asuraiv    5123  5121  0 14:03 ? 00:00:00 /home/asuraiv/apps/apache/bin/httpd -k start
asuraiv    5124  5121  0 14:03 ? 00:00:00 /home/asuraiv/apps/apache/bin/httpd -k start
asuraiv    5125  5121  0 14:03 ? 00:00:00 /home/asuraiv/apps/apache/bin/httpd -k start
asuraiv    5126  5121  0 14:03 ? 00:00:00 /home/asuraiv/apps/apache/bin/httpd -k start
asuraiv  5133  5077  0 14:04 pts/0    00:00:00 grep httpd
자, 이제 브라우저에서 해당 서버의 IP로 접근하게되면 아래와 같은 화면이 노출될 것이다.


2015년 7월 21일 화요일

[Elasticsearch] Logstash 설치와 기본개념

1. 개요



Logstash는 입출력 도구이다. 다양한 종류의 로그 (System logs, webserver logs, error logs, application logs) 뿐만아니라 입력되는 모든 종류의 데이터를 가공하여 출력할 수 있다.

Elasticsearch와 궁합이 잘 맞아 지금은 Elasticsearch의 공식 패키지에 포함되어 있다고 한다. 이제 그 Logstash 설치해보고 기본적인 개념들을 살펴보도록 한다.

2. Logstash 설치와 간단예제



일단 설치해보자.

1) download
$ wget 'http://download.elastic.co/logstash/logstash/logstash-1.5.1.tar.gz'

2) 압축풀기
$ tar -xvzf logstash-1.5.1.tar.gz

끝났다(..) 정말이다.

Logstash는 위에서 언급했듯이 입출력 도구이며,
input > filter > output 의 pipeline구조로 구성되어있다.










  • input : 데이터를 받아들인다
  • filter : 데이터를 가공한다
  • output : 데이터를 출력한다

이러한 input, filter, output 설정은 직접 configuration 파일을 작성하여 설정해야하는데,
문법은 아래와 같다
input {
        .
        .
        .
}

filter {
        .
        .
        .
}

output {
        .
        .
        .
}
엄청 간단해 보인다. 하지만 어떤 기술이든 마찬가지로 기본은 쉬워보이는법,, 조금만 파고들어가면 걷잡을 수 없이 미로를 헤맬수  있다.

여튼 가장 기본적인 설정 즉, 입력은 stdin, 출력은 stdout 으로 설정하여 어떤식으로 입출력을 처리하는지 살펴보자. 일단 설정파일은 아래와 같이 매우 간단하다.
$ cat logstash.conf
input {
        stdin { }
}

output {
        stdout {
                codec => rubydebug { }
        }
}
주목할 부분은 stdout 설정에 codec을 추가했다는 것이다. rubydebug는 출력을 보기좋은 포맷으로 바꿔 준다.

이제 logstash 압축을 해제한 디렉토리의 /bin 디렉토리로 이동하여 아래와같은 명령어로 conf 파일과 함께 실행 시킨다.
$ ./logstash -f [configuration file path]/logstash.conf
실행이 되었으면 stdin 으로 'Hello world'를 입력해보자
$ ./logstash -f logstash.conf
Logstash startup completed
Hello world!
{
       "message" => "Hello world!",
      "@version" => "1",
    "@timestamp" => "2015-07-21T11:47:37.140Z",
          "host" => "cweb02.ami"
}
표준 입력으로 Hello world! 라는 문자열을 입력했고, 표준 출력으로 출력이되며 rubydebug 코덱으로 인해 json 형식으로 출력된다. 이때 message, @version, @timestamp 등의 필드는 Logstash에 내장 되어있는 필드라고 볼 수 있다.

input, output 플러그인의 종류는 매우 많다. 물론 데이터의 출력과 동시에 Elasticsearch에 색인작업을 해주는 elasticsearch output plugin도 존재한다.
아래의 문서들을 참고하자!

  • input plugins : https://www.elastic.co/guide/en/logstash/current/input-plugins.html
  • output plugins : https://www.elastic.co/guide/en/logstash/current/output-plugins.html
  • codec plugins : https://www.elastic.co/guide/en/logstash/current/codec-plugins.html

filter 설정을 적용하면, 입력으로 들어온 데이터를 가공하는 작업을 수행한다. 예를들어 json 형식으로 데이터가 입력되었다면 필드를 삭제, 추가하거나 필드의 값을 조작할 수 있다. 여기서는 json 데이터를 가공해주는 json filter를 적용해보자.

아래와 같이 conf 파일을 수정한다
input {
        stdin { }
}

filter {
        json {
                source => "message"
                add_field => { "new_field1" => "New field value!"  }
                add_field => { "new_field2" => "My name is %{name}" }
                remove_field => [ "useless_field" ]
        }
}

output {
        stdout {
                codec => rubydebug { }
        }
}
filter로서 'json' filter를 추가했다. source 설정은 가공할 데이터가 들어있는 field를 가리킨다. add_field는 말그대로 field를 추가하는 것으로서, static한 고정값을 가지고있는 field를 추가할 수도있고, 기존 source의 데이터의 필드값을 '%{field이름}' 을 사용해 접근할 수 있다.

이제 이러한 설정을 저장하고, 실행한 뒤 표준 입력으로 json 포맷을 던져보자.
$ ./logstash -f logstash.simple.conf
Logstash startup completed
{ "name" : "timmy", "address" : "boston", "useless_field" : "garbage value" }
{
       "message" => "{ \"name\" : \"timmy\", \"address\" : \"boston\", \"useless_field\" : \"garbage value\" }",
      "@version" => "1",
    "@timestamp" => "2015-07-21T12:03:38.577Z",
          "host" => "cweb02.ami",
          "name" => "timmy",
       "address" => "boston",
    "new_field1" => "New field value!",
    "new_field2" => "My name is timmy"
}
{ "name" : "timmy", "address" : "boston", "useless_field" : "garbage value" } 와 같은 json 데이터를 표준입력을 통해 입력했다. name필드값으로 'timmy', address필드값으로 'boston'을 입력하였고, 필드 삭제 예제를 위해 'useless_field'도 추가했다.

결과는? 입력된 값 바로아래에서 볼 수 있다. 일단은 위에서 설명한것처럼 message, @version, @timestamp, host 필드는 Logstash의 내장 필드이다. 그 아래로, name과 address가 정상적으로 출력되고 있고, remove_field 설정으로 인해 'useless_field'는 삭제되었다.

그리고 add_field 설정에서 정의된 new_field1, new_field2 필드들이 새로 추가 되었으며, 주목할만한건 new_field2 의 값인데, %{name} 와 같이 기존 데이터의 필드의 값을 접근하여 새로운 필드의 값으로 저장된 것을 볼 수 있다.

짐작했겠지만 다양한 종류의 데이터를 가공하기 위해 필터의 종류도 매우 다양하다. 아래를 참고 하자.

fileter plugins : https://www.elastic.co/guide/en/logstash/current/filter-plugins.html

3. 결론



아무튼 Logstash는 input, filter, output 의 파이프라인 구조로 되어있다는 점, 더불어 input과 output의 한 부분으로 동작하며 데이터를 변화시키는 codec도 기억하면 좋을 것이다.

Elasticsearch와의 연동은 다음 포스팅으로 미루겠다.. (힘듬)





2015년 7월 19일 일요일

[JAVA] 리눅스에 JDK 설치

리눅스에 자바를 설치 해본다

현재 환경

배포판
CentOS 6.6
커널버전
2.6.32-504.23.4.el6.x86_64
환경
x86_64 GNU/Linux

java version을 확인해보았더니, 기존에 설치된 버전이 있었다
$ java -version
java version "1.6.0_35"
하지만 우리는 1.7.0_79 버전을 설치하겠당

1) Java download

일단 우리가 잘 아는 'wget' 커맨드로 jdk를 내려받는다
$ wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz"

2) 압축 해제

내려받은 tarball 파일을 압축해제 한다
$ tar -xvzf jdk-7u79-linux-x64.tar.gz

3) Symbolic Link 설정

심볼릭 링크로 접근을 간단하게 한다
$ ln -s jdk1.7.0_79/ jdk7

4) 환경변수 설정

아래와같은 명령어로 자바 버전을 확인해보면 여전히 1.6이다.
당연하다. 환경변수를 설정하지 않았으니깐...
$ java -version
java version "1.6.0_35"
CentOS에서 환경변수는, '.bashrc' 파일을 통해서 설정 할 수 있는데, 엄밀히 말하면 전역적인 환경변수가 아니라 지역적인 환경변수이다.

왜냐하면 ~/.bashrc 파일에 설정된 alias들은, 해당 아이디로 로그인한 사용자에게만 적용되는 설정이기 때문이다. 암튼 설정해보자.
$ vi ~/.basrhc

# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific aliases and functions

export LC_ALL=ko_KR.UTF-8
export LANG=ko_KR.UTF-8

# 아래를 추가한다!
# 'bin' 디렉토리를 포함하는 디렉토리까지 JAVA_HOME으로 설정
JAVA_HOME=/home/asuriv/apps/jdk7

PATH=${JAVA_HOME}/bin:$PATH
위 설정에서 JAVA_HOME을 변수를 정의하여 PATH에 추가한다.

그리고 source 커맨드를 .bashrc에 날려서 반영한다.
$ source ~/.bashrc
다시 아래와같이 버전을 확인해보면 1.7.0_79로 바뀌어있을것이다.
$ java -version
java version "1.7.0_79"

5) Hello World!

새로 설치한 jdk를 테스트할겸 심심한데 hello world나 찍어보자
왠만한 자바 문법 서적의 첫장에 있는 아래의 코드를 추가해보자.
class HelloWorld {

        public static void main(String[] args) {
                if(args.length > 0) {
                        System.out.println("Hello World! Hello " + (String)args[0]);
                        return ;
                }
                System.out.println("Parameter is empty!");
        }
}
그냥 일반적인 hello world는 밋밋하니, 파라메터를 받아서 찍어주는식으로 작성해봤다.
이제 컴파일하자.
$ javac HelloWorld.java
그리고 실행
$ java HelloWorld HongJuPyo
Hello World! Hello HongJuPyo

$ java HelloWorld
Parameter is empty!




2015년 7월 12일 일요일

[JAVA] Iterator

 Iterator는 하나의 객체로서, 객체가 저장된 컨테이너 사이를 이동하면서 각 객체를 선택해 주는 역할을 한다. 이때, 클라이언트 프로그래머는 그 컨테이너의 기반구조에 대해 알거나 신경쓸 필요가 없다.

어떤 종류의 컨테이너로 이루어 졌는지, 예컨데 ArrayList 인지, LinkedList인지, HashSet 인지 알 필요가 없는 것이다. 공통된 인터페이스를 사용하여 컨테이너의 객체들을 선택할 수 있다. 추상화의 대표적인 모델이라고 할 수 있다.

아래는 Iterator의 기본 인터페이스 이다.

메서드
설명
next()
컨테이너의 다음 요소를 반환한다
hasNext()
꺼낼 요소가 있는지 확인한다
remove()
가장 최근에 반환된 요소를 삭제한다. 따라서 next() 메서드를 호출할 때마다 사용할 수 있다.


아래는 next()와 hasNext() 메서드를 사용한 Iterator의 기본 사용 예제이다.
public class IteratorTest {
    
    public static void display(Iterator<String> it) {
        
        System.out.print("[");
        while(it.hasNext()) {
            String s = it.next();
            System.out.print(" " + s + " ");            
        }
        System.out.println("]");
    }
    
    public static void main(String[] args) {    

        List<String> strings = Arrays.asList("A", "B", "C", "D", "E", "F"); // ArrayList
        
        LinkedList<String> stringsLL = new LinkedList<String>(strings);
        HashSet<String> stringHS = new HashSet<String>(strings);
        TreeSet<String> stringsTS = new TreeSet<String>(strings);
        
        display(strings.iterator());
        display(stringsLL.iterator());
        display(stringHS.iterator());
        display(stringsTS.iterator());
    }
}
> 결과
[ A  B  C  D  E  F ]
[ A  B  C  D  E  F ]
[ D  E  F  A  B  C ]
[ A  B  C  D  E  F ]
위의 예제처럼, display() 메서드는 인자로 전달되는 Iterator의 기반 컨테이너 타입을 모른다. 하지만 추상화된 인터페이스를 통해 아주 잘 동작하는것을 볼 수 있다. 이것이 Iterator의 소소하지만 강력함? 이라고 할 수 있을 것이다.