elasticsearch에 보면 json 출력을 예쁘게 (&pretty) 할 수 있다.



만약 url을 통해 들어오는 json이라면 python을 활용해 예쁘게 출력할 수 있다. 



echo '{"url":"http:\/\/search.google.com\/api/v2/keyword", "param":"abc"}' | python -mjson.tool

{

    "url": "http://search.google.com/api/v2/keyword",

    "param": "abc"

}




Posted by 김용환 '김용환'


Apache Phoenix 드라이버를 사용할 때 유의할 사항이 있다. 

play2의 db에서는 jdbc url에 매개변수(또는 configuration)을 추가할 수 없다. 즉 DriverManager.getConnection("..", props)에서 props에 관련 설정을 추가해야 한다. 



아래와 같은 방식은 사용할 수 없다. 

db {
default.driver = org.apache.phoenix.jdbc.PhoenixDriver
default.url = "jdbc:phoenix:hbase-md15b1-031.dakao.io:8765/kemi;phoenix.schema.isNamespaceMappingEnable=true;phoenix.functions.allowUserDefinedFunctions=true"
default.logSql = true
default.username = ""
default.password = ""
}


문서를 잘 보면. 덜 개발되었다..




참고 https://phoenix.apache.org


Use JDBC to get a connection to an HBase cluster like this:

Connection conn = DriverManager.getConnection("jdbc:phoenix:server1,server2:3333",props);

where props are optional properties which may include Phoenix and HBase configuration properties, and the connection string which is composed of:

jdbc:phoenix [ :<zookeeper quorum> [ :<port number> [ :<root node> [ :<principal> [ :<keytab file> ] ] ] ] ] 





아래와 같이 사용해야 한다. 


Properties props = new Properties();

props.setProperty("phoenix.schema.isNamespaceMappingEnabled", "true");

props.setProperty("phoenix.functions.allowUserDefinedFunctions", "true");

connection = DriverManager.getConnection("jdbc:phoenix:...", props);





또한 sbt 또한 문제가 있다.  sbt에서 apache phoenix 드라이버를 사용하기 위해 lib, guava 이슈를 해결해야 한다. 얼추 해결되더라도 추후 runtime 이슈가 생길 수 있다. 




사례 1

Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.HBaseConfiguration

at java.net.URLClassLoader.findClass(URLClassLoader.java:381)

at java.lang.ClassLoader.loadClass(ClassLoader.java:424)

at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

at org.apache.phoenix.query.ConfigurationFactory$ConfigurationFactoryImpl$1.call(ConfigurationFactory.java:49)

at org.apache.phoenix.query.ConfigurationFactory$ConfigurationFactoryImpl$1.call(ConfigurationFactory.java:46)

at org.apache.phoenix.util.PhoenixContextExecutor.call(PhoenixContextExecutor.java:76)

at org.apache.phoenix.util.PhoenixContextExecutor.callWithoutPropagation(PhoenixContextExecutor.java:91)

at org.apache.phoenix.query.ConfigurationFactory$ConfigurationFactoryImpl.getConfiguration(ConfigurationFactory.java:46)

at org.apache.phoenix.jdbc.PhoenixDriver.initializeConnectionCache(PhoenixDriver.java:151)

at org.apache.phoenix.jdbc.PhoenixDriver.<init>(PhoenixDriver.java:142)




resolvers += "Cloudera Repository" at "https://repository.cloudera.com/artifactory/cloudera-repos/"


libraryDependencies ++= Seq(
"org.apache.hbase" % "hbase" % "1.2.6",
"org.apache.hbase" % "hbase-common" % "1.2.6",
"org.apache.hbase" % "hbase-client" % "1.2.6",
"org.apache.hbase" % "hbase-server" % "1.2.6", "org.apache.phoenix" % "phoenix-core" % "4.11.0-HBase-1.2",

..)



사례 2



 org.apache.hadoop.hbase.DoNotRetryIOException: java.lang.IllegalAccessError: tried to access method com.google.common.base.Stopwatch.<init>()V from class org.apache.hadoop.hbase.zookeeper.MetaTableLocator



libraryDependencies ++= Seq(
"com.google.guava" % "guava" % "13.0.1" force(),
"org.apache.hbase" % "hbase" % "1.2.6",
"org.apache.hbase" % "hbase-common" % "1.2.6",
"org.apache.hbase" % "hbase-client" % "1.2.6",
"org.apache.hbase" % "hbase-server" % "1.2.6",
"org.apache.phoenix" % "phoenix-core" % "4.11.0-HBase-1.2")



결론은 apache phoenix를 연동하기 위해 play2-sbt를 사용하는 것은 조금 귀찮을 수 있다..


scala를 쓰려면 무거운 play2보다는 경량 프레임워크를 사용하고 내가 db 모듈을 만드는 게 나을 수도.. 

Posted by 김용환 '김용환'


https://www.playframework.com/documentation/2.6.x/api/java/play/db/Database.html 문서에는 있는데.


play.db.Database를 import하려고 하려면 에러가 난다.


import play.db._



libraryDependencies += jdbc 를 추가하면 된다. 기본적으로 추가가 되어 있지 않다.. 

Posted by 김용환 '김용환'



sbt는 스칼라 컴파일 툴이다.

의존성을 추가할 때 

%%를 사용하면 버전을 artifact 뒤에 추가한다. 스칼라는 아직 하위 호환성보다는 잘 만들어질 언어를 지향하기 때문인데..


그러나 자바 라이브러리를 쓰기 위해 %%를 하면 에러가 발생한다. 그 것은 자바는 버전 별로 라이브러리를 만들지 않기 때문이다. 



sbt.librarymanagement.ResolveException: unresolved dependency: org.apache.phoenix#phoenix-core_2.11;4.11.0-HBase-1.2: not found




scala lib은 %%를

java lib은 %를 사용하는 것에 익숙해질 필요가 있다. ㅠ(맨날 틀림.)

libraryDependencies ++= Seq(guice,
"org.scalatestplus.play" %% "scalatestplus-play" % "3.1.1" % "test",
"org.apache.phoenix" % "phoenix-core" % "4.11.0-HBase-1.2")


Posted by 김용환 '김용환'


요즘 뜨고 있는 java REST 테스트 관련 라이브러리 중에 https://github.com/rest-assured/rest-assured이 있다.


자바에서는 구조적으로 REST 호출과 결과 테스트(특히 json)를 하려면 지저분한 코드(map, list)를 써야 한다.

rest-assured는 이를 쉽게 테스트해줄 수 있다. 



http://localhost:8080/lotto


{
"lotto":{
 "lottoId":5,
 "winning-numbers":[2,45,34,23,7,5,3],
 "winners":[{
   "winnerId":23,
   "numbers":[2,45,34,23,3,5]
 },{
   "winnerId":54,
   "numbers":[52,3,12,11,18,22]
 }]
}
}




테스트 코드는 다음과 같다. 써봐야 할듯 ㅎㅎ


get("/lotto").then().body("lotto.lottoId", equalTo(5));



get("/lotto").then().body("lotto.winners.winnerId", hasItems(23, 54));




Posted by 김용환 '김용환'


intellij에서 sbt 컴파일 중에 에러가 발생했다. 


[error] java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: sbt/internal/librarymanagement/GetClassifiersModule



최신 버전으로 intellij를 업데이트하면 문제가 해결된다.

Posted by 김용환 '김용환'

도커를 다시 하니 개념이 없어서 다시 개념을 잡기 위해서 무한 링크.. 


docker network, docker container, docker client cli, docker image, docker data volumns, docker rest api, docker daemon


출처 : https://docs.docker.com/engine/docker-overview/#what-can-i-use-docker-for




docker client, docker host, docker object, docker daemon, docker container, docker image, docker registry

출처 : https://docs.docker.com/engine/docker-overview/#the-docker-platform


namespace 


출처 : http://prog3.com/sbdm/blog/shlazww/article/details/47284675

https://success.docker.com/KBase/Introduction_to_User_Namespaces_in_Docker_Engine








veth, docker networking



출처 : http://www.linuxjournal.com/content/concerning-containers-connections-docker-networking








bridged, host mode, macvlan bridge mode, ipvlan mode 



출처 : http://www.abusedbits.com/2016/09/docker-host-networking-modes.html












libcontainer, libvirt, lxc, systemd-nspawn


출처: https://itechcraft.com/docker-containers-microservice-architecture/





aufs, lvm, zfs, rootfs, bootfs, 


출처 : https://image.slidesharecdn.com/bonamico-codemotion-docker-2014-2-141129035905-conversion-gate01/95/codemotiondocker2014-10-638.jpg?cb=1417233667




Posted by 김용환 '김용환'



카산드라 모니터링 메트릭 

- cassandra 3.0부터는 ops center가 없기 때문에 devops가 잘 살펴봐야 한다. 



https://www.datadoghq.com/blog/how-to-monitor-cassandra-performance-metrics/


https://github.com/QuentinAmbard/cassandra-troubleshooting


https://wiki.apache.org/cassandra/Metrics


https://www.datadoghq.com/blog/how-to-collect-cassandra-metrics/


http://www.datastax.com/dev/blog/pluggable-metrics-reporting-in-cassandra-2-0-2


Posted by 김용환 '김용환'

soscon 2017 후기

scribbling 2017.10.28 07:22




http://www.soscon.net/schedule.do를 다녀왔고 후기를 적는다.


http://www.soscon.net/pdf/day1_1530_3.pdf

# 부럽다. 9x년대생, 행복해 보여요.


http://www.soscon.net/pdf/day1_1330_3.pdf

# AI + Cloud !!


http://www.soscon.net/pdf/day1_1430_1.pdf

# java redis client https://github.com/lettuce-io/lettuce-core


http://www.soscon.net/pdf/day1_1630_2.pdf

# hive2 좋아지네


http://www.soscon.net/pdf/day2_1000_1.pdf

# 대단!, 존경!


http://www.soscon.net/pdf/day2_1430_3.pdf

# webidl이 생겼구나


http://www.soscon.net/pdf/day2_1530_3.pdf

# openwhisk가 있구나


http://www.soscon.net/pdf/day2_1630_2.pdf

# openstack-helm을 사용하여 쿠버네티스로 오픈 스택을 관리할 수 있네.

Posted by 김용환 '김용환'


맥에서 도커 컨테이너 실행 시, 포트 연결이 안될 수 있다. 내부망 172.17.x.x 대역을 사용하는 환경에서 이슈가 존재한다. 도커는 디폴트로 172.17.0.0/16 대역을 사용하고 있다. 



gateway가 172.17.0.1이고 IPAddress가 172.17.0.2이라면 도커 컨테이너 실행시 포트 포워딩한다 해도 로컬 호스트에서 도커 포트로 연결이 안되는 문제가 발생된다. 


도커 기본 네트워크 환경을 변경한다. 다음 처럼 도커 기본 네트워크를 172.17.x.x. 대역이 아닌 192.168.x.x 대역으로 기본 구성을 변경한다. 


# cd ~/Library/Containers/com.docker.docker/Data/database

# git reset HEAD com.docker.driver.amd64-linux

Unstaged changes after reset:

D com.docker.driver.amd64-linux/disk/compact-after

D com.docker.driver.amd64-linux/disk/on-flush

D com.docker.driver.amd64-linux/disk/path

D com.docker.driver.amd64-linux/disk/size

D com.docker.driver.amd64-linux/disk/trim

D com.docker.driver.amd64-linux/etc/docker/daemon.json

D com.docker.driver.amd64-linux/etc/hostname

D com.docker.driver.amd64-linux/etc/ssl/certs/ca-certificates.crt

D com.docker.driver.amd64-linux/etc/sysctl.conf

D com.docker.driver.amd64-linux/expose-docker-socket

D com.docker.driver.amd64-linux/filesystem

D com.docker.driver.amd64-linux/hypervisor

D com.docker.driver.amd64-linux/insecure-registry

D com.docker.driver.amd64-linux/memory

D com.docker.driver.amd64-linux/memoryMiB

D com.docker.driver.amd64-linux/mounts

D com.docker.driver.amd64-linux/native/boot-protocol

D com.docker.driver.amd64-linux/native/port-forwarding

D com.docker.driver.amd64-linux/native/uefi-boot-disk

D com.docker.driver.amd64-linux/ncpu

D com.docker.driver.amd64-linux/network

D com.docker.driver.amd64-linux/on-sleep

D com.docker.driver.amd64-linux/proxy-system/exclude

D com.docker.driver.amd64-linux/proxy-system/http

D com.docker.driver.amd64-linux/proxy-system/https

D com.docker.driver.amd64-linux/proxy-verbose

D com.docker.driver.amd64-linux/proxy/exclude

D com.docker.driver.amd64-linux/proxy/http

D com.docker.driver.amd64-linux/proxy/https

D com.docker.driver.amd64-linux/proxy/mode

D com.docker.driver.amd64-linux/schema-version

D com.docker.driver.amd64-linux/slirp/dns

D com.docker.driver.amd64-linux/slirp/docker

D com.docker.driver.amd64-linux/slirp/domain

D com.docker.driver.amd64-linux/slirp/host

D com.docker.driver.amd64-linux/slirp/max-connections

D com.docker.driver.amd64-linux/slirp/mtu

D com.docker.driver.amd64-linux/state/last-shutdown-time

D com.docker.driver.amd64-linux/state/last-start-time

D com.docker.driver.amd64-linux/upgrade/experimental-debug

D com.docker.driver.amd64-linux/vmnet-simulate-failure


# git checkout -- com.docker.driver.amd64-linux


# vi com.docker.driver.amd64-linux/etc/docker/daemon.json

// {"debug":true,"experimental":true} 이렇게 되어 있는데.. 다음처럼 추가한다. 

{"debug":true,"experimental":true, "bip":"192.168.5.1/24"}



그 다음 Docker for mac 프로세스를 재시작한다. 



이제 확인해보자. 최신 docker를 사용 중인지 확인하고 테스트할 도커 이미지를 실행한다. 테스트할 도커 이미지는 springcloud/eureka이다. 



$ docker version

Client:

 Version:      17.09.0-ce

 API version:  1.32

 Go version:   go1.8.3

 Git commit:   afdb6d4

 Built:        Tue Sep 26 22:40:09 2017

 OS/Arch:      darwin/amd64


Server:

 Version:      17.09.0-ce

 API version:  1.32 (minimum version 1.12)

 Go version:   go1.8.3

 Git commit:   afdb6d4

 Built:        Tue Sep 26 22:45:38 2017

 OS/Arch:      linux/amd64

 Experimental: true

 





참고로 도커 컨테이너를 포그라운드 데몬하고 싶다면 다음 방식을 사용한다. 포트가 8761포트로 뜬 지 확인한다. 


이렇게 하면 포트 포워딩이 되지 않는다.


$ docker run springcloud/eureka

..

2017-10-20 02:35:42.958  INFO 1 --- [       Thread-4] c.n.eureka.PeerAwareInstanceRegistry     : Adding replica node: http://localhost:8761/eureka/

2017-10-20 02:35:43.025  INFO 1 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8761 (http)

2017-10-20 02:35:43.028  INFO 1 --- [           main] eurekademo.EurekaApplication             : Started EurekaApplication in 8.907 seconds (JVM running for 9.702)

2017-10-20 02:35:43.081  INFO 1 --- [       Thread-4] c.n.eureka.PeerAwareInstanceRegistry     : Updating the replica nodes as they seem to have changed from [] to [http://localhost:8761/eureka/]





-p 옵션을 주어야 동작할 수 있다. 8761포트를 8888포트로 연결할 마음으로  -p 8761:8888을 추가했다.

(따라하지 말고, 아래부터는 내용을 볼 것!!!)


$ docker run  -p 8761:8888  springcloud/eureka


-ti 옵션을 주면 조금 출력이 예뻐보인다. 


$ docker run  -p 8761:8888 -ti springcloud/eureka




백그라운드로 데몬을 실행하려면 다음을 사용한다. 


$ docker run  -p 8761:8888 -d springcloud/eureka




docker ps로 확인하니. 아래와 같이 나왔다. 



$ docker ps

CONTAINER ID        IMAGE                COMMAND                CREATED              STATUS              PORTS                              NAMES

a3938ad9745b        springcloud/eureka   "java -jar /app.jar"   About a minute ago   Up About a minute   8761/tcp, 0.0.0.0:8761->8888/tcp   focused_hopper




그러나 


8761, 8888 포트로 접근이 되지 않는다. 


$ curl localhost:8761/eureka/


$ curl localhost:8888/eureka/





확인해보기 위해 docker inspect를 실행해 보낟. 


$ docker inspect 도커-컨테이너-이름




네트워크만 보려면 다음 커맨드를 실행한다.  docker bridge 잘 있고. 네트워크도 192.168로 잘 설정되어 있다. 




$ docker network inspect bridge

[

    {

        "Name": "bridge",

        "Id": "13216e45817d9a5c15fffd0b77c732a65365129d49d1ed04fb8bbdc53c0ab348",

        "Created": "2017-10-27T06:33:11.783006123Z",

        "Scope": "local",

        "Driver": "bridge",

        "EnableIPv6": false,

        "IPAM": {

            "Driver": "default",

            "Options": null,

            "Config": [

                {

                    "Subnet": "192.168.5.1/24",

                    "Gateway": "192.168.5.1"

                }

            ]

        },

        "Internal": false,

        "Attachable": false,

        "Ingress": false,

        "ConfigFrom": {

            "Network": ""

        },

        "ConfigOnly": false,

        "Containers": {},

        "Options": {

            "com.docker.network.bridge.default_bridge": "true",

            "com.docker.network.bridge.enable_icc": "true",

            "com.docker.network.bridge.enable_ip_masquerade": "true",

            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",

            "com.docker.network.bridge.name": "docker0",

            "com.docker.network.driver.mtu": "1500"

        },

        "Labels": {}

    }

]





도커 컨테이너로 들어가도 잘 동작되는 것 같다. 


$ docker exec -it focused_hopper bash

root@6090234a5b33:/# 

root@6090234a5b33:/# ip addr

39: eth0@if40: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default

    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff

    inet 192.168.1.2/16 scope global eth0

       valid_lft forever preferred_lft forever

       



네트워크도 문제 없다. 

       

root@6090234a5b33:/# ip route

default via 172.17.0.1 dev eth0

172.17.0.0/16 dev eth0  proto kernel  scope link  src 172.17.0.2



내부에서 실행하면 동작이 잘된다. 


root@6090234a5b33:/#curl 172.17.0.2:8761

<!doctype html>

...





문제는 docker exec -p 옵션을 줄 때 반대로 주었다. 실제로 포트 포워딩할 포트가 앞에. 도커 컨테이너 포트는 뒤에 있어야 한다. 


docker -p "포트 포워딩할 포트:도커 컨테이너 포트" 이렇게 구성해야 한다. 이걸 모르고 삽질하고 있었다. 


다시 도커 컨테이너를 실행해본다. 



# docker run  -p 8888:8761 -d springcloud/eureka



# docker ps

CONTAINER ID        IMAGE                COMMAND                CREATED             STATUS              PORTS                    NAMES

75ba8624fff6        springcloud/eureka   "java -jar /app.jar"   6 seconds ago       Up 4 seconds        0.0.0.0:8888->8761/tcp   frosty_elion




# curl localhost:8888 하니 동작이 잘된다. 


docker port로 확인해보니 잘 동작한다. 


# docker port frosty_elion

8761/tcp -> 0.0.0.0:8888



lsof listen 포트 확인하니. 제대로 동작하는지 확인할 수 있었다. 


# lsof -iTCP -sTCP:LISTEN -n -P


vpnkit    21848 samuel.kim   20u  IPv4 0xb0df1cffacb7067      0t0  TCP *:8888 (LISTEN)

vpnkit    21848 samuel.kim   21u  IPv6 0xb0df1d003088737      0t0  TCP [::1]:8888 (LISTEN)





잘 동작한 것을 확인하고 도커 컨테이너를 내린다. 


$ docker stop frosty_elion




공부자료.

https://docs.docker.com/engine/userguide/networking/default_network/custom-docker0/

https://github.com/moby/moby/issues/25064

https://docs.docker.com/engine/reference/commandline/dockerd/




Posted by 김용환 '김용환'