使用Elastic APM实现真实用户监控(RUM)
什么是RUM?
Elastic真实用户监控(RUM)能够捕获用户与Web浏览器的交互,从性能角度为您提供Web应用程序"真实用户体验"的详细视图。Elastic的RUM代理是一个JavaScript代理,这意味着它支持任何基于JavaScript的应用程序。
RUM可以为您提供有价值的应用洞察,常见优势包括:
- 帮助识别瓶颈并发现网站性能问题如何影响访问者体验
- 通过用户代理信息识别客户最常用的浏览器、设备和平台
- 结合位置信息,了解网站在全球范围内的区域性能
- 为应用程序的服务水平协议(SLA)提供洞察和衡量
- 收集客户访问和点击行为信息,帮助开发团队识别新功能的影响
使用Elastic APM开始RUM监控
本文将逐步介绍如何对一个由React前端和Spring Boot后端组成的简单Web应用程序进行完整的插桩过程。
前提条件
要使用Elastic APM真实用户监控,必须安装带有APM服务器的Elastic Stack。最简单的方法是创建一个云试用帐户,在几分钟内准备好集群。
示例应用程序
我们将要插桩的应用程序是一个简单的汽车数据库应用,包含React前端和提供内存汽车数据库API访问的Spring Boot后端。
创建CarApp目录并克隆前端和后端应用:
1
2
|
git clone https://github.com/carlyrichmond/carfront
git clone https://github.com/carlyrichmond/cardatabase
|
RUM开箱即用的丰富插桩
要开始使用RUM,需要启用RUM来捕获来自RUM代理的事件。设置RUM代理有两种方式:
- 通过包管理器安装RUM代理:
1
|
npm install @elastic/apm-rum --save
|
- 通过HTML脚本标签包含RUM代理:
1
2
3
4
5
6
7
8
|
<script src="https://unpkg.com/@elastic/apm-rum@5.12.0/dist/bundles/elastic-apm-rum.umd.min.js"></script>
<script>
elasticApm.init({
serviceName: 'carfront',
serverUrl: 'http://localhost:8200',
serviceVersion: '0.90'
})
</script>
|
对于React应用,我们使用第一种方法。安装完成后,在rum.js中查看初始化代码:
1
2
3
4
5
6
7
8
9
|
import { init as initApm } from '@elastic/apm-rum'
var apm = initApm({
serviceName: 'carfront',
serviceVersion: '0.90',
serverUrl: 'APM_URL',
})
export default apm;
|
配置说明
- 服务名称:必须设置,代表APM UI中的应用程序
- 服务版本:应用程序版本号,APM服务器使用此版本号查找正确的源映射
- 服务器URL:APM服务器URL,通常可从公共互联网访问
查看监控数据
在index.js中包含rum.js并设置页面加载名称:
1
2
3
4
5
6
7
8
9
10
|
import apm from './rum'
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
apm.setInitialPageLoadName("Car List")
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();
|
访问应用程序页面并执行操作后,登录Kibana并点击"可观测性"磁贴,选择APM子菜单中的"服务"选项。
灵活的自定义插桩
RUM代理除了提供开箱即用的详细浏览器交互插桩外,还可以在需要时执行自定义插桩。
自定义事务示例
在我们的示例应用中,“New Car"按钮允许向数据库添加新车。我们将插桩代码以捕获添加新车的性能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
// 添加新车
addCar(car) {
// 将汽车元数据作为标签添加到RUM点击事务
var transaction = apm.startTransaction("Add Car", "Car");
transaction.addLabels(car);
fetch(SERVER_URL + 'api/cars',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(car)
})
.then(res => this.fetchCars())
.catch(err => console.error(err))
}
fetchCars = () => {
fetch(SERVER_URL + 'api/cars')
.then((response) => response.json())
.then((responseData) => {
this.setState({
cars: responseData._embedded.cars,
});
})
.catch(err => console.error(err));
// 在响应回调结束时结束当前事务
var transaction = apm.getCurrentTransaction()
if (transaction) transaction.end()
}
|
用户体验仪表板
Elastic APM提供精心设计的APM UI和内置APM仪表板,可以可视化代理捕获的所有APM数据。
您还可以使用摄取节点管道在Elastic中创建自己的自定义可视化,以丰富和转换APM数据。
通过分布式追踪查看全局情况
我们还将插桩后端Spring Boot应用程序,以便在一个视图中完整查看从Web浏览器到后端数据库的整个事务。
在RUM代理中配置分布式追踪
分布式追踪在RUM代理中默认启用,但仅包括对同一源的请求。要包括跨源请求,必须设置distributedTracingOrigins配置选项。
对于我们的应用程序,前端从http://localhost:3000提供服务。要包括对http://localhost:8080的请求,需要在React应用中添加distributedTracingOrigins配置:
1
2
3
4
|
var apm = initApm({
// ...
distributedTracingOrigins: ['http://localhost:8080']
})
|
服务器端插桩
对于服务器端手动插桩方法,需要下载Java代理并使用它启动应用程序。在IDE中,需要将以下vmArgs添加到启动配置中:
1
2
3
4
5
|
-javaagent:apm/wrapper/elastic-apm-agent-1.33.0.jar
-Delastic.apm.service_name=cardatabase
-Delastic.apm.application_packages=com.packt.cardatabase
-Delastic.apm.server_urls=<YOUR_APM_ENDPOINT>
-Delastic.apm.secret_token=<YOUR_SECRET_TOKEN>
|
跨源资源共享(CORS)
RUM代理只是分布式追踪中的一部分。要使用分布式追踪,还需要正确配置其他组件,其中之一就是跨源资源共享(CORS)。
这意味着两件事:
- 必须设置distributedTracingOrigins配置选项
- 使用该配置后,RUM代理会在实际HTTP请求之前发送HTTP OPTIONS请求
Spring Boot应用程序中的MyCorsConfiguration类正是为此而设:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@Configuration
public class MyCorsConfiguration {
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<CorsFilter>(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
|
总结
使用Elastic RUM插桩应用程序既简单又强大。与其他用于后端服务的APM代理一起,RUM通过分布式追踪从最终用户角度为您提供应用程序性能的整体视图。
要开始使用Elastic APM,可以下载Elastic APM服务器在本地运行,或者创建云试用帐户并在几分钟内准备好集群。