PHP企业研发-核心基本模块设计-化学方程式两端的企业级数据
<h1 style="color: black; text-align: left; margin-bottom: 10px;">6.2 化学方程式两端的企业级数据</h1>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">先<span style="color: black;">来讲</span>一下企业级网站数据的多级缓存。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">缓存的<span style="color: black;">运用</span>,<span style="color: black;">针对</span>有项目<span style="color: black;">研发</span>经验的技术人员<span style="color: black;">来讲</span>,都不陌生。在PHP<span style="color: black;">研发</span>中,<span style="color: black;">能够</span><span style="color: black;">运用</span>的缓存有<span style="color: black;">非常多</span>,譬如文件缓存、APCU缓存、数据库缓存、SESSION缓存、COOKIE缓存、Redis和Memcache缓存等。但这些都只是存储的方式<span style="color: black;">区别</span>,<span style="color: black;">已然</span><span style="color: black;">表现</span>在功效上。而在这往前一点,则是<span style="color: black;">咱们</span><span style="color: black;">针对</span>数据的理解。理<span style="color: black;">处理</span>定<span style="color: black;">运用</span>。<span style="color: black;">形成</span>系统有两大核心要素:数据与程序。其中<span style="color: black;">针对</span>流通在二进制中世界中的数据,它的品质和价值,不取决于<span style="color: black;">咱们</span>缓存的方式有多好,而在于<span style="color: black;">咱们</span>对它的理解有多深。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">这儿</span><span style="color: black;">供给</span>了一种数据可视化管理的新视角,基于这个新视角,<span style="color: black;">从而</span>讨论组织数据的方式,最后落地到多层缓存架构的设计与实现。</p>
<h1 style="color: black; text-align: left; margin-bottom: 10px;">6.2.1 数据划分的新视角</h1>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在用户打开浏览器,<span style="color: black;">拜访</span>网站的页面后,会看到<span style="color: black;">非常多</span>形式多样的内容、信息和<span style="color: black;">照片</span>、视频等。这些都<span style="color: black;">源自</span>于后端代码处理、加工和整合的数据。当网站系统成长到<span style="color: black;">必定</span>规模的时候,这些数据会来自四面八方,有从数据库提取的,有从接口请求的,有读缓存的,<span style="color: black;">亦</span>有根据公式、规则实时计算的,不一而足。更让人无可奈何的是,在过往项目迭代中,都缺少对这些数据的统一管理、规划和<span style="color: black;">守护</span>,<span style="color: black;">导致</span>于来一个新数据,就不加<span style="color: black;">思虑</span>“<span style="color: black;">茫然</span>”堆彻。最后造就了混沌、乏力的数据体系。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/be99f08414ec40b5b675c419bbf560bc~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1729840829&x-signature=lVMjShnjM7idOlGFHGC98wP7vvg%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">图6-1 传统网站数据的划分,混沌而乏力</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">那应该怎么组织企业级网站数据,才是行之有效的呢?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">软件<span style="color: black;">研发</span>这一<span style="color: black;">行业</span>,有不少灵感是从其他行业、自然界启发而来的。<span style="color: black;">咱们</span>不妨先来回想一下高中时代学习的化学方程式。<span style="color: black;">能够</span>说,有时化学方程式<span style="color: black;">繁杂</span>到我怎么背都背不下来,但我<span style="color: black;">晓得</span>在化学方程式的左边是反应物,右边是生成物,而中间是反应<span style="color: black;">要求</span>。<span style="color: black;">实质</span>上,化学方程式是很容易理解的,并且它能够清晰、准确、恰当地<span style="color: black;">暗示</span><span style="color: black;">繁杂</span>化学反应的本质。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">此刻</span>,<span style="color: black;">做为</span>软件开发工程师的<span style="color: black;">咱们</span>,有<span style="color: black;">无</span><span style="color: black;">发掘</span>错误<span style="color: black;">繁杂</span>的网站数据与化学之间的微妙关系?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">一方面,由分子<span style="color: black;">构成</span>的化学物质,有活泼、稳定之分。越活泼的物质变化越快,反之,越稳定的物质变化缓慢,<span style="color: black;">能够</span><span style="color: black;">安置</span>很长一段时间。而<span style="color: black;">针对</span>网站数据,有的需要频繁更新<span style="color: black;">乃至</span>实时更新,如商品库存;有的则相对稳定,不需要频繁更新并在业务上<span style="color: black;">能够</span>接受一<span style="color: black;">按时</span>间的延时,如商品的信息;有的<span style="color: black;">乃至</span>非常稳定,<span style="color: black;">一般</span>很长的时间内都不会<span style="color: black;">出现</span>变化,如全站的通用开关配置。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">另一方面,化学反应前的分子,会在特定的<span style="color: black;">要求</span>下,产生化学反应,从而生成<span style="color: black;">最后</span>新的分子和产物。<span style="color: black;">针对</span>网站数据,道理是类似的。所获取到的原始数据,<span style="color: black;">一般</span>都不会直接输出到页面,而是会<span style="color: black;">经过</span>一系列的操作,加工处理,<span style="color: black;">包含</span>数据在业务层面的二次转换、包装、排序,<span style="color: black;">亦</span><span style="color: black;">包含</span>了技术层面的缓存、队列、多线程等。经过各函数、类、接口、模块处理后,才会形成<span style="color: black;">咱们</span><span style="color: black;">最后</span>呈现给终端用户的信息。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">这般</span>,联想到原子的轨道图,<span style="color: black;">按照</span>网站数据<span style="color: black;">自己</span>的稳定程度,<span style="color: black;">咱们</span><span style="color: black;">能够</span>得到一种新的企业级网站数据新视角。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/a75528be0e074fabb04f20607b8c9adb~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1729840829&x-signature=cE7nsCD51TXfSjue4VwEqauw3dc%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">图6-2 数据的稳定程序<span style="color: black;">指的是</span>数据变化的频率,频率越高越活泼,反之越稳定</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">当一个网站是企业级网站时,就整体页面而言,它需要很高的响应速度。细分下来,页面各数据需要具备合适的缓存策略,并能以一种简单明了的方式来进行管理。这些数据,肯定不是杂乱无章地存在系统之中,而是以某一种特定的方式,遵循某种规律,有序地分布在系统中。<span style="color: black;">咱们</span>没找到,并不<span style="color: black;">暗示</span>这种规律不存在。若按<span style="color: black;">这儿</span>所说的新视角,<span style="color: black;">能够</span><span style="color: black;">显著</span><span style="color: black;">发掘</span>,针对以往混沌的数据,<span style="color: black;">此刻</span>有了全新井然有序的划分规律。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/0010c6e202744481bbd96369fc826cd5~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1729840829&x-signature=giEgBLBJzpmMRnC3KQIpPX%2FqVwM%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">图6-3 传统数据分布与新视角的划分对比</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在这<span style="color: black;">基本</span>再进一步,<span style="color: black;">咱们</span><span style="color: black;">能够</span>推演出正确<span style="color: black;">运用</span>企业数据的方式,通俗<span style="color: black;">来讲</span><span style="color: black;">便是</span>“打开企业级网站数据的正确姿势”。为了在<span style="color: black;">有效</span>缓存和实时性之间取得更好的平衡,需要为<span style="color: black;">区别</span>的业务数据,<span style="color: black;">按照</span>各自的稳定程度,为其<span style="color: black;">选取</span><span style="color: black;">区别</span>的缓存策略。例如<span style="color: black;">针对</span>列表页的档期信息,<span style="color: black;">因为</span><span style="color: black;">拜访</span>频繁,<span style="color: black;">不可</span>每次都直接从数据库中读取,而是应该进行缓存之。又如<span style="color: black;">针对</span>成千上万个细粒度的商品信息,<span style="color: black;">倘若</span><span style="color: black;">运用</span>的是本地缓存,<span style="color: black;">亦</span>是不<span style="color: black;">恰当</span>的,<span style="color: black;">由于</span>本地缓存空间有限,<span style="color: black;">基本</span>容纳不了<span style="color: black;">那样</span>多组合<span style="color: black;">状况</span>的海量商品列表,<span style="color: black;">最后</span>会<span style="color: black;">引起</span>本地缓存频繁淘汰,反而适得其反。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">结合数据的稳定程度,和数据<span style="color: black;">拜访</span>的<span style="color: black;">状况</span>,<span style="color: black;">能够</span>引出数据稳定-<span style="color: black;">拜访</span>象限分布图。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/bcdc230abbdb44e7bbee45f23ec243fe~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1729840829&x-signature=DL91ydS88CgqjQkxRTgPA0tcX9c%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">图6-4 数据稳定-<span style="color: black;">拜访</span>象限分布</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这个数据稳定-<span style="color: black;">拜访</span>象限分布图<span style="color: black;">特别有</span>意思,值得花点时间来<span style="color: black;">科研</span>和学习。一旦<span style="color: black;">把握</span>其中的要点,<span style="color: black;">针对</span>后面设计和规划企业级网站数据将会大有裨益。<span style="color: black;">能够</span>看到,前面是按数据<span style="color: black;">自己</span>稳定程度单一维度进行划分,<span style="color: black;">此刻</span>是结合数据的使用场景,即<span style="color: black;">增多</span>了数据<span style="color: black;">拜访</span>的频率这个新维度,从而构<span style="color: black;">成为了</span>此象限图。<span style="color: black;">那样</span>这象限图又<span style="color: black;">能够</span>给到<span style="color: black;">咱们</span>什么启发呢?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">就<span style="color: black;">这儿</span>的图而言,左上角的实心大圆圈<span style="color: black;">暗示</span>最稳定的数据但又是<span style="color: black;">拜访</span>得最多的数据,例如全局配置数据,几乎<span style="color: black;">每一个</span>页面都会用到,最<span style="color: black;">平常</span>的莫过于网站的标题、Logo<span style="color: black;">照片</span>链接这些基本公共信息。在这个区域要<span style="color: black;">重视</span>的一点是,缓存时要避免Hot Key问题。右上角<span style="color: black;">暗示</span>极不稳定的数据,<span style="color: black;">一样</span>需要高频<span style="color: black;">拜访</span>,例如商品的库存。尤其在秒杀活动的时候,<span style="color: black;">针对</span>库存的数量<span style="color: black;">需求</span>就更严格了,一个<span style="color: black;">亦</span><span style="color: black;">不可</span>少,一个<span style="color: black;">亦</span><span style="color: black;">不可</span>多,否则就会<span style="color: black;">显现</span>超卖的现象。<span style="color: black;">此时</span>,<span style="color: black;">需求</span>的数据都是具备实时性的,<span style="color: black;">不可</span>缓存,<span style="color: black;">或</span>即便缓存<span style="color: black;">亦</span>要快速同步,<span style="color: black;">由于</span>有时效性<span style="color: black;">需求</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">再来看下半部分,左下方区域<span style="color: black;">暗示</span>既稳定、<span style="color: black;">拜访</span>次数又少的数据,<span style="color: black;">因此呢</span><span style="color: black;">咱们</span><span style="color: black;">不消</span><span style="color: black;">那样</span>担心,<span style="color: black;">能够</span>缓存很长一段时间,<span style="color: black;">亦</span><span style="color: black;">能够</span><span style="color: black;">运用</span><span style="color: black;">有些</span>低速的缓存<span style="color: black;">方法</span>。例如<span style="color: black;">资讯</span><span style="color: black;">文案</span>一经审核发布后,基本不会再作修改,但并不是每篇<span style="color: black;">文案</span>都会高频<span style="color: black;">拜访</span>。最后<span style="color: black;">针对</span>右下方象限,则又是另一个需要<span style="color: black;">尤其</span>关注的<span style="color: black;">地区</span>。在这个区域,数据是不稳定的,容易<span style="color: black;">出现</span>变化,但<span style="color: black;">拜访</span>量时高时低,流量不确定。<span style="color: black;">一般</span><span style="color: black;">咱们</span>的核心业务数据就落在这个区域内,占据了大部分网站数据。这些数据可能是用户生成的,<span style="color: black;">或</span>是<span style="color: black;">经过</span>管理后台发布编辑而来。例如用户发布的<span style="color: black;">博客</span>,在供应商管理系统录入的商品信息等。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">针对网站数据本身的特质,<span style="color: black;">咱们</span><span style="color: black;">能够</span><span style="color: black;">按照</span>数据的稳定程度来对数据进行归类划分。<span style="color: black;">而后</span>,结合数据的<span style="color: black;">运用</span>场景,<span style="color: black;">思虑</span>其<span style="color: black;">拜访</span>量的<span style="color: black;">状况</span>,得出数据稳定-<span style="color: black;">拜访</span>象限分布图。这是一个新的数据管理视角。下面<span style="color: black;">咱们</span>再来看下,在这新视角的<span style="color: black;">基本</span>上,<span style="color: black;">能够</span>得出<span style="color: black;">怎么样</span>的架构设计,从而实现多级缓存和可视化管理。</p>
<h1 style="color: black; text-align: left; margin-bottom: 10px;">6.2.2 <span style="color: black;">运用</span>缓存的<span style="color: black;">平常</span>例子与<span style="color: black;">坏处</span>端</h1>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">如前面所说,在PHP中能<span style="color: black;">运用</span>的缓存方式有<span style="color: black;">非常多</span>,例如文件缓存、Redis缓存、APCU缓存等。但<span style="color: black;">此刻</span><span style="color: black;">咱们</span>缺的不是缓存的技术,而是缺乏正确<span style="color: black;">运用</span>缓存的方式,以及恰当组合<span style="color: black;">运用</span>多级缴存的策略。先来看一个普通<span style="color: black;">运用</span>缓存的简单例子。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">一个<span style="color: black;">平常</span>的场景是获取用户的个人信息,<span style="color: black;">按照</span>用户的ID<span style="color: black;">查找</span>数据库中的用户表,<span style="color: black;">而后</span>返回相应的用户信息。<span style="color: black;">这儿</span>暂时不关注底层实现,以下是调用的代码示例。</p><span style="color: black;"><span style="color: black;"><?php</span>
<span style="color: black;">// 用户ID</span>
$userId = <span style="color: black;">1</span>;
<span style="color: black;">// 从数据库获取用户信息</span>
$model = <span style="color: black;">new</span> User();
$userInfo = $model->getUserInfo($userId);
<span style="color: black;">// 输出用户信息</span>
var_dump($userInfo);</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">当需要<span style="color: black;">运用</span>缓存时,下面的代码写法<span style="color: black;">亦</span>是很<span style="color: black;">平常</span>的,<span style="color: black;">亦</span>很容易理解。</p><span style="color: black;"><span style="color: black;"><?php</span>
<span style="color: black;">// 用户ID</span>
$userId = <span style="color: black;">1</span>;
<span style="color: black;">// 从缓存中获取</span>
$cache = <span style="color: black;">new</span> Cache();
$key = <span style="color: black;">userinfo_</span> . $userId;
$userInfo = $cache->get($key);
<span style="color: black;">// 缓存<span style="color: black;">无</span></span>
<span style="color: black;">if</span> (<span style="color: black;">empty</span>($userInfo)) {
<span style="color: black;">// 从数据库获取用户信息</span>
$model = <span style="color: black;">new</span> User();
$userInfo = $model->getUserInfo($userId);
<span style="color: black;">// 同步写入缓存,缓存10分钟</span>
$cache->set($key, $userInfo, <span style="color: black;">600</span>);
}
<span style="color: black;">// 输出用户信息</span>var_dump($userInfo);</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">虽然这是<span style="color: black;">公众</span><span style="color: black;">运用</span>缓存的方式,初步看起来<span style="color: black;">亦</span><span style="color: black;">无</span>什么问题,但试想一下,打开一个企业级网站页面时,需要的数据数量从几份到十几份不等,而一个企业级系统中的数据规模<span style="color: black;">更加是</span><span style="color: black;">能够</span>达到成千上百个。再深入思考一下,<span style="color: black;">倘若</span>都是<span style="color: black;">根据</span>这种初级的缓存<span style="color: black;">运用</span>方式,将会催生多少重复性的代码?除了混乱外,还<span style="color: black;">增多</span>了<span style="color: black;">守护</span>的成本。关于重复性的代码,又分为两类,一类是显而易见的重复代码,基本都是“拷贝-粘贴”式的代码;另一类是隐式的重复,<span style="color: black;">很难</span>察觉,表面上看起来有点类似,但<span style="color: black;">无</span><span style="color: black;">显著</span>的重复。而<span style="color: black;">这儿</span><span style="color: black;">运用</span>缓存的初级方式就属于后者。这<span style="color: black;">亦</span>是<span style="color: black;">非常多</span>编程<span style="color: black;">研发</span>人员<span style="color: black;">无</span><span style="color: black;">发掘</span>,<span style="color: black;">或</span><span style="color: black;">无</span><span style="color: black;">留意</span><span style="color: black;">发掘</span>的<span style="color: black;">原由</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">至于<span style="color: black;">为何</span>,后面加入的新团队成员,即便<span style="color: black;">她们</span>有这种洞察的能力,<span style="color: black;">亦</span>没能去做出好的改变呢?我想这是社会认同感的作崇。当一个新成员加入到团队后,他在写新代码前都有<span style="color: black;">认识</span>或无<span style="color: black;">认识</span>参考之前代码的写法,<span style="color: black;">而后</span>模仿之。这是有<span style="color: black;">原由</span>的,<span style="color: black;">咱们</span><span style="color: black;">非常多</span>团队都会约定自己的编程风格和规范,即<span style="color: black;">需求</span>新人<span style="color: black;">不可</span>标新立异。另一方面,新人模仿前人写的代码,<span style="color: black;">亦</span>能很大程度上避免过往遇到过的缺陷。<span style="color: black;">然则</span>规则是需要树立的,但<span style="color: black;">亦</span>需要打破的。遵循规则,<span style="color: black;">能够</span>保持顺畅;而打破规则,则<span style="color: black;">能够</span>实现创新,<span style="color: black;">得到</span>突破。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">再回过头来看<span style="color: black;">这儿</span>的例子,相信读者在<span style="color: black;">日前</span>工作的项目中<span style="color: black;">亦</span>不乏<span style="color: black;">发掘</span>这类<span style="color: black;">状况</span>。那它的问题是什么呢?<span style="color: black;">咱们</span>又该<span style="color: black;">怎样</span>改进或应对呢?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span><span style="color: black;">咱们</span>把上面<span style="color: black;">运用</span>缓存的例子,加以分析,就能<span style="color: black;">发掘</span>在短短的十来行代码里,其实它做了<span style="color: black;">非常多</span>事情。</p><span style="color: black;">第1</span>步,构建<span style="color: black;">查找</span>参数。<span style="color: black;">这儿</span>参数<span style="color: black;">仅有</span>一个,即用户ID,但<span style="color: black;">亦</span>有可能需要多个参数。第二步,获取缓存数据。<span style="color: black;">详细</span>的缓存方式<span style="color: black;">这儿</span><span style="color: black;">无</span>指定,<span style="color: black;">能够</span>是文件缓存、Redis缓存<span style="color: black;">或</span>APCU缓存。第三步,当缓存<span style="color: black;">无</span>数据时,进入第四步;否则进入第六步。<span style="color: black;">重视</span>缓存的key要与参数相对应。第四步,从数据源获取原始数据。<span style="color: black;">这儿</span>的原始数据存放在数据库中,但<span style="color: black;">亦</span>有可能需要从远程接口获取,或其他存储媒介。第五步,将原始数据同步写入缓存,并设置缓存时间。第六步,返回或输出数据结果。<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">从上面六个<span style="color: black;">过程</span>中,<span style="color: black;">咱们</span>不禁发问:数据应该采用何种缓存方式,应该设置缓存超时时间为多久?而这又是出于何种<span style="color: black;">思虑</span>或依据?<span style="color: black;">这儿</span>混合了两个层级,一个是高层的概念层,一个是底层的实现层。<span style="color: black;">做为</span>客户端<span style="color: black;">研发</span>人员,他所关心的是获取到用户的信息,而不关注<span style="color: black;">详细</span><span style="color: black;">怎样</span>获取。那有什么<span style="color: black;">办法</span><span style="color: black;">能够</span>把缓存机制<span style="color: black;">运用</span>的这套模板抽取出来,既能分离关注点,又能达到代码重用的效果呢?最后一个问题,假设<span style="color: black;">咱们</span><span style="color: black;">期盼</span>在获取到数据后还想进行<span style="color: black;">有些</span>实时计算的操作,又该<span style="color: black;">怎样</span>设计、<span style="color: black;">研发</span>和扩展?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这些问题,归根到底,都是技术与业务关注点混杂的后果。从业务<span style="color: black;">方向</span>上看,<span style="color: black;">咱们</span><span style="color: black;">期盼</span><span style="color: black;">按照</span>用户ID就能提取用户的信息;但落实到技术代码编程实现时,技术人员就无<span style="color: black;">认识</span>地<span style="color: black;">思虑</span>到技术实现的细节。我该怎么存数据,我又该怎么缓存数据呢?<span style="color: black;">这儿</span>顺便延伸说一下,<span style="color: black;">咱们</span>软件<span style="color: black;">研发</span>工程师所任职的大部分<span style="color: black;">机构</span>都<span style="color: black;">能够</span>分为三类:纯技术驱动型的且以线上虚拟世界为主的信息<span style="color: black;">机构</span>、业务驱动型的互联网<span style="color: black;">机构</span>、和需要增设技术<span style="color: black;">分部</span>却不倚重技术的传统企业。除了<span style="color: black;">第1</span>类<span style="color: black;">机构</span>外,大部分业务驱动型<span style="color: black;">机构</span>的核心竞争力都<span style="color: black;">表现</span>在<span style="color: black;">制品</span>业务上,而<span style="color: black;">做为</span>在这类<span style="color: black;">机构</span>内任职的<span style="color: black;">研发</span>人员,<span style="color: black;">亦</span><span style="color: black;">便是</span><span style="color: black;">咱们</span>,<span style="color: black;">更加多</span>应该<span style="color: black;">思虑</span>的是<span style="color: black;">怎样</span><span style="color: black;">经过</span>技术快速支撑业务的发展。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">顺着这个思维再稍微想多一步,<span style="color: black;">咱们</span>就不难<span style="color: black;">发掘</span>,回归到例子中用户信息的获取,这<span style="color: black;">便是</span>业务的需要。而为了更快地获取用户信息而<span style="color: black;">运用</span>缓存,则是<span style="color: black;">咱们</span>技术本身的<span style="color: black;">需求</span><span style="color: black;">罢了</span>。<span style="color: black;">倘若</span>不加<span style="color: black;">思虑</span>,<span style="color: black;">茫然</span>顺从的<span style="color: black;">运用</span>初级的方式,<span style="color: black;">持续</span>编写重复性代码<span style="color: black;">运用</span>缓存,不仅<span style="color: black;">增多</span>了偶然的<span style="color: black;">繁杂</span>性,还拖慢了快速交付有价值业务的进度。并且,<span style="color: black;">倘若</span><span style="color: black;">咱们</span>需要从宏观上对某一大类的数据进行调控时,例如在<span style="color: black;">拜访</span>量低时,我们容许<span style="color: black;">能够</span>直接<span style="color: black;">查找</span>数据库以<span style="color: black;">得到</span>数据的实时性,当<span style="color: black;">拜访</span>量<span style="color: black;">增多</span>时,<span style="color: black;">咱们</span>则要<span style="color: black;">运用</span>缓存,以损失短暂数据有效性为代价换取高可用的服务质量。<span style="color: black;">倘若</span>原来的代码像七龙珠那样,分散在世界各地,等<span style="color: black;">咱们</span>历经千辛万苦齐集时,世界早已<span style="color: black;">出现</span>巨大的变化。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">咱们</span>应当始终关注业务的需要,<span style="color: black;">而后</span>把技术的关注点从中剥离出来,实现技术与业务的关注点分离。所提取出来的抽象、通用的技术<span style="color: black;">处理</span><span style="color: black;">方法</span>,要么是一个微架构,要么<span style="color: black;">便是</span>一个行业通用的<span style="color: black;">行业</span>标准。有了<span style="color: black;">这般</span>的认识后,再来看下<span style="color: black;">怎样</span>进行核心的设计,以满足技术上非功能性的<span style="color: black;">各样</span><span style="color: black;">需求</span>。</p>
<h1 style="color: black; text-align: left; margin-bottom: 10px;">6.2.3 数据供给器</h1>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">为了实现技术与业务的关注点分离,接下来将探寻可行的<span style="color: black;">处理</span><span style="color: black;">方法</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">近期</span>,在<span style="color: black;">咱们</span>团队<span style="color: black;">研发</span>的项目中,我<span style="color: black;">发掘</span>了<span style="color: black;">运用</span>匿名函数来封装原始数据获取的方式。大致的实现方式,应用到<span style="color: black;">咱们</span>的例子的示例代码如下:</p><span style="color: black;"><span style="color: black;"><?php</span>
<span style="color: black;">// 用户ID</span>
$userId = <span style="color: black;">1</span>;
$key = <span style="color: black;">userinfo_</span> . $userId;
<span style="color: black;">// <span style="color: black;">经过</span>匿名函数封装原始数据的获取</span>$userInfo = smart_cache_retrieve($key,<span style="color: black;">600</span>, <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">()</span> <span style="color: black;">use</span> <span style="color: black;">($userId)</span></span>{
<span style="color: black;">// 从数据库获取用户信息</span>
$model = <span style="color: black;">new</span> User();
$userInfo = $model->getUserInfo($userId);
});</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这种方式,确实抽取了缓存<span style="color: black;">运用</span>的模板,在某个程度上达到了重用的效果。但我觉得<span style="color: black;">不足</span>优雅,<span style="color: black;">亦</span><span style="color: black;">不足</span>正统。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">首要</span>,它<span style="color: black;">运用</span>了面向过程编程的匿名函数,并不是说面向过程编程的写法就<span style="color: black;">欠好</span>,而是在于PHP本身是一门脚本解释性编程语言,其语法是很通俗易懂的。<span style="color: black;">另外</span>,匿名函数不是PHP的一等<span style="color: black;">百姓</span>,PHP的上下文与闭包函数并不是很完美,<span style="color: black;">亦</span>不是它的侧重点。<span style="color: black;">针对</span>闭包函数支持较好的语言,我认为是Javascript。或许,<span style="color: black;">咱们</span>能找到一种更符合PHP本质、<span style="color: black;">更易</span>被接受的架构设计。好的架构设计不会让人觉得有意而为,或刻意要去学习和被迫接受,而是能让人顺其自然,<span style="color: black;">根据</span>约定成俗的方式去理解和<span style="color: black;">运用</span>。另一个<span style="color: black;">不足</span>友好的<span style="color: black;">地区</span>是,关于缓存的三要素:缓存的key,缓存的超时时间,缓存的数据。其中在<span style="color: black;">这儿</span>缓存的key和缓存的超时时间是暴露给客户端的,难以统一<span style="color: black;">掌控</span>。<span style="color: black;">另外</span>,<span style="color: black;">倘若</span>客户端<span style="color: black;">研发</span>人员A与<span style="color: black;">研发</span>人员B,刚好起的缓存key名字冲突了怎么办?谁来<span style="color: black;">发掘</span>,由谁来<span style="color: black;">处理</span>?这不是杞人忧天,而是为作理性的技术人员,<span style="color: black;">咱们</span>要<span style="color: black;">尽可能</span>做到严谨,<span style="color: black;">思虑</span>周全。</p>
<h1 style="color: black; text-align: left; margin-bottom: 10px;">数据供给器的核心设计</h1>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在前面做了<span style="color: black;">那样</span>多铺垫,<span style="color: black;">亦</span>对比了一个不怎么优雅的<span style="color: black;">处理</span><span style="color: black;">方法</span>后,<span style="color: black;">咱们</span>最后引出在面向对象的世界里,<span style="color: black;">举荐</span>的<span style="color: black;">处理</span><span style="color: black;">方法</span>——三套数据模板的核心架构设计。<span style="color: black;">这儿</span>不会作<span style="color: black;">仔细</span>的<span style="color: black;">详细</span>实现,但会着重分享这个核心架构设计的高层建设与实现要点。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">按照</span>“针对接口编程,而不是针对实现编程”这一思想,<span style="color: black;">咱们</span>需要在概念视角,站在业务的<span style="color: black;">方向</span>,构建设计<span style="color: black;">咱们</span>的高层接口。<span style="color: black;">咱们</span>把这类业务数据的获取封装到数据供给器DataProvider这一接口中。其肩负的责任,从以下的接口代码中<span style="color: black;">能够</span>一眼看出。<span style="color: black;">运用</span>抽象类的<span style="color: black;">原由</span>,是<span style="color: black;">由于</span>部分内部操作和钩子函数不需要对外暴露,要<span style="color: black;">运用</span>protected<span style="color: black;">守护</span>级别,而接口的操作<span style="color: black;">所有</span>在PHP中必须是public公开级别。另一个<span style="color: black;">原由</span>是有<span style="color: black;">有些</span>通用的模板实现和默认的钩子实现,需要在抽象基类中实现,减少<span style="color: black;">详细</span>实现子类的重复编程工作。下面是DataProvider抽象类的关键代码。</p><span style="color: black;"><span style="color: black;"><?php</span>
<span style="color: black;">require_once</span> dirname(<span style="color: black;">__FILE__</span>) . <span style="color: black;">/DataQuery.php</span>;
<span style="color: black;">/**
* 数据供给器接口
*
* - 接口抽离,便于在高层统一接口
* - <span style="color: black;">经过</span>多级缓存来优化性能
* - 支持<span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器链路收集
*
*<span style="color: black;">@author</span> dogstar 2018-06-17
*/</span>
<span style="color: black;">abstract</span> <span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">DataProvider</span> </span>{
<span style="color: black;">/**
* 获取业务数据
*
* <span style="color: black;">@param</span> DataQuery $query 获取业务数据的<span style="color: black;">查找</span>对象
* <span style="color: black;">@param</span>string &$trace <span style="color: black;">全世界</span><span style="color: black;">跟踪</span>收集器
*<span style="color: black;">@return</span> mixed/NULL 业务数据,NULL<span style="color: black;">暗示</span>获取失败
*/</span>
<span style="color: black;">public</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getData</span><span style="color: black;">(DataQuery $query, &$trace = )</span> </span>{
$cache = <span style="color: black;">$this</span>->getCacheInstance();
$key =<span style="color: black;">$this</span>->getCacheKey($query);
<span style="color: black;">// 从缓存中获取</span>
$data = $cache->get($key);
<span style="color: black;">if</span> ($data === <span style="color: black;">NULL</span>) {
<span style="color: black;">// 从数据源获取</span>
$data = <span style="color: black;">$this</span>->doGetData($query, $trace);
<span style="color: black;">// 写入到缓存</span>
$cache->set($key, $data, <span style="color: black;">$this</span>->getCacheExpireTime($query));
}
<span style="color: black;">// 钩子函数回调</span>
<span style="color: black;">$this</span>->afterGetData($query, $data);
<span style="color: black;">return</span>$data;
}
}</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">稍微解释一下,DataProvider::getData(DataQuery $query, &$trace = )操作是<span style="color: black;">供给</span>给客户端<span style="color: black;">研发</span>人员<span style="color: black;">运用</span>的接口,<span style="color: black;">经过</span>这个接口,<span style="color: black;">能够</span>快速方便地获取业务数据。在这个接口内,会封装一系列的操作,<span style="color: black;">包含</span>对缓存的读取与写入,对原始业务数据的获取,以及获取到原始业务数据后的加工处理等。它的<span style="color: black;">第1</span>个参数是<span style="color: black;">查找</span>对象,为避免过长的参数列表,<span style="color: black;">亦</span>为了统一接口签名,<span style="color: black;">咱们</span>引入了DataQuery<span style="color: black;">查找</span>对象类,它相当于一个结构体,<span style="color: black;">能够</span>不需要getter/setter,并且<span style="color: black;">运用</span>了魔法<span style="color: black;">办法</span>丰富它的<span style="color: black;">行径</span>。第二个参数是<span style="color: black;">全世界</span><span style="color: black;">跟踪</span>收集器,简单<span style="color: black;">来讲</span>,业务数据走过的路,经历过的节点,都<span style="color: black;">能够</span>记录在这上面,便于可视化管理和历史回放。关于<span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器,下一小节会重点讲解。</p>
<h1 style="color: black; text-align: left; margin-bottom: 10px;">内部辅助操作</h1>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">核心的代码实现,以及关键的操作,<span style="color: black;">已然</span>在DataProvider::getData(DataQuery $query, &$trace = )中完成。它<span style="color: black;">做为</span>对外的总入口,<span style="color: black;">供给</span>了清晰明了的<span style="color: black;">运用</span>方式。但客户端的<span style="color: black;">运用</span>越简单,内部的实现就会越<span style="color: black;">繁杂</span>。<span style="color: black;">因此</span><span style="color: black;">咱们</span>需要保持<span style="color: black;">有些</span>耐心继续往下看DataProvider抽象类的两大内部辅助操作。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">第1</span>类内部辅助操作,是针对业务数据的处理,<span style="color: black;">包含</span>对原始业务数据的获取,以及在获取业务数据后的加工处理钩子函数。如下所示:</p><span style="color: black;">abstract</span> <span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">DataProvider</span> </span>{
……
<span style="color: black;">/**
* 返回需要缓存的原始数据
*
*<span style="color: black;">@param</span> DataQuery $query 获取业务数据的<span style="color: black;">查找</span>对象
* <span style="color: black;">@param</span> string &$trace <span style="color: black;">全世界</span><span style="color: black;">跟踪</span>收集器
* <span style="color: black;">@return</span>mixed <span style="color: black;">重视</span>:<span style="color: black;">无</span>数据时请返回空数组array(),<span style="color: black;">或</span>,切勿返回NULL/FALSE
*/</span>
<span style="color: black;">abstract</span> <span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">doGetData</span><span style="color: black;">(DataQuery $query, &$trace = )</span></span>;
<span style="color: black;">/**
* 钩子函数:数据的实时处理操作,将会在业务数据成功获取后进行回调
*<span style="color: black;">@param</span> mixed &$data 业务数据
* <span style="color: black;">@return</span> mixed 加工处理后的业务数据
*/</span>
<span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">afterGetData</span><span style="color: black;">(DataQuery $query, &$data)</span> </span>{
<span style="color: black;">// 可选实现:加工处理</span>
}
}<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">第二类内部辅助操作,则是针对技术层面的缓存操作,<span style="color: black;">包含</span>获取缓存实例,方便内部<span style="color: black;">供给</span>缝纫点,从而切换<span style="color: black;">区别</span>的缓存策略,和获取缓存的Key、返回缓存有效时间这两个操作。如下所示:</p><span style="color: black;">abstract</span> <span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">DataProvider</span> </span>{
……
<span style="color: black;">/**
* 获取缓存实例
* <span style="color: black;">@return</span>Cache 缓存实例
*/</span>
<span style="color: black;">abstract</span> <span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getCacheInstance</span><span style="color: black;">()</span></span>;
<span style="color: black;">/**
* 获取缓存的Key,返回<span style="color: black;">独一</span>缓存key,<span style="color: black;">这儿</span>将$query传入,以便同类数据<span style="color: black;">按照</span><span style="color: black;">区别</span>的值生成<span style="color: black;">区别</span>的key
*
* <span style="color: black;">@param</span> DataQuery $query 获取业务数据的<span style="color: black;">查找</span>对象
* <span style="color: black;">@return</span> string 缓存key
*/</span>
<span style="color: black;">abstract</span> <span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getCacheKey</span><span style="color: black;">(DataQuery $query)</span></span>;
<span style="color: black;">/**
* 返回缓存有效时间,单位为:秒
*
*<span style="color: black;">@param</span> DataQuery $query 获取业务数据的<span style="color: black;">查找</span>对象
* <span style="color: black;">@return</span> int 缓存有效时间
*/</span>
<span style="color: black;">abstract</span> <span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getCacheExpireTime</span><span style="color: black;">(DataQuery $query)</span></span>;
}<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">而<span style="color: black;">针对</span>getCacheKey()操作,<span style="color: black;">无</span><span style="color: black;">供给</span>默认实现的<span style="color: black;">原由</span>是<span style="color: black;">由于</span><span style="color: black;">查找</span>参数里面的参数有可能是除了字符串类型外,还可能有数组、布尔值<span style="color: black;">或</span>其他类型。<span style="color: black;">倘若</span>统一处理,有可能<span style="color: black;">导致</span>数据丢失,<span style="color: black;">或</span><span style="color: black;">由于</span>特殊的符号影响缓存key的<span style="color: black;">构成</span>,<span style="color: black;">显现</span><span style="color: black;">违法</span>缓存key的<span style="color: black;">状况</span>。<span style="color: black;">况且</span>,有时并不是<span style="color: black;">所有</span>的参数都需要<span style="color: black;">做为</span>缓存key的<span style="color: black;">构成</span>部分。</p>
<h1 style="color: black; text-align: left; margin-bottom: 10px;">参数<span style="color: black;">查找</span>对象</h1>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">完成对数据供给器DataProvider的塑造后,再来看下它的周边配套<span style="color: black;">设备</span>。其中最为关键的是参数<span style="color: black;">查找</span>对象类DataQuery。它的实现代码很简单,其中<span style="color: black;">运用</span>了两个魔法函数:__set()和__get()。</p><span style="color: black;"><span style="color: black;"><?php</span>
<span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">DataQuery</span> </span>{
<span style="color: black;">public</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">__set</span><span style="color: black;">($name, $value)</span> </span>{
<span style="color: black;">$this</span>->$name = $value;
}
<span style="color: black;">public</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">__get</span><span style="color: black;">($name)</span> </span>{
<span style="color: black;">return</span> <span style="color: black;">isset</span>(<span style="color: black;">$this</span>->$name) ? <span style="color: black;">$this</span>->$name : <span style="color: black;">NULL</span>;
}
}</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这是一个松散的结构体,业务在实现时,<span style="color: black;">能够</span>丰富其子类,清晰定义<span style="color: black;">查找</span>对象的<span style="color: black;">详细</span>参数名<span style="color: black;">叫作</span>,<span style="color: black;">亦</span><span style="color: black;">能够</span><span style="color: black;">运用</span>此默认的实现类,<span style="color: black;">而后</span>填充必要的参数。但<span style="color: black;">意见</span><span style="color: black;">运用</span>前者。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">最后稍微<span style="color: black;">弥补</span>一下,<span style="color: black;">此时</span><span style="color: black;">亦</span>会<span style="color: black;">运用</span>到缓存,但鉴于缓存本身的实现<span style="color: black;">已然</span>是广为人知的技术,<span style="color: black;">这儿</span>就<span style="color: black;">再也不</span><span style="color: black;">尤其</span>说明。</p>
<h1 style="color: black; text-align: left; margin-bottom: 10px;">6.2.4 3+1套数据模板</h1>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">至此,<span style="color: black;">咱们</span>有了基本的核心元素:数据供给器和参数<span style="color: black;">查找</span>对象,以及缓存机制。还记得前面介绍过的数据稳定-<span style="color: black;">拜访</span>象限分布吗?数据<span style="color: black;">按照</span>其稳定程度和<span style="color: black;">拜访</span>频率<span style="color: black;">能够</span>分为四类:</p>稳定但高频<span style="color: black;">拜访</span>的数据稳定且低频<span style="color: black;">拜访</span>的数据不稳定且高频<span style="color: black;">拜访</span>的数据不稳定但低频<span style="color: black;">拜访</span>的数据<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">下面将探讨<span style="color: black;">怎样</span><span style="color: black;">运用</span>基本的核心元素,为这四类数据<span style="color: black;">供给</span>合适的数据模板,<span style="color: black;">逐步</span>丰富<span style="color: black;">咱们</span>的数据体系。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">3+1套数据模板,其中的3套数据模板是分别针对稳定且低频<span style="color: black;">拜访</span>、稳定但高频<span style="color: black;">拜访</span>、不稳定但低频<span style="color: black;">拜访</span>这三类数据的模板,它们依次是:轻量级数据模板、重量级数据模板,和介于这两者之间的多级缓存数据模板。剩下的1套数据模板则是针对不稳定且高频<span style="color: black;">拜访</span>的数据,<span style="color: black;">亦</span><span style="color: black;">便是</span>不适宜<span style="color: black;">运用</span>任何缓存的实时数据,对应的是实时数据模板。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">前面3套数据模板的差异点<span style="color: black;">重点</span>是在于缓存机制和缓存策略的<span style="color: black;">区别</span>,着重满足业务数据本身的非功能性<span style="color: black;">需要</span>。<span style="color: black;">这儿</span>以其中一个模板为例,讲解<span style="color: black;">怎样</span>实现。其他模板实现思路类似,则<span style="color: black;">再也不</span>赘述。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">以轻量级数据模板为例,它的抽象类代码如下:</p><span style="color: black;"><span style="color: black;"><?php</span>
<span style="color: black;">require_once</span> dirname(<span style="color: black;">__FILE__</span>) . <span style="color: black;">/DataProvider.php</span>;
<span style="color: black;">// 轻量级数据模板</span>
<span style="color: black;">abstract</span> <span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">LightWeightDataProvider</span> <span style="color: black;">extends</span> <span style="color: black;">DataProvider</span> </span>{
<span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getCacheInstance</span><span style="color: black;">()</span> </span>{
<span style="color: black;">return</span> <span style="color: black;">new</span>LightWeightCache();
}<span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getCacheExpireTime</span><span style="color: black;">(DataQuery $query)</span> </span>{
<span style="color: black;">return</span> <span style="color: black;">600</span>;
}
}</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">它做了两件事情,分别<span style="color: black;">指的是</span>定了<span style="color: black;">运用</span>LightWeightCache轻量级缓存机制,以及统一指定了缓存的有效时间为600秒,即10分钟。LightWeightCache的<span style="color: black;">详细</span>实现,<span style="color: black;">能够</span>是<span style="color: black;">运用</span>集群缓存,如Redis、Memcache<span style="color: black;">或</span>其他NoSQL服务。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">继续回到前面的用户信息的获取示例,在改用此轻量级数据模板后,它需要<span style="color: black;">首要</span>实现<span style="color: black;">详细</span>的数据模板子类,以及<span style="color: black;">供给</span>相应的<span style="color: black;">查找</span>对象子类。<span style="color: black;">关联</span>代码如下:</p><span style="color: black;"><span style="color: black;"><?php</span>
<span style="color: black;">require_once</span>dirname(<span style="color: black;">__FILE__</span>) . <span style="color: black;">/LightWeightDataProvider.php</span>;
<span style="color: black;">// 实现<span style="color: black;">详细</span>的业务数据获取,如:获取用户信息</span>
<span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">UserData</span> <span style="color: black;">extends</span> <span style="color: black;">LightWeightDataProvider</span> </span>{
<span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">doGetData</span><span style="color: black;">(DataQuery $query, &$trace = )</span> </span>{
$model = <span style="color: black;">new</span> User();
<span style="color: black;">return</span> $model->getUserInfo($query->userId);
}
<span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getCacheKey</span><span style="color: black;">(DataQuery $query)</span> </span>{
<span style="color: black;">return</span> <span style="color: black;">userinfo_</span> . $query->userId;
}
}
<span style="color: black;">// 用户信息<span style="color: black;">查找</span>对象</span>
<span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">UserInfoDataQuery</span> <span style="color: black;">extends</span> <span style="color: black;">DataQuery</span> </span>{
<span style="color: black;">public</span> $userId;
}</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在完成前面的准备工作后,最后再来看下客户端调用的新代码。</p><span style="color: black;">// 实例化</span>
$user = <span style="color: black;">new</span> UserData();
$query = <span style="color: black;">new</span> UserInfoDataQuery();
<span style="color: black;">// <span style="color: black;">经过</span>轻量级数据模板获取用户信息</span>
$query->userId = <span style="color: black;">1</span>;
$userInfo = $user->getData($query);
<span style="color: black;">// 输出结果</span>var_dump($userInfo);<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在完成<span style="color: black;">这般</span>的设计,以及编程工作后,<span style="color: black;">倘若</span>需要切换<span style="color: black;">区别</span>的缓存策略,<span style="color: black;">能够</span>在不改动客户端调用代码的<span style="color: black;">状况</span>下,只需要切换UserData子类继承<span style="color: black;">区别</span>的数据模板基类<span style="color: black;">就可</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span>要追求极致的代码,还<span style="color: black;">能够</span>对上面的客户端调用代码进行封装,<span style="color: black;">而后</span><span style="color: black;">经过</span>简化版的调用向客户端<span style="color: black;">供给</span>获取用户信息的快速通道。<span style="color: black;">由于</span>在上面的代码片段中,<span style="color: black;">独一</span>变化的是用户ID这一参数,故而<span style="color: black;">能够</span>提取到一个类静态函数的内部。如下:</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">UserInfoHelper</span> </span>{
<span style="color: black;">public</span> <span style="color: black;">static</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">get</span><span style="color: black;">($userId)</span> </span>{
<span style="color: black;">// 实例化</span>
$user = <span style="color: black;">new</span> UserData();
$query = <span style="color: black;">new</span>UserInfoDataQuery();<span style="color: black;">// <span style="color: black;">经过</span>轻量级数据模板获取用户信息</span>
$query->userId = $userId;
$userInfo = $user->getData($query);
<span style="color: black;">return</span> $userInfo;
}
}
<span style="color: black;">// 输出结果</span>var_dump(UserInfoHelper::get(<span style="color: black;">1</span>));<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">以上,是轻量级数据模板实现的基本思路,剩下的重量级数据模板和多缓存缓存数据模板实现的思路与之类似,<span style="color: black;">区别</span>的是<span style="color: black;">运用</span>的缓存策略不<span style="color: black;">同样</span>,默认指定的缓存失效时间<span style="color: black;">亦</span><span style="color: black;">区别</span>。但实时数据模板比较有意思,它是一个特例,<span style="color: black;">咱们</span><span style="color: black;">一块</span>来看下。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">首要</span>,<span style="color: black;">亦</span>是数据供给器的抽象子类,在<span style="color: black;">这儿</span>它<span style="color: black;">供给</span>了一个空对象缓存实例,<span style="color: black;">由于</span>不需要缓存,<span style="color: black;">因此</span>缴存的key和缓存时间默认<span style="color: black;">能够</span>为空。</p><span style="color: black;"><span style="color: black;"><?php</span>
<span style="color: black;">require_once</span> dirname(<span style="color: black;">__FILE__</span>) . <span style="color: black;">/DataProvider.php</span>;
<span style="color: black;">// 实时数据模板</span>
<span style="color: black;">abstract</span> <span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">RealTimeDataProvider</span> <span style="color: black;">extends</span> <span style="color: black;">DataProvider</span> </span>{<span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getCacheInstance</span><span style="color: black;">()</span> </span>{
<span style="color: black;">return</span> <span style="color: black;">new</span> NoneCache();
}
<span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getCacheKey</span><span style="color: black;">(DataQuery $query)</span> </span>{
<span style="color: black;">return</span> ;
}
<span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getCacheExpireTime</span><span style="color: black;">(DataQuery $query)</span> </span>{
<span style="color: black;">return</span> <span style="color: black;">0</span>;
}
}</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span>哪天在获取用户信息时,<span style="color: black;">再也不</span>需要任何缓存时,只需要将UserData类的基类改为RealTimeDataProvider<span style="color: black;">就可</span>,如下所示:</p><span style="color: black;"><span style="color: black;"><?php</span>
<span style="color: black;">// 更换为实时数据模板</span>
<span style="color: black;">// class UserData extends LightWeightDataProvider {</span>
<span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">UserData</span> <span style="color: black;">extends</span> <span style="color: black;">RealTimeDataProvider</span> </span>{
<span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">doGetData</span><span style="color: black;">(DataQuery $query, &$trace = )</span> </span>{
$model =<span style="color: black;">new</span> User();
<span style="color: black;">return</span> $model->getUserInfo($query->userId);
}
}</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其他的实现代码和客户端调用<span style="color: black;">能够</span>保持不变。由此可推,逆向<span style="color: black;">亦</span>是成立的。即一<span style="color: black;">起始</span><span style="color: black;">无</span><span style="color: black;">运用</span>缓存,<span style="color: black;">倘若</span>需要<span style="color: black;">运用</span>缓存,<span style="color: black;">亦</span>可<span style="color: black;">经过</span>改变基类来切换。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这<span style="color: black;">便是</span><span style="color: black;">咱们</span>所说的3+1套数据模板。最后<span style="color: black;">做为</span>小结部分,<span style="color: black;">咱们</span>画一个整体的静态类结构UML图,来加深对此核心架构设计的理解。看下它是<span style="color: black;">怎样</span>分离技术与业务关注点,又是<span style="color: black;">怎样</span>把概念视角、规约视角、实现视角这三层进行划分的。</p>
<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/f07cf254fe1d471cbe9db34b179f0f11~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1729840829&x-signature=lbzSJoZWAy9rz98XLPlkF%2BRkjEE%3D" style="width: 50%; margin-bottom: 20px;"></div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">图6-5 数据供给器的核心设计</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这个架构设计,把<span style="color: black;">咱们</span>前面讲到的关键要素、3+1套数据模板、以及<span style="color: black;">详细</span>实现的业务类都有机地串联了起来。<span style="color: black;">根据</span>三层视角,从上往下依次是概念层、规约层、实现层。概念层与规约层的划分,有效地分离了技术与业务的关注点,在业务上,我只需要关注业务的数据的获取<span style="color: black;">就可</span>,而<span style="color: black;">不消</span>关心它是怎么来的。规约层与实现层的划分,则将架构的<span style="color: black;">基本</span>组件设计与<span style="color: black;">详细</span>实现的业务代码进行了分离,类的职责更为<span style="color: black;">知道</span>,架构师与<span style="color: black;">研发</span>工程师之间的合作<span style="color: black;">亦</span>就更为明朗。实现层是需要<span style="color: black;">研发</span>工程来<span style="color: black;">按照</span>业务<span style="color: black;">详细</span>实现的,而规约层则<span style="color: black;">能够</span>由架构师来统一<span style="color: black;">安排</span>、搭建和设计。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在大学时代,<span style="color: black;">咱们</span>就学到了,程序由算法和数据<span style="color: black;">构成</span>。数据中<span style="color: black;">包含</span>了<span style="color: black;">非常多</span>有价值的信息,<span style="color: black;">因此呢</span>很值得<span style="color: black;">咱们</span>花一点时间来深入讨论这<span style="color: black;">一起</span>。关于企业级网站数据,暂时分享到<span style="color: black;">这儿</span>。这肯定不是放之四海而皆准的<span style="color: black;">方法</span>,不<span style="color: black;">必定</span>能适用于任何项目<span style="color: black;">研发</span>中,但它确实是行之有效的一种<span style="color: black;">处理</span><span style="color: black;">方法</span>,并且值得<span style="color: black;">咱们</span>去思考、去探索、去演进。</p>
<h1 style="color: black; text-align: left; margin-bottom: 10px;">6.2.5 <span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器</h1>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">接下来的主题是<span style="color: black;">怎样</span>进行企业级网站数据的可视化管理。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">前面提及到的<span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器,这一节重点来<span style="color: black;">仔细</span>说明。为了方便查看数据的<span style="color: black;">源自</span>和穿透<span style="color: black;">状况</span>,<span style="color: black;">咱们</span>引入了对数据<span style="color: black;">源自</span>的<span style="color: black;">跟踪</span>,并且各业务数据<span style="color: black;">能够</span><span style="color: black;">按照</span>需要进行记录累加。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在前面设计数据供给器时,为避免混淆关注点,<span style="color: black;">已然</span>为<span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器预留了占位符,<span style="color: black;">这儿</span>继续完成<span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器的实现代码。以轻量级数据模板为例,追加<span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器,只需要修改三处<span style="color: black;">地区</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">首要</span>,在客户端调用入口处,<span style="color: black;">亦</span><span style="color: black;">便是</span><span style="color: black;">跟踪</span>器的起点,添加业务数据的名<span style="color: black;">叫作</span>,并把此<span style="color: black;">跟踪</span>链路字符串传递下去。</p>$query->userId = <span style="color: black;">1</span>;
$trace = <span style="color: black;">|UserData-</span>; <span style="color: black;">// <span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器:用户信息(起点)</span>
$userInfo = $user->getData($query, $trace);<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">这儿</span>以竖线为多个数据的分割符,并且以UserData<span style="color: black;">做为</span>用户数据的名<span style="color: black;">叫作</span>。为了减少最后输出的流量,以及避免外界<span style="color: black;">晓得</span>内部的数据<span style="color: black;">状况</span>,<span style="color: black;">亦</span><span style="color: black;">能够</span>采用缩写的形式,例如<span style="color: black;">运用</span>:UD。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其次,修改轻量级数据模板,统一加上<span style="color: black;">跟踪</span>标识。<span style="color: black;">此时</span>需要重载基类的getData()<span style="color: black;">办法</span>,在追加完标识后,继续调用父类的getData()<span style="color: black;">办法</span>。</p><span style="color: black;">abstract</span> <span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">LightWeightDataProvider</span> <span style="color: black;">extends</span> <span style="color: black;">DataProvider</span> </span>{
<span style="color: black;">public</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getData</span><span style="color: black;">(DataQuery $query, &$trace = )</span> </span>{
<span style="color: black;">// <span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器:轻量级数据模板,追加L标识</span>
$trace .= <span style="color: black;">L</span>;
<span style="color: black;">return</span> <span style="color: black;">parent</span>::getData($query, $trace);
}
}<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">L在<span style="color: black;">这儿</span><span style="color: black;">暗示</span>数据经过了轻量级数据模板,依此类推,重量级数据模板<span style="color: black;">能够</span>用H<span style="color: black;">暗示</span>,而多级缓存数据模板<span style="color: black;">能够</span>用M<span style="color: black;">暗示</span>,最后实时数据模板<span style="color: black;">能够</span>用R来<span style="color: black;">暗示</span>,都是取自类名<span style="color: black;">叫作</span>的首字母。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">最后,在<span style="color: black;">详细</span>实现的业务数据子类中,追加最后数据源的<span style="color: black;">源自</span>标识。<span style="color: black;">一样</span><span style="color: black;">运用</span>开头首字母来<span style="color: black;">暗示</span>,例如D<span style="color: black;">暗示</span><span style="color: black;">源自</span>数据库,A<span style="color: black;">暗示</span><span style="color: black;">源自</span>于APCU缓存,<span style="color: black;">针对</span>Redis和Memcache,<span style="color: black;">思虑</span>到前面已被数据模板占用,<span style="color: black;">能够</span>起用新的名<span style="color: black;">叫作</span>,如取最后一个字母,S<span style="color: black;">暗示</span>Redis,而E<span style="color: black;">暗示</span>Memcache。这些都是<span style="color: black;">能够</span>内部约定的。在用户数据实现的子类中,<span style="color: black;">因为</span>是从数据库获取用户信息,故<span style="color: black;">运用</span>D来标识。</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">UserData</span> <span style="color: black;">extends</span> <span style="color: black;">LightWeightDataProvider</span> </span>{
<span style="color: black;">protected</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">doGetData</span><span style="color: black;">(DataQuery $query, &$trace = )</span> </span>{
<span style="color: black;">// <span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器:数据库</span>
$trace .= <span style="color: black;">D</span>;
$model = <span style="color: black;">new</span> User();
<span style="color: black;">return</span>$model->getUserInfo($query->userId);
}
}<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">完成这些<span style="color: black;">跟踪</span>器的填充后,最后<span style="color: black;">能够</span>把<span style="color: black;">跟踪</span>的结果输出来。例如<span style="color: black;">这儿</span>,最后会输出“|UserData-LD”。<span style="color: black;">倘若</span>把<span style="color: black;">全部</span>网站页面用到的数据都<span style="color: black;">这般</span>加上<span style="color: black;">跟踪</span>器,<span style="color: black;">咱们</span>最后就<span style="color: black;">能够</span>得到数据可视化管理的全局<span style="color: black;">状况</span>。在页面渲染时,<span style="color: black;">能够</span><span style="color: black;">经过</span>头部信息把<span style="color: black;">跟踪</span>的结果返回给浏览器,便于<span style="color: black;">咱们</span>监控、调试和排查。<span style="color: black;">按照</span>此业务数据链路<span style="color: black;">跟踪</span>的<span style="color: black;">状况</span>,<span style="color: black;">咱们</span>能<span style="color: black;">更易</span>察觉现有系统中存在的问题。例如该用缓存的数据<span style="color: black;">是不是</span><span style="color: black;">运用</span>了合适的缓存; <span style="color: black;">针对</span>容易因穿透而<span style="color: black;">导致</span>雪崩的数据<span style="color: black;">咱们</span>有<span style="color: black;">无</span>提前<span style="color: black;">经过</span>计划任务来生成并预热; <span style="color: black;">倘若</span>数据未能<span style="color: black;">即时</span>更新,是<span style="color: black;">由于</span>缓存还没刷新还是<span style="color: black;">由于</span>确实数据本身未被修正; 诸如此类。<span style="color: black;">能够</span>说<span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器,<span style="color: black;">怎样</span>应用恰当,会是<span style="color: black;">咱们</span>项目<span style="color: black;">研发</span>中的一大利器。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">思虑</span>到<span style="color: black;">非常多</span>时候,网站都要<span style="color: black;">供给</span>预览的功能,<span style="color: black;">倘若</span>想追求更极致的数据供给器,<span style="color: black;">咱们</span><span style="color: black;">能够</span>在对象<span style="color: black;">查找</span>对象添加读缓存开关、写缓存开关,以便<span style="color: black;">能够</span>随时切换<span style="color: black;">是不是</span><span style="color: black;">运用</span>缓存。当缓存读开关的状态为开启时才读取缓存,<span style="color: black;">一样</span>当写缓存开关状态为开启时才写入到缓存。<span style="color: black;">这儿</span>的实现很简单,留给读者<span style="color: black;">做为</span>课后作业,有兴趣的<span style="color: black;">朋友</span><span style="color: black;">能够</span>尝试一下。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">做为</span>本节小结,<span style="color: black;">咱们</span><span style="color: black;">经过</span>一个表格来汇总此次新的数据管理方式,与传统做法的差异有<span style="color: black;">那些</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">表6-1 传统数据管理与新数据管理方式的对比</p>
<div style="color: black; text-align: left; margin-bottom: 10px;">
<div style="color: black; text-align: left; margin-bottom: 10px;">
<div style="color: black; text-align: left; margin-bottom: 10px;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">归类</span>与要点</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">传统数据管理</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">新的数据管理方式</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">面向运营的预览</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">手动支持,需要手动切换<span style="color: black;">是不是</span><span style="color: black;">运用</span>缓存</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">统一自动支持切换</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">面向运营的强制刷新</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">一般</span>不支持或手动支持</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">支持,页面<span style="color: black;">拜访</span>时可<span style="color: black;">运用</span>强刷模式</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">业务路径触达</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">只能靠人工经验判断业务路径</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">可视化,<span style="color: black;">经过</span>专业术语标识能精确描述业务场景</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">数据规划中的缓存策略</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">不<span style="color: black;">知道</span>、不清晰</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">有序,按稳定-<span style="color: black;">拜访</span>象限清晰,并且可视化</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">数据规划中的缓存时间</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">各自指定,较为凌乱</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">统一规划,支持自定义</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">用于故障排查的页面<span style="color: black;">跟踪</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">不支持</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">支持,更可视化</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">用于故障排查的穿透查看</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">不支持</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">支持,<span style="color: black;">能够</span>清楚<span style="color: black;">晓得</span>数据从哪里来</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在线调试</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">不支持</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">支持</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">用于后台作业的计划任务生成</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">难以支持</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">支持,可快速模拟数据获取,以触发<span style="color: black;">有效</span>缓存填充</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">快速<span style="color: black;">研发</span>与效率的<span style="color: black;">提高</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">拷贝-粘贴式重复<span style="color: black;">研发</span>,容易出错</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">模板支持,便于快速<span style="color: black;">研发</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">研发</span>规范与标准化</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">缺乏标准</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">有利于形成企业级架构设计,<span style="color: black;">由于</span>形<span style="color: black;">成为了</span>统一的接口规约</p>
</div>
</div>
</div>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这套数据管理的架构,能<span style="color: black;">显著</span><span style="color: black;">加强</span>代码<span style="color: black;">研发</span>的效率,<span style="color: black;">由于</span><span style="color: black;">研发</span>人员<span style="color: black;">不消</span>再需要关注并且重复编码实现<span style="color: black;">详细</span>重复实现的缓存策略,取而代之是<span style="color: black;">选取</span>合适的数据模板<span style="color: black;">就可</span>,相当于让程序员做<span style="color: black;">选取</span>题而不是简答题,<span style="color: black;">乃至</span><span style="color: black;">能够</span><span style="color: black;">容易</span>切换<span style="color: black;">区别</span>的缓存策略。<span style="color: black;">另一</span>一个<span style="color: black;">方向</span>,<span style="color: black;">咱们</span>对<span style="color: black;">各样</span>稳定数据、活跃数据、实时数据都有了更为清晰的划分,<span style="color: black;">因此呢</span><span style="color: black;">亦</span>就大大降低了对业务数据<span style="color: black;">守护</span>的成本,并且使得原来混乱的业务数据变得更有序可循。<span style="color: black;">另外</span>,<span style="color: black;">全世界</span><span style="color: black;">跟踪</span>器为测试、<span style="color: black;">研发</span>人员<span style="color: black;">供给</span>了重要的上下文场景信息。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">能够</span>说,某种程度上,这是一种企业级的架构设计。</p>
顶楼主,说得太好了!
页:
[1]