可观测性网站之Session的生命周期

本文涉及的产品
可观测可视化 Grafana 版,10个用户账号 1个月
云拨测,每月3000次拨测额度
简介: 本文会列出session的属性值、统计指标,重点讲解session几个字段值,虽然session和view、app均有关联,但本文仅从代码层面对session的生命周期做解释。

本文会列出session的属性值、统计指标,重点讲解session几个字段值,虽然从代码中看出的考虑策略,session和view、app均有关联,但本文仅从代码层面对session的创建、更新、过期的逻辑进行讲解,其中会把关键的变量值也会列出来。

定义:

用户会话信息记录,当前会话中,将会基于会话维度用户页面、资源、操作、错误、长任务相关访问数据。 下面简单列出session有哪些属性,仅供参考。

属性

字段 类型 描述
session_id string 会话 id(用户会话 15 分钟内未产生交互行为则视为过期 )
session_type string 会话类型。参考值:user synthetics - user 表示是RUM功能产生的数据;- synthetics 表示是 headless拨测产生的数据。
session_referrer string 会话来源。一般是记录来源的页面地址。
session_first_view_id string 当前会话的第一个页面的 view_id
session_first_view_url string 当前会话的第一个页面的 URL
session_first_view_host string 当前会话的第一个页面的域名
session_first_view_path string 当前会话的第一个页面的地址
session_first_view_path_group string 当前会话的第一个页面的地址分组
session_first_view_url_query string 当前会话的第一个页面的 query 信息
session_last_view_id string 当前会话的最后一个访问页面的 view_id
session_last_view_url string 当前会话的最后一个页面的 URL
session_last_view_host string 当前会话的最后一个页面的域名
session_last_view_path string 当前会话的最后一个页面的地址
session_last_view_path_group string 当前会话的最后一个页面的地址分组
session_last_view_url_query object 当前会话的最后一个页面的 query 信息

统计指标

字段 类型 描述
time_spent number(ns) 当前会话持续时长
session_view_count number 当前会话关联view_id个数
session_error_count number 当前会话产生错误个数
session_resource_count number 当前会话加载资源个数
session_action_count number 当前会话用户操作次数
session_long_task_count number 当前会话产生长任务次数

session部分逻辑

并不是所有字段都有值得讲解,比如session_has_replay这个字段代表是否有会话是否有录制。今天只针对session的生命周期进行讲解。

id的生成

这个简单,首先这个要从startSessionStore,其中session要从cookie中获取,如果没有就需要创建,创建或更新的这部分逻辑如下:

function expandOrRenewCookie(cookieSession) {
    var sessionState = computeSessionState(cookieSession[productKey])
    var trackingType = sessionState.trackingType
    var isTracked = sessionState.isTracked
    cookieSession[productKey] = trackingType
    if (isTracked && !cookieSession.id) {
      cookieSession.id = UUID()
      cookieSession.created = String(dateNow())
    }
    return isTracked
  }
复制代码

上面需要注意一点,这里的cookie值是_dataflulx_usr_id,如何查看当前的cookie值呢,一般可以通过document.cookie进行获取,简单的查看方式便是f12打开控制台,在application中查看,如下图所示。

网络异常,图片无法展示
|

在上图中,我们除了能看到当前的cookie的value,还有比较重要的内容:

  • domain
  • 过期时间
  • 大小

获取cookie

有关如何获取cookie,这里实现的逻辑是调用

#bytemd-mermaid-1679971038295-0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#bytemd-mermaid-1679971038295-0 .error-icon{fill:#552222;}#bytemd-mermaid-1679971038295-0 .error-text{fill:#552222;stroke:#552222;}#bytemd-mermaid-1679971038295-0 .edge-thickness-normal{stroke-width:2px;}#bytemd-mermaid-1679971038295-0 .edge-thickness-thick{stroke-width:3.5px;}#bytemd-mermaid-1679971038295-0 .edge-pattern-solid{stroke-dasharray:0;}#bytemd-mermaid-1679971038295-0 .edge-pattern-dashed{stroke-dasharray:3;}#bytemd-mermaid-1679971038295-0 .edge-pattern-dotted{stroke-dasharray:2;}#bytemd-mermaid-1679971038295-0 .marker{fill:#333333;stroke:#333333;}#bytemd-mermaid-1679971038295-0 .marker.cross{stroke:#333333;}#bytemd-mermaid-1679971038295-0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#bytemd-mermaid-1679971038295-0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#bytemd-mermaid-1679971038295-0 .cluster-label text{fill:#333;}#bytemd-mermaid-1679971038295-0 .cluster-label span{color:#333;}#bytemd-mermaid-1679971038295-0 .label text,#bytemd-mermaid-1679971038295-0 span{fill:#333;color:#333;}#bytemd-mermaid-1679971038295-0 .node rect,#bytemd-mermaid-1679971038295-0 .node circle,#bytemd-mermaid-1679971038295-0 .node ellipse,#bytemd-mermaid-1679971038295-0 .node polygon,#bytemd-mermaid-1679971038295-0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#bytemd-mermaid-1679971038295-0 .node .label{text-align:center;}#bytemd-mermaid-1679971038295-0 .node.clickable{cursor:pointer;}#bytemd-mermaid-1679971038295-0 .arrowheadPath{fill:#333333;}#bytemd-mermaid-1679971038295-0 .edgePath .path{stroke:#333333;stroke-width:1.5px;}#bytemd-mermaid-1679971038295-0 .flowchart-link{stroke:#333333;fill:none;}#bytemd-mermaid-1679971038295-0 .edgeLabel{background-color:#e8e8e8;text-align:center;}#bytemd-mermaid-1679971038295-0 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#bytemd-mermaid-1679971038295-0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#bytemd-mermaid-1679971038295-0 .cluster text{fill:#333;}#bytemd-mermaid-1679971038295-0 .cluster span{color:#333;}#bytemd-mermaid-1679971038295-0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80,100%,96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#bytemd-mermaid-1679971038295-0:root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#bytemd-mermaid-1679971038295-0 flowchart{fill:apa;}

name

document.cookie,name

findCommanSeparatedValue是利用正则进行获取,代码如下:

export function findCommaSeparatedValue(rawString, name) {
  var matches = rawString.match('(?:^|;)\\s*' + name + '\\s*=\\s*([^;]+)')
  return matches ? matches[1] : undefined
}
复制代码

创建cookie的值

接着上面的逻辑,如果是首次进入,需要创建和设置cookie,我们先看创建的代码:

cookieSession.id = UUID()
复制代码

UUID这个方法实现也比较简单,是通过Math.random后最后转换成16进制,可以看下面代码:

export function UUID(placeholder) {
  return placeholder
    ? // eslint-disable-next-line  no-bitwise
      (
        parseInt(placeholder, 10) ^
        ((Math.random() * 16) >> (parseInt(placeholder, 10) / 4))
      ).toString(16)
    : `${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g, UUID)
}
复制代码

但是我们需要注意,还有几个其他相关属性很重要

export var SESSION_TIME_OUT_DELAY = 4 * ONE_HOUR
export var SESSION_EXPIRATION_DELAY = 15 * ONE_MINUTE
复制代码

这里SESSION_TIME_OUT_DELAY用于设定最大时长,也就是说4个小时;SESSION_EXPIRATION_DELAY用于判断是否过期,这里是15分钟。

说到时间,就需要知道cookieSession创建时,还有一个比较重要的参数,上面两个变量便是依据这个参数进行的对比,这个参数是:cookieSession.created:

cookieSession.created = String(dateNow())
复制代码

目测是本地时间,但是得看一下源码import { dateNow, UUID, throttle } from '../helper/tools'dataNow也来自helper/tools中,其中代码是这样写的:

export function dateNow() {
  return new Date().getTime()
}
复制代码

看代码采用的是new Date(),也就是客户端的时间,在上面两个相对的时间后,就会执行相关session的更新或者创建。所以对于session的判断也有必要讲一讲,这里使用的函数是根据hasSessionInCache的返回值真假来判断 return sessionCache[productKey] !== undefined,如果存在,还需要判断是否过期(isSessionInCacheOutdated),这里判断条件除了id外还有另外一个值

function isSessionInCacheOutdated(cookieSession) {
    return (
      sessionCache.id !== cookieSession.id ||
      sessionCache[productKey] !== cookieSession[productKey]
    )
  }
复制代码

假设返回为假,则需要session过期(expireSession):

function expireSession() {
    sessionCache = {}
    expireObservable.notify()
  }
复制代码

检查session

因为session的特殊性,所以不能频繁更新和检查session,所以应该有性能上的节流。 expandOrRenewSession: throttle(expandOrRenewSession, COOKIE_ACCESS_DELAY)       .throttled,目前软件的节流时间是export var COOKIE_ACCESS_DELAY = ONE_SECOND 节流函数比较简单,就不做介绍了。 其中还有最后一项,就是session是否在有效期内(isActiveSession):

function isActiveSession(session) {
    return (
      (session.created === undefined ||
        dateNow() - Number(session.created) < SESSION_TIME_OUT_DELAY) &&
      (session.expire === undefined || dateNow() < Number(session.expire))
    )
  }
复制代码

session的过期

SESSION_TIME_OUT_DELAY就是上面提到的比较重要的属性值,目前是export var SESSION_TIME_OUT_DELAY = 4 * ONE_HOUR有关session是否还要持久化的方法(persistSession)

export function persistSession(session, options) {
  if (isExpiredState(session)) {
    clearSession(options)
    return
  }
  session.expire = String(dateNow() + SESSION_EXPIRATION_DELAY)
  setSession(session, options)
}
复制代码

SESSION_EXPIRATION_DELAY就是上面提到的比较重要的属性值,目前是15分钟。

有关用户是否活动,是通过事件监听dom是否出现VISIBILITY_CHANGE来判断。

var _addEventListener= addEventListener(document, DOM_EVENT.VISIBILITY_CHANGE, expandSessionWhenVisible)
复制代码

总结

本文介绍了session的属性和常见统计指标,单独把session的id的创建、更新、获取逻辑以及过期时间的逻辑都做了讲解,希望能对读者有所启发。


作者:Yestodorrow

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

目录
相关文章
|
2月前
|
缓存 JavaScript
onActivated 生命周期的使用和介绍
onActivated 生命周期的使用和介绍
37 3
|
2月前
|
弹性计算 数据库
生命周期挂钩概述
生命周期挂钩概述
15 0
|
3月前
|
存储 Java API
session的状态或者生命周期
session的状态或者生命周期
|
7月前
IT服务生命周期
IT服务生命周期
148 0
|
7月前
|
存储 消息中间件 Java
设计与思考,关于资源和生命周期
在工作中,经常会看到或者用到池化技术,例如数据库连接池、线程池、内存池等等。这类池化技术在很多经典框架中都存在,并且是设计中的重要部分。
125 0
|
8月前
|
应用服务中间件 数据安全/隐私保护
session 生命周期和经典案例-防止非法进入管理页面
session 生命周期和经典案例-防止非法进入管理页面
84 0
|
9月前
|
SQL 数据采集 监控
数据可观测性——使用SQL构建自己的数据质量监视器
数据可观测性——使用SQL构建自己的数据质量监视器
106 0
|
存储 安全 Java
|
存储 Go 数据库
第二十章 CSP Session 管理 - 状态管理
第二十章 CSP Session 管理 - 状态管理
生命周期forceUpdate流程
生命周期forceUpdate流程
166 0