안녕하세요. 강의에서 k6를 실행하기 위해 30명의 가상유저가 10초동안 요청을 무한히 보내도록 설정하셨습니다. 그 결과 http_reqs 값이 1.66/s 가 나왔습니다. 이 값은 시스템의 대역폭 max값으로 이해해도 되나요? 30명, 10초 설정값이 아니더라도 100명, 10초 설정값으로 진행해도 1.66/s 에 근사한 값이 나와야하는지 궁금합니다. (시스템이 처리할 수 있는 능력 의 Maximum은 항상 일정해야하지 않을까 라는 생각에 질문드립니다.)
안녕하세요! 수업 잘 듣고 저희 서비스에서 테스트를 해보고 있습니다. duration 3m, target 500 으로 테스트를 해보았는데, 46TPS 정도 에서 병목이 생긴걸로 파악 했습니다. 다만 메트릭들을 확인해보니, ec2 메모리 사용률은 46% 정도고, CPU 사용율도 58% 정도며, DB 의 메모리도 충분히 남아있고, CPU 사용율도 59%정도로 여유가 있어보이는데요, 이 메트릭 외에도 병목을 확인할 수 있는 메트릭이 있을까요? 예시로 보여주셨던 걸로는 100% 에 가깝게 수치가 튀어야할거 같은데, 그정도가 아닌 상태에서 병목이 발생해서요!
GenericJackson2JsonRedisSerializer를 사용할 때 저장되는 캐싱 데이터는 다음과 같았습니다. "[{\"@class\":\"org.example.package..\",\"id\":\"123984\",\"title\":\"title0123984\",..., 강의상에 나온 데이터 순서?? 와는 조금 다르게 package 다음에 @class 이후 데이터가 저장되는 구조가 나오는 것을 확인했습니다. 이때 캐싱된 데이터를 조회하려고 하는데 com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected VALUE_STRING: need String, Number of Boolean value that contains type id (for subtype of java.lang.Object) 에러가 발생했습니다. 너무 궁금해서 GenericJackson2JsonRedisSerializer에 대해서 알아보고 있는데, 여전히 에러가 발생하는 이유를 잘 모르겠습니다ㅜㅜ 데이터가 캐싱되어서 저장될 때 구조가 다르게 들어가는 이유가 궁금합니다 아 물론 강의 후반부처럼 Jackson2JsonRedisSerializer를 사용했을 때는 정상적으로 동작했습니다.
안녕하세요 레디스를 공부하면서 궁금한게 있습니다. 제가 토이프로젝트를 하면서 상품 검색 입력시 버튼 하나씩 누를때마다(이벤트 keyup 사용) 백엔드와 통신하여 입력창 하단에 자동완성 기능창을 만들려고 하고 있습니다. 아무래도 버튼 하나씩 누를때마다 통신해야되니 빠르게 통신해야될 것 같아서 redis를 사용했습니다. 상품 등록할 때 DB와 redis에 저장하고 (redis에는 상품 이름만 저장했습니다.) 입력창 하단의 자동완성은 redis를 통해 상품 이름을 출력하고 출력된 상품이름을 선택시 DB를 통해서 상품 상세정보를 가져오는 식으로 했는데 배운대로라면 Cache Aside 전략과 다른데 이럴때는 어떻게 구성해야되나요? 아니면 SQL 튜닝만 잘해도 굳이 redis는 필요없는건지 궁금합니다. 아무래도 버튼 누를때마다 통신하다보니 SQL은 느릴까봐 싶어 조바심이 나네요ㅠㅠ 알아보니 최근검색어나 인기검색어 같은 경우도 redis로 한다고하는데 이런것들도 굳이 출력하자면 DB로만 사용하여 출력이 될텐데 이게 Cache Aside 전략과 어떤 관계가 있는지 감이 안잡힙니다 실무뛰면서 redis를 써본적이 없고 거의 db로만 해결하다보니 redis 사용예시를 잘 모르겠습니다
안녕하세요. 강의 잘 들었습니다. 강의를 듣다보니 의문이 드는 점이 있어 질문드립니다. redis를 사용하다 보면 redisinsight같은 gui 툴을 통해 데이터를 확인하는데 운영관점에서 더 편한데요. aws elasticcache redis가 외부 로컬에서 접속이 안되면 aws elasticcache는 데이터 확인을 툴로 못하는건가요? 실무에서 운영을 하다보면 분명 직접 데이터를 체크를 해야하는 케이스가 발생하는데 이걸 일일이 cli 명령어 찾는다는 것은 돈을 주고 aws 사용하는 고객입장에서는 너무 불편하다고 생각들어 문의드립니다.
로컬에서 docker compose up --build -d 명령어 실행 시 아래와 같은 에러가 발생합니다. Cannot connect to the Docker daemon at unix:///Users/milaju/.docker/run/docker.sock. Is the docker daemon running? 따로 설정을 해줘야 하는 부분이 있을까요?
# 스프링 프로젝트 경로로 들어가서 아래 명령어 실행 $ ./gradlew clean build -x test $ cd build/libs $ java -jar -Dspring.profiles.active=prod {빌드된 jar 파일명} 서버 실행시키기 명령어 단계에서 $ java -jar -Dspring.profiles.active=prod {빌드된 jar 파일명} 실행 시 ec2 터미널 창에서 아래와 같은 에러가 발생하게 됩니다. 현재 jar 파일은 그림과 같이 생성되었고 명령어는 java -jar -Dspring.profiles.activate=prod demo-0.0.1-SNAPSHOT.jar 이렇게 진행하였습니다. Failed to initialize JPA EntityManagerFactory: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided) 2024-10-03T16:57:37.160Z WARN 5523 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided) 2024-10-03T16:57:37.166Z INFO 5523 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat] 2024-10-03T16:57:37.213Z INFO 5523 --- [ main] .s.b.a.l.ConditionEvaluationReportLogger : Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. 2024-10-03T16:57:37.243Z ERROR 5523 --- [ main] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1806) ~[spring-beans-6.1.13.jar!/:6.1.13] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.13.jar!/:6.1.13] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.13.jar!/:6.1.13] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.13.jar!/:6.1.13] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.13.jar!/:6.1.13] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.13.jar!/:6.1.13] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205) ~[spring-beans-6.1.13.jar!/:6.1.13] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:954) ~[spring-context-6.1.13.jar!/:6.1.13] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) ~[spring-context-6.1.13.jar!/:6.1.13] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.3.4.jar!/:3.3.4] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.3.4.jar!/:3.3.4] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.3.4.jar!/:3.3.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.4.jar!/:3.3.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.4.jar!/:3.3.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.4.jar!/:3.3.4] at com.example.demo.DemoApplication.main(DemoApplication.java:10) ~[!/:0.0.1-SNAPSHOT] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na] at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:102) ~[demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64) ~[demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40) ~[demo-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided) at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:276) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.boot.model.relational.Database.<init>(Database.java:45) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:221) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:189) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:171) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1431) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1502) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) ~[spring-orm-6.1.13.jar!/:6.1.13] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:390) ~[spring-orm-6.1.13.jar!/:6.1.13] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.1.13.jar!/:6.1.13] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.1.13.jar!/:6.1.13] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366) ~[spring-orm-6.1.13.jar!/:6.1.13] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853) ~[spring-beans-6.1.13.jar!/:6.1.13] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1802) ~[spring-beans-6.1.13.jar!/:6.1.13] ... 22 common frames omitted Caused by: org.hibernate.HibernateException: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided) at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:191) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:87) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentWithDefaults(JdbcEnvironmentInitiator.java:153) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final] at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:364) ~[hibernate-core-6.5.3.Final.jar!/:6.5.3.Final]
안녕하세요? 끝까지 강의를 들었는데, 알차고 재미있는 강의였습니다. 강의를 보다보니 레디스를 사용해도 성능적인 차이가 많이 안나는 것을 보고 궁금한 점이 있어서 질문드립니다. 사실 주변에서 캐시로 레디스를 무조건적으로 사용을 하시는 경우를 많이 봤는데요, 제가 생각할때는 결국 I/O대기시간이 일반적인 api에서 큰 부분을 차지하고, 결국 레디스라는 것도 IO를 기다려야 하는 것은 동일하지 않나요? 그렇게 따지고 보면 강의에서 보여주신 것처럼 레디스를 사용하더라도 성능적 차이가 많이 안나는 경우가 꽤나 빈번할 것 같은데, 강사님의 의견이 궁금합니다. 레디스 내에서 해시값을 기반으로 데이터를 조회하는 속도야 빠르겠지만, 애초에 요청받았을 때 수행해야하는 [작업] 그 자체의 비중보다 [IO]를 대기하는 시간이 큰 경우가많은, 예를 들면 DB에서 단순히 레코드한줄을 조회한다든지 하는 기능이라고 하면 레디스를 쓰는 건 비용까지 고려했을 때 굳이 할 필요가 없는 선택처럼 느껴집니다. 결국 레디스는 IO보다 요청에 따라 수행해야 하는 작업 그자체의 크기가 조금 클때 그제서야 유의미해 보이는데 어떻게 생각하시는지 의견이 궁금합니다! 추가로 강의 잘들었습니다. 혹시 다음 강의는 언제쯤 출시할 예정이신지 알 수 잇을까요?
안녕하세요? 강의쭉 잘 듣고 있습니다. 강의에서 말씀해주시고자 하는 부분은 [IO대기시간이 있는 작업을 비동기로 돌려서 클라이언트쪽에 우선응답을 빠르게 주고, 나머지는 따로 알아서 처리하는 것]으로 이해했습니다. 말씀해주신 방법은 충분히 사용할 수 있는 방법이라고 생각합니다. 그런데 조금 논외로, 이렇게 분리하는 방식이 좋은 방향성인가?에 대해서 궁금증이 생기고 사실 이 부분에 대해 최근 현업에서도 꽤 고민하고 있어서 질문을 드립니다. 아무래도 쪼렙 주니어개발자다보니.. 이런 부분에서 부족함과 의문이 많이 있네요 ㅠㅠ 제 생각에, 단축 url을 만드는 api가 200을 내려준다고하면 저장까지 올바르게 완료됨을 전제해야한다고 생각합니다. 이렇게 생각하는 이유는, 단축 url을 저장하는 것까지가 일종의 핵심적인 로직에 포함되지 않나? 하는 생각입니다. 예를 들어 로그를 찍거나, 혹은 비즈니스로직이여도 그렇게 중요하지 않은 부분이라면 마음편하게 완료를 보장하지 않는 async로 돌려도 될것 같습니다. 하지만 url저장처럼 핵심적인 로직에 관한 부분에 대해서는 200을 내려줄 거면 저장도 올바르게 보장되어야 하지 않나? 하는 생각이 듭니다. 다르게 말하면, 내려준 단축 url이 정상적으로 동작하지 않는데 200을 내려줘도 되나? 에 대한 궁금증입니다.(물론 핵심적인 로직에 대한 판단은 개개인마다 또 상황마다 다를 수 있지만요) 결론적으로 여쭤보고 싶은 부분은 아래와 같습니다 1) 비동기로 나누는 부분의 기준이 강사님에게 있으실 것 같은데, 보통 어떤 기준으로 나누시나요? 2) 추가로, 핸들링을 어떤식으로 하시는지도 궁금합니다. 예를 들면 위와 같이 저장하는 로직을 비동기로 뺏을 때, 실패한다면 보통 어떤식으로 핸들링을 하시나요?
안녕하세요 강의 잘 듣고 있습니다! You have requested more vCPU capacity than your current vCPU limit of 1 allows for the instance bucket that the specified instance type belongs to. Please visit http://aws.amazon.com/contact-us/ec2-request to request an adjustment to this limit. <EC2, RDS, Spring Boot, Redis 셋팅> 강의 중 t3s.small 로 인스턴스를 설정하려 하는데 위와 같이 문구가 나오면서 '인스턴스 시작 실패'가 떴습니다. 할당량 증가 요청을 보내기 위해 ' 새 할당량 값'을 넣어야 되는데 얼마를 넣어야 되는지 알 수 있을까요?
안녕하세요, 좋은 강의 감사합니다. Spring Boot 에서 Redis 세팅 추가하는 편에서, CacheManager 를 하나만 등록해서 사용하고 있습니다. 그리고 이를 활용하는 API 가 1개 뿐인데, 이름이 boardCacheManager 로 정확히 Board 도메인에 대한 전용 CacheManager 인 것처럼 보입니다. 도메인 별로 CachaManager 를 각각 만들면서 사용을 하는 게 좀 더 바람직한 방법인가요? 만약 그렇다면, 각 도메인 별로 설정을 관리하고 유지보수성을 높이기 위함인가요? 만약 CachaManager 를 도메인 별로 값이나 타입을 다르게 적용하지 않고 프로젝트 전체에 대해서 동일하게 적용을 하기로 결정했다면, 그때에도 CacheManager 를 각각 적용해야 할 이유가 혹시 있을까요? 인터넷 기사나 블로그 등에서는 이렇게도 하고 저렇게도 하는 것 같습니다. 선생님의 의견이나 또 실무 상의 고려사항이 있는지 궁금합니다.