묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
ImprovedOrder의 구조에 대한 질문입니다.
우선 orderResponse에서는 totalItems만 사용해서 수량만 요구하는 DTOOrderDetailResponse에서는 List<OrderItemResponse> items; 물품 정보를 요구하는 DTO 용으로 나뉘어 있고 Improved 역시 마찬가지였습니다.그런데 toOrderDetailResponse에서orderItems가 매핑이 안되어 있고, toOrderResponse와 코드가 동일한 상태였습니다. 제 생각에는 totalItems에 집중하신 나머지 빠뜨리신 거라고 생각되어 글을 남기게 되었고, 현재 ImprovedOrder에 orderItem이 매핑되어 있지 않은 상태 즉 반정규화 상태에서 어떻게 OrderItem을 매핑하는게 좋을지 생각해봤습니다.1. orderNumber로 findByOrderNumber단순히 ImprovedOrder에 저장된 orderNumber로 따로 orderItem들을 찾고 매핑해주는 것입니다. 현재 반정규화 의도가 totalCount만을 요구하는 도메인이 중요하기 때문에 ImprovedOrderDetailResponse를 반환할 때만 따로 매핑하는 것이죠. 다만 이는 ImprovedOrder와 OrderItem이 분명한 관계가 있음에도 매핑이 되어 있지 않는 것이라 좋은 방법인지는 의문입니다.2. ImprovedOrder에 orderItem 필드 추가totalItems와 orderItems를 모두 가지게 하고 totalItems만 필요한 상황이라면 굳이 orderItems를 get하지 않으면 Lazy 상태이기 때문에 fetch가 발생하지 않아 유연하게 사용할 수 있지 않을까 생각했습니다.포트폴리오를 위해 분석하던 과정에서 의문이 생겨 질문드렸습니다. 만약 제가 잘못 생각하고 있다면 말씀해주세요.
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
포트폴리오 질문이 있습니다.
포트폴리오에 해당 강의들의 내용을 담으면 정말 좋은 무기가 될 거 같다는 생각이 드는데, 백엔드 포트폴리오에서 웹 디자인 없이 이러한 비지니스 로직들에 대해 고민하고 해결하는 걸 프로젝트라고 해도 괜찮을까요?우선 챕터 2~4 내용을 합쳐서 2,3 내용으로 인터넷 배송 도메인을 동일하게 만든 다음 4내용으로 물건 수량이 50개 남은 경우 100명의 사용자가 몰린 경우 어떻게 처리할 지 확장할 생각입니다.기업 입장에서 실제 웹사이트가 없이 API만을 이용한 대규모 처리, 각종 문제들에 대한 고민과 해결을 인정해주는지, 그것을 프로젝트라고 칭하고 포트폴리오에 담아도 되는지 잘 모르겠습니다 ㅠ
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
후보정 로직에 대해 궁금한 것이 있습니다.
4-12강 스케쥴러를 활용해서 5분마다 누락된 예약번호를 보정하는 방식인데요.만약 이럴 경우 예약 직후 예약정보를 조회하는 사용자 입장에서는 예약번호가 없어서 해당 정보창에 문제가 발생할 거 같은데, 이러면 후보정 방식은 위험한 게 아닐까 하는 의문이 들었습니다.이런 건 지금 따지지 말고 수업용으로 유연하게 넘어가는 게 맞는걸까요?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
키워드 검색 페이징에 대한 Redis 캐시
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.안녕하세요! 강의 잘 들었습니다! 궁금한 점이 있어서 문의 드립니다.강의에서는 상위 1000건에 대해서 articleId를 기준으로 Redis 캐시를 해두었는데 혹시 키워드(제목, 작성자, 내용등)에 대한 검색 페이징 처리도 캐시가 가능한걸까요? 제가 생각했을 때는 아래와 같은 방법으로 처리가 가능할 것 같은데 보통 대용량 트래픽 환경에서 해당 케이스를 어떻게 처리하는지 궁금합니다!키워드 검색이 있을 경우 RDB에서 직접 조회키워드 검색 조건 별로 Redis 캐시Elasticsearch 도입 후 동기화하여 키워드 검색시 Elasticsearch에서 조회
-
미해결개발자라면 알아야 할 redis 기본
key값에 대한 작성 컨벤션
좋은 강의 만들어주셔서 감사합니다. 질문드리고 싶은 내용은 key 값은 아래 처럼 리소스 관점에서 계층 방식, 스네이크 케이스로 작성하는게 일반적인 컨벤션인가요? user:email:1 user:email:{id} user:{id}:refresh_token 아래 강의에서 보여주신 user:email:{id} 은 리프레쉬 토큰의 예시랑 좀 다른 패턴인데, 무슨 차이가 있을까요?
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
노션에 오타가 있는 거 같아요
[4주차] 꼬임을 막는 트랜잭션과 락 전략02.트랜잭션가 ACID7) 초기 DDL & DML 설정1000건인 거 같은데 50만이라고 적혀있어요
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
ArticleLikeRepository 부분에 대한 내용 질문
@Repository public interface ArticleLikeRepository extends JpaRepository<ArticleLike, Long> { // 메서드 이름 기반 쿼리 생성 // JPQL로 암시적으로 생성 해줌 // SELECT a FROM ArticleLike a WHERE a.articleId = ?1 AND a.userId = ?2 Optional<ArticleLike> findByArticleIdAndUserId(Long articleId, Long userId); }보통 Repository 부분 보면 JPQL로방식으로 native쿼리를 통해 db데이터 조회,삭제,추가,업데이트 등등 내용이 많앗는데,, 아래부분은 쿼리를 작성 안해도 명시적인 구현체 없이 메서드 이름 기반 쿼리생성을 통해서 데이터를 조회 할수 있다고 하면 될가요?? 암시적으로 메서드 이름 기반 쿼리 생성은 암시적으로 JPQL이 생성된 상태에서 조회되는건가요?? 혹시 나해서 주석으로 spring document랑 기타 자료를 찾아서 주석문을 추가 했는데, 제가 이해한 부분이 맞나 싶어서 글을 올려봣습니다
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
CRUD test시, localhost:9000 에러가 뜹니다
package kdy.board.article.api; import MSA.board.article.service.response.ArticleResponse; import lombok.AllArgsConstructor; import lombok.Getter; import org.junit.jupiter.api.Test; import org.springframework.web.client.RestClient; public class ArticleApiTest { RestClient restClient = RestClient.create("http://localhost:9000"); @Test void createTest() { ArticleResponse response = create(new ArticleCreateRequest( "hi", "my content", 1L, 1L )); System.out.println("response = " + response); } ArticleResponse create(ArticleCreateRequest request) { return restClient.post() .uri("/v1/articles") .body(request) .retrieve() .body(ArticleResponse.class); } @Getter @AllArgsConstructor static class ArticleCreateRequest { private String title; private String content; private Long writerId; private Long boardId; } @Getter @AllArgsConstructor static class ArticleUpdateRequest { private String title; private String content; } }위와 같이 코드 쓰고 Test를 진행하면 아래와 같은 에러가 뜹니다. cmd창에서 검색해봐도 현재 9000을 쓰고 있는 서버는 없다고 뜨는데 어느 부분이 문제인 건가요?> Task :common:snowflake:compileJava UP-TO-DATE > Task :common:snowflake:processResources NO-SOURCE > Task :common:snowflake:classes UP-TO-DATE > Task :common:snowflake:jar UP-TO-DATE > Task :service:article:compileJava UP-TO-DATE > Task :service:article:processResources UP-TO-DATE > Task :service:article:classes UP-TO-DATE > Task :service:article:compileTestJava > Task :service:article:processTestResources NO-SOURCE > Task :service:article:testClasses org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:9000/v1/articles": null at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.createResourceAccessException(DefaultRestClient.java:575) at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:498) at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.retrieve(DefaultRestClient.java:460) at kdy.board.article.api.ArticleApiTest.create(ArticleApiTest.java:24) at kdy.board.article.api.ArticleApiTest.createTest(ArticleApiTest.java:14) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) Caused by: java.net.ConnectException at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:951) at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:133) at org.springframework.http.client.JdkClientHttpRequest.executeInternal(JdkClientHttpRequest.java:102) at org.springframework.http.client.AbstractStreamingClientHttpRequest.executeInternal(AbstractStreamingClientHttpRequest.java:70) at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66) at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:492) ... 6 more Caused by: java.net.ConnectException at java.net.http/jdk.internal.net.http.common.Utils.toConnectException(Utils.java:1041) at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:227) at java.net.http/jdk.internal.net.http.PlainHttpConnection.checkRetryConnect(PlainHttpConnection.java:280) at java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$2(PlainHttpConnection.java:238) at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934) at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911) at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1773) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583) Caused by: java.nio.channels.ClosedChannelException at java.base/sun.nio.ch.SocketChannelImpl.ensureOpen(SocketChannelImpl.java:202) at java.base/sun.nio.ch.SocketChannelImpl.beginConnect(SocketChannelImpl.java:786) at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:874) at java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$1(PlainHttpConnection.java:210) at java.base/java.security.AccessController.doPrivileged(AccessController.java:571) at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:212) ... 9 more java.net.ConnectException at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:951) at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:133) at org.springframework.http.client.JdkClientHttpRequest.executeInternal(JdkClientHttpRequest.java:102) at org.springframework.http.client.AbstractStreamingClientHttpRequest.executeInternal(AbstractStreamingClientHttpRequest.java:70) at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66) at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:492) at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.retrieve(DefaultRestClient.java:460) at kdy.board.article.api.ArticleApiTest.create(ArticleApiTest.java:24) at kdy.board.article.api.ArticleApiTest.createTest(ArticleApiTest.java:14) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) Caused by: java.net.ConnectException at java.net.http/jdk.internal.net.http.common.Utils.toConnectException(Utils.java:1041) at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:227) at java.net.http/jdk.internal.net.http.PlainHttpConnection.checkRetryConnect(PlainHttpConnection.java:280) at java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$2(PlainHttpConnection.java:238) at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934) at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911) at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1773) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583) Caused by: java.nio.channels.ClosedChannelException at java.base/sun.nio.ch.SocketChannelImpl.ensureOpen(SocketChannelImpl.java:202) at java.base/sun.nio.ch.SocketChannelImpl.beginConnect(SocketChannelImpl.java:786) at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:874) at java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$1(PlainHttpConnection.java:210) at java.base/java.security.AccessController.doPrivileged(AccessController.java:571) at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:212) ... 9 more > Task :service:article:test ArticleApiTest > createTest() FAILED org.springframework.web.client.ResourceAccessException at ArticleApiTest.java:24 Caused by: java.net.ConnectException at ArticleApiTest.java:24 Caused by: java.net.ConnectException at Utils.java:1041 Caused by: java.nio.channels.ClosedChannelException at SocketChannelImpl.java:202 1 test completed, 1 failed > Task :service:article:test FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':service:article:test'. > There were failing tests. See the report at: file:///D:/projects/MSA-board/service/article/build/reports/tests/test/index.html * Try: > Run with --scan to get full insights. BUILD FAILED in 9s 6 actionable tasks: 2 executed, 4 up-to-date
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
댓글 최대 2 depth - 목록 API 구현 조회 테스트 부분
아래코드 첨부 하였구요, readAllInfiniteScroll 부분 secondPage 출력 부분에 getParentCommentId 조건 체크 부분에 진입이 되서 그런지, 부모, 하위 댓글 위치가 다르게 출력 됩니다.강의자료에 있는걸로 이식 해봐도 동일한 증상 나옵니다. 출력 부분은 각 함수마다 하단에 기입 해놨습니다음 그니까, readAll() 부분은 부모, 자식 구분되서 잘나오는데 무한스크롤 부분에서는 기대값은 아래처럼 첫번째 첨부한 기대값과 같아야 하는데 실제 로직에서 출력되는 부분은 다르게 출력 되는거같습니다. 어떤 부분을 확인 해봐야 할가요?? firstPage comment.getCommentId() = 179060865682051072 comment.getCommentId() = 179060867179417600 comment.getCommentId() = 179060867334606848 comment.getCommentId() = 179061928581599232 comment.getCommentId() = 179061929433042944 comment.getCommentId() = 179061929709867008 secondPage comment.getCommentId() = 179065967874379776 comment.getCommentId() = 179065968025374733 comment.getCommentId() = 179065967874379777 comment.getCommentId() = 179065968008597505 @Test void readAll() { CommentPageResponse response = restClient.get() .uri("/v1/comments?articleId=1&page=1&pageSize=10") .retrieve() .body(CommentPageResponse.class); System.out.println("response.getCommentCount() = " + response.getCommentCount()); for (CommentResponse comment : response.getComments()) { if (!comment.getCommentId().equals(comment.getParentCommentId())) { System.out.print("\t"); } System.out.println("comment.getCommentId() = " + comment.getCommentId()); } /** * 1번 페이지 수행 결과 comment.getCommentId() = 179060865682051072 comment.getCommentId() = 179060867179417600 comment.getCommentId() = 179060867334606848 comment.getCommentId() = 179061928581599232 comment.getCommentId() = 179061929433042944 comment.getCommentId() = 179061929709867008 comment.getCommentId() = 179065967874379776 comment.getCommentId() = 179065968025374733 comment.getCommentId() = 179065967874379777 comment.getCommentId() = 179065968008597505 */ } @Test void readAllInfiniteScroll() { List<CommentResponse> responses1 = restClient.get() .uri("/v1/comments/infinite-scroll?articleId=1&pageSize=5") .retrieve() .body(new ParameterizedTypeReference<List<CommentResponse>>() { }); System.out.println("firstPage"); for (CommentResponse comment : responses1) { if (!comment.getCommentId().equals(comment.getParentCommentId())) { System.out.print("\t"); } System.out.println("comment.getCommentId() = " + comment.getCommentId()); } Long lastParentCommentId = responses1.getLast().getParentCommentId(); Long lastCommentId = responses1.getLast().getCommentId(); List<CommentResponse> responses2 = restClient.get() .uri("/v1/comments/infinite-scroll?articleId=1&pageSize=6&lastParentCommentId=%s&lastCommentId=%s" .formatted(lastParentCommentId, lastCommentId)) .retrieve() .body(new ParameterizedTypeReference<List<CommentResponse>>() { }); System.out.println("secondPage"); for (CommentResponse comment : responses2) { if (!comment.getCommentId().equals(comment.getParentCommentId())) { System.out.print("\t"); } System.out.println("comment.getCommentId() = " + comment.getCommentId()); } /** firstPage comment.getCommentId() = 179060865682051072 comment.getCommentId() = 179060867179417600 comment.getCommentId() = 179060867334606848 comment.getCommentId() = 179061928581599232 comment.getCommentId() = 179061929433042944 secondPage comment.getCommentId() = 179061929709867008 comment.getCommentId() = 179065967874379776 comment.getCommentId() = 179065968025374733 comment.getCommentId() = 179065967874379777 comment.getCommentId() = 179065968008597505 comment.getCommentId() = 179065967874379778 */ }
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
테스트코드 실행
2-10 강의에서 테스트코드? 실행하시는데 실행할 버튼이 없습니다.. 어떻게 하죠..?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
LikeApiTest 에서 질문이 있습니다
LikeApiTest 에서 unlike 메서드에 lockType을 추가 하지 않아도 테스트가 깨지지 않은 이유가 궁금한데요.. unlike 메서드에 lockType을 추가하지 않고api를 호출하면 해당 uri경로가 없지 않나요?
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
빌드 시에 테스트 무한로딩
1. 현재 학습 진도몇 챕터/몇 강을 수강 중이신가요?2-4. 프로젝트 설정하기 14:09에 강의 런칭 시점에는 테스트 모두 통과하도록 변경했습니다. 라고 적혀있는데 테스트에서 무한로딩이 걸리길래./gradlew build --info로 띄워 봤습니다.그래서 보니깐 이 로직이 계속 반복되더라구요 그래서 찾아보니여기 while문에 계속 걸리는 거 같은데제가 잘못 세팅한 건가요?강의 앞전에 bootRun해서 http://localhost:8080/api/chapter2/boards까지 접속되는 거 확인했고 도커에서 backend-pass-portfolio 컨테이너에 Db-mysql 만 실행된 채로 build눌렀습니다.
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
hot-article Test 진행 중 좋아요 수 문의
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. [인기글 Producer&Consumer 테스트] 강의 6분 30초에서 좋아요 수는userId는 유니크해야 좋아요 수가 중복없이 하나씩으로 집계된다고 말씀하셨습니다. 근데 비관적 락 방법 1과 2 그리고 낙관적 락 방법 모두 다 저희가 구현할 때,따로 userId에 대한 중복 처리는 하지 않았는데userId는 동일해도 상관 없지 않나 싶어서요. 비관적 락 방법 1 쿼리도 단순 where 조건은 articleId 뿐이라서 질문드려봅니다. 게시글 조회수는 redis로 key 생성할때, articleId와 userId를 활용해서 중복처리는 했는데,게시글 좋아요수는 redis를 활용하지 않아서요!
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
디비 오류
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. mysql 말고 마리아 디비로 진행하고 있는데 다음과 같은 오류가 납니다... java.sql.SQLException: (conn=47) Record has changed since last read in table 'article_like_count' 그래서 인지 count가 일정하지 않네요.. 이유가 있을까요
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
restClinet retrieve() ignore문제
안녕하세요.강의 잘 듣고 있습니다! restClient 사용시에 retrieve ignore로 테스트가 계속 실패 되네요.void인 경우 body(Void.class)하면 됐었는데 likePerformance 하는 경우 실패가 계속 되버려서요. 500에러라면서.body를 제거하고 하면 test 실패이고 해결방법 있을까요?
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
게시글 테스트 데이터 삽입 에서 SQL 최대 2만건 삽입 되는문제
게시글 데이터 삽입 부분에서요, 영상 강의에서는 데이터 1200만건 삽입 하는데 대략 13분 정도 걸리는걸 확인 햇는데, 저는 2초만에 끝나더니 삽입된 갯수 확인해보니까 2만건만 추가 되고 더 추가 안된거같은데 어떤 문제가 있을가요??아래는 코드랑 영상에서 설명한 sql 설정값 첨부 했습니다. @SpringBootTest public class DataInitializer { @PersistenceContext EntityManager entityManager; @Autowired TransactionTemplate transactionTemplate; Snowflake snowflake = new Snowflake(); CountDownLatch latch = new CountDownLatch(EXECUTE_COUNT); static final int BULK_INSERT_SIZE = 2000; static final int EXECUTE_COUNT = 6000; @Test void initialize() throws InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(10); for(int i = 0; i < EXECUTE_COUNT; i++) { executorService.submit(() -> { insert(); latch.countDown(); System.out.println("latch.getCount() = " + latch.getCount()); }); } latch.await(); executorService.shutdown(); } void insert() { transactionTemplate.executeWithoutResult(status -> { for(int i = 0; i < BULK_INSERT_SIZE; i++) { Article article = Article.create( snowflake.nextId(), "title" + i, "content" + i, 1L, 1L ); entityManager.persist(article); } }); } }
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
댓글 신규 path 동시성 이슈
댓글의 path를 설정하는 과정에서 public CommentPath createChildCommentPath(String descendantsTopPath) { if (descendantsTopPath == null) { return CommentPath.create(path + MIN_CHUNK); } String childrenTopPath = findChildrenTopPath(descendantsTopPath); return CommentPath.create(increase(childrenTopPath)); } 이런식으로 findChildrenTopPath를 설정하게 되는데 이 과정에서 동시성 이슈가 발생할 수 있을 것 같아 질문 드립니다. increase하는 함수에서도 동시성 제어를 하는 파트가 없어 동시에 같은 계층의 댓글이 생성되면 id가 겹칠 것 같습니다!
-
해결됨스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판
인기글 Consumer 구현 - 이벤트 핸들러 및 서비스 레이어 강의 질문
학습 관련 질문을 최대한 상세히 남겨주세요!고민 과정도 같이 나열해주셔도 좋습니다.먼저 유사한 질문이 있었는지 검색해보세요.인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.해당 강의 마지막 부분의 handleEventIfScoreUpdatedEventTest()에서given(event.getType()).willReturn(mock(EventType.class));위의 코드로 test하신 이유가 단순히 게시글 생성과 게시글 삭제만 아니면 되어서,그냥 아무 class로 테스트하신게 맞으실까요?? 아래 코드로도 가능하긴 하지만 그냥 게시글 생성과 게시글 삭제만 아니면, test 가능하니로 이해하면 될까요?given(event.getType()).willReturn(EventType.ARTICLE_UPDATED);
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
AWS 환경 인프라 도표에서 private 서브넷 질문 드립니다 !
1. 현재 학습 진도몇 챕터/몇 강을 수강 중이신가요? 2챕터/5강 수강중입니다. 여기까지 이해하신 내용은 무엇인가요? 도커와 모니터링에 대해 전반적인 틀을 이해했습니다.질문 설명에서는 private subnet2에 데이터 베이스 서버를 배포 한다고 하셨는데 아래 도표에서 public서브넷으로 표기 되어있어서 혼동이 있습니다 ! private 서브넷이 맞는건가요 ?
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
2주차 성능테스트 관련 질문입니다.
상황 :같은 테스트를 진행했는데 저는 성능이 너무 안나와서 고민입니다.문제 :이전 개인 프로젝트에서도 클라우드상에서 기본 API 응답 시간이 2초 가량 소요됐었는데, 그 때 당시에는 비지니스 로직이 무거워서 그랬나보나 싶었는데이번 실습에서도 이렇게나 느린 걸 보면 개인 PC의 성능이 안좋은 것 같습니다.(게임도 잘 돌아가고 네트워크도 절대 느린 편이 아닌데 말이죠...)질문 : 이력서에 성능 시간에 관해 쓸 때 잘 만들어진 코드임에도 이렇게 느리면 담당관 입장에서는 "이렇게 느린데 무슨 성능 향상을 했다는거야?" 하는 생각이 들 것 같습니다.실제로 http_reqs가 1.036077/s로 1초에 1명밖에 받지 못하고 있는데, 이 상태로는 이력서에 쓰는게 의미가 없을 거 같아서 어떤 식으로 테스트를 하는 게 좋을지 궁금합니다.아 참고로 이 테스트는 Bad Test 입니다.