Spring Data JPA - LazyInitializationException

Java|2015. 4. 14. 10:00

개요

요즘 Spring Boot 저장소에 있는 Spring Data JPA 샘플 프로젝트를 살펴 보고 있습니다.

테스트 코드를 작성하면서 하나하나 파악하고 있는데, OneToMany로 엮인 다른 엔티티의 목록을 가져오려고 하면 아래와 같은 오류가 발생합니다.

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: kr.co.javaworld.jpa.domain.Person.cars, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
    at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)
    at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:278)
    at org.hamcrest.collection.IsCollectionWithSize.featureValueOf(IsCollectionWithSize.java:21)
    at org.hamcrest.collection.IsCollectionWithSize.featureValueOf(IsCollectionWithSize.java:14)
    at org.hamcrest.FeatureMatcher.matchesSafely(FeatureMatcher.java:40)
    at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:12)
    at org.junit.Assert.assertThat(Assert.java:956)
    at org.junit.Assert.assertThat(Assert.java:923)
    at kr.co.javaworld.jpa.service.PersonRepositoryIntegrationTests.testFindCars(PersonRepositoryIntegrationTests.java:46)
    ..............
    .... 중략 ....
    ..............
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

늦은 초기화(Lazy initialization)에 관련된 예외 상황인데, 이에 대한 해결 방법을 정리해 봅니다.

예외가 발생하는 코드

아래의 테스트 코드를 실행하던 중 예외가 발생했습니다. testFindCars 메소드는 Person 객체를 하나 찾은 후, 다시 그 Person이 가진 Car 목록을 조회하는 테스트 코드입니다.

Person.getCars() 호출 후 목록(cars)의 크기를 얻으려고 하니까(assertThat(cars, hasSize(4))) 오류가 발생했습니다.

package kr.co.javaworld.jpa.service;

import kr.co.javaworld.jpa.domain.Car;
import kr.co.javaworld.jpa.domain.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sample.data.jpa.SampleDataJpaApplication;

import javax.transaction.Transactional;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
public class PersonRepositoryIntegrationTests {

    @Autowired
    PersonRepository repository;

    ..............
    .... 중략 ....
    ..............

    @Test
    public void testFindCars() {
        Person person = repository.findOne(1L);
        List<Car> cars = person.getCars();

        assertThat(cars, hasSize(4));
        assertThat(cars.get(0).getName(), is("Mercedes"));
    }
}

Person 엔티티의 코드입니다.
cars@OneToMany annotation이 붙어있을 뿐 특별한 점은 없습니다.

package kr.co.javaworld.jpa.domain;

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "TB_PERSON_02837")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "PERSON_NAME", length = 100, unique = true, nullable = false)
    private String name;

    @OneToMany
    private List<Car> cars;

    ..............
    .... 중략 ....
    ..............

}

해결 방법

@OneToMany로 엮을 경우 JPA는 늦은 초기화를 통해 Personcars 목록을 가져오는게 기본 설정입니다. 즉, 위 코드의 @OneToMany annotation 선언은 @OneToMany(fetch = FetchType.LAZY)로 대체해도 동일합니다.

따라서 해결 방법은 간단합니다. 패치 타입을 FetchType.EAGER로 변경하여 늦은 초기화 대신 이른 초기화(Eager initialization)를 사용하면 됩니다.

아래 코드와 같이 @OneToMany(fetch = FetchType.EAGER)로 annotation 선언을 변경해 주면 오류가 사라집니다.

package kr.co.javaworld.jpa.domain;

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "TB_PERSON_02837")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "PERSON_NAME", length = 100, unique = true, nullable = false)
    private String name;

    @OneToMany(fetch = FetchType.EAGER)
    private List<Car> cars;

    ..............
    .... 중략 ....
    ..............

}

다른 해결 방법

앞서의 해결 방법은 People 엔티티를 얻어 올 때는 언제나 Car 목록도 함께 가져오도록 강제합니다. 따라서 가끔씩만 Car 목록이 필요하다면 불필요한 메모리 낭비나 서버 성능 저하 등의 문제가 발생할 수 있습니다.

늦은 초기화를 사용하면서도 문제를 해결하려면 아래와 같이 트랜잭션을 Person.getCar() 호출 후 관련 동작을 완료할 때까지 유지하면 됩니다.

아래에서는 testFindCars 메소드에 @Transactional annotation을 붙여서 메소드 전체를 하나의 트랜잭션으로 감쌌습니다.

실무에서는 서비스 클래스의 메소드 단위로 트랜잭션을 잡아 주거나, 뷰 단의 서블릿 필터에서 UserTransaction을 이용하여 요청 단위로 트랜잭션을 처리하는 방법을 사용하면 됩니다.

package kr.co.javaworld.jpa.service;

import kr.co.javaworld.jpa.domain.Car;
import kr.co.javaworld.jpa.domain.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import sample.data.jpa.SampleDataJpaApplication;

import javax.transaction.Transactional;
import java.util.List;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
public class PersonRepositoryIntegrationTests {

    @Autowired
    PersonRepository repository;

    ..............
    .... 중략 ....
    ..............

    @Test
    @Transactional
    public void testFindCars() {
        Person person = repository.findOne(1L);
        List<Car> cars = person.getCars();

        assertThat(cars, hasSize(4));
        assertThat(cars.get(0).getName(), is("Mercedes"));
    }
}

EOF

댓글()

PuTTY로 Amazon EC2 인스턴스 접속하기

Developer Tools|2015. 4. 2. 10:00

PuTTYgen 내려 받기

EC2 인스턴스에 PuTTY를 이용해 접속하려면, Key Pair 파일(.pem)을 .ppk 파일로 변환해야 합니다.

.ppk 파일은 PuTTYgen(PuTTY Key Generator)을 이용해서 생성 할 수 있습니다.
아래 링크에서 PuTTYgen을 내려받습니다.

PuTTY Download Page

바로 내려받기

설치 없이 바로 실행하여 사용할 수 있습니다.

Amazon Key Pair(.pem)를 PuTTY Private Key File(.ppk)로 변환

PuTTYgen을 실행한 후 상단 메뉴에서, Conversions > Import key를 클릭합니다.

Load private key 창이 열리면 .pem 파일을 찾아서 엽니다.


Key Pair에 대한 정보가 로딩되면 Save private key를 클릭합니다.


passphrase 없이 키를 저장할 것인지 물어봅니다. 예(Y)를 클릭하여 수락합니다.


Save private key as 창이 열리면, 원하는 경로와 이름을 지정한 후 ppk 파일을 저장합니다.
여기에서는 바탕화면에 aws_hbase.ppk로 저장했습니다.


PuTTY에서 ppk 파일 사용하기

PuTTY 설정창(PuTTY Configuration)의 Category에서 Connection > SSH > Auth로 이동한 후, Browse를 클릭합니다.


위에서 저장한 ppk 파일을 선택합니다.


ppk 파일 선택이 완료됐습니다.


이제 Session Category로 이동한 후 Host Name에 EC2 인스턴스의 주소를 입력한 후 Open을 클릭하여 접속하면 됩니다.


댓글()

Pinpoint 빨리 설치하기(QuickStart)

설치&설정|2015. 3. 30. 15:57

Pinpoint QuickStart

얼마 전에 Hadoop, Hbase 최근 버전을 설치한 후, 네이버 Pinpint 설치를 시도해 봤습니다. 하지만 Pinpoint가 Hadoop 최신 버전을 공식 지원하지 않아서인지 실패했습니다.

어쨌든 빨리 사용해 보고 싶어서 QuickStart 가이드를 따라서 설치해 봅니다.

Linux 환경에서 QuickStart 실행하기

Pinpoint QuickStart 가이드 문서는 아래 주소에서 볼 수 있습니다(영문).

https://github.com/naver/pinpoint/tree/master/quickstart

리눅스 환경에서의 설치를 가이드하고 있어서 저는 AWS에 설치한 CentOS 7에 설치했습니다.

아래 주소에 가면 윈도 환경에서 실행하는 방법을 볼 수 있습니다.
Windows 환경에서 QuickStart 실행하기

Install JDK 6

Pinpoint 실행을 위해서는 JDK 6JDK 7+, Maven 3.2x+ 버전을 먼저 설치해야 합니다.

우선 JDK 설치를 위해서 wget 부터 설치합니다.

[centos@ip-172-31-7-87 ~]$ sudo -i
[root@ip-172-31-7-87 ~]# yum install -y wget

wget으로 JDK 6 바이너리(jdk-6u45-linux-x64.bin)를 다운로드 받은 후, chmod 명령으로 실행권한을 부여한 후 설치합니다.

[root@ip-172-31-7-87 ~]# wget http://ghaffarian.net/downloads/Java/JDK/jdk-6u45-linux-x64.bin
--2015-03-25 11:03:07--  http://ghaffarian.net/downloads/Java/JDK/jdk-6u45-linux-x64.bin
Resolving ghaffarian.net (ghaffarian.net)... 178.32.91.18
Connecting to ghaffarian.net (ghaffarian.net)|178.32.91.18|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 72087592 (69M) [application/octet-stream]
Saving to: ‘jdk-6u45-linux-x64.bin’

100%[=================================================>] 72,087,592  5.52MB/s   in 25s

2015-03-25 11:03:33 (2.78 MB/s) - ‘jdk-6u45-linux-x64.bin’ saved [72087592/72087592]

[root@ip-172-31-7-87 ~]# 
[root@ip-172-31-7-87 ~]# chmod u+x jdk-6u45-linux-x64.bin
[root@ip-172-31-7-87 ~]# ./jdk-6u45-linux-x64.bin
Unpacking...
Checksumming...
Extracting...
UnZipSFX 5.50 of 17 February 2002, by Info-ZIP (Zip-Bugs@lists.wku.edu).
   creating: jdk1.6.0_45/
   creating: jdk1.6.0_45/db/
   creating: jdk1.6.0_45/db/bin/
  inflating: jdk1.6.0_45/db/bin/ij
  inflating: jdk1.6.0_45/db/bin/NetworkServerControl
  inflating: jdk1.6.0_45/db/bin/setNetworkClientCP.bat
  inflating: jdk1.6.0_45/db/bin/setEmbeddedCP.bat
....
....
....
  inflating: jdk1.6.0_45/include/classfile_constants.h
  inflating: jdk1.6.0_45/COPYRIGHT
Creating jdk1.6.0_45/jre/lib/rt.jar
Creating jdk1.6.0_45/jre/lib/jsse.jar
Creating jdk1.6.0_45/jre/lib/charsets.jar
Creating jdk1.6.0_45/lib/tools.jar
Creating jdk1.6.0_45/jre/lib/ext/localedata.jar
Creating jdk1.6.0_45/jre/lib/plugin.jar
Creating jdk1.6.0_45/jre/lib/javaws.jar
Creating jdk1.6.0_45/jre/lib/deploy.jar

Done.

설치 후 생성된 jdk1.6.0_45 디렉토리를 /opt 디렉토리로 이동합니다.

[root@ip-172-31-7-87 ~]# mv jdk1.6.0_45 /opt

Install JDK 8

wget으로 JDK 8 압축 파일(jdk-8u25-linux-x64.tar.gz)을 다운로드 받은 후, /opt에 압축을 해제합니다.

압축 해제가 완료되면 /opt/jdk1.8.0_25 디렉토리가 생성됩니다.

[root@ip-172-31-7-87 ~]# 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/8u25-b17/jdk-8u25-linux-x64.tar.gz"

[root@ip-172-31-7-87 ~]# tar -zxvf jdk-8u25-linux-x64.tar.gz -C /opt

alternatives 명령을 사용하여 어디에서나 java 명령을 사용할 수 있도록 설정합니다.

[root@ip-172-31-7-87 ~]#  /usr/sbin/alternatives --install /usr/bin/java java /opt/jdk1.8.0_25/bin/java 100

[root@ip-172-31-7-87 ~]# java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

/etc/profile 파일을 편집하여 JAVA_HOME, JAVA_7_HOME, JAVA_6_HOME 환경변수를 설정합니다.

JAVA_HOME, JAVA_7_HOME은 앞에서 설치한 JDK 8을 가리키도록 설정했습니다.

[root@ip-172-31-7-87 ~]# vi /etc/profile
export JAVA_HOME=/opt/jdk1.8.0_25
export JAVA_7_HOME=/opt/jdk1.8.0_25
export JAVA_6_HOME=/opt/jdk1.6.0_45

source 명령으로 방금 편집한 /etc/profile을 새로 읽어 들인 후, 환경변수 설정이 잘 됐는지 확인합니다.

[root@ip-172-31-7-87 ~]# source /etc/profile

[root@ip-172-31-7-87 ~]# echo $JAVA_7_HOME
/opt/jdk1.8.0_25

[root@ip-172-31-7-87 ~]# echo $JAVA_6_HOME
/opt/jdk1.6.0_45

Install Maven

지금까지는 JDK 설치를 위해서 root 계정을 사용했습니다만, Mavencentos 계정으로 설치합니다. Pinpoint 실행 또한 centos 계정을 사용합니다.

Maven 3.2.5 버전을 wget으로 다운로드 받은 후 압축을 해제합니다.

[root@ip-172-31-7-87 ~]# exit
[centos@ip-172-31-7-87 ~]# source /etc/profile
[centos@ip-172-31-7-87 ~]# wget http://apache.tt.co.kr/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.tar.gz
--2015-03-25 11:16:07--  http://apache.tt.co.kr/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.tar.gz
Resolving apache.tt.co.kr (apache.tt.co.kr)... 121.125.79.185
Connecting to apache.tt.co.kr (apache.tt.co.kr)|121.125.79.185|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7956528 (7.6M) [application/x-gzip]
Saving to: ‘apache-maven-3.2.5-bin.tar.gz’

100%[======================================>] 7,956,528    124KB/s   in 62s

2015-03-25 11:17:09 (125 KB/s) - ‘apache-maven-3.2.5-bin.tar.gz’ saved [7956528/7956528]

[centos@ip-172-31-7-87 ~]$ tar xfz apache-maven-3.2.5-bin.tar.gz

.bashrc 파일을 편집하여 MAVEN_HOME, PATH 환경변수를 추가합니다.

[centos@ip-172-31-7-87 ~]$ vi ~/.bashrc
export MAVEN_HOME=/home/centos/apache-maven-3.2.5
export PATH=$PATH:$MAVEN_HOME/bin

mvn -version 명령을 실행하여 설치가 잘 됐는지 확인합니다. mvn은 Maven 실행파일입니다.

[centos@ip-172-31-7-87 ~]$ mvn -version
mvn -version
Apache Maven 3.2.5 (12a6b3acb947671f09b81f49094c53f426d8cea1; 2014-12-14T17:29:23+00:00)
Maven home: /home/centos/apache-maven-3.2.5
Java version: 1.8.0_25, vendor: Oracle Corporation
Java home: /opt/jdk1.8.0_25/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-123.8.1.el7.x86_64", arch: "amd64", family: "unix"

Pinpoint 저장소 복제

Pinpoint 저장소를 복제(clone)하기 위해서 root 계정으로 Git을 설치합니다.

[centos@ip-172-31-7-87 ~]$ sudo -i
[root@ip-172-31-7-87 ~]# yum install -y git
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * updates: ftp.riken.jp
Resolving Dependencies
--> Running transaction check
---> Package git.x86_64 0:1.8.3.1-4.el7 will be installed
--> Processing Dependency: perl-Git = 1.8.3.1-4.el7 for package: git-1.8.3.1-4.el7.x86_64
--> Processing Dependency: perl >= 5.008 for package: git-1.8.3.1-4.el7.x86_64
....
....
....
  perl-Time-Local.noarch 0:1.2300-2.el7    perl-constant.noarch 0:1.27-2.el7
  perl-libs.x86_64 4:5.16.3-283.el7        perl-macros.x86_64 4:5.16.3-283.el7
  perl-parent.noarch 1:0.225-244.el7       perl-podlators.noarch 0:2.5.1-3.el7
  perl-threads.x86_64 0:1.87-4.el7         perl-threads-shared.x86_64 0:1.43-6.el7

Complete!

git clone 명령으로 Pinpoint 저장소를 복제합니다.

[root@ip-172-31-7-87 ~]# exit
logout

[centos@ip-172-31-7-87 ~]$ git clone https://github.com/naver/pinpoint.git
Cloning into 'pinpoint'...
remote: Counting objects: 93939, done.
remote: Compressing objects: 100% (218/218), done.
remote: Total 93939 (delta 111), reused 0 (delta 0), pack-reused 93579
Receiving objects: 100% (93939/93939), 151.77 MiB | 7.53 MiB/s, done.
Resolving deltas: 100% (48776/48776), done.

mvn install -Dmaven.test.skip=true 명령으로 Pinpoint를 설치합니다.

maven.test.skip=true은 단위테스트를 건너뛰기 위한 옵션입니다

[centos@ip-172-31-7-87 ~]$ cd pinpoint
[centos@ip-172-31-7-87 pinpoint]$ mvn install -Dmaven.test.skip=true
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] pinpoint
[INFO] pinpoint-thrift
[INFO] pinpoint-commons
[INFO] pinpoint-bootstrap-core
[INFO] pinpoint-bootstrap
[INFO] pinpoint-rpc
[INFO] pinpoint-profiler
[INFO] pinpoint-profiler-optional
[INFO] pinpoint-jdk-http-plugin
[INFO] pinpoint-test
[INFO] pinpoint-redis-plugin
[INFO] pinpoint-servlet-plugin
[INFO] pinpoint-tomcat-plugin
[INFO] pinpoint-plugins
[INFO] pinpoint-agent-distribution
[INFO] pinpoint-collector
[INFO] pinpoint-web
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building pinpoint 1.1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: http://repository.codehaus.org/org/apache/maven/plugins/maven-install-plugin/2.4/maven-install-plugin-2.4.pom
....
....
....
[INFO] Installing /home/centos/pinpoint/web/target/pinpoint-web-1.1.0-SNAPSHOT-classes.jar to /home/centos/.m2/repository/com/navercorp/pinpoint/pinpoint-web/1.1.0-SNAPSHOT/pinpoint-web-1.1.0-SNAPSHOT-classes.jar
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] pinpoint ........................................... SUCCESS [ 23.635 s]
[INFO] pinpoint-thrift .................................... SUCCESS [01:51 min]
[INFO] pinpoint-commons ................................... SUCCESS [01:56 min]
[INFO] pinpoint-bootstrap-core ............................ SUCCESS [  1.393 s]
[INFO] pinpoint-bootstrap ................................. SUCCESS [ 21.062 s]
[INFO] pinpoint-rpc ....................................... SUCCESS [  5.175 s]
[INFO] pinpoint-profiler .................................. SUCCESS [ 48.396 s]
[INFO] pinpoint-profiler-optional ......................... SUCCESS [  0.910 s]
[INFO] pinpoint-jdk-http-plugin ........................... SUCCESS [  0.990 s]
[INFO] pinpoint-test ...................................... SUCCESS [ 34.903 s]
[INFO] pinpoint-redis-plugin .............................. SUCCESS [  1.074 s]
[INFO] pinpoint-servlet-plugin ............................ SUCCESS [  0.887 s]
[INFO] pinpoint-tomcat-plugin ............................. SUCCESS [  1.096 s]
[INFO] pinpoint-plugins ................................... SUCCESS [  0.007 s]
[INFO] pinpoint-agent-distribution ........................ SUCCESS [ 55.523 s]
[INFO] pinpoint-collector ................................. SUCCESS [ 50.376 s]
[INFO] pinpoint-web ....................................... SUCCESS [ 42.698 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 08:37 min
[INFO] Finished at: 2015-03-25T11:38:15+00:00
[INFO] Final Memory: 33M/139M
[INFO] ------------------------------------------------------------------------

HBase 설치, 시작, 초기화

~/pinpoint/quickstart/bin/start-hbase.sh 스크립트를 이용해서 hbase를 다운로드하고 시작합니다.

[centos@ip-172-31-7-87 pinpoint]$ quickstart/bin/start-hbase.sh
Hbase not detected.
Downloading hbase...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 56.5M  100 56.5M    0     0  4030k      0  0:00:14  0:00:14 --:--:-- 5817k
starting master, logging to /home/centos/pinpoint/quickstart/hbase/hbase-0.94.25/bin/../logs/hbase-centos-master-ip-172-31-7-87.out

~/pinpoint/quickstart/bin/init-hbase.sh 스크립트를 이용해서 hbase 테이블을 초기화(initialize)합니다.

[centos@ip-172-31-7-87 pinpoint]$ quickstart/bin/init-hbase.sh
0 row(s) in 1.7520 seconds

0 row(s) in 1.0980 seconds

0 row(s) in 1.0580 seconds

0 row(s) in 2.7240 seconds

0 row(s) in 1.0700 seconds

0 row(s) in 1.0770 seconds

0 row(s) in 2.2110 seconds

0 row(s) in 1.0990 seconds

0 row(s) in 1.0650 seconds

0 row(s) in 1.0530 seconds

0 row(s) in 1.0590 seconds

0 row(s) in 1.0660 seconds

0 row(s) in 1.0470 seconds

0 row(s) in 1.0570 seconds

TABLE
AgentInfo
AgentStat
ApiMetaData
ApplicationIndex
ApplicationMapStatisticsCallee
ApplicationMapStatisticsCaller
ApplicationMapStatisticsSelf
ApplicationStatistics
ApplicationTraceIndex
HostApplicationMap
HostApplicationMap_Ver2
SqlMetaData
StringMetaData
Traces
14 row(s) in 0.0340 seconds

Collector 시작

~/pinpoint/quickstart/bin/start-collector.sh 스크립트를 이용해서 Pinpoint collector를 시작합니다.

[centos@ip-172-31-7-87 pinpoint]$ quickstart/bin/start-collector.sh
---check pinpoint-quickstart-collector process status.---
---initialize pinpoint-quickstart-collector logs.---
mkdir /home/centos/pinpoint/quickstart/logs
mkdir /home/centos/pinpoint/quickstart/logs/pid
---pinpoint-quickstart-collector initialization started. pid=10526.---
starting pinpoint-quickstart-collector. 0 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 5 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 10 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 15 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 20 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 25 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 30 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 35 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 40 /180 sec(close wait limit).
starting pinpoint-quickstart-collector. 45 /180 sec(close wait limit).
---pinpoint-quickstart-collector initialization completed. pid=10526.---
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :230) Pinpoint-UDP-Stat start.
03-25 11:41:54 [WARN ](c.n.p.c.r.u.BaseUDPReceiver        :211) DatagramSocket.setReceiveBu fferSize() error. 4194304!=212992
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :236) UDP Packet reader:2 started .
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :132) start ioThread localAddress :0.0.0.0/0.0.0.0, IoThread:Pinpoint-UDP-Span-Io(11-0)
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :132) start ioThread localAddress :0.0.0.0/0.0.0.0, IoThread:Pinpoint-UDP-Stat-Io(13-0)
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :132) start ioThread localAddress :0.0.0.0/0.0.0.0, IoThread:Pinpoint-UDP-Span-Io(11-1)
03-25 11:41:54 [INFO ](c.n.p.c.r.u.BaseUDPReceiver        :132) start ioThread localAddress :0.0.0.0/0.0.0.0, IoThread:Pinpoint-UDP-Stat-Io(13-1)
03-25 11:41:54 [INFO ](o.s.w.c.ContextLoader              :313) Root WebApplicationContext:  initialization completed in 2246 ms
Mar 25, 2015 11:41:54 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-28082"]

Web UI 시작

~/pinpoint/quickstart/bin/start-web.sh 스크립트를 이용해서 Pinpoint Web UI를 시작합니다.

[centos@ip-172-31-7-87 pinpoint]$ quickstart/bin/start-web.sh
---check pinpoint-quickstart-web process status.---
---initialize pinpoint-quickstart-web logs.---
---pinpoint-quickstart-web initialization started. pid=13397.---
starting pinpoint-quickstart-web. 0 /180 sec(close wait limit).
starting pinpoint-quickstart-web. 5 /180 sec(close wait limit).
starting pinpoint-quickstart-web. 10 /180 sec(close wait limit).
starting pinpoint-quickstart-web. 15 /180 sec(close wait limit).
starting pinpoint-quickstart-web. 20 /180 sec(close wait limit).
starting pinpoint-quickstart-web. 25 /180 sec(close wait limit).
---pinpoint-quickstart-web initialization completed. pid=13397.---
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/transactionInfo/] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/transactionList] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/transactionList.*] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/transactionList/] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/lastTransactionList] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/lastTransactionList.*] onto handler 'businessTransactionController'
11:44:08 INFO (m.a.DefaultAnnotationHandlerMapping:315) Mapped URL path [/lastTransactionList/] onto handler 'businessTransactionController'
11:44:08 INFO (o.s.w.s.DispatcherServlet          :473) FrameworkServlet 'pinpoint-web': initialization completed in 1265 ms
Mar 25, 2015 11:44:08 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-28080"]

TestApp 시작

~/pinpoint/quickstart/bin/start-testapp.sh 스크립트를 이용해서 Pinpoint TestApp을 시작합니다.

[centos@ip-172-31-7-87 ~]$ quickstart/bin/start-testapp.sh
-bash: quickstart/bin/start-testapp.sh: No such file or directory
[centos@ip-172-31-7-87 ~]$ cd pin
-bash: cd: pin: No such file or directory
[centos@ip-172-31-7-87 ~]$ cd pinpoint/
[centos@ip-172-31-7-87 pinpoint]$ quickstart/bin/start-testapp.sh
---check pinpoint-quickstart-testapp process status.---
---initialize pinpoint-quickstart-testapp logs.---
---initialize pinpoint-quickstart-testapp agent.---
---pinpoint-quickstart-testapp initialization started. pid=4048.---
starting pinpoint-quickstart-testapp. 0 /180 sec(close wait limit).
starting pinpoint-quickstart-testapp. 5 /180 sec(close wait limit).
starting pinpoint-quickstart-testapp. 10 /180 sec(close wait limit).
starting pinpoint-quickstart-testapp. 15 /180 sec(close wait limit).
---pinpoint-quickstart-testapp initialization completed. pid=4048.---
2015-03-25 11:48:29 [DEBUG](c.n.p.p.i.b.AspectWeaverClass      :149) JointPoint method __getHeaders(Ljava/lang/String;)Ljava/util/Enumeration; -> invokeOriginal:$_=__getHeaders_$$pinpoint($$);
....
....
....
2015-03-25 11:49:05 [WARN ](c.n.p.r.c.PinpointClientSocketHandshaker:260) Handshake already completed.

확인

설치 및 실행이 완료되면 아래 주소에서 Pinpoint Web UI와 TestApp의 동작을 확인할 수 있습니다.

Web UI - http://localhost:28080

TestApp - http://localhost:28081

TestApp에 있는 여러 링크를 눌러본 후, Pinpoint가 어떻게 동작하는지 확인합니다.

종료

각각 아래의 스크립트로 종료합니다.

HBase - ~/pinpoint/quickstart/bin/stop-hbase.sh

Collector ~/pinpoint/quickstart/bin/stop-collector.sh

Web UI - ~/pinpoint/quickstart/bin/stop-web.sh

TestApp - ~/pinpoint/quickstart/bin/stop-testapp.sh


댓글()

Trello - 리스트 최상단에 카드 추가하기

DevOps|2015. 3. 16. 20:14

Trello 보드에 카드를 추가하려면 보통 리스트 하단의 Add a card를 클릭한 다음 내용을 입력하고 엔터를 치거나 Add를 클릭합니다.

위의 방식으로 한동안 잘 사용해 왔는데 리스트에 카드가 늘어나니까, 최근에 작성한 카드가 맨 아래에 추가되서 눈에 안띄게 됩니다.
카드가 눈에 띄도록 리스트 최상단에 추가해 보겠습니다.

Trello는 보드를 열면 모든 리스트의 스크롤이 최상단에 있기 때문에, 목록에 카드가 많으면 스크롤을 끝까지 내려야 최근에 추가한 카드를 볼 수 있습니다.

리스트 제목 오른쪽에 있는 메뉴를 클릭합니다. 리스트 메뉴는 작고 둥근 회색 버튼이라서 눈에 잘 띄지 않습니다.

Add Card 메뉴를 클릭합니다.

리스트 최상단에 카드 제목을 입력란이 생성됩니다. 내용을 입력하고 Add 버튼을 클릭하면 새 카드가 추가됩니다.

댓글()

Sublime Text 설정과 패키지 동기화 하기(with Dropbox)

Developer Tools|2015. 3. 16. 00:42

Sublime Text에 설치한 패키지와 설정을 여러 컴퓨터에서 동일하게 유지하려면 Packages/User/ 폴더를 공유 저장소에 두고 이를 동기화 해야 합니다. Dropbox를 공유 저장소로 사용하는 동기화 방식을 적용해 봅니다.

기준이 되는 컴퓨터

패키지 설치 및 설정이 완료된 기준 컴퓨터의 설정을 Dropbox로 옮깁니다.

먼저 Sublime Text를 완전히 종료한 후 Windows PowerShell관리자 권한으로 실행합니다.

아래와 같이 PowerShell을 통해 Sublime Text의 Packages/User/ 폴더를 D:\Dropbox\Sublime\User\ 폴더로 대체합니다. Sublime Text 폴더와 Dropbox 폴더는 각자의 설정에 따라 변경해서 적용해야 합니다. 저는 Sublime Text는 기본 위치에 설치했지만, Dropbox는 공유 폴더를 D:\Dropbox로 변경하여 사용 중입니다.

Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Windows\system32> # Sublime Text의 Packages 폴더로 이동합니다
PS C:\Windows\system32> cd "$env:appdata\Sublime Text 3\Packages\"
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> # Dropbox 공유 폴더에 Sublime 폴더를 생성합니다
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> mkdir D:\Dropbox\Sublime
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> # User 폴더를 D:\Dropbox\Sublime 디렉토리로 이동합니다
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> mv User D:\Dropbox\Sublime
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> # D:\Dropbox\Sublime\User 폴더에 대한 링크(User)를 생성합니다
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> cmd /c mklink /D User D:\Dropbox\Sublime\User
User <<===>> D:\Dropbox\Sublime\User에 대한 기호화된 링크를 만들었습니다.
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages>

설정을 공유할 다른 컴퓨터

위에서 Dropbox로 옮긴 패키지/설정을 다른 컴퓨터에서도 똑같이 사용하려면 역시 PowerShell을 통해 작업을 해줘야 합니다. Sublime Text를 종료한 후 Windows PowerShell관리자 권한으로 실행합니다.

Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Windows\system32> # Sublime Text의 Packages 폴더로 이동합니다
PS C:\Windows\system32> cd "$env:appdata\Sublime Text 3\Packages\"
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> # User 폴더와 포함된 모든 폴더/파일을 삭제합니다
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> rmdir -recurse User
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> # D:\Dropbox\Sublime\User 폴더에 대한 링크(User)를 생성합니다
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages> cmd /c mklink /D User D:\Dropbox\Sublime\User
User <<===>> D:\Dropbox\Sublime\User에 대한 기호화된 링크를 만들었습니다.
PS C:\Users\homedir\AppData\Roaming\Sublime Text 3\Packages>

이제 D:\Dropbox\Sublime\User 폴더에 공유된 설정을 통해서 Sublime Text가 실행되기 때문에 양쪽 컴퓨터에서 동일한 개발환경을 사용할 수 있습니다.


댓글()