반응형

IT 18

Connection prematurely closed BEFORE response 에러 대응기

오늘 다룰 내용은 Reactor Netty HTTP Client에서 간헐적으로 발생했던 Connection prematurely closed BEFORE response 에러와 관련된 내용 입니다. 왜 이 에러가 발생하는지 원인을 추적하는 과정과 어떻게 대응 했는지에 대한 내용을 살펴 보려고 합니다. 문제의 발단 서비스 오픈 후 트래픽이 증가하면서 기존에는 발생하지 않던 새로운 종류의 에러가 발생하기 시작 했습니다. 바로 Connection prematurely closed BEFORE response 에러 였습니다. 에러 메세지만 봐도 응답을 받기 전에 커넥션이 끊어졌다는 메세지 였고, 이는 네트워크 문제가 발생했음을 알 수 있는 메세지 였습니다. 과연 원인이 무엇일까, 원인을 찾아내기 위해 tcpdu..

IT/DevOps 2022.02.21

VPC Flow logs는 네트워크 문제 분석에 활용할 수 있을까?

간헐적으로 발생하는 네트워크 이슈 만큼 원인을 추적하기 어려운 이슈는 아마 없을 겁니다. 모든 요청에 대해서 에러가 발생하는 것도 아니고 가끔씩 에러가 발생하면서 수집하는 메트릭에는 특별한 흔적도 남기지 않는 그런 이슈들. 요즘에는 eBPF 기반의 도구를 이용해 네트워크 문제를 분석하는 경우도 많지만 어떤 경우에는 tcpdump와 같은 전통적인 도구가 필요한 경우가 있습니다. 간헐적인 네트워크 이슈들은 전반적인 패킷의 흐름을 수집하고 분석하면서 어느 구간에서 언제 문제가 생기는지를 분석해야 할 필요가 있기 때문 입니다. 하지만 클라우드 환경에서는 tcpdump와 같은 도구를 이용해 패킷을 수집하기 쉽지 않습니다. 그래서 이번 글에서는 AWS에서 제공하는 VPC Flow logs를 네트워크 문제 분석에 어..

IT/DevOps 2022.02.10

docker run 과 docker exec 재현을 통해 컨테이너 이해하기

쿠버네티스 기반으로 전환할 때 가장 중요한 요소 중 하나가 컨테이너에 대한 이해입니다. 쿠버네티스라는 시스템이 컨테이너를 어느 노드에서 실행하게 할 것인가를 관리하는 오케스트레이션 시스템이기 때문에 그 근간이 되는 컨테이너에 대한 이해가 없다면 쿠버네티스 기반의 환경을 제대로 활용하기 어렵습니다. 그래서 이번 글에서는 컨테이너 런타임으로 가장 많이 사용되는 docker의 run과 exec 명령어를 리눅스 명령어들로 하나씩 재현해 봄으로써 컨테이너에 대한 이해를 돕고자 합니다. 이 글에서 다룬 방법은 제가 컨테이너에 대해 학습할 때 사용했던 방법이고 저도 꽤 많은 도움을 받았던 방법입니다. 그럼 시작해 보겠습니다. 컨테이너란 무엇일까요? 본격적인 이야기를 시작하기 전에 컨테이너란 무엇인지에 대해서 이야기해..

IT/DevOps 2022.01.25

Go 언어에서 YAML 파일을 구조체로 표현하기 위한 일곱가지 패턴

YAML 파일을 이용해서 환경 설정을 구조화하고 이를 바탕으로 유연하게 동작할 수 있도록 애플리케이션을 만드는 것은 많이 사용되는 패턴입니다. 저도 그런 패턴을 좋아해서 가급적 많은 것들을 YAML 파일로 설정할 수 있도록 하고 실제 애플리케이션 코드에서는 YAML 파일을 읽은 후 이터레이션을 돌거나 값을 참조하는 형태로 구현하고 있습니다. 그리고 이런 YAML 파일을 읽어서 구조체로 접근할 수 있다면 애플리케이션의 코드가 훨씬 가독성이 높아지게 됩니다. 하지만 YAML 파일을 이용한 설정들의 패턴이 워낙 다양하다 보니 필요할 때마다 구글에서 찾아보거나 하는 경우가 많습니다. 그래서 오늘은 제가 그동안 애플리케이션을 만들면서 만났던 다양한 YAML 파일들의 패턴을 살펴보고 이를 구조체로 표현하는 방법에 ..

IT/GoLang 2022.01.17

aws-node-termination-handler를 활용해서 EKS 워커 노드에 스팟 인스턴스 적용하기

AWS 기반의 인프라를 운영하는 곳에서 가장 많은 비용을 차지하는 것들 중 하나가 바로 EC2입니다. EC2 비용 최적화를 위한 작업은 보통 워크로드에 적합한 사양의 인스턴스를 사용하고, RI를 구매해서 온디멘드로 발생하는 비용을 줄이는 방식으로 진행하게 됩니다. 하지만 그 외에도 스팟 인스턴스를 도입하는 것도 EC2 비용을 줄일 수 있는 좋은 방법입니다. 하지만 스팟 인스턴스는 언제 종료될지 모른다는 단점을 가지고 있기 때문에 도입을 위해서는 자동화된 서비스 제외 환경이 구성되어야 합니다. 이에 대해서는 브런치를 통해서도 한 번 공유 하기도 했습니다. 오늘은 기존 글에서 조금 더 나아가 EKS에 스팟 인스턴스 도입을 하기 위해 고민했던 과정에 대해서 공유하려고 합니다. EKS 워커 노드에 스팟 인스턴스..

IT/DevOps 2021.12.09

Logstash의 Kafka Input 성능 개선 이야기

오늘은 Logstash의 Kafka Input 성능 개선과 관련된 이야기를 해보겠습니다. 어떤 문제가 있었고 어떻게 해결했는지 그 과정에 대해 살펴보겠습니다. 참고로 이 글에 있는 작업은 박병진 님의 작품 입니다. 저는 그저 사람들에게 알리기 위해 대신해서 글을 쓸 뿐입니다. ^^ 문제의 발단 일부 서비스를 오픈하고 트래픽을 처리하고 있던 중 아래와 같은 모습의 Kafka Lag 지표를 발견했습니다. 피크 시에는 3천을 육박할 정도로 높은 수준의 Lag이 감지되고 있었습니다. 초당 7백여개의 로그가 인입되고 있는 상황이었기 때문에 3천대의 Lag이라면 로그가 ES에 실리기까지 약 4~5초 정도 밀린다는 의미가 됩니다. 물론 4~5초 정도의 로그 적재 지연이 크리티컬 한 상황은 아니었지만, 좀 더 빠르고 ..

IT/DevOps 2021.10.28

Connection Timeout과 Read Timeout 살펴보기

오늘은 타임아웃 계의 양대 산맥 Connection Timeout과 Read Timeout에 대해 이야기 해 보려고 합니다. 두 타임아웃의 의미에 대해 살펴보며 적정한 값을 찾는 방법에 대해서 살펴 보겠습니다. Connection Timeout과 Read Timeout의 의미 먼저 Connection Timeout은 종단 간 연결하는데 소요되는 최대 시간을 의미 합니다. 이 시간을 넘기게 되면 연결 할 수 없는 것으로 판단하고 에러가 발생 합니다. Connection 이라는 단어가 의미하는 것처럼 종단 간 연결에 사용되는 타임아웃 입니다. 그리고 이 때의 연결이란 우리가 잘 알고 있는 TCP 3 way handshake를 통해 TCP 연결이 생성되는 것을 의미 합니다. Read Timeout은 연결된 종..

IT/DevOps 2021.10.07

세번째 글 - 패키지 만들기

애플리케이션이 해야 할 일이 많아지고 규모가 커지게 되면 코드를 분리해야 하는 경우가 생깁니다. 우리가 지금까지 만들었던 것처럼 main.go라는 파일 안에 모든 로직들을 넣을 순 없게 됩니다. 그래서 패키지화라는 과정을 통해 애플리케이션의 로직을 비슷한 역할을 하는 코드들끼리 모아 둡니다. 파이썬에서는 디렉터리를 만들고 __init__. py라는 파일을 만들어서 패키지화를 할 수 있습니다. 비슷한 방법으로 Go 언어 역시 패키지화를 할 수 있습니다. 하지만 Go 언어에서의 패키지화는 개인적으로는 파이썬 보다 훨씬 편하다고 생각합니다. 그리고 Go 언어가 가지는 여러 가지 특징 중 하나가 손쉬운 패키지화라고도 생각합니다. 이번 글에서는 우리가 앞에서 다뤘던 애플리케이션을 패키지화해서 관리하는 방법에 대해..

IT/GoLang 2021.10.04

두번째 글 - 함수 사용하기

오늘은 Go 언어의 함수에 대해 살펴보겠습니다. 사실 언어를 공부하게 되면 제일 먼저 학습하게 되는 것이 변수 선언 같은 것일 텐데요, 여기서는 조금 다르게 함수를 먼저 살펴보겠습니다. 지난번에 만들었던 Hello Workd on API Gateway의 코드(https://fallwalker.tistory.com/4) 를 바탕으로 함수를 만들어서 여러 개의 Path를 처리할 수 있도록 해보겠습니다. URI 별로 분기 하기 우리가 만든 Go 애플리케이션은 람다로 실행되고 앞단의 HTTP 요청은 API Gateway가 처리해 주기 때문에 Header와 Path와 같은 HTTP와 관련된 데이터들은 인자로 받을 수 있습니다. handler() 함수에서 인자로 받고 있는 events.APIGatewayProxyR..

IT/GoLang 2021.09.25

첫번째 글 - Hello World on API Gateway

Go 언어는 Go 루틴, 고계함수, Interface 등과 같이 Go 언어를 Go 언어 답게 만들어 주는 몇가지 기능들이 있습니다. 사실 이런 것들이 Go 언어를 어렵고 복잡하게 만들기도 하지만 그만큼 강력하게 만들어 주기도 하죠. 하지만 이런 특징적인 기능들 없이 기본적인 기능들만 잘 활용해도 Go 언어를 이용해서 다양한 애플리케이션을 만들 수 있습니다. 특히 AWS Lambda 서비스와 함께 동작하면 간단하면서도 확장성 높은 API 서버 혹은 배치 작업들을 만들어 낼 수 있죠. 이번 시리즈의 목표도 그렇습니다. Go 언어를 Go 언어 답게 만들어 주는 특징적인 기능들을 빼고, 기본적인 문법들과 패턴들을 이용해서 나에게 필요한 애플리케이션을 만들어 보는 시리즈 입니다. 하나의 글 마다 목표로 하는 애플..

IT/GoLang 2021.09.22
반응형