본문 바로가기

Programming

(60)
AWS Lightsail로 HTTPS 서버를 구축해보다. GitHub - olive-side-project/payment-project: 📌[ 결제 시스템 프로젝트 ] 👉 확장성을 고려한 멀티모📌[ 결제 시스템 프로젝트 ] 👉 확장성을 고려한 멀티모듈 구조와 결제 API 설계 👉 Redis 기반 동시성 처리 👉 멀티프로파일 환경에서의 로그백 설정 및 MDC를 활용한 쓰레드별 로그 관리 - olive-sgithub.com [ AWS Lightsail을 선택한 이유 ]  최근 사이드 프로젝트를 진행하면서HTTPS로 서버를 구축하기로 했다. 이때 AWS Lightsail을 사용했다.Lightsail은 AWS에서 제공하는 가상 프라이빗 서버로,간편하고 직관적인 서버 설정을 제공해 준다. AWS EC2는 다양한 용도에 맞춰 수백 가지 인스턴스 옵션과 네트워크..
Push Server "개선" 작업을 해보다. 얼마 전 회사에서 기존 푸시서버 개선을 진행했다. 기존 푸시 서버의 문제점은인증정보 기반의 타겟 푸시 발송에 국한되어 있는 포맷이라서비스성 및 이벤트성 메세지 발송을 하기에는 비효율적이었다. (ex) 보내려는 서비스성 푸시메세지가 기존 시스템의 포맷과 맞지 않아 새로운 DB 테이블을 생성하거나새로운 객체에 맞게 발송 프로그램을 따로 구현하고 테스트 해야 했음 한 마디로 확장성과 유연성이 떨어지는 구조였다.  이를 해결하기 위해 인증 기반 푸시 메세지 뿐 아니라다양한 서비스 유형 푸시 메세지를 발송할 수 있도록 DB와 코드를 재설계했다. 개선 전에는 새로운 유형의 푸시를 보낼 때기존 포맷에 맞춰 추가 개발하고 테스트하는데 하루 정도 시간이 소요되었으나개선된 시스템에서는 스펙만 정해지면 대상 쿼리, 발송 시..
MDC를 활용해 쓰레드 전환을 이해해보다. 멀티쓰레드 환경에서는 항시적으로 로그가 뒤섞이곤 한다. 여러 요청이 동시에 처리될 때동일한 요청에 대한 로그가 연속적으로 쌓이는것이 아니기 때문이다.  이 문제를 해결하는 한 가지 방법으로, MDC(Mapped Diagnostic Context)를 활용할 수 있다. 각 HTTP 요청에 대한 UUID를 MDC에 저장하고, 이 UUID를 모든 로그 메시지에 자동으로 포함시키는 방식이다.이를 통해 로그를 분석할 때 각 요청을 명확하게 구분할 수 있다. 이처럼 MDC는 주로 로그에 추가적인 컨텍스트 정보를 자동으로 포함시키는 기능을 제공한다.덕분에 멀티스레드 환경에서도 요청별 또는 사용자별로 로그를 일관되게 관리할 수 있어로그 추적이 훨씬 간편해진다.    MDC를 이용해 특정 로그를 제외시키는 것은 일반적인 ..
JPA에서 @BatchSize 를 쓸 것인가 vs Fetch Join을 쓸 것인가 [ JPA에서 @BatchSize 사용 시 장점 ] @BatchSize 어노테이션은 Hibernate에서 성능을 개선하는 데 유용하다.특히 대량의 데이터를 처리할 때 이 어노테이션의 효과를 직접 느낄 수 있다.  상황cust_info (사용자 정보) 테이블을 조회할 때,대부분의 상황에서 cust_agree_info (사용자 동의 정보)도 함께 조회해야 해야 하는 상황.예를들어 1,000명의 회원 정보를 한꺼번에 조회 할 때는 어떨까? JPA 기본 쿼리 방식기본적으로 Hibernate는 1000명의 cust_info를 조회한 후,각 회원의 cust_agree_info를 조회하기 위해 별도의 쿼리를 실행함.결과적으로 1000개의 쿼리가 데이터베이스로 나가게 되며,이로 인해 성능 저하를 초래하는 N+1 문제가..
[k8s] 모니터링 시스템을 구축했다. (Fluentd, Elasticsearch, Kibana) [ 프롤로그 ] 회사에서 쿠버네티스를 도입한 지 얼마 되지 않았다. 쿠버네티스 모니터링 시스템을 구축하라는 명을 받고- Fluentd(로그 수집 도구)- ElasticSearch (로그 저장 및 검색)- Kibana (수집된 로그를 시각화)이 3가지를 연결한 내용을 정리하였다.   [ 상황 ] (1) 모니터링 시스템을 구축하기 위해ElasticSearch와 Kibana를 만들었다. 참고로 ElasticSearch는 VM으로 만들었다.이유는 안정화를 높이기 위해모니터링 시스템은 쿠버네티스 노드와 격리된 환경에서 구축하는 것이 좋다고 생각했기 때문이다.  (2) 로그 수집을 담당하는 Fluentd는 Kubernetes DaemonSet을 이용하여각 노드에 설치하였다.  (3) Fluentd를 선택한 이유 F..
[쿠버네티스] cronjob.yaml - error converting YAML to JSON 에러 해결하기 회사 개발 프로젝트에서 쿠버네티스 크론잡을 이용해 포인트를 만료시키는 스프링 배치 코드를 실행시키고 있었다. [ 개발 환경 ] - JAVA : 17 - Spring framework : 3.1.5 - Cloud : Azure 나는 매일 오전 12시 01분에 도는 배치였고, value.yaml 파일은 대략 다음과 같았다. 그리고 이렇게 내가 만든 포인트 만료 배치만 돌릴 때는 문제가 발생하지 않았다. service: "batch" image: repository: 생략 pullPolicy: IfNotPresent tag: "" jobs: - name: expire-point (1번 배치) envFrom: - configMapRef: name: 생략 - secretRef: name: 생략 - secretRe..
[Java] 인터페이스를 통해 if문의 향연을 고쳐보았다. 상황 물건의 최소 시세값이 '5억', 최대 시세값이 '10억' 이라고 세팅 되었다고 할 때, - 사용자의 물건이 7억이면? 필터링을 통과한다. 👉 5억과 10억 사이기 때문이다. - 사용자의 물건이 3억이면? 필터링을 통과하지 못한다. 👉5억과 10억 사이가 아니기 때문이다. 이에 대한 필터링 코드를 작성했고, 이를 리팩토링 하는 과정을 정리해보고자 한다. 결론 비교 화면 리팩토링 전 코드 딱 봐도 if 문의 향연 그 잡채다. 최소값과 최대값이 항상 둘 다 세팅된다는 보장이 없기에 (1) 최소값 / 최대값이 둘 다 세팅되었을 때 (2) 최대값만 세팅되었을 때 (3) 최소값만 세팅되었을 때 를 나누어 조건을 분리하는 그런 코드이다. 필터링을 수행하는데 크게 이상은 없지만, if 문이 너무 많아 보기 좋아보..
[Java] 역직렬화로 JSON 포맷을 바꿔보았다. 백오피스 프로젝트를 개발하던 중에 Jackson 라이브러리를 통해 '역직렬화'를 사용해 보았다. 먼저 상황은 다음과 같았다. 프로모션 관련 백오피스 기능이었는데, 프로모션을 등록할 때 섹션 종류가 총 3가지가 있었다. (buttion, image, detail) 이 때 프론트에서 세팅해야하는 JSON 데이터 포맷을 맨 처음에는 아래 이미지에서 A와 같이 되도록 코드를 작성했었다. sectionType이 달라짐에 따라 "imageSection" , "buttonSection", "detailSection" 과 같은 필드가 따로 따로 생기는 방식이었다. 프론트 입장을 고려했을 때는 A 보다는 B 방식이 데이터를 다루는 데 있어서 더 편하다고 판단하였고 B 와 같이 JSON 포맷이 되도록 하기 위해 Jacks..
[Java] 인터페이스 사용하여 필터링 기능을 구현해 보았다. 최근에 했던 개발 중,  특정 상품에 대해 필터링을 해야 하는 내용이 있었다. 내용을 간단히 말하면,현재 이 상품을 사용하려는 사용자가 가진 조건이이 상품이 요구하는 조건과 일치하지 않는다면 필터링 아웃 시켜야하는 것이었다.   제일 처음 작성했던 코드 스타일은 다음과 같다. @Slf4j@Service@Transactional@RequiredArgsConstructorpublic class CalculatorService {private boolean filterConditions(CalculatorContext context, long productSeq) { return Stream.of( isPurposeValid(putData.getPurposeCd(), p..
[Linux] top과 jstat -gc 명령어로 서버와 GC 살펴보기(with 챗지피티) 📌 크롬은 용량을 너무 많이 차지해....😢 최근에 크롬창을 띄워 스크래핑을 진행하는 서버를 개발하면서 만난 이슈가 하나 있었다. 테스트를 위한 스테이지 서버는 t3.small 인스턴스 유형으로 세팅이 되어 있었는데, 하나의 스크래핑 요청만 진행할 때는 이상없이 진행됐지만 2개의 스크래핑을 동시에 진행하니 서버가 뻗어버렸다. (겨우 2개에 뻗다니 ㄷㄷㄷ) 가장 큰 원인은 스크래핑이 실패하는 경우 무조건 크롬창을 닫아야 하는데, 부분부분 특정 단계에서 크롬창이 닫히지 않고 그대로 떠있어서 크롬이 많은 용량을 차지하고 있었기 때문이었다. (크롬의 용량은 상당히 크다..........!) 그래서 어떤 단계에서든 스크래핑이 실패하면 무조건 크롬창을 닫도록 코드를 수정하니 동시의 2개의 스크래핑 요청이 온다고 해..
[Spring] 멀티 쓰레드 환경에서 자원이 공유돼 버렸다. 이번에는 어떤 상황이 발생했을까?! 최근에 특정 데이터를 스크래핑하는 개발을 했다.  Java + Selenium 을 통해 서버에서 크롬창을 연 뒤 클릭이벤트를 발생시켜 데이터를 스크래핑 한 후,그 데이터를 Redis에 저장하는 방식이었다.  AWS SQS (Simple Queue Service) 기술도 사용했다."C"라는 서버에서는 SQS 메세지를 Publishing 하는 역할을 하고=> "D"라는 스크래핑 서버에서는 AWS SQS를 구독하고 있다가 메세지가 생기면 수신하여 처리하는 방식이다.   이때 "D"라는 스크래핑 서버에는 아래와 같은 서비스가 존재한다. (1) SqsService (큐 서비스)(2) ScraperService (스크래퍼 서비스)  (1) SqsService(큐 서비스)는 SQS..
[Spring] @Async는 왜 제대로 동작하지 못했는가악! 일단, @Async가 뭘까? @Async는 Spring에서 제공하며, Thread Pool을 활용하여비동기를 지원하는 어노테이션이다.   @Async가 제대로 동작하지 않는 상황이 발생했다! 이번에도 어김없이 등장하신 개발실 실장님 🙌 최근 누군가가 개발한 코드 중에서@Async 어노테이션을 붙인 코드가 제대로 동작하지 않아서비동기 처리가 되고 있지 않은데원인이 무엇인지 확인해 보라고 하셨다.   회사코드라 그대로 옮길 수 없지만,대략 큰 뼈대 내용은 다음과 같다.   public class BenzService extends CarService{ public void init(CarDto carDto) { // 생략 .. callExternalApi(carDto, api..
[Spring] Thread-safe 에 대해서 고찰해 보다. 부제 : 스프링 빈은  멀티쓰레드 환경에서 Thread-safe 할까?  개발 실장님께서아래 코드에 버그가 있는데, 무엇이 버그인지 알겠냐고 물어보셨다. ( 회사코드를 그대로 가져다 쓸 수 없어 예시를 들기 위해 클래스명, 변수명 등을 조금 변경했다. )   아래 코드를 보면,for문을 돌면서 getBean() 메소드를 통해 생성되어 있는 스프링 빈(bean)을 찾아와 characterService에 할당하고 있다.                                       - (1)번 파트  그다음 할당된 스프링 빈(bean)의 init() 메소드를 실행한다.   - (2)번 파트  public class Service { // .... 생략 private CharacterServi..
[코드리뷰 받은 내용 정리] 코드를 작성할 때 '이것'을 생각해보자! 🎨 참조타입 vs 원시타입 @Schema(description = "정기알림 신청여부", example = "false") private Boolean monthlyRequestYn; [ 위 코드에 대한 코드리뷰 내용 ] " 개인적으론 Boolean type은 boolean을 쓰는 걸 추천합니다. Reference type과 성능 차이도 있을 수 있지만 null point exception 과 같은 것도 고민안해도 되니깐요. 특히 boolean type은 만약 입력을 하지 않으면 false나 true 둘 중에 하나의 default 값이 존재하는 경우가 많아서 reference type을 쓸일이 더 없었던거 같아요. 물론 100%라고 말씀드릴 순 없어요. 그러나 여기는 false가 default 일거 같긴..
[AWS야 제발 친해지자] VPC / 서브넷 / 인터넷 게이트웨이 / 라우팅 테이블 / 로드밸런싱 스케쥴러는 기존에 A web 서버와 같이 쓰고 있어서 subnet이 was와는 다르게 설정되어 있는 상태였는데 설계목적이나 역할로 봤을 때 스케쥴러는 was 쪽 보안그룹이나 network 설정을 공유하고 was subnet에서 실행하는게 맞을 것 같아서 스케쥴러 ec2를 만들려합니다. crm 서버 사양도 조정할 예정입니다. 🤚 왜 이 글을 작성하게 되었는가 회사 업무 슬랙에 개발 실장님이 위와 같이 말씀하셨는데, 단번에 이해되지 않아 난 AWS를 너무 모르는구나 싶어서.... 공부해야 겠다는 마음에 이 글을 작성하게 되었다. 먼저, 위에서 'subnet(서브넷)' 이라는 단어가 등장하는데 서브넷을 이해하기 위해서는 앞서 VPC라는 것을 알아야 한다. 그래서 VPC부터 시작하여 연관된 내용을 하나씩 알아보..
[리팩토링 기술-7] 기본형을 객체로 바꾸기 / 타입 코드를 서브클래스로 바꾸기 / 조건부 로직을 다형성으로 바꾸기 👀 기본형 집착 ? - 어플리케이션이 다루고 있는 도메인에 필요한 기본 타입을 만들지 않고 프로그래밍 언어가 제공하는 기본 타입을 사용하는 경우가 많다. - 기본형으로는 단위 또는 표기법을 표현하기 어렵다. 🙌 기본형을 객체로 바꾸기 (Replace Primitive with Object) - 개발 초기에 기본형 (숫자 또는 문자열)으로 표현한 데이터가 나중에는 해당 데이터와 관련있는 다양한 기능을 필요로 하는 경우가 많다. (예) 문자열로 표현하던 전화번호의 지역코드가 필요한 경우 (예) 숫자로 표현하던 온도의 단위(화씨, 섭씨)를 변환하는 경우 기본형을 사용한 데이터를 감싸 줄 클래스를 만들면, 필요한 기능을 추가할 수 있다. [ Berfore ] Order 클래스에서 우선순위를 의미하는 prioir..
[리팩토링 기술-6] 단계 쪼개기 / 클래스 추출하기 🙌 단계 쪼개기 (Split Phase) - 서로 다른 일을 하는 코드를 각기 다른 모듈로 분리한다. : 그래야 어떤 것을 변경해야 할 때, 그것과 관련있는 것만 신경쓸 수 있다. - 여러 일을 하는 함수의 처리과정을 각기 다른 단계로 구분할 수 있다. (예) 전처리 -> 주요작업 -> 후처리 (예) 컴파일러 : 텍스트 읽어오기 -> 실행 가능한 형태로 변경 - 서로 다른 데이터를 사용한다면, 단계를 나누는데 있어 중요한 단서가 될 수 있다. - 중간 데이터를 만들어 단계를 구분하고, 매개변수를 줄이는데 활용할 수 있다. [ Berfore ] priceOrder() 함수는 주문에 값을 매기는 일을 하지만 내부에서 할인가격과 할인된 가격을 구하는 두가지 일을 같이한다. [ After ] - basePric..
[리팩토링 기술-5] 반복문을 처리하는 리팩토링 👀 반복문 (Loops) - 프로그래밍 언어 초기부터 있었던 반복문은 처음에는 별다른 대안이 없어서 간과했지만 최근 자바와 같은 언어에서 함수형 프로그래밍을 지원하면서 반복문에 비해 더 나은 대안책이 생겼다. - "반복문을 파이프라인으로 바꾸는 (Replace Loop with Pipeline)" 리팩토링을 적용하면 필터나 맵핑같은 파이프라인 기능을 사용해 보다 빠르게 어떤 작업을 하는지 파악할 수 있다. 🙌 반복문을 파이프라인으로 바꾸기 (Replace Loop with Pipeline) - 고전적인 반복문을 파이프라인 오퍼레이션을 사용해 표현하면 코드를 더 명확하게 만들 수 있다. (1) filter : 전달받은 조건의 true에 해당하는 데이터만 다음 오퍼레이션으로 전달 (2) map : 전달받은 ..
[리팩토링 기술-4] 가변데이터를 처리하는 리팩토링 👀 가변 데이터 (Mutable Data) - 데이터를 변경하다보면 예상치 못했던 결과나 해결하기 어려운 버그가 발생하기도 한다. - 함수형 프로그래밍 언어는 데이터를 변경하지 않고 복사본을 전달한다. 하지만 그밖의 프로그래밍 언어는 데이터 변경을 허용하고 있다. 따라서 변경되는 데이터 사용 시 발생할 수 있는 리스크를 관리할 수 있는 방법을 적용하는 것이 좋다. * 관련 리팩토링 - "변수 쪼개기(Split Variable)"을 사용해 여러 데이터를 저장하는 변수를 나눌 수 있다. - "질의 함수와 변경 함수 분리하기(Separate Query form Modifier)"를 적용해서 클라이언트가 원하는 경우에만 사이드 이팩트가 있는 함수를 호출하도록 API를 개선할 수 있다. - 가능하다면 "세터 제거..
[리팩토링 기술-3] 긴 매개변수를 처리하는 리팩토링 👀 매개변수가 많으면 무엇이 문제일까? 그리고 어떻게 해결할 수 있을까? - 어떤 함수에 매개변수가 많을수록 함수의 역할을 이해하기 어려워진다. 그렇다면 아래 내용을 생각해 봐야한다. 1. 과연 그 함수는 한 가지 일을 하고 있는게 맞는가? 2. 불필요한 매개변수는 없는가? 3. 하나의 레코드로 뭉칠 수 있는 매개변수 목록은 없는가? - 어떤 매개변수를 다른 매개변수를 통해 알아낼 수 있다면, "매개변수를 질의함수로 바꾸기(Replace Parameter with Query)"를 사용할 수 있다. - 매개변수가 플래그로 사용된다면, "플래그 인수 제거하기(Remove Flag Argument)"를 사용할 수 있다. - 여러 함수가 일부 매개변수를 공통적으로 사용한다면 "여러 함수를 클래스로 묶기(Comb..
[리팩토링 기술-2] 긴 함수를 처리하는 리팩토링 👀 짧은 함수 vs 긴 함수 - 함수가 길 수록 이해하기 어렵다! vs 짧은 함수는 더 많은 문맥전환을 필요로 한다. - 작은 함수에 "좋은 이름"을 사용했다면, 해당 함수의 코드를 보지 않고도 이해할 수 있다. - 어떤 코드에 "주석"을 남기고 싶다면, 주석 대신 함수를 만들고 함수의 이름으로 "의도"를 표현해보자. ✍ 긴 코드를 리팩토링할 때 사용할 수 있는 기술 1. 99%는 "함수 추출하기"로 해결할 수 있다. 2. 함수로 분리하면서 해당함수로 전달해야 할 매개변수가 많아진다면, 다음과 같은 리팩토링을 고려해볼 수 있다. (1) 임시 변수를 질의 함수로 바꾸기 (Replace Temp With Query) (2) 매개변수 객체 만들기 (Introduce Parameter Object) (3) 객체..
[리팩토링 기술-1] 중복코드를 처리하는 리팩토링 👀 중복코드의 단점 1. 비슷한 코드인지, 완전히 동일한 코드인지 주의깊게 살펴봐야 한다. 2. 코드 변경 시 통일한 모든 곳의 코드를 변경해야 한다. ✍ 사용할 수 있는 리팩토링 기술 1. 함수 추출하기 - 동일한 코드를 여러 메소드에서 사용하는 경우 사용한다. - 무슨 일을 하는 코드인지 알아내려고 노력해야 하는 코드라면, 해당 코드를 함수로 분리하고 함수 이름으로 "무슨 일을 하는지" 표현할 수 있다. ( = 의도를 드러낼 수 있다. ) [ Berfore ] * printParticipants() : 깃헙 커넥션을 만들고 -> 리포지토리를 읽어오고 -> 이슈를 찾아서 -> 이슈에서 코멘트를 돌면서 -> 참석한 사람들의 이름을 담아주고 -> 담은 userName을 출력하는 내용이다. import or..
[Spring] 멀티모듈 구성 방법 ✏️ (예시) 아래와 같이 모듈 프로젝트를 구현해야 하는 상황일 때 관리자 API 모듈, 스케쥴러 API 모듈, 서비스 모듈을 구성해야 함 관리자 API 모듈 : 게시판 CRUD / 회원 CRUD / 로그인 담당 (controller) 서비스 모듈 : service, mapper 등 스케쥴러 API : 껍데기만 생성 🎯프로젝트 생성방법, pom.xml 구성 방법 먼저 전체를 아우르는 ‘basic-module’ 을 아래와 같이 new Project로 생성한다. 2. 새로 만든 ‘basic-module' 프로젝트에 아래와 같이 관리자 API 모듈 ( = admin) 을 추가한다. 스케쥴러 API 모듈 ( = schedule)도 동일한 방법으로 추가한다. 3. ‘basic-module’ 프로젝트에 서비스 모듈..
[Spring Batch] 오류가 나면 어떻게 해야할까? - Skip과 Retry 스프링 배치에서는 Skip이라는 기능을 통해 Step 내에서 발생한 특정 Exception에 대해 해당 Exception을 n번까지 허용하겠다는 설정을 할 수가 있다. 예를들어 skip(NotFoundNameExcpetion.class).skipLimit(3) 으로 설정한 경우 NotFoundNameExcpetion 발생 3번까지는 에러를 skip 한다. NotFoundNameExcpetion 발생 4번째부터는 Job과 Step의 상태가 실패로 끝나며, 배치가 중지된다. 단, 에러가 발생하기 전까지 데이터는 모두 처리된 상태로 남는다. Step은 chunk 1개 기준으로 Transaction이 동작한다. 예를 들어 items = 100, chunk.size = 10 일 때 총 chunk 동작 횟수는 10..
[Spring Batch] 스프링 배치를 써야 할까? 휴면회원 상태변경 스프링 배치를 통해 스프링배치를 구현하면서 이런 의문점이 생겼습니다. [Spring Batch] 로그인한지 1년 지난 회원 -> 휴면회원으로 상태변경하는 배치구현 [ 실행흐름 ] 1. [ Job] Job은 스프링부트 배치를 처리함에 있어서 가장 상위 계층이다. JobBuilderFactory에서 생성된 JobBuilder를 통해 Job을 생성한다. ✏️ .incrementer(new RunIdIncrementer()) Spring.. domean.tistory.com ‘솔직히 이렇게 스프링 배치로 긴 코드를 구현할 것 없이 update user set status = 'inactive' where login_date > 2022-01-01 라는 업데이트 쿼리 날리는 API 를 스케쥴러로..
[Spring Batch] Step에서 데이터를 처리하는 방법 2가지 (+ 예제) 스프링배치의 Step 단계에서 데이터를 처리하는 방법은 2가지가 있다. 1. Chunk를 사용한 Step 2. Tasklet을 사용한 Step 이 2가지 방법의 차이점을 아래와 같이 알아보았다. 🎈예제 상황 100개의 문자열을 list로 만들고, list 사이즈를 로그로 찍는 Task 1. Chunk를 사용한 Step @Bean public Step chunkBaseStep() { return stepBuilderFactory.get("chunkBaseStep") .chunk(10) .reader(itemReader()) .processor(itemProcessor()) .writer(itemWriter()) .build(); } private ItemReader itemReader() { return ..
[Spring Batch] 로그인한지 1년 지난 회원 -> 휴면회원으로 상태변경하는 배치구현 오늘 기준으로 마지막 로그인 일자가 1년이 넘은 회원의 사용자 상태를 ‘ACTIVE’ 👉 ‘INACTIVE’ 상태로 변경하는 배치를 만들었다. * 전체 소스코드는 하단에 있습니다. :) [ 스프링 배치 실행흐름 ] 코드로 살펴보면 다음과 같다. 1. [ Job] Job은 스프링부트 배치를 처리함에 있어서 가장 상위 계층이다. JobBuilderFactory에서 생성된 JobBuilder를 통해 Job을 생성한다. ✏️ JobBuilderFactory는 JobBuilder를 생성할 수 있는 get() 메소드를 포함하고 있다. get()메소드는 "inactiveUserJob"이라는 Job을 만들어 반환한다. ✏️ .incrementer(new RunIdIncrementer()) Spring Batch에서 전..
[보안] SQL Injection / PreparedStatement / Statement 🎈 SQL Injection이란? SQL Injection 이란 악의적인 사용자가 보안상의 취약점을 이용하여, 임의의 SQL 문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위 입니다. 🎈 SQL Injection 공격 종류 및 방법 - 논리적 에러를 이용한 SQL Injection 위의 사진에서 보이는 쿼리문은 일반적으로 로그인 시 많이 사용되는 SQL 구문입니다. 해당 구문에서 입력값에 대한 검증이 없음을 확인하고, 악의적인 사용자가 임의의 SQL 구문을 주입하였습니다. 주입된 내용은 ‘ OR 1=1 -- 로 WHERE 절에 있는 싱글쿼터를 닫아주기 위한 싱글쿼터와 OR 1=1 라는 구문을 이용해 WHERE 절을 모두 참으로 만들고, -- 를 넣어줌으로 뒤의 구문을 모두..
왜 프로그래밍 언어에서 0.1 + 0.2 는 0.3이 아닐까요? 🎈결론 인간은 숫자를 표현하기 위해 혹은 연산을 하기위해 10진법을 사용하지만 컴퓨터는 2진법을 사용하기 때문에 그 차이에서 비롯된 오차때문이다. 우리가 12라는 숫자를 컴퓨터에 입력하면 컴퓨터에서는 내부적으로 해당 숫자를 1100(이진법)으로 변환하여 처리한다. 우리가 소수 0.75를 입력하면 컴퓨터에서는 0.11(이진법)으로 변환하여 처리한다. 🎈 그럼 왜 2진수로 표현하는데 오차가 생길까? 0.1(십진법)을 이진법으로 변환하게 되면 0.0001100110011001100110011001....... 과 같이 무한 소수로 정확하게 떨어지지 않는다. 컴퓨터의 메모리는 무한하지 않기 때문에 표현할 수 있는 최대한의 범위 내에서 가장 근접한 값으로 반올림 처리하여 우리에게 결과를 보여준다. 그리고 이로 인..
[네트워크] OSI7계층이 뭔가요? 🎈 OSI (Open Systems Interconnection Reference Model) 7계층이란? 네트워크에서 통신이 일어나는 과정을 7단계로 나눈 것이다. 국제표준기구 (ISO)에서 발표한 것으로 '인터넷 연결을 할 때 이렇게 설계를 하면 통신이 정상적으로 작동을 할것이다'라는 권고안이다. 🎈 왜 나눌까? 통신이 일어나는 과정을 단계별로 알 수 있고, 특정한 곳에 이상이 생기면 그 단계만 수정할 수 있기 때문이다. 1. 물리계층 (physical layer) 0과 1로 되어있는 데이터를 전기신호로 바꿔주는 계층이다. 물리계층에서는 0과1로 데이터가 구성이 되고, 통신단위는 'bit'이다. 이 계층에서는 단지 데이터를 전달만 할 뿐 전송하려는 데이터가 무엇인지, 어떤 에러가 있는지 등에는 전혀 ..