12/08/2018, 13:56

Track performance với Skylight

I. Giới thiệu Xin chào các bác (lay2) Performance là một vấn đề rất quan trọng trong web app mà tất cả các developer đều phải quan tâm. Nhưng để xác định được vị trí, nguyên nhân làm giảm tốc độ trang web thì không phải là điều đơn giản, kể cả với những lập trình viên kinh nghiệm. Hôm nay ...

I. Giới thiệu

Xin chào các bác (lay2)

Performance là một vấn đề rất quan trọng trong web app mà tất cả các developer đều phải quan tâm.

Nhưng để xác định được vị trí, nguyên nhân làm giảm tốc độ trang web thì không phải là điều đơn giản, kể cả với những lập trình viên kinh nghiệm.

Hôm nay mình sẽ giới thiệu với các bạn một công cụ khá hữu ích, giúp dev xác định và cải thiện performance cho app của mình: Sky's light's

Nếu bạn đã từng nghe tới New Relic thì đúng rồi đấy, Skylight là tool gần tương tự như vậy. Tuy nhiên, nó được lược bỏ đi một số feature không hữu ích và focus vào Rails nhiều hơn.

Trang chủ: https://www.skylight.io

II. Demo

Để giới thiệu về Skylight, tôi sẽ xây dựng 1 app nho nhỏ.

Công việc cần làm:

  • Khởi tạo rails app
  • Setup Skylight
  • Track performance và sửa

Công cụ sử dụng:

  • Rails 4.2.1
  • Ruby 2.1.5

GLHF (honho)

1. Khởi tạo

Khởi tạo rails app, lấy tên là skylighter

rails new skylighter

Tạo ra 2 model có quan hệ 1-n với nhau để test phát

rails g model House name:string city:string
rails g model Character name:string house:references

Sau khi migrate xong, ta tạo ViewController cho trang index của House - show ra một list

class HousesController < ApplicationController
  def index
    @houses = House.all
  end
end

Trong file db/seed.rb ta tạo ra dữ liệu để hiển thị

30.times do
  house = House.create name: Faker::GameOfThrones.house, city: Faker::GameOfThrones.city
  20.times do
    house.characters.create name: Faker::GameOfThrones.character
  end
end

Phần view, ta làm đơn gian như sau

# index.html.erb
<h1>Houses</h1>
<ul>
  <%= render @houses %>
</ul>
# _house.html.erb
<li>
  House <strong><%= house.name %></strong> in <%= house.city %>
  <ul>
    <% house.characters.each do |char| %>
      <li><%= char.name %></li>
    <% end %>
  </ul>
</li>

Nội dung hiển thị đơn giản vậy thôi. Nếu bạn để ý kỹ, đoạn code trên đã mắc lỗi gây ảnh hưởng tới performance nhưng ... ༼ つ ◕_◕ ༽つ cứ để nó vậy đi .

Để implement Skylight vào app của ta khá đơn giản.

Như đã nói ở phần giới thiệu, Skylight forcus mạnh vào Rails nên ta đưa nó vào app chỉ trong 1 nốt nhạc (dance2)

Add thêm

# Gemfile
gem "skylight"

Sau khi chạy bundle install, hãy truy cập tới https://www.skylight.io/ để tạo tài khoản trier.

Create account xong, skylight sẽ cung cấp cho chúng ta 1 đoạn KEY để setup trên app.

bundle exec skylight setup KEY

File config/skylight.yml được generate ra, nội dung bên trong sẽ có dạng:

authentication: abczyz...

Đây là token kết nối tới Dashboard trên skylight, nhớ giấu nó đi (yaoming)

Skylight không support chạy trên development, cho nên để test, ta cần phải deploy

Mặc định, skylight chạy trên production, nếu muốn thử trên staging, ta thêm dòng sau vào application.rb.

config.skylight.environments += %w(staging)

Sau khi deploy xong, truy cập vào Dashboard của Skylight sẽ thấy nó đã bắt đầu tracking được

skydb6.png

Đây là trang tổng quan, cung cấp cái nhìn toàn cảnh về tốc độ hoạt động của app.

Phần Endpoints list ra toàn bộ các Views và Controller tương ứng với nó.

Bên cạnh tên Views nếu xuất hiện icon màu đỏ -> phía Skylight đã phát hiện vấn đề performance issue bên trong, ấn vào để xem chi tiết vị trí và vấn đề gặp phải là gì.

2. Xác định performance issue

Dựa biểu đồ mà Skylight track được, ta sẽ xác định vị trí của code mà ta đang gặp vấn đề về performance.

skydb3.png Ta hay chú ý vào biểu tượng bên trên mũi tên đỏ

Khi click vào đó, chú thích được hiện ra như sau:

skydb4.png

Skylight phát hiện ra có SQL query bị thực hiện lặp lại, dẫn đến giảm performance cho hệ thống.

Quay lại code phần Controller

class HousesController < ApplicationController
  def index
    @houses = House.all
  end
end

và View

# _house.html.erb
<li>
  House <strong><%= house.name %></strong> in <%= house.city %>
  <ul>
    <% house.characters.each do |char| %>
      <li><%= char.name %></li>
    <% end %>
  </ul>
</li>

Ta dễ dàng có thể thấy, hiện tại code đang mắc lỗi N + 1 Query.

Để khắc phục, sửa code phần Controller lại 1 chút

@houses = House.includes(:characters)

Kết quả sau khi deploy lại

skydb5.png

Cảnh báo lỗi đã biến mất, cùng với đó, tốc độ cũng tăng lên đáng kể (dance2)

GGWP

Source

  • github: https://github.com/nguyentanduc/skylighter

Nguồn tham khảo

  • https://docs.skylight.io/
  • http://blog.endpoint.com/2014/06/rails-performance-with-skylight.html
  • https://www.sitepoint.com/tracking-common-rails-performance-issues-with-skylight/
0