草庐IT

JSF预热功能在企业前台研发部的实践与探索

jingdongkeji 2023-04-11 原文

作者:京东零售 李孟东

00 导读

企业前台研发部包含了企业业务大部分的对外前台系统,其中京东VOP平台(开放平台)适合于自建内网采购商城平台的企业客户。

京东为这类客户专门开发API接口,对接到客户内网的网上商城,将产品SKU直接推送到客户内网,客户内部采购人员可以直接在内网商城进行下单采购,订单信息通过API接口传递到京东后台,由京东安排物流配送服务。VOP模式下,客户内网的数据信息京东并不抓取,从而实现内部采购架构的独立搭建及数据的保密与安全。

随着业务的不断发展过程中,VOP截至目前已经服务于上千家企业Sass商城,其API接口的高并发、高可用、高可靠也就越发的重要。尽管我们如履薄冰的进行上线来尽可能的降低对接口的波动,但是发现,当下我们整个的上线流程中无损下线是没问题(NP层冷备机器直至无流量打进来,JSF层下线JSF服务),但是(自身&服务提供方)上线的瞬时波动都会或多或少引起我们系统的一阵报警。

这对于一个"夜黑风高" 即将回家的我们多大的伤害。毕竟每一次性能或者可用率的报警都牵动着我们作为技术的心血管(牵动着客户的投诉...)。

本文将从JSF1.7.6预热的实践测试报告中,真实的讲述预热给我们平台带来的体验和帮助,供大家参考。

01 背景

应用调用情况

场景一:对外服务,部分接口发布过程中出现了大量的 5xx 超时异常,根据和客户侧研发团队的沟通,大概确定在应用启动后的时间点,会有部分接口的超时请求。

场景二:服务提供者接口发布,机器启动后,会有调用JSF超时请求。

以上两种情况都会影响到服务的稳定性,进而引起我们系统的一阵(TP99/可用率)报警,如下所示:

【补充】这里同步一下检测工具:我们如何得知上下游是否存在部署事件。见:泰山平台故障分析模块,可以智能分析出上下游故障,或历史问题排查。

详细地址:
http://taishan.jd.com/faultAnalysis

帮助文档:
https://cf.jd.com/pages/viewpage.action?pageId=491274317

通过故障分析,我们发现我们所依赖的接口系统正在处于部署状态,也就是说其上线发布影响到了我们接口的稳定性。

02 预热管理实践

问题是显而易见的,那么如何发现问题本质,并找到问题通用性,进而解决问题,推广各平台,最终达到良性循环,是我们着重需要考虑的。

解决思路:JSF1.7.6版本特性三:预热策略动态下发,提升Provider实时治理能力通过服务器其负载均衡的能力,对于上线需要预热的接口进行流量权重的调整,做到刚上线的应用按照对应所配置的规则进行小流量预热,使用方只需指定预热规则即可按照预期对刚上线的节点进行小流量预热。

当然新功能的引入,小至工具包升级,大至基础服务升级,都需要足够的测试实践和验证回归,一方面测试该功能是否符合我们的诉求,另一方面避免直接引入导致的一些未知异常。因此我们通过针对地址应用及自产自销的JSF接口进行测试实践,并形成以下报告。

机器配置

共计5台服务器 规格:4c8g

四台提供者:11.94.2.225,11.94.13.242,11.94.65.31,11.94.65.45

一台消费者:11.38.181.175

考虑到篇幅的问题,本文主要描述其中一个接口的上线情况,具体实践报告见:
https://joyspace.jd.com/page/LxPqDgcSA3GVjSYQRb73

涉及接口

HTTP接口(消费者):
https://bizapi.jd.com/api/area/getTown

JSF接口(提供者):
com.jd.ka.vop.soa.address.sdk.provider.QueryAddressOpenProvider#queryJdAreaIdList

测试流程

采用压力机,模拟调用对应接口,流量稳定后,模拟上线流程,按照50%的比例发布两台机器进行测试。

未设置预热管理

如下为流量稳定调用的UMP监控:

提供者监控

消费者监控

未设置预热发布上线

发布周期(15:40——15:44)发布机器比例50%

提供者监控

消费者监控

通过上方监控图,我们可以清晰的看出

  • 无损下线过程符合预期,并且下线过程中并没有出现任何报错。
  • 报错和性能下降期间处于服务端应用成功启动后且注册成功后。

设置预热管理(流程同未设置预热情况)

配置地址:
http://taishan.jd.com/jsf/protection/index

补充:

  • 权重和周期指的是初始权重到目标权重100,在预热周期内线性增长,流量在新节点逐渐增长的过程。(即:小流量预热)
  • 在泰山流量防护页面中新增的接口配置,必须是拥有该接口权限才可以直接进行配置。
  • 在泰山平台配置后,则直接面向所有消费者有效。当然也可以使用JSF的标签配置进行预热,就仅对自身服务器有效。
  • 预热周期最大2min

这里有个小插曲,最初我设置的权重为:预热权重:10 周期:30000ms,但是在测试结果中发现,效果并不明显,如下:

因此调整配置策略:预热权重1,周期60000ms。以此降低初始权重,增大预热周期。

设置预热发布上线

发布周期(17:36——17:40)发布机器比例50%

提供者监控

效果十分明显,如下:

03 总结

综上,性能波动影响,从直接发布的50%占比机器上看,配置预热后,其中一台影响下降了2.8——15倍左右;另一台机器上线性能波动几乎可以忽略(16ms)。(测试接口本身性能queryJdAreaIdList TP99 11ms左右)

故,经过评估:provider冷启动后的瞬时TP耗时高,调用波动大进而导致请求有损的问题,可以通过自动预热机制解决。

当然,根据目前行业的一些解决方案,无损上线功能远不止于此,期待JSF预热功能的能力与场景不断地大家的实践反馈中逐渐完善与丰富。

有关JSF预热功能在企业前台研发部的实践与探索的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  3. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

  4. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  5. ruby-on-rails - Rails 中同一个类的多个关联的最佳实践? - 2

    我认为我的问题最好用一个例子来描述。假设我有一个名为“Thing”的简单模型,它有一些简单数据类型的属性。像...Thing-foo:string-goo:string-bar:int这并不难。数据库表将包含具有这三个属性的三列,我可以使用@thing.foo或@thing.bar之类的东西访问它们。但我要解决的问题是当“foo”或“goo”不再包含在简单数据类型中时会发生什么?假设foo和goo代表相同类型的对象。也就是说,它们都是“Whazit”的实例,只是数据不同。所以现在事情可能看起来像这样......Thing-bar:int但是现在有一个新的模型叫做“Whazit”,看起来

  6. ruby-on-rails - 向 Rails 3 添加 Ruby 扩展方法的最佳实践? - 2

    我有一个要在我的Rails3项目中使用的数组扩展方法。它应该住在哪里?我有一个应用程序/类,我最初把它放在(array_extensions.rb)中,在我的config/application.rb中我加载路径:config.autoload_paths+=%W(#{Rails.root}/应用程序/类)。但是,当我转到railsconsole时,未加载扩展。是否有一个预定义的位置可以放置我的Rails3扩展方法?或者,一种预先定义的方式来添加它们?我知道Rails有自己的数组扩展方法。我应该将我的添加到active_support/core_ext/array/conversion

  7. ruby-on-rails - rails 功能测试 - 2

    在Rails自动生成的功能测试(test/functional/products_controller_test.rb)中,我看到以下代码:classProductsControllerTest我的问题是:方法调用products()在哪里/如何定义?products(:one)到底是什么意思?看代码,大概意思是“创建一个产品”,但是它是如何工作的呢?注意我是Ruby/Rails的新手,如果这些是微不足道的问题,我深表歉意。 最佳答案 如果您查看test/fixtures文件夹,您会看到一个products.yml文件。这是在您创建

  8. Ruby 最佳实践 : working with classes - 2

    参见下面的示例,我想最好使用第二种方法,但第一种也可以。哪种方法最好,使用另一种的后果是什么?classTestdefstartp"started"endtest=Test.newtest.startendclassTest2defstartp"started"endendtest2=Test2.newtest2.start 最佳答案 我肯定会说第二种变体更有意义。第一个不会导致错误,但对象实例化完全过时且毫无意义。外部变量在类的范围内不可见:var="string"classAvar=A.newendputsvar#=>strin

  9. ruby-on-rails - 功能测试 Authlogic? - 2

    在我的一些Controller中,我有一个before_filter检查用户是否登录?用于CRUD操作。application.rbdeflogged_in?unlesscurrent_userredirect_toroot_pathendendprivatedefcurrent_user_sessionreturn@current_user_sessionifdefined?(@current_user_session)@current_user_session=UserSession.findenddefcurrent_userreturn@current_userifdefine

  10. ruby - 存储外部 API 的密码 - 最佳实践 - 2

    如果我构建了一个应用程序来访问来自Gmail、Twitter和Facebook的一些数据,并且我希望用户只需输入一次他们的身份验证信息,并且在几天或几周后重置,那会怎样是在Ruby中动态执行此操作的最佳方法吗?我看到很多人只是拥有他们客户/用户凭证的配置文件,如下所示:gmail_account:username:myClientpassword:myClientsPassword这看起来a)非常不安全,b)如果我想为成千上万的用户存储此类信息,它就无法工作。推荐的方法是什么?我希望能够在这些服务之上构建一个界面,因此每次用户进行交易时都必须输入凭据是不可行的。

随机推荐