Elastic 推出 RUM,最重要的一個目的,就是從效能的角度改善使用者體驗。
而改善使用者體驗的方式,也就是貼近使用者端,了解使用者行為動作中發生的事,其中包含:
RUM Agent 使用瀏覽器依照 W3C 提出規範的一些與 Timing 相關 API,來收集 Web 頁面的效能數據,包含以下四種 Timing APIs:
當中收集的資訊如下:
補充:所謂 LCP、FID、CLS 的定義如下 [6]:
- LCP (Largest Contentful Paint):最大內容完成繪製的時間,較佳的體驗會是在 2.5s 內完成。
- FID (First Input Delay):首次輸入的延遲,最好在 100m 以內。
- CLS (Cumulative Layout Shift):累計版面配置轉移,例如動態注入的內容,或是沒定位好的圖片載入,分數應該在 0.1 以內。
首先要在 APM Server 端啟用 RUM,在 apm-server.yml
中,定義相關的設定:
apm-server.rum.enabled: true
apm-server.auth.anonymous.rate_limit.event_limit: 300
apm-server.auth.anonymous.rate_limit.ip_limit: 1000
apm-server.auth.anonymous.allow_service: [your_service_name]
apm-server.rum.allow_origins: ['*']
apm-server.rum.allow_headers: ["header1", "header2"]
apm-server.rum.library_pattern: "node_modules|bower_components|~"
apm-server.rum.exclude_from_grouping: "^/webpack"
apm-server.rum.source_mapping.enabled: true
apm-server.rum.source_mapping.cache.expiration: 5m
apm-server.rum.source_mapping.index_pattern: "apm-*-sourcemap*"
apm-server.rum.enabled
:設定為 true
以啟用 RUM。apm-server.auth.anonymous.*
:由於 RUM 是從 Client 端直接存取 APM Server,所以要設定相關的 anonymouse
設定。apm-server.rum.*
相關的設定,細節可參考 APM Server - Configure RUM [7]。如果是使用 React, Vue, Angular 這些前端的框架進行開發,可以直接使用 APM RUM 已經準備好的套件。
npm install @elastic/apm-rum-react --save
npm install --save @elastic/apm-rum-vue
npm install @elastic/apm-rum-angular --save
並且參考 官方文件 - Framework-specific integrations 的範例說明。
一般安裝 APM RUM Agent 的方式有兩種:
script
tag 來宣告以及初始化 ( <version>
要改成指定的版本):<script src="https://<your-cdn-host>.com/path/to/elastic-apm-rum.umd.min-<version>.js" crossorigin></script>
<script>
elasticApm.init({
serviceName: '<instrumented-app>',
serverUrl: '<apm-server-url>',
})
</script>
npm install @elastic/apm-rum --save
並且在應用程式中,將 APM 初始化:
import { init as initApm } from '@elastic/apm-rum'
const apm = initApm({
// Set required service name (allowed characters: a-z, A-Z, 0-9, -, _, and space)
serviceName: '',
// Set custom APM Server URL (default: http://localhost:8200)
serverUrl: 'http://localhost:8200',
// Set service version (required for sourcemap feature)
serviceVersion: ''
})
另外大部份的環境中,APM Server 不會和 APM Agent 安裝的網站應用程式放在相同的網域的位置 (origin
),所以要記得設定 CORS (Cross-Origin Resource Sharing) [8],避免瀏覽器因為安全性限制而阻擋 APM Agent 對 APM Server 傳送資訊。
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Origin: [request-origin]
要產生 SourceMap 之前,要先取得或先定義好 Web 專案的版本號 serviceVersion
,這是為了讓不同版本之間的 SourceMap 能有效的對應到正確版本的 js
檔,所以會使用 serviceVersion
來當作比對的條件之一。
不同的前端打包或自動化工具會有不同的方式,如果是使用 WebPack 的話,會要加入類似於下方的宣告:
const webpack = require('webpack')
const serviceVersion = require("./package.json").version
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
entry: 'app.js',
output: {
filename: 'app.min.js',
path: './dist'
},
devtool: 'source-map',
plugins: [
new webpack.DefinePlugin({'serviceVersion': JSON.stringify(serviceVersion)}),
new TerserPlugin({
sourceMap: true
})
]
}
再針對產生出來的 SourceMap app.min.js.map
檔,透過 APM Server 的 /assets/v1/sourcemaps
API,上傳到 APM Server 中。
以下是 CURL 的範例:
SERVICEVERSION=`node -e "console.log(require('./package.json').version);"` && \
curl http://localhost:8200/assets/v1/sourcemaps -X POST \
-F sourcemap="@./dist/app.min.js.map" \
-F service_version="$SERVICEVERSION" \
-F bundle_filepath="http://localhost/app.min.js" \
-F service_name="myService"
-H "Authorization: ApiKey <token>"
另外也可以考慮將 SourceMap 上傳的動作,當作一個標準的 Deployment 步驟,可以透過 Configuration Management 的工具,例如:Ansible、Pupet、Chef...等,或是在 Node.js 裡在啟動時直接上傳。
當資料透過 APM Agents 收集進入 Elasticsearch 之後,我們可以直接從 Kibana \ Observability \ User Experience 的功能選單進入專門針對 RUM 建立的 Dashboard。
這部份主要是針對 Overview 來檢視,若是要觀看詳細的資訊,其實 RUM Agent 所收集的資料,也會是 APM 當中的其中一個 Services,所以我們到 Kibana > Observability > APM > Services 中,可以看到以 RUM 收集到的前端服務,進而可以追縱到特定頁面的載入行為,也能查看所有發生的 Errors,以及對應到 Logs。
同時使用 Elastic Observibility 最優勢的地方就是整合性,RUM 的資料透過和我們的 Distributed Tracing 整合,我們還能看到過程中後端服務執行的內容及每個 Span 處理,甚至是下了哪些 SQL 指令以及所花費的時間。
查看最新 Elasticsearch 或是 Elastic Stack 教育訓練資訊: https://training.onedoggo.com
歡迎追蹤我的 FB 粉絲頁: 喬叔 - Elastic Stack 技術交流
不論是技術分享的文章、公開線上分享、或是實體課程資訊,都會在粉絲頁通知大家哦!