묻고 답해요
148만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실습으로 배우는 선착순 이벤트 시스템
레디스 적용 시 여러번응모 테스트에서 에러가 발생합니다.
@SpringBootTest class ApplyServiceTest { @Autowired private ApplyService applyService; @Autowired private CouponRepository couponRepository; @Test public void 한번만응모() { applyService.apply(1L); long count = couponRepository.count(); assertThat(count).isEqualTo(1); } @Test public void 여러번응모() throws InterruptedException { int threadCount = 1000; //ExecutorService : 병렬 작업을 간단하게 할 수 있게 도와주는 Java API ExecutorService executorService = Executors.newFixedThreadPool(32); // CountDownLatch : 다른 Thread에서 수행하는 작업을 기다리도록 도와주는 클래스 CountDownLatch latch = new CountDownLatch(threadCount); for (int i=0; i<threadCount; i++) { long userId = i; executorService.submit(() -> { try { applyService.apply(userId); } finally { latch.countDown(); } }); } latch.await(); long count = couponRepository.count(); assertThat(count).isEqualTo(100); } }@Service public class ApplyService { private final CouponRepository couponRepository; private final CouponCountRepository couponCountRepository; public ApplyService(CouponRepository couponRepository, CouponCountRepository couponCountRepository) { this.couponRepository = couponRepository; this.couponCountRepository = couponCountRepository; } public void apply(Long userId) { Long count = couponCountRepository.increment(); System.out.println("count : "+count); // long count = couponRepository.count(); if (count > 100) { return; } Coupon save = couponRepository.save(new Coupon(userId)); System.out.println("save! : "+save.getId()); } }@Repository public class CouponCountRepository { private final RedisTemplate<String, String> redisTemplate; public CouponCountRepository(RedisTemplate<String, String> redisTemplate) { this.redisTemplate = redisTemplate; } public Long increment() { try { return redisTemplate .opsForValue() .increment("coupon_count"); } catch (Exception e) { e.printStackTrace(); throw e; } } }여러번응모 테스트 케이스 실행CouponCountRepository.java의 increment 메서드에서 다음과 같은 에러가 발생하고 있습니다.제일 처음에 나는 에러메시지는 다음과 같습니다.Caused by: io.lettuce.core.RedisCommandExecutionException: MISCONF Redis is configured to save RDB snapshots, but it's currently unable to persist to disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.쿠폰도 정상적으로 등록되지 않아 아에 0개로 출력되고 있습니다.구글링을 해봤지만 도저히 원인을 찾을 수가 없어요 ..++추가로, 도커에서 레디스 컨테이너와 이미지를 삭제한 후 실행해도 동일한 결과가 나타나는 것을 확인됩니다.강의에서 나온 그대로 도커 명령어를 사용해서 레디스를 pull 하였는데 왜 컨테이너와 이미지를 삭제해도 동일한 오류가 발생하는 걸까요?도커에서 레디스 컨테이너와 이미지를 삭제하고 ApiApplication을 실행하면 정상적으로 실행됩니다...++ 정리 드리자면, 1. 강의를 그대로 따라했는데 RedisCommandExecutionException가 발생하면서 테스트 케이스를 실행할 수 없는 이유2. 강의에서 나온 그대로 도커 명령어를 사용해서 레디스를 pull 하였는데 왜 컨테이너와 이미지를 삭제해도 동일한 오류가 발생하는 이유3. 도커에서 레디스 컨테이너와 이미지를 모두 삭제하고 ApiApplication를 실행했을 때 정상적으로 실행되는 이유답변 부탁드립니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
yarn add @apollo-server 405 에러...
설치하려하는데 405 에러 나오네요....검색해서 나오는것도 몇가지 해보긴했는데...해결이 안되서 올려봅니다~## 에러메시지Error: https://registry.npmjs.org/@apollo-server: Request "https://registry.npmjs.org/@apollo-server" returned a 405
-
미해결실습으로 배우는 선착순 이벤트 시스템
redis 설정 시 application.yml을 수정하지 않는 이유
안녕하세요 강사님.spring-data-redis 의존성을 추가하여 디펜전시 받고couponcountrepository.java를 생성하였습니다.보통 yml 파일에 redis 관련 설정도 해주는 것으로 알고있었는데 강의에서는 따로 yml에 redis 설정을 하지 않아서요.redis 설정을 안해준다면 어플리케이션에서 어떻게 redis와 연결될 수 있는지.. 궁금합니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
next-auth 로그인 시 unauthorized 문제
문제가 몇일째 안풀리는게 있어 문의드려요제가 next-auth를 사용해서 로그인 프로세스를 해보고 있습니다.로컬에서 별도로 배포환경 만들어서 테스트를 했을 때에는 잘 되는데 배포시에 계속 Unauthorized 에러가 발생해서요제가 작성한 [...nextauth].ts 코드입니다.import NextAuth, { User } from 'next-auth'; import CredentialsProvider from 'next-auth/providers/credentials'; import { refreshAccessToken } from 'utils/tokenRefresh'; export default NextAuth({ providers: [ CredentialsProvider({ name: 'Credentials', credentials: { userId: { label: 'UserId', type: 'text', placeholder: 'jsmith' }, password: { label: 'Password', type: 'password' }, }, authorize: async (credentials) => { const res = await fetch(`${process.env.NEXT_PUBLIC_BACKEND_URL}/api/v1/users/signin`, { method: 'POST', body: JSON.stringify({ userId: credentials!.userId, password: credentials!.password, }), headers: { 'Content-Type': 'application/json' }, }); const user = await res.json(); // 로그인 성공 시 사용자 객체를 반환하고, 실패 시 null을 반환 if (res.ok && user) { console.log('ok user', user); return user; } else { console.log('error user', user); return false; } }, }), ], secret: process.env.NEXTAUTH_SECRET, // session: { // strategy: 'jwt', // maxAge: 0, // 브라우저가 닫히면 세션 종료 // // updateAge: 24 * 60 * 60, // 24시간마다 세션 갱신 (옵션) // }, callbacks: { async jwt({ token, user }) { // 사용자 로그인 시 토큰 설정 if (user) { return { ...token, accessJwt: user.result?.accessJwt, refreshJwt: user.result?.refreshJwt, companyId: user.result?.companyId, userName: user.result?.userName, accessTokenExpires: Date.now() + 3600 * 1000, }; } // 토큰 만료 확인 및 리프레시 if (Date.now() > token.accessTokenExpires!) { const newAccessJwt = await refreshAccessToken(token.refreshJwt!); return refreshAccessToken(newAccessJwt); } return token; }, async session({ session, token }) { if (token && token.accessJwt) { const customUser = session.user as User; if (!customUser.result) { customUser.result = { accessJwt: '', refreshJwt: '', companyId: '', userName: '', }; } customUser.result.accessJwt = token.accessJwt; customUser.result.refreshJwt = token.refreshJwt; customUser.result.companyId = token.companyId; customUser.result.userName = token.userName; session.user = customUser; } return session; }, }, }); NEXT_PUBLIC_BACKEND_URL 환경변수는 별도의 백엔드를 구성한 주소이구요 배포는 도커를 사용했습니다.FROM node:20.10 as builder # pnpm 설치 RUN npm install -g pnpm WORKDIR /usr/src/app COPY package*.json ./ RUN pnpm install ARG NEXT_PUBLIC_BACKEND_URL ARG NEXTAUTH_SECRET COPY . . RUN NEXT_PUBLIC_BACKEND_URL=https://${NEXT_PUBLIC_BACKEND_URL} NEXTAUTH_SECRET=${NEXTAUTH_SECRET} pnpm run build FROM node:20.10 RUN npm install -g pnpm WORKDIR /usr/src/app COPY --from=builder /usr/src/app/package*.json ./ RUN pnpm install --prod COPY --from=builder /usr/src/app . # COPY --from=builder /usr/src/app/.next ./.next EXPOSE 3000 CMD ["pnpm", "run", "dev"]NEXTAUTH_SECRET은 프론트 주소를 도커 실행 시 넣어줘야 한대서 도커 실행 할 때 환경변수로 따로 넣어줬구요Docs, Stackoverflow, ChatGPT 등 여러 방면으로 찾아봤는데 해결이 안되더라구요..강의하고는 별개 내용이긴 한데 더이상 물어볼 데가 없어서 강사님께 여쭈어봅니다..
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
Github
터미널에 'git push origin master'를 입력하고 엔터를 누르면fatal: 'origin' does not appear to be a git repositoryfatal: Could not read from remote repository.Please make sure you have the correct access rightsand the repository exists. 이렇게 나와고 있어요. 어디서 실수했어요?
-
미해결따라하며 배우는 도커와 CI환경 [2023.11 업데이트]
여러 컨테이너에서 동일 컨테이너를 공유할땐 어떻게 구성해야하나요?
안녕하세요. 여러 마이크로서비스에서 동일한 db를 공유할 경우는 어떻게 구성하는지 궁금합니다.일단 동일 network로 db컨테이너와 마이크로서비스 컨테이너를 run하고 실행한 컨테이너명으로 요청하도록은 알겠는대 docker compose를 이용해서 여러 마이크로서비스가 같은 db 컨테이너를 어떻게 참조할 수 있는지 궁금합니다.
-
미해결쉽게 시작하는 쿠버네티스(v1.30) - {{ x86-64, arm64 }}
노드 IP접근 관련 문의 (2.2 강의 관련)
2.2.파드를 외부에서도 접속하게 하는 서비스(Service)강의에서 궁금한 사항이 있습니다.해당 강의에서 nginx는 w3-k8s 노드(103)에만 생성이 되어 있는데요. service 테스트는 w1-k8s의 IP(101)로 테스트 하는것을 보았습니다. 다른 노드에서도 해당 IP로 접근이 가능한 건가요?
-
해결됨파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트
simple-jwt Refresh Token 사용 노하우
안녕하세요. 진석님!강의에서 알려주신 drf-jwt 말고, 다른 수강생분이 문의한 글에서 보니 simple-jwt도 있다고 하셔서 doc 읽어보면서 토큰 적용해보고 있는데요. 로그인 성공하면 access / refresh 토큰 발행되고, access 토큰이 만료되면 refresh 토큰으로 access 토큰을 재발행해야 한다고 이해했습니다. (refresh 토큰 만료기한도 장고 설정값 있는 것 확인했구요!) 궁금한점은.. access 토큰을 갱신하는 방향이 크게 두 가지 일 것 같은데, 어떤식으로 가야하는 걸까요?1) useEffect 훅 안에서 setInterval로 주기적 갱신2) 강의에서 만들어주신 useAppContext 안에서 토큰 만료여부 확인 후 명시적 갱신 3) 다른방법
-
미해결AWS 배포 완벽가이드 (feat. Lightsail, Docker, ECS)
Workflow 작성시 npm install 문제
name : SSH and deployrun : | ssh ...run 스크립트 안의 npm install 실행시 command not found 라고 뜹니다. 근데 LightSail SSH 접속해서 다 확인해봤을 때, npm, npx 모두다 정상적으로 설치가 되어있는데 혹시 다른 문제가 있는걸까요?
-
미해결대세는 쿠버네티스 [초급~중급]
externalTrafficPolicy 질문입니다.
apiVersion: v1 kind: Service metadata: name: svc-2 spec: selector: app: pod ports: - port: 9000 targetPort: 8080 nodePort: 30001 type: NodePort externalTrafficPolicy: Localkind: Service apiVersion: v1 metadata: name: svc-2 namespace: default uid: fb123857-fa60-42d3-ab9c-f03a1a7b6348 resourceVersion: '814181' creationTimestamp: '2023-11-27T12:38:12Z' managedFields: - manager: dashboard operation: Update apiVersion: v1 time: '2023-11-27T12:38:12Z' fieldsType: FieldsV1 fieldsV1: f:spec: f:externalTrafficPolicy: {} f:internalTrafficPolicy: {} f:ports: .: {} k:{"port":9000,"protocol":"TCP"}: .: {} f:nodePort: {} f:port: {} f:protocol: {} f:targetPort: {} f:selector: {} f:sessionAffinity: {} f:type: {} spec: ports: - protocol: TCP port: 9000 targetPort: 8080 nodePort: 30001 selector: app: pod clusterIP: 10.100.174.243 clusterIPs: - 10.100.174.243 type: NodePort sessionAffinity: None externalTrafficPolicy: Local ipFamilies: - IPv4 ipFamilyPolicy: SingleStack internalTrafficPolicy: Cluster status: loadBalancer: {} 워커 2번 주소로 반복적으로 실험해봤는데 워커노드가 2개가 번갈아서 나오는게 정상적인건지 확인차 질문드려봅니다.워커 1번 주소로는 pod-1만 노출이 되고있습니다.워커 2번 주소도 마찬가지로 pod-2만 응답해야되는게 아닌가요?
-
해결됨쥬쥬와 함께 하루만에 시작하는 백엔드 - 스프링, 도커, AWS
docker에 관하여 질문 드립니다.
안녕하세요 우선 끝까지 강의 잘들었습니다!!! docker 부분이 아직 익숙하지 않아 질문드립니다docker를 따라 설치하니 저장소 같은 곳에 이미지가 저장되는 것을 확인하였습니다.해당 이미지를 aws 인스턴스에서 받아서 바로 사용할 순 없는건가요? -> 굳이 git clone으로 프로젝트를 받아와야 하는지 궁금합니다 / docker 저장소에 이미지를 올리고 바로 받아서 실행하면 되는게 아닌가 싶어서 질문드립니다...2.가 만약 틀린거라면 build/libs에 있는 파일이 직접적으로 실행을 시키면서 애플리케이션이 실행되는 것 같은데 이 이미지를 굳이 docker 저장소에 올리는 이유가 궁금합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
AccessToken은 잘 만들어지는데 payload에 아무것도 안담겨요
로그인 시 받은 accesstoken을 밑에 /user/test의 헤더에 넣었습니다.처음에는 payload에 값이 담겼는데 갑자기 아무것도 안담기네요ㅜㅜ변경사항이 있었던 건 다 돌려봤는데도 도저히 뭐가 문제인지 모르겠어서 남깁니다.뭐가 문제인지도 모르겠어서 코드도 뭘 보여드려야 할 지 모르겠네요ㅜㅜ accesstoekn은 잘 만들어지는데.. 저 accesstoekn으로 UseGuards(AuthGuard('access')) 이 가드를 통과하는 거 아닌가요?validate()까지 간 거 보면 인가는 됐다고 생각했는데 왜 payload에 아무것도 안담기는지 모르겠네요ㅜㅜ
-
해결됨쥬쥬와 함께 하루만에 시작하는 백엔드 - 스프링, 도커, AWS
DTO, Request, Response 차이점
질문이 너무 짧아서 죄송하지만... 제목 그대로 3가지 쓰임의 차이점을 알고 싶습니다. 언제 어떤것을 사용해야 하는지 잘모르겠네요...
-
미해결대세는 쿠버네티스 [초급~중급]
vagrant up 수행시 404 에러가 발생 하네요.
https://vagrantcloud.com/rockylinux/boxes/8/versions/8.0.0/providers/virtualbox/unknown/vagrant.box 해당 url에서 404오류가 발생 되어 진행이 되지 않네요.
-
미해결실습으로 배우는 선착순 이벤트 시스템
코드 제공
혹시 전체 코드를 받아볼 수 있는 리포지토리가 있을까요?
-
미해결따라하며 배우는 도커와 CI환경 [2023.11 업데이트]
도커에서 NginX 이미지 사용시 CMD로 nginx start가 없는 이유
[섹션 6 : 운영환경 도커 이미지를 위한 Dockerfile 작성하기]에서 도커에서 NginX 이미지 실행시, CMD로 nginx start를 Dockerfile에 작성하지 않았는데요.리액트의 경우 Dockerfile에서 CMD 로 'npm run start' 를 사용 했었는데, nginx의 경우에는 CMD 없이 도커를 실행하기만 하면 자동시작이 맞는건지 궁금합니다.
-
해결됨쥬쥬와 함께 하루만에 시작하는 백엔드 - 스프링, 도커, AWS
TestRepositoryImpl 질문이요
where(QTestEntity.testEntity.name.eq(name)과 같이조건을 넣어줘야되지 않나요..?
-
해결됨그림으로 배우는 쿠버네티스(v1.30) - {{ x86-64, arm64 }}
IP가 변경되는 것에 대해서 질문이 있습니다.
질문 답변을 제공하지만, 강의 비용에는 Q&A는 포함되어 있지 않습니다. 다만 실습이 안되거나, 잘못된 내용의 경우는 알려주시면 가능한 빠르게 조치하겠습니다![질문 전 답변]1. 강의에서 다룬 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 법을 읽어보셨나요? 예(https://www.inflearn.com/blogs/1719)4. 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.5. vagrant up 에서 발생하는 문제는 주로 호스트 시스템(Windows, MacOS)과 연관된 다양한 조건에 의해 발생합니다. 따라서 이를 모두 제가 파악할 수 없어서 해결이 어렵습니다. vagrant up으로 진행이 어렵다면 제공해 드리는 가상 머신(VM) 이미지를 import해서 진행하시기 바랍니다. (https://www.inflearn.com/questions/992407/comment/281901)6. ARM 계열의 m1 , m2 계열은 VirtualBox를 통한 구성이 원할하지 않고, 실습 환경의 다변화는 추후 대처하기 어려워서 현재 과정에서는 지원하지 않습니다. (https://www.inflearn.com/questions/915529)[질문 하기]안녕하세요! 명강의 잘 듣고있습니다 :)4.4 로드밸런서 파드에서의 질문입니다.로드밸런서는 사실 내부적으로 nodePort가 동작하므로 노드 포트로 접속하고자 하는 노드들 中 1택을 할 때 RR과 같은 트래픽 분산정책이 사용된다고 알고있습니다. 서비스 내부로 도착해서 파드에 트래픽이 분배될 때 또한 트래픽 분산정책이 발생하고요. 따라서 로드밸런서를 사용할 경우, <접속할 노드 중 1택>을 결정할 때 트래픽이 한번 분산되고, 내부의 서비스에 도착해서 파드에 접속할 때 트래픽이 분산되는, 총 2번의 트래픽 분산이 수행되는 것으로 알고있습니다. [질문]질문은 아래와 같습니다.현재 실습에서 접속되는 파드의 IP가 "지속적으로 변경되는 것"은 직접적으로 보았을 때 서비스에서 파드에 접속할 때의 트래픽 분산에 의한 것인가요?
-
해결됨AWS 배포 완벽가이드 (feat. Lightsail, Docker, ECS)
ECS Deployment Circuit Breaker was triggered
안녕하세요 계속 질문만남기는 것 같아 죄송합니다.섹션 10. AWS Elastic Container Service (ECS) 자세히 알아보기!에서 ECR private repository 이미지로 AWS ECS service 생성하기 강좌를 따라하고 있는데요앞강좌에서 local 에서 도커 이미지 push 까지 완료하고 해당 강좌도Task definition 까지 생성을 잘 완료 하였습니다.하지만 서비스 생성중에강좌대로 똑같이 서비스를 생성후 서비스 생성 클릭을 눌렀는데요해당 에러가 나와서 CloundFormation 에서 보기 버튼을 눌러서 확인해보니깐Resource handler returned message: "Error occurred during operation 'ECS Deployment Circuit Breaker was triggered'." (RequestToken: c1e2037e-83e2-33f1-1337-2b3ffd4347aa, HandlerErrorCode: GeneralServiceException) 검색을 해봐도 정확히 나오지가 않아서다시 서비스 생성해도 동일한 에러가 나오네요혹시 더 디테일한 로그를 보는방법이나해결방법을 알 수 있을까요?
-
미해결AWS 배포 완벽가이드 (feat. Lightsail, Docker, ECS)
nginx와 app 연결 (ECS 내에서)
안녕하세요 강사님강사님께서는 강의에서 어플리케이션을 80포트에 배포해 바로 ELB에 연결하셨는데요혹시 nginx를 중간에 끼게 된다면 어떤 방식으로 하면 좋은지 궁금합니다 저는 nginx를 중간에 껴서 리버스 프록시 서버를 만들고 싶은데요이러한 방법이 ecs에서는 권장되지 않아 80포트로 어플리케이션을 배포하신건지 궁금합니다 또한 만약 nginx를 중간에 낄 수 있다면이를 service discovery 방식으로 nginx와 어플리케이션을 각각 서비스로 분리해 연결하는 방식하나의 태스크 정의에 nginx + 어플리케이션을 같이 정의해 하나의 서비스로 배포하는 방식이 방법은 fargate 사용시 bridge 를 지원해 주지 않아 localhost로 통신했습니다둘 중에 어떤 방식이 더 괜찮을지...? 아님 더 추천해주는 방식이 있으신지 궁금합니다