Làm thế nào để làm nóng các lớp java để tránh cuộc gọi đầu tiên chậm?


13

Tôi đang thực hiện một dự án trong đó tôi cần tất cả các lệnh gọi API để thực hiện dưới 1 giây nhưng tôi gặp phải vấn đề với cuộc gọi đầu tiên đến mỗi tuyến chậm hơn các tuyến sau.

Hiện tại, cuộc gọi đến / đăng nhập đầu tiên mất 3,6 giây và các cuộc gọi tiếp theo mất 170ms và tương tự cho tất cả các tuyến khác.

Tôi phát hiện ra -XX:+TraceClassLoadingrằng trong cuộc gọi đầu tiên, các lớp được tải trong bộ nhớ và điều đó gây ra vấn đề về hiệu năng.

Tuy nhiên, tôi không tìm thấy một cách dễ dàng để tải tất cả các lớp khi bắt đầu và đối với mỗi dịch vụ mới, tôi cần thêm một cuộc gọi khởi động trong ApplicationRunner.

Có ai có giải pháp để tự động tải các lớp của ứng dụng SpringBoot hoặc làm nóng tất cả các tuyến của nó không?


Bạn có thể thêm chi tiết? Là ứng dụng của bạn ngay lập tức kiểm soát? Hay bạn đang gọi các dịch vụ khác? Làm thế nào bạn thực hiện các cuộc gọi đến các dịch vụ khác?
Menios

Spring Boot sử dụng quét lớp mạnh mẽ, do đó bạn không cần phải 'làm nóng' bất cứ thứ gì như trên ứng dụng máy tính để bàn. Tải ban đầu dài này có thể là kết quả của tìm kiếm tài nguyên - ví dụ tải mẫu trang.
Alex Chernyshev

Một chút về cách tiếp cận gián tiếp: nếu bạn có phạm vi kiểm tra đơn vị 100% cho các điểm cuối, bạn có thể sử dụng chúng. Bạn vẫn sẽ phải mã cho mỗi điểm cuối nhưng bạn có được thứ gì đó
Đã kết thúc vào

1
Có thể không lý tưởng tùy thuộc vào dự án bạn đang thực hiện, nhưng bạn có thể gọi điểm cuối của mình trong nội bộ khi ứng dụng của bạn được tải.
omoshiroiii

@omoshiroiii không có sai với điều đó. chúng tôi làm điều đó. trong sản xuất. lý do phải làm với một số thư viện động sử dụng invokedynamicvà chúng tôi biết độ phân giải chậm trong cuộc gọi đầu tiên (chúng tôi có hàng chục ngàn cuộc gọi như vậy, mà không có cuộc gọi đầu tiên này tích lũy đến hàng chục giây).
Eugene

Câu trả lời:


1

Tải lớp của Java là lười biếng. Điều này có nghĩa là một lớp chỉ được JVM tải khi nó cần và nếu nó cần.

Nếu bạn muốn buộc nó tải các lớp một cách háo hức, bạn chỉ cần tham khảo chúng. Một cách để làm điều đó là lặp qua các nội dung jar hoặc tệp lớp để lấy tên lớp và sau đó sử dụng chúng để gọi Class.forName(className).

Ngoài ra, nếu thời gian khởi động và hiệu suất rất quan trọng đối với trường hợp sử dụng của bạn, bạn có thể muốn xem xét các giải pháp biên dịch trước thời gian như GraalVM hoặc giảm ngưỡng của JIT để biên dịch ( -XX:CompileThreshold).


không ai trong số họ sẽ giải quyết vấn đề của OP. tải vẫn còn lười biếng trong GraalVM và thực sự JITvô nghĩa đối với các lệnh đầu tiên , thực sự.
Eugene

Ngoài ra, GraalVMlà tốt, nhưng xin vui lòng xem số lượng các vấn đề có trong github: ngay khi bạn đi từ một dự án hộp cát đến một cái gì đó lớn hơn (chủ yếu là tôi đang nhìn vào phản xạ của bạn), bạn sẽ bị đau, ít nhất. quan điểm của tôi là: trao đổi với GraalVM không phải là một ngón tay đơn giản.
Eugene

Tôi đã nghĩ về việc tải các lớp trong jar nhưng tôi không tìm thấy cách nào để làm điều đó, bạn có một ví dụ không?
Ybri

@Eugene nếu bạn đọc câu trả lời của tôi, bạn sẽ thấy rằng tôi chưa nói GraalVM hoặc ngưỡng JIT sẽ thay đổi sự lười biếng của việc tải lớp. Câu trả lời cho câu hỏi của OP liên quan đến sự lười biếng là đoạn trước đó. Đoạn cuối chỉ là một mẹo bổ sung trong trường hợp OP cần tối ưu hóa hơn nữa thời gian / hiệu suất khởi động ngoài tải lớp.
andresp

1
@Ybri có những câu hỏi khác với câu trả lời ở đây, ví dụ stackoverflow.com/questions/2370867/ Lời
andresp

0

Đối với tôi, tùy chọn khả thi duy nhất bạn có là class data sharing, trải rộng trên JEP 310 , JEP 341JEP 350 , nhưng điều này đòi hỏi java-13 rất có thể. Chúng tôi đang thử nghiệm nội bộ này tại nơi làm việc của tôi (chủ yếu là để giải trí, không nói dối) và cho đến nay kết quả có vẻ tốt.

Tùy chọn khác đang gọi điểm cuối của bạn khi ứng dụng khởi động - nếu đó là một tùy chọn. Một lần nữa, đó cho chúng tôi ví dụ: chúng tôi gọi chúng bằng dữ liệu giả một vài trăm lần để làm nóng mã. Nhưng, đồng thời, chúng tôi có các dịch vụ trong đó điều này là không thể - đó là lý do tại sao việc khám phá CDSquá.


Làm thế nào để bạn xử lý xác thực và các điểm cuối bài để tránh việc tạo dữ liệu trong cơ sở dữ liệu sản xuất của bạn?
Ybri

@Ybri chính xác tại sao tôi nói, không thể đối với một số người.
Eugene
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.