Tagged: 리눅스

[발 번역] 자바 가비지 컬렉션

이글은 Garbage Collectors Available In JDK 1.7.0_04 를 발 번역한 것입니다.

Jack Shirazi 씨는 가비지 컬랙터가 무엇이고 오파클 자바 7 업데이트 4 JVM 에서 활용할 수 있는 가비지 컬렉터 조합에 대해서 말해줄 것입니다.

Published June 2012, Author Jack Shirazi

마침내 G1 을 공식적으로 – i.e. 더 이상 실험적 가비지 컬렉터가 아니다 – 1.7.0_04 (Java 7 update 4) 릴리즈에서 지원되며 이것은 이제 Sun JVM 의 가비지 컬렉터 측면에서 활용가능한 가치있는 주식(?)을 가지는 중임을 말한다. 아래에 기술할 자세한 사항은 다른 많은 Sun JVM 버전에 적용가능성이 높지만 특별히 Sun 1.7.0_04 JVM 과 연관된다.

현재 7개의 주요한 가비지 컬렉션 알고리즘이 있고 그중에 하나는(PS Scavenge), 우리가 두가지 다른 알고리즘으로 부르는(adaptive GC 를 가진것과 가지지 않은것), 확실히 다른 두가지 모드(Mode)를 가지고 있고 아주 많은 옵션들을 가지는 다른것들은(concurrent collector) 실질적으로 나머지 절반의 알고리즘을 구성한다. 이것은 우리가 여기서 해야할 가비지 컬렉터 리스트를 위해 유용하다.

첫째로, 나는 실질적으로 다른 주요한 가비지 컬렉터들을 특징지을 것이다. 그것은 7가지다.(나는 G1 컬렉터까지 포함했다.)

Garbage CollectorGeneration
CopyYoung generation
PS ScavengeYoung generation
ParNewYoung generation
G1 Young GenerationYoung generation
PS MarkSweepOld generation
ConcurrentMarkSweepOld generation
G1 Mixed GenerationOld generation

Young generation collectors

Copy (enabled with -XX:+UseSerialGC)

the serial copy collector는 에덴(Eden) 영역에서 살아남은 객체들을 Survivor space로 복사하기 위해서 그리고 Survivor space 사이에서 객체들을 old generation 으로 복사할 시점에서 충분히 오랫동안 객체가 존재하는지 결정될때까지 하나의 쓰레드(thread)를 사용합니다.

PS Scavenge (enabled with -XX:+UseParallelGC)

the parallel scavenge collector 는 복사 컬렉터(the serial Collector)와 유사하지만 병렬로 여러개의 쓰레드를 사용하고 old generation 을 수집하는 방법에 대한 몇가지 지식을 가지고 있다. (기본적으로 serial 과 PS old gen 컬렉터를 함께 동작하도록 작성하라)

ParNew (enabled with -XX:+UseParNewGC)

the parallel copy collector 는 복사 컬렉터(the serial Collector)와 유사하지만 병렬로 여러개의 쓰레드를 사용하고 old generation collector 가 수집하는 객체에서 작동하도록 허용한 내부 콜백(callback)을 허용한다. (실제로 concurrent collector와함께 동작하도록 작성하라)

G1 Young Generation (enabled with -XX:+UseG1GC)

the garbage first collector 는 힙영역을 수 많은 작은 공간으로 나누는 ‘Garbage First’ 알고리즘을 사용하지만 이것은 여전히 G1 을 위해서 young genration 을 Eden 영역과 Survivor space로 나눈다.

Old generation collectors

MarkSweepCompact (enabled with -XX:+UseSerialGC)

the serial mark-sweep collector는, 모든 컬렉터의 아버지, 옵션으로 압축(compaction) 기능을 가지는 시리얼(하나의 쓰레드) 풀 mark-sweep 가비지 컬렉션 알고리즘을 사용한다.

PS MarkSweep (enabled with -XX:+UseParallelOldGC)

the parallel scavenge mark-sweep collector, MarkSweepCompact 의 패러럴 버전이다.

ConcurrentMarkSweep (enabled with -XX:+UseConcMarkSweepGC)

the concurrent collector, 컬렉션이 동작하는 동안 애플리케이션 쓰레드들이 정지 없이 백그라운드로 대부분의 가비지 컬렉션 작업을 하도록 시도하는 가비지 컬렉션 알고리즘이다. (여전히 애플리케이션 쓰레드가 정지되는 단계가 있지만 이러한 단계는 최소로 유지되도록 시도된다.) 주의할 것은 concurrent collector 가 가비지를 수집에 실패한다면, 다음번 GC를 위한 the serial MarkSweepCompact collector 도 실패한다.

G1 Mixed Generation (enabled with -XX:+UseG1GC)

the garbage first collector는 힙(heap)을 아주 많은 작은 공간들로 나누는 ‘Garbage First’ 알고리즘을 사용한다.

ConcurrentMarkSweep 제외한 모든 가비지 컬렉션 알고리즘은 stop-the-world 고, i.e 그들이 동작하는 동안에 모든 애플리케이션 쓰레드들을 정지시킨다 – 정지(the stop)은 ‘멈춤시간(pause time)’ 으로 알려져 있다. ConcurrentMarkSweep 는 모든 작업을 백그라운드로 동작하고 멈춤시간을 최소화하도록 노력하지만 이 컬렉션도 stop-to-world 단계를 가지며 완전한 stop-the-world 를가지는 MarkSweepCompact 가 실패할수 있다.

Combinations of Garbage Collectors

그것은 활용할 수 있는 가비지 컬렉션의 집합이지만, 그들은 두개의 서로다른 힙(heap) 공간에서 운영되고 이것은 우리가 실제로 특정한 JVM 세팅을 가지는 조합이며, 그래서 나는 가능한 조합들을 보여줄 것이다. 이것은 이러한 모든 컬렉션들은 서로함께 동작하기 때문에 여러 묶음 조합이 나올수 없다. G1 다른것들과 동작하지 않는 반사회적(antisocial) 컬렉터이고 the serial collector 는 최후의 보루 컬렉터, ‘PS’ 컬렉터는 다른 것들과 함께 동작하는게 좋고 ParNew 와 Concurrent는 서로함께 동작하는게 좋다. 물론 이렇게 아주 단순화 할수는 없지만, 그래서 여기에 내가 생각하는 가비지 컬렉션 알고리즘 옵션들내에 메인 옵션 리스트들이다. 퀴즈의 비트를 좋아하는 부류의 사람들에게서는, 다양한 JVMS 들에서 -Xincgc 와 -XX:+UseTrainGC 사용해 활용할 수 있는(이러한 플래그는 더 이상 유용하지 않으며 정식 플래그에서는 ParNew 와 Concurrent 를 사용하는것으로 변경되었으며 -XX:+UseTrainGC 플래그는 이 JVM에서 시작시 에러를 발생시킨다) “train” 가비지 컬렉터를 우리는 시간이 지남에따라 잃어버렸다.

GC 알고리즘을 조합해 동작할 수있는 Full list:

Command Options (1)Resulting Collecto Combination
-XX:+UseSerialGCyoung Copy and old MarkSweepCompact
-XX:+UseG1GCyoung G1 Young and old G1 Mixed
-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicyyoung PS Scavenge old PS MarkSweep with adaptive sizing
-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:-UseAdaptiveSizePolicyyoung PS Scavenge old PS MarkSweep, no adaptive sizing
-XX:+UseParNewGCyoung ParNew old MarkSweepCompact
-XX:+UseParNewGC -XX:+UseConcMarkSweepGCyoung ParNew old ConcurrentMarkSweep (2)
-XX:-UseParNewGC -XX:+UseConcMarkSweepGCyoung Copy old ConcurrentMarkSweep (2)
(1) 이 리스트들의 모든 조합은 오직 -XX:+UseConcMarkSweepGC 와 조합할 수 있는 -XX:+UseParNewGC를 제외하고 이 리스트에 없는 다른 GC 알고리즘을 추가하하고 JVM을 시작시키면 실패할 것이다.
(2) 알고리즘을 바꾸는 -XX:+UseConcMarkSweepGC 와 함께 사용할 경우 아주 아주 많은 옵션들이 있다. 예를들어
* -XX:+/-CMSIncrementalMode - an incremental concurrent GC algorithm 를 사용 혹은 비활성.
* -XX:+/-CMSConcurrentMTEnabled - parallel (multiple threads) concurrent GC algorithm 을 사용 혹은 비활성.
* -XX:+/-UseCMSCompactAtFullCollection - Full GC가 발생할때 압축(compaction)을 사용 혹은 비활성

위와 똑같은 다른 옵션들

Command Options Used On Their OwnEquivalent To Entry In Table Above
-XX:+UseParallelGC-XX:+UseParallelGC -XX:+UseParallelOldGC
-XX:+UseParallelOldGC-XX:+UseParallelGC -XX:+UseParallelOldGC
-Xincgc-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
-XX:+UseConcMarkSweepGC-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
no option on most Windows-XX:+UseSerialGC (see also this page)
no option on most Unix-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy (see also this page) - 역주) 이것은 잘못된 내용이다. Java 버전에 따라 Default 옵션이 다르다.
-XX:+AggressiveHeapOS와 어떻게 서로 상호작용하고 메모리와 쓰레드의 크기와 연관된 옵션들의 묶음인 -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy

JAVA에서 스크린 Refresh 하기

리눅스 터미널에서 실행되는 각종 모니터링 프로그램들을 보면 화면이 그대로 인채 수치만 바뀌는 형식을 취하는 프로그램들이 많다. 사실 터미널 스크린을 빠르게 Refresh 하는것인데, 자바에서는 다음과 같이 프로그래밍을 하면 된다.

Console 객체를 이용해 구현한다.

Jmxterm – 커맨드 라인 JMX

JAVA 에는 JMX(Java Management Extension) 이라고해서 JAVA 애플리케이션을 관리하기 위한 확장을 제공합니다. JAVA 애플리케이션을 시작할때에 다음과 같이 JVM 옵션을 주게되면 사용할 수 있습니다.

  • -Dcom.sun.management.jmxremote
  • -Dcom.sun.management.jmxremote.port
  • -Dcom.sun.management.jmxremote.authenticate
  • -Djava.rmi.server.hostname
  • -Dcom.sun.management.jmxremote.ssl

hostname, port 그리고 authenticate 을 설정하면 특정 호스트에서 특정포트를 통해서 인증을 통해서 JMX 클라이언트를 통해서 접속할 수 있는데, JMX 클라이언트로 가장 유명한 것이 JConsole 입니다.

jconsole

그런데, 보안상의 이유로 JMX 는 활성화하되 접속은 로컬호스트에서만 되도록 설정을 해놓는 경우가 많습니다. 다음과 같이 말입니다.

대부분의 로컬호스트가 리눅스일 경우에는 JConsole 을 이용하기 위해서는 터미널의 터널링을 해주는 방법등을 동원하는데 JConsole 이 아닌 jmxterm 프로그램을 이용하면 리눅스 터미널에서 jmx 를 활용할 수 있습니다.

jmxterm

jmxterm 은 JMX Terminal 로 자바로 작성된 커맨드 라인 JMX 클라이언트 입니다. 다른 추가적인 라이브러리가 필요없이 jdk 만 있으면 동작하고 사용자와 상호작용을 할수 있도록 Interactive 하게 동작합니다.

또, JMX 서버 설정대로 인증을 할 수 있고 로컬호스트라면 JAVA 애플리케이션의 PID 를가지고 접속을 할수 있습니다.

Interactive 작업시 탭키(Tab key) 를 이용한 자동완성기능(Auto completion)을 제공합니다. 따라서 MBean domain 이나 Beans 들을 전부 외울 필요가 없습니다.

다운로드 

다운로드는 다음의 주소에서 다운받을 수 있습니다.

사용방법.

이제부터 간단한 예제를 통해서 어떻게 사용하는지 알아보겠습니다.  먼저 Tomcat 을 실행하는데, JMX 를 로컬호스트를 통해서만 접속할 수 있도록 옵션을 주고 실행했습니다. 다음과 같이 말이지요.

JMX 포트는 8090 이고 인증은 없으며 로컬호스트에서만 접속되도록 했습니다.

이제 jmxterm 을 실행합니다.

위와같이 $> 프롬프트가 나옵니다. 여기서 이제 JMX로 접속을 해야 합니다. 프롬프트에서 다음과 같이 입력을 합니다.

접속방법은 위와같이 “open 로컬아이피:포트” 형식입니다. 만일 Tomcat 의 PID 를 알고 있다면 “open PID” 형식으로도 접속을 할 수 있습니다.

이제부터는 JMX 의 MBeans Domain, Beans 를 이용해서 JMX 의 속성들을 찾을 수 있습니다. 먼저 Domain 목록은 다음과 같이 조회를 합니다.

domain 리스트를 확인했으니 domain 을 지정할려면 “domain 도메인명” 을 입력해주면 됩니다.

domain을 지정했으니 이제는 bean 들을 볼 수 있습니다. 다음과 같이 합니다.

그럼 Bean 을 지정할려면 어떻게 해야할까요? 짐작대로 “bean 빈명” 해주면 됩니다.

bean 은 각종 속성과 액션들을 가지고 있는 셋트입니다. 이들을 보기 위해서는 info 명령어를 사용합니다.

위와같이 bean 에 속하는 속성들을 볼 수 있고 액션도 볼수 있습니다.(위 예제에서는 액션은 안나왔네요.)

속성이 가지고 있는 값을 보기 위해서는 “get 속성” 을 해주시면 됩니다.

각 속성들은 리턴타입에 맞게 화면에 표시됩니다.

이렇게 리눅스 터미널에서도 얼마든지 JMX 를 이용할 수 있습니다.

SSH 포트 포워딩.

많은 IT 종사자들은 회사 보안 때문에 특정 서버에 포트를 오직 SSH 와 서비스를 위한 포트만을 열어둔 경우가 많다. 그런데 서버를 관리하다보면 특정 서비스 체크를 위한 매니징 서비스에 접속을 해야하는 경우가 발생한다. 이럴 경우 사내 보안팀에 매니징 서비스 접속을 위해서 포트를 개방해 줄것을 요구할 수 있지만 이럴때에 SSH 의 포트 포워딩(Port Forwarding)을 이용하면 쉽게 해결 할 수 있다.

SSH 포트 포워딩에도 다음과 같이 세가지 종류가 있다.

  • Local Port Forwarding
  • Remote Port Forwarding
  • Dynamic Port Forwarding

SSH 포트 포워딩은 SSH 서버를 Gateway 나 Proxy 서버처럼 활용해 외부 접속을 하는 것이여서 터널링(Tunneling)이라고 부르기도 한다. 각 포트 포워딩 설명을 예제상황을 가정해 설명하도록 하겠다.

192.168.96.6 서버에는 Tomcat 서버가 가동중이고 Web 접속 포트는 8180 이며 서버 상태를 체크하기 위한 JMX 가 활성화 되어 있고 이 포트는 8190 이다.

현재 이 서버는 테스트 서버여서 자체 방화벽으로 22번 포트만 개방되어 있고 Web 접속 포트와 JMX 포트가 개방되어 있지 않다.

접속하고자 하는 사용자의 PC는 리눅스를 사용한다.

위 말을 도식화 하면 다음과 같다.

Local Port Forwarding 상황

Local Port Forwarding

접속은 SSH 포트인 22번만 열려있고 Tomcat 관련 포트는 리눅스 서버의 로컬 방화벽으로 막혀 있는 상황이라고 가정하자.

이제 Tomcat 서비스에 접속을 하고 싶다면 어떻게 해야하는 걸까? 이럴때 사용하는 것이 바로 Local Port Forwarding 이다. 형식은 다음과 같다.

ssh 의 ‘-L’ 옵션이 바로 Local Port Forwarding 을 하도록 해주는 것이다. <local port> 는 접속하는 클라이언트에서 사용할 포트이며 <Remote Server> 는 접속할 서버(여기서는 192.168.96.6) 를 Gateway 로 이용해 접속할 서버, <Remote Port>는 Remote Server 의 포트이다.

여기서 한가지 주목해야할 것이 [SSH 서버] 는 Gateway 역활을 할 뿐이라는 사실이다. 예를 들어 [SSH 서버] 에서는 외부로 모든 접속이 가능하다라고 가정했을때에 yahoo.com 의 80 포트로 Local Port Forwarding 은 다음과 같다.

위와같이 한후에 클라이언트 PC(여기서는 왼쪽에 있는 컴퓨터)에서 웹 브라우져를 켜고 주소창에 ‘http://localhost:10030’ 이라고 하면 yahoo.com 이 열리게 된다.

다시 가정한 상황으로 돌아오면 Gateway 서버(여기서는 192.168.96.6서버) 외부가 아닌 그 자체의 서비스들을 포워딩할 것이기에 다음과 같이 하면 된다.

이렇게 한 후에 웹 브라우져를 실행하고 주소창에 ‘http://localhost:10030’ 이라고 입력하면 192.168.96.6 서버의 Tomcat 서버 포트인 8180 에 연결되고 톰캣 페이지가 보이게 된다.

Local Port Forwarding 이기 때문에 웹 브라우져에서의 접속 서버명은 항상 localhost 가 된다.

Remote Port Forwarding 

이것은 필자가 아직 다루어보지 못했기에 설명을 생략한다.

Dynamic Port Forwarding

이 포워딩은 접속하는 서버를 SOCKS Proxy 서버로 동작하도록 한다. Local Port Forwarding 에서 접속하는 서버는 Gateway 서버로 동작을 했지만 이 포워딩은 접속하는 서버를 Proxy 서버로 그것도 SOCKS 동작하게 한다.

Proxy 서버이기 때문에 클라이언트에서 접속할때에는 항상 실제 접속을 하는 서버와 포트를 사용하면 된다.

JDK 1.7 이상부터는 JMC(Java Mission Control) 이 함께 설치된다. 이걸 이용하면 Java 애플리케이션의 각종 정보를 볼 수 있는데, 물론 JMX 에 접속도 가능하다. 위 예제 상황에서 Dynamic Port Forwarding 을 이용해 접속해보자.

사용방법은 간단하다.

위와같이 하게되면 192.168.96.6 서버가 포트 10030 으로 Proxy 서버로 역활을 하게된다. 이제 클라이언트에서 JMC 를 구동하고 다음과 같이 Network 설정을 해준다.

JMC Socks Network 설정

그리고 나서 JMX 접속 서버와 포트는 실제 접속을 하기 위한 192.168.96.6 과 8190 으로 해주면 접속이 이루어진다.

JMC 접속 완료

디바이스를 이용한 화면전송

리눅스에 접속되어 있는 상태에서 상대방에게 화면을 전송하고 싶다면 디바이스를 이용한 화면전송 을 이용하면 됩니다. 방법은 아주 간단합니다.

우선 텔넷이나 ssh로 두분이 같은 시스템에 접속 합니다.

저의 디바이스(가상 터미널)명을 찾아야 합니다.
#tty 이 명령어를 입력하시면 다음과 같은 가상터미널이 나타납니다.

그럼, 함께 접속된 상대방의 디바이스(가상터미널)명을 또 찾아야 합니다.
#w 이 명령어를 입력하시고 고객이 잡고 있는 가상터미널을 찾거나
만일 어떤 가상 터미널을 잡고 있는지 잘 모르겠으면 고객에게
tty 명령어를 입력하여 나타나게 되는 가상터미널 번호를 알아
내시면 됨니다. 예) /dev/pts/2 이 나타났다고 가정 하구요.

그럼, 제가 접속한 화면에서 아래와 같은 명령어를 입력하시면 같은 시스템
에 접속된 상대방의 화면이 저의 제어권으로 넘어 오게 됨니다.

자주 사용하지는 않아도 아주 가끔 사용하는 것이오니 참고 하시라구 장황
하게 몇자 적습니다.

그리고, 종료 하실려면 exit 입력하시면 됨니다.

Proxy 서버 개념

Forward Proxy

forward proxy
Forward proxy

포워드 프락시(Forward Proxy)는 클라이언트가 타켓서버(목표서버)의 주소를 받아서 타켓서버로 연결을 시켜준다. 클라이언트는 타켓서버의 주소를 요청하면 프락시 서버는 뒷단에 타켓서버의 주소를 가진 서버에 연결을 포워딩 한다. 프락시 서버는 타켓서버의 주소를 가지고 있지 않다.

Reverse Proxy

Reverse Proxy
Reverse Proxy

리버스 프락시(Reverse Proxy)는 타켓서버의 주소가 아닌 프락시 서버가 타켓서버의 주소를 가지고 있고 프락시 서버가 이를 받아서 뒷단에 실제 타켓 서버로 연결을 시켜준다. 그러니까 타켓서버의 주소를 프락시서버가 가지고 있어야 하며 클라이언트는 타켓서버의 주소로 요청을 하면 프락시 서버가 응답을 하게 된다.

High Availability – Cold, Warm, Hot

이글은 다음의 내용을 번역한 것입니다.

클러스터링(Clustering) 은 소프트웨어, 하드웨어, 데이터 이중화 도입이 필요한 어떤 서비스에 대해 고가용성(High Availability) 구현을 위한 가장 일반적인 기술이다. 실패한 클러스터링 소프트웨어에서는 즉각적으로 관리자 개입이 필요없이 대기(standby) 시스템에 애플리케이션이 시작된다. 소프트웨어 이중화의 타입에 따라서 고가용성이 제공되어질 클러스터들은 다음과 같은 설정들로 구성되어질 수 있다.

  • Cold Standby: 보조 노드는 다른 동일한 기존 시스템의 백업처럼 동작 한다. 이 보조 노드는 처음으로 기존 노드가 고장이 발생했을때만 설치되어지고 구성되어진다. 그리고 나서, 기존 노드가 실패할때에 보조 노도는 켜지고 마지막으로 실패된 컨포넌트가 시작되기 이전 데이터로 복구되어진다. 기존 시스템의 데이터는 스토리지 시스템으로 백업되어질 수 있고 필요할때마다 보조 시스템으로 복구되어질 수 있다. 이것은 일반적으로 몇 시간의 복구 시간을 제공 한다.
  • Warm Standby: 소프트웨어 컨포넌트는 보조 노드에 설치되어지고 활용되어진다. 보조 노드는 켜지고 운영된다. 기존 노드가 실패할때에 이러한 소프트웨어 컨포넌트들은 보조 노드에서 시작되어진다. 이 과장은 일반적으로 클러스터 매니저를 사용해 자동화된다. 데이터는 정기적으로 공유 디스크나 디스크 기반 리플레케이션을 사용해 보조 노드 시스템에 미러(mirror) 된다. 이것은 일반적으로 몇분의 복구 시간을 제공한다.
  • Hot Standby: 소프트웨어 컨포넌트들은 기존 노드와 보조 노드 양쪽 모두에 설치되어지고 활용되어 진다. 보조 시스템의 소프트웨어 컨포넌트들은 켜져 있지만 데이터를 처리하거나 요청을 처리하지 않는다. 데이터는 거의 실시간으로 미러(mirror) 되고 양쪽 시스템은 동일한 데이터를 갖는다. 데이터 리플리케이션은 전형적으로 소프트웨어의 기능을 통해서 이루어진다. 이것은 일반적으로 몇초의 복구 시간을 제공한다.
  • Active-Active (Load Balanced): 이 방법에서는 기본과 보조 시스템들은 Active 이고 병령로 요청을 처리중이다. 데이터 리플레케이션은 소프트웨어 기능을 통해서 행해지고 양방향이 될 수 있다. 이것은 일반적으로 순간적 복구 시간을 제공 한다.

 

SNMP Extend

snmpd 는 시스템의 자원들에 대해서 SNMP 프로토콜을 통해서 볼 수 있는 기능을 제공 한다. 그런데, 알고 싶은 자원들에 대한 목록들을 조회하기 위해 MIB 값들이 할당되어 있으며 자주 사용되는 운영체제, 라우터, 스위치 같은 장비들에 대한 MIB 값들을 미리 할당되어 전 세계적으로 표준으로 재정해 사용하고 있다.

그런데, 표준으로 재정된 MIB 값외에 사용자가 필요한 자원들을 조회하기 위한 MIB 값을 등록해야 하는데 이때 사용하는 것이 SNMP Extend 를 사용하면 된다.

SNMP Extend 는 ‘.1.3.6.1.4.1.2021.8.10’ 같은 MIB 에 조회하고자하는 값들을 등록하면 된다.

예를들면 다음과 같다.

이렇게 하면 ‘.1.3.6.1.4.1.2021.8.10.101’ 를 뿌리로하는 MIB 를 조회하면 iostate 으로 조회된 값이 등록되어 SNMP 프로토콜을 이용해서 원격에서도 조회가 가능하다.

테스트를 해보면 snmpwalk 명령어를 이용해서 다음과 같이 해보자

‘-v 1’ 은 snmpd 의 version 1 을 지정해주는 것이다. 만일 이게 안된다면 ‘-v2c’ 로 지정해서 해보자

이렇게해서 무언가 나온다면 정상이다.

만일 ‘Timeout’ 에러 메시지를 만단다면 다음과 같이 퍼미션을 조정해주자.

흥미롭게도 snmpd 는 /etc/hosts.allow, /etc/hosts.deny 두개의 파일을 참조하는데, 퍼미션이 없다면 ‘Timeout’ 이 오류를 내다.

HyperText Transfer Protocol

HyperText Transfer Protocol 은 인터넷 미디어를 전송하기 위한 규약이다. 인터넷 미디어라는 단어를 쓰기는 했지만, 요즘에는 인터넷을 통해서 못하는게 없을 정도로 인터넷 미디어를 규정하는 매체의 경계는 없다. 따라서 “인터넷 미디어를 전송하기 위한 규약”은 구시대적인 정의이며 차라리 “인터넷을 이용한 웹을 사용할 경우에 쓰이게되는 규약” 정도가 더 잘 맞는듯 하다.

HyperText 는 텍스트를 가지는 노드사이에 지역적인 링크(이걸 HyperLink라 한다)를 사용하는 구조적 텍스트를 말한다. 쉽게 말해서 웹사이트에서 링크를 클릭하면서 텍스트를 불러오는 텍스트 구조를 말하는 것이다.

History

Tim Berners-Lee
Tim Berners-Lee

1989년 CERN (유럽 입자 물리학 연구소) 에 근무하던  Tim Berners-Lee 는 각국에서 온 연구원들과 수많은 논문들을 컴퓨터를 이용해 공유할 방법을 궁리하고 있었다. 박사들의 논문들은 간단한 텍스트와 수식이 전부였는데, 이것을 컴퓨터로 표현하기 위한 손쉬운 방법을 궁리했는데, 그건 프로그래머 수준의 교육을 받은자가 아닌 어떤 규칙성만 알면 손쉽게 만들수 있도록 하는데 초점이 있었다.

여러가지 가능성을 연구하던중에 마크업(MarkUp)  언어로 간단한 규칙만으로 논문들을 공유할 수 있도록 HTML 을 만들어낸다.

문제는 주석이였다. 각종 논문에는 글의 중간중간에 어려운 단어의 해석을 위해서 주석을 붙이곤 했고 논문에 뒷부분에는 참고문헌들을 나열하여 추가적으로 필요한 자료들을 찾아보도록 되어 있었다.

어떻게하면 이러한 수많은 정보들을 손쉽게 접근할 수 있을까라는 생각 끝에 HyperLink 라는 개념이 나오고 이러한  HyperLink 를 포함하는 구조적인 텍스트로서 HTML 이 만들어졌으며 이를 전송하기위한 프로토콜로서 HTTP 를 만들어낸다.

Tim Berners-Lee 는 HTML, HTTP, 그리고 이것을 이용할 오늘날의 웹 브라우저를 만들어냈다. 그것도 1990년대 일이였으며 이렇게해서 제작한 것을 CERN 연구소에서 1991년 8월 6일날 첫번째 웹 문서가 온라인에 게재된다. 이때 이용한 HTTP 의 버전이 바로 0.9 버전이다.

그가 만든 HTML, HTTP 웹 브라우저는 로열티도 없는 무료였으며 많은 회사들이 이에 관심을 가지고 웹(web)의 발전에 기여하도록 만든다. 이러한 그의 노력은 World Wide Web 이라는 단어를 세상에 알리는 계기가 되면서 1994년에 W3C (World Wide Web Consortium) 이 창립되게 이른다.

HTTP 버전.

  • 1991년 HTTP 0.9
  • 1996년 HTTP 1.0
  • 1999년 HTTP 1.1

HTTP 특징.

HTTP 의 가장 큰 특징은 다음과 같다.

  1. 클라이언트(Client) 로부터 요청이 있어야만 한다.
  2. 모든 필요한 HyperText 를 서버가 클라이언트로 전송이 끝나면 서버와의 연결은 해제된다.

HTTP 은 클라이언트가 서버로 연결을 이루고 필요한 HyperText 를 전송받고 연결을 해제하는 세가지 방법으로 동작한다. 필요한 HyperText 를 다 전송하고 나면 연결을 해제한다는 것, 즉 연결지향이 아닌 비연결지향이라고 해서 “Connectionless Protocol” 이라고도 한다.

클라이언트가 서버로 연결을 요청해야만 무언가를 할 수 있다는 것도 중요한데, 이는 서버가 클라이언트를 먼저 연결 요청을 할 수 없다는 것이다.

또, HTTP 는 TV 방송처럼 서버에서 동작하는 것을 보기위한 TV 같은 것이 아니라 서버에서 필요한 자원들을 전부 다운로드 받아서 클라이언트의 웹 브라우저에서 플레이를 해주는 것이다.

따라서 웹(Web)이라는 것은  HTTP 는 서버로부터 HTML 을 구성하는 자원들을 모두 클라이언트에 모두 가지고 와서 클라이언트가 웹 브라우저를 이용해서 보여주는 것이다.

HTTP 구조.

HTTP 는 HTML 을 전송하기 위한 프로토콜이다. 이것을 만들었을 당시에 대상이 연구 논문이였다는 점을 감안하면 최대한 단순한 구조로 만들어져있다는 건 놀라운 일이 아니다.

HTTP 는 Header 와 Body 로 구분되어진다.

Structure of a request message
Structure of a request message.(http://www.icodeguru.com/dotnet/core.c.sharp.and.dot.net/0131472275/ch17lev1sec1.html)

Header 에는 메소드(Method), URI, HTTP 프로토콜과 버전을 비롯한 각종 정보들을 포함하고 Body 에는 클라이언트가 서버에 요청할 내용이 들어간다. 메소드가 GET 일 경우에 QueryString 의 경우가 바로 Body 다.

HTTP 구조에서 Header 들어가는 내용은 HTTP 버전별로 차이가 있다. 주요한 차이는 다음과 같다.

분류HTTP 1.0HTTP 1.1
Pragma지원미지원
Cache-Control미지원지원
Transfer-Encoding미지원지원
Content-Language미지원지원
Connection미지원지원
Accept미지원지원
Accept-Charset미지원지원
Accept-Encoding미지원지원
Accept-Language미지원지원
Host미지원지원
GET지원지원
POST지원지원
HEAD지원지원
OPTIONS미지원지원
PUT미지원지원
DELETE미지원지원
TRACE미지원지원

HTTP 1.0 과 HTTP 1.1 이 가장 큰 차이점이라면 바로 Connection 헤더이며 이 값이 Keep-Alive 를 지원 여부이다. HTTP 1.1 은 Keep-Alive 를 지원해 다수 접속의 요청과 연결을 줄이고 한번의 연결로 다수의 데이터를 전송받을 수 있게 해준다.

이러한 HTTP 는 웹을 보여주는 웹 브라우저와 서버간의 통신이며 기본적으로 메타데이터를, 이는 텍스트 데이터여서 사람이 눈으로 읽을 수 있다, 주고받는 것이여서 이것을 캡쳐해서 볼 수 있다.

HTTP 통신 들여다 보기.

HTTP 통신은 웹 브라우저와 서버간의 통신으로 이를 들여다 볼 수 있다. 여기서는 Telnet 을 통해서 서버에 요청을 보내고 받아보는 방법을 소개한다.

이것은 브라우저가 해야하는 것을 Telnet 이 대신하는 것이라고 보면 되며 실제 웹 브라워져와 서버와의 통신이 어떻게 이루어지는지를 극명하게 보여주는 실제 예라 할 수 있다.

먼저 Telnet 을 이용해서 서버에 다음과 같이 접속을 한다.

linux.systemv.pe.kr 를 했지만 아무 웹 사이트나 상관이 없다. 중요한 것은  “직접입력”,”Enter 쳐준다” 같이 직접 해준 것이다. 이 부분이 바로 웹 브라우져가 웹 서버에 요청을 하는 아주 간단한 방법이다.  위 방법에는 body 가 없다. 그런데도 서버로의 요청이 전달되고 응답도 정상으로 나온다.

응답은 정확하게 Header 와 Body 로 나뉘어 나온다.  주목해야 하는 것은 바로 Header 이다.

응답 Header 는 HTTP 버전과 함께 HTTP 응답 코드로부터 시작한다. 그리고 응답하는 컨텐츠가 어떤 타입인지, 텍스트 인지 그림파일인지 아니면 바이너리 파일인지등, 을 명시하고 있으며 body 의 길이도 보여주고 있으며 현재 연결 상태가 어떤것인지도 나타내고 있다.

Telnet 말고 다른 툴들도 있는데, 여기서 몇개를 소개한다.

Internet Explorer 11 개발자 도구

Windows 운영체제에서 가장 많이 사용하는 Internet Explorer 11 에는 개발자 도구라는 것이 있다. 정확하게는 웹 개발자 도구인데, 단축키 F12 이며 이것을 누르면 브라우져 아래에서 창이 올라온다.

IE11의 개발자 도구
IE11의 개발자 도구

여기에서 “네트워크” 메뉴를 클릭하면 위 화면과 같은 상태가 된다. 이제 왼쪽에 초록색 플레이 단추를 누르고 주소창에 웹 사이트 주소를 입력해서 엔터를 쳐보자.

IE11 개발자도구 네트워크 요약
IE11 개발자도구 네트워크 요약

그러면 위와 같이 웹 브라우저가 입력한 웹 사이트로부터 내려받은 웹 컨텐츠들에 대한 정보와함께 보여준다. 내려받은 웹 컨텐츠의 정보로는 유형, 받은 용량, 받는데 걸린 시간등이다.

이제 위 내려받은 컨텐츠중에 하나를 클릭하고 왼쪽에 ‘자세히’를 클릭하면 아래와 같이 HTTP 정보가 나온다.

IE11 개발자도구 네트워크 상세 정보
IE11 개발자도구 네트워크 상세 정보

아주 보기 편하도록 각각 필요한 정보들을 분류하고 내용들을 잘 보여준다. 이쯤되면 유료 소프트웨어 못지 않다.

Safari

Safari 웹 브라우저에서도  IE11 과 같은 툴을 제공한다. Safari 를 실행하고 “웹 속성보기”혹은 마우스 오른쪽 버튼을 클릭해 요소검사를 실행하면 아래쪽에 IE11 과같이 창이 올라온다.

Safari HTTP 보기
Safari HTTP 보기

여기서 왼쪽에 “타임라인” 클릭하고 페이지를 다시 한번 릴로드 하거나 주소창에 웹 사이트 주소를 입력하고 엔터를 친다. 그러면 타임라인에 시간들이 그려지고 왼쪽에 컨텐츠들이 나오며 그것을 클릭하고 오른쪽에 “리소스” 를 클릭하면 이 컨텐츠의 상세한 정보가 나오면서 HTTP 이 내용을 볼 수 있다.

FireFox

FireFox 웹 브라우저에도 “요소검사” 를 통해서 각 웹 컨텐츠별로 HTTP 의 내용을 아래와 같이 살펴볼 수 있다. “네트워크” 탭을 클릭한 후에 주소창에 웹 사이트 주소를 입력해 엔터를 치면 왼쪽에 웹 사이트의 컨텐츠들이 표시되며 클릭을하면 HTTP의 상세한 정보를 보여준다.

Firefox HTTP 분석
Firefox HTTP 분석

 

Fiddler

Fiddler 는 Web Debugger 이며 독립된 소프트웨어 이다. 무료여서 누구나 사용할 수 있다. 설치를한 후에 실행을 하면 곧바로 HTTP 들을 캡쳐하기 시작하며 어떤 웹 브라우져를 사용하던지간에 HTTP를 캡쳐해준다.

Fiddler
Fiddler

전송된 컨텐츠에 대해서 매우 상세한 정보를 보여주는 전문적인 툴이다.

HTTP 프로토콜이 무엇인지부터해서 이것을 눈으로 직접확인해 볼수 있는 방법까지 간단하게 살펴봤다. 위 내용이 전부가 아니며 아주 기초적인 내용에 불과할 뿐이라는 사실을 상기할 필요가 있다. HTTP 는 아주 간단하지만 위에서 기술한 것보다 훨씬 다양하고 체계적인 내용들이 다수 포함되어 있다.

웹 개발자이거나 웹 서버를 다루는 사람이라면 이러한 툴들을 가까이하는 것이 좋다. 주로 보안 쿠키를 검사하거나 보이지 않은 헤더의 변조가능성등을 살펴봐야하는 때에는 이러한 방법들이 기초적인 추적의 실마리를 제공할 수도 있다.

 

리눅스 시스템 자원 제한.

아주 접속이 많은 웹 서버를 운영하던중에 다음과 같은 종류의 메시지를 접하는 경우가 종종 있다.

너무나 많은 파일을 열었다는 건데, 도대체 무슨 파일을 열었다는건지 서비스하는 웹 페이지의 파일 개수도 많지도 않은데 말이다.

이 문서는 이러한 의문을 가지는 사람들 위한 것이다.

모든게 파일!

리눅스 시스템은 모든것이 파일이다. 장치도 파일이다. 그 유명한 /dev/ 디렉토리에 있는 팡리들이 바로 장치들이다. 저 파일들에게 cat 명령어로 데이터를 던져주면 그것을 알아먹는 장치는 동작하게 된다.

또, 리눅스에서 프로그램의 실행은 혼자 동작하는 것이 아니다. C 프로그램을 해본사람이라면 라이브러리(Library) 개념을 알고 있을 텐데 프로그램이 동작할때에는 이러한 라이브러리 파일도 함께 로딩(Loading)된다. 예를들어 sshd 라는 명령어가 어떤 라이브러리들고 로딩되는지는 다음과 같이 알수 있다.

sshd 가 실행중인데, 현재 이 프로그램은 아주 많은 파일들을 사용하고 있다. 프로그램 실행을 위한 라이브러리 파일뿐만 아니라 sshd 설정파일들도 눈에 보인다.

그런데, 리눅스 시스템에서 각 프로그램에게 64개 이상의 파일을 사용하지 못하도록 설정되어 있다면 어떻게 될까? 그것이 바로 위에서 만나게 되는 메시지이다.

리눅스 시스템 자원 제어하기.

리눅스 시스템은 위에서 설명한 것처럼 열어야할 파일 개수뿐만아니라 다양한 자원들에게 대해서 제어를 할 수 있도록 해놨다. 이를 위해서 ulimit 라는 명령어를 제공하고 이를 통해서 각각의 자원들을 제어할 수 있다.

위에 나열한 것처럼 cpu, login, file open, file size 등 다양한 것에 대해서 제한(limit)을 둘 수 있다.

또, 각각의 제한은 리눅스 시스템 계정 사용자별, 그룹별, 프로세스별로 줄 수 있다. 그렇다면 현재 로그인한 상태에서 제한은 다음과 같이 확인이 가능하다.

만일 슈퍼 유저(혹은 root 유저) 라면 다른 사용자의 제한도 다음과 같이 확인할 수 있다.

 

Soft and Hard Limit

시스템 리소스 제한에는 Soft Limit 와 Hard Limit 가 있다. Hard Limit 는 Soft Limit 의 최대임계치로서 이 제한에 걸리면 곧바로 문제가 된다. 하지만 Soft Limit 는 최대 임계치는 아니여서 이것을 벗어나더라도 Hard Limit 까지는 문제가 없다. 대신에 Soft Limit 를 벗어났을때에 메일을 보낸다든지 경고 메시지를 내보내는등 조만간에 최대 임계치에 도달할 수 있다는 것을 미리 알려줄 수 있다.

사용자별, 자원별 제한

사용자별, 자원별로 제한을 둘 수 있다. 이는 /etc/security/limits.conf 파일에 명시하면 사용자별, 자원별로 제한이 된다. 파일을 열어보면 자원별은 item 으로 부르고 있는데 제한을 두고 싶은 시스템 자원에 대한 지시어를 찾아서 적으면 된다.

예를들어 systemv 사용자에 대해 최대 파일 열기 디스크립터 개수를 제한고 싶다면 다음과 같이 해주면 된다.

이 내용을 적은 이후부터 systemv 로 시스템에 로그인 하는 사용자는 바로 적용이 되고 이 사용자 계정으로 실해되는 데몬 프로그램은 재시작을 해주면 바로 적용된다.

각 프로세스당 자원에 대한 제한을 알고 싶다면 PID 를 알아낸뒤에 다음과 같이 해주면 된다.