日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在這篇博客中,我們將看到如何在spring-boot中利用loom虛擬線程。我們還將在JMeter的幫助下做一些負載測試,看看虛擬線程和普通線程的響應時間如何。

首先,虛擬線程是 Project Loom 的一部分。

此外,Loom 不會加速內存計算,例如并行流,這不是 Loom 的目標。

我們正在研究如何使用可用的相同硬件來提高應用程序吞吐量,即充分利用 CPU 的潛力,為此我們花費了大量精力。截至目前,我們能夠利用 2% 到 3% 的 CPU。我在這篇博客中詳細討論了這一點:

https://medium.com/@anil.JAVA.story/project-loom-virtual-threads-part-1-b17e327c8ba7

“我認為 Loom 項目將會消滅響應式編程”——Brian Goetz(Java 語言架構師)

讓我們快速設置我們的 Spring Boot 項目。

<?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>3.1.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.anil</groupId>
    <artifactId>virtualthread</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>virtualthread</name>
    <description>virtualthread</description>
    <properties>
        <java.version>20</java.version>
        <Tomcat.version>11.0.0-M4</tomcat.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/MySQL/mysql-connector-java -->

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>8.0.33</version>
        </dependency>


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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                  <compilerArgs>
                      <arg>--enable-preview</arg>
                      </compilerArgs>
                  <source>20</source>
                  <target>20</target>
              </configuration>

            </plugin>
        </plugins>
    </build>

</project>

由于 Project Loom 處于預覽階段,我們需要啟用預覽功能。

package org.anil.virtualthread;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
import org.springframework.context.annotation.Bean;

import java.util.concurrent.Executors;

@SpringBootApplication
@Slf4j
public class VirtualthreadApplication {

    public static void mAIn(String[] args) {
        SpringApplication.run(VirtualthreadApplication.class, args);
    }

    @Bean
    public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
        return protocolHandler -> {
            log.info("Configuring " + protocolHandler + " to use VirtualThreadPerTaskExecutor");
            protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
        };
    }

}

到目前為止,我們需要為 Tomcat 服務器配置虛擬線程設置。將來,這可能會在自動配置本身中得到解決。

package org.anil.virtualthread;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class HomeController {

    @Autowired
    ProductRepository productRepository;


    @GetMapping("/thread")
    public List<Product> checkThread() throws InterruptedException {
        Thread.sleep(1000);
        return productRepository.findAll();
    }


    @PostMapping("/save")
    public String saveProduct() throws InterruptedException {
        for(int i=0; i< 1000; i++){
            Product product = new Product();
            product.setProductName(RandomStringUtils.randomAlphanumeric(5));
            product.setPrice(RandomUtils.nextLong(10,1000));
            product.setPrice(1L);
            productRepository.save(product);
        }
        return "anil";
    }
}

我們有一個GetMapping返回所有結果,我們的數據庫中有 1000 條數據。我們已經讓線程休眠 1 秒。讓我們看看我們的Product實體和ProductRepository。

package org.anil.virtualthread;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;

@Entity
@Getter
@Setter
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String productName;
    private Long price;
}
package org.anil.virtualthread;

import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository extends JpaRepository<Product,Long> {
}

讓我們看看我們的 application.yaml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    maxIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    hikari:
      connection-timeout: 60000
      maximum-pool-size: 10
      minimum-idle: 5
    url: jdbc:mysql://localhost:3306/todos
    testWhileIdle: true
    username: root
    password: root1234
    validationQuery: SELECT 1
  flyway:
    baseline-version: 0
    enabled: true
    validate-on-migrate: false
  jpa:
    database: mysql
    generate-ddl: true
    hibernate:
      ddl-auto: none
      format_sql: true
    show-sql: true

現在,我們首先通過注釋以下行來運行應用程序,這將在普通線程上運行我們的應用程序

package org.anil.virtualthread;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
import org.springframework.context.annotation.Bean;

import java.util.concurrent.Executors;

@SpringBootApplication
@Slf4j
public class VirtualthreadApplication {

    public static void main(String[] args) {
        SpringApplication.run(VirtualthreadApplication.class, args);
    }

//    @Bean
//    public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
//        return protocolHandler -> {
//            log.info("Configuring " + protocolHandler + " to use VirtualThreadPerTaskExecutor");
//            protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
//        };
//    }
}

現在讓我們設置JMeter。我們將有 1000 個請求,該請求將在 3 秒內增加。并且這樣的狀態會持續200秒。每 3 秒,將觸發 1000 個 GET (“/thread”) 請求。我們還添加了響應時間圖偵聽器。

SpringBoot+虛擬線程,接口吞吐量成倍增加,太爽了!

 

圖片

現在讓我們運行測試并等待 200 秒。

SpringBoot+虛擬線程,接口吞吐量成倍增加,太爽了!

 

圖片

從圖中我們可以看到,一旦Tomcat的整個線程池被利用,響應時間從3600毫秒猛增到5200毫秒。從那時起,只有當以前的線程被釋放時,它才保持這種狀態。

現在讓我們在啟用虛擬線程功能的情況下運行負載測試。

package org.anil.virtualthread;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
import org.springframework.context.annotation.Bean;

import java.util.concurrent.Executors;

@SpringBootApplication
@Slf4j
public class VirtualthreadApplication {

    public static void main(String[] args) {
        SpringApplication.run(VirtualthreadApplication.class, args);
    }

    @Bean
    public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
        return protocolHandler -> {
            log.info("Configuring " + protocolHandler + " to use VirtualThreadPerTaskExecutor");
            protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
        };
    }

}

現在讓我們運行測試并等待 200 秒。

SpringBoot+虛擬線程,接口吞吐量成倍增加,太爽了!

 

圖片

顯然,現在并發 1000 個請求的響應時間幾乎略高于 1000 毫秒,有時甚至會達到 1400 毫秒,這比我們使用普通線程時要好得多。

顯然,當我們需要充分利用底層 CPU 時,我們應該開始在應用程序中采用虛擬線程,突然間我們可以看到,對于相同的硬件,應用程序的吞吐量增加了很多倍。

這比切換到反應式編程要好得多,反應式編程意味著重寫所有代碼,這很難先學習,然后編寫,甚至更難調試和分析。

簡而言之,更多用戶可以使用該應用程序并與第一個用戶同時獲得響應。

分享到:
標簽:SpringBoot
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定