API ialah tulang belakang aplikasi moden. Apabila saya mula membina API dengan Spring Boot, saya sangat tertumpu pada penyampaian ciri sehingga saya terlepas pandang satu aspek penting: daya tahan. Saya belajar dengan susah payah bahawa keupayaan API untuk menangani kegagalan dengan anggun dan menyesuaikan diri dengan keadaan yang berbeza adalah yang menjadikannya benar-benar boleh dipercayai. Izinkan saya membawa anda melalui beberapa kesilapan yang saya lakukan sepanjang perjalanan dan cara saya membetulkannya. Mudah-mudahan, anda boleh mengelakkan perangkap ini dalam perjalanan anda sendiri.
Kesilapan 1: Mengabaikan Konfigurasi Tamat Masa
Perkara yang Berlaku: Dalam salah satu projek awal saya, saya membina API yang membuat panggilan luaran kepada perkhidmatan pihak ketiga. Saya menganggap perkhidmatan tersebut akan sentiasa bertindak balas dengan cepat dan tidak mengganggu menetapkan tamat masa. Semuanya kelihatan baik sehingga trafik meningkat, dan perkhidmatan pihak ketiga mula perlahan. API saya hanya akan tergantung selama-lamanya, menunggu jawapan.
Impak: Responsif API semakin merosot. Perkhidmatan bergantung mula gagal, dan pengguna menghadapi kelewatan yang lama—malah ada yang mendapat Ralat Pelayan Dalaman 500 yang digeruni.
Cara Saya Membetulkannya: Ketika itulah saya menyedari kepentingan konfigurasi tamat masa. Begini cara saya membetulkannya menggunakan Spring Boot:
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder .setConnectTimeout(Duration.ofSeconds(5)) .setReadTimeout(Duration.ofSeconds(5)) .additionalInterceptors(new RestTemplateLoggingInterceptor()) .build(); } // Custom interceptor to log request/response details @RequiredArgsConstructor public class RestTemplateLoggingInterceptor implements ClientHttpRequestInterceptor { private static final Logger log = LoggerFactory.getLogger(RestTemplateLoggingInterceptor.class); @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { long startTime = System.currentTimeMillis(); log.info("Making request to: {}", request.getURI()); ClientHttpResponse response = execution.execute(request, body); long duration = System.currentTimeMillis() - startTime; log.info("Request completed in {}ms with status: {}", duration, response.getStatusCode()); return response; } } }
Konfigurasi ini bukan sahaja menetapkan tamat masa yang sesuai tetapi juga termasuk pengelogan untuk membantu memantau prestasi perkhidmatan luaran.
Kesilapan 2: Tidak Melaksanakan Pemutus Litar
Apa Yang Berlaku: Ada masanya perkhidmatan dalaman kami yang kami harapkan merosot selama beberapa jam. API saya tidak mengendalikan keadaan dengan baik. Sebaliknya, ia terus mencuba semula permintaan yang gagal itu, menambah lebih banyak beban pada sistem yang sudah tertekan.
Kegagalan berlatarkan adalah salah satu masalah yang paling mencabar dalam sistem teragih. Apabila satu perkhidmatan gagal, ia boleh mencipta kesan domino yang menjatuhkan keseluruhan sistem.
Kesan: Percubaan semula berulang mengatasi sistem, memperlahankan bahagian lain aplikasi dan menjejaskan semua pengguna.
Cara Saya Membetulkannya: Ketika itulah saya menemui corak pemutus litar. Menggunakan Spring Cloud Resilience4j, saya dapat memecahkan kitaran.
@Configuration public class Resilience4jConfig { @Bean public CircuitBreakerConfig circuitBreakerConfig() { return CircuitBreakerConfig.custom() .failureRateThreshold(50) .waitDurationInOpenState(Duration.ofSeconds(60)) .permittedNumberOfCallsInHalfOpenState(2) .slidingWindowSize(2) .build(); } @Bean public RetryConfig retryConfig() { return RetryConfig.custom() .maxAttempts(3) .waitDuration(Duration.ofSeconds(2)) .build(); } } @Service @Slf4j public class ResilientService { private final CircuitBreaker circuitBreaker; private final RestTemplate restTemplate; public ResilientService(CircuitBreakerRegistry registry, RestTemplate restTemplate) { this.circuitBreaker = registry.circuitBreaker("internalService"); this.restTemplate = restTemplate; } @CircuitBreaker(name = "internalService", fallbackMethod = "fallbackResponse") @Retry(name = "internalService") public String callInternalService() { return restTemplate.getForObject("https://internal-service.com/data", String.class); } public String fallbackResponse(Exception ex) { log.warn("Circuit breaker activated, returning fallback response", ex); return new FallbackResponse("Service temporarily unavailable", getBackupData()).toJson(); } private Object getBackupData() { // Implement cache or default data strategy return new CachedDataService().getLatestValidData(); } }
Tambahan mudah ini menghalang API saya daripada mengatasi dirinya sendiri, perkhidmatan dalaman atau perkhidmatan pihak ketiga, memastikan kestabilan sistem.
Kesilapan 3: Pengendalian Ralat yang Lemah
Apa yang Berlaku: Pada awalnya, saya tidak terlalu memikirkan tentang pengendalian ralat. API saya sama ada melemparkan ralat generik (seperti HTTP 500 untuk segala-galanya) atau mendedahkan butiran dalaman sensitif dalam surih tindanan.
Impak: Pengguna keliru tentang perkara yang salah dan pendedahan butiran dalaman mewujudkan potensi risiko keselamatan.
Cara Saya Membetulkannya: Saya memutuskan untuk memusatkan pengendalian ralat menggunakan anotasi @ControllerAdvice Spring. Inilah yang saya lakukan:
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder .setConnectTimeout(Duration.ofSeconds(5)) .setReadTimeout(Duration.ofSeconds(5)) .additionalInterceptors(new RestTemplateLoggingInterceptor()) .build(); } // Custom interceptor to log request/response details @RequiredArgsConstructor public class RestTemplateLoggingInterceptor implements ClientHttpRequestInterceptor { private static final Logger log = LoggerFactory.getLogger(RestTemplateLoggingInterceptor.class); @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { long startTime = System.currentTimeMillis(); log.info("Making request to: {}", request.getURI()); ClientHttpResponse response = execution.execute(request, body); long duration = System.currentTimeMillis() - startTime; log.info("Request completed in {}ms with status: {}", duration, response.getStatusCode()); return response; } } }
Ini menjadikan mesej ralat jelas dan selamat, membantu pengguna dan pembangun.
Kesilapan 4: Mengabaikan Had Kadar
Perkara yang Berlaku: Pada suatu hari yang baik, kami melancarkan kempen promosi dan trafik ke API kami meningkat. Walaupun ini merupakan berita baik untuk perniagaan, sesetengah pengguna mula menghantar spam kepada API dengan permintaan, menyebabkan orang lain kelaparan sumber.
Impak: Prestasi merosot untuk semua orang, dan kami menerima banyak aduan.
Cara Saya Membetulkannya: Untuk mengendalikan perkara ini, saya melaksanakan pengehadan kadar menggunakan Bucket4j dengan Redis. Berikut ialah contoh:
@Configuration public class Resilience4jConfig { @Bean public CircuitBreakerConfig circuitBreakerConfig() { return CircuitBreakerConfig.custom() .failureRateThreshold(50) .waitDurationInOpenState(Duration.ofSeconds(60)) .permittedNumberOfCallsInHalfOpenState(2) .slidingWindowSize(2) .build(); } @Bean public RetryConfig retryConfig() { return RetryConfig.custom() .maxAttempts(3) .waitDuration(Duration.ofSeconds(2)) .build(); } } @Service @Slf4j public class ResilientService { private final CircuitBreaker circuitBreaker; private final RestTemplate restTemplate; public ResilientService(CircuitBreakerRegistry registry, RestTemplate restTemplate) { this.circuitBreaker = registry.circuitBreaker("internalService"); this.restTemplate = restTemplate; } @CircuitBreaker(name = "internalService", fallbackMethod = "fallbackResponse") @Retry(name = "internalService") public String callInternalService() { return restTemplate.getForObject("https://internal-service.com/data", String.class); } public String fallbackResponse(Exception ex) { log.warn("Circuit breaker activated, returning fallback response", ex); return new FallbackResponse("Service temporarily unavailable", getBackupData()).toJson(); } private Object getBackupData() { // Implement cache or default data strategy return new CachedDataService().getLatestValidData(); } }
Ini memastikan penggunaan yang adil dan melindungi API daripada penyalahgunaan.
Kesilapan 5: Mengabaikan Kebolehmerhatian
Apa yang Berlaku: Setiap kali berlaku masalah dalam pengeluaran, ia seperti mencari jarum dalam timbunan jerami. Saya tidak mempunyai pengelogan atau metrik yang betul, jadi mendiagnosis isu mengambil masa yang lebih lama daripada yang sepatutnya.
Impak: Penyelesaian masalah menjadi mimpi ngeri, menangguhkan penyelesaian isu dan mengecewakan pengguna.
Cara Saya Membetulkannya: Saya menambahkan Spring Boot Actuator untuk pemeriksaan kesihatan dan menyepadukan Prometheus dengan Grafana untuk visualisasi metrik:
@RestControllerAdvice @Slf4j public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler(HttpClientErrorException.class) public ResponseEntity<errorresponse> handleHttpClientError(HttpClientErrorException ex, WebRequest request) { log.error("Client error occurred", ex); ErrorResponse error = ErrorResponse.builder() .timestamp(LocalDateTime.now()) .status(ex.getStatusCode().value()) .message(sanitizeErrorMessage(ex.getMessage())) .path(((ServletWebRequest) request).getRequest().getRequestURI()) .build(); return ResponseEntity.status(ex.getStatusCode()).body(error); } @ExceptionHandler(Exception.class) public ResponseEntity<errorresponse> handleGeneralException(Exception ex, WebRequest request) { log.error("Unexpected error occurred", ex); ErrorResponse error = ErrorResponse.builder() .timestamp(LocalDateTime.now()) .status(HttpStatus.INTERNAL_SERVER_ERROR.value()) .message("An unexpected error occurred. Please try again later.") .path(((ServletWebRequest) request).getRequest().getRequestURI()) .build(); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); } private String sanitizeErrorMessage(String message) { // Remove sensitive information from error messages return message.replaceAll("(password|secret|key)=\[.*?\]", "=[REDACTED]"); } } </errorresponse></errorresponse>
Saya juga melaksanakan pengelogan berstruktur menggunakan ELK Stack (Elasticsearch, Logstash, Kibana). Ini menjadikan log lebih mudah diambil tindakan.
Bawa pulang
Membina API yang berdaya tahan adalah satu perjalanan dan kesilapan adalah sebahagian daripada proses. Berikut ialah pengajaran utama yang saya pelajari:
- Sentiasa konfigurasi tamat masa untuk panggilan luaran.
- Gunakan pemutus litar untuk mengelakkan kegagalan lata.
- Memusatkan pengendalian ralat untuk menjadikannya jelas dan selamat.
- Laksanakan pengehadan kadar untuk mengurus lonjakan trafik.
Perubahan ini mengubah cara saya mendekati pembangunan API. Jika anda pernah menghadapi cabaran yang sama atau mempunyai petua lain, saya ingin mendengar cerita anda!
Nota Akhir: Ingat bahawa daya tahan bukanlah ciri yang anda tambah—ia adalah ciri yang anda bina ke dalam sistem anda dari bawah. Setiap komponen ini memainkan peranan penting dalam mencipta API yang bukan sahaja berfungsi tetapi terus berfungsi dengan pasti di bawah tekanan.
Atas ialah kandungan terperinci Membina API Berdaya Tahan: Kesilapan yang Saya Buat dan Cara Saya Mengatasinya. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Artikel ini membincangkan pelaksanaan caching pelbagai peringkat di Java menggunakan kafein dan cache jambu untuk meningkatkan prestasi aplikasi. Ia meliputi persediaan, integrasi, dan faedah prestasi, bersama -sama dengan Pengurusan Dasar Konfigurasi dan Pengusiran PRA Terbaik

Artikel ini meneroka mengintegrasikan pengaturcaraan berfungsi ke dalam Java menggunakan ekspresi Lambda, API Streams, rujukan kaedah, dan pilihan. Ia menyoroti faedah seperti kebolehbacaan dan kebolehkerjaan kod yang lebih baik melalui kesimpulan dan kebolehubahan

Kelas kelas Java melibatkan pemuatan, menghubungkan, dan memulakan kelas menggunakan sistem hierarki dengan bootstrap, lanjutan, dan pemuat kelas aplikasi. Model delegasi induk memastikan kelas teras dimuatkan dahulu, yang mempengaruhi LOA kelas tersuai

Artikel ini membincangkan menggunakan JPA untuk pemetaan objek-relasi dengan ciri-ciri canggih seperti caching dan pemuatan malas. Ia meliputi persediaan, pemetaan entiti, dan amalan terbaik untuk mengoptimumkan prestasi sambil menonjolkan potensi perangkap. [159 aksara]

Artikel ini membincangkan menggunakan Maven dan Gradle untuk Pengurusan Projek Java, membina automasi, dan resolusi pergantungan, membandingkan pendekatan dan strategi pengoptimuman mereka.

Artikel ini menerangkan NIO API Java untuk I/O yang tidak menyekat, menggunakan pemilih dan saluran untuk mengendalikan pelbagai sambungan dengan cekap dengan satu benang. Ia memperincikan proses, faedah (skalabilitas, prestasi), dan potensi perangkap (kerumitan,

Artikel ini membincangkan membuat dan menggunakan perpustakaan Java tersuai (fail balang) dengan pengurusan versi dan pergantungan yang betul, menggunakan alat seperti Maven dan Gradle.

Artikel ini memperincikan API soket Java untuk komunikasi rangkaian, yang meliputi persediaan pelanggan-pelayan, pengendalian data, dan pertimbangan penting seperti pengurusan sumber, pengendalian ralat, dan keselamatan. Ia juga meneroka teknik pengoptimuman prestasi, i


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

mPDF
mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Dreamweaver Mac版
Alat pembangunan web visual

EditPlus versi Cina retak
Saiz kecil, penyerlahan sintaks, tidak menyokong fungsi gesaan kod

Pelayar Peperiksaan Selamat
Pelayar Peperiksaan Selamat ialah persekitaran pelayar selamat untuk mengambil peperiksaan dalam talian dengan selamat. Perisian ini menukar mana-mana komputer menjadi stesen kerja yang selamat. Ia mengawal akses kepada mana-mana utiliti dan menghalang pelajar daripada menggunakan sumber yang tidak dibenarkan.