成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

性能優化!七個策略,讓Spring Boot 處理每秒百萬請求

人工智能 機器學習
在實施任何優化前,我首先明確了性能基準。這一步至關重要——若不清楚起點,便無法衡量進展,也無法定位最關鍵的改進方向。

環境:SpringBoot3.4.2

1. 簡介

在實施任何優化前,我首先明確了性能基準。這一步至關重要——若不清楚起點,便無法衡量進展,也無法定位最關鍵的改進方向。以下是我們的初始性能指標概況:

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

平均響應時間:350 毫秒

95 分位響應時間:850 毫秒

峰值時段 CPU 使用率:85%-95%

內存占用:堆內存使用達可用空間的 75%

數據庫連接:頻繁達到連接池上限(100 )

線程池飽和:線程池資源經常耗盡

以上指標通過如下的工具進行收集所得:

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

根據上面的指標總結如下性能瓶頸:

  • 線程池飽和默認的 Tomcat 連接器已達到性能上限
  • 數據庫連接爭用HikariCP 連接池配置未針對實際負載優化
  • 序列化效率低下Jackson 在請求/響應處理中消耗大量 CPU 資源
  • 阻塞式 I/O 操作尤其在調用外部服務時表現明顯
  • 內存壓力過度對象創建導致頻繁的 GC 停頓 

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

2. 性能優化

2.1 使用響應式編程

阻塞方式:

@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)) ;
  }
}

基于響應式改造:

@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)));
    }
  }
}

同時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());
  }
}

注意,對應依賴方面你需要引入如下相關的依賴:

<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>
<!--基于響應式的mysql驅動包-->
<dependency>
  <groupId>com.github.jasync-sql</groupId>
  <artifactId>jasync-r2dbc-mysql</artifactId>
  <version>2.1.24</version>
</dependency>

總結:僅這一項改動便使吞吐量翻倍,其核心在于更高效地利用線程資源。WebFlux 不再為每個請求分配獨立線程,而是通過少量線程處理海量并發請求。

有關響應式編程,請查看下面文章:

新一代WebFlux框架核心技術Reactor響應式編程基本用法

響應式編程引領未來:WebFlux與R2DBC的完美結合實現數據庫編程

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

新一代web框架WebFlux到底要不要學?

2.2 數據庫優化

數據庫交互成為下一個關鍵性能瓶頸。我采用了三管齊下的優化策略:

  • 查詢優化

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

優化前:

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

優化后:

@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 優化 N+1 查詢:

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

HikariCP 的默認設置造成了連接爭用。經過大量測試,我得出了這樣的配置(實際要根據自己的環境):

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

關鍵的一點是,連接數并不總是越多越好;這里的hikari可不支持響應式。所以,我們應該吧響應式與阻塞式2種方式進行分開處理。

基于響應式數據庫的配置如下:

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

對于頻繁訪問的數據添加了 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

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

2.3 序列化優化

通過優化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。

關于Protocol Buffers的使用,請查看下面文章:

接口優化!Spring Boot 集成 Protobuf 并使用 RestTemplate 實現微服務間通信

基于 Spring Boot 實現自定義二進制數據傳輸協議

2.4 線程池&連接優化

有了 WebFlux,我們需要調整 Netty 的事件循環設置:

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

對于使用 Spring MVC 的,調整 Tomcat 連接器:

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

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

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

通過橫向擴展提升系統容量。將應用容器化后部署至 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

然后根據 CPU 利用率配置自動縮放:

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

利用 Istio 實施服務網格功能,以實現更好的流量管理:

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

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

責任編輯:武曉燕 來源: Springboot全家桶實戰案例源碼
相關推薦

2025-06-03 02:55:00

2022-08-17 09:54:57

Java性能優化

2024-08-13 08:00:00

2024-06-28 09:39:58

2023-10-26 11:07:48

Golang開發

2023-06-09 09:54:36

攜程工具

2021-08-17 10:08:44

HTML網站網絡

2011-02-22 10:23:34

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優化數據

2024-06-24 10:31:46

2024-03-12 10:02:31

Python內存編程

2025-05-29 04:00:00

2023-03-13 07:40:44

高并發golang

2019-10-15 09:30:15

開源Spring BooJava

2025-01-26 10:49:52

2025-01-07 08:21:03

2024-11-11 13:32:56

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一区在线视频 | 成人在线电影网站 | 亚洲欧美在线视频 | 国产精品久久一区二区三区 | 亚洲视频免费观看 | 久久精品免费一区二区 | 在线免费观看日本视频 | 在线免费看黄 | 91精品国产麻豆 | 一级做a爰片性色毛片视频停止 | 中日av| 精品久久久久久红码专区 | av中文字幕在线观看 | 国产一区二区三区四区 | 一区二区三区四区国产 | 国产欧美一区二区三区国产幕精品 | 九九综合九九 | 国产片侵犯亲女视频播放 | 欧美视频免费在线 | 精品在线一区二区三区 | 日韩欧美在线观看一区 | 久久免费看 | 女同久久另类99精品国产 | 日一区二区 | 亚洲一区二区精品 | 日本天堂视频 | 免费簧片视频 | 天天操操 | 男女啪啪网址 | 久久久久国产一区二区三区 | 三级av在线 | 精品免费| 97精品超碰一区二区三区 | 中文字幕 在线观看 | 黄色一级免费 | 毛片在线视频 | 国产精品国产馆在线真实露脸 | 午夜av电影| 国内精品伊人久久久久网站 | 久久综合伊人 | 成人网在线 |