좀 더 의식적으로 배우고 성장 하고 싶어서, 남들 하는 TIL를 따라 해 봄. 분명 생각 정리하는 데 도움이 됨. 더불어, 오늘 내가 배운 건 뭐가 있는지, 혹시나 기계적 반복을 하는 건 아닌지 의식하게 됨. 하지만 매일 하는 건 참 쉽지 않음.

08/29

NewRelic Custom Instrumentation

  • NewRelic이 지원하는 프레임워크가 아닌 경우에는 Custom Instrumentation이 필요함.
  • 사용중인 프레임워크는 Spring Zuul 이었으며, 이 때 ZuulProperties가 코딩량 줄이기에 도움이 됨.
  • 프레임워크 내부 코드 열어보는 것은 거의 매번 도움이 됨.

AWS Elastic Beanstalk Leader Instance

  • EB 인스턴스 leader 종종 실종. AutoScalingGroup에서 termination policy가 OldestInstance이기 때문임.
  • 운영 환경의 특성상 NewestInstance로 바꾸면 해결됨.

08/30

AWS Beanstalk Auto Scaling Trigger Setting

AWS RDS Configuration

  • RDS의 높은 CPU Utilization의 원인을 추정함. 실험 후 결과 궁금.
  • RDS 설정(slow_query_log, long_query_time, log_output option) 이해. 좀 더 나은 모니터링을 위해 설정 변경 예정. 궁금함.
  • SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 300;

Java 8 Optional map Performance

  • forEach가 특정 경우에 performance 저하(상황에 따라 유의미하기도 함)를 가져왔던 것과 다르게, Optional의 map은 유의미한 차이를 가져오지는 않음. 코드 배포함. 덕분에 간결하고 읽기 쉬움. (나만?)

09/02

Trivial Java Tip

  • selection을 통해 median을 찾는 알고리즘 작성하다가 실수한 것들.
  • int ary = new int[3];을 하면 ary의 원소들은 0으로 채워짐.
  • new Random().nextInt()은 음수가 반환될 수 있음.
  • new Random().nextInt(bound)로 하면, 0~bound 사이의 값을 반환해 줌. 그래서인지 0 이하를 지정하는 경우 예외를 던지는 코드가 내부에 존재함.

09/04

TDD & PP

  • TC를 얼마나 작성해야 하느냐? 사례가 일반화 된 수 만큼. FizzBuzz의 경우는 8개 정도. 그런 면에서, TDD가 도움이 됨.
  • FizzBuzz 구현을 TDD로 아주 세밀한 단계까지 나누어 수행. 이 정도까지 나눌 필요는 없지만, 이 정도까지 나눌 수 있다는 게 중요해 보임. 문제의 난이도에 따라 도움이 됨. Baby Step 이라고도 부름. 라이브 코딩 면접 시 안정감을 주기도 함.
  • 요구사항이 추가되거나 수정되는 것은 별로 문제가 되지 않음. 이보다는 인터페이스가 바뀌는 경우가 어려움. 예컨대, 문자열이 아닌 다른 자료구조를 반환해야 한다면, TC에서 전체를 바꿔야 함. 한 가지 해결책은 헬퍼 메소드. 의존 라이브러리를 래퍼wrapper 객체를 두어 사용하는 느낌. 결국은 의존성을 한 곳으로 모는 것.
  • TDD & PP를 하면서 코드를 연구한다는 느낌을 받음. 중요 부분에는 TDD & PP를 고려.

09/05

Spring Boot Externalized Configuration

AWS Beanstalk Deploy

  • Failed to deploy application. 외에 별다른 메시지도 없이 deploy 실패함.
  • /var/log/ 파일들에 특별히 남겨지는 로그도 없음.
  • 이전에는 Rebuild Environment를 했었음. 만약, Live 장비라면?
  • Auto Scaling Group에서 특정 EC Instance를 제거함과 동시에 투입하는 방법을 사용.

AWS Beanstalk Auto Scaling Group Termination Policy

ETC

  • BFF 용도로 사용하고 있는 API Gateway의 Aggregate 필요성에 대해 다시 한번 고민하게 됨. 조심.
  • 스프링 부트가 개발자를 바보로 만든다는 비판. 하지만 잘 사용한다면 좋은 측면이 더 많음. 오히려 실수도 줄여주고, 부가적 기능도 설정만으로 간단하게 추가하는 등. Back to the Basic이라는 말은 남용되면 안됨.

09/05

Zuul Service

  • Zuul 인증 라우팅에 커넥션 타임아웃을 늘리자는 고민을 같이 하다보니,
  • Zuul에 명시하는 의존 서비스는 논리적 단위.
  • 반드시 물리적 서버(하나의 인스턴스 혹은 인스턴스 그룹)에 대응할 필요 없음.
  • 같은 물리적 서버로의 라우팅이지만, 독립적인 정책을 가져가야 한다면, 서비스를 구분.

ETC

  • 단순화. Queue를 사용하지 않고, 동기적 호출에서 발생할 수 있는 문제를 극복하는 것을 봄. 이런 저런 생각을 하게 됨.

09/13

Ribbon (Client Side Load Balancer)

  • Discovery를 사용하지 않는다면, @LoadBalanced 보다 LoadBalancerClient를 더 선호. 더 명시적이고, 단순함의 수준은 비슷.
  • AbstractRibbonCommandHystrixCommandHystrixCommandGroupKey 값으로 “RibbonCommand”를 명시.
  • 결국, Ribbon을 통한 Hystrix는 기본적으로 격리 X. 반대로, 스레드 풀 등을 공유해서 사용.
  • 한편, Ribbon에서의 HystrixCommandKey는 의존 서비스 아이디를 값으로 함.
  • 그룹과 커맨드의 단위가 이게 좋은가에 대해서는 의문.

Java

Non-Blocking, Asynchronous

09/14

Git Merge Commit Revert

  • git revert-n(--no-commit): revert 시 자동 수행되는 commit을 하지 않음.
  • git revert-m(--mainline): merge commit revert 시 mainline을 지정함.
  • Revert of Revert (참고: Undoing Merges)

Back to the Basic

  • 문제 생겼을 때 빠르게 확인할 수 있는 TC 혹은 replay의 필요성에 대해 다시 한번 절실히 느낌.
  • 얽히고 섥혀 있는 시스템을 보며, 기본적인 OCP도 지키지 못하는 시스템의 고달픔을 다시 한번 절실히 느낌.
  • getXXX류의 함수를 열었는데, 내부에서 몰래 값을 할당하고 있는 시스템에 당혹감을 느끼며, SCP가 이렇게 중요하구나를 또다시 체감함.

09/15

Hystrix Thread Timeout

  • 다수의 Hystrix 비동기/병렬 호출 시, 별도의 스레드를 사용하는데, 분리된 스레드에서의 타임아웃은?
  • Hystrix에 의해 감싸진 녀석이 InteruptedException을 해석하지 않으면 멈추지 않음.
  • 출처: https://github.com/Netflix/Hystrix/wiki/How-it-Works#6-hystrixobservablecommandconstruct-or-hystrixcommandrun

Please note that there’s no way to force the latent thread to stop work - the best Hystrix can do on the JVM is to throw it an InterruptedException. If the work wrapped by Hystrix does not respect InterruptedExceptions, the thread in the Hystrix thread pool will continue its work, though the client already received a TimeoutException. This behavior can saturate the Hystrix thread pool, though the load is ‘correctly shed’. Most Java HTTP client libraries do not interpret InterruptedExceptions. So make sure to correctly configure connection and read/write timeouts on the HTTP clients.

RestTemplate

  • RestTemplate의 기본 타임아웃은 무려 0(무한).
  • setErrorHandler, setInterceptor 등의 인터페이스가 존재함.
  • HttpComponentsClientHttpRequestFactory를 통해 Pooling, Timeout 등의 설정 가능
  • 호스트 별로 여러개의 RestTemplate 인스턴스를 두어 사용할수도.

09/25

Endpoint Version Design

  • 서비스 엔드포인트의 versioning은 불변 서비스immutable service의 의미
  • 서비스 내의 단위 기능 수준보다, 서비스 수준에서 버전을 적용하는 것이 언제나 더 간단하다는 이야기에 여러 가지 생각.

Planning & Analisys

  • 하루 종일 플래닝, 설계를 진행. 이것 저것 따져가며 리스크를 찾아내는데, 자꾸만 조금만 더, 조금만 더, 하는 욕구가 생겨남.
  • 집에 오는 길에 읽고 있던 <호모데우스, 유발하라리> 내용 중 아래 문구가 눈에 들어옴.

당신이 추구하는 어떤 이상이 애초에 결함을 품고 있다면, 대게 그 이상의 실현 단계에 와서야 그러한 결함을 알게 된다.

Run TIL like a Machine

  • 성장하기 위해, 단순히 어떤 일을 반복하기보다는 의도적 수련deliberate practice이 필요.
  • (매일 같이 하지는 못하지만, 그리고 이제 막 시작했지만) TIL는 스스로 얼마나 나아가는지를 돌아보는 피드백이 됨.
  • 아래는 이와 관련하여 떠오른 Management Priciples, Ray Dailo의 그림과 내용 일부.

1) understanding how well your people and designs are operating to achieve your goals, and 2) constantly improving them.

improvement-machine

09/26

API Endpoint Design

09/27

Code Smell (Vulnerability)

  • 아래 코드는 여러 가지 문제점을 가짐.
  • 그 중의 한 가지는, 주로 값객체로 사용되는 mutable 객체를 그대로 반환한다는 것.
@Data
public class Hello {
  private Date date;
}

Gradle FindBugs

09/28

try-with-resource

final FileOutputStream outputStream = new FileOutputStream(file);
try {
    workbook.write(outputStream);
} finally {
    outputStream.close();
}
try (FileOutputStream outputStream = new FileOutputStream(file)) {
    workbook.write(outputStream);
}

10/05

Maven BOM

10/06

Spring Context

  • @Lazy라는 녀석이 존재함. 얼마나 유용할지는 모르겠음.

Gradle Multi Module Project

10/12

Spring ObjectProvider

Spring Database Popluation

Meta-Annotation Support for Testing

  • 중복된 테스팅 환경 설정 선언들을, 커스텀 애노테이션을 생성하여 재사용 할 수 있음.
  • 반드시 인과관계가 있는 것도 아니고 부산물이긴 하지만, 테스트 컨텍스트 캐시에도 유리해 보임.
  • 내용은 여기를 참고.

10/15

Complex Number

  • 켤레 복소수, 복소수의 절대값, 복소평면(가우스 평면)의 개념.
  • 복소수의 극형식(극좌표 표시) z = r(cosθ + i·sinθ)
  • 편각 θ = arg(z)
  • 복소수의 곱과 나눗셈. 극형식과 삼각함수의 덧셈정리를 활용.
  • 예컨대, i의 극형식은 cos(\frac{\pi}{2}) + i \cdot sin(\frac{\pi}{2})이므로,
  • ‘복소수 z에 i를 곱한다’는 것은 90˚ 회전시킨다는 것과 같음.
  • 드무아브르의 공식은 수학적 귀납법을 이용.
  • 이 때, cos2θ = cos^2θ - sin^2θsin2θ = 2sinθcosθ 성질을 이용함.

10/22

Java Set Interface Bulk Operations

  • Set Interface를 살펴보니, 교집합, 부분집합, 합집합, 여집합에 대한 처리가 잘 되어 있음.
  • Oracle Tutorior에서도 이들이 집합 대수set-algebraic 연산을 잘 수행한다고 명시되어 있음.
  • 처음에 사용하려 했던 비트 연산보다, 여러모로 좋은 선택으로 보임.
Set-algebraic Operation Set Interface
subset containsAll
union addAll
intersection retainAll
complement removeAll
cartesian product 없는 것 같다.

Java HTTP Connection Close

  • HTTP 응답을 처리하는 데 있어, close가 명시적으로 필요할 수 있음.
  • 예컨대, Ribbon RestClient의 618라인에서는,
  • 결국 아래의 Jersey WebResource 코드를 호출하게 되는데,
  • 이 때 class type이 ClientResponse이므로 close되지 않고 그대로 반환됨.
private <T> T handle(Class<T> c, ClientRequest ro) throws UniformInterfaceException, ClientHandlerException {
    setProperties(ro);
    ClientResponse r = getHeadHandler().handle(ro);
    if (c == ClientResponse.class) return c.cast(r);
    if (r.getStatus() < 300) return r.getEntity(c);
    throw new UniformInterfaceException(r,
            ro.getPropertyAsFeature(ClientConfig.PROPERTY_BUFFER_RESPONSE_ENTITY_ON_EXCEPTION, true));
}
  • 참고로, 위 코드에서 r.getEntity(c) 내부에서는 알아서 close가 호출됨.
  • Jersey의 ClientResponse 코드를 보다보면, Closeable 녀석들은 close가 필요하다고 함.
  • 다른 문서나 코드에서도 비슷한 내용들을 찾을 수 있음.
If the entity is not an instance of Closeable then this response
* is closed (you cannot read it more than once, any subsequent
* call will produce {@link ClientHandlerException}).

10/31

TIL인데, 1주일 간격으로 작성 중. 반성.

Collecting Parameter

  • 함수 파라미터로 객체를 넘겨주고, 함수는 이 객체에게 질의도 하고 값 설정도 하게 만듦.
  • 효율성을 이유로 이렇게 만들었으나, 아무래도 다른 사람이 보기에 좀 더 쉽게 작성할 수는 없을지 고민하게 됨.
  • 마침 “Move accumulation to Collecting Parameter“가 생각남.
  • 리팩토링 책에 나왔던 것 같음. 출처는 확인 필요.
  • 옆 동료와 한참을 이야기 함. 그리고 파라미터로 넘어온 객체의 상태를 바꾸는 것을 허용하기로 함.
  • 참고로 여기서는 이것이 일반적으로는 안티 패턴이라고 소개함.

A variation on this pattern occurs when the CollectingParameter is not a collection, but is an object with various properties. As the object is passed around, various actors get and set properties on the ParameterObject. I think this version of the pattern is generally an AntiPattern, but may be useful when refactoring from the use of globals.

The Expert Beginner

novice-to-expert

11/01

Java Access Modifier

Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
  • 출처는 오라클의 Controlling Access to Members of a Class 문서.
  • default 접근자를 진짜 많이 사용하는데, 참 모르고 (혹은 까먹고) 쓰고 있었구나를 느낌.
  • protecetdno modifier보다 더 개방적.

Java NavigableMap

API Endpoint Versioning

  • 1개의 서비스에서 20개의 API 엔드포인트를 제공한다고 가정.
  • 이 엔드포인트들은 여러 서비스에서 사용됨.
  • 그런데, 특정 엔드포인트가 변경되야 한다고 하자.
  • 이 엔드포인트의 버전만 올려야 할까, 아니면 전체 엔드포인트의 버전을 함께 올려야 할까?
  • 혹은, 얼마만큼의 변경이 있을때 버전을 올리는가?
  • 그러니까, 버전이 뭔가? 왜 하는가?
  • 많은 접근법들이 있구나 알게 됨.

API GW, Shared Client Library

  • Mastering Chaos, A Netflix Guide to Microservices
  • 위 영상의 20분 즈음에는 GW가 또 다른 레거시가 되는 이야기가 나옴.
  • 물론, GW 자체의 문제라기보다 공유 라이브러리에 의한 것. 재미있음.
  • 여러 서비스 간의 공유 라이브러리에 대한 실제 문제 사례가 이런저런 생각을 하게 만듦.