반응형

실수를 하여 기록해둔다.

 

Java Map 객체에서 값을 빼올 때 

 

예)

HashMap<String, Object> apiResponse = new Map<>();
logger.debug(apiResponse.get("aaa").toString());

aaa라는 이름의 객체를 빼온다고 하자. 

이때 값이 null이면 NullPointException 이 떨어진다. 이때는 값을 굳이 형변환을 할필요 없이 값 앞에다 알맞은 형을 명시해둔다. 이미 Object객체임으로 컴파일러에게 String이라고 아래와 같이 명시해주면 된다.

 

HashMap<String, Object> apiResponse = new Map<>();
logger.debug((String)apiResponse.get("aaa"));

 

아니면 NPE 방지를 위해서 String.valueOf()를 쓰는것도 한 방법이다.

String.valueOf()은 파라미터가 null이면 null인 문자열을 반환시킨다.

String lowerCoatingVal1 = String.valueOf(destItemMap.get("LOWER_VAL"));

String lowerCoatingVal2 = destItemMap.get("LOWER_VAL").toString();

 

lowerCoatingVal1 = "null"

lowerCoatingVal2 = NullPointerException 발생

 

String.valueOf()의 null 체크

String lowerCoatingVal1 = String.valueOf(destItemMap.get("LOWER_VAL"));

if("null".equals(lowerCoatingVal1)) {

    // To do Somting....

}

 

출처 : https://swjeong.tistory.com/146,https://okky.kr/article/71363

반응형
반응형

객체의 리스트 형태에서 조건에 맞는 객체를 삭제 하고 싶을때 for loop를 돌려서 삭제하는 경우가 있다.

아래의 코드는 오류가 나니 항상 주의해서 사용하여야 한다.

잘못된예 >>

List<String> names = .... 

for (String name : names) { 

                  names.remove(name);

 }

객체를 꺼내서 사용하는 대신 iterator 를 이용하여야 오류를 막을 수 있다.

List<String> names = .... 

Iterator<String> i = names.iterator(); 

while (i.hasNext()) {

                String s = i.next(); 

                i.remove(); 

}

해당 개념과 관련하여 업무상 실수를 한적이 있어 기록해둔다.

 

출처 : https://stackoverflow.com/questions/1196586/calling-remove-in-foreach-loop-in-java

반응형
반응형

Tomcat 설치 시 소스 경로를 설정할 때 두가지 방법이 있다.

 

1) {톰캣 폴더}/conf/Catalina/localhost/ROOT.xml 에 해당 경로를 넣는 방법 - 이때 유의해야 할것은 server.xml 의 Host 경로를 수정하지 말아야 한다는 점이다.

 

ROOT.xml 파일 내용를 아래와 같이 설정한다.

<Context docBase="{해당 소스가 위치한 경로를 넣어준다}" reloadable="true" privileged="true" antiResourceLocking="false" useHttpOnly="false"> </Context>

 

2) server.xml 에서 직접 설정해준다. 단, 붉은 색으로 표시한 컨텍스트 패스를 함께 설정해주어야 오류가 나지 않는다.

<Host name="localhost" appBase="{해당 소스가 위치한 경로를 넣어준다}" unpackWARs="false" autoDeploy="false">

<Context path="" docBase="" reloadable="true" />

 

 

반응형
반응형
자바로 HttpsURLConnection을 사용하여 https 사이트에 connect 하면 오류가 난다.

이 경우에는 SSL을 무시하여 우회하도록 하는 코드를 작성하여야 한다.

먼저, 해당 URL이 https 인지 판별하는 코드를 썼다.

1
2
3
4
5
6
URL aURL = new URL(url);
 
if (aURL.getProtocol().equals("https")) {    //해당 url이 https이면
      resultData = httpsGet(url);            //ssl인증서를 무시하는 함수를 호출한다.
      logger.debug("https resultData: {}" , resultData);
}
cs


httpsGet함수 - 다른 부분은 http 호출방식과 유사하나 ignoreSSL 처럼 connection 전에 처리해줘야할 사항들이 있다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    public static String httpsGet(String strURL) throws Exception
    {
        URL url = null;
        HttpsURLConnection con = null;
        String ret = new String();
        
        try {
            url = new URL(strURL);
            ignoreSsl();
            con = (HttpsURLConnection)url.openConnection();
    
    
            BufferedReader br = null;
            br = new BufferedReader(new InputStreamReader(con.getInputStream()));
    
            String input = null;
    
            while ((input = br.readLine()) != null){
                ret += input;
            }
            
            br.close();
        }
        catch (IOException e) {
            ExceptionUtil.getStackTrace(e);
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        
        return ret;
        
    }
cs


ignoressl()함수
1
2
3
4
5
6
7
8
9
    public static void ignoreSsl() throws Exception{
        HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String urlHostName, SSLSession session) 
                return true;
            }
        };
        trustAllHttpsCertificates();
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    private static void trustAllHttpsCertificates() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[1];
        TrustManager tm = new miTM();
        trustAllCerts[0= tm;
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }
 
    static class miTM implements TrustManager,X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
 
        public boolean isServerTrusted(X509Certificate[] certs) {
            return true;
        }
 
        public boolean isClientTrusted(X509Certificate[] certs) {
            return true;
        }
 
        public void checkServerTrusted(X509Certificate[] certs, String authType)
                throws CertificateException {
            return;
        }
 
        public void checkClientTrusted(X509Certificate[] certs, String authType)
                throws CertificateException {
            return;
        }
    }
cs



핵심은 connection 전에 호출 처리를 해줘야 오류가 나지 않는다.


반응형
반응형
리눅스 상에서 tar 명령어를 이용할때 절대경로를 이용해서 하면  원하는 곳에 풀수가 없고 만들때 지정된 절대경로를 사용해서 그대로 풀린다.
얼마전 하루넘게 절대경로로 압축된 tar 파일을 상대경로로 풀기 위해 삽질을 하여 이곳에 적어둔다. 이는 다시 상대경로를 이용해서 압축하는 방법을 이용하는 수밖에 없다. 아니면 임시폴더를 이용하여 압축을 풀고 cp를 하던가..

그럼 상대경로를 이용하여 tar 압축을 하는 법을 알아보자

예를 들어 /root/aaa/bb/ex폴더를 압축할때 

tar cfP new.tar /root/aaa/bb/ex      

이렇게 지정하면 압축풀때 /root/aaa/bb/ex 폴더로 풀리게 된다.

따라서  tar 로 압축할때는 상대경로로 이동해서 압축을 하여야 한다.

이미 절대경로를 사용해서 만들었다면 이걸 상대경로로 푸는방법이 있긴 하다. pax 명령어를 이용하는 것이다.
# cd /target 
# /usr/bin/pax -r -s ',^/,,' -f /test.tar 

$ pax -r -s ',^ __없앨 경로들___ , __원하는 경로들___ ,' -f 파일.tar
---> 없앨 경로 : 이미 압축 파일에 포함되어있는 없애고 픈 경로들
---> 원하는 경로 : 압축 파일에 있지만, 압축 해제와 동시에 새로운 경로로 풀리기를 바라는 경로

단,  파일 이름이 . 으로 시작하는 hidden file들은 풀리지 않고 tar -C 처럼 지정한 경로에 풀수 없다는 단점이 있다.


참고

https://kldp.org/node/90185


반응형
반응형
String
String은 새로운 값을 할당할 때마다 새로 생성된다.
char형의 배열형태로 저장되며 final형이기 때문에 초기값으로 주어진 String의 값은 불변으로 바꿀 수가 없게 되는 것이다.

StringBuilder, StringBuffer

둘 다 객체의 공간이 부족해지면 기존의 버퍼 크기를 늘리면서 유연하게 동작한다.

StringBuffer는 멀티스레드 환경에서의 동기화를 지원하지만 StringBuilder는 단일스레드 환경에서만 동기화를 지원한다. 물론 단일스레드 환경에서 StringBuffer를 사용해서 문제가 되는 것은 아니지만 동기화와 관련된 처리로 인해 StringBuilder에 비해 성능이 좋지 않다.

StringBuffer는 각 메서드별로 Synchronized Keyword가 존재하여, 멀티스레드 환경에서도 동기화를 지원.


※ JDK 1.5 버전 이후에는 String 객체를 사용하더라도 컴파일 단계에서 StringBuilder로 컴파일되도록 변경되었다. 따라서 일반적으로 String 클래스를 활용해도 StringBuilder와 성능상으로 차이가 없다고 한다.


하지만 반복 루프를 사용해서 문자열을 더할 때에는 객체를 계속 추가한다는 사실에는 변함이 없습니다. 그러므로 String 클래스를 쓰는 대신, 스레드와 관련이 있으면 StringBuffer를, 스레드 안전 여부와 상관이 없으면 StringBuilder를 사용하는 것을 권장합니다.

 

단순히 성능만 놓고 본다면 연산이 많은 경우, StringBuilder > StringBuffer >>> String 입니다.


검색을 통하여

출처: http://12bme.tistory.com/42 [길은 가면, 뒤에 있다]


반응형
반응형

"특정 시간에 특정 작업을 해야한다." 

 


1. 크론탭 기본 (crontab basic)
 crontab -e
-  콜론(:) 입력 후에 wq 를 입력해 크론탭을 갱신
 crontab -l 
- 표준 출력으로 크론탭 내용이 나온다.
 crontab -r
- 크론탭 삭제

2. 주기 결정

 

*      *      *      *      

(0-59)  시간(0-23)  일(1-31)  월(1-12)   2요일(0-7)

 
순서대로 분-시간-일-월-요일 순입니다.

그리고 괄호 안의 숫자 범위 내로 별 대신 입력 할 수 있습니다.

 

3. 주기별 예제

 

1) 매분 실행

 

* * * * * /home/script/test.sh

매분 test.sh 실행 

 

2) 특정 시간 실행

 

45 5 * * 5 /home/script/test.sh 

매주 금요일 오전 5시 45분에 test.sh 를 실행 

 

3) 반복 실행

 


0,20,40 * * * * /home/script/test.sh

매일 매시간 0분, 20분, 40분에 test.sh 를 실행 

 

4) 범위 실행

 

0-30 1 * * * /home/script/test.sh

매일 1시 0분부터 30분까지 매분 tesh.sh 를 실행 

 

5) 간격 실행

 


*/10 * * * * /home/script/test.sh

매 10분마다 test.sh 를 실행 

 

6) 조금 복잡하게 실행

 

*/10 2,3,4 5-6 * * /home/script/test.sh

5일에서 6일까지 2시,3시,4시에 매 10분마다 test.sh 를 실행 

 

주기 입력 방법엔 * , - / 을 이용하는 방법이 있습니다. 위에서 보셨듯이 각각의 특수기호가 하는 기능이 다르고 조합을 어떻게 하느냐에 따라 입맛대로 주기를 설정 할 수 있습니다.

 

4. 크론 사용 팁

 

1) 한 줄에 하나의 명령만 씁시다.

 

잘못된 예)

* * * 5 5

/home/script/test.sh

 잘된 예)

* * * 5 5 /home/script/test.sh

 
2) 주석

 

#############################

# 이것은 주석입니다.                    #

############################# 

 

# 을 입력해서 그 뒤로 나오는 모든 문자를 주석 처리할 수 있습니다.






출처: http://javafactory.tistory.com/119 [FreeLife의 저장소]


반응형
반응형
zookeeper(주키퍼)란?
분산 처리 시스템에서 일괄적으로 관리해주는 시스템

분산처리 환경에서는 기본적으로 서버가 몇대에서 수백대까지도 구축 가능 
- 이런 환경에서는 예상치 못하는 예외적인 부분이 많이 발생 (네트워크장애, 일부 서비스 기능 중지, 서비스 업그레이드 및 확장)

즉, 싱글 서버에서는 문제가 되지 않으나 멀티 서버 관리를 하면 문제가 될 수도 있는ㄷ 이러한 문제점들을 쉽게 해결해준다.

1)  네임서비스를 통한 부하분산
- 하나의 서버에만 서비스가 집중되지 않게 서비스를 알맞게 분산해 각각의 클라이언트들이 동시에 작업하게 해준다
- DNS 서버에 어느 서버로접속해야 하는지 물어보고 나서 직접 서버에 연결하는 방식

2) 데이터의 안정성 보장
- 하나의 서버에서 처리한 결과를 다른 서버들과 동기화하여 데이터의 안정성을 보장한다.

3) 장애상황 판단 및 복구
- 운영서버에 문제가 발생해서 서비스를 제공할 수 없을 경우, 다른 대기중인 서버를 운영 서버로 바꿔서 서비스가 중지없이 제공되게 한다.

4) 환경설정 관리
분산환경을 구성하는 서버의 환경설정을 따로 분산하지 않고 주키퍼 자체적으로 관리한다.

주키퍼는 다중의 서버 집합을 묶어서 관리해주는 시스템인데 그 중에서도 리더가 되는 서버 하나가 존재한다.
모든 서버의 중심이 되는 서버, 또한 하나의 서버에서 처리가 되어 데이터가 변경되면 모든 서버에 전달되어 동기화를 하게 된다.

분산 환경에서의 주키퍼 서버는 일반적으로 세대 이상을 사용하고 홀수로 구성한다. - 과반수룰을 적용하기 위해

SPOF(single Point Of Failure) 처리

액티브 서버 : 현재 서비스를 하고있는 서버

스탠바이 서버 : 장애 발생시 대처하기 위한 대기 서버

동작중이던 액티브 서버가 장애가 발생 할 경우 관리시스템이 판단하여 기존의 스탠바이 서버를 액티브 서버로 전환하여 서비스를 처리


주키퍼의 기본 구조와 상세 활용법에 대해서는 추후 업로드 하도록 하겠다.




출처: http://creatorw.tistory.com/entry/2-주키퍼zookeeper-기본-구조 []

출처: http://creatorw.tistory.com/entry/2-주키퍼zookeeper-기본-구조 []
출처 : http://exem-academy.com/?p=2927


반응형
반응형
 Cache 란 무엇인가부터 개념을 잡아야 한다.
 Cache는 빠른 속도를 위해서 사용하게 된다.

 Cache를 사용하게 되면, 보통 Key-Value 타입을 사용하게 되면, 쿼리를 파싱하는 시간도 없어지고, 훨씬 접근 속도가 빠른 메모리에서 읽어오게 되기 때문에, 거기서 많은 속도 차이가 나게 됩니다. 다음은 DB 서버의 CPU 사용량입니다. Cache를 적용한 이후부터, 전체적으로 Wait I/O가 많이 떨어지는 것을 볼 수 있습니다.

Select와 Qcache_hits 는 거의 1/10 수준으로 줄어버립니다. DB서버로의 요청이 줄어버려서, 전체 서비스가 좀 더 큰 요청이 들어와도 버틸 수 있게 해줍니다.

캐싱(Caching)은 말 그대로 미리 읽어두었다가 요청이 올 경우 빠르게 응답하기 위한 목적으로 사용할 수 있다. 이 경우 전체 데이터가 필요없고 데이터 역시 계속 유지될 필요가 없기에 Redis처럼 적은 공간의 데이터베이스에 최적이다.

Redis - REmote DIctionary System
여러 솔루션 중 하나로 메모리를 사용하는 키, 밸류 형식의 데이터베이스

-  DB 종류에는 RDBMS, NOSQL, IN-memory  방식이 있다.

1)  RDB
- 관계형 데이터베이스, 둘의 관계를 나타내줄 수 있는 무엇인가가 필요한다.
추가적으로 RDB에서는 근본적으로 null값을 허용하지 않음
- 해당 데이터의 모델의 정의가 확실해야 한다.
- 트랜젝션이라고 하는 처리 단위를 중요시 여김.
-데이터의 모델이 확실하고 하나하나의 처리가 확실해야 한다

2) NOSQL
데이터를 막 저장을 하자 다만 데이터의 고유성을 알아야 하니 키값만 만들어 두자

3) IN-MEMORY
하드 기반이 아닌 메모리 기반의 디비
- 말 그대로 데이터를 HDD가 아닌 memory에 저장하는 기술
- get, put을 이용하여 데이터를 넣고 뺄 수 있다.
인 메모리 기반의 디비는 key:value의 형태로 저장이 되지만 redis의 경우 value가 단순한 objet가 아닌 자료구조를 갖는 점에서 다른 인 메모리 기반의 디비와 큰 차이를 보입니다.
- 메모리는 휘발성 - 캐싱 서버로 사용하기 위해 나왔지만, 하드 저장이 가능해짐


대부분 Redis를 보조 데이터베이스 역할로 그 가치를 최대한 끌어내어 활용하고 있다. 그 중 Redis에 가장 적합한 것이 바로 데이터베이스 캐싱(Caching)이다.

Redis는 별도 서버로 구축되어 주서버와 지속적인 서비스를 주고 받는 방법이 효과적이다. 요즘은 하나에 모든 것을 관리 운영하기 보다 각각의 기능, 필요에 따른 마이크로 서비스(Micro Service) 형태로 많이 운영되어진다. 


Redis의 내부구조

영속성을 지원하는 인메모리 데이터 저장소다.
레디스는 고성능 키-값 저장소로서 문자열, 해시, 셋, 정렬된 셋 형식의 데이터를 지원하는 NoSQL이다
장점은 익히기 쉽고 직관적인 데 있고, 단점은 저장된 데이터를 가공하는 방법에 제한이 있다는 데 있다.


1) key/value Store
기본적으로 Key/Value Store이다. 특정 키 값에 값을 저장하는 구조로 되어 있고 기본적인 PUT/GET Operation을 지원한다.

2) 다양한 데이타 타입
Value가 단순한 Object가 아니라 자료구조를 갖는다고 앞서 언급하였다.  redis가 지원하는 데이타 형은 크게 아래와 같이 5가지가 있다.


** 각 타입의 명령어는 해당 링크를 통해 진입 가능 하다. 사용할때 참고할 것.

(1) String
일반적인 문자열로 최대 512mbyte 길이 까지 지원한다.
Text 문자열 뿐만 아니라 Integer와 같은 숫자나 JPEG같은 Binary File까지 저장할 수 있다.

(2) Set
set은 string의 집합이다. 여러개의 값을 하나의 Value 내에 넣을 수 있다고 생각하면 되며 블로그 포스트의 태깅(Tag)등에 사용될 수 있다.
재미있는 점은 set간의 연산을 지원하는데, 집합인 만큼 교집합, 합집합, 차이(Differences)를 매우 빠른 시간내에 추출가능하다

(3) Sorted Set
set 에 "score" 라는 필드가 추가된 데이타 형으로 score는 일종의 "가중치" 정도로 생각하면 된다.
sorted set에서 데이타는 오름 차순으로 내부 정렬되며, 정렬이 되어 있는 만큼 score 값 범위에 따른 쿼리(range query), top rank에 따른 query 등이 가능하다.

(4) Hashes
hash는 value내에 field/string value 쌍으로 이루어진 테이블을 저장하는 데이타 구조체이다.
RDBMS에서 PK 1개와 string 필드 하나로 이루어진 테이블이라고 이해하면 된다.

(5) List
list는 string들의 집합으로 저장되는 데이타 형태는 set과 유사하지만, 일종의 양방향 Linked List라고 생각하면 된다. List 앞과 뒤에서 PUSH/POP 연산을 이용해서 데이타를 넣거나 뺄 수 있고, 지정된 INDEX 값을 이용하여 지정된 위치에 데이타를 넣거나 뺄 수 있다. 

출처:



http://develop.sunshiny.co.kr/1001



반응형

+ Recent posts