학습 관련 질문을 최대한 상세히 남겨주세요! 고민 과정도 같이 나열해주셔도 좋습니다. 먼저 유사한 질문이 있었는지 검색해보세요. 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 강사님 이번에 강의를 구매한 학생입니다. 해당 강의가 실제로 현업에서 사용될 수 있는 방법들인가요? 해당 강의를 수강하고, 이를 바탕으로 프로젝트에 녹여내볼려고 하는데 현업에서 사용하지 않는 방법들이라던가 교육용 강의라면 고민을 좀 해봐야 될 것 같아 문의글 남깁니다 감사합니다.
25/02/26 18:11:20 INFO zookeeper.ZooKeeper: Session: 0x0 closed 25/02/26 18:11:20 INFO zookeeper.ClientCnxn: EventThread shut down 25/02/26 18:11:20 INFO zookeeper.ZooKeeperClient: [ZooKeeperClient] Closed. Exception in thread "main" kafka.zookeeper.ZooKeeperClientTimeoutException: Timed out waiting for connection while in state: CONNECTING at kafka.zookeeper.ZooKeeperClient$$anonfun$kafka$zookeeper$ZooKeeperClient$$waitUntilConnected$1.apply$mcV$sp(ZooKeeperClient.scala:242) at kafka.zookeeper.ZooKeeperClient$$anonfun$kafka$zookeeper$ZooKeeperClient$$waitUntilConnected$1.apply(ZooKeeperClient.scala:238) at kafka.zookeeper.ZooKeeperClient$$anonfun$kafka$zookeeper$ZooKeeperClient$$waitUntilConnected$1.apply(ZooKeeperClient.scala:238) at kafka.utils.CoreUtils$.inLock(CoreUtils.scala:251) at kafka.zookeeper.ZooKeeperClient.kafka$zookeeper$ZooKeeperClient$$waitUntilConnected(ZooKeeperClient.scala:238) at kafka.zookeeper.ZooKeeperClient.<init>(ZooKeeperClient.scala:96) at kafka.zk.KafkaZkClient$.apply(KafkaZkClient.scala:1824) at kafka.admin.TopicCommand$ZookeeperTopicService$.apply(TopicCommand.scala:262) at kafka.admin.TopicCommand$.main(TopicCommand.scala:53) at kafka.admin.TopicCommand.main(TopicCommand.scala) 카프카 토픽생성에서 이런 에러가 뜹니다...
8강 Spring Boot 프로젝트 세팅 2 강의를 반복해서 보고 있습니다. 강의에서는 Multi Module 을 생성하기 위하여 Directory 를 생성하고, build.gradle 파일을 생성한 후 코드 입력 settings.gradle 에 Module 정의를 하시고 계십니다. 인텔리제이에서는 프로젝트에 Module 을 추가하기 메뉴가 있습니다. 인텔리제이 에서 프로젝트에 Module 을 추가하면, 강좌파일의 모듈처럼 생성이 되지 않습니다. project/module1, project/module2 이렇게 1단계 모듈만 작성이 가능합니다. 인터넷 검색자료에도 모듈작성이 1단계방식(에를들어 service-article, service-like)으로 되어 있습니다. 계층구조가 강의 내용이 보기 깔끔하여 따라 해보려 하는데 잘 되지 않습니다 디렉토리를 2단계로 작성( project/service/article)하고 build.gradle 파일을 직접 생성하면 "dependecies" 키워드도 자동안성이 되지 않습니다 인텔리제이 버전은 "IntelliJ IDEA 2024.3.3 (Ultimate Edition)", "Build #IU-243.24978.46, built on February 11, 2025" 입니다 인텔리제이가 버전업이 될때마다 메뉴라던가, 기능이 많이 바뀌기는 합니다만. 조금 답답합니다
안녕하세요 강사님 강의 잘 듣고 있습니다. 댓글 무한 depth 강의를 듣고 있는 도중에, 전부터 궁금했던 내용인데 Repository에 extends JpaRepository를 하면 @Repository를 안 붙여도 되는 걸로 알고 있는데 붙이시는 이유가 따로 있으신지 궁금합니다. https://sudo-minz.tistory.com/147 참고했던 블로그 글입니다!
강사님 안녕하세요. 강의의 테스트 코드도 보고 실무서 테스트 코드 작성시 문득 궁금한 사항이 생겼습니다. 테스트 코드 작성시 단위, 통합, E2E 등 종류도 많고 일정 등 고려해야 될 사항이 많은데 강사님의 테스트 코드 작성 기준이 궁금합니다. 제가 정한 기준은 아래와 같습니다. 단위 테스트 (도메인 폴더 하위 순수 객체) 는 반드시 작성 일정 일정이 급할때 단위 테스트 일정이 여유로울때 단위 테스트 API 테스트 or 통합 테스트 서비스의 핵심 로직 단위 테스트 API 테스트 or 통합 테스트 일정이 급해도 최대한 작성 그리고 다음과 같은 고민도 있습니다. Mockito를 이용한 테스트가 충분히 검증이 될까? 근데 될것 같기도..? XxxFacade 혹은 XxxService에 Mockito를 이용한 테스트의 정확도에 의문을 품었습니다. 그래서 @SpringBootTest를 이용한 통합 테스트 를 작성하였는데 테스트를 위한 데이터 세팅이 너무 귀찮더라구요.(하하하) 그래서 도메인 모델링을 잘하고 단위 테스트를 꼼꼼하게 작성 한다고 쳤을때 Mockiot의 verify를 이용해 의도한 메서드가 호출이 되었는지만 테스트만 해도 괜찮지 않을까? 란 생각이 들었습니다. 회사일도 바쁘실텐데 다음 강의 준비도 하시고 질의응답도 해주셔서 언제나 감사드립니다.
안녕하세요. 만 1년된 작은 중소기업에서 일하고 있는 개발자입니다. 강의 잘 듣고 있습니다! 현재 회사에서는 오라클 데이터베이스를 사용하고 있고 최근 스프링부트와 JPA를 사용해서 프로젝트를 시작했고, 낡은 레거시 사업을 영위하는 업체라서 이게 회사의 첫 스프링부트 프로젝트입니다! 나름 새로운 기술스택을 제안했기에 가지는 부담감이 심한데요. 최근에 만든 거의 대부분의 프로젝트들은 단일 DB를 사용하고 있기 때문에 별다른 고민 없이 AutoIncrement를 선택했습니다. 오라클에서도 최신 버전에서는 잘 지원해주고 있고 DB 버전은 높았기 때문에 이에 익숙해서 JPA에서 지원하는 IDENTITY 전략을 사용해서 시스템을 만들었는데요. 현재 ID를 노출해야하는 상황이 생길 경우 이를 그대로 노출하고 있습니다. 다른 PK 전략을 사용하지 않고 보완할 수 있는 방법이 있을까요? 현재 떠오르는것은 외부로 노출할 때 컨트롤러에서 이를 해싱하거나 난수화를 하는 방법을 생각하고 있습니다. 감사합니다!
2025-02-24 추가) 해당 문제는 psql session 로그인 시도에서 database만 잘 접근하면 문제 없습니다. 강의대로 따라가시면 됩니다. psql -h localhost -U connect_dev -d ${database_name} p.s.) MySQL과 달리, PostgreSQL은 생각한 대로 JDBC Sink Config에서 connection.url 의 첫 번째 파라미터를 데이터베이스 그대로 읽고, table.name.format 옵션에서 구분자 . 을 가지고 스키마와 테이블을 제대로 구분하네요. 제가 인지하지 못한 부분이 있다면 다음 사람을 위해서 댓글 남겨주시면 감사하겠습니다. 안녕하세요 선생님. 이전에 MySQL Sink Config 파일에서 table.name.format 설정하는데 있어서, 데이터베이스 스키마를 바라보지 현상이 발생하여 질문 게시판에 자문자답을 남긴 적이 있습니다. 해당 PostgreSQL도 마찬가지로 JDBC Sink Connector가 해당 search_path를 제대로 읽어오지 못하고 에러가 발생하는 것을 확인했습니다. (모든 프로그램 버전은 강의와 동일합니다.) PostgreSQL도 실습하며 명확해졌네요. DBMS마다 관련 데이터베이스를 자동으로 연결해주는 기능(auto-creation)이 제대로 동작하지 않는 JDBC Sink Connector의 내부적인 문제 같습니다. 또한, 아직 kafka-connect-jdbc/issues/246 이슈가 close되지 않은 것으로 확인했습니다. 다른 해결 방안이 있어서 몇 년이 지나도 내부적으로 수정해주지 않는 것 같습니다... Error log 기존 postgres_jdbc_ops_sink_customers_avro_01.json { "name": "postgres_jdbc_ops_sink_customers_avro_01", "config": { "connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector", "tasks.max": "1", "topics": "mysqlavro-ops-customers", "connection.url": "jdbc:postgresql://localhost:5432/postgres", "connection.user": "connect_dev", "connection.password": "1234", "table.name.format": "ops_sink.customers_sink" 혹여 같은 현상이 발생하신다면, 마찬가지로 connection url 에 직접적인 schema 설정으로 문제를 해결할 수 있습니다. Solved jdbc:postgresql://<host>:<port5432>/<database>?options=-c%20search_path=myschema,anotherschema
7강 > 컨슈머의 안전한 종료에서 컨슈머 애플리케이션의 안전한 종료를 위해서 shutdownThread 을 활용한다고 하셨는데요.. 개념을 설명하실때에는 컨슈머 그룹내 특정 컨슈머에 대한 문제 발생시 wakeup을 통하여 컨슈머를 종료시키고 리밸런싱 하여 특정 파티션이 컨슈머에 다시 할당되는 개념으로 이해를 했는데 실습하는걸 보여주실때는 컨슈머그룹내 특정 컨슈머의 대한 종료가 아닌 전체 어플리케이션에 대한 종료로 보여지는데, 제가 이해한게 맞을까요? 컨슈머 그룹내 n개의 컨슈머에 대한 동작 및 특정 컨슈머의 대한 문제발생시 이를 리밸런싱 하는 예제는 없나요?
현재 카프카를 종료하고 API로 2개의 데이터를 넣고 다시 카프카를 켰을 때, delete 가 동작하지 않습니다. 이전에 카프카를 켜놓은 상태에서 API 2개의 데이터 생성하는 경우는 바로 delete쿼리가 날라갔는데, 지금의 경우 어떤 부분에서 동작하지 않는지 잘 모르겠습니다. 따라서 압축 파일의 outbox-message-relay에 적으신 코드랑도 비교해봤는데, 동일하게 나오고 있습니다. 일단 카프카를 종료하면 다음과 같은 에러가 나오는데, 강사님과 동일한 에러인지 궁금합니다. bernate: insert into article (board_id,content,created_at,modified_at,title,writer_id,article_id) values (?,?,?,?,?,?,?) Hibernate: update board_article_count set article_count = article_count + 1 where board_id = ? Hibernate: select bac1_0.board_id,bac1_0.article_count from board_article_count bac1_0 where bac1_0.board_id=? 2025-02-22T14:21:16.536+09:00 INFO 32925 --- [kuke-board-article-service] [nio-9000-exec-5] k.b.c.outboxmessagerelay.MessageRelay : [MessageRelay.createOutbox] outboxEvent=OutboxEvent(outbox=Outbox(outboxId=151558979476971520, eventType=ARTICLE_CREATED, payload={"eventId":151558979474350080,"type":"ARTICLE_CREATED","payload":{"articleId":151558979451625472,"title":"hi","content":"my content","boardId":1,"writerId":1,"createdAt":[2025,2,22,14,21,16,530575000],"modifiedAt":[2025,2,22,14,21,16,530575000],"boardArticleCount":9}}, shardKey=4, createdAt=2025-02-22T14:21:16.536478)) Hibernate: select o1_0.outbox_id,o1_0.created_at,o1_0.event_type,o1_0.payload,o1_0.shard_key from outbox o1_0 where o1_0.outbox_id=? Hibernate: insert into outbox (created_at,event_type,payload,shard_key,outbox_id) values (?,?,?,?,?) 2025-02-22T14:21:16.694+09:00 INFO 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Node 1 disconnected. 2025-02-22T14:21:16.694+09:00 WARN 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Connection to node 1 (localhost/127.0.0.1:9092) could not be established. Node may not be available. 2025-02-22T14:21:17.547+09:00 ERROR 32925 --- [kuke-board-article-service] [ mr-pub-event-3] k.b.c.outboxmessagerelay.MessageRelay : [MessageRelay.publishEvent] outboxEvent=Outbox(outboxId=151558979476971520, eventType=ARTICLE_CREATED, payload={"eventId":151558979474350080,"type":"ARTICLE_CREATED","payload":{"articleId":151558979451625472,"title":"hi","content":"my content","boardId":1,"writerId":1,"createdAt":[2025,2,22,14,21,16,530575000],"modifiedAt":[2025,2,22,14,21,16,530575000],"boardArticleCount":9}}, shardKey=4, createdAt=2025-02-22T14:21:16.536478) java.util.concurrent.TimeoutException: null at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1960) ~[na:na] at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2095) ~[na:na] at kuke.board.common.outboxmessagerelay.MessageRelay.publishEvent(MessageRelay.java:46) ~[main/:na] at kuke.board.common.outboxmessagerelay.MessageRelay.publishEvent(MessageRelay.java:37) ~[main/:na] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:113) ~[spring-aop-6.1.11.jar:6.1.11] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na] 2025-02-22T14:21:17.695+09:00 INFO 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Node 1 disconnected. 2025-02-22T14:21:17.695+09:00 WARN 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Connection to node 1 (localhost/127.0.0.1:9092) could not be established. Node may not be available. 2025-02-22T14:21:18.697+09:00 INFO 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Node 1 disconnected. 2025-02-22T14:21:18.697+09:00 WARN 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Connection to node 1 (localhost/127.0.0.1:9092) could not be established. Node may not be available. Hibernate: select a1_0.article_id,a1_0.board_id,a1_0.content,a1_0.created_at,a1_0.modified_at,a1_0.title,a1_0.writer_id from article a1_0 where a1_0.article_id=? Hibernate: insert into article (board_id,content,created_at,modified_at,title,writer_id,article_id) values (?,?,?,?,?,?,?) Hibernate: update board_article_count set article_count = article_count + 1 where board_id = ? Hibernate: select bac1_0.board_id,bac1_0.article_count from board_article_count bac1_0 where bac1_0.board_id=? 2025-02-22T14:21:19.531+09:00 INFO 32925 --- [kuke-board-article-service] [nio-9000-exec-7] k.b.c.outboxmessagerelay.MessageRelay : [MessageRelay.createOutbox] outboxEvent=OutboxEvent(outbox=Outbox(outboxId=151558992038912000, eventType=ARTICLE_CREATED, payload={"eventId":151558992036290560,"type":"ARTICLE_CREATED","payload":{"articleId":151558992013565952,"title":"hi","content":"my content","boardId":1,"writerId":1,"createdAt":[2025,2,22,14,21,19,525215000],"modifiedAt":[2025,2,22,14,21,19,525215000],"boardArticleCount":10}}, shardKey=4, createdAt=2025-02-22T14:21:19.531129)) Hibernate: select o1_0.outbox_id,o1_0.created_at,o1_0.event_type,o1_0.payload,o1_0.shard_key from outbox o1_0 where o1_0.outbox_id=? Hibernate: insert into outbox (created_at,event_type,payload,shard_key,outbox_id) values (?,?,?,?,?) 2025-02-22T14:21:19.699+09:00 INFO 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Node 1 disconnected. 2025-02-22T14:21:19.699+09:00 WARN 32925 --- [kuke-board-article-service] [ad | producer-1] org.apache.kafka.clients.NetworkClient : [Producer clientId=producer-1] Connection to node 1 (localhost/127.0.0.1:9092) could not be established. Node may not be available. 2025-02-22T14:21:20.544+09:00 ERROR 32925 --- [kuke-board-article-service] [ mr-pub-event-4] k.b.c.outboxmessagerelay.MessageRelay : [MessageRelay.publishEvent] outboxEvent=Outbox(outboxId=151558992038912000, eventType=ARTICLE_CREATED, payload={"eventId":151558992036290560,"type":"ARTICLE_CREATED","payload":{"articleId":151558992013565952,"title":"hi","content":"my content","boardId":1,"writerId":1,"createdAt":[2025,2,22,14,21,19,525215000],"modifiedAt":[2025,2,22,14,21,19,525215000],"boardArticleCount":10}}, shardKey=4, createdAt=2025-02-22T14:21:19.531129) java.util.concurrent.TimeoutException: null at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1960) ~[na:na] at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2095) ~[na:na] at kuke.board.common.outboxmessagerelay.MessageRelay.publishEvent(MessageRelay.java:46) ~[main/:na] at kuke.board.common.outboxmessagerelay.MessageRelay.publishEvent(MessageRelay.java:37) ~[main/:na] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.11.jar:6.1.11] at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:113) ~[spring-aop-6.1.11.jar:6.1.11] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na] 카프카 종료후 다시 연결해도 폴링은 되는ㄴ데 select만 하고 있고 기존에 outbox에 남아있는 2개의 데이터는 delete처리가 되지 않고 있습니다.
안녕하세요, 강의 잘 듣고 있습니다. "삭제할 댓글이 자식 있으면, 삭제 표시만 한다." 테스트 코드의 내부에서 commentService.delete(commentId); 가 호출되고, delete의 내부에는 댓글이 이미 삭제 됐는지 확인하는 .filter(not(Comment::getDeleterd)) 필터가 존재하는데, getDeleted에 대한 목 객체의 동작은 따로 선언하지 않는 것일까요? (ex) given(comment.getDeleted()).willReturn(false); 답변 주시면 감사하겠습니다.
안녕하세요 강의 잘 듣고 있습니다. 강의랑 버전 맞춰서 실행하고 있는데 delete 메서드는 잘 동작하는데 deleted가 계속 0이네요.. 아래 질문글도 보고 해봤는데 저는 강의 버전이랑 딱 맞춰서 뭐가 문제인지 잘 모르겠습니다!.. 댓글 세 개 다 테스트 해봤는데 테스트는 잘 통과하는데 강의에서는 두번째 댓글부터 Empty Set이라고 나오는데 저는 아래 사진처럼 나옵니다..