2019년 7월 29일 월요일

DI와 스프링

DI는 외부 인스턴스 혹은 특정 container가 두 object 간의 종속성을 (대신) 주입해주어 서로에 대한 종속성을 낮추게 해준다. DI를 사용함으로써 어떤 클래스가 특정 클래스에 의존성을 갖을 때 구체적인 구현에 대해 모르게 할 수 있다. (구현에 대해 갖는 종속성을 제거.) 이렇게 하면 모듈화에도 좋고, DI를 적용하지 않았을 때보다 독립적인 단위 테스트를 하기 쉬워진다. 독립적인 단위 테스트를 하기 쉬워진다는 말은 결합도(coupling)가 낮아지는 것을 의미한다. 알다시피 낮은 결합도(=모듈의 높은 응집도)는 좋은 소프트웨어 설계의 목표 지점 중 하나다.

DI가 구현에 대한 의존성을 제거하는 유일한 방법은 아니다. 이 작업을 수행하는 데 사용할 수 있는 또 다른 패턴으로 Service Locator가 있다. Service Locator 패턴을 따르는 경우엔 애플리케이션이 service locator에게 필요한 서비스를 메시지로 직접 요청하는 형태를 띄게 된다. 반면 DI의 경우엔 명시적인 요청 없이 서비스가 주입된다. 이런 형태를 일반적으로 'Inversion of Control' 이라 한다.

아래는 마틴 파울러가 15년전 작성한 글인데 정말 좋다.
https://martinfowler.com/articles/injection.html

DI 구현방식

DI엔 constructor injection, setter injection, field injection의 세가지 방식이 있다. 그리고 이 중에선 일반적으로 constructor injection 방식이 가장 권장된다. Constructor injection 방식을 쓰면 생성자만 보고도 의존 관계와 복잡성을 쉽게 알 수 있게 되기 때문에 작성하는 코드가 올바른 방향으로 가고 있는지 알 수 있게 된다. 그리고 final 키워드를 이용해 객체의 상태를 변하지 않게 만들 수 있다. 이는 setter, field injection 방식에서는 가질 수 없는 형태다.
일반적으로 객체를 생성할 땐 가능하면 하나의 방식을 갖는 것이 좋고, 의존 관계가 있다면 setter method 보다 매개 변수가 있는 생성자를 통해 드러내는 것이 좋다고 알려져 있다. (객체를 구성하는 방법이 여러개라면 Factory Methods를 쓰고..) 이와 비슷한 맥락에서 DI도 constructor injection 방식을 권장하는게 아닌가 한다.

반대로 setter injection의 경우엔 특정 의존 관계를 인스턴스의 생성 시점과 구분해서 지정하거나 또는 지정하지 않거나, 교체할 수 있는 형식을 가질 수 있기 때문에 setter injection 방식도 쓰임새가 있다.

[코드 예시: https://multifrontgarden.tistory.com/214]


DI와 스프링

잘 알려진 DI 구현체를 꼽으면 스프링을 예로 들 수 있다. 스프링에선 스프링 DI 컨테이너가 관리하는 객체를 빈(bean)이라고 표현한다. 여기서 빈이 특별한 개발 사양을 갖는 것은 아니고 빈은 단지 스프링 컨테이너에 의해 관리를 받는다는 의미로 쓰인다. 그리고 스프링 컨테이너는 이 빈들을 관리한다는 의미로 빈 팩토리(bean factory)라 불린다. 빈 팩토리는 단어 그대로(factory=공장) 빈을 생성(instantiating)하고, 설정(configuring)하고, 관계를 갖는 빈들을 묶어주는(assembling) 역할을 맡는다. 여기에 비즈니스 애플리케이션을 지원하는데 필요한 기능 몇가지가 추가되면 바로 그(?) ApplicationContext가 된다.

TCP 제어 플래그 (Control Flag)

TCP 통신에서 TCP 헤더의 컨트롤 플래그는 연결 상태를 나타내는데 쓰인다. 이 값에 대해 잘 알고 있으면 관련된 문제 발생시 꽤나 도움이 된다. 플래그에는 SYN, ACK, FIN, RST, PSH, URG 가 있다. 각 플래그는 1비트씩 소비한다.



  • Synchronization (SYN) : 두 호스트 간 연결을 맺기 위한 3-way handshake 프로세스의 첫 번째 단계에서 쓰인다.
  • Acknowledgement (ACK) : 상대방으로부터 패킷을 받았다는 것을 알려주는데 쓰인다. SYN 세그먼트 전송 이후(TCP 연결 시작 후) 모든 세그먼트에는 항상 이 비트가 1로 셋팅된다. 1로 셋팅되면 'Acknowledgement number' 필드에 유효한 값이 적혀있다는 의미를 갖는다.
  • Finish (FIN) : 커넥션 종료 요청으로 더 이상 보낼 데이터가 없을 시에 sender가 마지막 패킷으로 보내게 된다. 정상적인 종료에 해당하므로 데이터 유실은 없고, receiver가 꼭 연결을 끊어야 할 의무는 없다. 연결을 종료하고 싶다는 뜻을 상대에게 보내기 위한 플래그다.
  • Reset (RST) : TCP 연결에 문제가 있다고 판단될 때 연결을 종료하는데 쓰인다. 정상적인 연결과 종료를 할 수 없는 경우에도 사용된다. 비정상적인 중단으로 데이터 유실이 생길 수 있고, 양쪽 모두에 영향을 준다. RST는 반-개방 또는 연결 문제 등의 상황 처리를 위한 초기화용 제어 비트다.
  • PUSH (PSH) : 전송 계층은 일반적으로 네트워크의 효율을 위해 충분한 양의 데이터가 모인 다음에 데이터를 전달한다. 그러나 이러한 장치는 채팅과 같이 빠른 응답을 필요로 하는 경우엔 적합하지 않을 수 있다. PSH 플래그를 1로 설정하면 세그먼트는 버퍼링되지 않고 즉각 전송된다. 수신측도 PSH 플래그가 1로 설정된 세그먼트는 바로바로 애플리케이션 계층으로 전달한다. (in-sequence)
  • Urgent (URG) : 긴급성을 갖는 데이터로 간주되어 URG가 1로 세팅된 세그먼트는 전송 큐의 제일 앞으로 보내지게 된다. (out-of-sequence)
https://www.geeksforgeeks.org/computer-network-tcp-flags/

2019년 7월 28일 일요일

JMX란

JMX = Java Management Extensions.

JMX는 JDK 1.5부터 포함된 사양이라 한다. JMX는 실행 중인 애플리케이션의 상태를 모니터링 하고, 설정을 변경할 수 있게 해주는 API라고 이해하면 될 듯 하다. 이해하기 쉬운 단순한 규격을 가지고 있어서 어렵지 않게 런타임 상태의 애플리케이션을 관리할 수 있다.

외부에선 JMX Connectors로 MBean 서버에 접근하면 되지만 JConsole과 같은 미리 구현된 모니터링 도구가 있기 때문에 직접 모든 것을 만들 필요는 없다.

JMX를 통해 리소스 관리를 하려면 MBeans라는 Managed Beans를 생성해야 하고, 생성한 MBean을 MBean Server에 등록해야 한다. MBean 서버는 등록된 MBeans를 관리하는 agent 역할을 수행하게 된다. 당연히 MBean 서버는 구현한 애플리케이션 내부에서 띄운다.

MBean을 구현하는덴 룰이 있는데 interface와 구현체를 쌍으로 만들어야 하고 MBean interface의 이름은 'MBean'으로 끝나야 한다. 노출하는 변수를 모니터링만 할 것이라면 setter는 생략해도 된다.

다음은 예제 코드.
public interface MonitoringBean {
    long getStorageSize();
}

public class Monitoring implements MonitoringBean {
    @Override
    public long getStorageCount() {
        return ...;
    }
}

// boot up MBean server
Monitoring monitoring = new Monitoring();

// 팩토리 클래스로 부터 MBeanServer 인스턴스를 생성한다.
MBeanServer server = ManagementFactory.getPlatformMBeanServer();

// ObjectName은 domain, key의 구성을 갖는다.
// domain은 이름 충돌이 발생하지 않도록 자바 패키지 이름을 쓰는 것이 관례.
// key는 key=value 쌍을 콤마로 구분해 여러 개를 지정할 수 있다.
ObjectName jmxObjectName = new ObjectName("com.okminseok.example:type=basic,name=mymon");
server.registerMBean(monitoring, jmxObjectName);

! 소스 참고: https://github.com/eugenp/tutorials/blob/master/core-java-modules/core-java-perf/src/main/java/com/baeldung/jmx/JMXTutorialMainlauncher.java

! 애플리케이션의 실행 파라미터.
-Dcom.sun.management.jmxremote.port = 8686 // 8686이 기본 포트.
-Dcom.sun.management.jmxremote.ssl = false // 설정 편의를 위한 ssl off
-Dcom.sun.management.jmxremote.authenticate = false // 설정 편의를 위한 인증 off
=> https://www.ibm.com/support/knowledgecenter/ko/SSHS8R_8.0.0/com.ibm.worklight.installconfig.doc/install_config/t_optional_config_app_server_tomcat.html


2019년 7월 25일 목요일

npm 기본 사용법

Node Package Manager, npm의 사용법을 간단히 정리해보았다.

자주 쓰게되는 명령들


# npm init: package.json 파일을 만들어 준다. package.json은 프로젝트가 참조하는 의존 라이브러리의 버전 정보를 기록해두는 파일이다. JavaScript 생태계에서 Java의 maven, gradle과 같은 역할을 하는 파일이다.
npm init

# npm install/uninstall: 패키지 설치와 삭제. -g 옵션을 붙이면 사용하는 PC 환경 전체에 영향을 준다. 붙이지 않으면 명령을 날린 하위 폴더에 적용된다.
npm install 모듈
npm uninstall 모듈

# 배포 시 참조하게 되는 라이브러리 정보를 package.json에 추가한다. (dependencies에 추가)
npm install 모듈 --save

# 개발 단계에서만 참조하는 라이브러리 정보를 package.json에 추가한다. (devdependencies에 추가)
npm install 모듈 --save-dev

# npm이 npm을 업데이트 해준다.
npm install -g npm

# npm ls: 설치된 패키지 정보를 확인할 수 있다. -depth=0 옵션을 주면 참조의 참조 패키지는 제외하고 표시해준다. -g 옵션은 이전과 동일한 의미.
npm ls
npm ls -g
npm ls -depth=0

# npm cache: clean 명령은 캐쉬 폴더를 비운다. verify는 캐쉬 폴더에서 필요하지 않은 정보를 날리거나 캐쉬 데이터가 올바른지 확인하는 명령이다.
npm cache clean [<path>]
npm cache verify

! package-lock.json


npm 특정 버전부터 package-lock.json이라는 파일이 추가로 생성된다. package-lock.json 파일은 pakcage.json 파일이 업데이트 되는 시점에 참조하는 모듈들의 자세한 의존성 트리 정보(참조의 참조, 참조의 참조의 참조~ 모듈의 버전 정보)를 기록해두기 위한 장치다. package.json 보다 더 정확한 정보를 담고 있기 때문에 특정 개발자와 협업하는 경우 미세한 버전 틀어짐 없이 정확히 같은 버전을 바라보며 개발을 할 수 있다.


! 버전 표기시 ^(캐럿)과 ~(틸드).


캐럿은 참조 모듈들이 메이저, 마이너, 패치의 SemVer 규약을 잘 따르고 있다고 가정하고 모듈의 버전을 하위 호환성이 보장되는 버전까지 올릴 수 있게 해준다. 반면에 틸드는 참조 모듈의 버전 업그레이드에 대해 비교적 보수적인 version range를 두고 접근한다. outsider님 블로그에 올라온 글을 읽으면 이해가 빠르다. (https://blog.outsider.ne.kr/1041)
~(틸드)
~0.0.1 : >=0.0.1 <0.1.0
~0.1.1 : >=0.1.1 <0.2.0
~0.1 : >=0.1.0 <0.2.0
~0 : >=0.0 <1.0
^(캐럿)
^1.0.2 : >=1.0.2 <2.0
^1.0 : >=1.0.0 <2.0
^1 : >=1.0.0 <2.0

2019년 7월 24일 수요일

Angular 히스토리

Angular History


상세

* 2010년: AngularJS의 탄생. Misko Hevery라는 사람이 Google에서 Side Project로 시작. 이후 몇몇의 동료 개발자가 참여하여 오픈 소스로 공개하였다. 하나의 코드 셋으로 웹과 모바일 환경에 바로 적용할 수 있었기 때문에 많은 호응을 받았다.

* 2014-2015년: 다시 쓰다. AngularJS가 호평을 받았지만 웹 환경은 변화했고, 더 나은 성능을 보여주는 경쟁 프레임워크가 등장하게 되었다. AngularJS는 벽에 부딪혔고, Google의 핵심 팀은 기존 AngularJS의 디자인에 얽매이지 않고 프레임워크를 다시 작성하게 되었다. 새로 만드는 Angular의 목표는 여전히 대규모, 크로스 플랫폼 애플리케이션을 구축할 때 생기는 어려운 문제점들을 해결하기 위한 것이다.
  • AngularJS vs Angular
  1. AngularJS는 기본적으로 양방향 데이터 바인딩(2-way data binding)을 채택하고 있는데 여기서 오는 성능 문제가 있었다. → Angular는 단방향 데이터 바인딩, 양방향 데이터 바인딩을 개발자가 선택할 수 있다.
  2. AngularJS의 컨트롤러, 스코프($scope) 개념은 컴포넌트와 Directive로 대체되었다.
  3. Angular는 TypeScript를 채택한다. RxJS 사용시 리액티브 프로그래밍을 지원한다.

* 2016년: 혼란스러운 시기. AngularJS 프로그램을 새로운 Angular로 이식하는 명확한 마이그레이션 전략은 없다. AngularJS 기반 프로젝트를 운영하는 개발자에겐 안좋은 소식이었다. → 우려와 다르게 AngularJS는 지금도 지원이 이루어지고 있다.

* 2017-2018년: 새로운 버전의 Angular가 자리를 잡은 시기. 기존의 AngularJS와 비교해서 더 나은 빌드 크기, 안정적인 API와 향상된 성능을 제공할 수 있게 되었다. React와 다르게 Angular는 대규모 응용 프로그램을 빌드할 때 필요한 모든 솔루션을 제공한다. React와 같은 라이브러리는 누락된 부분을 채우기 위해 다른 외부 프로젝트를 필요로 한다. Angular가 React보다 낫다는 말은 아니다.

[Django] Cookie

오랜만에 장고..

Django에서 조건에 따라 컨텐츠를 일부 바꿔야 하는 일이 생겼다. 그리고 조건에 의해 한번 정해진 값은 애플리케이션을 이용하는 동안 유지될 필요가 있었다. (참고로 사내에서만 사용하는 프로그램이라 동작이 우선인 상황.)

고민하지 않고 쿠키에 값을 실어 처리하기로 했다. 찾아보니 HttpRequest에는 딕셔너리 타입으로 COOKIES 속성이 제공되고, HttpResponse에는 set_cookie 메서드가 제공된다.

HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False, samesite=None)
 [link: https://docs.djangoproject.com/en/2.2/ref/request-response/]


쿠키를 세팅하는 방법은 그리 어렵지 않다. 호출되는 view 함수에서 render의 반환 값을 바로 리턴하지 않고 값을 지정해주면 된다. 그리고 페이지에 처음 진입할 때에도 화면을 올바르게 렌더링 해야하기 때문에 render()를 호출하기 전에 request 객체에 쿠키 값을 지정해 주었다.
request.COOKIES['app_type'] = 'v1'
response = render(request, 'template.html', context)
response.set_cookie(key='app_type', value='v1')
return response

템플릿에선 request의 COOKIES 값을 읽어서 처리하면 된다.
{% if request.COOKIES.app_type and request.COOKIES.app == 'v1' %}
...

+ 마지막으로 나의 경우 쿠키 값을 읽어서 로그인, 로그아웃 이후의 리다이렉트를 고려해야 했는데 그냥 settings.py의 LOGIN_REDIRECT_URL에 별도의 view 함수를 정해주고, 해당 view 함수에서 쿠키 값을 읽어 분기되도록 하였다.

2019년 7월 17일 수요일

WPF의 DIU(Device-Independent Units)

WPF는 DIU(Device-Independent Units) 좌표 단위를 사용한다. DIU의 값은 1/96 Inch이고 WPF는 항상 1/96 Inch에 해당하는 값을 좌표 단위로 사용한다. 따라서 Width와 Height 값이 96인 WPF Rectangle은 프린터로 출력했을 때 가로 세로가 1 Inch 크기의 사각형으로 출력된다.

재미있는건 Microsoft Windows에서도 특별한 설정을 하지 않으면 기본 DPI 값은 96이라고 한다. DPI는 Dots per Inch의 약자로 1 Inch 당 점이 몇개 들어가지는지를 나타내는 단위이다. 기본 설정인 경우 WPF의 DIU 단위와 Windows의 DPI 단위가 같아서 1DIU = 1pixel 관계가 된다. 물론 Windows에서 DPI 설정을 바꿀 수 있다.

요약해 정리하면,
1. WPF는 1/96 Inch에 해당하는 값을 좌표 단위로 사용한다. 이를 장치 독립적 픽셀 값이라고 표현한다.
2. WPF의 DIU 값과 Windows의 기본 DPI 값이 같기 때문에 1 DIU는 1 pixel로 표시된다. 단, Windows의 DPI 설정이 바뀌면 1 DIU는 1보다 작거나 큰 pixel 값을 갖게 되어 화면이 번져 보이게 된다.

http://www.charlespetzold.com/blog/2005/11/250723.html
In WPF, you always draw in units of 96 DPI. For example, if you want to create a one-inch square Rectangle object, you make it 96 units wide and 96 units high. If the program runs on a video display set at 96 DPI, the object will be drawn 96 pixels square. In the most common case device-independent units map directly to pixels. If the program runs on a video display set at 120 DPI, the object will be drawn as 120 pixels square. That's a fairly clean 3 units-to-4 pixels mapping.

2019년 7월 14일 일요일

스트리트 패션 다큐멘터리 [PERCENTAGE%]


https://youtu.be/YFhuMiYS72E

돈주고 봐야할 수준의 다큐멘터리가 유투브에 아무론 조건 없이 공개됨.

김종선(JAYASS)님을 중심으로 하여 지난 10년의 한국 스트리트 패션 문화에 대해 다룬다.
사실 BA나 휴먼트리에 대해선 잘 모르지만 어렸을 적 이런 문화와 문화를 이끄는 인물에 대해선 막연한 동경심이 있었다.
밤 늦게 시청했음에도 한 번에 클리어.

2019년 7월 11일 목요일

대칭키 암호화, 비대칭키 암호화

암호화

1. 대칭키 암호화
→ 암호화하고 복호화 하는데 같은 키를 사용하는 방식.

대칭키 암호화 기법은 2개의 키를 사용하는 비대칭키 암호화 기법에 비해 간단한 반면 A와 B가 메시지를 주고 받기 전에 동일한 내용의 대칭키를 미리 알고 있어야 하는 문제가 있다. 이 대칭키는 쉽게 바꿀 수도 없고 사전에 공유하기 어려운 성질을 갖는다. A와 B가 대칭키 암호화 방식으로 데이터를 주고 받기 결정했다면 A 또는 B 중 한사람은 암호키를 만들어서 상대방에게 전달해야 한다. 그런데 전달 과정에서 누군가 이 암호키를 가로챈다면 그 누군가는 언제든 암호화된 메시지를 복호화 해서 내용을 확인할 수 있게 된다.


2. 비대칭키 암호화
→ 암호화하고 복호화 하는데 공개키/비밀키의 한 쌍을 사용하는 방식.

대칭키 암호화 기법에서 대칭키 교환의 문제를 해결하기 위해 고안된 기법이다. 비대칭키 암호화 기법은 공개키와 비밀키 한쌍의 암호화 키를 이용해 암복호화를 수행한다. 무슨 얘기인가 하면 공개키로 암호화된 메시지는 Pairing된 비밀키로만 복호화할 수 있고, 비밀키로 암호화된 메시지 또한 Pairing된 공개키로만 복호화할 수 있다는 말이다.
비대칭키 암호화 방식의 단점은 CPU 리소스를 대칭키 암호화 방식에 비해 많이 쓴다는 점이다. 따라서 일반적으론 비대칭키 암호화 방식을 이용해 대칭키를 서로 공유한 뒤에 이후의 암호화는 대칭키 방식을 사용한다.


3. 웹 암호화
SSL/TLS 기반의 웹 사이트에 접근하게될 때, 웹 서버는 공개키가 포함된 인증서를 사용자에게 보내주어 이 공개키를 이용해 암호화 하면 된다고 알려준다.  앞선 예와 유사한 이유로 수신한 공개키의 진위 여부를 가릴 필요가 있다.

만약 해커가 인증서와 인증서에 포함된 공개키를 조작해 전달한 것이라면 사용자의 암호화된 패킷을 자유롭게 열어볼 수 있을 것이다. SSL/TLS 기반의 통신을 지원하는 웹 서버는 웹 서버가 사용자에게 전달하는 공개키가 진짜라는 것을 보증받기 위해 신뢰할 수 있는 인증 기관 (Certificate Authority)에 공개키를 등록하게 된다.

인증서가 만들어지는 목적은 공개키의 무결성을 검증하기 위함이고, 신뢰할 수 있는 인증기관에 의해 보증된다. (*신뢰할 수 있는 인증 기관 목록은 이미 브라우저가 알고 있다.)

2019년 7월 8일 월요일

[SQL] WITH (NOLOCK)

http://www.sqler.com/bColumn/870643

SQL Server에서 잠금(LOCK)은 지극히(?) 정상적인 동작이다. 특정 데이터 영역에 INSERT나 UPDATE 작업이 일어나면 해당 영역엔 LOCK이 걸리게 된다. 데이터의 일관성을 유지하기 위한 것으로 동시에 이 영역을 참조하는 SELECT 작업은 LOCK이 해제될 때까지 대기해야 한다.

문제는 사용자 입장에서 불필요하다고 느낄 때가 있다는 것인데, 정말 단순한 데이터라 일관성은 뒤로하고 그저 빠르게 읽어오고 싶은 경우가 있기 때문이다.

이럴 때 잠금 힌트 중 NOLOCK을 사용한다. NOLOCK 힌트는 커밋되지 않은 트랜잭션이나 읽는 중 롤백된 데이터에 대한 조회를 가능하게 한다. 즉, 커밋되지 않은 읽기가 가능하므로 LOCK이 걸려있어도 대기하지 않고 데이터를 가져올 수 있다. (READUNCOMMITTED) 단, 다시 언급하지만 데이터의 일관성이 보장되진 않으므로 데이터 성격을 감안해서 써야 한다.

사용 방법은 FROM 절 뒤에 WITH (NOLOCK)을 붙여주면 된다.
ex) SELECT * FROM EMPLOYEE WITH (NOLOCK)

Apache Commons DBCP 설정

https://commons.apache.org/proper/commons-dbcp/configuration.html

  • initialSize (default: 0) : BasicDataSource 클래스 생성 후 최초로 getConnection()을 호출할 때 커넥션 풀에 채워지는 커넥션 개수
  • maxTotal (default: 8) : 동시에 사용할 수 있는 최대 커넥션 개수
  • maxIdle (default: 8) : 커넥션 풀에 반납할 때 유지될 수 있는 커넥션 개수
  • minIdle (default: 0) : 최소한으로 유지할 커넥션 개수
→ initialSize, maxTotal, maxIdle, minIdle은 동일한 값으로 통일해도 무방한데 실제로 성능에 영향을 주는 요소는 커넥션 개수를 몇개까지 쓸 것인가에 대한 것이기 때문이다. 풀의 최대 크기를 몇 개로 설정할 것인가가 관건이지 저 4개의 변수를 미세 조정하는 것은 별 의미가 없다. 그리고 일반적으론 maxTotal과 maxIdle 값은 같게 지정하는 것이 좋다. maxTotal 보다 maxIdle이 낮게 설정되면 일부 커넥션이 거의 즉시 닫혔다 열리는 현상을 볼 수 있다. 이런 현상은 비용 측면에서 낭비다.
# 초기엔 initialSize, maxIdle, minIdle 값을 maxTotal 대비 낮은 값을 지정해 적정 커넥션 수치를 모니터링한 뒤 값을 Fix하는 것이 권장된다.

  • maxWaitMills : 커넥션 풀 안의 커넥션이 고갈됐을 때 커넥션 반납을 대기하는 시간. 단위는 밀리초. 이 값이 너무 짧으면 불필요한 오류가 생기고 너무 크면 사용자가 과도하게 대기하는 증상이 발생해 좋지 않다. (10초(10000ms) 권장)
  • validationQuery : 커넥션 풀에서 연결의 유효성을 검사하는데 사용할 SQL 쿼리를 지정한다. 형식은 적어도 하나의 행을 반환하는 SQL SELECT 문이어야 한다.
     - Oracle : select 1 from dual
     - MS-SQL : select 1
     - MySQL : select 1
  • testOnBorrow (default: true) : 커넥션 풀에서 커넥션을 얻어올 때 테스트 실행
  • testOnReturn (default: false) : 커넥션 풀로 커넥션을 반환할 때 테스트 실행
  • testWhileIdle (default: false) : 유휴 객체 제거기(object evictor)에 의한 유효성 검증을 할 것인가에 대한 설정. validate에 실패하면 커넥션이 풀에서 삭제된다. testOnBorrow는 getConnection()을 호출할 때마다 테스트를 한다면 이 설정은 특정 주기로 여러 개의 커넥션을 모아서 테스트한다. (by object evictor thread.)
  • timeBetweenEvictionRunsMillis (default: -1) : object evictor 쓰레드 실행 간격. object evictor를 활성화 시키려면 양수 값을 갖어야 한다. Tomcat DBCP는 이 값을 5초 정도로 해도 괜찮지만 Commons DBCP에선 성능 저하의 위험이 있다. Commons DBCP에선 기본 설정이 아예 false인 것으로 봐도 짧은 시간을 지정하는건 무리가 있는듯. (30초 ~ 60초 권장)
  • numTestsPerEvictionRun (default: 3) : object evictor 쓰레드가 실행할 때마다 검사할 커넥션 개수. 검사 시간 동안 커넥션 풀에 락이 걸린다고 한다. 기본값 권장.
  • minEvictableIdleTimeMillis (default: 1000 * 60 * 30, 30분.) : 커넥션이 축출 대상이 되기 전에 커넥션 객체가 풀에서 유휴 상태로 있을 수 있는 최소 시간.
  • removeAbandoned (default: false) : 오랫동안 열려만 있고 close() 메서드가 호출되지 않는 커넥션을 임의로 닫는 기능을 설정. (removeAbandonedOnBorrow / removeAbandonedOnMaintenance)

2019년 7월 3일 수요일

Conquer and divide

In XP, We don't divide and conquer. We conquer and divide. First we make something that works, then we bust that up and and solve the little parts.
- Kent Beck.

애자일이나 TDD에 대한 가장 흔한 오해 중 하나는 그 방식들이 divide and conquer를 장려한다는 생각이다.
...
고객에게 가치를 전달하는 측면을 보자면 divide and conquer는 제대로 가치를 주지 못할 수 있습니다. 왜냐하면 experience를 주기보다 feature를 주기 때문입니다.
...
- 김창준님 페이스북