2014년 5월 14일 수요일

Using NRPE

지난번 포스트에서는 서버의 ping 또는 health 체크하기 위해 Icinga 서버의 /usr/local/icinga/libexec/ 에 해당 plugin을 위치하고 NagiosQL을 통해 command 및 service를 등록하여 사용하였다.
이번에는 원격지 서버의 로컬정보를 모니터링 하기 위해 NRPE를 사용하는 방법을 다룬다.
가령 원격지 서버의 mount가 제대로 되어 있는지 여부를 모니터링하기 위해서는 NRPE 기능을 사용한다.
이를 위해 원격지 서버에 NRPE 서버를 설치하고, /usr/lib/nagios/plugins/ 에 mount 유무를 모니터링하기 위한 plugin(check_mountpoints.sh)을 위치하고, /etc/nagios/nrpe.cfg의 COMMAND DEFINITIONS 부분에 아래와 같이 내용을 추가한다.


적용을 위해 nrpe server를 restart 한다.

이제 NagiosQL에서 nrpe commad 및 mount를 위한 service를 등록한다.


service 등록이 완료되면 적용하고자 하는 host의 service settings를 통해 해당 service를 등록하고, 모든 변경된 설정을 write 한후 icinga 서버를 restart하면 완료된다.

2014년 4월 22일 화요일

Icinga and NagiosQL 사용하기

시스템 및 서비스 모니터링을 위해 Icinga를 사용하고 있으며, Icinga 설정파일들을 직접 editting 할 수 있지만 편의를 위해 다양한 설정은 NagiosQL을 사용하고 있다.
여기에서는 Icinga 및 NagiosQL이 설치되어 있다고 가정한다.

관리해야될 host 및 service가 적을 경우에는 수작업에 의해 모니터링이 가능하나 그 개수가 늘어나게 되면 모니터링을 위해 알맞은 툴이 필요하다. 여기서 언급하는 Icinga는 오픈소스인데 반해 훌륭한 기능을 제공하고 있다.

원하는 서비스를 모니터링하기 위해서는 기본적으로 그에 알맞는 실행파일(혹은 plugin)이 존재해야 한다. Icinga를 설치한 경우(여기서는 CentOS기준) /usr/local/icinga/libexec 아래에 몇개의 실행파일들이 기본으로 존재한다. 이외에 사용자가 작성한 스크립트 또는 exe 파일을 이곳에 위치할 수 있다.
테스트로 solr서버의 health 체크를 위한 check_solr_health.py plugin을 아래와 같이 작성하였다.


* plugin 작성시 참고 - http://docs.icinga.org/latest/en/pluginapi.html

다음으로 NagiosQL을 통해 host, service, command 등을 설정한다.

# Command에 작성된 plugin 등록
$HOSTADDRESS$, $ARGn$ 와 같은 standard macro는 http://docs.icinga.org/latest/en/macrolist.html를 참조한다.

# 모니터링을 위한 host 등록
성격이 유사한 host가 여러개 존재할 경우 check settings, Alarm settings, Addon settings 등에 공통적으로 적용할 사항이 있다면 Template을 만들어 사용할 수 있다.

# Service 등록
service 등록시에 Hosts 항목에서 service를 적용하고자 하는 host를 지정할 수 있다.
$_HOSTHEALTH_PORT$, $_HOSTHEALTH_URL$ 등 custom variable은 http://docs.icinga.org/latest/en/customobjectvars.html을 참조한다.

# Write config

위의 그림에서 missed라고 되어있는 부분은 service 설정시 Active 를 체크해제한 상태를 나타낸다. 즉, 적용을 보류하는 것이다.
각각의 설정은 Write config 또는 Write all config files을 통해 저장되며, icinga service를 restart 하여 적용할 수 있다.

# Icinga-web을 통한 모니터링

2014년 4월 16일 수요일

logrotate 오류

CentOS 환경에서 log파일의 rotate를 위해 logrotae를 사용하고 있다.
공통적인 설정은 /etc/logrotate.conf에 설정되어 있으며, 여러개의 log파일을 개별로 설정하고자 할 경우 /etc/logrotate.d/ 아래에 개별 설정을 아래와 같이 할 수 있다.

logroate는 /etc/cron.daily/logrotate에 등록되어 일단위로 실행되게 되어있다. 하지만 logrotate가 정상동작하지 않아 몇가지를 확인해 보았다.
먼저, /var/log/cron 을 통해 cron job이 정상 실행된 것을 확인하였으나, /var/log/messages에 아래와 같은 ALERT 메시지가 남겨져 있었다.

또한 logrotate -v /etc/logrotate.conf 를 통해 테스트 한 결과 "error creating unique temp file: Permission denied" 와 같은 오류 메시지가 나타났다

이와 같은 logrotate가 정상적으로 실행되지 않은 이유는 SELinux의 enforcing mode 때문이었다.
이를 해결하기 위해서는 다음과 같이 실행할 수 있다.

단, 위와 같은 방법은 시스템 재부팅시 다시 원래대로 되돌아가기 때문에 영구적인 적용을 위해서는 /etc/sysconfig/selinux 의 내용을 변경해야 한다.

2014년 2월 21일 금요일

특허 Family의 종류

DSA(Domestic Single Application)

개별국 내에서 단일 출원에 대해 발행되는 하나 이상의 공보 집합을 말한다.
보다 쉬운 이해를 위해 부연하자면 Kind Code(문서의 종류)는 다르지만 출원번호가 동일한 공보를 의미함.
보통 특허 출원 및 등록의 진행과정을 보면 [공개 - 보정 - 등록 - 정정] 과 같은 순서로 진행이 된다. (단, 일본의 경우 등록 이후에 공개공보가 발행되는 경우도 있다.)
이때 문서의 종류는 다르지만 모두 동일한 출원번호를 가지고 있기 때문에 이들을 하나의 DSA라 한다.

ISA(International Single Application)

DSA와 함께 국제출원번호가 같은 공보 집합을 말한다.
어떤 출원인이 WIPO에 출원하고자 하는 국가정보와 함께 국제출원을 신청할 경우 해당 국가에 대해서도 개별적으로 국제출원을 신청한다. 이때 각 국가에서는 이를 기반으로 공개공보 및 등록공보가 발행이 되며, 각 공보들은 모두 동일한 국제출원번호를 가지게 된다.


DOCDB-SF(Simple Family), INPADOC Family

DOCDB-SF 및 INPADOC Fam.은 모두 EPO에서 발행하는 것으로서 동일한 우선권주장번호를 갖는 공보 집합을 말한다. 이때, 둘을 구분하는 기준은 우선권주장번호가 완전 일치해야지만 DOCDB-SF로 분류하고, 일부만이라도 일치하는 경우에는 INPADOC Fam. 이라고 한다. 


위의 그림에서 처럼 DOCDB-SF의 경우 JP와 KR의 공보는 우선권주장번호가 완전히 일치하지만 US의 공보는 두개의 우선권주장번호를 가지고 있어 완전히 일치한다고 볼수 없다. 즉, DOCDB-SF가 INPADOC Fam. 보다 엄격한 기준을 적용한다고 할 수 있다.

2014년 2월 17일 월요일

Solr DIH 사용시 유의점

Solr의 DIH(Data Import Handler)를 사용하여 DB의 데이터를 인덱싱하는 경우 DB의 column name과 shcema.xml에 정의된 field name이 동일한 경우(대소문자 구분없이)  db-data-config.xml 에서 entity 정의시 field 항목을 정의하지 않더라도 색인이 가능하다.

[참고] http://wiki.apache.org/solr/DataImportHandler#A_shorter_data-config

이러한 내용을 알고 있었지만 다음과 같은 실수를 범한 경험이 있다.

DB에 table1과 table2 모두에 "ipc"라는 column이 존재하며, schema.xml에 색인하고자 하는 필드로 "ipc"가 multiValued=true의 속성값을 가지고 정의되어 있다고 가정하자.

table1과 table2의 column 정보는 아래와 같다.

[table1] id, ipc
[table2] id, ipc, fi, ft

DIH를 위해 정의된 db-data-config.xml의 내용이 아래와 같다고 하자.

이 경우 의도는 table1의 ipc 정보를 색인하고 싶었으나 table2의 ipc 정보까지 함께 색인이 되어 버렸다.
따라서, "ent2"의 query를 select *이 아닌 select fi,ft로 바꿔주어야 한다.

2014년 1월 19일 일요일

org.apache.http.NoHttpResponseException

single 서버에서 solr core를 여러개 운영할 때 클라이언트 측으로 간헐적으로 500 error가 리턴되는 현상이 나타났다.

서버 운영환경은 single서버에서 두개의 톰캣 인스턴스를 운영하며, 각각의 톰캣에는 solr 인스턴스가 2,3개씩 운영되고 있었다. 또한 각각의 solr 인스턴스는 다수개의(4~6개) solr core(shards)를 포함하고 있었다.

사용자가 질의를 요청하면 대부분의 경우 모든 solr core에 distribute search를 요청하게 되는데, 에러가 발생한 경우의 톰캣 로그는 아래와 같다.

2014-01-13 12:23:41,814 [http-8080-12] ERROR org.apache.solr.servlet.SolrDispatchFilter - null:org.apache.solr.common.SolrException: org.apache.solr.client.solrj.SolrServerException: IOException occured when talking to server at: http://solr07:8100/solr_ep/epp03
        at org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:298)
        at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:129)
        at org.apache.solr.core.SolrCore.execute(SolrCore.java:1561)
        at org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:446)
        at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:267)
        at org.apache.solr.servlet.PipcDispatchFilter.doFilter(PipcDispatchFilter.java:62)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:470)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:662)
Caused by: org.apache.solr.client.solrj.SolrServerException: IOException occured when talking to server at: http://solr07:8100/solr_ep/epp03
        at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:409)
        at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:182)
        at org.apache.solr.handler.component.HttpShardHandler$1.call(HttpShardHandler.java:165)
        at org.apache.solr.handler.component.HttpShardHandler$1.call(HttpShardHandler.java:132)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
        ... 1 more
Caused by: org.apache.http.NoHttpResponseException: The target server failed to respond
        at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:101)
        at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:252)
        at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:282)
        at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:247)
        at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:216)
        at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:298)
        at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
        at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:647)
        at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:464)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
        at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
        at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:351)
        ... 11 more


톰캣 설정이 잘못되었을 것이라는 추측하에 톰캣 connector에 관한 설정을 보던중 keepAliveTimeout 에 대한 설정이 정의가 되지 않을 경우 default로 connectionTimeout 설정의 값을 사용한다는 걸 알았다.
The number of milliseconds this Connector will wait for another HTTP request before closing the connection. The default value is to use the value that has been set for the connectionTimeout attribute.
사용하고 있던 톰캣의 설정에는 keepAliveTimeout는 설정되지 않았으며, connectionTimeout만 60000ms으로 설정되어 있었다. 즉, keepAliveTimeout이 설정되지 않다보니 connectionTimeout의 설정값인 60000ms를 사용하게 되었고, 이는 thread가 종료되기까지 많은 시간을 소요하게 되어 thread의 수를 증가시켰다. 
connectionTimeout의 값을 20000ms로 낮추고 운영한 결과 현재까지는 위의 오류가 발생되지 않고 있다.