반응형
반응형
일단 어떤 솔루션이든 클러스터 구성을 위해선, 적어도 3대의 장비를 필요로 한다.

1. 설치
 - Java 설치 (+환경변수) : 생략
 - Zookeeper 설치
# download
wget http://apache.mirror.cdnetworks.com/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz

# 압축해제
tar -zxvf zookeeper-3.4.10.tar.gz

# 심볼릭 링크 설정 (선택)
ln -s zookeeper-3.4.10 zookeeper


설치하고 나면, conf 폴더에 zoo_sample.cfg 파일이 있는데, 복사하여 zoo.cfg파일을 만든 후 내용을 아래와 같이 편집한다.

# zoo.cfg
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
# for cluster
server.1=0.0.0.0:2888:3888
server.2=머신2의 ip:2888:3888
server.3=머신3의 ip:2888:3888


for cluster 주석 아래 부분에 server목록을 지정해주는데, server.{id} 형태로 지정하게 된다.

id 부분에 입력된 숫자를 dataDir에 myid 파일을 생성하여 아래와 같이 입력해주어야 한다.

$ echo 1 >> /tmp/zookeeper/myid


server.1의 경우 ip가 0.0.0.0인데, 해당 하는 노드가 localhost에 위치해 있는 경우, 예외상황 발생을 막기 위해 0.0.0.0으로 지정해주는 것을 권장한다고 하니, 자기 자신은 0.0.0.0으로 지정해준다.


이제 Zookeeper 서버를 띄워본다.

$ bin/zkServer.sh start


서버를 띄운 후 설정 값에 문제가 있는 경우, Cannot open channel to x at election address 와 같은 에러를 로그에서 확인할 수 있는데, 이런 경우는 myid 값이 제대로 들어가지 않았거나, 존재하지 않는 경우 발생하니 다시 한번 체크해보면 된다.

반응형
,
반응형

application/json 헤더를 지정하여 WebAPI를 통해 들어오는 Json Request Body를 그대로 Broker에 전달해야하는 API를 만들 일이 생겼다.


전달하는 것까지는 좋은데, 최소한의 검증 (Null, Empty Check나 integer의 경우 마이너스 값 체크) 정도는 해야되겠다 싶어서, @Valid를 이용해보기로 하였다.


일단 Model선언은 아래와 같이 했다.

public class TestLog {
	@Min(1)
	private int id;
	
	@NotNull
	@NotEmpty	
	private String description;
	
	@NotNull
	@NotEmpty
	private String now;
}


@Min, @NotNull 의 경우 기본적으로 java에서 제공하지만, @NotEmpty같은 경우는 hibernate-validator 의존성을 추가해주어야 한다.  (http://hibernate.org/validator/)


위와 같이 Model을 만든 후 Controller의 API에, @Valid만 붙여주면 된다.

@PostMapping("/test_log")
public Result testLog(@RequestBody @Valid TestLog testLog) {
	return "ok";
}


이제 Body로 들어오는 파라미터가 id는 1보다 작은 경우, description, now는 비어있거나 Null인 경우 400에러와 함께, org.springframework.web.bind.MethodArgumentNotValidException를 뱉어내게 된다.


클라 입장에서 받는 Response Body는 아래와 같이 생겼다.

{
	"timestamp": 1494829780576,
	"status": 400,
	"error": "Bad Request",
	"exception": "org.springframework.web.bind.MethodArgumentNotValidException",
	"errors": [{
		"codes": ["Min.testLog.id", "Min.id", "Min.int", "Min"],
		"arguments": [{
			"codes": ["testLog.id", "id"],
			"arguments": null,
			"defaultMessage": "id",
			"code": "id"
		}, 1],
		"defaultMessage": "반드시 1보다 같거나 커야 합니다.",
		"objectName": "testLog",
		"field": "id",
		"rejectedValue": 0,
		"bindingFailure": false,
		"code": "Min"
	}],
	"message": "Validation failed for object='testLog'. Error count: 1",
	"path": "/api/test_log"
}


기본적으로 위와 같은 Json 형태로 Response를 주기 때문에, 클라 입장에서 공통으로 Body를 parsing하여 사용하려면, 서버 단에서 해당 Exception을 핸들링하여 별도로 아래와 같이 예외처리를 해주어야 한다. 

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result handleMethodArgumentException(MethodArgumentNotValidException e) {	
        return "fail";
}


반응형
,
반응형

apt-get이나 yum을 이용해서 패키지 설치를 하게 되면, 기본적으로 cassandra는 127.0.0.1로 뜨게되어,

로컬 환경에서밖에 접속을 못하게 된다.


이런 경우, cassandra.yaml을 열어서 rpc가 지원되도록 아래와 같은 설정을 찾아서 변경해주어야 한다.


콜론 뒤에 띄어쓰기가 무조건 한 칸 있어야 에러가 발생하지 않으므로, 설정 변경 간 띄어쓰기에 유의해야 한다.

# /etc/cassandra/cassandra.yaml
start_rpc: true     # default : false
rpc_address: 0.0.0.0  # default: localhost
broadcast_rpc_address: localhost  # 원래 주석처리 되어있던 걸 풀어서 localhost로 맞춰준다.


이렇게 설정해두면, 기본 포트인 9042포트와 Thrift를 이용한 고속 전송(맞는 표현인지 모르겠음;)을 지원하는 9160포트가 동시에 0.0.0.0으로 listening 되게 된다.

반응형

'개발 > Cassandra' 카테고리의 다른 글

[Cassandra] 클러스터 구성  (0) 2017.05.31
[Cassandra] 3.10 기준 Cluster name 변경하기  (0) 2017.05.10
,
반응형

cassandra.yaml에서만 변경하면, 서비스 재시작 시 자동으로 반영해줄거라 생각했지만, 클러스터 명이 다르다는 에러가 발생하게 된다.


이런 경우 설정을 원래대로 원복시키고, cqlsh에 들어가서 직접 쿼리를 날려준 후, 설정 파일을 바꾸어주면 문제가 발생하지 않는다.

cqlsh> UPDATE system.local SET cluster_name = '변경할 클러스터명' where key='local';


반응형

'개발 > Cassandra' 카테고리의 다른 글

[Cassandra] 클러스터 구성  (0) 2017.05.31
[Cassandra] 3.10 기준 rpc 설정하기  (0) 2017.05.10
,
반응형

docker-compose를 사용했다는 가정하에, Version2의 compose파일을 이용하는 경우는 아래와 같이 확인 (브릿지어댑터를 이용해서 네트워크 할당을 한다고 한다.)

$ docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'  container_name


그외의 경우는 아래와 같이 확인

$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' container_name


반응형
,
반응형

하나의 서버가 http와 ws스펙을 지원해야 하고, apache / nginx 같은 웹서버 뒷단(Proxy 환경)에서 서비스를 해야 되는 경우가 생겼다.


nginx같은 경우 간단하게 헤더 몇개만 추가해주면 자연스럽게 해결이 되는데,

apache같은 경우는 rewrite engine과 proxy_wstunnel engine을 enable 시킨 후, 별도의 조건까지 등록을 해주어야 가능하다.


아래 커맨드는 Ubuntu / Debian 계열 Linux 기준의 예제이고, 위에 얘기한 engine들을 enable 시키는 방법은 아래와 같다. 

$ a2enmod rewrite        # 보통 default로 enable 되어있는 경우가 많다.
$ a2enmod proxy_wstunnel


이제 Rewrite Engine 설정을 해준다. (포트가 6050인 경우)

# http-vhosts.conf
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} =websocket [NC]
RewriteRule .* ws://127.0.0.1:6050/$1 [P,L]

ProxyPass / http://127.0.0.1:6050
ProxyPassReverse / http://127.0.0.1:6050


모든 작업 후 apache2를 재시작 해주면 적용된다.


정리하는 김에.. Nginx같은 경우는 아래와 같이 설정하면 됨.

server:
  location /:
    proxy_pass http://127.0.0.1:6050;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;


반응형
,
반응형

SSH 서버 하나에 붙어서, 여러가지 명령을 처리해야 하는 경우 application 단에서는 SSH 서버에 인증을 한 후 RPC콜을 위해 요청 하나마다 세션을 하나씩 할당받아서 사용하게 되는데, Linux 머신의 sshd의 경우 MaxSession값이 Default값이 10으로 되어 있어서, 10개 이상 요청하려고하면 연결이 안된 것처럼 오동작을 할 때가 있다.

 

이런 경우 sshd_config 설정을 조금 건드려주면, 원활하게 처리가 가능하다.


아래 키워드를 sshd_config 설정 안에 포함을 시키면, 원하는 개수만큼 세션이 늘어나게 된다.

MaxSessions 200


위 내용을 추가하고, 서비스를 재시작 해주면 완료

$ service sshd restart       # 서비스 재시작 (환경에 따라 서비스명이 ssh일수도 있음)
$ /usr/sbin/sshd -T | grep -i maxsessions      # 적용된 내용 확인


반응형
,
반응형

3rd Party API를 jquery 단에서 여러번 호출해야 하는 일이 있는데, network latency 등 여러가지 이슈가 있기 때문에,

front단에서 한 번에 묶어서 보내고, back단에서 처리되게끔 하다보니, jquery 단에서 array형태로 묶어서,

back단(Spring)에서 List형태의 Model로 받아서 처리하니 깔끔하게 정리가 되어서, 이 방법에 대해 정리한다.


[Jquery]

var arr = [{"a":1, "b":2}, {"a":2, "b":4}];

$.ajax({
    url: 'url',
    , type: 'post'
    , dataType: 'json'   // 데이터 타입을 Json으로 변경
    , contentType: 'application/json'   // Content-Type을 Json으로 변경
    , data: JSON.stringify(arr)    // JSON String으로 전환하여 보낸다.
    , success: function(response) {
    }
});


위와 같이 전송을 하면, 서버에서는 javascript의 array를 Json Array로 인식을 하기 때문에, 

application/json 기반의 서비스라면, List Model로 매핑을 할 수가 있다. (Spring Boot가 기본 MessageConverter가 마침 Json이어서 이렇게 사용했다.)


[Spring Boot]

...
@Getter
@Setter
@ToString
public class Abc {
    Abc() { }

    private int a;
    private int b;
}

@PostMapping("url")
public void url(@RequestBody List abcs) {
    abcs.stream().forEach(abc -> {
        System.out.println(abc.toString());
    });
}
...


원하는 형태로 List로 잘 매핑이 된다.

반응형
,
반응형

리눅스 같은 경우는 pip3 install mysqlclient 키워드 하나로 종료되지만,

Windows의 경우 VisualStudio의 영향을 받는지, 이것저것 에러가 발생을 하기 때문에

mysqlclient을 직접 받아서 컴파일 하는 복잡한 과정을 거쳐야 한다.


하지만, 다행히도 누가 이미 컴파일을 해놓은 바이너리를 모아놓은 아래와 같은 사이트가 있다.

http://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient


python과 os bit에 맞게 파일을 다운 받은 후 아래와 같이 설치를 하면 된다.

$ pip install 다운받은파일.whl


반응형
,
반응형

매번 VisualStudio를 몇시간씩 깔고 하는게 귀찮아서, 간단한 걸 찾아보던 중

Python에서도 지원하는 Form기반의 GUI 툴이 있었다.


일단 설치는 공식홈에서도 가능하긴하지만, QT Designer가 Windows에서는 잘 안되는 모양인 것 같으니,

아래 링크에서 설치하였다. (Python 3.4, 64bit OS 기준)

https://sourceforge.net/projects/pyqt/files/PyQt5/PyQt-5.4.1/PyQt5-5.4.1-gpl-Py3.4-Qt5.4.1-x64.exe/download


설치하고 나면, 프로그램 목록에 아래와 같은 Qt Designer라는 GUI 구성을 편리하게 해주는 Tool이 덤으로 설치되어 나온다.


이것저것 편집을 하고나서 저장을 하려고 보면, .ui 파일만 하나 떨구게 되는데,

ui파일을 py파일로 변환을 해서 사용을 해야 한다.


변환방법은 아래와 같다.

Windows에서 기본 설치 기준으로 C:\Python34\Lib\site-packages\PyQt5 경로로 이동 후 아래 키워드 입력

$ python uic/pyuic.py -x ui파일명.ui -o 뽑아낼파일명.py


변환 과정에서 두 가지 예외 케이스가 있다.

1. PyQt5와 Python3.4의 OS bit 버전이 다르게 설치된 경우

  > 해결 : OS bit버전을 서로 맞춰서 재설치한다.


2. OS 자체에서 상대경로 참조를 못하는 경우

  > 해결 : pyuic.py 을 열어서 아래와 같이 절대경로로 바꿔준다. 

import sys
import optparse

from PyQt5 import QtCore
from PyQt5.uic.driver import Driver # 이 부분!

Version = "Python User Interface Compiler %s for Qt version %s" % (QtCore.PYQT_VERSION_STR, QtCore.QT_VERSION_STR)

if sys.hexversion >= 0x03000000:
    from PyQt5.uic.port_v3.invoke import invoke  # 이 부분!
else:
    from PyQt5.uic.port_v2.invoke import invoke  # 이 부분!


주석 달아놓은 세 군데 정도만 바꿔주면 정상적으로 .py 파일로 변환을 해준다.

본 포스팅에선 세팅이 목표이므로, 사용법은 다루지 않겠다.

반응형

'개발 > Python' 카테고리의 다른 글

[Python 2.x] UTF-8 인코딩 관련  (0) 2017.08.09
[Python] Python 3.x no module MysqlDB  (0) 2017.02.14
[Python] pyYaml을 이용한 yaml parsing  (0) 2017.02.10
[Python] asyncio  (0) 2017.02.10
[Python] paramiko for SSHClient  (0) 2017.02.10
,
반응형