반응형
반응형

9200번 포트를 외부에 열지 않기 위해, nginx의 proxy를 이용하여 간단히 연결만 해주면 될줄 알았는데,

쪼끄만거 때문에 삽질을 여러번해서 정리함.


[elastic search]

location /elastic {
       proxy_pass http://127.0.0.1:9200/;        // 맨 마지막에 / 를 꼭 넣어주어야 한다.
}

[kibana]

location /kibana/ {      // 여기서도 마지막에 / 를 넣어준다.
    rewrite /kibana/(.*) /$1 break;            // 이걸 빼먹으면, url이 /kibana/를 빼고 세팅이 되버려서, 유지하려면 넣어줌.
    proxy_pass http://127.0.0.1:5601/;    // 마찬가지로 / 를 꼭 넣자 
}

[elastic search hq]

location ~ /hq/_site/ {       
         root        /usr/local/elasticsearch-2.3.2/plugins;     // html파일이 들어있는 root 경로 지정
         index       index.html                                     // index 경로
         proxy_pass  http://127.0.0.1:9200/_plugin/hq/_site/;  // 어디로 연결할지 지정
}

분명 다른 방법도 있을거같은데, nginx를 잘 모르고, 더 이상 삽질하기 싫어서

다음 세팅할땐 이렇게 사용하려고 정리함.


다 redirect때문에 발생하는 문제이기 때문에, 왠만하면 그냥 9200포트 열어서 쓰는게 깔끔함;

반응형
,
반응형

vhost설정에서 아래 구문만 추가해주면 된다.

RedirectMatch ^/$ /application/
반응형
,
반응형

mongoDB 로그를 filter해서 kibana에서 봐야할 일이 생겼다.


shipper부분에서 filter grok 부분을 작성해줘야되는데, 커스터마이즈가 쉽지 않아서

이리저리 구글링하다가 정상적으로 동작하는 구문을 발견!


대충 아래처럼 적어주고 shipping 하면 redis로 잘 적재되고, elasticsearch가 indexing하는데 문제가 없었다.

mongoDB는 3.0버전을 사용하였고, 2.x버전에서는 잘 안될지도 모르겠다. match 구문에 보면 MONGO3라고 되어있기 때문이지..


[logstash.conf]


input {
  file {
    path => "/data/log/mongodb/mongod.log"
    type => mongodb
    start_position => "end" # rotate policy 같은건데, 별 차이 없으므로 default인 end로 그냥 놓는다.
# 자세한 설명은 공홈에... (https://www.elastic.co/guide/en/logstash/current/plugins-inputs-file.html)
  }
}

filter {
  grok {
       match => ["message","%{TIMESTAMP_ISO8601:timestamp}\s+%{MONGO3_SEVERITY:severity}\s+%{MONGO3_COMPONENT:component}%{SPACE}(?:\[%{DATA:context}\])?\s+%{GREEDYDATA:body}"]
  }
  if [body] =~ "ms$"  {
       grok {
        match => ["body",".*\}(\s+%{NUMBER:spend_time:int}ms$)?"]
       }
 }
 date {
   match => [ "timestamp", "ISO8601" ]
   #remove_field => [ "timestamp" ]
  }
}

output {
   if [type] == "mongodb" {
     redis {
       host => "서버 host"
       port => "포트"
       data_type => "list"
       key => "redis에 어떤 key로 넣을 것인지"
     }
   }
}
반응형
,
반응형

AWS를 이용중인데, EBS를 추가하는 경우 볼륨을 수동으로 Mount 해주어야 할 일이 있었다. 


아래와 같은 절차로 Mount를 하면 된다.

$ fdisk -l   # 디스크 목록 확인
$ fdisk [디스크명] # (ex : /dev/xvdb)
Command (m ) : # 이렇게 생긴 창이 나오는데, 다음과 같이 입력한다.

n # 새로운 파티션 생성
p # primary
# 이후 계속 물어보는게 나오는데, 사이즈 조절 등이 필요하지 않은 경우 그냥 Enter를 치면 된다. (나눠서 사용하는 것도 가능한것 같은데 해보진 않아서 잘 모름;)

w # 물어보는게 끝난 후 저장하여 빠져나옴.

$ fdisk -l  # 방금 생성한 파티션명을 확인한다.

$ mkfs -t ext4 [파티션명] (ex: /dev/xvdb1) # ext4 형태로 포맷

$ mount [파티션명] [연결할 폴더명]  # 마운트 (사전에 폴더가 생성되어 있어야 함)

$ echo "[파티션명] [연결할 폴더명] ext4 defaults 1 2" >> /etc/fstab # 영구적으로 마운트 되도록 설정 
    # 위에 진행 했던 정보와 동일해야한다. 

마운트를 하다가 잘못된 경우, Instance를 새로 만들어야 하니, 주의해야 한다.

반응형
,
반응형

프로그래밍을 처음 배울때 if문을 배우면서 숫자 비교 같은 것을 배우게 됩니다. 

그러다가 응용 단계로 가면 문자열 비교를 배우게 되죠.

아마 대부분 아래와 같이 쓰지 않았었나 생각됩니다.. (물론 저도 포함 ^^;;) 

 

String str = "abc";
String input = "abc";
 
if(str == input) {
   system.out,println("true");
} else {
   system.out,println("false");
}


 

결과는, 당연히 false가 찍히겠죠. false가 찍히는 원인은 문자열 변수마다 가지고 있는 hashCode가 다르기 때문입니다.

따라서, String 비교시에는 아래와 같이 equals를 사용하면 원하는 결과인 true를 얻을 수 있습니다.

 

if(str.equals(input) {
   system.out.println("true");
} else {
   system.out.println("false");
}


 

하지만, equalsIgnoreCase라는 것이 있습니다. equals같은 경우에는 대소문자 구분을 철저히 하지만,

equalsIgnoreCase 같은 경우 대소문자를 구분하지 않습니다. 클라이언트에서 입력받은 String을 비교할 때 유용하게 쓰이겠죠.

아래와 같이 말입니다.

 


 

결과는 true가 찍힙니다.

String str = "abc"
String input = "AbC";
 
if(str.equalsIgnoreCase(input)) {
   system.out.println("true");
} else {
   system.out.println("false");
}

 

보통은 대소문자 구분 처리할때 toLowerCase(모두 소문자 변환), toUpperCase(모두 대문자 변환) 등을 이용하여 사용하지만,

equalsIgnoreCase를 사용하면, 한방에 해결할 수 있어서 좋은 것 같습니다.

반응형
,
반응형

가끔 일을 하다보면 HTML내에서 또 HTML파일을 생성해달라고 하는 (HTML파일 제작툴?) 요청사항이 올 때가 있습니다. 

 

그런 경우에 zxml이라는 라이브러리를 이용해서 구현이 가능합니다.

 

다운로드 : http://www.nczonline.net/downloads/

 

압축파일로 되어 있고, 압축을 풀면, sample 소스 등이 나오는데,

실제로 우리가 필요한 건 zxml.js 파일 하나 뿐입니다.

 

DOM방식으로 구현을 해야되서, 소스가 지저분해질 수 밖에 없더군요.

(다른 좋은 방법이 있으면 소개좀.. ㅠㅠ)

 

간단하게 예제코드를 통해 작성법을 소개하도록 하겠습니다.

 

아래 html 코드를 zxml을 통해 만들어 보도록 하겠습니다.


<head>
<title>test</title>
<meta http-equiv="Cache-Control" content="no-cache" />
</head>
// document 생성
var oXmlDom   = zXmlDom.createDocument();
 
//  
var htmlContainer  = oXmlDom.createElement("html");
 
// <head> </head>
var headContainer  = oXmlDom.createElement("head");

// <title>test</title>  
 var titleContainer  = oXmlDom.createElement("title");
// 태그 사이에 값을 넣어주는 역할
 titleContainer.appendChild(oXmlDom.createTextNode("test"));
 
// <meta />
 var metaContainer  = oXmlDom.createElement("meta");
// <meta http-equiv= /> : 속성 추가
 var attHttpEquiv = oXmlDom.createAttribute("http-equiv");
// 추가된 속성에 값 추가 <meta http-equiv="Cache-Control" />
 attHttpEquiv.value = "Cache-Control";
// meta태그에 위 속성 적용
 metaContainer.attributes.setNamedItem(attHttpEquiv);
// <meta http-equiv="Cache-Control" content="no-cache" /> 위와 동일
 var attContent  = oXmlDom.createAttribute("content");
 attContent.value = "no-cache";
 metaContainer.attributes.setNamedItem(attContent);
 
// <head> 안에 title과 meta를 추가
headContainer.appendChild(titleContainer);
headContainer.appendChild(metaContainer);
 
//  안에 head 추가
htmlContainer.appendChild(headContainer);
 
// document에 html 추가
oXmlDom.appendChild(htmlContainer);
 
// 리턴
return oXmlDom.xml;
반응형

'개발 > Front-End' 카테고리의 다른 글

[Jquery] $.ajax 사용 시 success callback에서 this 객체 사용하기  (0) 2016.06.10
[CSS] 텍스트 말줄임  (0) 2016.06.10
[HTML] favicon 추가  (0) 2016.06.10
[JavaScript] byte formatter  (0) 2016.06.10
[Jquery] Ajax Fileupload Option  (0) 2016.06.10
,
반응형

primitive type (int, long, double, char 등..)을 사용하는 경우,

따로 객체 생성을 하지 않고 처리되기 때문에, 메모리 관리가 자동으로 이루어짐.

 

하지만 Reference Type (Integer, Long, Double, String 등)은 Object를 상속받는 객체이기 때문에,

null로 처리하거나, GC가 이루어진 경우에만 메모리 정리가 됨.

 

개인적으로 내린 결론은, Reference Type 사용 시에는 사용 후에 반드시 null처리를 해주도록 하는 것이다.

GC가 하는 일을 줄여보기 위한....

혹시나 코딩을 잘못했을 경우에, 사용하지도 않는게 메모리 영역에 살아있을 수도 있으니, 귀찮더라도 null로 세팅해주도록 하자.

GC에게 모든걸 맡기면 언젠가 OOM (out of memory)를 보는 상황이 올지도 모른다. 

 

물론 SoftReference나 WeakReference를 사용하는 것도 좋은 방법 중 하나이다. 

 

이건 참고한 글.

 

http://lemonfish.egloos.com/viewer/5380639  

반응형
,

[Gson] TypeAdapter

개발/Java 2016. 6. 10. 23:08
반응형

기존까지 Json Parser는 Jackson을 사용하고 있었는데,

어딘가에서 Gson이 가장 퍼포먼스가 좋다는 이야기를 듣고, 작년부터 Gson을 도입하여 사용하기로 하였다.

 

근데.. 엄청난 문제가 하나 있었다.

Number Type의 경우 toJson이나 fromJson메소드를 사용 시에, 무조건 double형태로 내부적으로 변환을 해서 주는 것이었다.

 

물론.. Integer라던지, Long이라던지 제대로 명시를 해서 변환을 요청하면 제대로 바꿔준다.  

하지만, Map<String, Object> 형태를 사용하여, 변환을 요청하는 경우 위와 같은 문제가 발생. 

 

성능을 높이기 위해 모든 Number Type을 double로 바꿔주는 것인가...  

자세한 이유는 만든사람만 알겠지;;

 

처음에는 일일히 double로 받아서, int로 변환해서 사용을 하였었는데..

찾아보니 역시나 간단하게 해결할 수 있는 방법이 있었다.

 

gson객체에 registerTypeAdapter라는 설정 관련 메소드가 있었고,

이것을 통해, Double로 들어오는 것들을 값의 범위를 계산하여 

Integer범위보다 크면 Long으로.. 아니면 Integer로 변경하도록 구현해보았다.

 

참고로, toJson과 fromJson을 사용 시 구현해야 하는 인터페이스가 다르다.

 

toJson : JsonDeserializer<T>

fromJson : JsonSerializer<T>

 

현재 클라이언트에서 받는 객체는 Pojo로 타입이 확실하게 명시되어 있고,

Response Data의 경우 Map으로 받고 있어서, toJson(obj, HashMap.class)을 할 때,  

무조건 .0이 붙어서 나오는 문제가 있으니 JsonDeserializer를 구현해서 쓰도록 결정하였다.

 

 

@Override
public HashMap<String, Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        Map<String, Object> map = Maps.newHashMap();
        JsonObject jsonObject = json.getAsJsonObject();
        for(Entry<String, JsonElement> entry : jsonObject.entrySet()) {
            JsonElement element = entry.getValue();
            if(element instanceof JsonPrimitive && element.getAsJsonPrimitive().isNumber()) {
                Number nValue = CommonUtils.getRemoveDot(element.getAsDouble());
                map.put(entry.getKey(), nValue);
                
            } else {
                map.put(entry.getKey(), context.deserialize(element, Object.class));
            }
        }
        return (HashMap<String, Object>) map;
}

서비스에도 적용되어 있는 상태인데, 특별한 문제는 없었다.

반응형
,
반응형

데이터베이스를 Scale Out으로 구성하는 경우, auto increment sequence값에 대해 고민을 하게 된다.

 

다음과 같은 시도를 해보았다.

 

1. Unique idx 발급용 Redis를 별도로 두어, increment 명령어만 호출하여 사용한다.

  - 개발환경에서는 잘 사용하고 있었지만, SPOF 이슈가 있고, 별도 머신 세팅을 해야하므로 관리 이슈가 따름. (fail) 

 

2. java 내부에서 제공하는 UUID를 이용하여 randomString을 추출해낸다.

  - 겹칠 확률이 없다고 봐도 되고, 로직에서 처리하는 것이기 때문에 1번보다는 성능이 좋지만, 보통 DB에서 사용하는 unique idx는 long타입인데, 얘는 String타입으로 리턴해준다. 물론, long형태로 리턴해주는 메소드도 있어서 사용해봤고, 어느정보 겹칠 확률도 없었지만.. 좀 껄끄러워서 패스 (fail) 

 

3. 구글링을 하던 중 누군가 Github에 snowflake에서 unique idx발급 시 사용하는 알고리즘을 올려두었다. (트위터에서 올린건지는 모름;;)  

  - 전체적인 로직을 보진 않았지만, timestamp값을 가지고 or연산 등을 이용하여 생성해내는 방식인 것 같다. 이것도 unique idx를 generate하는 메소드는 string형태로 리턴이 되는 구조였지만, 내부적으로 Long으로 만든 후에 toString하는 방식이어서 toString만 없애고, 어느정도 맞게 수정해서 사용. 트위터에서 사용하고 있는 알고리즘이므로 믿고 사용하기로 결정.

링크 : https://github.com/Predictor/javasnowflake  

※ long id generate하는 부분 중에, hardWareAddress 가져오는 코드가 있는데, 이거 centOS에서 잘 안가져와 지는 것 같다. windows에서는 잘되는데, 왜 안되지 찾다가 보니 null을 반환했었다는.... 이럴 경우 getHardWareAddress()를 사용하면 안되고, Iterable한 형태로 리턴해주는 method를 이용하면 해결이 된다. (본인은 귀찮아서, null일 경우 로컬에서 한번 받아온 hardWareAddress를 세팅하도록 변경해서 사용중;; 어차피 중복 확률이 0%니깐 상관없을거 같아서..) 

 

nosql을 주 Storage로 사용하는 경우 2번의 방법도 괜찮다고 한다. 

반응형
,
반응형

https://github.com/guari/eclipse-ui-theme

 

검정 Base의 테마.

가독성도 나쁘지않고 맘에든다. 

반응형
,
반응형