본문 바로가기

JAVA

HashSet<URL> 기반 악성 URL 중복 제거 로직의 함정과 해결기 개요보안 시스템에서 수집되는 악성 URL들은 다양한 형태로 존재하며, 이들을 정규화하고 중복 제거하는 과정은 분석의 정확성과 효율성을 위해 필수적입니다. 이를 위해 Java의 HashSet을 활용해 중복을 제거하는 구조로 구성이 되어 있었지만, 예상치 못한 DNS 트래픽이 내부망에서 발생하는 문제가 나타났습니다.단순히 중복이 제대로 제거되지 않는 수준이 아니라, 각 URL 객체 생성 시마다 DNS 쿼리가 자동 발생하며 내부 DNS 서버에 부하를 주는 현상이 발생한 것이죠. 이 글에서는 해당 현상의 원인과 실제 네트워크 패킷 분석을 통해 검증한 과정, 그리고 최종적으로 적용한 해결 방안을 공유합니다. 현상: 내부망 DNS 트래픽 급증보안 로그 처리 중, 내부 DNS 서버에 반복적으로 DNS 쿼리가 찍히는 .. 더보기
Effective java 정복기 6장 아이템_35 ordinal 메서드 대신 인스턴스 필드를 사용하라 나쁜예시public enum Rank { FIRST, SECOND, THIRD; public static Rank fromOrdinal(int ordinal) { for (Rank rank : values()) { if (rank.ordinal() == ordinal) { return rank; } } throw new IllegalArgumentException("Invalid ordinal: " + ordinal); }}public class Main { public static void main(String[] .. 더보기
Reactor Netty HTTP Client Connection 문제의 발단고객사에서 TI대량분석 시 트래픽이 증가하면서 기존에는 발생하지 않던 새로운 종류의 에러가 발생하기 시작 했습니다.바로 해당 오류는 reactor.netty.internal.shaded.reactor.pool.SimpleDequePool 관련 IOException이며, 주요 원인은 WebClient의 연결 풀에서 리소스를 가져오지 못하는 문제입니다. 주요 원인:Connection Pool 고갈WebClient가 reactor.netty.internal.shaded.reactor.pool.SimpleDequePool을 사용하여 HTTP 연결을 재사용하는데, 사용 가능한 연결이 부족하여 새 연결을 가져오지 못하고 있습니다.외부 API 응답 지연 또는 타임아웃WebClient가 특정 API를 호출.. 더보기
Effective java 정복기 4장 아이템_15 클래스와 멤버의 접근 권한을 최소화하라 정보 은닉- 다른 객체에게 자신의 정보를 숨기고 자신의 연산만을 통해 접근을 허용하는 것- 여러 컴포넌트를 병렬로 개발 가능 (시스템 개발 속도 UP)- 각 컴포넌트를 더 빨리 파악할 수 있고 교체 부담도 적음 (시스템 관리 비용 DOWN) - 성능 최적화 도움- 소프트웨어 재사용성 UP  // AS-ISpublic class A{ private int a;}public class B{ // B가 A에서만 쓰이는 클래스라면? private int b;} // TO-DOpublic class A{ private int a; private static class B{ private int b; }}멤버 접근성의.. 더보기
Effective java 정복기 3장 아이템_10 equals는 일반 규악을 지켜 재정의해라  equals는 언제 재정의 할까? equals는 논리적인 동치성을 확인하고 싶을 때 재정의 한다.Enum: 값 클래스라고 해도 값이 같은 인스턴스가 둘 이상 만들어지지 않음을 보장할때 hashCode: 객체의 주소값을 변환하여 생성한 객체의 고유한 정수값 equals 메서드:목적: 두 객체의 "내용"이 같은지를 비교합니다.기본 동작:기본적으로는 Object 클래스의 equals 메서드를 상속받아, 두 객체의 참조값(주소)을 비교합니다.하지만 필요에 따라 **객체의 내용(필드 값)**을 비교하도록 equals를 재정의(override)할 수 있습니다.사용 예:문자열 비교: String 클래스는 equals를 재정의하여 문자열의 내용을 비교하도록 구현.. 더보기
ParallelStream은 무엇일까? JAVA8에는 람다식을 효과적으로 사용할 수 있도록 기존 API에 람다를 대폭 적용하였고,그 대표적인 인터페이스는 Stream입니다. 스트림인터페이스는 컬렉션을 파이프 식으로 처리하도록하면서 고차함수로 구조를 추상화시킵니다. 스트림을 사용하게되면, 여러줄의 코드를 간편하게 처리할 수 있고, 가독성이 쉽습니다.또한 Parallel Stream이라는 것을 통해 병렬연산을 쉽고 간단하게 할 수 있다고합니다. ForkJoinFrameWork 란? ForkJoinFrameWork 는 큰 작업을 작은 작업들로 쪼개어 작업을 병렬로 처리하고 처리한 작업들을 다시 큰 작업으로 합치는 방식으로 동작합니다.(마치 분할정복 알고리즘과 같이 동작합니다.)Fork: 작업들을 작은 작업들로 분할함.Join: 분할된 작업들을 큰 .. 더보기
스프링 첫요청이 처리되는데 오래 걸리는 이유 [ 디스패처 서블릿과 서블릿의 생명 주기 ] 스프링에는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임하는 디스패처 서블릿이 존재한다. 첫요청이 오래걸리는 이유는 서블릿의 생명주기를 봐야한다.  - 초기화단계 : 요청이 들어오면 서블릿이 웹 컨테이너에 등록되어 있는지 확인하고, 없으면 초기화를 진행함- 요청처리: 요청이 들어오면 각각의 HTTP메소드에 맞게 요청 처리- 소멸: 웹 컨테이너가 서블릿에 종료 요청을 하여 종료 시에 처리해야하는 작업들 처리 init() 메소드는 첫 요청이 왔을 때 한번만 실행되기 때문에 서블릿의 쓰레드에서 공통적으로 필요로 하는 작업이진행이 되며, 첫요청 시 많은 시간을 필요로한다. [ 디스패처 서블릿과 서블릿의 생명 주기 ]- Multipart 파일 업로드를 위한 Mut.. 더보기