Hatırı sayılır bir şekilde bussiness'ı karmaşık bir microservicelerden oluşan Spring Boot uygulamam var. Projeme exception yapısı inşa etmek istiyorum. Ayrıca Exception mesajlarımı DB'de tutup dinamik olarak farklı language'ler için değiştirebilmek istiyorum.

Hatırı sayılır bir şekilde bussiness'ı karmaşık bir microservicelerden oluşan Spring Boot uygulamam var. Projeme exception yapısı inşa etmek istiyorum. Advanced bir senaryo üzerine kod örnekleri ile anlatmanı istiyorum. 




Spring Boot uygulamalarında istisna (exception) işleme konusunda karmaşık bir yapı oluşturmak çok önemli olabilir. Bu makalede, mikroservislerden oluşan bir projede, merkezi bir istisna yönetim sistemi oluşturacağız. İşte adım adım bir rehber:


1. Merkezi İstisna Yönetimi

Mikroservisler arası işbirliği yapan bileşenlerin olduğu bir projede, istisnaların merkezi bir şekilde işlenmesi, hata izleme ve düzeltebilirlik açısından büyük bir avantaj sağlar.


1.1. Custom Exception Sınıfları Oluşturma

Kendi istisna sınıflarınızı oluşturarak, belirli hatalar için daha açıklayıcı mesajlar sunabilirsiniz.



public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

public class UnauthorizedException extends RuntimeException {
    public UnauthorizedException(String message) {
        super(message);
    }

}


1.2. Controller Advice Kullanarak Merkezi İstisna İşleyicisi Oluşturma

Spring Boot, @ControllerAdvice anotasyonunu kullanarak istisna işleyicilerinin merkezi bir noktada toplanmasını sağlar.


@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)


    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException e) {
        return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(UnauthorizedException.class)


    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ResponseEntity<String> handleUnauthorizedException(UnauthorizedException e) {
        return new ResponseEntity<>(e.getMessage(), HttpStatus.UNAUTHORIZED);
    }

    // Diğer istisna işleyicileri


}


 

Bu yaklaşım, belirli istisnalar için özelleştirilmiş yanıt nesneleri oluşturmanıza izin verir, böylece istemci tarafında daha iyi bir anlayış elde edilir.


2. İstisnaların Loglanması ve İzlenmesi

Merkezi bir hata işleyicisi oluştururken, tüm istisnaların uygun bir şekilde loglandığından emin olmak önemlidir.


@ControllerAdvice

public class GlobalExceptionHandler {


    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);


    @ExceptionHandler(Exception.class)

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)

    public ResponseEntity<String> handleAllExceptions(Exception e) {

        logger.error("Beklenmeyen hata", e);

        return new ResponseEntity<>("Bir hata oluştu", HttpStatus.INTERNAL_SERVER_ERROR);

    }


    // Diğer işleyiciler

}


Şimdiye kadar temel istisna işleme yapılarını inceledik, şimdi daha gelişmiş bir senaryo üzerinde çalışalım.


3. İstisna Detaylarının Zenginleştirilmesi

İstisnalarınızın daha zengin bilgi içermesini sağlamak, sorun giderme sürecini büyük ölçüde kolaylaştırabilir.


3.1. Custom Exception Response Modeli Oluşturma


public class ExceptionResponse {

    private String message;

    private List<String> details;

    private LocalDateTime timestamp;


    // Getter ve Setter'lar

}



3.2. Global İstisna İşleyicisi ile Bu Modeli Kullanma


@ControllerAdvice

public class GlobalExceptionHandler {


    @ExceptionHandler(ResourceNotFoundException.class)

    @ResponseStatus(HttpStatus.NOT_FOUND)

    public ResponseEntity<ExceptionResponse> handleResourceNotFoundException(ResourceNotFoundException e) {

        ExceptionResponse response = new ExceptionResponse(e.getMessage(), Arrays.asList("Detay 1", "Detay 2"), LocalDateTime.now());

        return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);

    }


    // Diğer işleyiciler

}


4. Özelleştirilmiş İstisna İşleyicileri ile İlgili İstisna Zincirleme

Bazen belirli bir istisnayı başka bir istisna ile yakalamak ve bunlara özel işlem uygulamak isteyebilirsiniz. Bunun için @ExceptionHandler içinde birden fazla istisna tipi belirleyebilirsiniz.



@ExceptionHandler({ResourceNotFoundException.class, UnauthorizedException.class})

@ResponseStatus(HttpStatus.NOT_FOUND)

public ResponseEntity<ExceptionResponse> handleMultipleExceptions(Exception e) {

    ExceptionResponse response = new ExceptionResponse(e.getMessage(), Collections.emptyList(), LocalDateTime.now());

    return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);

}



5. İstisna Yapısını Mikroservisler Arasında Standardize Etme

Mikroservisler arası istisnaları tutarlı bir şekilde işlemek, her servisin aynı istisna yapısına sahip olması gerektiği anlamına gelir. Bu, istisna sınıfları ve işleyicilerinin ortak bir kütüphanede oluşturulmasını ve her mikroservis projesinde bu kütüphanenin dahil edilmesini gerektirebilir.


Bu, her mikroservis arasında istisna işleme davranışının tutarlı olmasını sağlar ve istemci tarafında ortak bir anlayış oluşturur.


Sonuç

Gelişmiş istisna işleme, bir Spring Boot uygulamasının sağlamlığını ve bakımını büyük ölçüde artırabilir. Merkezi istisna işleme, özelleştirilmiş istisna yanıtları, loglama ve istisna detaylarının zenginleştirilmesi gibi tekniklerle karmaşık bir mikroservis mimarisi bile çok daha yönetilebilir hale gelebilir.


Kesinlikle, devam edelim! Şimdi daha da derine dalalım ve istisna işlemenin mikroservisler arası iletişimde nasıl uygulanacağına odaklanalım.


6. Mikroservisler Arası İstisna Yönetimi

Mikroservisler arası iletişimde, bir servisin başka bir servise yaptığı çağrıda bir hata oluştuğunda, bu durumun uygun bir şekilde ele alınması gerekir.


6.1. Feign İstemcilerinde İstisna Yönetimi

Feign, mikroservisler arası HTTP istemcilerini oluşturmanın kolay bir yoludur. Bu istemcilerle çalışırken, Feign hata dekoderini özelleştirebilirsiniz.


@Component

public class CustomErrorDecoder implements ErrorDecoder {


    private final ErrorDecoder defaultErrorDecoder = new Default();


    @Override

    public Exception decode(String methodKey, Response response) {

        if (response.status() == 404) {

            return new ResourceNotFoundException("Kaynak bulunamadı");

        }

        return defaultErrorDecoder.decode(methodKey, response);

    }

}



6.2. Hystrix ile Dolaşım Kırıcılar

Bir servisin diğer bir servisle iletişime geçemediğinde, dolaşım kırıcısı kullanarak servisin devre dışı bırakılmasını sağlayabilirsiniz. Hystrix, bu işlevi sağlayan popüler bir kütüphanedir.


@HystrixCommand(fallbackMethod = "fallbackMethod")

public String callAnotherService() {

    // Diğer servise yapılan çağrı

}


public String fallbackMethod() {

    return "Dolaşım Kırıcı Aktif";

}



7. İstisna İzleme ve İzleme

Karmaşık mikroservis ortamlarında, istisnaların merkezi bir şekilde izlenmesi ve izlenmesi hayati önem taşıyabilir.


7.1. ELK Stack ile Log İzleme

Elasticsearch, Logstash ve Kibana (ELK) kullanarak, tüm mikroservislerden logları merkezi bir yerde toplayabilir ve analiz edebilirsiniz.


7.2. Distributed Tracing

Jaeger gibi araçlar kullanarak, mikroservisler arasındaki isteklerin izini sürmek de mümkündür. Bu, bir isteğin sisteminizde nerede hata yaptığını anlamanızı kolaylaştırır.


Sonuç

İstisna işlemenin yanı sıra, mikroservisler arası iletişimde kararlılık ve izlenebilirlik de çok önemli kavramlardır. Uygun hata işleme, dolaşım kırıcılar, merkezi loglama ve dağıtılmış izleme, karmaşık bir mikroservis ekosisteminin sağlamlığını ve bakımını büyük ölçüde artırabilir.


Bu kavramlar, genellikle büyük ölçekli, üretim seviyesinde sistemlerde kullanılır ve proje büyüdükçe giderek daha önemli hale gelir.

Exception mesajlarını Mysql database'inde saklamak istiyorum ve istediğimde değiştirmek istiyorum. Kullanıcıya bu mesajı dönmek için ne yapabilirim? Spring Data JPA kullanıyorum.


Exception mesajlarını bir MySQL veritabanında saklamak ve dinamik olarak güncellemek, özellikle çok dilli uygulamalar veya iş kuralları sık sık değişen sistemler için faydalı olabilir. İşte bunu nasıl yapabileceğinizle ilgili bir rehber:


1. Exception Mesajları İçin Veritabanı Tablosu Oluşturma

İlk olarak, exception mesajlarını saklamak için bir veritabanı tablosu oluşturmanız gerekir. Örnek bir şema şu şekilde olabilir:


CREATE TABLE exception_messages (

    id INT PRIMARY KEY AUTO_INCREMENT,

    code VARCHAR(255) UNIQUE NOT NULL,

    message TEXT NOT NULL,

    locale VARCHAR(10) DEFAULT 'en_US'

);



2. Spring Data JPA ile Entite Sınıfı Oluşturma

Bu tabloyla eşleşen bir Java sınıfı oluşturmanız gerekir:



@Entity

@Table(name = "exception_messages")

public class ExceptionMessage {

    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Long id;

    private String code;

    private String message;

    private String locale;


    // Getter ve Setter'lar

}


3. Exception Mesajları İçin Repository Oluşturma

Spring Data JPA, ExceptionMessage nesneleriyle çalışmak için bir repository oluşturmanıza yardımcı olabilir:



public interface ExceptionMessageRepository extends JpaRepository<ExceptionMessage, Long> {

    Optional<ExceptionMessage> findByCodeAndLocale(String code, String locale);

}


4. Exception Mesajlarını Döndürmek İçin Servis Oluşturma

Exception mesajlarını döndürmek için bir servis sınıfı oluşturun:


@Service

public class ExceptionMessageService {


    @Autowired

    private ExceptionMessageRepository exceptionMessageRepository;


    public String getExceptionMessage(String code, String locale) {

        return exceptionMessageRepository.findByCodeAndLocale(code, locale)

                .map(ExceptionMessage::getMessage)

                .orElse("Default exception message");

    }

}


5. İstisna İşleyicisinde Bu Servisi Kullanma

GlobalExceptionHandler sınıfınız içinde, exception mesajlarını veritabanından almak için bu servisi kullanabilirsiniz:



@ControllerAdvice

public class GlobalExceptionHandler {


    @Autowired

    private ExceptionMessageService exceptionMessageService;


    @ExceptionHandler(ResourceNotFoundException.class)

    @ResponseStatus(HttpStatus.NOT_FOUND)

    public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException e) {

        String message = exceptionMessageService.getExceptionMessage(e.getCode(), "en_US");

        return new ResponseEntity<>(message, HttpStatus.NOT_FOUND);

    }


    // Diğer işleyiciler

}


Bu şekilde, exception mesajlarını veritabanında saklayabilir ve istediğiniz zaman değiştirebilirsiniz. Kullanıcıya özel bir mesaj döndürmek istediğinizde, sadece veritabanındaki ilgili kaydı güncellemeniz yeterlidir.


Bu yaklaşımın, exception mesajlarını merkezi bir yerde yönetmenize ve hızla değiştirmenize olanak tanıdığını unutmayın, bu da esneklik ve bakım kolaylığı sağlar.

Please Select Embedded Mode To Show The Comment System.*

Daha yeni Daha eski

نموذج الاتصال