登录
首页 >  数据库 >  MySQL

Matomo 从了解到落地——页面流量统计与分析最佳实践

来源:SegmentFault

时间:2023-02-19 19:07:43 273浏览 收藏

小伙伴们有没有觉得学习数据库很有意思?有意思就对了!今天就给大家带来《Matomo 从了解到落地——页面流量统计与分析最佳实践》,以下内容将会涉及到MySQL、docker、vue.js、流量分析、统计分析,若是在学习中对其中部分知识点有疑问,或许看了本文就能帮到你!

背景

在开发面向内部使用的「内容管理平台」的过程中,我们不时会收到一些页面问题的反馈,但在本地调试的过程中,有大量无法在本地重现的问题,这些问题的出现跟用户的访问设备、网络环境、访问路径可能存在关联。为了方便快捷地去定位这些问题,我们试图为所有页面点击操作都加上打点记录,但在实际操作中,由于业务变更频繁,开发框架的限制,展示打点数据较为复杂等因素,通过打点排查问题的实际效果并不理想,因此我们希望引入完整的流量统计和用户行为分析来定位问题。

不同的方案分析对比

对于流量统计和用户行为分析记录的工具,行业内已经有大量成熟的解决方案,相对于自行打点,这些专门的流量通过平台和工具对于业务的基本没有侵入性,也解决了如何展示数据的问题。这些平台和工具中,有著名的 Google Analytics、百度统计、WebTrends 等,也有相对冷门的今天的主角 —— Matomo,而这些方案之间各有优劣:

解决方案/平台优势劣势
Google Analytics部署简单,只需在页面加入 JS 追踪器代码,数据分析快(小时级别),功能强大,分析维度丰富数据量大的时候偶尔会丢失数据,无法定制化
Adobe Analytics数据展示清晰明了,功能强大部署复杂,只有付费版本,技术支持和文档都较少
WebTrends数据分析维度丰富,报告全面,监控过程安全主要针对大客户,费用非常高
CNZZ部署和接入简单,分析功能易用,报告简洁没有用户细分数据,也不支持用户路径分析,功能较为单一
Matomo对标 Google Analytics 的功能,接入简单,功能强大,分析维度丰富,支持私有化部署,包括代码和数据都可以私有化处理,有强大的插件机制,可以自行开发功能私有化需要自行部署和维护服务器、数据库等,部分分析功能需要二次开发

通过对比,Matomo 整体功能比较强大,对标了 Google Analytics 但在安全性和私密性方面更优,支持私有化部署,代码和数据都可以不透露给第三方,并且可以通过插件的机制配合业务实现自定义,这些优点都是我们最终选择 Matomo 作为「内容管理平台」用户记录的工具的原因。

Matomo 是什么?

这里介绍一下 Matomo,作为一套基于 PHP 与 MySQL 的网页流量统计和分析平台,它的大部分功能已经开源,并且做了很好的封装,可以轻松地进行私有化部署,它的功能主要分成两块:

  • 收集并存储页面访问数据,主要是用户信息,如设备型号、分辨率、用户地区、来源,以及页面信息,如页面访问路径、访问操作等。
  • 对收集起来的数据进行指标量化并可视化的展示,例如用户设备型号分布、地区分布、某个页面的浏览人数、访问最多的页面、某个用户在某个页面的访问路径和具体操作等,并且在收集数据时,Matomo 会有大量的策略保护用户隐私,例如上报 IP 时隐藏最后一位字节等。

在实际使用时,用户信息的上报以及页面的访问路径,只需要安装并引入 Matomo 即可实现,无需额外的配置。但是开发者可以通过接口增强上报的数据,例如上报某个弹窗的展示,或者上报某个请求的结果,这样最终可以在平台上展示出完整的用户访问路径和操作,结合业务日志,可以很准确地定位问题以及还原问题的触发路径。

Matomo 落地到业务

在引入 Matomo 之前,先说明一下 Matomo 的主要组成追踪器和 Matomo 服务端,追踪器基于 JS 实现,需要在网页引入,用于上报数据。服务端主要提供了三个功能:

  • HTTP 接口,追踪器可以收集所在网页的数据但不上报,通过 HTTP 接口发送给 Matomo。
  • 归档任务运行并预处理数据,默认分为实时动态处理(页面访问数据,用户访问轨迹)和 cron 任务处理(用户维度的列表)。
  • 可视化展现数据,也可以数据接口或者报表接口来访问这些数据。

引入简单落地不易

Matomo 有很成熟封装,因此本身部署很简单,主要分为两个步骤:

  1. 部署私有化 Matomo 服务。
  2. 在需要流量统计ide页面上引入追踪器。

其中部署私有化服务只需要下载 Matomo 的程序并上传到服务端,然后打开访问地址就可以使用引导程序部署服务,包括检测服务器环境是否符合要求,填写数据库信息,创建管理账号等,具体参考官方文档

但在实际落地到内容平台的过程中,却遇到了问题——我们需要基于 Docker 进行部署。

由于业务的部署都基于 Docker 和 k8s 进行,因此私有化的 Matomo 也需要基于此进行部署,这样会带来几个问题:

  1. Matomo 的设置分成系统配置与功能设置,其中功能设置储存在 MySQL 中,而系统设置则储存在本地的配置文件中,当部署多个容器时,配置无法对齐,另外 Docker 重新部署后,这些配置修改也会丢失。
  2. 这套部署需要域名 + 路径的形式访问 Matomo,Matomo 社区镜像中是使用 Apache2 进行路由处理的,而 Apache2 默认的配置并不适配路径,需要修改 Apache 的配置文件。

解决在 Docker 中部署 Matomo 的问题

Matomo 有官方发布的社区镜像可以直接使用,但为了解决上述的问题,需要在构建 Docker 镜像时进行额外的处理。

解决配置丢失的问题

Matomo 的配置文件是

[database]
host = "${MATOMO_DATABASE_HOST}"
username = "${MATOMO_DATABASE_USERNAME}"
password = "${MATOMO_DATABASE_PASSWORD}"
dbname = "${MATOMO_DATABASE_DBNAME}"
tables_prefix = "${MATOMO_DATABASE_TABLES_PREFIX}"
charset = "utf8mb4"
multi_server_environment = 1
enable_installer = 0

[General]
force_ssl = 0
assume_secure_protocol = 1
proxy_client_headers[] = "HTTP_X_FORWARDED_FOR"
proxy_client_headers[] = "HTTP_X_ORIGINAL_FORWARDED_FOR"
proxy_host_headers[] = "HTTP_X_FORWARDED_HOST"
salt = "xxxx" // 加密串,用于解密配置内容
trusted_hosts[] = "weread.qq.com"

[Plugins]
Plugins[] = "CorePluginsAdmin"
// ...
// 需要启动的插件列表,由于篇幅有限,省略默认的启动插件

[PluginsInstalled]
PluginsInstalled[] = "Diagnostics"
// ...
// 所有插件列表,,由于篇幅有限,省略默认的插件列表

复制出默认的配置文件后,即可根据业务进行修改,主要包括:

  1. 数据库的配置,建议使用环境变量进行配置。
  2. salt 是用于解密配置内容的加密串,保留默认配置中的值即可。
  3. 
    

    Matomo 的追踪器包含了大量的选项和方法,主要包括:

    1. Tracker Object,用于记录某个行为,例如上面代码中的
       // @param bool enable Defaults to true.
       //    If "true", use pseudo click-handler (treat middle click and open contextmenu as
       //    left click). A right click (or any click that opens the context menu) on a link
       //    will be tracked as clicked even if "Open in new tab" is not selected.
       //      If "false" (default), nothing will be tracked on open context menu or middle click.
       //    The context menu is usually opened to open a link / download in a new tab
       //    therefore you can get more accurate results by treat it as a click but it can lead
       //    to wrong click numbers.
       //
      this.enableLinkTracking = function (enable) {
          linkTrackingEnabled = true;
          // ...
      };

      也就是说,这个选项仅对 link,也就是常见的

      const enableJSErrorTracking = (): void => {
        if (window._paq) {
          window._paq.push(['enableJSErrorTracking']);
        } else {
          console.warn('can not found window._paq');
        }
      };

      主动上报更多操作

      除了链接跳转,页面中通常还会有一些 UI 操作不涉及链接变化,也不涉及请求,这类操作可以使用追踪器提供的 Tracker Object 进行主动上报,为了方便起见,可以抽取成工具方法,例如:

      // 上报一个事件,例如点击事件,播放事件等,在主动上报中比较常用。
      export const trackEvent = (category: string, action: string, name?: string, value?: number): void => {
        if (window._paq) {
          window._paq.push(['trackEvent', category, action, name, value]);
        } else {
          console.warn('can not found window._paq');
        }
      };
      
      // 二次封装,专门上报弹窗的动作,例如 action 参数可以填写 show, close
      export const trackDialogEvent = (action: string, name?: string, value?: number): void => {
        if (window._paq) {
          window._paq.push(['trackEvent', 'Dialog', action, name, value]);
        } else {
          console.warn('can not found window._paq');
        }
      };
      
      // 上报错误
      export const trackErrorEvent = (action: string, name?: string, value?: number): void => {
        if (window._paq) {
          window._paq.push(['trackEvent', 'Error', action, name, value]);
        } else {
          console.warn('can not found window._paq');
        }
      };
      
      // 上报搜索动作
      export const trackSiteSearch = (keyword: string, category?: string, resultsCount?: string): void => {
        if (window._paq) {
          window._paq.push(['trackSiteSearch', keyword, category, resultsCount]);
        } else {
          console.warn('can not found window._paq');
        }
      };

      请求失败自动上报

      业务中涉及请求的操作通常都比较关键,请求失败自动上报有利于记录下完整的用户动作路径,方便定位问题,在我们的业务中,我们的请求都是使用 Axios 发出的,因此可以利用 axios interceptors 劫持所有请求,在遇到指定错误时自动上报到 Matomo,例如:

      const baseURL = 'xxx';
      // axios instance
      const service = axios.create({
        baseURL,
        timeout: 60000,
      });
      
      service.interceptors.response.use(
        (response: AxiosResponse) => {
          const errCode = response.data && (response.data.errCode || response.data.errcode);
          if (errCode && errCode  {
          return Promise.reject(error);
        }
      );

      至此,已经可以很准确展示用户在访问页面时的完整操作路径了,开发者可以通过这些操作路径,结合业务日志,方便地去定位问题以及还原问题。

      利用 Matomo 上报完整的用户操作

      效果展示

      经过以上的处理,现在已经可以上报非常丰富的访问数据,以及用户路径了,例如:

      访客分析 - 访问日志

      访客分析 - 访问日志

      可以看到,界面上显示了完整的用户操作,通过时间轴的形式,配合不同的关键词和 icon 可以很好地呈现出实际的操作路径。

      访客分析 - 设备

      访客分析 - 设备

      除了设备,在 Matomo 中还有地区等用户维度,并且 Matomo 在不同的数据展示中,例如目标转化率等,都可以基于这些不同的维度进行展示,对于分析用户组成相当方便。

      转化与收益分析 - 概览

      Matomo 支持设定指定的目标,用于计算转化率,并进行多个维度的展示,包括转化流向,每个阶段的转化人数和转化率等,并且可以通过不同的维度,例如渠道类型、城市、设备类型分别展示各种维度下的转化数据,这也是 Matomo 一种重要的特性,数据的展示维度丰富。

      转化与收益分析 - 概览

      另外,Matomo 的插件机制也非常强大,可以插入自定义的数据,注入到各个界面或者基于 Matomo 自身收集的数据重新展示,基于篇幅所限,后续再对 Matomo 的插件机制进行实践说明。

      Matomo 的性能分析与局限性

      从上面的说明中可以看出,Matomo 的分析功能强大,分析的维度也很丰富,但同时也带来了较大的服务端资源消耗。

      Matomo 的架构可以支撑千万级甚至亿级的月 PV,但同时对于服务端的 CPU,RAM 和硬盘空间都有相应的要求。因此在实际使用时,需要注意当前服务端的配置是否足以支撑上报页面的 PV 量,否则会导致 Matomo 无法及时处理数据甚至崩溃。

      量化性能分析

      • Matomo 的默认配置是 1GB 内存,在默认配置下,Matomo 可以轻松支撑 1000 PV/天的访问量,对于这种级别的访问量,通常是一些内部平台或者面向特定人群的辅助页面。
      • 对于 3000 PV/天访问量的业务,则建议使用2核 CPU,2GB RAM,50GB 硬盘的配置。
      • 对于 30000 PV/天访问量的业务,则建议使用4核 CPU,8GB RAM,250GB 硬盘的配置,这个量级的访问可以是面向大众用户的业务页面了。
      • 对于 300000 PV/天访问量的业务,建议把 PHP 服务端和 MySQL 分开部署,对于这种量级的业务,MySQL 的瓶颈会更加明显,把 MySQL 部署进行单独部署,会更加稳定,建议最低的配置是8核 CPU,16GB RAM, 100GB 硬盘的机器作为 PHP 服务端,8核 CPU, 16GB RAM, 400GB 硬盘作为 MySQL 服务,
      • 对于更高访问量的业务,可以再叠加机器配置,硬盘空间主页是给 MySQL 消耗用的,一个参考数据是:大概每增加500万PV,数据库就会增加1GB的数据。

      可以看到,对于高访问量的业务,需要给予 Matomo 大量的服务器资源才能支撑,具体来说,超过 30000 PV/天的业务就需要注意了。因此在业务中引入时,可以考虑业务引入上报的必要性,如果页面功能单一,操作路径少,例如展示型的 H5 页面,其实引入 Matomo 的作用不是很大。

      优化 Matomo 的性能的最佳实践

      • Matomo 对于 PHP 的最低版本要求是 PHP5,但尽量使用 PHP7,PHP7 在性能上有大量的优化。
      • 使用 PHP cache,PHP5 及以上版本默认开启了。
      • 通过调整 Innodb 配置来优化 MySQL 的性能,例如增加
        innodb_buffer_pool_size
        来适应内存大小,另外可以把
        innodb_buffer_pool_size
        设置为 MySQL 可用内存的80%。增大
        innodb_flush_log_at_trx_commit
        来增加追踪器的吞吐量,具体可以参考这里
      • 业务访问量比较大的时候(例如 300000 PV/天的访问量),可以关闭实时动态处理的功能(管理 - 系统 - 通用设置 - 归档设置 - 在浏览器中查看报告时进行归档 - 否),关闭实时动态处理后,页面访问数据和用户访问轨迹也需要等待 cron 任务进行数据处理后才能展示,归档时间建议是设置为 3600 秒,减轻服务端的负担。
      • 对于 URL 带 Query 的情况,如果无需要区分 Query 进行数据分析的情况,可以选择忽略这些 Query(管理 - 网站 - 管理 - 编辑网站 - 排除参数),否则同一个 URL 带有不同 Query,Matomo 会当作不同的 URL 来处理,大大增加 MySQL 的负担。
      • 定期删除旧数据(管理 - 隐私设置 - 匿名化数据 - 定期删除旧的原始数据),旧数据的删除可以减小数据库的大小,既节省硬盘空间,也加快了数据的处理。

      理论要掌握,实操不能落!以上关于《Matomo 从了解到落地——页面流量统计与分析最佳实践》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>
评论列表