- Spring JPA 비관적 락 (Pessimistic Lock) 락의 필요성금융이나 결제쪽 개발을 할때 동시성 제어가 필요한 경우가 있다.물론 synchronized 처리를 떠올리지만, 쓰레드 레벨로 막는 것이고 실제로는 여러대의 서버를 두기때문에 부족하다.이 경우 DB(RDBMS, Redis 등) 레벨의 락이 필요한데, 이럴때 사용할 수 있는 JPA 락 방법이 있다. 락의 종류흔히 2가지로 나뉜다.낙관적 락 (Optimistic Lock) : 이름은 락이지만, 락을 걸진않고 수정 시 업데이트 되었는가를 감지비관적 락 (Pessimistic Lock) : 다른 트랜잭션의 데이터 (조회, 수정) 혹은 수정만 막는다.낙관적 락은 JPA에서 @Version 이라는 어노테이션을 통해 사용하고수정 시 버전이 다른 경우, ObjectOptimisticLockingFailureE..
- Spring Spring Controller 중복 호출되는 이슈 최근에 로그를 보다가 Controller에 특정 페이지를 리턴하는 메소드에서 중복 호출이 되고있는 것을 발견했다.사실 이전에도 발견되어 인지하고있었지만, 따닥 이라던가 새로고침을 빠박 할 수도 있기 때문에 넘어갔는데생각보다 너무 자주 로그가 찍혀있고 시간 간격도 매우 짧기 때문에 원인을 찾아야겠다는 생각이 들었다. 상황은 이렇다.@Controllerpublic class TestController { ... @GetMapping("index") //아니면 "/" public String index(Model model, HttpServletRequest request, args...) { ... return "/~~~/index" } ...}해당 ..
- Server [Linux] Ubuntu 사용자 계정 생성 및 접속 설정 먼저 root로 접속해준다 sudo su root 권한으로 하지않으면 아래와 같은 에러문구가 출력된다 adduser: Only root may add a user or group to the system. 계정 생성 adduser 계정아이디 해당 커맨드를 입력하면 아래와같이 추가 입력 부분이 출력된다. New password: Retype new password: passwd: password updated successfully Changing the user information for rkdvnfms5 Enter the new value, or press ENTER for the default Full Name []: Room Number []: Work Phone []: Home Phone []:..
- Spring Spring JPA @Id 복합키 설정 Spring JPA를 사용하면서 기본키가 2개 이상 컬럼으로 구성된 테이블을 Entity로 지정할 때가 있다. 예시로 아래와 같은 Work 테이블과 WorkE 엔티티 클래스가 있다고 가정했을때 @Table(name = "Work") public class WorkE { @Id @Column(name = "name") private String name; @Id @Column(name = "type") private String type; .... } 이름(name)과 구분(type) 두개의 컬럼을 기본키로 사용하고 있는 경우, 위처럼 두 필드에 모두 @Id 어노테이션을 사용하면 된다고 생각할 수 있다. 하지만 추가해야할 것이 있는데, 아래처럼 엔티티에 @IdClass 어노테이션을 추가해줘야한다. @IdC..
- Spring Maven Jar 빌드 외부 dependency 추가 Spring Webflux로 오브젝트 스토리지 솔루션 프로젝트를 만들면서 빌드 도구는 maven, 배포는 내장 netty 서버 쓸거라서 처음으로 jar로 배포하게 되었다. 한심하다고 느낀건 아직도 나는 maven을 제대로 모른다는 것이다. 시간이 될때 maven에 대해서 공부하고 정리를 해볼 필요를 느꼈다. 문제 pom.xml에 외부 jar파일을 추가해서 사용하고 있었는데 로컬에서 실행하면 잘 돌아가지만 jar로 배포해서 실행하면 NoClassDefFoundError가 발생하는 특정 경우가 있었다. 원인 pom에서 추가한 외부 jar dependency는 적용이 잘 되었지만, 빌드 후 생성된 jar 파일을 풀어서 BOOT-INF/lib를 보면 해당 외부 라이브러리가 없었기 때문에 필요한 클래스가 정의되지..
- Server iptables 80포트 설정 iptables를 오랜만에 쓰면 자꾸 잊어버린다. 방화벽 목록 확인 iptables --list 출력 이미지에 표시된 reject-with icmp-host-porhibited를 볼 수 있는데, 이 REJECT라인 밑으로 적용된 설정은 적용되지 않는다. 예를 들기 전, 80포트를 추가하자 iptables -A INPUT -p tcp --dport 80 -j ACCEPT 이 후에 다시 리스트를 출력하면 REJECT 설정 밑으로 80포트가 설정된 것을 볼 수 있다. 이렇게 되면 80포트 INPUT이 되지 않는다는 것이다. 이 경우에는 REJECT를 INPUT에서 지워줬다가 다시 추가하면 된다. iptables -D INPUT -j REJECT --reject-with icmp-host-prohibited i..
- Spring Spring Webflux Filter 적용 (Webfilter) Webflux를 사용해보면서 Interceptor를 적용해보고 싶었는데 기존 MVC 구조에서 사용하던 interceptor, 엄밀히 말하면 톰캣을 위해 사용하던 인터셉터는 사용할 수 없었다. 약간 찾아본 결과 Webfilter 사용을 많이 하는듯 보여서 적용해봤다. 적용은 매우 간단하다. Webfilter 인터페이스를 구현한 클래스를 하나 생성해서 @Component만 적용해주면 끝. 그래서 나는 Webfilter를 구현한 AclFilter라는 클래스를 생성했다. AclFilter import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org..
- Spring Spring Webflux Exception 전역 처리 (Functional Endpoints) webflux로 api 서버를 하나 개발하면서 에러 상황들을 전역으로 처리하고 싶었다. 스프링 mvc나 boot에서는 @ControllerAdvice나 @RestControllerAdvice를 사용하는데, webflux도 어노테이션 방식으로 @Controller를 사용한다면 동일하게 @ControllerAdvice를 사용할 수 있을것 같았다. 하지만 나는 request를 Functional Endpoints 방식으로 RouterFunction을 활용해 요청을 라우팅하기 때문에 다른 예제를 찾아보게 되었고, 그 과정에서 메서드를 까보진 않았지만 까보기전 추측한 생각을 정리하려 한다. 참고 : https://www.baeldung.com/spring-webflux-errors Handling Errors i..
- Spring Spring Webflux (3) - Select 이전 글에서 Insert하는 과정에 대해서 작성했다. 이번엔 CRUD중 Read인 SELECT 과정에 대해서 기록해보려고 한다. 사실 SELECT기능을 구현한지 꽤 되어서 기억이 듬성듬성이다. 이전과 마찬가지로 Board와 BoardFile 1:N 관계에서 목표는 Board를 여러개 받는 Flux를 리턴하는 api( getBoardList() )와 Board 1개와 해당 Board의 BoardFile을 여러개 리턴하는 api( getBoardOne() )를 구현하는 것이다. 1. getBoardList api 에 들어가기 전에 이슈가 하나 생겼다. 나는 MariaDB를 사용하고있고, 기존에 r2dbc 설정에서 mysql 드라이버를 사용하고 있었는데 이 드라이버에서 DatabaseClient나 R2dbcE..
- Java String은 왜 불변 객체로 만들었을까? Java에서 String은 불변 객체다. 이전글 : https://riverblue.tistory.com/42?category=929398 Java String, StringBuilder, StringBuffer 자바에서 문자열 클래스는 대표적으로 String, StringBuilder, StringBuffer가 있다. 사실 String밖에 다루지 않아봐서 잘 몰랐는데 좋은 경험을 하게 되어서 나머지 두 클래스도 다뤄야 겠다고 생각했다. St riverblue.tistory.com 근데 한번도 왜 불변으로 만들었는지, 불변이 뭐가 좋은지 생각해본적이 없다. 그래서 이유를 좀 찾아보게 되었고 나름대로 정리한 생각을 기록해본다. 참고 : https://www.baeldung.com/java-string-im..
- Java StringBuilder 살짝 까보기 (생성자, append) StringBuilder (Buffer도 마찬가지)를 몇번 사용했지만, 어떻게 생긴지에 대해서 생각해본적이 없어서 살짝 까보려고한다. 참고로 jdk는 1.8 StringBuilder는 추상클래스인 AbstractStringBuilder을 상속받고있다. 이름부터만 봐도 StringBuilder에 대해서 정의한 클래스라는게 느껴진다. StringBuilder 생성자 일부분 public StringBuilder() { super(16); } /** * Constructs a string builder with no characters in it and an * initial capacity specified by the {@code capacity} argument. * * @param capacity the..
- Spring Spring AOP 주의할 점 (프록시의 주의할 점) Spring에서 aop를 동작할 땐 프록시 방식으로 동작한다. 하지만 이 프록시를 사용할 때 주의할 점이 무엇인가 질문을 받았던 적이 있는데, 대답을 못했다. 그러고보니 나는 업무를 하면서 aop를 사실 잘 안쓰기도 했고, 개인적으로 사용할 때 그런걸 고려해본적이 없는데 그동안 aop를 제대로 활용하지 않아서 그런것이라고 생각된다. 그러면 질문의 답이 무엇일까? 사실 모른다. 하지만 구글링을 조금 해본 결과 스프링에서 aop를 타지 않는 케이스가 생길 수 있는데 아래와 같은 상황이다. 콘솔에 print만 하는 간단한 Service와 aop를 구현했다. PrintTestService @Service public class PrintTestService { @AopTester public void logic..
- Spring Spring AOP의 동작 원리 (1) - JDK Dynamic Proxy 이전에 AOP 사용에 대해 정리한 글이 있는데, 생각해보니 정확한 원리에 대해서 알아보지 못한거 같아 정리하려고 한다. Spring에서 AOP는 프록시 방식으로 동작한다. 크게 두가지 프록시 방식이 있는데 1. JDK Dynamic Proxy 2. CGLib 이 중 1번 jdk의 동적 프록시에 대해서 개인적으로 찾아보고 생각한 내용을 정리해본다. 프록시가 뭐시여 프록시는 대리 수행하는 놈이라고 생각한다. 사실 프록시는 다양한 곳에서 널리 쓰이는 개념인데, 그렇다면 Spring에서 프록시는 어떤 것으로 생각해야할까. 이렇다는건 아니지만 느낌을 쉽게 받기위해 프록시 유무에 따라 동작을 비교해 본다. 프록시X 프록시 O Service Proxy는 실제 Service가 아니지만 Service인척 Controll..
- Spring Spring Webflux (2) - Insert 이전 글에서 간단하게 Webflux 사용을 위한 R2DBC, Router, Handler에 대해 설정해봤다. 이번엔 CRUD중 Create인 Insert 기능을 먼저 구현하려고 한다. Insert의 목표는 게시글인 Board 추가와 첨부파일을 의미하는 BoardFile도 Insert하는 기능을 구현할 예정이다. Board와 BoardFile은 릴레이션(1:N)으로 테이블을 구성했다. 테스트 - Postman Board Class import org.springframework.data.annotation.Id; import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.co..
- DB Mysql 인덱스에 대해서 저장 프로시저 하나를 돌리면서 인덱스의 중요성을 알게된 적이 있다. 그때 인덱스에 대해서 많이 찾아보고 알게된 것들이 많았는데 시간이 지날수록 금방 잊어버려서 다시 공부하는겸 인덱스에 대해서 정리해보려한다. 인덱스란 인덱스에 대해서 검색하면 항상 색인이라는 단어가 나온다. 실제로 색인은 영어로 index로 쓰이고 책에서 내용의 단어나 구절등의 위치가 몇페이지에 있는지 알려주는 정보의 목록인데, 개인적으로 책을 많이 읽지 않아서 그런지 색인이라는 단어가 굉장히 낯설게 느껴진다. 때문에 나처럼 책알못이라 색인이 와닿지 않는다면, 호텔의 x호 ~ x호는 왼쪽 x호 ~ x호 는 오른쪽으로 표시되어있는 화살표를 생각한다면 좀 더 와닿지 않을까 추측해본다. 방 호수를 의미하는 room_num이라는 컬럼에 인덱스를 ..
- Spring Spring Webflux (1) - 간단한 시작 논블로킹으로 동작하는 Webflux로 간단한 API 앱을 구현하고싶어서 시작했다. webflux 기초 지식이 많이 부족한 내가 쌓아가는 과정을 기록하려고 한다. IDE : eclipse JDK : 1.8 프로젝트 생성 Spring boot에 Gradle로 설정한 후 Next 간단하게 Reactive Web만 체크하고 생성 자바 라이브러리가 안되어있다면 Build Path에서 add library 해주자 gradle plugins { id 'org.springframework.boot' version '2.6.4' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' id 'war' } group = 'com.zero' versio..
- 그 외 HTTPS 동작 과정 이 글은 HTTPS 원리에 대해서 여러 글을 보고 이슈에 대해 추측해서 정리한 주관적인 글이다. 때문에 잘못된 정보가 있을 수 있다. HTTPS란 HTTPS는 Hyper Text Transfer Protocol을 의미하는 HTTP에 Over Secure Socket Layer가 추가된 프로토콜을 말한다. 즉, 통신할때 보안이 적용된 계층(Layer)위에 HTTP가 동작하는 프로토콜을 의미한다. 보안 계층은 SSL(Secure Socket Layer)과 TLS(Transport Layer Security)를 의미하는데 SSL은 넷스케이프에 의해 개발되어 넓게 사용되다가 관리 기구가 바뀐이후로 TLS로 이름이 바뀌었기 때문에 원리를 이해하는데 있어서는 SSL과 TLS를 같은 개념으로 인지해도 무방하다. SS..
- Spring Spring 캐시 추상화 (Cache Abstraction) 간단하게 적용해보기 개인 프로젝트를 진행하면서 페이지의 공통 부분에 필요한 데이터를 aop로 적용한 부분이 있다. 때문에 자주 바뀌지 않는 데이터지만 지속적으로 실행되는 메서드가 존재했는데 결과 데이터를 캐시에 저장하면 좋을 것 같아서 찾다보니 캐시 추상화(Cache Abstraction)를 지원하는것을 알게 되었다. 그리고 기존에 redis를 세션 클러스터링으로만 사용하고 있었는데 아깝다고 생각하던 찰나였기 때문에 마침 잘된 것같다. Spring Framework에서는 3.1버전부터 투명하게 캐싱기능을 적용하는 캐싱 추상화를 제공했다고 한다. 이는 트랜잭션 처리 처럼 쉽게 적용이 가능하고 4.1 버전에서 크게 확장되었다고 한다. @transactional로 편리하게 트랜잭션 처리를 하는 것 처럼, 캐싱 관련 어노테이션으로..
- 그 외 블럭(block)과 논블럭(non-block), 동기(sync)와 비동기(async) 상당히 어렵고 생각할수록 혼란스러운 주제다. 많이 언급되지만 개념적으로 명확하게 내려진 정의라고 해야할지 획일화된 정의라고 느껴지는 글은 없었고, 다들 나름의 정의 혹은 그저 누군가의 정의를 옮기기만 한 글이었다. 그래서 나도 다른 글들을 많이 읽으며 고심끝에 마찬가지로 나름대로 내가 이해하고 정의한 대로 풀어보려고한다. 때문에 매우매우매우 주관적이고, 다른 글들을 보고 내 글을 보면 더 느낌이 와닿을 수 있다. 간단한 개념 정의 상당히 많은 글들이 블럭/논블럭에서는 제어권, 동기/비동기는 결과값이라는 키워드를 많이 사용하고 있는데 맞는 말이지만, 개인적으로 코드적으로 얘기를 하는게 더 이해하기 쉽다고 생각해서 함수의 입장에서 풀어보려고 한다. 블럭과 논블럭 블럭 보통 함수 A 안에서 다른 함수 B를 호..
- Spring Spring redis session 적용하기 지난 글에 이어서 스프링에 redis lettuce를 적용해봤다. 그래서 이제 서버단에서 redis로 데이터를 관리할 수 있게 되었지만, 사실 목적은 세션데이터를 redis로 클러스터링해서 관리하는것이다. 내 경우 톰캣이 1대여서 로드밸런싱은 필요없지만 서버를 재시작해도 세션이 남아있게 하기 위해 spring-session-data-redis를 활용해 세션또한 redis로 관리하기로 했다. 스프링 문서를 참고해 적용했다. https://docs.spring.io/spring-session/docs/current/reference/html5/#java-servlet-container-initialization Spring Session With the new major release version, the..