#9 Jmeter và thế giới Performance Testing

#9 Jmeter và thế giới Performance Testing

November 11, 2020 2 By Nam Vu

Jmeter là công cụ để đo độ tải và performance của đối tượng, có thể sử dụng để test performance trên cả nguồn tĩnh và nguồn động, có thể kiểm tra độ tải và hiệu năng trên nhiều loại server khác nhau như: Web – HTTP, HTTPS, SOAP, Database via JDBC, LDAP, JMS, Mail – SMTP(S), POP3(S) and IMAP(S)… Jmeter là một mã nguồn mở được viết bằng java. Cha đẻ của JMeter là Stefano Mazzocchi sau đó Apache đã thiết kế lại để cải tiến hơn giao diện đồ họa cho người dùng và khả năng kiểm thử hướng chức năng.

Jmeter là mã nguồn mở được viết bằng java. Nó là một công cụ độc lập có thể chạy trên nhiều nền tảng hệ điều hành khác nhau, trên Linux chỉ cần chạy bằng một shell script, trên Windows thì chỉ cần chạy một file duy nhất. Bên cạch tính năng chính là xử lý đa luồng, giúp tạo nhiều request cùng một khoảng thời gian, xử lý các dữ liệu thu được một cách hiệu quả thì một đặc điểm nổi bật của Jmeter là có thể tích hợp plugin. Giống như Nuget của DotNet, Maven của Java đều là những chợ thư viên mã nguồn mở giúp tích hợp vào ứng dụng. Ở đây plugin trong jmeter cũng vậy, bạn có thể tự viết plugin và chia sẻ cho mọi người hoặc lấy những plugin của cộng đồng về sử dụng trong công việc của bản thân.

Ưu điểm:

– Kiểm tra tải và kiểm tra hiệu năng theo nhiều kiểu khác nhau: Web – HTTP, HTTPS, SOAP, Database via JDBC, LDAP, JMS, Mail – POP3(S) and IMAP(S).
– Rất nhẹ, không cần cài đặt, miễn phí.
– Nền tảng xử lý đa luồng cho phép mô phỏng nhiều mẫu bởi nhiều thread của các chức năng khác nhau trên các thread group khác nhau
– Dễ dàng thêm các plugin và tạo các báo cáo phù hợp yêu cầu.
– Được hỗ trợ mạnh bởi cộng đồng open source

Nhược điểm:

– JRE (Java Runtime Environment – Môi trường thực thi java) phải được cài đặt.
– Chỉ sử dụng được với ứng dụng web.
– Kết quả stress testing có thể khó xác định chính xác.
– Khó khăn khi thực hiện các kịch bản kiểm thử phức tạp.
– Khó thực hiện Recording

Cài đặt:

– Download Jmeter http://jmeter.apache.org/download_jmeter.cgi
– Sau khi download về giải nén và mở thư mục đó ra
– Trên win chạy file : jmeter.bat
– Trên ubuntu chạy file: jmeter.sh (Chú ý: Cần chắc chắn rằng máy tính đã được cài đặt Java)

Cách thức hoạt động:

Jmeter thực hiện giả lập một nhóm người dùng gửi các yêu cầu tới một máy chủ, nhận và xử lý các phản hồi từ máy chủ và cung cấp các kết quả báo cáo hiệu suất dưới dạng biểu đồ trực quan, dễ hiểu.

JMeter Performance Testing bao gồm:

Load testing: Mô hình hóa dự kiến sử dụng bởi nhiều người dùng truy cập một dịch vụ website trong cùng thời điểm.
Stress testing: Tất cả các web server có thể tải một dung lượng lớn, khi mà tải trọng vượt ra ngoài giới hạn thì web server bắt đầu phản hồi chậm và gây ra lỗi. Mục đích của stress testing là có thể tìm ra độ tải lớn mà web server có thể xử lý.

Các thuật ngữ cơ bản:

Test Plan: Bao gồm các bước sẽ được JMeter thực thi.
Thread Group: Đại diện cho người dùng ảo (virtual user), có thể gồm các thành phần sau:
Logic Controller: Cho phép điều chỉnh logic khi gửi các yêu cầu đến đối tượng cần kiểm tra.
Sampler: Cung cấp thông tin cho JMeter gửi các yêu cầu đến máy chủ cần kiểm tra. Tùy theo giao thức kiểm tra, JMeter hỗ trợ những loại sampler khác nhau.
Config Element: Sử dụng để thêm vào những thay đổi/ cấu hình cần thiết cho các sampler.
Timer: Điều chỉnh khoảng thời gian dừng giữa các lần gửi yêu cầu.
Listener: Cho phép thu thập thông tin kết quả. Có thể đưa ra các báo cáo kết quả kiểm tra dạng đồ thị, hoặc xuất ra tập tin.
Test Fragment: Một dạng đặc biệt của controller nhưng vẫn ở vẫn ở cấp Thread Group. Nó không phải là một phần của việc thực thi test trừ khi được tham chiếu bởi một trong hai Module Controller hoặc Include Controller.
Pre Processors: Được sử dụng để thực thi một số hành động trước khi Sampler Request được gửi đến máy chủ.
Post Processors: Được sử dụng để thực hiện một số hành động sau khi Sampler Request được thực thi và được gửi đến máy chủ.
Assertions: Bạn có thể nhận biết được request thực thi thành công hay không.
Number of Threads: Mỗi Thread đại diện cho một người dùng ảo, JMeter cho phép thay đổi số lượng người dùng không hạn chế để thực hiện các thử nghiệm.
Ram-Up Period: Thời gian để bắt đầu tất cả những Thread.
Loop Count: Số lần lặp lại những yêu cầu của người dùng. Ngoài ra còn có những tùy chọn khác như việc chạy các Thread vào lịch biểu định sẵn, xác định hành động sẽ thực hiện khi xảy ra lỗi
HTTP Request Defaults: Định nghĩa trang web mà mình sẽ thực hiện xuyên suốt kịch bản test.
Http request: Định nghĩa 1 request mô phỏng cho 1 chức năng/thao tác của user trên hệ thống.
View Results Tree: Báo cáo chi tiết kết quả thực hiện của từng request. Tại đây ta có thể xem lại dữ liệu request đó đã gửi đi, và dữ liệu nhận được từ phía server.
Summary report: Báo cáo tóm tắt kết quả thực hiện test.
View Results in Table: Chi tiết kết quả thực hiện từng request ở dạng bảng. (Chi tiết của dạng summary report)
Graph Results: Biểu đồ thống kê thời gian phản hồi và các tham số sau mỗi request được gửi đi.

Các thuật ngữ trong request:

Name: Đặt tên Request
Server name of IP: Điền vào Domain hoặc IP trang web mà mình đang cần test
Port Number: Chỉ ra port của web, nếu để trống thì sẽ default là 80
Protocol: Giao thức được sử dụng là HTTP hoặc HTTPs
Method: Phương thức để các HTTP request. có các method: GET, POST, HEAD, PUSH..
Path: Đường dẫn các nguồn để xử lý các request
Parameter: Biểu diễn danh sách các tham số để gửi cùng request (có thể thêm hoặc xoá thông số này)

Các thuật ngữ trong report:

Label: Hiển thị tên của từng requests có trong test plan
Samples: Tổng số lần run của request (Samples = Number of Thread (users)*Loop Count)
Average (millisecond): Thời gian phản hồi trung bình (Response Time) của request, tính cho đến lần run cuối cùng.
Median (millisecond): 50% số request có response time nhỏ hơn giá trị (hiển thị trên table), và 50% số request còn lại có response time lớn hơn giá trị này.
90% Line (90th Percentile) (millisecond): 90% số requests sẽ có response time nhỏ hơn giá trị hiển thị trong table, 10% số requests còn lại sẽ có response time lớn hơn giá trị hiển thị trong table.
Min (millisecond): Respone Time thấp nhất của request tính cho toàn bộ tất cả các lần run.
Max (millisecond): Respone Time cao nhất của request tính cho toàn bộ tất cả các lần run.
Error %: % số lượng request bị fail, lỗi.
Throughput/ Thông lượng: Lượng requests được hệ thống (server) xử lý trong 1 đơn vị thời gian, có thể là giây, phút, hoặc giờ. Avg. Bytes: dung lượng trung bình của 1 lần response tính bằng bytes.
Std.Dev.(Standard Deviation): độ lệch chuẩn đo lường sự thay đổi của 1 tập hợp data, dựa trên thống kê.
Total: Trong report có 1 dòng cuối cùng đó là Total, nó sẽ tổng kết lại toàn bộ kết quả từ những request bên trên.

Thật sự là có rất nhiều trang web cũng nhưng blog nói về Jmeter rồi nên trên đây mình chỉ liệt kê tóm tắt lại là chính. Nếu bạn đọc muốn tìm hiểu thêm có thể vào trực tiếp trang chủ của Jmeter để tìm đọc https://jmeter.apache.org/

Ở đây mình muốn nhất mạnh một vài ý mà không có trong tài liệu, phải trải qua chạy thực tế mới nhận ra được.

Thứ nhất, bản chất của performance test nói chung và jmeter nói riêng là giả lập call api giống hệt như browser mà người dùng gọi đến server. Bạn có thể bật tab network của browser khi vào một trang web có thể thấy được các thông số response giống hệt. Tuy nhiên Jmeter chỉ giả lập số người dùng đó gấp nhiều lần lên mà thôi.

Thứ hai, việc chạy performance test thực tế được gắn theo một quy trình khép kín tương tự như automation test. Khi source code được delivery (bàn giao ổn định nhất) hoặc thông số config thay đổi thì sẽ nhận được một trigger (phát tín hiệu) để có thể tự động chạy file jmx (file chứa script jmeter) thông qua command line (non-gui), do trên thực tế thì thường không chạy gui vì lý do bên thứ 3 bên dưới. Sau khi chạy xong với kết quả report là file jtl (file chứa các thông số response, pass, fail sau khi chạy script jmeter). Các thông số này sẽ được tổng hợp lại, phân tích và đẩy lên server report chứ không phải là xem từng file từng kịch bản. Có nhiều cloud server hỗ trợ quy trình tổng thể này như Aws, Azure hay bạn có thể tự xây dựng quy trình này kết hợp với Jenkin (Jenkins là một opensource dùng để thực hiện chức năng tích hợp liên tục gọi là CI – Continuous Integration và xây dựng các tác vụ tự động hóa)

Thứ 3, một máy có thể cài đặt môi trường chạy với nhiều luồng Jmeter với cùng một script chỉ khác nhau bộ data đầu vào thì sẽ cho kết quả tương đương thay vì chạy hết một bộ dữ liệu đó trong cùng 1 luồng Jmeter duy nhất. Giống như bạn đang phân tải nhiều người cùng chạy một kịch bản. Điều này tương tự với việc bạn chia ra nhiều máy với mạng LAN để cùng chạy một kịch bản. Vấn đề đặt ra ở đây là script của bạn phải chạy cùng một lúc và báo cáo report của bạn phải được tổng hợp của tất cả các luồng và tất cả các máy sau đó mới cho được báo cáo hoàn chỉnh. Để giải quyết vấn đề này thì bạn sẽ thực thi tất cả các máy và tất cả các luồng cùng một lúc qua command line (Jmeter đã support bạn có thể chạy non-gui)

Thứ 4, bạn có thể cài đặt trên nhiều máy nội bộ bên trên, tuy nhiên vấn đề này chỉ tốt khi mạng của bạn là mạng LAN hoặc không bị hạn chế. Khi xây dựng môi trường performance test sẽ bị ảnh hưởng bởi mạng internet khu vực khiến kết quả report không được chính xác. Giống như bạn vào một mạng lưới nội bộ và truy cập internet bị chậm do nội bộ tổ chức đó đã chặn băng thông cũng như lượng truy cập ra bên ngoài internet chung rồi. Do vậy cách giải quyết vấn đề này là cái đặt và chạy kiểm thử trên cloud với cùng một ý tưởng như mạng nội bộ. Điều này rất khách quan vì cloud thường có location khá giống với một user thực tế.

Thứ 5, bạn hãy tưởng tượng bạn truy cập vào 1 website, bạn thao tác giữa các bước hay các chức năng bạn có phải nghĩ không? Bạn có bị độ trễ giữa các thao tác click chuột hay nhập liệu không? Khi đó think time ra đời nhằm mục đích kiểm thử giống thực tế nhất. Tuy nhiên đối với mỗi loại trong performance test lại có một các config thông số khác nhau ví dụ như bạn kiểm tra độ chịu tải của hệ thống thì bạn cứ set kịch khung để xem website đó chịu được bao nhiêu request và bao lâu thì website đó sập.

Hoặc mỗi một kịch bản có độ khó dễ khác nhau ví dụ như bạn có thể kịch bản xem chi tiết một bài viết khác hẳn với kịch bạn đặt cọc đặt chỗ của một sàn giao dịch nào đó. Khi đó think time của các kịch bản cũng sẽ khác nhau

Cuối cùng là phải cùng một hệ quy chiếu về khái niệm CCU (Concurrent Users). Khái niệm này khá quan trọng giữa các bên, nếu các bên giữa khách hàng, đội ngũ kiểm thử và đội ngũ xây dựng phát triển mà hiểu sai hoặc không cùng một hệ quy chiếu sẽ dẫn tới nhiều vấn đề tranh cãi không đáng có.

CCU viết tắt của Concurrent Users (số người dùng cùng đồng thời)
Nếu các bạn đọc tài liệu về  tiếng Anh, sẽ đôi lúc thấy khái niệm “Simultaneous Users”, dịch ra tiếng Việt, nó cũng là “đồng thời”

Concurrent Users:
Được sử dụng để diễn tả việc nhiều users cùng đồng thời truy cập vào hệ thống nhưng những users này sẽ làm những action khác nhau. Lấy ví dụ, một nhóm users cùng truy cập vào ứng dụng thương mại điện tử, trong số này sẽ có người thực hiện login, khi người khác đang tìm kiếm sản phẩm, các users khác đang add to cart, và số còn lại thì đang place order. Vậy khi giả lập số users để run test plan tương ứng với ví dụ trên, nó sẽ được gọi là Concurrent User.

Simultaneous Users:
Cũng dùng để thể hiện việc sử dụng nhiều users cùng đồng thời truy cập vào ứng dụng, nhưng tất cả những users đó đều thực hiện chung một actions. Vẫn là ví dụ ở trên, nhưng nhóm users này chỉ làm một việc duy nhất đó là place order. Vậy những users này sẽ được gọi là Simultaneous Users lúc mà bạn giả lập test plan để run một performance test trong trường hợp tương tự.

Một số điểm cần chú ý giữa Concurrent Users và Simultaneous Users
– Cả hai khái niệm này đều có chung một ý là “cùng đồng thời”, nhưng “concurrent” thì dùng cho nhiều loại actions khác nhau, còn “simultaneous” thì chỉ một loại action duy nhất.
– Có thể hiểu “Simultaneous” là một trường hợp con của Concurrent
– Thông thường với thực tế, trong một hệ thống thì số lượng “Concurrent Users” sẽ nhiều hơn số lượng “Simultaneous Users”

Bạn hãy tưởng tượng bạn có thể vừa lái xe và vừa nghe điện thoại nhưng bạn sẽ không thể vừa ngủ vừa đọc sách. Đây là nguyên nhân chính khiến các bên gây tranh cãi với hệ quy chiếu này.

Bài toán thực tế ở đây mà khi chạy performance test nói chung cũng như jmeter nói riêng là bạn đã chia ra nhiều kịch bản rồi, bạn phải đánh giá xem với kịch bản đó sẽ có độ phức tạp ra sao sau đó gắn thông số CCUs vào với kịch bản đó phù hợp, sau cùng tổng số lượng CCUs cho tất cả các kịch bản sẽ là con số phù hợp nhất.

Ví dụ mục tiêu website trên spiderum là 5000 CCUs tức là cùng 1 thời điểm có chịu tải được tối đa 5000 người cho tất cả các kịch bản. Như vậy mình sẽ phải đánh giá là chức năng tìm kiếm sẽ có lượng người truy cập nhiều hơn chức năng đăng bài. Lúc đó mình sẽ chia 2000 CCUs cho kịch bản tìm kiếm, 500 CCUs cho kịch bản đăng bài, 300 CCUs cho kịch bản bình luận, 200 CCUs cho kịch bản theo dõi, 1500 CCUs cho kịch bản upvote/downvote, 500 CCUs cho kịch bản chẳng có mục đích dạo vòng vòng xem mấy bài viết chơi.
Còn nếu bạn hiểu sai hệ quy chiếu với tôi, bạn cho rằng 5000 CCUs là phải 5000 thằng cùng tham gia vào 1 kịch bản duy nhất là đăng nhập và xem cùng 1 bài viết. Tự nhiên hệ thống sẽ bị thắt cổ chai ở bước login. Đó là tấn công chứ không phải là kiểm thử.

Suy cho cùng kiểm thử cũng phải phù hợp với thực tế một chút, đối với performance testing thì mọi người có thể chỉ cần sử dụng khái niệm VUser (Virtual User) là đủ, thay cho hai từ vựng ở trên. VUser ở đây sẽ đại diện cho “Real User”, hiểu đơn giản là vậy. Một test plan hiệu quả thì sẽ mô phỏng được các real user’s behavior càng giống càng tốt, nếu không, kết quả test cuối cùng của bạn có tốt như thế nào cũng khó lòng mà kết luận chính xác được.

Đến đây thôi, những lưu ý ngoài lề bên trên là những kinh nghiệm mà mình gặp phải thông qua dự án thực tế nên hi vọng có thể giúp bạn được phần nào đó trên con đường kiểm thử hiệu năng này