인덱스 정리
인덱스 확인 show index from DASHBOARD_JOB_CARD; 인덱스 생성 ALTER TABLE DASHBOARD_JOB_CARD ADD INDEX DASHBOARD_JOB_CARD_USER_ID_IDX (USER_ID); DASHBOARD_JOB_CARD_JOB_TABLE_IDX 이는 복합 인덱스(composite index)입니다. 컬럼 순서: (JOB_TABLE, USER_ID) 이 인덱스는 두 컬럼을 함께 사용하는 쿼리에 최적화되어 있습니다. DASHBOARD_JOB_CARD_USER_ID_IDX 이는 단일 컬럼 인덱스입니다. 컬럼: USER_ID 주요 차이점 - 용도 DASHBOARD_JOB_CARD_JOB_TABLE_IDX는 JOB_TABLE과 USER_ID를 함께 조회하는 쿼리에 유용합니다. DASHBOARD_JOB_CARD_USER_ID_IDX는 USER_ID만으로 조회하는 쿼리에 유용합니다.
마이크로미터, 프로메테우스, 그라파나
프로덕션 준비 기능 - 지표, 추적, 감사 - 모니터링 - 액추에이터는 프로덕션 준비 기능을 매우 편리하게 사용할 수 있도록 다양한 편의 기능 제공 => 마이크로미터, 프로메테우스, 그라파나 액츄에이터 관련 내용 localhost:8080/actuator localhost:8080/actuator/health management: endpoints: web: exposure: include: "*" 액츄에이터 endpoint. 1. 앤드포인트 활성화 2. 앤드포인트 노출 Http를 통해서 웹에 노출할지, jmx에 노출할지. 근데 jmx는 거의 안쓰므로 http에 노출할지말지 선택하면 된다. 엔드포인트 노출 management: endpoints: web:...
자주쓰는 명령어 정리
사용중인 플러그인 정리 IntellJ opt + cmd + T : Surround With opt + 위 -> ctrl + w 로 변경 : Extend Selection opt + cmd + / : Main Menu - Navigate - Go to Endpoint ctrl + t : Refactor this opt + shift + u : CamelCase 변환 (CamelCase 플러그인 설치 필요) shift + cmd + 위,아래 : 메서드 위치 변경...
Redis 오류 (MISCONF Redis is configured to save RDB snapshots~~~) 에러 발생
Redis 오류 (MISCONF Redis is configured to save RDB snapshots~~~) 에러 발생 Redis는 특정시점에 데이터를 디스크로 저장하여 파일로 보관이 가능. 이러한 기능으로 장애발생시 복구가능하고 파일로 저장하는경우 RDB 파일로 저장한다. Redis 에서는 RDB 파일 저장 실패 시 Redis의 데이터 쓰기가 모두 불가능하게 되고 Redis를 이용하고 있는 서비스들은 심각한 장애가 발생 MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on...
Too many connections 오류 발생
최근 운영 서버에서 Too many connections 오류 발생 현재 운영하고 있는 DB(MySQL) 커넥션 수 확인 후 커넥션 수 조절하여 해결 //동시에 최대 접속(커넥션)했던 수 확인 SHOW STATUS LIKE 'Max_used_connections'; //최대 커넥션 수 확인 (=> DB는 커넥션 수를 최대 얼마나 허용하고 있는지 확인 ) SHOW VARIABLES LIKE '%max_connection%'; //현재 접속자 수(사용하고 있는 커넥션 수) 확인 SHOW STATUS LIKE 'Threads_connected'; //MySQL의 connection pool size를 1000으로 증가시키겠다. set...
@Configuration vs @Component
@Component public class MyService { // 이 클래스 자체가 빈으로 등록 } @Configuration public class AppConfig { @Bean public MyBean myBean() { return new MyBean(); // 이 메서드가 빈을 생성하고 구성 } ... } 상황에 따라 적절한 어노테이션을 선택하여 사용. 단순한 빈 등록은 @Component를, 복잡한 설정이나 여러 빈의 관계 설정은 @Configuration을 사용하는 것이 일반적. @Component: 목적: 개별 클래스를 Spring의 빈으로 등록하기 위해 사용 사용: 주로...
라눅스 서버 내부 방화벽 설정
kt cloud 접속, 방화벽 설정해도 서버 연결되지 않는 경우! 서버 내부 방화벽도 해제해줘야함! - `netstat -tuln` : 실행중인 포트 확인 - `firewall-cmd --list-ports` : 방화벽 해제 되어있는 포트 확인 - `firewall-cmd --zone=public --add-port=3006/tcp --permanent` : 3006 포트 방화벽 해제 - `firewall-cmd --reload` : 방화벽 재시작
QueryDsl 중급 문법
프로젝션(Projection) : select 대상 지정 프로젝션 대상이 하나면 하나의 타입을 명확하게 지정 가능 프로젝션 대상이 둘 이상이면 튜플이나 DTO로 조회 Tuple -> 서비스, 컨트롤러까지 넘어가면 좋지 않은 설계다. DTO로 변환해서 사용하자. 프로젝션과 결과 반환 : DTO 조회 결과를 DTO 반환할때 사용 총 3가지의 방법을 지원한다. 1. setter 접근(프로퍼티 접근) 방식 (주의 : 기본생성자가 있어야한다. -> @NoArgsConstructor) ... Projections.bean(MemberDto.class, member.username, member.age) 2. 필드 직접 접근 ......
CompletableFuture
비동기 처리 -> CompletableFuture<T> Future에서는 에러 핸들링을 할 수 없지만, java8 나온 CompletableFuture<T>을 사용하면 에러 핸들링이 가능하다! [기본적인 사용 방법] - runAsync 반환 값이 없는 경우 비동기 작업 실행 - supplyAsync 반환 값이 있는 경우 비동기 작업 실행 [작업 콜백] 비동기 실행이 끝난 후에 다음과 같이 체이닝 형태로 작성하여 전달 받은 작업 콜백을 실행시켜 준다. - thenApply 함수형 인터페이스 Function 타입을 파라미터로 받으며, 반환 값을...
Controller vs RestController
[@Controller 예제 코드] @Controller @RequiredArgsConstructor public class UserController { private final UserService userService; @GetMapping(value = "/users") public @ResponseBody ResponseEntity<User> findUser(@RequestParam("userName") String userName){ return ResponseEntity.ok(userService.findUser(user)); } } [@RestController] @RestController는 @Controller에 @ResponseBody가 추가! (Json 형태로 객체 데이터를 반환하는 것) [@RestController 예제 코드] @RestController @RequiredArgsConstructor public class UserController { private final UserService userService; @GetMapping(value = "/users") public ResponseEntity<User> findUserWithResponseEntity(@RequestParam("userName") String userName){ return ResponseEntity.ok(userService.findUser(user)); } }
JPA exists 쿼리 성능 및 queryDsl 구현
개발을 하다보면, 데이터가 유무를 판별하는 경우가 많다. 보통은 size(), count, exists 중에서 데이터의 유무를 판별하게 되는데, 어떤것을 사용하는게 성능이 더 좋을까??? size()는 모든 데이터를 select을 해야하는 부분이 있어서 성능이 안나온다고 생각했었다. 하지만, count vs exists는 크게 생각을 안해본거 같아서 정리해본다. count는 총 몇건인지 확인을 하기 위해 전체를 확인해봐야하고, exists는 첫번째 결과에서 바로 true를 리턴하게 된다. 'exists가 count보다 성능이 좋은 이유가 결국 전체를 조회하지 않고 첫번째...
@Async
'비동기 처리'란? 비동기 처리는 작업을 별도의 스레드에서 실행하고 결과를 나중에 처리하는 방식이다. 특정 로직의 실행이 끝날때까지 기다리지 않고 다음 코드를 실행할 수 있고, 결과가 있으면 이벤트를 받거나 콜백을 통해 처리한다. --- @Async 어노테이션은 메서드에 적용하여 해당 메서드를 비동기적으로 실행시킨다.
jpa 복합키 매핑하는 법
JPA는 영속성 컨텍스트에 엔티티를 보관 시, 식별자를 사용하고 이를 구분하기 위해 equals와 hashcode를 사용해 비교한다. 이때 식별자가 2개 이상이면 별도의 식별자 클래스를 만들고 그곳에 equals와 hashcode를 구현해야한다. JPA는 2가지 방법을 제공하고 있다. 1.1 @IdClass 1.2 @EmbeddedId 이번에 @EmbeddedId로 구현했다. -> 해당 방법이 좀 더 객체지향적이라고 생각! 필수 조건 @Embeddable 어노테이션 필수 Sericalizable 인터페이스를 구현 equals, hashcode를 구현 -> @EqualsAndHashCode 어노테이션 활용 기본 생성자가 있어야 한다...
queryDsl 사용시 주의사항
querydsl을 사용할 때는 다음과 같이 {Entity명}Repository, {Entity명}RepositoryCustom, {Entity명}RepositoryImpl의 구조로 인터페이스 및 클래스를 생성합니다. Custom 인터페이스의 경우 다른 이름이 되어도 상관이 없지만, 실제 해당 메서드가 구현되는 Impl 클래스의 경우 '{Entity명}RepositoryImpl' 이라는 이름으로 생성되어야 한다는 규칙이 있습니다. 오늘 오류가 발생했던 원인은 생성된 Impl 클래스의 이름이 엔티티명과 다르기 때문에 발생했습니다.
@Transactional(readOnly = true)
@Transactional(readOnly = true) -> 조회 쿼리 시 성능 최적화(읽기 전용 트랜잭션) class에서 @Transactional(readOnly = true)로 전체를 잡고, 쓰기를 하는 메서드에 @Transactional를 추가해주는 것으로 세팅을 권장한다. @Slf4j @Service @Transactional(readOnly = true) @RequiredArgsConstructor public class XXXXXService { @Transactional public ResponseDto getXXX(...) { } }
JPA 영속성 컨텍스트 및 연관관계
회사의 코드를 리펙토링 하면서 jpa에 대해서 다시 한번 공부를 하면서 정리를 해봤다! @Test @Transcational -- 스프링꺼 사용 권장. -> @Transcational이 테스트에 있으면 테스트가 끝난 후 디비를 롤백시킨다! 롤백을 시키지 않으려면 @Rollback(false) 같은 트랜잭션에서 저장하고 조회한다면, 영속성컨텍스트에서 같은 엔티티라고 생각. 영속성컨텍스트에 있네? -> 1차 캐시에서 꺼냄. [영속성 컨텍스트란?] 영속성 컨텐스트란 엔티티를 영구 저장하는 환경이라는 뜻이다. 엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를...
HTTP 웹 기본 지식
개발자는 평생 http 기반 위에서 개발한다. 인터넷 통신 클라이언트 - 인터넷 - 서버 IP(인터넷 프로토콜) - 클라이언트 패킷 전달 - 전송 데이터(출발지 ip, 목적지 ip , 기타..) - 서버 패킷 전달 - 전송 데이터(출발지 ip, 목적지 ip , 기타..) IP 프로토콜 문제 비연결성 - 패킷을 받을 대상이 없거나 서비스 불능 상태여도 패킷 전송 비신뢰성 - 중간에 패킷이 사라지거나 순서대로 안오면? 해결이 안됨. 프로그램 구분 -...
스프링 부트 3 - queryDsl 적용하기
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" 추가 후, gradle - build - classes 한다. 그러면 프로젝트에서 build - generated - … - Q~ 를 확인할 수 있다. 왜 generated로 잡힐까? 인텔리제이 setting - Annotation Processors에서 디렉토리가 generated - 기본으로 설정되어 있다.
현재 회사의 배치 프로그램에 관련한 내 생각
오늘 아침에 비가 내렸다. 지하철을 타면서 우리 회사의 배치 프로그램에 대해서 다시 한번 생각을 해봤다. 현재 우리 회사는 스프링 부트 애플리케이션으로 배포가 되어있지만, 배치를 php 스크립트와 리눅스 크론을 쓴다는건 정말 비효율적이라고 생각했다….!!! ( 유지 보수 및 관리 차원 , 성능.) 레거시를 걷어내고 스프링 배치로 수정을 해야겠다. 하지만, 스프링 배치에 대한 학습이 필요하다. 퇴근하고 회사 스터디 모임에서 스프링 배치에 대해서 공부하자고 의견을 내야겠다. 간단하게 스프링 배치와...
Git 자주쓰는 명령어 예제
* Git 자주쓰는 명령어 예제 커맨드 명령어 팁 ctrl + w : 백스페이스로 지우는게 아니라 문장 단위로 지워짐 git status - 현재 깃 상태를 알려줌 git diff - 변경된 파일 확인 git add <파일 경로> - stage에 올리기 git reset - stage에 올라간 파일 내리기. git log * 일반적인 순서 1. git add <파일 경로> - 스테이지에 올림 2. git status - 확인 3. git...