通过伪装者检查负载下的区域公共服务门户

哈Ha!您也正在好奇地观看“美国荒野地带分布史诗般的故事-先行举旗示意”或什至参与其中。更确切地说,是现代版本-率先申请公共服务,以便为儿童赚钱或获得通行证以离开房屋。综观所有这些,我想分享我们团队在测试和参与准备提供“一流记录”服务的区域服务门户方面的经验。这也与哈布拉效应非常相似,我认为这与几天前联邦门户网站gosuslugi.ru发生的情况非常接近,但在区域范围内。

我们于今年1月在哈巴罗夫斯克(Khabarovsk)克服了这一挑战,最近我们参与了为在另一个地区发放狩猎许可证的类似服务的准备工作。以下是一些小经验,您将有机会从另一个角度研究为高峰期准备地区公共服务门户网站的问题。

对于初学者来说,这是一辆黑色的公共汽车的照片,他在学校全天候值班三天,其中这些台词的作者证实了三年前他在父母中的位置。至少我们的父母聚在一起。冬季在哈巴罗夫斯克观看-30度仍然是一种享受。

图片

在准备一年级最高录音的过程中,几个团队合作了,因为 其中涉及一种或另一种方式:数据中心运营商,区域门户网站信息系统的运营商和开发商,集成教育信息系统的运营商和开发商,为区域门户网站的用户提供技术支持。我们在iondv执行最后一项任务,独立监视门户的运行状况并为用户提供支持。

我们在准备工作中的角色是组织有关nginx中缓存配置的测试和建议,当然,我们还为具有建议“行为”的用户准备了说明。

对于那些不知道一年级写作问题的人
, . . , , - ( , — ), , - , , . , , , – , . .

1- , . 0:00 , 10:00 26 . , – . 10:00 , — , - .

. . 2017 . . , , . .

作为技术任务的对所需资源的服务


负载(或查询概率)的积分指标中倾向于“增量函数”(δ函数,狄拉克函数)的服务中的问题(如“写入一年级”)在图表上以峰的形式清晰可见。此刻,在短时间内通话量呈倍数增长。

δ函数和峰值查询统计

我们的经验表明,培训的主要任务不是增加资源。任务是最大程度地减少每秒的潜在请求数,将其延长一段时间,并为系统准备剩余的负载。在这种情况下,有必要发现并加速瓶颈-根据有界系统理论的原理(戈德拉特原理),这将产生最大的效果。否则,瓶颈将失败。整个系统应该从他那里工作:“鼓缓冲绳”的原理。

从物理上讲不可能在1分钟内将整个体积洒在10分钟的沙漏中-显然它们会崩溃。同样提供服务。它并不使任何人感到惊讶-当轮到MFC和丑闻来接收服务时,却让所有人感到惊讶-为什么门户网站关闭。

根据排队理论,负载处理行为有不同的模式

  • 您可以暂停用户,即 增加队列;
  • 您可以简单地拒绝为后来的那些人提供服务,例如,直到处理之前的那些人为止;
  • 您可以尝试不断提高生产力。

权宜之计介于两者之间。实际上,对于区域或州提供的资源有限的服务,不仅速度很重要,而且首先要维护社会正义,即所有人享有平等的条件。同时-如果用户没有收到他需要的东西,他将发起一个新的请求。在这种情况下,请求会雪崩地增长,形成攻击“狗堆效应(狗堆效应,缓存踩踏,命中未命中风暴)的模型-用户已经取消了请求并发起了一个新请求,而前一个请求仍在队列中进行处理。

这个过程强化了整个家庭都参与提交的事实-爸爸和妈妈同时填写申请,并且出于可靠性的考虑,经常提交几次申请。此外,通常还可以在多个选项卡和多个浏览器中使用。因此,通常预期的高峰负载是实际申请此类服务的人数的2-3倍。

司法撤退
, «», . ? «» , . . — , . « ». . .

提供服务的组织


我们根据去年提交的申请总数数据和其他地区的每分钟数据综合计算出了预期的申请人数。通常,应用程序的高峰时间为5-10分钟,这包括因为门户网站在最初的3至5分钟内几乎没有响应,而后来的用户则在1至5分钟内填写了表格(不要感到惊讶,即使在这种“紧张”的情况下,很多人仍从电话中填写表格) 。

每小时有条件的1000个应用程序的近似计算模型如下:

  • 从一开始的5到10分钟达到峰值,并且80%的申请将根据Paretto规则提交
  • 按照惯例,我们计划每分钟160个应用程序或每秒3个应用程序。

实际上,第一次提交是在1分45秒之后发生的,申请的高峰期是4分钟。

为了减少ESIA和系统上产生授权会话的负担,这些说明建议用户提前登录并延长会话寿命。实际上,一小时内授权了50%,半小时内授权了约90%。我们之前遇到过,用户在服务启动前10分钟开始登录门户-授权开始不稳定。很难说为什么。也许原因是当晚上在莫斯科,哈巴罗夫斯克进行技术工作时,我们才刚刚开始工作。

退修指导和组织安排
.

, « » . .. . , - ..

, , , . - . , , .

在00:00重新加载表单时,无法删除“增量功能”。该过程的重点是该服务在给定时间出现。但是,您可以尝试减少所有预期用户路由上的浏览器请求的数量,从而仅将必需的请求(表单,动态目录和发送应用程序)留在系统上。

Nginx设置本身是相当标准的。在这里,选择系统可以承受的限制更为重要。接他们-即当服务器预计将达到其功能极限时,开始排队请求。

好了,最重要的是,我们对所有静态路径以及(如果可能的话,其中没有会话的)动态页面强制进行了缓存(proxy_cache),并增加了nginx中“过期”数据的生存期。顺便说一句,这是缓存时的常见错误-写入保存了他人会话的缓存数据(有时甚至是静态数据),如果服务器无法分离数据类型,则输出通常是从标头中删除这些cookie。

在用户浏览器中,看起来就像从磁盘或内存下载的文件中更新页面。但是,即使用户从服务器获取它们,它们也会从nginx缓存中获取。目录本身当然会缓存在系统本身中。

图片

这将潜在请求的数量从89个减少到14个,并将容量从2.1 MB(对于1000个更新页面的用户来说,这是一个潜在的峰值4-8 Gbit / s)减少到38 Kb(我们都记得webpack,但是对于企业平台,这不是总是很容易做到)。根据段落的结果,仍然有必要不仅在系统中缓存,而且还要在nginx中缓存一些表格和动态分类器中的某些目录,这些目录和动态分类器在高峰时刻没有使用,并强制它们的生命周期。随着负载的增加,通常有必要放在主页面上,将用户路由到所需的服务,或者为该服务创建单独的资源。

为了减轻发送负担,已禁用了该儿童的草稿和自动填充数据的功能。所有用户的数据输入速度不同,这消除了完全可以提交的表单的外观,并且避免了发送应用程序的增量功能-一分钟内可以发送1000个数据。同时,维护了社会正义,尽管当然会出现抱怨。

我不会描述系统本身的优化-在负载测试期间,发现瓶颈-主要在DBMS查询中,并且对索引和查询本身进行了优化。

可能最重要的优化是简化表格。以表单实施时,对速度影响最大的是什么?

  • — , , . — 5-10 ( iPhone ) 5- 375 / (1 10 , application/x-www-form-urlencoded – 20 ), 100 625 /. 100/ — . , « ». — ? , . , ?
  • 精致的指南。通常通过使用FIAS或CLADR地址目录来增加负载。这里的问题是由于大小引起的-FIAS在数据库中占用40GB的空间,并且需要花费一些时间进行搜索。十分之一秒(但乘以1000个并发请求)将加载任何系统。如果没有特殊的准备(可能以单独的Web服务的形式和在单独的资源上),则很难承受负载-因此,他们通常使用纯文本字段作为地址。

好吧,让我们继续进行测试。

准备进行负载测试


测试是通过伪造者完成的-通过在Crominium浏览器中模拟用户操作。Yanedeks.tank和JMeter阻止了针对攻击的防护,因为它们生成许多相同类型的请求。另外,这些测试在更改系统在负载下的行为时,与实际查询的特性几乎不符。另外,服务器缓存请求,并且很难在其中重现部分过程(例如,授权)。顺便说一句,在其中一个devDV研讨会中,我们做了一个演讲,里面有关于使用伪造者进行测试的演讲,包括 加载,链接到视频

首先,我们编译了一个用户行为配置文件,并将该过程分为几个关键阶段:

  1. ESIA中的批量授权
  2. 一次性更新服务表格,
  3. 大量进料

对于每个阶段,我们都进行了单独的测试。

去年,在ESIA的授权阶段遇到了困难,但是要对其进行全面测试是困难的。该系统是外部的,可以防范攻击和禁止授权。尽管如此,仍然可以制定测试配置文件来精确测试被测系统的瓶颈-通常这是同时授权的会话数和每分钟计划的授权值,可以通过建议进行调节。
在测试中,包装对于组织多个线程很重要,我们使用“ puppeteer-cluster”。但通常处理异常和更改门户网站在负载下的行为会更加复杂-布局元素通常会弹出两次。或者,如果某些数据未按预期加载,则元素不会出现。这些都是用户将看到并重新加载页面的所有错误-这意味着他们将创建其他加载。有两种方法:在测试中实施异常处理。或修改门户。

测试本身很简单。以下是从单击服务门户上的“登录”按钮到将数据输入ESIA的片段。

await page.waitForSelector(AUTH_AVAIL,{timeout:OPT_ELEM_WAIT_TIME});
const needAuth = await page.$(ELEM_AUTH_IN);
if (!needAuth) throw (new Error(`  `));
        
await page.waitForSelector(AUTH_BUT, OPT_ELEMENT_VISIBLE);
await page.click(AUTH_BUT);
await waitNewUrl(page, 'https://esia.gosuslugi.ru/idp/rlogin?cc=bp', OPT_PAGE_WAIT_TIME);
await page.waitForSelector('#mobileOrEmail', OPT_ELEMENT_VISIBLE);
let text = await elemGetText(page, '#authnFrm > div.login-slils-box > div > div.detected > div.left > div.this-user');
if (text) 
   text = text.replace(/ -\(\)/g, '');        
if (text && text.indexOf(user) === -1) {
  await page.click('div.click-to-another > a');
  await page.waitForSelector('#authnFrm > div.login-slils-box > div >' +
                ' div.detected > div.left > div.this-user', OPT_ELEMENT_INVISIBLE);
}
await page.waitForSelector('#password', OPT_ELEMENT_VISIBLE);
await page.type('#mobileOrEmail', user);
await page.type('#password', pwd);
await page.click('#loginByPwdButton');

验证更新申请表的未决用户“正在打开记录”。重新启动测试本质上是一个步骤,但是检查返回的错误类型非常重要-网络存在问题,nginx错误,服务器错误以及表单是否符合条件。困难在于在最短的时间内生成最大数量的请求并且不属于保护限制(但是,在测试期间可以更改它,另一方面,这也是对网络和服务器基础结构设置以及WAF的检查)。

对p的这种测试需要大量资源才能工作。实际上,事实证明,相对于前端子系统的第1个核心和一个非常宽的通道,您至少需要2个核心。但是,在云中租用它们时-这是相当实惠的。我们使用了Yandex.cloud。

在测试中,首先在ESIA中为每个流分别实现授权。之后,为每个线程启动一个单独的浏览器,并在一个实例的框架内执行给定数量的更新。之后,实例将重新启动。支票本身可以包括典型路径,例如主页,服务形式。但是更多的情况是,仅完全更新服务并检查可以提交服务的必要目录就足够了,所有操作均在用户说明中进行。

图片

测试的一个片段打开主页面并刷新页面。

try {
  await page.setViewport(PUP_OPT);
  await page.goto(BASE_URL);
  await page.setCookie(...cookies[worker.id]);
  await page.goto(`${BASE_URL}/nd/lk/form/dnv.htm`);
  rdyRefresh++;
} catch (err) {
  console.error(`#       ${data}: ${err.message}`);
  getErr++;
  await page.screenshot({path: filename});
}
for (let i = 0; i < AMOUNT_REFRESH - 1; i++) {
  const filenameIter = path.join(BASE_DIR, PIC_DIR, `${data}-${i}.png`);
   try {
       await page.reload({waitUntil: ["networkidle0", "domcontentloaded"]});
        rdyRefresh++;
    } catch (err) {
        if (!err.message.includes('Navigation failed because browser')) {
           console.error(`#     ${data}-${i}: ${err.message}`);
           getErr++;
           await page.screenshot({path: filenameIter});
        }
   }
}

对于通过发送应用程序进行加载的过程,整个验证周期得以实现-重新加载表格并验证所有数据的输入。

分段。

for (let i = 0; i < AMOUNT_RESEND; i++) {
   const filename = path.join(BASE_DIR, PIC_DIR, `${data}-${i}.png`);
  try {
     await page.goto('https://uslugi27.ru/nd/lk/form/dnv.htm');
  } catch (err) {
      console.error(`#      1  ${data}-${i}: ${err.message}`);
      await page.screenshot({path: filename});
      getErr++;
      continue;
 }
 try {
     const FORM_PREF = '#createForm > div:nth-child(4) > ';
     await clickDelayed(page,`${FORM_PREF}fieldset.petgroup.ungroupped-attrs > div > div:nth-child(4) > div.col-md-9.attr-data`);
// <…>
     await page.type(`${FORM_PREF}fieldset:nth-child(2) > div > div:nth-child(1) > div.col-md-9.attr-data > input`, '');
// <…>
  } catch (err) {
      console.error(`#      ${data}-${i}: ${err.message}`);
      await page.screenshot({path: filename});
     continue;
  }
  try {
      await page.click('#createForm > div.col_100.controls > button.btn.btn-primary.pull-right.next');
      await clickDelayed(page,`#createForm > div:nth-child(5) > fieldset > div > div:nth-child(1) > div > div`);
       await page.click('#createForm > div:nth-child(5) > fieldset > div > div:nth-child(2) > div > div');
       await page.click('#createForm > div.col_100.controls > button.btn.btn-success.pull-right.submit');
  } catch (err) {
    console.error(`#     ${data}-${i}: ${err.message}`);
    await page.screenshot({path: filename});
    sendErr++;
    continue;
  }

顺便说一下,如果您不是通过await page.type构造输入来自puppeteer的所有数据,而是将这种逻辑传递给浏览器本身,则可以加快测试速度。但是,捕获错误的复杂性增加了。像这样

document.querySelector('#createForm > div:nth-child(4) > fieldset.petgroup.ungroupped-attrs > div > div:nth-child(4) > div.col-md-9.attr-data').click();
 document.querySelector('#createForm > div:nth-child(4) > fieldset:nth-child(2) > div > div:nth-child(1) > div.col-md-9.attr-data > input').value = '';

在测试期间,我们提供了数千个ESIA授权,并发送了约1.6万份申请。经过如此多的陈述后,如何恢复生产性教育信息系统-甚至不问。这是一个完全不同的故事。

这个过程的主要可见结果是,当地的媒体在一年级入学的那一天就很无聊。该服务已离开媒体区域。

同时,我们制作了一个仪表板,用于监视基于Grafana的表单的功能:应用程序数量,调用数量,Yandex指标等。但是,下一次我们将离开这个话题。

好吧,我要祝贺与提高电子形式的州和市政服务质量有关的每个人。这项无休止的准备工作没有白费-毕竟,在4月和5月,提交的申请数量大大增加了。

All Articles