Spring Boot Client Performance Optimization

Java Technologies - স্প্রিং বুট ক্লায়েন্ট (Spring Boot Client)
123
123

স্প্রিং বুট ক্লায়েন্টের পারফরম্যান্স উন্নত করা একটি গুরুত্বপূর্ণ বিষয়, বিশেষ করে মাইক্রোসার্ভিস আর্কিটেকচারের ক্ষেত্রে যেখানে ক্লায়েন্ট সার্ভিসগুলোর মধ্যে কমিউনিকেশন অত্যন্ত গুরুত্বপূর্ণ। এখানে Spring Boot ক্লায়েন্টের (RestTemplate/WebClient) পারফরম্যান্স অপটিমাইজ করার কিছু কৌশল আলোচনা করা হলো।


১. HTTP Client নির্বাচন ও কনফিগারেশন

(ক) WebClient ব্যবহার করুন:

  • WebClient non-blocking I/O এবং reactive programming সমর্থন করে, যা উচ্চ স্কেল ও লোডে ভালো পারফরম্যান্স দেয়।
  • RestTemplate এখনও সিঙ্ক্রোনাস এবং ব্লকিং। যদি সম্ভব হয়, নতুন প্রজেক্টের জন্য WebClient ব্যবহার করুন।

(খ) HTTP Client Library নির্বাচন:

Spring Boot এর ডিফল্ট HTTP ক্লায়েন্ট হলো HttpURLConnection, যা সীমিত পারফরম্যান্স প্রদান করে। HTTP ক্লায়েন্টের পারফরম্যান্স উন্নত করতে নিচের কোনো একটি ক্লায়েন্ট ব্যবহার করুন:

  • Apache HttpClient
  • OkHttp
  • Netty (WebClient এর জন্য আদর্শ)

কনফিগারেশন:

@Bean
public WebClient webClient() {
    HttpClient httpClient = HttpClient.create()
            .responseTimeout(Duration.ofSeconds(5))
            .doOnConnected(conn ->
                    conn.addHandlerLast(new ReadTimeoutHandler(5))
                        .addHandlerLast(new WriteTimeoutHandler(5))
            );

    return WebClient.builder()
            .clientConnector(new ReactorClientHttpConnector(httpClient))
            .build();
}

২. Connection Pooling সক্রিয় করা

HTTP কলের প্রতিটি রিকোয়েস্ট-রেসপন্সের জন্য নতুন কানেকশন তৈরি করা ব্যয়বহুল। Connection Pooling ব্যবহার করে কানেকশন পুনরায় ব্যবহার করুন।

RestTemplate এর জন্য Connection Pooling:

@Bean
public RestTemplate restTemplate() {
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
    factory.setHttpClient(HttpClients.custom()
            .setMaxConnTotal(100)
            .setMaxConnPerRoute(20)
            .build());
    return new RestTemplate(factory);
}

WebClient এর জন্য Connection Pooling:

@Bean
public WebClient webClientWithConnectionPool() {
    HttpClient httpClient = HttpClient.create()
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
            .doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(5))
                                       .addHandlerLast(new WriteTimeoutHandler(5)))
            .connectionProvider(ConnectionProvider.builder("custom")
                    .maxConnections(100)
                    .maxIdleTime(Duration.ofSeconds(20))
                    .build());

    return WebClient.builder()
            .clientConnector(new ReactorClientHttpConnector(httpClient))
            .build();
}

৩. Timeout সেট করা

RestTemplate:

@Bean
public RestTemplate restTemplateWithTimeout() {
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
    factory.setConnectTimeout(5000);
    factory.setReadTimeout(5000);
    return new RestTemplate(factory);
}

WebClient:

HttpClient httpClient = HttpClient.create()
        .responseTimeout(Duration.ofSeconds(5));

৪. Caching ইন্ট্রোডিউস করা

(ক) Response Caching:

অপ্রয়োজনীয় API কল এড়াতে Spring Cache ব্যবহার করতে পারেন। Spring Boot এর ক্যাশিং এনাবল করতে:

  1. Dependency যোগ করুন:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    
  2. Cache Configuration:

    @EnableCaching
    @Configuration
    public class CacheConfig {
        @Bean
        public CacheManager cacheManager() {
            return new ConcurrentMapCacheManager("responses");
        }
    }
    
  3. Cache ব্যবহার:

    @Cacheable("responses")
    public String getCachedData(String url) {
        return restTemplate.getForObject(url, String.class);
    }
    

৫. Load Balancing ব্যবহার করুন

Spring Cloud LoadBalancer:

Spring Cloud LoadBalancer ব্যবহার করে সার্ভিস ডিসকভারি এবং লোড ব্যালেন্সিং নিশ্চিত করুন।

@Bean
@LoadBalanced
public RestTemplate loadBalancedRestTemplate() {
    return new RestTemplate();
}

WebClient এর জন্য:

@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
    return WebClient.builder();
}

৬. Compression সক্রিয় করা

Gzip Compression:

Response সাইজ কমানোর জন্য Gzip ব্যবহার করুন। WebClient বা RestTemplate এ হেডার যোগ করুন:

webClient.get()
        .uri("/api/data")
        .header("Accept-Encoding", "gzip")
        .retrieve()
        .bodyToMono(String.class);

৭. Bulkhead এবং Circuit Breaker ব্যবহার করুন

(ক) Resilience4j Circuit Breaker:

সার্ভিস ফেইল হলে API কল বন্ধ করতে Circuit Breaker ব্যবহার করুন।

Dependency যোগ করুন:

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
</dependency>

Usage:

@CircuitBreaker(name = "myService", fallbackMethod = "fallback")
public String callService() {
    return restTemplate.getForObject("http://example.com/api", String.class);
}

public String fallback(Exception e) {
    return "Fallback response";
}

৮. Metrics এবং Monitoring

(ক) Actuator এবং Micrometer ব্যবহার করুন:

API কলের পারফরম্যান্স মনিটর করতে Spring Boot Actuator এবং Micrometer ব্যবহার করুন।

Dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

৯. Thread Management

(ক) WebClient এর জন্য Reactor Thread Pool:

Schedulers.parallel();
Schedulers.boundedElastic();

উপসংহার:

Spring Boot ক্লায়েন্টের পারফরম্যান্স অপটিমাইজ করতে নিচের বিষয়গুলোর দিকে গুরুত্ব দিন:

  1. WebClient ব্যবহার করে non-blocking কল করুন।
  2. Connection Pooling এবং Timeout সঠিকভাবে কনফিগার করুন।
  3. সার্ভিসের জন্য Load Balancing এবং Circuit Breaker ইন্ট্রোডিউস করুন।
  4. Caching এবং Gzip Compression ব্যবহার করুন।
  5. Monitoring এবং Metrics সিস্টেম ইন্টিগ্রেট করুন।

প্রয়োজনে আরও বিস্তারিত বা নির্দিষ্ট উদাহরণ চাইলে জানাতে পারেন! 😊

Content added By

RestTemplate এবং WebClient এর Performance Issues

78
78

Spring Boot ক্লায়েন্টে RestTemplate এবং WebClient RESTful API কল করতে ব্যবহৃত হয়। তবে এদের ব্যবহার করার সময় কিছু পারফরম্যান্স ইস্যু দেখা দিতে পারে, যা অ্যাপ্লিকেশনের কার্যকারিতা এবং রেসপন্স টাইম প্রভাবিত করে। এখানে RestTemplate এবং WebClient-এর পারফরম্যান্স সম্পর্কিত ইস্যু এবং সেগুলো সমাধানের পদ্ধতি আলোচনা করা হলো:


1. RestTemplate এর Performance Issues

a. Blocking Nature

  • সমস্যা: RestTemplate একটি ব্লকিং HTTP ক্লায়েন্ট। এটি সিঙ্ক্রোনাস পদ্ধতিতে কাজ করে এবং রেসপন্স না আসা পর্যন্ত থ্রেড আটকে রাখে। এই কারণে থ্রেড সংখ্যা বেশি হলে পারফরম্যান্স ড্রপ হয়।
  • সমাধান: রিয়েল-টাইম বা উচ্চ-কনকারেন্সি অ্যাপ্লিকেশনের জন্য RestTemplate পরিবর্তে WebClient ব্যবহার করা উচিত।

b. Thread Utilization

  • সমস্যা: ব্লকিং অপারেশনের কারণে RestTemplate প্রতি অনুরোধে একটি থ্রেড ব্যবহার করে। যদি অনেক অনুরোধ হয়, তবে থ্রেড পুল দ্রুত পূর্ণ হয়ে যায়।
  • সমাধান:
    • থ্রেড পুল বৃদ্ধি করুন: ThreadPoolTaskExecutor বা ExecutorService ব্যবহার করে কনফিগার করা যায়।
    • Connection Pooling চালু করুন: HTTP ক্লায়েন্টের জন্য HttpComponentsClientHttpRequestFactory ব্যবহার করুন।

উদাহরণ: Connection Pooling সেটআপ

import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(100); // সর্বোচ্চ কানেকশন সংখ্যা
        connectionManager.setDefaultMaxPerRoute(20); // প্রতি রুটের জন্য সর্বোচ্চ কানেকশন সংখ্যা

        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .build();

        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
        return new RestTemplate(factory);
    }
}

c. Scalability Issues

  • সমস্যা: RestTemplate বড় স্কেল অ্যাপ্লিকেশন বা মাইক্রোসার্ভিসের জন্য উপযুক্ত নয়। থ্রেড-ব্লকিং এর কারণে এটি বেশি লোড পরিচালনা করতে পারে না।
  • সমাধান: নন-ব্লকিং WebClient ব্যবহার করুন।

2. WebClient এর Performance Issues

a. Configuration Overhead

  • সমস্যা: WebClient ব্যবহার করার জন্য সঠিক কনফিগারেশন প্রয়োজন। ডিফল্ট সেটিংস যথেষ্ট কার্যকর নয়।
  • সমাধান: টাইমআউট, রেসপন্স ক্যাশিং এবং কানেকশন পুলিং কনফিগার করুন।

উদাহরণ: Custom Configuration

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;

import java.time.Duration;

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient() {
        HttpClient httpClient = HttpClient.create()
                .responseTimeout(Duration.ofSeconds(5)) // টাইমআউট সেট করুন
                .doOnConnected(conn -> 
                    conn.addHandlerLast(new ReadTimeoutHandler(5))
                        .addHandlerLast(new WriteTimeoutHandler(5)));

        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build();
    }
}

b. Connection Pooling

  • সমস্যা: ডিফল্টভাবে WebClient নতুন কানেকশন তৈরি করে। এটি কানেকশন পুলিং চালু না করলে পারফরম্যান্সে নেতিবাচক প্রভাব ফেলে।
  • সমাধান: Reactor Netty বা Apache HttpClient ব্যবহার করে কানেকশন পুলিং সক্রিয় করুন।

উদাহরণ: Connection Pooling চালু করা

import reactor.netty.resources.ConnectionProvider;

HttpClient httpClient = HttpClient.create(
    ConnectionProvider.builder("custom")
        .maxConnections(50) // সর্বোচ্চ কানেকশন সংখ্যা
        .pendingAcquireTimeout(Duration.ofSeconds(5)) // Pending timeout
        .build()
);
WebClient webClient = WebClient.builder()
        .clientConnector(new ReactorClientHttpConnector(httpClient))
        .build();

c. High Memory Usage

  • সমস্যা: অনেক রিয়্যাকটিভ অপারেশনের সময় পর্যাপ্ত মেমরি না থাকলে OutOfMemoryError হতে পারে।
  • সমাধান:
    • buffer এড়িয়ে stream ব্যবহার করুন।
    • বড় রেসপন্স ক্ষেত্রে Flux ব্যবহার করে স্ট্রিম ডেটা প্রক্রিয়াকরণ করুন।

উদাহরণ: Streaming Data

public Flux<String> fetchLargeData(String url) {
    return webClient.get()
            .uri(url)
            .retrieve()
            .bodyToFlux(String.class); // ডেটা স্ট্রিম আকারে প্রসেসিং
}

d. Timeout Issues

  • সমস্যা: ডিফল্টভাবে WebClient টাইমআউট কনফিগার করা থাকে না, যা অপ্রয়োজনীয় বিলম্ব সৃষ্টি করতে পারে।
  • সমাধান: টাইমআউট ম্যানেজ করুন।

উদাহরণ: Request এবং Response Timeout

HttpClient httpClient = HttpClient.create()
        .responseTimeout(Duration.ofSeconds(5)); // রেসপন্স টাইমআউট

WebClient webClient = WebClient.builder()
        .clientConnector(new ReactorClientHttpConnector(httpClient))
        .build();

RestTemplate বনাম WebClient: Performance Comparison

ফিচারRestTemplateWebClient
NatureBlockingNon-blocking
ConcurrencyLowHigh
ScalabilityLimitedHighly scalable
ConfigurationSimpleRequires proper configuration
Use CaseLegacy or simple synchronous appsModern, reactive, and scalable apps

উপসংহার

  1. RestTemplate:
    • ছোট বা সিঙ্ক্রোনাস অ্যাপ্লিকেশনের জন্য ভালো।
    • ব্লকিং প্রকৃতির কারণে উচ্চ কনকারেন্সি বা রিয়্যাকটিভ অ্যাপ্লিকেশনের জন্য অপ্রতুল।
  2. WebClient:
    • রিয়্যাকটিভ এবং উচ্চ-কনকারেন্সি অ্যাপ্লিকেশনের জন্য আদর্শ।
    • সঠিকভাবে কনফিগার না করলে পারফরম্যান্স সমস্যা হতে পারে।

প্রস্তাবনা:

  • নতুন বা আধুনিক অ্যাপ্লিকেশনের জন্য WebClient ব্যবহার করুন।
  • ছোট ও ব্লকিং প্রকৃতির অ্যাপ্লিকেশনের ক্ষেত্রে RestTemplate কার্যকর।
Content added By

Connection Pooling এবং Timeout কনফিগারেশন

70
70

স্প্রিং বুট ক্লায়েন্টে Connection Pooling এবং Timeout কনফিগারেশন কার্যকর করতে RestTemplate বা WebClient ব্যবহার করা যেতে পারে। নিচে ধাপে ধাপে এই কনফিগারেশনগুলো দেখানো হলো।


১. Connection Pooling কনফিগারেশন

১.১ RestTemplate এর জন্য Connection Pooling

HttpClient বা HttpComponentsClientHttpRequestFactory ব্যবহার করে Connection Pooling সেটআপ করা যায়।

ডিপেন্ডেন্সি যোগ করা:

pom.xml এ Apache HttpClient ডিপেন্ডেন্সি যোগ করুন:

<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.4</version>
</dependency>

কনফিগারেশন:

import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.core5.util.TimeValue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        // Create connection manager
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(50); // Max total connections
        connectionManager.setDefaultMaxPerRoute(20); // Max connections per route
        connectionManager.setValidateAfterInactivity(TimeValue.ofSeconds(10));

        // Create HttpClient with connection manager
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .build();

        // Create RestTemplate with custom request factory
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        return new RestTemplate(requestFactory);
    }
}

১.২ WebClient এর জন্য Connection Pooling

Reactor Netty ব্যবহার করে WebClient এ Connection Pooling কনফিগার করা যায়।

ডিপেন্ডেন্সি যোগ করা:

<dependency>
    <groupId>io.projectreactor.netty</groupId>
    <artifactId>reactor-netty</artifactId>
</dependency>

কনফিগারেশন:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient() {
        // Create connection pool
        ConnectionProvider provider = ConnectionProvider.builder("custom")
                .maxConnections(50)
                .pendingAcquireMaxCount(100)
                .build();

        HttpClient httpClient = HttpClient.create(provider);

        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build();
    }
}

২. Timeout কনফিগারেশন

২.১ RestTemplate এর জন্য Timeout

HttpComponentsClientHttpRequestFactory ব্যবহার করে Timeout কনফিগার করা যায়।

উদাহরণ:

import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.util.Timeout;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(
                        org.apache.hc.client5.http.config.RequestConfig.custom()
                                .setConnectTimeout(Timeout.ofSeconds(5)) // Connection timeout
                                .setResponseTimeout(Timeout.ofSeconds(10)) // Read timeout
                                .build()
                )
                .build();

        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        return new RestTemplate(requestFactory);
    }
}

২.২ WebClient এর জন্য Timeout

HttpClient ব্যবহার করে WebClient-এ Timeout কনফিগার করা যায়।

উদাহরণ:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient() {
        HttpClient httpClient = HttpClient.create()
                .responseTimeout(java.time.Duration.ofSeconds(10)) // Response timeout
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000); // Connection timeout

        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build();
    }
}

৩. Connection Pooling এবং Timeout একত্রে ব্যবহার

RestTemplate উদাহরণ:

@Bean
public RestTemplate restTemplate() {
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
    connectionManager.setMaxTotal(50);
    connectionManager.setDefaultMaxPerRoute(20);

    CloseableHttpClient httpClient = HttpClients.custom()
            .setConnectionManager(connectionManager)
            .setDefaultRequestConfig(
                    org.apache.hc.client5.http.config.RequestConfig.custom()
                            .setConnectTimeout(Timeout.ofSeconds(5))
                            .setResponseTimeout(Timeout.ofSeconds(10))
                            .build()
            )
            .build();

    return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient));
}

WebClient উদাহরণ:

@Bean
public WebClient webClient() {
    ConnectionProvider provider = ConnectionProvider.builder("custom")
            .maxConnections(50)
            .pendingAcquireMaxCount(100)
            .build();

    HttpClient httpClient = HttpClient.create(provider)
            .responseTimeout(java.time.Duration.ofSeconds(10))
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);

    return WebClient.builder()
            .clientConnector(new ReactorClientHttpConnector(httpClient))
            .build();
}

সংক্ষেপে:

  1. Connection Pooling:
    • RestTemplate: PoolingHttpClientConnectionManager ব্যবহার।
    • WebClient: ConnectionProvider ব্যবহার।
  2. Timeout কনফিগারেশন:
    • Connection এবং Read Timeout নির্ধারণ।
  3. বেস্ট প্র্যাকটিস:
    • উচ্চ কনকারেন্সি হ্যান্ডল করার জন্য Connection Pooling অপরিহার্য।
    • Slow API কল হ্যান্ডল করার জন্য যথাযথ Timeout ব্যবহার করুন।

এই পদ্ধতিগুলো ব্যবহার করে আপনি স্প্রিং বুট ক্লায়েন্টে Connection Pooling এবং Timeout সঠিকভাবে কনফিগার করতে পারবেন।

Content added By

Caching এবং Rate Limiting এর মাধ্যমে Performance Optimization

72
72

Spring Boot ClientCaching এবং Rate Limiting ব্যবহার করে পারফরম্যান্স অপ্টিমাইজেশন করা অত্যন্ত কার্যকর পদ্ধতি। Caching পুনরাবৃত্ত রিকোয়েস্টের প্রতিক্রিয়া দ্রুত প্রদান করতে ব্যবহৃত হয়, এবং Rate Limiting সার্ভারের উপর অতিরিক্ত লোড পড়া থেকে রক্ষা করে। নিচে এই দুটি পদ্ধতি বিস্তারিতভাবে ব্যাখ্যা করা হয়েছে:


Caching

Caching এর ধারণা

Caching ব্যবহার করে ক্লায়েন্ট API রেসপন্সগুলো মেমোরি বা স্টোরেজে সংরক্ষণ করে। একবার ডেটা ক্যাশে সংরক্ষিত হলে, একই রিকোয়েস্টের জন্য সার্ভারে না গিয়ে ক্যাশ থেকে দ্রুত রেসপন্স প্রদান করা যায়।


Spring Boot এ Caching এর ইমপ্লিমেন্টেশন

১. Maven Dependency যোগ করুন

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

২. Cache Configuration

Application Class এ @EnableCaching এনোটেশন যোগ করুন:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class SpringBootClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootClientApplication.class, args);
    }
}

৩. Cache ব্যবহার করে Service তৈরি করুন

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class ApiService {

    private final RestTemplate restTemplate = new RestTemplate();

    @Cacheable("apiData")
    public String fetchData() {
        String url = "https://api.example.com/data";
        System.out.println("Fetching data from API...");
        return restTemplate.getForObject(url, String.class);
    }
}

৪. Cache Configuration

application.yml ফাইল:

spring:
  cache:
    type: simple # Simple in-memory cache

৫. Cache Clear করা (ঐচ্ছিক)

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

@Service
public class CacheService {

    @CacheEvict(value = "apiData", allEntries = true)
    public void clearCache() {
        System.out.println("Cache cleared!");
    }
}

Rate Limiting

Rate Limiting এর ধারণা

Rate Limiting এমন একটি পদ্ধতি যা নির্দিষ্ট সময়ে API রিকোয়েস্টের সংখ্যা সীমাবদ্ধ করে। এটি সার্ভারের অতিরিক্ত লোড এড়াতে সহায়ক।


Spring Boot এ Rate Limiting এর ইমপ্লিমেন্টেশন

১. Maven Dependency যোগ করুন

<dependency>
    <groupId>com.github.bucket4j</groupId>
    <artifactId>bucket4j-core</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

২. API এর উপর Rate Limiting প্রয়োগ করুন

Rate Limiter Filter তৈরি করুন:

import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Bucket4j;
import io.github.bucket4j.Refill;
import org.springframework.stereotype.Component;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Duration;

@Component
public class RateLimiterFilter extends javax.servlet.Filter {

    private final Bucket bucket;

    public RateLimiterFilter() {
        Bandwidth limit = Bandwidth.classic(5, Refill.greedy(5, Duration.ofMinutes(1)));
        this.bucket = Bucket4j.builder().addLimit(limit).build();
    }

    @Override
    public void doFilter(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (bucket.tryConsume(1)) {
            chain.doFilter(request, response);
        } else {
            response.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);
            response.getWriter().write("Too Many Requests");
        }
    }
}

৩. Rate Limiting Configuration

Filter Bean Configure করুন:

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RateLimiterConfig {

    @Bean
    public FilterRegistrationBean<RateLimiterFilter> rateLimiterFilter() {
        FilterRegistrationBean<RateLimiterFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new RateLimiterFilter());
        registrationBean.addUrlPatterns("/api/*"); // Apply on specific API endpoints
        return registrationBean;
    }
}

Caching এবং Rate Limiting একত্রে ব্যবহার করা

Spring Boot ক্লায়েন্টে Caching এবং Rate Limiting একত্রে ব্যবহার করে ক্লায়েন্ট এবং সার্ভারের মধ্যে ভারসাম্য বজায় রাখা যায়।

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class OptimizedApiService {

    private final RestTemplate restTemplate = new RestTemplate();

    @Cacheable("optimizedData")
    public String fetchData() {
        String url = "https://api.example.com/data";
        System.out.println("Fetching data from API...");
        return restTemplate.getForObject(url, String.class);
    }
}

Performance Optimization এর সুবিধা

  1. Caching:
    • Latency হ্রাস: রেসপন্স দ্রুত প্রদান করে।
    • API কল কমায়: পুনরাবৃত্ত কল এড়ায়।
    • ব্যবহারকারী অভিজ্ঞতা উন্নত করে।
  2. Rate Limiting:
    • সার্ভারের লোড কমায়।
    • DoS আক্রমণ থেকে সুরক্ষা দেয়।
    • নিয়ন্ত্রিত API ব্যবহার নিশ্চিত করে।

উদাহরণ আউটপুট

Caching Example:

Fetching data from API... # First request
# Second request returns cached data, no "Fetching data" log

Rate Limiting Example:

Response: 200 OK # First 5 requests
Response: 429 Too Many Requests # Subsequent requests in the same minute

Best Practices

  1. Proper Cache Invalidation: ডেটা পরিবর্তনের সময় ক্যাশ আপডেট করুন।
  2. Rate Limit ভিন্ন API তে ভিন্নভাবে প্রয়োগ করুন।
  3. Monitoring ব্যবহার করুন: ক্যাশ এবং রেট লিমিটের পারফরম্যান্স ট্র্যাক করুন।

Caching এবং Rate Limiting একত্রে ব্যবহার করে Spring Boot Client অ্যাপ্লিকেশন আরও স্থিতিশীল এবং পারফরম্যান্স-উন্নত করা সম্ভব।

Content added By

উদাহরণ সহ Performance Optimization

72
72

স্প্রিং বুট ক্লায়েন্টে Performance Optimization করার জন্য বিভিন্ন পদ্ধতি ব্যবহার করা যায়। এর মধ্যে রয়েছে caching, asynchronous processing, connection pooling, এবং efficient data serialization। নিচে উদাহরণসহ একটি পূর্ণাঙ্গ গাইড দেওয়া হলো:


১. Caching ব্যবহারের মাধ্যমে পারফরম্যান্স উন্নত করা

স্প্রিং বুট ক্লায়েন্টে ক্যাশিং ব্যবহার করে বারবার একই ডেটা পুনরুদ্ধার এড়ানো যায়।

উদাহরণ: Spring Boot Cache Integration

ডিপেনডেন্সি যোগ করুন:

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

কনফিগারেশন যুক্ত করুন:

@EnableCaching অ্যানোটেশন ব্যবহার করে ক্যাশিং সক্রিয় করুন।

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
public class CacheConfig {
}

ক্যাশিং যুক্ত করুন:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class ApiClient {

    private final RestTemplate restTemplate;

    public ApiClient(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Cacheable("posts")
    public String fetchPost(int postId) {
        String url = "https://jsonplaceholder.typicode.com/posts/" + postId;
        return restTemplate.getForObject(url, String.class);
    }
}

কন্ট্রোলার:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiController {

    private final ApiClient apiClient;

    public ApiController(ApiClient apiClient) {
        this.apiClient = apiClient;
    }

    @GetMapping("/posts/{id}")
    public String getPost(@PathVariable int id) {
        return apiClient.fetchPost(id);
    }
}

লগ আউটপুট (ক্যাশ হিট):

INFO - Cache hit for key: posts::1

২. Asynchronous Processing ব্যবহার করুন

Spring’s @Async ব্যবহার করে asynchronous কাজ করা সম্ভব।

ডিপেনডেন্সি যোগ করুন:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

কনফিগারেশন:

@EnableAsync ব্যবহার করে asynchronous প্রসেসিং সক্রিয় করুন।

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;

@Configuration
@EnableAsync
public class AsyncConfig {
}

Asynchronous API ক্লায়েন্ট:

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.CompletableFuture;

@Service
public class AsyncApiClient {

    private final RestTemplate restTemplate;

    public AsyncApiClient(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Async
    public CompletableFuture<String> fetchData(String url) {
        String response = restTemplate.getForObject(url, String.class);
        return CompletableFuture.completedFuture(response);
    }
}

কন্ট্রোলার:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CompletableFuture;

@RestController
public class AsyncController {

    private final AsyncApiClient asyncApiClient;

    public AsyncController(AsyncApiClient asyncApiClient) {
        this.asyncApiClient = asyncApiClient;
    }

    @GetMapping("/async-fetch")
    public CompletableFuture<String> fetchAsync() {
        String url = "https://jsonplaceholder.typicode.com/posts/1";
        return asyncApiClient.fetchData(url);
    }
}

৩. Connection Pooling সেটআপ করুন

RestTemplate বা WebClient-এ Connection Pooling ব্যবহার করা হলে একই সার্ভারে একাধিক রিকোয়েস্ট দ্রুত পাঠানো সম্ভব।

উদাহরণ: RestTemplate এবং HttpClient Pooling

ডিপেনডেন্সি যোগ করুন:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

কনফিগারেশন:

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(100);
        connectionManager.setDefaultMaxPerRoute(20);

        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .build();

        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        return new RestTemplate(requestFactory);
    }
}

৪. Efficient Data Serialization (JSON)

ডিফল্টভাবে, স্প্রিং Jackson ব্যবহার করে JSON সিরিয়ালাইজেশন করে। পারফরম্যান্স উন্নত করার জন্য কাস্টমাইজেশন করুন।

ডিপেনডেন্সি যোগ করুন:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

কনফিগারেশন:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        return objectMapper;
    }
}

৫. Monitoring এবং Metrics

স্প্রিং অ্যাকচুয়েটর ব্যবহার করে অ্যাপ্লিকেশনের মেট্রিক্স মনিটরিং করুন।

ডিপেনডেন্সি:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

কনফিগারেশন:

management.endpoints.web.exposure.include=*

Actuator Endpoint:
http://localhost:8080/actuator/metrics


পারফরম্যান্স অপ্টিমাইজেশনের সুবিধা:

  1. Caching: পুনরায় ডেটা রিট্রিভ করার সময় সাশ্রয়।
  2. Asynchronous Processing: ব্লকিং ছাড়াই দ্রুত API রেসপন্স।
  3. Connection Pooling: হাই কনকারেন্ট রিকোয়েস্ট হ্যান্ডল করা সহজ।
  4. Efficient Serialization: বড় JSON ডেটার জন্য দ্রুত প্রসেসিং।
  5. Monitoring: মেট্রিক্স বিশ্লেষণের মাধ্যমে সমস্যা নির্ণয়।

এই পদ্ধতিগুলি একত্রে ব্যবহার করলে স্প্রিং বুট ক্লায়েন্টে উল্লেখযোগ্য পারফরম্যান্স উন্নতি করা সম্ভব।

Content added By
টপ রেটেড অ্যাপ

স্যাট অ্যাকাডেমী অ্যাপ

আমাদের অল-ইন-ওয়ান মোবাইল অ্যাপের মাধ্যমে সীমাহীন শেখার সুযোগ উপভোগ করুন।

ভিডিও
লাইভ ক্লাস
এক্সাম
ডাউনলোড করুন
Promotion