Computer >> Máy Tính >  >> Lập trình >> Ruby

Kiểm tra hiệu suất, căng thẳng và tải trong Rails

Kiểm tra là một phần không thể thiếu của hầu hết các ứng dụng Rails đang hoạt động tốt, nơi bảo trì không phải là cơn ác mộng và các tính năng mới được bổ sung liên tục hoặc các tính năng hiện có được cải thiện. Thật không may, đối với nhiều ứng dụng, môi trường sản xuất là nơi lần đầu tiên chúng phải chịu khối lượng công việc lớn hoặc lưu lượng truy cập đáng kể. Điều này có thể hiểu được vì những thử nghiệm như vậy rất tốn kém.

Rất may, Rails hỗ trợ tốt không chỉ cho các bài kiểm tra đơn vị, đầu cuối và tích hợp mà còn cho các bài kiểm tra liên quan đến hiệu suất và tải. Tôi sẽ trình bày tất cả chúng trong bài viết và đưa ra một số ví dụ thực tế sẽ giúp bạn hiểu cách sử dụng hiệu quả các công cụ kiểm tra mức hiệu suất của ứng dụng của bạn.

Bài báo được chia thành hai phần:

  • Lý thuyết - Tôi sẽ chỉ cho bạn lý do tại sao cần kiểm tra, các loại kiểm tra chúng tôi có thể thực hiện và các chỉ số cần thiết khi thực hiện kiểm tra trên một ứng dụng

  • Thực tế - chúng tôi sẽ làm bẩn tay và viết các bài kiểm tra cho một ứng dụng thực tế để có được kết quả đầu ra

Sau khi đọc hai phần, bạn sẽ hiểu sâu hơn về các loại kiểm tra khác nhau và cách thực hiện chúng trên ứng dụng Rails của bạn. Nghe có vẻ thú vị? Sau đó, hãy bắt đầu với một chút lý thuyết về các bài kiểm tra.

Kiểm tra lý thuyết

Kiểm tra luôn phải là một phần vốn có của sự phát triển của bất kỳ loại ứng dụng nào. Nếu bạn vẫn chưa bị thuyết phục về điều đó hoặc chưa viết bất kỳ bài kiểm tra nào, thì đây là một số lập luận để kiểm tra sẽ giúp bạn:

  • Giới thiệu các thay đổi mà không lo lắng về việc vi phạm điều gì đó - đây là lý do chính tại sao các thử nghiệm là cần thiết. Hãy tưởng tượng làm việc trên một ứng dụng lớn, nơi bạn phải nhấp qua toàn bộ ứng dụng để đảm bảo không có gì bị hỏng mỗi khi bạn giới thiệu một số thay đổi, dù chỉ là một thay đổi nhỏ. Với các bài kiểm tra, bạn chỉ cần thực hiện một lệnh và quá trình xác minh diễn ra tự động và nhanh chóng.
  • Quy trình tái cấu trúc dễ dàng - Tôi đã đề cập ở trên rằng các bài kiểm tra là điều cần thiết khi thêm các tính năng mới hoặc thực hiện thay đổi. Với thử nghiệm tại chỗ, bạn cũng cảm thấy thoải mái hơn khi cải thiện mã hiện có của mình.
  • Kiểm tra là một dạng tài liệu - các bài kiểm tra được viết tốt có thể là một dạng tài liệu cho các bộ tính năng khác nhau trong ứng dụng. Họ không chỉ mô tả tính năng là gì mà còn cả cách hoạt động của tính năng này.
  • Cơ hội để xem xét lại việc triển khai - khi bạn viết một bài kiểm tra, bạn có cơ hội suy nghĩ lại xem cách bạn muốn triển khai mã có đúng và hợp lý hay không. Ngoài ra, bạn chỉ cần kiểm tra xem mã của mình có đang hoạt động theo cách bạn mong đợi hay không.

Tôi hy vọng những lập luận trên đã thuyết phục bạn sử dụng các bài kiểm tra trong quá trình phát triển bất kỳ ứng dụng nào. Mặc dù biết lý do tại sao phải kiểm tra mã là điều cần thiết, nhưng việc tìm hiểu về các loại kiểm tra khác nhau cũng rất quan trọng.

Các loại kiểm tra khác nhau

Có ba loại kiểm tra chính mà bạn có thể viết để đảm bảo rằng hiệu suất ứng dụng Rails của bạn là chính xác và cơ sở hạ tầng đang hoạt động tốt trong điều kiện khối lượng công việc lớn. Các loại đó như sau:

  • Kiểm tra tải - loại kiểm tra này trả lời câu hỏi sau:hệ thống có thể xử lý bao nhiêu người dùng đồng thời trong một khoảng thời gian nhất định. Hãy tưởng tượng rằng bạn tung ra một sản phẩm được xếp hạng hàng đầu trên trang web của mình và hàng nghìn người dùng muốn đặt hàng cùng một lúc. Nếu không có các thử nghiệm tải phù hợp, bạn có nguy cơ gặp sự cố trong thời điểm quan trọng nhất.
  • Kiểm tra căng thẳng - với loại kiểm tra này, bạn không tập trung vào việc xác minh số lượng người dùng mà hệ thống có thể xử lý đồng thời mà vào cách hệ thống sẽ hoạt động khi đạt đến giới hạn số người dùng.
  • Kiểm tra hiệu suất - Tôi có thể nói rằng loại thử nghiệm này là cha mẹ của thử nghiệm căng thẳng và tải trọng. Mục đích chính của các thử nghiệm như vậy là để có được một bộ chỉ số cụ thể, dựa vào đó chúng tôi có thể thực hiện một số hành động để cải thiện mã của ứng dụng. Tôi sẽ nói về các chỉ số đó sau một thời gian.

Nói như vậy, bây giờ chúng ta đã chuẩn bị để chuyển sang bước cuối cùng của phần lý thuyết:tìm hiểu những số liệu nào là cần thiết khi thực hiện kiểm tra hiệu suất trên ứng dụng Rails. Nếu không có kiến ​​thức đó, chúng tôi sẽ không diễn giải chính xác kết quả kiểm tra và quyết định xem chúng tôi có nên thay đổi mã hay không.

Các chỉ số quan trọng

Loại số liệu bạn có thể nhận có thể khác nhau tùy thuộc vào công cụ bạn sử dụng để thử nghiệm, nhưng nói chung, chúng tôi có thể nhóm chúng thành một tập hợp các số liệu khá phổ biến:

  • Thời gian phản hồi - khoảng thời gian từ khi yêu cầu được thực hiện đến khi phản hồi được hiển thị trong trình duyệt. Chỉ số này cho chúng ta biết người dùng cần đợi bao lâu trước khi nhận được thông tin mà họ yêu cầu. Đôi khi nó được gọi là thời gian xử lý.
  • Sử dụng bộ nhớ - dung lượng bộ nhớ được sử dụng cho yêu cầu nhất định. Đây là một phần thông tin cần thiết vì nó chỉ cho bạn nơi bạn có thể cải thiện mã để hệ thống có thể phản hồi nhanh hơn và sử dụng ít tài nguyên hơn.
  • Phân bổ đối tượng - phân bổ bộ nhớ cao gây ra việc sử dụng bộ nhớ cao và thời gian phản hồi lâu. Chỉ số này có thể dẫn bạn đến vị trí chính xác trong mã nơi nhiều đối tượng được phân bổ, vì vậy bạn có thể kiểm tra ngay lập tức.

Bạn có thể có nhiều chỉ số hơn khi thử nghiệm, nhưng ba chỉ số đó là quan trọng nhất và sẽ có giá trị cho bất kỳ ứng dụng nào bạn thử nghiệm. Giờ đây, chúng tôi có thể làm bẩn tay và viết các bài kiểm tra thực tế.

Thực hành

Chúng tôi không thể viết bài kiểm tra mà không có thứ gì đó để kiểm tra. Đó là lý do tại sao bước đầu tiên trong phần thực hành là viết một ứng dụng Rails đơn giản mà chúng ta có thể viết các bài kiểm tra.

Ứng dụng Đường ray Mẫu

Tôi sẽ sử dụng Ruby 3.0.1 và Rails 6.1.3.1 nhưng hãy thoải mái sử dụng bất kỳ phiên bản nào bạn cảm thấy thoải mái. Nếu bạn đã cài đặt Ruby và Rails, bước tiếp theo là tạo khung của ứng dụng:

rails new simpleapp -d=postgresql

Với mục đích của bài viết, tôi sẽ tạo một ứng dụng trong đó danh sách người dùng được hiển thị cùng với tên thú cưng của họ. Cấu trúc như vậy sẽ cho phép chúng tôi dễ dàng tạo các truy vấn N + 1 sẽ mang lại nhiều niềm vui hơn khi thực hiện các bài kiểm tra hiệu suất và kiểm tra tác động đến tốc độ và các chỉ số khác sẽ có những thay đổi.

Trước khi chúng tôi tạo mô hình, trước tiên hãy tạo cơ sở dữ liệu:

cd simpleapp/
bin/rails db:create

Bây giờ, chúng ta có thể tạo các mô hình:

rails g model User name:string
rails g model Animal name:string user:references
bin/rails db:migrate

Chỉ một bản cập nhật nhỏ cho User mô hình để phản ánh mối quan hệ với Animal mô hình:

Người dùng
class User < ApplicationRecord
  has_many :animals
end

Bây giờ chúng ta có thể thêm một số hạt giống trong db/seeds.rb tệp:

people = {
  'Tim' => ['Pinky', 'Rick'],
  'Martha' => ['Rudolph'],
  'Mark' => ['Niki', 'Miki', 'Bella'],
  'Tina' => ['Tom', 'Luna']
}
 
people.each_pair do |name, pets|
  user = User.create(name: name)
  pets.each do |pet_name|
    user.animals.create(name: pet_name)
  end
end

và tải dữ liệu vào cơ sở dữ liệu:

bin/rails db:seed

Tôi sẽ tạo một bộ điều khiển với sự chỉ định của người dùng và sau đó, trong chế độ xem, tôi sẽ liệt kê tất cả người dùng với tên thú cưng của họ. Tôi đang cố ý sử dụng mã gây ra sự cố về hiệu suất để bạn có thể đo lường các cải tiến sau này.

touch app/controllers/home_controller.rb
mkdir app/views/home
touch app/views/home/index.html.erb

Bộ điều khiển rất đơn giản:

class HomeController < ApplicationController
  def index
    @users = User.all
  end
end

và chế độ xem cũng:

<h1>List</h1>
 
<ul>
  <% @users.each do |user| %>
    <li><%= user.name %> (<%= user.animals.count %>)
      <ul>
        <% user.animals.each do |animal| %>
          <li><%= animal.name %></li>
        <% end %>
      </ul>
    </li>
  <% end %>
</ul>

Bước cuối cùng là cập nhật config/routes.rb để cho Rails biết những gì chúng tôi muốn xem khi truy cập vào URL chính:

Rails.application.routes.draw do
  root to: 'home#index'
end

Kiểm tra tải với JMeter

JMeter là một phần mềm mã nguồn mở được tạo ra bởi nền tảng phần mềm Apache, được thiết kế để tải hành vi chức năng kiểm tra. Vì đây là một chương trình được tạo bằng Java nên bạn có thể cài đặt nó trên bất kỳ hệ điều hành nào. Bạn có thể tải xuống các tệp tại đây:https://jmeter.apache.org/download_jmeter.cgi

Nếu bạn đang làm việc trên hệ thống macOS, bạn có thể dễ dàng cài đặt JMeter với Homebrew:

brew install jmeter

Sau khi cài đặt, bạn có thể chạy chương trình bằng lệnh sau:

jmeter

Định cấu hình bài kiểm tra

Quá trình cấu hình bao gồm các bước sau:

  • Thêm nhóm chủ đề - chỉ định số lượng người dùng và thời gian mỗi người sẽ truy cập trang web của bạn
  • Định cấu hình yêu cầu HTTP - chỉ định điểm cuối mà JMeter sẽ truy cập
  • Đặt các chỉ số mà chúng tôi quan tâm

Hãy cùng hướng dẫn từng bước qua một cấu hình thử nghiệm đơn giản để mô phỏng một yêu cầu của người dùng đến trang chính của ứng dụng đơn giản mà chúng tôi đã tạo trước đây.

Thêm nhóm chuỗi

Chọn Thêm -> Chủ đề (Người dùng) -> Nhóm Chủ đề từ menu mở rộng sau khi bạn nhấp chuột phải vào “Kế hoạch kiểm tra”:

Chỉ định số lượng người dùng và các thuộc tính bổ sung:

Định cấu hình yêu cầu HTTP

Nhấp chuột phải vào chuỗi mà chúng ta đã tạo ở bước trước và chọn Thêm -> Trình lấy mẫu -> Yêu cầu HTTP:

Định cấu hình giao thức, tên máy chủ, cổng và đường dẫn của yêu cầu:

Chỉ định chế độ xem kết quả

Nhấp chuột phải vào yêu cầu HTTP và chọn Thêm -> Trình nghe -> Xem Cây kết quả:

Chạy thử nghiệm

Kiểm tra hiện đã được định cấu hình và chúng tôi có thể kích hoạt nó. Để thực hiện việc này, chỉ cần nhấp vào nút phát màu xanh lục:

Như bạn có thể thấy, ứng dụng đã vượt qua bài kiểm tra, nhưng nó chỉ là một yêu cầu duy nhất, vì vậy kết quả là hiển nhiên. Bây giờ bạn có thể thử nghiệm với số lượng người dùng và các tùy chọn cấu hình khác để xem ứng dụng sẽ hoạt động như thế nào. Từ các thử nghiệm của tôi, ứng dụng đơn giản bắt đầu gặp sự cố khi khoảng 200 người dùng bắt đầu truy cập đồng thời.

Các bước tiếp theo

Sau khi thực hiện kiểm tra tải, bạn sẽ biết những điểm khó khăn của ứng dụng của mình. Hiểu được giới hạn người dùng, bây giờ bạn có thể thực hiện kiểm tra căng thẳng để xem ứng dụng sẽ hoạt động như thế nào.

Kiểm tra hiệu suất với Ruby-prof

Tính năng kiểm tra hiệu suất được tích hợp sẵn trong Rails cho đến phiên bản 3 và sau đó nó được trích xuất sang gem riêng https://github.com/rails/rails-perftest. Vì tôi gặp một số vấn đề khi sử dụng nó với phiên bản Rails mới nhất, tôi quyết định không đưa nó vào bài viết này. Thay vào đó, tôi sẽ sử dụng thư viện ruby-prof hoạt động rất tốt.

Như thường lệ, bước đầu tiên là thêm đá quý vào ứng dụng của chúng tôi:

bundle add ruby-prof

Bước thứ hai và là bước cuối cùng của quá trình cấu hình là cập nhật config/application.rb và sử dụng phần mềm trung gian cho gem để thư viện có thể tự động kiểm tra các yêu cầu của chúng tôi và tạo báo cáo dựa trên chúng:

module Simpleapp
  class Application < Rails::Application
    config.middleware.use Rack::RubyProf, :path => './tmp/profile'
  end
end

Giờ đây, bạn có thể truy cập ứng dụng và mỗi khi bạn thực hiện một yêu cầu, viên ngọc sẽ tạo ra một báo cáo mới. Nó trông như thế này:

Bạn có thể tìm thấy nó theo đường dẫn đã định cấu hình, là tmp/profile trong trường hợp của chúng ta. Báo cáo thứ hai cũng được tạo và nó hiển thị ngăn xếp cuộc gọi, đây cũng là một số liệu khá hữu ích khi gỡ lỗi các vấn đề về hiệu suất trong ứng dụng Rails.

Điều quan trọng cần nhớ là đặt cache_classescache_template_loading cài đặt thành true sẽ làm chậm ứng dụng và lấn át các chỉ số ứng dụng vì Rails sẽ cố gắng tải các tệp cần thiết.

Tóm tắt

Kiểm tra là một phần thiết yếu của mọi quá trình phát triển. Kiểm tra xem mã có hoạt động như chúng ta muốn hay không cũng quan trọng như xác minh xem các giải pháp của chúng tôi có hoạt động tốt hay không. Việc bỏ qua các bài kiểm tra sẽ dẫn đến các vấn đề nghiêm trọng ảnh hưởng đến hiệu suất của ứng dụng và lòng tin của người dùng. Hy vọng rằng việc kiểm tra không quá khó.

Trong bài viết này, chúng tôi đã đề cập đến các khía cạnh quan trọng sau của thử nghiệm:

  • lý do bạn nên kiểm tra mã của mình
  • các loại kiểm tra hiệu suất khác nhau
  • cách bạn có thể kiểm tra hiệu suất của ứng dụng Rails của mình

Tôi hy vọng rằng giờ đây bạn đã thuyết phục hơn tại sao việc viết bài kiểm tra lại quan trọng vì bạn biết lý do tại sao và làm thế nào.

Nếu bạn muốn theo dõi hiệu suất ứng dụng của mình không chỉ cục bộ mà còn trong môi trường sản xuất hoặc môi trường dàn dựng, bạn cũng nên xem AppSignal.

Tái bút. Nếu bạn muốn đọc các bài đăng của Ruby Magic ngay khi chúng xuất hiện trên báo chí, hãy đăng ký bản tin Ruby Magic của chúng tôi và không bao giờ bỏ lỡ một bài đăng nào!