Skip to content

Commit

Permalink
[FEAT] apply rabbitmq dead letter queue
Browse files Browse the repository at this point in the history
  • Loading branch information
ohksj77 committed Mar 15, 2024
1 parent c415282 commit 3bb73de
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ public class RabbitMQConfig {
@Bean
public Queue locationQueue() {
return QueueBuilder.durable(RabbitMQConstant.LOCATION_QUEUE.getName())
.withArgument(
"x-dead-letter-exchange", RabbitMQConstant.DEAD_LETTER_EXCHANGE.getName())
.withArgument(
"x-dead-letter-routing-key",
RabbitMQConstant.DEAD_LETTER_ROUTING_KEY.getName())
.deadLetterExchange(RabbitMQConstant.DEAD_LETTER_EXCHANGE.getName())
.deadLetterRoutingKey(RabbitMQConstant.DEAD_LETTER_ROUTING_KEY.getName())
.build();
}

Expand All @@ -50,11 +47,8 @@ public Binding locationBinding() {
@Bean
public Queue notificationQueue() {
return QueueBuilder.durable(RabbitMQConstant.NOTIFICATION_QUEUE.getName())
.withArgument(
"x-dead-letter-exchange", RabbitMQConstant.DEAD_LETTER_EXCHANGE.getName())
.withArgument(
"x-dead-letter-routing-key",
RabbitMQConstant.DEAD_LETTER_ROUTING_KEY.getName())
.deadLetterExchange(RabbitMQConstant.DEAD_LETTER_EXCHANGE.getName())
.deadLetterRoutingKey(RabbitMQConstant.DEAD_LETTER_ROUTING_KEY.getName())
.build();
}

Expand All @@ -76,8 +70,8 @@ public Queue deadLetterQueue() {
}

@Bean
public TopicExchange deadLetterExchange() {
return new TopicExchange(RabbitMQConstant.DEAD_LETTER_EXCHANGE.getName());
public DirectExchange deadLetterExchange() {
return new DirectExchange(RabbitMQConstant.DEAD_LETTER_EXCHANGE.getName());
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.twtw.backend.domain.deadletter;

import com.twtw.backend.domain.notification.dto.NotificationRequest;
import lombok.extern.slf4j.Slf4j;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
Expand All @@ -20,7 +20,7 @@ public DeadLetterConsumer(@Value("${slack.url}") final String slackUrl) {
}

@RabbitListener(queues = "deadletter.queue")
public void handleDeadLetterMessage(final String message) {
public void handleDeadLetterMessage(final NotificationRequest message) {
log.error("Dead letter received: {}", message);
webClient
.post()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.twtw.backend.domain.notification.messagequeue;

import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.FirebaseMessagingException;
import com.rabbitmq.client.Channel;
import com.twtw.backend.domain.notification.dto.NotificationRequest;

import lombok.extern.slf4j.Slf4j;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

@Slf4j
import java.io.IOException;

@Component
public class FcmConsumer {
private final FirebaseMessaging firebaseMessaging;
Expand All @@ -19,8 +19,14 @@ public FcmConsumer(FirebaseMessaging firebaseMessaging) {
}

@RabbitListener(queues = "notification.queue")
public void sendNotification(final NotificationRequest request)
throws FirebaseMessagingException {
firebaseMessaging.send(request.toMessage());
public void sendNotification(
final NotificationRequest request,
final Channel channel,
@Header(AmqpHeaders.DELIVERY_TAG) final long tag) throws IOException {
try {
firebaseMessaging.send(request.toMessage());
} catch (final Exception e) {
channel.basicNack(tag, false, false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ private URI getPathUri(final SearchCarPathRequest request, final UriBuilder uriB
}

@Override
@CircuitBreaker(name = "backend-a", fallbackMethod = "fallback")
@CircuitBreaker(name = "backend-b", fallbackMethod = "fallback")
public SearchCarPathResponse request(final SearchCarPathRequest request) {
return webClient
.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,21 @@ public ResponseEntity<SearchCarPathResponse> searchCarPath(
return ResponseEntity.ok(pathService.searchCarPath(request));
}

@PostMapping("/search/car/cache")
public ResponseEntity<SearchCarPathResponse> searchCarPathWithCache(
@RequestBody @Valid SearchCarPathRequest request) {
return ResponseEntity.ok(pathService.searchCarPathWithCache(request));
}

@PostMapping("/search/ped")
public ResponseEntity<SearchPedPathResponse> searchPedPath(
@RequestBody @Valid SearchPedPathRequest request) {
return ResponseEntity.ok(pathService.searchPedPath(request));
}

@PostMapping("/search/ped/cache")
public ResponseEntity<SearchPedPathResponse> searchPedPathWithCache(
@RequestBody @Valid SearchPedPathRequest request) {
return ResponseEntity.ok(pathService.searchPedPathWithCache(request));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.twtw.backend.domain.path.dto.client.ped.SearchPedPathResponse;
import com.twtw.backend.global.client.MapClient;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

Expand All @@ -23,18 +24,34 @@ public PathService(

@Cacheable(
value = "carPath",
key = "'searchCarPath'.concat(#request)",
key = "'searchCarPath'.concat(#request.toString())",
cacheManager = "cacheManager",
unless = "#result.code != 0")
public SearchCarPathResponse searchCarPathWithCache(final SearchCarPathRequest request) {
return carPathClient.request(request);
}

@CacheEvict(
value = "carPath",
key = "'searchCarPath'.concat(#request.toString())",
cacheManager = "cacheManager")
public SearchCarPathResponse searchCarPath(final SearchCarPathRequest request) {
return carPathClient.request(request);
}

@Cacheable(
value = "pedPath",
key = "'searchPedPath'.concat(#request)",
key = "'searchPedPath'.concat(#request.toString())",
cacheManager = "cacheManager",
unless = "#result.features.size() <= 0")
public SearchPedPathResponse searchPedPathWithCache(final SearchPedPathRequest request) {
return pedPathClient.request(request);
}

@CacheEvict(
value = "pedPath",
key = "'searchPedPath'.concat(#request.toString())",
cacheManager = "cacheManager")
public SearchPedPathResponse searchPedPath(final SearchPedPathRequest request) {
return pedPathClient.request(request);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public SurroundPlaceClient(final KakaoProperties kakaoProperties) {
}

@Override
@CircuitBreaker(name = "backend-a", fallbackMethod = "fallback")
@CircuitBreaker(name = "backend-c", fallbackMethod = "fallback")
public SurroundPlaceResponse request(final SurroundPlaceRequest request) {
return webClient
.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public SearchDestinationClient(final KakaoProperties kakaoProperties) {
}

@Override
@CircuitBreaker(name = "backend-a", fallbackMethod = "fallback")
@CircuitBreaker(name = "backend-d", fallbackMethod = "fallback")
public SearchDestinationResponse request(final SearchDestinationRequest request) {
return webClient
.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public class PlanService {

@Cacheable(
value = "planDestination",
key = "'searchPlanDestination'.concat(#request)",
key = "'searchPlanDestination'.concat(#request.toString())",
cacheManager = "cacheManager",
unless = "#result.results.size() <= 0")
public PlanDestinationResponse searchPlanDestination(final SearchDestinationRequest request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.twtw.backend.global.exception.AuthorityException;
import com.twtw.backend.global.exception.EntityNotFoundException;
import com.twtw.backend.global.exception.WebClientResponseException;

import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
Expand All @@ -30,4 +30,9 @@ public ResponseEntity<ErrorResponse> authority(final AuthorityException e) {
public ResponseEntity<ErrorResponse> interrupted(final InterruptedException e) {
return ResponseEntity.badRequest().body(new ErrorResponse(e.getMessage()));
}

@ExceptionHandler(CallNotPermittedException.class)
public ResponseEntity<ErrorResponse> callNotPermitted(final CallNotPermittedException e) {
return ResponseEntity.badRequest().body(new ErrorResponse(e.getMessage()));
}
}
8 changes: 7 additions & 1 deletion backend/src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,10 @@ resilience4j.circuitbreaker:
waitDurationInOpenState: 10000
instances:
backend-a:
base-config: default
base-config: default
backend-b:
base-config: default
backend-c:
base-config: default
backend-d:
base-config: default
6 changes: 6 additions & 0 deletions backend/src/main/resources/application-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ resilience4j.circuitbreaker:
instances:
backend-a:
base-config: default
backend-b:
base-config: default
backend-c:
base-config: default
backend-d:
base-config: default
jwt:
secret: ${JWT_SECRET}
kakao-map:
Expand Down

0 comments on commit 3bb73de

Please sign in to comment.