Golang A/B Testing SDK 依赖于神策分析 SDK,在使用前请确保已经成功集成神策分析 SDK,并进行了 SDK 初始化,详情可参考 SDK 集成 (Golang)。
SDK 需要 Golang 1.6 以上,不依赖第三方库。目前 Golang SDK 不支持 Windows。
SDK 集成
我们推荐 Golang 官方工具管理 Golang 项目并获取 A/B Testing SDK :
go get github.com/sensorsdata/abtesting-sdk-go
或更新本地已经存在的 SDK:
go get -u github.com/sensorsdata/abtesting-sdk-go
也可以从 GitHub 下载 abtesting-sdk-go 的源代码。
初始化 SDK
在神策分析中创建 A/B Testing 后,会生成分流试验请求 URL,通过该 URL 初始化 A/B Testing SDK:
import (
"fmt"
"github.com/sensorsdata/abtesting-sdk-go"
"github.com/sensorsdata/abtesting-sdk-go/beans"
"github.com/sensorsdata/sa-sdk-go"
)
必须先初始化分析埋点 SDK(参考文档:https://manual.sensorsdata.cn/sa/latest/tech_sdk_server_golang-17569150.html)
abconfig := beans.ABTestConfig{
APIUrl: "分流试验请求地址",
EnableEventCache: true, // 开启事件缓存
SensorsAnalytics: sa, // 神策分析埋点 SDK 实例
}
// 初始化 A/B Testing SDK
err, abtest := sensorsabtest.InitSensorsABTest(abconfig)
获取试验变量
初始化 SDK 之后,通过 API 获取具体试验的变量值,根据获取试验变量值的方式,可分为下面两种策略:
- AsyncFetchABTest :忽略内存缓存,从服务端获取数据;
- FastFetchABTest :优先读取内存缓存,缓存不存在时从服务端获取数据。
应该选择哪个API获取试验变量值?
1.一般情况下,我们推荐使用FastFetchABTest获取试验变量值。
2.如果您进行的是时间片轮转等在试验过程中用户会进入不同组的试验,建议您使用AsyncFetchABTest,直接从服务端获取数据,保证获取变量的准确性。
1. 接入前请参考如何设置distinctId,在调用时正确设置distinctId参数.
2. 请确保对A/B分流返回的 result 结果 & 接口中使用的默认值,都做了正常的业务逻辑处理!
3. 请确保默认值 default_value 和当前试验值类型相同。比如参数对应试验值为 Int 类型,则传入的 default_value 也必须是 Int 类型,同时返回的试验结果 result 也是 Int 类型
如果您需要在新用户注册流程中使用A/B Testing服务端SDK对新用户进行用户主体分流试验,不建议您使用loginId请求分流。可参考以下方案,根据您试验的实际情况选择其中一个:
- 如果您目前的A/B Testing 版本在v0.9.1以上,可以在创建试验时采用登录ID作为试验的分流主体。
- 如果用户只会在一台设备登录,没有多设备登录场景,可使用客户端设备的匿名ID请求分流,即distinctId为从客户端获取的匿名ID,isLoginId为false.
- 可以将试验移到客户端进行。
- 可以使用服务端SDK进行自定义主体分流试验。
以 FastFetchABTest 为例,可在相应的业务逻辑中添加如下代码:
// int 类型试验(第二个参数 DefaultValue,表示未命中试验时,会返回此默认值,请根据业务需要更改此处的值)
requestParam := beans.RequestParam{
ParamName: "具体的试验参数",
DefaultValue: 0, //必填
EnableAutoTrackABEvent: true, // true 表示自动触发 A/B 测试($ABTestTrigger)事件,用于后续分析试验效果,计算置信区间等。
}
distinctId := "ABCDEFG1234567" // 具体的用户 ID 标识
isLoginId := true // 当前用户是否是登录 ID
err, experiment := abtest.FastFetchABTest(distinctId, isLoginId , requestParam)
if err == nil {
// TODO 根据返回值做试验,注意返回值是 map[string]interface{} 类型需要自己做类型判断
// 这里通过数值类型进行示例
switch experiment.Result {
case 0:
break
case 1:
// 试验组 1 的处理逻辑
break
case 2:
// 试验组 2 的处理逻辑
break
// .......
// .......
default:
break
}
}
携带自定义属性获取试验
v0.0.2 及以上版本 SDK 支持自定义属性扩充受众筛选能力,可在请求接口 FastFetchABTest、AsyncFetchABTest 中的 RequestParam 变量中添加自定义属性。以 FastFetchABTest 接口为例:
// int 类型试验(第二个参数 DefaultValue,表示未命中试验时,会返回此默认值,请根据业务需要更改此处的值)
requestParam := beans.RequestParam{
ParamName: "具体的试验参数",
Properties: map[string]interface{}{// 设置自定义属性
"property1": property1,
"property2": property2,
},
DefaultValue: 0, //必填
EnableAutoTrackABEvent: true, // true 表示自动触发 A/B 测试($ABTestTrigger)事件,用于后续分析试验效果,计算置信区间等。
}
distinctId := "ABCDEFG1234567" // 具体的用户 ID 标识
isLoginId := true // 当前用户是否是登录 ID
err, experiment := abtest.FastFetchABTest(distinctId, isLoginId , requestParam)
if err == nil {
// TODO 根据返回值做试验,注意返回值是 map[string]interface{} 类型需要自己做类型判断
// 这里通过数值类型进行示例
switch experiment.Result {
case 0:
break
case 1:
// 试验组 1 的处理逻辑
break
case 2:
// 试验组 2 的处理逻辑
break
// .......
// .......
default:
break
}
}
携带自定义主体获取试验
v0.0.2 及以上版本 SDK 支持自定义主体分流能力,可在请求接口 FastFetchABTest、AsyncFetchABTest 中的 RequestParam 变量中添加自定义主体。
在接入前,需要确认以下几点:
- 确认您要使用的自定义主体参数名(例如 phone_number, account等,支持自定义)。
- 在神策元数据管理将该自定义主体设置为公共属性。
- 将自定义主体名提供给神策,由神策技术人员将其配置到分流服务后台。
初始化SDK后,在调用获取试验变量API时,手动将自定义主体添加到接口请求参数CustomIDs中,并在后续上报的事件中添加该自定义主体作为事件属性。
以 FastFetchABTest 接口为例:
// int 类型试验(第二个参数 DefaultValue,表示未命中试验时,会返回此默认值,请根据业务需要更改此处的值)
requestParam := beans.RequestParam{
ParamName: "具体的试验参数",
CustomIDs: map[string]interface{}{// 设置自定义主体
"id1": id1,
"id2": id2,
},
DefaultValue: 0, //必填
EnableAutoTrackABEvent: true, // true 表示自动触发 A/B 测试($ABTestTrigger)事件,用于后续分析试验效果,计算置信区间等。
}
distinctId := "ABCDEFG1234567" // 具体的用户 ID 标识
isLoginId := true // 当前用户是否是登录 ID
err, experiment := abtest.FastFetchABTest(distinctId, isLoginId , requestParam)
if err == nil {
// TODO 根据返回值做试验,注意返回值是 map[string]interface{} 类型需要自己做类型判断
// 这里通过数值类型进行示例
switch experiment.Result {
case 0:
break
case 1:
// 试验组 1 的处理逻辑
break
case 2:
// 试验组 2 的处理逻辑
break
// .......
// .......
default:
break
}
}
properties = map[string]interface{}{
"自定义主体参数名": "自定义主体参数值"
}
//如果需要上报事件参与AB试验指标计算,需要将该自定义主体作为事件属性
sa.Track(distinctId, "buy", properties, isLoginId);
获取设备主体试验变量
SDK支持使用设备主体进行分流,需要根据您使用的SDK版本和A/B Testing版本,做对应的接入设置。
接入前请参考如何设置distinctId,在调用时正确设置distinctId参数。获取设备主体试验变量时,distinctId为从客户端获取的匿名ID。
请确保对A/B分流返回的 result 结果 & 接口中使用的默认值,都做了正常的业务逻辑处理!
- 如果您使用的A/B Testing Golang SDK为0.1.0及以上版本,且当前A/B Testing为0.9.1及以上版本,可以采用以下方式获取设备主体试验变量
// int 类型试验(第二个参数 DefaultValue,表示未命中试验时,会返回此默认值,请根据业务需要更改此处的值) requestParam := beans.RequestParam{ ParamName: "具体的试验参数", DefaultValue: 0, //必填 EnableAutoTrackABEvent: true, // true 表示自动触发 A/B 测试($ABTestTrigger)事件,用于后续分析试验效果,计算置信区间等。 } distinctId := "ABCDEFG1234567" // 具体的用户 ID 标识,这里是从客户端获取的匿名ID isLoginId := false // 当前distinctId不是登录ID err, experiment := abtest.FastFetchABTest(distinctId, isLoginId , requestParam) if err == nil { // TODO 根据返回值做试验,注意返回值是 map[string]interface{} 类型需要自己做类型判断 // 这里通过数值类型进行示例 switch experiment.Result { case 0: break case 1: // 试验组 1 的处理逻辑 break case 2: // 试验组 2 的处理逻辑 break // ....... // ....... default: break } } properties = map[string]interface{}{ "anonymous_id": distinctId } //如果需要上报事件参与AB设备主体试验指标计算,需要在每条埋点事件中将anonymous_id作为事件属性一起上报 sa.Track(distinctId, "buy", properties, isLoginId);
- 如果您使用的A/B Testing Golang SDK 或 A/B Testing版本不满足上述要求,可采用以下方式获取设备主体试验变量
// int 类型试验(第二个参数 DefaultValue,表示未命中试验时,会返回此默认值,请根据业务需要更改此处的值) requestParam := beans.RequestParam{ ParamName: "具体的试验参数", DefaultValue: 0, //必填 EnableAutoTrackABEvent: false, // 表示需要手动触发 A/B 测试($ABTestTrigger)事件,用于后续分析试验效果,计算置信区间等。 } distinctId := "ABCDEFG1234567" // 具体的用户 ID 标识,这里是从客户端获取的匿名ID isLoginId := false // 当前distinctId不是登录ID err, experiment := abtest.FastFetchABTest(distinctId, isLoginId , requestParam) //手动上报$ABTestTrigger事件,将anonymous_id作为事件属性 anonymousIdProperties = map[string]interface{}{ "anonymous_id": distinctId } abtest.TrackABTestTrigger(experiment, anonymousIdProperties) if err == nil { // TODO 根据返回值做试验,注意返回值是 map[string]interface{} 类型需要自己做类型判断 // 这里通过数值类型进行示例 switch experiment.Result { case 0: break case 1: // 试验组 1 的处理逻辑 break case 2: // 试验组 2 的处理逻辑 break // ....... // ....... default: break } } properties = map[string]interface{}{ "anonymous_id": distinctId } //如果需要上报事件参与AB设备主体试验指标计算,需要在每条埋点事件中将anonymous_id作为事件属性一起上报 sa.Track(distinctId, "buy", properties, isLoginId);
API 介绍
在 A/B Testing SDK 中提供了试验获取接口和埋点事件接口。
初始化配置参数说明
在 A/B Testing SDK 中,初始化参数配置封装在 ABConfig 类中,提供的初始化参数有:
参数名 | 类型 | 说明 |
---|---|---|
APIUrl | string | 试验请求 API 地址(必填) |
SensorsAnalytics | sensorsanalytics.SensorsAnalytics | 用于 SDK 埋点 SensorsAnalytics 实例(必填) |
ExperimentCacheTime | time.Duration | 试验缓存时长,单位是分钟,默认是 24 * 60 |
ExperimentCacheSize | int | 试验总缓存用户量限制,默认值为 4096 |
EventCacheTime | time.Duration | A/B 测试($ABTestTrigger)事件缓存时间,单位是分钟,默认是 24 * 60 |
EventCacheSize | int | A/B 测试($ABTestTrigger)事件总缓存用户量限制,默认值为 4096 |
EnableEventCache | bool | 是否开启 A/B 事件缓存,默认 false |
获取试验方法说明
从服务端获取试验数据。
描述 | 说明 |
---|---|
方法名 | AsyncFetchABTest/FastFetchABTest |
参数 | distinctId, isLoginId, requestParam beans.RequestParam
|
返回值 | error, experiment beans.Experiment
|
RequestParam 参数说明
在 A/B Testing SDK 中,试验请求参数配置封装在 RequestParam 类中,提供的参数有:
名称 | 类型 | 说明 |
---|---|---|
ParamName | string | 试验变量名(必填) |
DefaultValue | interface{} | 未命中试验时,会返回默认值,请根据业务需要更改此处的值(必填) |
EnableAutoTrackEvent | bool | 是否自动触发 A/B 测试($ABTestTrigger)事件,用于后续分析试验效果,计算置信区间等(必填) |
Properties | map[string]interface{} | 自定义属性,请求试验时,用于分流筛选的属性 |
CustomIDs | map[string]interface{} | 自定义分流主体 |
TimeoutMilliseconds | time.Duration | 网络请求超时时间,默认 3000ms,单位 ms |
手动触发 A/B 测试($ABTestTrigger)事件说明
如果设置了 EnableAutoTrackABEvent: true 表示由 SDK 自动触发 A/B 测试($ABTestTrigger)事件,用于后续分析试验效果,计算置信区间等。
如果不想让 SDK 自动触发 A/B 测试($ABTestTrigger)事件,可以设置 EnableAutoTrackABEvent: false ,然后调用 TrackABTestTrigger 方法来手动触发事件。
示例如下:
requestParam := beans.RequestParam{
ParamName: "具体的试验参数",
DefaultValue: 0, // 必填
EnableAutoTrackABEvent: false, // false 表示不自动触发 A/B 测试($ABTestTrigger)事件
}
distinctId := "ABCDEFG1234567" // 具体的用户 ID 标识
isLoginId := true // 当前用户是否是登录 ID
// 优先从缓存获取试验,由 SDK 触发埋点事件
err, experiment := abtest.AsyncFetchABTest(distinctId, isLoginId, requestParam)
if err == nil {
// TODO 根据返回值做试验,注意返回值是 map[string]interface{} 类型需要自己做类型判断
// 这里通过数值类型进行演示
switch experiment.Result {
case 1:
// 试验组 1 的处理逻辑
break
case 2:
// 试验组 2 的处理逻辑
break
// .......
// .......
default:
break
}
}
//……
// 手动触发 A/B 测试($ABTestTrigger)事件
abtest.TrackABTestTrigger(experiment, nil)
experiment 对象信息
试验 experiment 对象中包含 DistinctId、是否登录 ID、试验变量值(Result)、试验 ID(AbtestExperimentId)、试验内分组 ID(AbtestExperimentGroupId)、是否是对照组(IsControlGroup)、是否是白名单(IsWhiteList)和试验参数对象(VariableList)。
TrackABTestTrigger 方法说明
该接口用于手动触发 A/B 测试($ABTestTrigger)事件
方法名 | TrackABTestTrigger |
参数 | experiment beans.Experiment, property map[string]interface{}
|
返回值 | error error
|
调试试验
- 可以通过录入调试设备的方式,把用户加入指定分组中;加入调试设备后,会强制命中当前试验指定的分组(调试设备在调试状态和正式上线阶段都会生效)。
- 使用服务端SDK对该用户请求分流,返回当前试验指定的分组。需要注意的是,在请求分流时,请根据调试设备的ID类型(设备ID、登录ID)正确设置分流API中使用的distinctId与isLoginId参数,否则可能不会命中试验。