偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

性能優(yōu)化!七個(gè)策略,讓Spring Boot 處理每秒百萬請求

人工智能 機(jī)器學(xué)習(xí)
在實(shí)施任何優(yōu)化前,我首先明確了性能基準(zhǔn)。這一步至關(guān)重要——若不清楚起點(diǎn),便無法衡量進(jìn)展,也無法定位最關(guān)鍵的改進(jìn)方向。

環(huán)境:SpringBoot3.4.2

1. 簡介

在實(shí)施任何優(yōu)化前,我首先明確了性能基準(zhǔn)。這一步至關(guān)重要——若不清楚起點(diǎn),便無法衡量進(jìn)展,也無法定位最關(guān)鍵的改進(jìn)方向。以下是我們的初始性能指標(biāo)概況:

最大吞吐量:50,000 次請求/秒

平均響應(yīng)時(shí)間:350 毫秒

95 分位響應(yīng)時(shí)間:850 毫秒

峰值時(shí)段 CPU 使用率:85%-95%

內(nèi)存占用:堆內(nèi)存使用達(dá)可用空間的 75%

數(shù)據(jù)庫連接:頻繁達(dá)到連接池上限(100 )

線程池飽和:線程池資源經(jīng)常耗盡

以上指標(biāo)通過如下的工具進(jìn)行收集所得:

  • JMeter用于負(fù)載測試,確定基礎(chǔ)吞吐量數(shù)值
  • Micrometer + Prometheus + Grafana實(shí)現(xiàn)實(shí)時(shí)監(jiān)控與可視化
  • JProfiler深入分析代碼中的性能熱點(diǎn)
  • 火焰圖(Flame graphs)定位 CPU 密集型方法 

根據(jù)上面的指標(biāo)總結(jié)如下性能瓶頸:

  • 線程池飽和默認(rèn)的 Tomcat 連接器已達(dá)到性能上限
  • 數(shù)據(jù)庫連接爭用HikariCP 連接池配置未針對實(shí)際負(fù)載優(yōu)化
  • 序列化效率低下Jackson 在請求/響應(yīng)處理中消耗大量 CPU 資源
  • 阻塞式 I/O 操作尤其在調(diào)用外部服務(wù)時(shí)表現(xiàn)明顯
  • 內(nèi)存壓力過度對象創(chuàng)建導(dǎo)致頻繁的 GC 停頓 

接下來,我們將逐一的解決上面的問題。

2. 性能優(yōu)化

2.1 使用響應(yīng)式編程

阻塞方式:

@Service
public class ProductService {
  private final ProductRepository productRepository ;
  public ProductService(ProductRepository productRepository) {
    this.productRepository = productRepository ;
  }
  public Product getProductById(Long id) {
    return repository.findById(id)
      .orElseThrow(() -> new ProductNotFoundException(id)) ;
  }
}

基于響應(yīng)式改造:

@Service
public class ProductService {
  private final ProductRepository productRepository ;
  public ProductService(ProductRepository productRepository) {
    this.productRepository = productRepository ;
  }
  public Product getProductById(Long id) {
    public Mono<Product> getProductById(Long id) {
      return productRepository.findById(id)
        .switchIfEmpty(Mono.error(new ProductNotFoundException(id)));
    }
  }
}

同時(shí)Controller層也需要改造

@RestController
@RequestMapping("/products")
public class ProductController {
  private final ProductService productService;
  public ProductController(ProductService productService) {
    this.productService = productService ;
  }
  @GetMapping("/{id}")
  public Mono<ResponseEntity<Product>> getProduct(@PathVariable Long id) {
    return service.getProductById(id)
      .map(ResponseEntity::ok)
      .defaultIfEmpty(ResponseEntity.notFound().build());
  }
}

注意,對應(yīng)依賴方面你需要引入如下相關(guān)的依賴:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<!--基于響應(yīng)式的mysql驅(qū)動(dòng)包-->
<dependency>
  <groupId>com.github.jasync-sql</groupId>
  <artifactId>jasync-r2dbc-mysql</artifactId>
  <version>2.1.24</version>
</dependency>

總結(jié):僅這一項(xiàng)改動(dòng)便使吞吐量翻倍,其核心在于更高效地利用線程資源。WebFlux 不再為每個(gè)請求分配獨(dú)立線程,而是通過少量線程處理海量并發(fā)請求。

有關(guān)響應(yīng)式編程,請查看下面文章:

新一代WebFlux框架核心技術(shù)Reactor響應(yīng)式編程基本用法

響應(yīng)式編程引領(lǐng)未來:WebFlux與R2DBC的完美結(jié)合實(shí)現(xiàn)數(shù)據(jù)庫編程

SpringBoot3虛擬線程 & 反應(yīng)式(WebFlux) & 傳統(tǒng)Tomcat線程池 性能對比

新一代web框架WebFlux到底要不要學(xué)?

2.2 數(shù)據(jù)庫優(yōu)化

數(shù)據(jù)庫交互成為下一個(gè)關(guān)鍵性能瓶頸。我采用了三管齊下的優(yōu)化策略:

  • 查詢優(yōu)化

我使用 Spring Data 的 @Query 注解取代了低效的自動(dòng)生成查詢:

優(yōu)化前:

List<Order> findByUserIdAndStatusAndCreateTimeBetween(
    Long userId, OrderStatus status, 
    LocalDate start, LocalDate end) ;

優(yōu)化后:

@Query("SELECT o FROM Order o WHERE o.userId = :userId " +
       "AND o.status = :status " +
       "AND o.createdDate BETWEEN :start AND :end " +
       "ORDER BY o.createdDate DESC")
List<Order> findUserOrdersInDateRange(
    @Param("userId") Long userId, 
    @Param("status") OrderStatus status,
    @Param("start") LocalDate start, 
    @Param("end") LocalDate end) ;

使用 Hibernate 的 @BatchSize 優(yōu)化 N+1 查詢:

@Entity
@Table(name = "t_order")
public class Order {
  // ...
  @OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
  // 批量抓取數(shù)據(jù)
  @BatchSize(size = 30)
  private Set<OrderItem> items ;
}
  • 連接池優(yōu)化

HikariCP 的默認(rèn)設(shè)置造成了連接爭用。經(jīng)過大量測試,我得出了這樣的配置(實(shí)際要根據(jù)自己的環(huán)境):

spring:
  datasource:
    hikari:
      maximum-pool-size: 100
      minimum-idle: 50
      idle-timeout: 30000
      connection-timeout: 2000
      max-lifetime: 1800000

關(guān)鍵的一點(diǎn)是,連接數(shù)并不總是越多越好;這里的hikari可不支持響應(yīng)式。所以,我們應(yīng)該吧響應(yīng)式與阻塞式2種方式進(jìn)行分開處理。

基于響應(yīng)式數(shù)據(jù)庫的配置如下:

spring:
  r2dbc:
    pool:
      initialSize: 30
      maxSize: 10
      max-acquire-time: 30s 
      max-idle-time: 30m
  • 使用緩存

對于頻繁訪問的數(shù)據(jù)添加了 Redis 緩存。

// 開啟
@Configuration
@EnableCaching
public class CacheConfig {
}
// 使用緩存
@Service
public class ProductService {
  @Cacheable(value = "products", key = "#id")
  public Mono<Product> getProductById(Long id) {
    return repository.findById(id)
        .switchIfEmpty(Mono.error(new ProductNotFoundException(id)));
  }
  @CacheEvict(value = "products", key = "#product.id")
  public Mono<Product> updateProduct(Product product) {
    return repository.save(product) ;
  }
}

配置緩存:

spring:
  cache:
    type: redis
    redis:
      cache-null-values: false
      time-to-live: 120m

需要更多個(gè)性化配置,可以自定義RedisCacheManager。

2.3 序列化優(yōu)化

通過優(yōu)化jackson序列化,可以明顯減少CPU的占用。

@Configuration
public class JacksonConfig {
  @Bean
  public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper() ;
    // 啟用 Afterburner 模塊以加速序列化
    mapper.registerModule(new AfterburnerModule()) ;
    // 僅僅序列化不為空的字段
    mapper.setSerializationInclusion(Include.NON_NULL) ;
    // 禁用不需要的功能
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) ;
    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) ;
    return mapper ;
  }
}

如果對部分接口要求非常高,那么可以采用Protocol Buffers。

關(guān)于Protocol Buffers的使用,請查看下面文章:

接口優(yōu)化!Spring Boot 集成 Protobuf 并使用 RestTemplate 實(shí)現(xiàn)微服務(wù)間通信

基于 Spring Boot 實(shí)現(xiàn)自定義二進(jìn)制數(shù)據(jù)傳輸協(xié)議

2.4 線程池&連接優(yōu)化

有了 WebFlux,我們需要調(diào)整 Netty 的事件循環(huán)設(shè)置:

spring:
  reactor:
    netty:
      worker:
        count: 32  #工作線程數(shù)(2 x CPU cores)
      connection:
        provider:
          pool:
            max-connections: 10000
            acquire-timeout: 5000

對于使用 Spring MVC 的,調(diào)整 Tomcat 連接器:

server:
  tomcat:
    threads:
      max: 200
      min-spare: 50
    max-connections: 8192
    accept-count: 100
    connection-timeout: 5000

這些設(shè)置使我們能夠以較少的資源處理更多的并發(fā)連接。

2.5 基于 Kubernetes 的橫向擴(kuò)展:終極解決方案 

通過橫向擴(kuò)展提升系統(tǒng)容量。將應(yīng)用容器化后部署至 Kubernetes 集群。

FROM openjdk:17-slim
COPY target/product-app.jar app.jar
ENV JAVA_OPTS="-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:+ParallelRefProcEnabled"
ENTRYPOINT exec java $JAVA_OPTS -jar /app.jar

然后根據(jù) CPU 利用率配置自動(dòng)縮放:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: product-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    #目標(biāo) Deployment 的名稱(即需要被擴(kuò)縮容的應(yīng)用)
    name: product-app
  #副本數(shù)范圍限制5~20
  minReplicas: 5
  maxReplicas: 20
  #定義觸發(fā)擴(kuò)縮容的指標(biāo)規(guī)則
  metrics:
  - type: Resource #使用資源指標(biāo)(如 CPU、內(nèi)存)
    resource:
      name: cpu #監(jiān)控 CPU 資源使用率
      target:
        type: Utilization #指標(biāo)類型為“利用率百分比”
        #當(dāng)持續(xù)超過 70% 時(shí)觸發(fā)擴(kuò)縮容
        averageUtilization: 70

利用 Istio 實(shí)施服務(wù)網(wǎng)格功能,以實(shí)現(xiàn)更好的流量管理:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: product-vs
spec:
  hosts:
  - product-service  # 目標(biāo)服務(wù)名(需與 Istio 服務(wù)網(wǎng)格中注冊的名稱一致)
  http:  # 定義 HTTP 協(xié)議相關(guān)的流量規(guī)則(支持路由、重試、超時(shí)等策略)
  - route:  # 配置流量路由規(guī)則
    - destination:  # 指定流量的實(shí)際目的地
        host: product-service  # 目標(biāo)服務(wù)名
    retries:  # 設(shè)置請求失敗時(shí)的重試策略
      attempts: 3  # 最大重試次數(shù)(首次請求 + 3次重試 = 最多4次嘗試)
      perTryTimeout: 2s  # 單次請求(含重試)的超時(shí)時(shí)間(2秒無響應(yīng)則中斷)
    timeout: 5s  # 整個(gè)請求(所有重試?yán)塾?jì))的全局超時(shí)時(shí)間(超過5秒直接失?。?/code>

這使我們能夠高效處理流量高峰,同時(shí)保持彈性。

責(zé)任編輯:武曉燕 來源: Springboot全家桶實(shí)戰(zhàn)案例源碼
相關(guān)推薦

2025-06-03 02:55:00

2022-08-17 09:54:57

Java性能優(yōu)化

2024-08-13 08:00:00

2024-06-28 09:39:58

2023-06-09 09:54:36

攜程工具

2021-08-17 10:08:44

HTML網(wǎng)站網(wǎng)絡(luò)

2011-02-22 10:23:34

2023-10-26 11:07:48

Golang開發(fā)

2024-07-26 07:59:25

2023-10-08 09:52:55

2022-10-08 13:13:14

Python程序性能

2024-03-07 08:08:51

SQL優(yōu)化數(shù)據(jù)

2024-03-12 10:02:31

Python內(nèi)存編程

2024-06-24 10:31:46

2025-05-29 04:00:00

2025-01-07 08:21:03

2025-01-26 10:49:52

2019-10-15 09:30:15

開源Spring BooJava

2023-03-13 07:40:44

高并發(fā)golang

2024-11-11 13:32:56

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號