01 Sep 2017
|
docker
redis
Docker를 이용하여 간단하게 redis 설치 및 사용하는 방법을 정리해봤습니다.
설치
Docker가 설치 된 상태에서 아래 커맨드를 이용하여 설치합니다.
시작하기
$ docker run --name some-redis -d -p 6379:6379 redis
Docker를 실행하여 Redis서버를 올리고 기본 포트인 6379로 실행됩니다.
-d옵션은 백그라운드에서 실행하겠다는 의미이며
-p옵션은 외부에서 해당 포트로 접속할 수 있게 열어둔다는 의미입니다.
해당 Redis서버의 데이터를 외부에서 관리하고 싶을 경우에는 아래와 같이 사용합니다.
## 외부 폴더에 데이터 저장소를 두고 싶을 경우
$ docker run --name some-redis -d -v /your/dir:/data redis redis-server --appendonly yes
## 다른 컨테이너에 저장소를 두고 싶은 경우
$ docker run --name some-redis -d --volumes-from some-volume-container redis redis-server --appendonly yes
appendonly yes 옵션은 AOF방식으로 데이터를 저장(참고:Redis Persistence Introduction)하겠다는 의미입니다.
데이터는 기본적으로 /data하위에 저장되며 외부에서 해당 폴더를 공유함으로써 해당 컨테이너를 지우고 새로 만들어도 해당 volume을 참고하게 하면 동일한 데이터를 유지 할 수 있습니다.
OS X의 경우 사전에 Docker에서 공유폴더로 지정되지 않은 경우 아래와 같은 오류를 만날 수 있습니다.
docker: Error response from daemon: Mounts denied:
The path /Users/jistol/data
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker -> Preferences… -> File Sharing.
See https://docs.docker.com/docker-for-mac/osxfs/#namespaces for more info.
위와 같은 오류 발생시 메시지에 나온데로 Docker -> Preferences -> File Sharing 설정에서 공유할 폴더를 추가해 주면 됩니다.

외부에서 접근하기
외부에서 Redis 컨테이너를 접근하는 방법은 3가지 입니다.
1. 외부 서버에서 접근하기
위에 명시한 것과 같이 -p 옵션을 통해 port를 뚫어 직접 접근 할 수 있습니다.
$ docker run --name some-redis -d -p 6379:6379 redis
2. 다른 컨테이너에서 접근하기
--link나 -network옵션을 통해 접근 가능합니다. (참고:Docker container networking)
$ docker run --name some-app --link some-redis:redis -d application-that-uses-redis
3. redis-cli로 접근하기
아래와 같은 명령으로 접근할 수 있습니다.
$ docker run -it --link some-redis:redis --rm redis redis-cli -h redis -p 6379
Redis 컨테이너 기동 방식에 따라 --link나 --network, 혹은 port를 외부로 열었다면 두 옵션 없이 사용 가능합니다.
--rm 옵션은 컨테이너 종료시 자동으로 해당 컨테이너를 삭제해줍니다.
참고
library/redis - Docker Hub
Redis Persistence Introduction
Docker container networking
30 Aug 2017
|
tomcat
cookie
rfc6265
troubleshooting
증상
여러 서브도메인에서 쿠키를 공유하기 위해 .xxxx.com 같이 쿠키 도메인을 설정하는 케이스가 있습니다.
// sub domain list : sub1.xxxx.com, sub2.xxxx.com, sub3.xxxx.com
cookie.setDomain(".xxxx.com");
위와 같이 사용시 Tomcat 8버전 이상 사용할 경우 아래와 같은 에러를 만나게 됩니다.
java.lang.IllegalArgumentException: An invalid domain [.xxxx.com] was specified for this cookie
원인
tomcat 8버전 이상에서는 Cookie Header를 파싱하는 기본 CookieProcessor가 RFC6265를 기반으로 합니다. (org.apache.tomcat.util.http.Rfc6265CookieProcessor)
RFC6265의 속성중 하나는 아래와 같은데
5.2.3. The Domain Attribute
If the attribute-name case-insensitively matches the string "Domain",
the user agent MUST process the cookie-av as follows.
If the attribute-value is empty, the behavior is undefined. However,
the user agent SHOULD ignore the cookie-av entirely.
If the first character of the attribute-value string is %x2E ("."):
Let cookie-domain be the attribute-value without the leading %x2E
(".") character.
Otherwise:
Let cookie-domain be the entire attribute-value.
Convert the cookie-domain to lower case.
Append an attribute to the cookie-attribute-list with an attribute-
name of Domain and an attribute-value of cookie-domain.
Domain값 맨 앞자리에 “.”을 붙일 경우 “.”을 제거하고 파싱하게 됩니다.
해결
위와 같은 현상을 막기 위해 org.apache.tomcat.util.http.LegacyCookieProcessor 클래스를 제공합니다.
위 클래스는 RFC6265, RFC2109, RFC2616 기반으로 파싱하며 쿠키 작업의 에약을 여러 옵션을 통해 풀 수 있도록 제공하는데
Tomcat 서버 사용시 context.xml에 아래와 같이 추가해주면 됩니다.
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor"/>
만약 SpringBoot에서 Embedded Tomcat을 사용하고 있다면 아래와 같이 설정 할 수 있습니다.
@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
return container -> {
if (container instanceof TomcatEmbeddedServletContainerFactory) {
TomcatEmbeddedServletContainerFactory tomcat = (TomcatEmbeddedServletContainerFactory) container;
tomcat.addContextCustomizers(context -> context.setCookieProcessor(new LegacyCookieProcessor()));
}
};
}
참고
Apache Tomcat 8 Configuration Reference - The Cookie Processor Component
RFC 6265 - HTTP State Management Mechanism - IETF Tools
RFC 2109 - HTTP State Management Mechanism - IETF Tools
java.lang.IllegalArgumentException: An invalid domain .test.com was specified for this cookie
25 Aug 2017
|
springboot
deploy
gradle
troubleshooting
로컬환경에서 gradle bootRun을 통해 멀쩡하게 돌아가던 서버가 Tomcat WAS에 올렸더니 별다른 ERROR Log도 없이 모든 페이지가 404로 떴습니다.
혹시나 싶어 deploy path에 html파일 하나 만들어놓고 접근해보니 멀쩡하게 페이지가 나오더군요.
멘붕에 빠져 이것저것 건드리다가 신규 Tomcat버전의 문제인가, 신규 SpringBoot버전의 문제인가까지 찾던 도중 catalina log에서 아래와 같은 특이한 메시지를 찾았습니다.
Info : No Spring WebApplicationInitializer types detected on classpath
(이런 중요한 정보가 INFO라니…)
WAS가 SpringBoot의 WAR파일을 인식하긴 했지만 WebApplicationInitializer를 찾지 못한 것이였는데
원인을 찾으려 또 별의 별 삽질을 하며 직접 main-class도 지정하고 구글링하니 Java Version 체크해보라고도 하고
거의 반나절을 헤메다가 원인을 찾았습니다.
SpringBoot Devtools을 사용하기 위해 dependencies에 걸어 두었는데 외부 WAS에 배포할때는 해당 설정을 다 빼고 배포하면 참조 안하겠다 싶어 providedCompile로 설정하고 application.yml에서 관련 설정을 빼고 배포했으나 이게 WAR로 배포되면서 오류를 발생시켰던 모양입니다.
해당 설정만 compile로 변경하였더니 잘 동작합니다.
// build.gradle
dependencies {
providedCompile("org.springframework.boot:spring-boot-devtools") // ( X )
compile("org.springframework.boot:spring-boot-devtools") // ( O )
}
외부 WAS에서 오류 없이 SpringBoot Container가 올라오지 않는다면 provided로 설정한 값 중 문제가 있는건 없는지 확인부터 해 보면 좋습니다.
22 Aug 2017
|
instanceof
class
간단하게 instanceof는 특정 Object가 어떤 클래스/인터페이스를 상속/구현했는지를 체크하며
Class.isAssignableFrom()은 특정 Class가 어떤 클래스/인터페이스를 상속/구현했는지 체크합니다.
// instanceof
MacPro obj = new MacPro();
if (obj instanceof Computer) {
...
}
// Class.isAssignableFrom()
if (Computer.class.isAssignableFrom(MacPro.class)) {
...
}
참고
instanceof랑 Class.isAssignableFrom(…)의 차이가 뭐죠?
18 Aug 2017
|
windows
HP 윈탭을 하나 구입했는데 테블릿이다 보니 OS가 먹는 자원을 빼면 CPU/RAM이 얼마 없습니다.
근데 그 와중에 CPU와 RAM을 쓸데없이 많이 잡아먹고 있는 녀석이 있었으니 그것은 MS에서 심어놓은 Windows Defender.
탭을 켜고 아무것도 안하고 있는데도 항상 CPU와 RAM이 거의 100%를 먹고 있어 브라우저 켜는것만으로도 버벅이고 있었습니다.
그래서 제거 하려 했더니 일반 노트북에서는 있는 Windows Defender 끄기 설정이 없어 레지스트리에서 직접 내려보기로 했습니다.
(아마 HP에서 OS심을때 설정화면을 없애버린게 아닌가 싶습니다.)
제거방법
실행창(윈도우+R)을 열어 “regedit”를 입력합니다.
레지스트리 편집창이 나오는데 아래와 같이 경로를 찾습니다.
- HKEY_LOCAL_MACHINE > SOFTWARE > Policies > Microsoft > Windows Defender

폴더를 우클릭하여 “새로만들기”를 누르고 DWORD형식의 레지스트리를 만듭니다.
이름 : DisableAntiSpyware
값 : 1
위와 같이 설정하고 재부팅하면 작업관리자 프로세스에서 Antimalware Service Executable이 사라진걸 볼 수 있습니다.
참고
Antimalware Service Executable 삭제 끄기