Spring Boot 및 Hazelcast를 사용한 데이터베이스 캐시


@priyankanandula로 로그인
며칠 후에 돌아왔습니다.😎
좋은 하루😃, 동료들!Spring Boot에서 ORM 도구를 사용하여 데이터베이스 작업을 수행하는 과정에서 중요한 개념을 가져왔습니다.
본고blog에서 우리는 캐시와 캐시 제공 프로그램 중 하나Hazel Cast를 어떻게 사용하여 캐시를 실현하는지 토론할 것이다.

최종 프로젝트 구조

시작해보도록 하겠습니다.👇

캐시에 대해 자세히 설명하기 전에 ORM 도구가 지정한 요청을 어떻게 처리하는지 봅시다.
  • 클라이언트가 저희 프로그램에 접근할 때 저희 프로그램은 데이터베이스 테이블 내부에서 select 조회를 실행하여 데이터를 검색합니다. 저희 프로그램은 ORMhibernate 도구를 사용하여 데이터베이스에서 데이터를 읽습니다.
  • 그 다음에 데이터를 하나의 대상으로 변환하여 우리 프로그램에 전달한 다음에 응용 프로그램이 필요에 따라 클라이언트에게 전송한다.
  • 클라이언트가 저희 프로그램이나 ORM 도구에서 데이터를 요청할 때마다 select 문장을 실행하고 이 과정은 다시 반복됩니다.
  • 같은 읽기 작업을 반복하는 대신 캐시나 캐시를 사용합니다.
  • 캐시:


    캐시는 데이터나 대상을 임시 위치에 저장합니다.처음 요청을 받았을 때 이 도구ORM 또는 caching framework는 데이터를 읽고 대상으로 변환하여 임시 위치나 CD에 저장합니다.
    다음 요청이 들어갈 때, 이 ORM 프레임워크는 요청한 데이터가 캐시에 있는지 확인합니다.존재하면 데이터베이스 선택 조회나 데이터베이스 통신을 실행하지 않습니다.캐시에서 대상을 간단하게 꺼내 처리한 다음 클라이언트에게 되돌려줍니다.

    Finally, we may increase our application's performance by using the Cache.


    우리 실현부터 시작합시다.👇

    다음 단계에 따라 Hazel Cast 또는 기타 캐시 공급자를 사용합니다.
  • 종속성 추가
  • 캐시 구성 생성
  • 캐시 설정 및 사용
  • 실행 중인 캐시
  • 1. 종속성 추가:


    POM에 다음 종속성 추가xml 파일.
  • spring boot starter 캐시
  • hazelcast 스프링

  • 폴.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.6.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.priya.springweb</groupId>
        <artifactId>ProductRestAPI</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>ProductRestAPI</name>
        <description>Demo project for Spring BootRestAPI</description>
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>
    <!-- https://mvnrepository.com/artifact/com.hazelcast/hazelcast-spring -->
    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast-spring</artifactId>
    
    </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    

    2. 캐시 구성 생성:


    현재, 우리는 Cache 창설에 필요한 자바 설정 클래스를 만들 것입니다.여기서 우리는 Cache에 명칭, 크기와 그 안에 놓을 수 있는 대상의 수량 등을 줄 것이다.

    다음과 같은 방법으로 Hazelcast 구성을 추가할 수 있습니다.
  • hazelcast를 추가합니다.yaml 구성 또는
  • hazelcast를 추가합니다.xml 설정 또는
  • 소스 코드
  • 에서 Hazelcast 설정으로 @Bean 정의

    I am using the Java Based Configuration using @Bean


    package com.priya.springweb.cacheconfiguraions;
    
    
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.hazelcast.config.Config;
    import com.hazelcast.config.EvictionConfig;
    import com.hazelcast.config.EvictionPolicy;
    import com.hazelcast.config.MapConfig;
    import com.hazelcast.config.MaxSizeConfig;
    
    
    @Configuration
    public class ProductCacheConfig {
    
        @Bean
        public Config cacheConfig() {
            return new Config()
                    .setInstanceName("hazel-instance")
                    .addMapConfig(new MapConfig()
                            .setName("product-cache")
                            .setTimeToLiveSeconds(5000)
                            .setMaxSizeConfig(new MaxSizeConfig(200,com.hazelcast.config.MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE))
                            .setEvictionPolicy(EvictionPolicy.LRU)
                            );
                    }
    }
    
    
  • addMapConfig: 이 MapConfig에서 Cache의 모든 값을 설정합니다. 예를 들어 이름, 크기, 시간 등입니다.그것은 Cache 의 모든 정보를 저장했다.
  • setName: 캐시 이름을 지정해야 합니다.원하는 이름을 선택하세요.
  • setTimeToLiveSeconds: 대상이 추방되기 전Cache에 거주하는 시간대입니다.
  • setMaxSizeConfig: 캐시MaxSizeConfig 옵션은 두 가지 값이 있습니다. 하나는 캐시가 수용할 수 있는 최대 대상 수이고, 다른 하나는 캐시가 유지할 수 있는 최대 공간입니다.
  • SetExcitionPolicy: 우리는 cache eviction information를 제시해야 한다. 캐시 크기가 시간이 지날수록 커지기 때문에 캐시를 지우지 않으면 응용 프로그램이 붕괴될 것이다.
  • We can employ a variety of cache policies, like as

    1 Least Recently Used(LRU)

    2 Least Frequently Used(LFU)

    3 Random : Randomly pick the element from Cache and removed it.

    4 NONE : It will do nothing.


    3. 캐시 설정 및 사용:


    내가 사용한 것은 우리가 이전 블로그에서 만든 것이다. Rest APIs이 점은 참고해야 한다[]
    package com.priya.springweb;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    
    
    @SpringBootApplication
    @EnableCaching
    public class ProductRestApiApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ProductRestApiApplication.class, args);
        }
    
    }
    
    

    @EnableCaching that will enable the caching for our application


    package com.priya.springweb.entities;
    
    import java.io.Serializable;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    @Entity
    public class Product implements Serializable{
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private int id;
        private String name;
        private String description;
        private int price;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getDescription() {
            return description;
        }
        public void setDescription(String description) {
            this.description = description;
        }
        public int getPrice() {
            return price;
        }
        public void setPrice(int price) {
            this.price = price;
        }
    
    }
    
    

    Our Model class Should implements the Serializable interface because hazel cast or any other Cache providers like EH Cache will serialize our projects or Model Entities to a file system or in memory as required to a database.


    package com.priya.springweb.controllers;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.priya.springweb.entities.Product;
    import com.priya.springweb.repos.ProductRepository;
    
    @RestController
    public class ProductController {
    
        @Autowired
        private ProductRepository repository;
    
        @RequestMapping(value="/products",method=RequestMethod.GET)
        public List<Product> getProducts(){
    
            return repository.findAll();
        }
    
        @RequestMapping(value="/products/{id}",method=RequestMethod.GET)
        @Cacheable(value="product-cache",key="#id")
        public Product getProductById(@PathVariable("id") int id) {
    
            return repository.findById(id).get();
    
        }
    
        @RequestMapping(value="/products/",method=RequestMethod.POST)
        public Product createProduct(@RequestBody Product product) {
    
            return repository.save(product);
        }
    
    
        @RequestMapping(value="/products/",method=RequestMethod.PUT)
        public Product updateProduct(@RequestBody Product product) {
    
            return repository.save(product);
        }
    
        @RequestMapping(value="/products/{id}",method=RequestMethod.DELETE)
        @CacheEvict(value="product-cache",key="#id")
        public void  deleteProduct(@PathVariable("id") int id) {
    
        repository.deleteById(id);
    
        }
    }
    
    
  • 캐시를 get a single product method에 사용합니다.
  • 캐시: rest 컨트롤러나 서비스 클래스에서도 사용할 수 있습니다@Cachable.여기value는 설정 클래스에서 제공하는 캐시 이름입니다. Key는 그 안에 저장된 유일한 키 Cache 입니다.
  • 캐시 디스카운트: 캐시 디스카운트 정보, 즉 캐시를 언제 정리해야 하는지.
  • After you made all these Changes Run the Application -->Run on Spring Boot App


    4. 캐시가 실행 중:


    캐시 작업 상태를 확인하기 위해서 GET MEthod 를 실행할 것입니다.

    NOTE: Please remember the following few points.

    1. Make sure MySQL Server is running.
    2. Make sure you are running the SpringBoot project in embedded Tomcat Server

    JUnit 클래스에서 RestTemplate를 사용하여 Controller 클래스에서 만든 Restful 서비스를 사용합니다.

  • springweb 모듈에서 제시한 RestTemplate를 사용하면 현재restfulweb 서비스를 사용하거나restful 클라이언트를 만들 수 있습니다.
  • Spring webrestful 웹 서비스를 디자인하고 사용할 수 있습니다.
  • Rest Template는 각종 HTTP 방법(GET/PUT/POST/DELETE..)을 집행하는 종류이다.
  • 사용 json 시 되돌아오는 spring or rest template는Product 클래스에 자동으로 반서열화됩니다.

  • 신청속성 파일:
    spring.datasource.url=jdbc:mysql://localhost:3306/myproducts
    spring.datasource.username=root
    spring.datasource.password=root
    
    server.servlet.context-path=/productapi
    
    productresapi.services.url=http://localhost:8080/productapi/products/
    
    spring.cache.cache-names=product-cache
    spring.cache.type=hazelcast
    spring.jpa.show-sql=true
    
    package com.priya.springweb;
    
    import static org.junit.Assert.assertEquals;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.web.client.RestTemplate;
    
    import com.priya.springweb.entities.Product;
    
    
    @RunWith(SpringRunner.class)
    @SpringBootTest()
    public class ProductRestApiApplicationTests {
    
        @Value("${productresapi.services.url}")
        private String baseURL;
    
        @Test
        public void textGetProduct() {
            RestTemplate template=new RestTemplate();
            Product product=template.getForObject(baseURL+"2", Product.class);
            System.out.println("name :"+product.getName());
            assertEquals("Mac Book Pro", product.getName());
    
    
    
        }
    
    }
    
    

    사용 가능한 방법은 다음과 같습니다.

  • getForObject(url,classType) - GET에서 실행URL을 통해 표시를 검색합니다.응답이 주어진 클래스 형식으로 해제되어 되돌아옵니다.

  • getForEntity(url,responseType) - ResponseEntity에서 실행GET을 통해 표시 형식URL을 검색합니다.

  • exchange(requestEntity,responseType) - 지정한 RequestEntity를 실행하고 응답을 ResponseEntity로 되돌려줍니다.

  • 실행(url, httpMethod, RequestCallback,responseExtractor) - 주어진 URI 템플릿에 httpMethod를 실행하고 RequestCallback 템플릿으로 요청을 준비하며 ResponseExtractor 템플릿으로 응답을 읽습니다.
  • "내가 곧 발표할 blogs 중에서 더 상세하게 소개할 것이다RestTemplate."

    현재 이 JUnit Test 사례를 실행합니다.


    Test Runs Successfully. Now go through the logs Console.




    보시다시피, 우리가 처음 요청을 보냈을 때, 데이터베이스에서 데이터를 얻기 위해 Select 조회를 실행합니다.

    JUnit 테스트 용례를 다시 실행하려면:


    I've now cleared the console logs and rerunning the Test Case.



    현재 Hibernate select 조회를 실행하지 않았습니다. 대상이 이미 cached 이기 때문입니다.

    NOTE : Instead of using RestTemplate within the Code, you can also use Postmansuiteand then check the logs Console.

    RestTemplate can be used anywhere in the application, such as in the RestController or Service classes.


    다음은 코드의 GIT 저장소에 대한 링크입니다.[ https://github.com/priyankanandula/SpringBoot/tree/feature/HazelCast_Cache/ProductRestAPI ]
    그렇습니다, 점원들. 이것이 바로 우리가 사용하는 Hazel Cast 캐시를 실현하는 방식입니다.나는 네가 재미있기를 바란다.

    푸리양카 남두라의 사인이야...

    좋은 웹페이지 즐겨찾기