策略开发人员在完成策略以后,在全流量上线以前要评估新的策略的优劣,经常使用的评估方法是A-B测试,作法是在全流量中抽样出两份小流量,分别走新策略分支和旧策略分支,经过对比这两份流量下的各指标的差别,咱们能够评估出新策略的优劣,进而决定新策略是否全流量。咱们把抽样的过程分为流量切分和流量筛选两个步骤。流量切分的逻辑较为复杂,包含多种切分类型和多层嵌套,另外为了保证灵活性,层的组合应该是任意的。算法
为了便于流量管理,咱们须要将这个过程平台化,这样就须要找到一种形象化的表现方式,将多层流量切分这个过程表现出来,显然这种需求下,简单的输入框、下拉框等控件是不能知足需求的,这就须要构建出可视化的多层流量切分功能,使流量切分这个复杂的动做变得低学习成本、便于理解。编程
图1.1 可视化流量切分示意图浏览器
上图是多层流量切分的一个效果假象图,为了便于理解和管理,咱们将多层流量切分过程当中使用的到的元素划分为三种:水平层、垂直层、抽样节点这三个元素,为了方便使用,咱们会将其封装为基本的控件,供用户直接拖拽使用,下面咱们介绍一下各个元素的含义,以方便下文的直接使用。数据结构
可视化多层流量切分采用的Flex技术实现,Flex 是一个高效、免费的开源框架,可用于构建具备表现力的 Web 应用程序,这些应用程序利用 Adobe Flash Player和 Adobe AIR, 运行时跨浏览器、桌面和操做系统实现一致的部署。能够经过智能编码、交互式遍历调试以及可视设计用户界面布局等功能加快开发。架构
可视化多层流量切分功能采用MVC模式实现,其模块结构以下图所示,数据管理中心模块的功能包括数据模型的构建、经过HTTP交互模块与服务端交互数据、算法的封装;逻辑控制模块是数据管理中心与展示模块之间沟通的桥梁,它能够分派用户的请求并选择恰当的展示方式以用于显示,同时它也能够解释用户的操做并将它们映射到数据管理中心模块,数据管理中心模块予以计算。框架
图1.2 可视化流量切分架构设计ide
上文介绍的多层流量切分功能中用到的基本元素——水平层、垂直层、抽样节点在数据管理中心模块中都创建了相应的数据模型,当初始化程序的时候,数据管理中心模块经过HTTP交互模块与服务端交互获取初始化数据,并将数据填充至基本的数据模型。函数
那么这些基本元素的数据模型如何实现呢?咱们能够从这些元素的特性着手分析,如图1.1所示,整个可视化界面中,将层分为垂直层和水平层,垂直层是如五、6号能够将完整层分割开的层,水平层是如二、三、4号占满父层的层,能够抽象层和数据节点为树结构,能够看做是一种不彻底的红黑树,注意这里的红黑树是一种不彻底符合规范的红黑树,咱们能够将水平层看做为黑色节点,垂直层看做为红色节点,数据节点看做为叶子节点,建立树的时候,咱们自动将不包含的抽样节点的空层去掉,那么从图1.2结构就能够转化为图1.3的结构。布局
图1.3 三种元素在数据管理中心的数据结构学习
有了上面的数据结构模型,咱们就能够在此基础上封装一些经常使用的功能函数了,咱们下面列举几个封装的计算的例子:
两个抽样节点复用流量是指一次请求同时命中了这两个抽样节点,从图1.4上面来看,若是两个抽样节点复用流量,咱们形象的表示为,从垂直方向上划一条线,咱们约定每个子层中咱们只可以通过一个抽样节点,在这种状况下,每条线能够通过多个抽样节点,也能够不通过任何抽样节点,若是两个抽样节点同时被穿中,就表示这两个抽样节点可能会复用流量。
图1.3 流量复用示意图
判断两个抽样节点是否可能会同时命中比较麻烦,咱们能够换一下思惟,为何会有两个节点不能被同时命中,比较容易想到的就是他们位于同一个父层中,这种状况下,两个抽样节点是不可能同时命中的了,还有一种状况就是他们位于不一样的父层中也有可能不能同时被命中,究其缘由主要是由于他们被垂直层隔开,例如,五、6两个层中的数据节点是不可能同时划中的。按照上面这个思路,咱们能够编程序实现判断过程,逻辑以下:
i. 判断这两个节点是否位于同一个父层节点中
ii. 追溯叶子节点的父节点,一直追溯到根节点,获取到其中红色节点,判断红色节点中是否有兄弟节点。好比,D1->7->5->2->1 红色节点是5, D3->8->6->2->1,红色节点是6,判断红色节点是不是兄弟节点,判断方法为是否父节点相同。
有了上面的数据结构,判断某层中是否能够添加其余元素的实现思路比较简单,按照咱们以前的约定,三种元素在某一个父层中是不能共存的,例如,不能在同一个层中即包含水平层又包含垂直层,同时也不能在一个父层中即包含层又包含抽样节点,所以,这里咱们的算法实现逻辑就是,获取到该父层中的全部的元素,判读其类别是否惟一便可。
在多层流量切分的架构中,有机会流量复用的抽样节点都是有必定的相互影响的几率,为了方便用户抉择流量分层以及抽样节点的排放位置,咱们须要计算出各个抽样节点之间的相互影响几率,计算的数据结果也是基于上面介绍的结构,算法步骤以下:
i. 追溯这两个抽样节点的父层路径,一直追溯到共同的父层为止,例如D1能够追溯为D1->7->5->2->1,D8能够追溯为D8->12->9->4->1,这样咱们就追溯到了他们的共同的父层1,这里咱们首先复用一下上面计算两个抽样节点是否会复用流量的算法,计算一下这两个抽样节点是否可能复用流量。若是没有机会复用流量,则直接返回0%。
ii. 若是这两个抽样节点有机会复用流量,按照追溯的父层路径计算相互影响几率,如上面的例子,D1和D8的相互影响几率为:
(D1的流量百分比*7号层的百分比*5号层的百分比*2号层的百分比)*(D8的流量百分比*12号层的百分比*9号层的百分比*4号层的百分比)
插入点判断也是基于上面这个数据结构算法封装的算法,它的实现思想是遍历须要插入的父层中的全部的子元素,依据上面的约定,同一父层下的元素类型是惟一的,所以,咱们只须要遍历一下各元素之间缝隙,若是能够空间大小能够插入某一元素,则咱们能够将该元素插入到指定的位置。
上面咱们举例列举了4种数据管理中心模块中封装的算法,数据管理中心中,根据上面的数据结构,咱们还能够封装出其余的数据基础算法,供逻辑控制模块使用。
展示模块封装了展示绘图的基本方法,实现的思想是从小粒度到总体的渲染过程,首先,咱们实现了三种基本元素的展示样式,例如,垂直层和水平层是统一的展示样式,它的基本绘图单元是矩形,垂直层和水平层为了作区分,它们的填充色是不同的,抽样节点的基本绘图单元是图片,抽样节点再每种不一样的状态下,展示的图片是不同的。
展示模块接收的绘图数据格式是上面介绍的树状结构,所以,展示界面渲染其实就是一个树的遍历的过程,咱们采用的遍历方式是前序遍历,例如,若是传如的数据格式为图1.2的形式,那么前序遍历的结果就是:
1->2->5->7->D1->D2->6->8->D3->D4->3->D5->D6->D7->4->9->12->D8->D9->15->D15->10->13->D10->D11->16->D16->11->14->D12->D13->D14
1.动态渲染过程当中的元素大小自动调节问题
渲染过程会有一个问题,这是从外向内的一种渲染方式,咱们必然会先固定一个最外层的高度和宽度,那么这样就会致使初始设定的高度或宽度太小,放不下内部的各个元素,针对这个问题,首先为了处理简单,咱们能够将每层的高度固定下来,宽度是可变的,基于这种前提,咱们处理上面这个问题的方案有二,一种是预先计算好渲染所须要的宽度,另外一种是方法是绘图过程当中动态的调整最外层的宽度,若是数据量比较大的状况下,选用方案一的效率较高,若是数据量不大,这两种方案的差别是不大的,两种渲染方式的实现逻辑以下图所示。
图1.4 动态渲染过程当中的元素大小自动调节方案,预先计算结果(左),渲染过程当中自动调节(右)
2.控件拖拽与双击的实现
控件的拖拽与双击实现比较简单,主要经过事件的方式来实现,预先在绘图面板上面增长了onCanvasMouseDown(鼠标按下),onCanvasMouseMove(鼠标移动),onIconMouseDown(控件鼠标按下),onIconDoubleClick(控件双击)等事件,在不一样的状况下展示的样式作出调整便可。
by randy_yao