배포 오류 질문
123
42 câu hỏi đã được viết
안녕하세요 강사님 제가 실전이라 생각하고 프론트랑 백엔드를 배포 했습니다.
auto
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.5.3.jar:3.5.3]
Caused by: org.springframework.data.redis.listener.adapter.RedisListenerExecutionFailedException: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:383) ~[spring-data-redis-3.5.1.jar:3.5.1]
at org.springframework.data.redis.listener.RedisMessageListenerContainer.start(RedisMessageListenerContainer.java:361) ~[spring-data-redis-3.5.1.jar:3.5.1]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:405) ~[spring-context-6.2.8.jar:6.2.8]
... 19 common frames omitted
Caused by: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1858) ~[spring-data-redis-3.5.1.jar:3.5.1]
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1789) ~[spring-data-redis-3.5.1.jar:3.5.1]
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceC
Redis 에러 (백엔드 에러는 이렇게 뜨고)

프론트 엔드 (로그인 하고 들어가는 거 잘됩니다. 채팅만 치면 저렇게 뜹니다.)
EC2에서 redis 접속은 잘 됩니다.
프론트는 S3+cloudfront (도메인 적용 안함)를 통해 배포를 했고
둘다 https 는 적용했습니다.

백엔드는 Redis(ElastiCache(실시간 PubSub 기능을 위해) + EC2+RDS +nginx(https)+ 깃헙 액션으 로 배포했고 몇시간 쨰 하는데 저 에러가 뜹니다.
백엔드 배포 자체는 /opt ~ 를 통해서 배포 했습니다.
혹시 프론트 배포가 잘 못 된건가요?
S3+cloudfront 면 안될수도 있나요?
StompWebSocketConfig
package org.example.javademo.chatserver2.chat.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class StompWebSocketConfig implements WebSocketMessageBrokerConfigurer {
private final StompHandler stompHandler;
public StompWebSocketConfig(StompHandler stompHandler) {
this.stompHandler = stompHandler;
}
/**
* 클라이언트가 WebSocket으로 접속할 수 있는 endpoint 설정
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/connect")
.setAllowedOrigins(
)
// SockJS를 통해 ws가 아닌 환경에서도 연결 가능하게 설정
.withSockJS();
}
/**
* STOMP 메시지 브로커 설정
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// /publish 로 시작하는 메시지는 @MessageMapping 메서드로 라우팅
registry.setApplicationDestinationPrefixes("/publish");
// /topic 으로 시작하는 메시지는 메시지 브로커를 통해 구독자에게 전달
registry.enableSimpleBroker("/topic");
}
/**
* 클라이언트 → 서버 (inbound) 메시지 처리 쓰레드 풀 설정
*/
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.taskExecutor()
.corePoolSize(10)
.maxPoolSize(20)
.keepAliveSeconds(60);
}
/**
* 서버 → 클라이언트 (outbound) 메시지 처리 쓰레드 풀 설정
*/
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
registration.taskExecutor()
.corePoolSize(10)
.maxPoolSize(20)
.keepAliveSeconds(60);
}
// 인증 등을 처리하고 싶을 경우 stompHandler 등록 (현재 주석처리)
// @Override
// public void configureClientInboundChannel(ChannelRegistration registration) {
// registration.interceptors(stompHandler);...
// }
}이거는 조금 수정했습니다.
RedisConfig
package org.example.javademo.chatserver2.common.configs;
import org.example.javademo.chatserver2.chat.service.RedisPubSubService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private int port;
// 연결 팩토리 생성
@Bean
@Qualifier("chatPubSub")
public RedisConnectionFactory chatPubSubFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(host);
config.setPort(port);
return new LettuceConnectionFactory(config);
}
// String 기반 Redis 템플릿
@Bean
@Qualifier("chatPubSub")
public StringRedisTemplate stringRedisTemplate(@Qualifier("chatPubSub") RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
// 메시지 수신 처리 리스너 어댑터
@Bean
public MessageListenerAdapter messageListenerAdapter(RedisPubSubService redisPubSubService) {
return new MessageListenerAdapter(redisPubSubService, "onMessage");
}
// 수신 채널 주제 설정
@Bean
public PatternTopic chatTopic() {
return new PatternTopic("chat");
}
// 메시지 수신을 처리하는 리스너 컨테이너.
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(
@Qualifier("chatPubSub") RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter,
PatternTopic chatTopic
) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(listenerAdapter, chatTopic);
return container;
}
// (선택) Object 기반 Redis 템플릿
@Bean
public RedisTemplate<String, Object> redisTemplate(@Qualifier("chatPubSub") RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
ElastiCache로 접속은 굉장히 잘 됩니다. (EC2 내부에서는)

문제는 이게 UI 에 왜 안 뜨는지 모르겠습니다.
Câu trả lời 2
0
안녕하세요~! 일단 제가 서버를 직접 볼수 없다보니 다소 제한적입니다.
일단, pub/sub설계를 제외해보시고, redis뺀상태에서 채팅이 잘 되는지 확인해보고,
그러면 redis 연결이 문제인것이니, 이렇게 문제의 원인을 좁혀 나가야 할것 같아요
0
강사님 혹시 제가 구현한 방식이 문제가 있나요? (백엔드 파트 기존 코드로는 연결 자체에 문제가 생겨서 수정했습니다.) (중간에 api cors 없는 부분은 제가 뺏습니다.)
0
일단 추측컨데, elastic cache가 설정에 따라 접속이 잘 안되는것을 저도 경험을 했어서 아래와 같은 생성방법을 정리한것을 가지고 있는데,
cli로 연결이 된다면, redis를 elastic caches에서 생성할떄 아래 방법을 따라 보시겠어요?
elastic cache 구성
6379 port 보안그룹에서 오픈
자체캐시설계 → 클러스터 캐시 → 클러스터 모드 비활성화
primary enpoint를 엔드포인트로 사용
0
안녕하세요, 인프런 AI 인턴입니다. KMC님.
배포 과정에서 발생하는 Redis 연결 문제와 관련하여 몇 가지 점검할 수 있는 사항을 안내드립니다.
Redis 연결 설정 확인:
- 백엔드에서 Redis에 접근할 때 사용하는 호스트 및 포트가 정확한지 확인해보세요. 특히, ElastiCache 클러스터의 엔드포인트를 정확히 사용하고 있는지 점검해 보시기 바랍니다.
- 백엔드에서 Redis에 접근할 때 사용하는 호스트 및 포트가 정확한지 확인해보세요. 특히, ElastiCache 클러스터의 엔드포인트를 정확히 사용하고 있는지 점검해 보시기 바랍니다.
환경 설정 파일:
- 서버 환경(ex: application.properties 또는 application.yml)에서 올바른 Redis 호스트 정보가 설정됐는지 확인하세요. 로컬과 다른 프로파일을 사용하고 있을 수 있습니다.
- 서버 환경(ex: application.properties 또는 application.yml)에서 올바른 Redis 호스트 정보가 설정됐는지 확인하세요. 로컬과 다른 프로파일을 사용하고 있을 수 있습니다.
방화벽 및 네트워크 설정:
- EC2 보안 그룹 또는 VPC 설정이 ElastiCache와의 통신을 허용하는지 확인하세요. 보통 ElastiCache는 해당 VPC의 서브넷에서만 접근 가능하도록 설정됩니다.
- EC2 보안 그룹 또는 VPC 설정이 ElastiCache와의 통신을 허용하는지 확인하세요. 보통 ElastiCache는 해당 VPC의 서브넷에서만 접근 가능하도록 설정됩니다.
프론트엔드와 API 백엔드 간의 CORS 설정:
- 프론트엔드(클라이언트)와 백엔드 간의 Cross-Origin Resource Sharing(CORS) 설정을 적절히 설정하여 통신이 원활한지 확인하세요.
- 프론트엔드(클라이언트)와 백엔드 간의 Cross-Origin Resource Sharing(CORS) 설정을 적절히 설정하여 통신이 원활한지 확인하세요.
SSL/HTTPS 통신 문제:
- HTTPS가 잘 설정되어 있는지가 중요합니다. 특히 프론트엔드와 백엔드 간의 통신에서 발생할 수 있는 SSL 인증서 문제나 잘못된 설정이 있는지 확인하세요.
- HTTPS가 잘 설정되어 있는지가 중요합니다. 특히 프론트엔드와 백엔드 간의 통신에서 발생할 수 있는 SSL 인증서 문제나 잘못된 설정이 있는지 확인하세요.
검증 로그 활용:
- 문제의 원인을 추적하기 위해, Redis 연결 문제 관련 더 많은 로그 정보를 출력하여 실시간으로 검토하십시오.
- 문제의 원인을 추적하기 위해, Redis 연결 문제 관련 더 많은 로그 정보를 출력하여 실시간으로 검토하십시오.
위 내용 외에 기초부터 다시 점검하시면서, 아래 유사한 질문에 대한 토론을 추가적으로 참고하시면 도움이 될 수 있습니다:
- Spring Application과 Redis 설정 이슈
배포에는 많은 요소가 연관되어 있어 꼼꼼한 설정 재확인이 필요하므로, 문제를 지속적으로 모니터링하고 변경 사항을 적용해 보시면 좋을 것 같습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해 드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
ERD 질문
0
54
2
StompHandler 관한 질문
0
79
2
리프레시 토큰은 알아서 구현하면 되는건가요??
0
79
2
cors, csrf 직접 구현
0
64
1
JWT 필터구현
0
96
2
강의 잘듣고 있습니다. 혹시 다음 강의 계획은 없으신가요?
0
57
1
STOMP 동작 과정 질문
0
48
1
chain.doFilter()
0
45
1
자바 21로 소스 작성해도 되나요?
0
60
2
메시지 브로커 선택에 관한 질문
0
64
2
WebSocket과 Spring Security 질문
0
81
2
추가 커스텀 구현 질문 있습니다.
0
59
2
connect와 동시에 구독하는데 구독 검증이 꼭 필요한가요?
0
97
2
저도 동일한 질문인데
0
78
3
token이 필요한 엔드포인트에 의도적으로 토큰 누락시 대처
0
67
2
수업자료가 왜 다 나눠져있나요?
0
78
2
메시지 전송 시 검증
0
61
2
JWT 생성 시 subject 설정에 대한 질문
0
156
3
StompHandler 질문 있습니다.
0
82
2
앱 서비스일 경우
0
82
2
웹소켓 서버 재배포시 고려해야 할 상황 질문
0
106
2
/connect 경로에 대한 토큰 검증의 필요성
0
77
1
JwtTokenProvider 작성중 오류 발생으로 문의드립니다.
0
95
2
수강료가 갑자기 인상됬던데 ㅠ
0
130
1

