京东前台PC首页系统技术详解
connygpt 2024-11-06 12:08 10 浏览
京东零售系统在2018年实现前中台架构的调整与划分。中台实现基础服务组件开发,前台主要对接用户请求,通过对中台RPC数据的聚合,来满足用户多样化需求。其前台系统又分为首页系统、单品系统、搜索系统、列表系统、订单系统等等。
作为PC首页研发,本文主要讲解PC首页的技术实现。
PC首页业务逻辑从最初的模板渲染,到后来的SSI模块加载以及现在的前后端分离。开发语言也从之前的ASP、PHP逐步过渡到以LUA为主的技术框架。通过技术迭代升级,首页页面打开速度从之前的200ms缩减到30ms内,API性能从之前的500ms优化至100ms左右。
京东零售系统,每天承载着亿万网民的购物需求。PC首页又是京东商城的一级入口,所以系统必须达到以下3方面要求:页面完整性(容灾、兜底、降级);流畅的加载速度(高并发、页面加载优化、API加载优化);监控&告警。
下面将根据系统设定目标逐步讲解首页系统实现方案。
1.页面完整性
页面完整性指任何时候访问页面均需呈现正常的页面样式,不得出现天窗以及非200状态码(40x、50x等)。如下图楼层,若将单模块缺失直接呈现给用户,将导致页面天窗,影响体验。在单模块异常时,系统可对整楼层隐藏操作,优先保证页面完整显示。
下面从6方面讲解容灾降级的业务逻辑:
页面的容灾:前端页面主要承载页面骨架,也会包含部分开关配置及必要的兜底数据,即使后端API服务异常,html依然可以提供基础的用户体验。前端页面由模板渲染生成,其中模板变量通过配置中心(蜂巢系统)维护,定时worker触发生成前端页面,然后推送到静态资源服务器,最终通过CDN加速提供服务。其中在worker触发生成html阶段执行多层验证逻辑,保证html的完整性。
接口的容灾:一般接口逻辑均是优先读取缓存数据,若缓存失效则继续读取上游RPC数据来输出。但上游系统均不保证100%可用,如何保证在上游异常的情况下提供可靠服务使页面正常渲染呢?PC首页系统在接口层面做了2方面工作:
第一、接口在读取&聚合上游RPC数据后会保存两部分缓存,一个为正常用户加速缓存,一般会设置5min过期时间,一个是兜底缓存,永不过期。当缓存或者上游RPC服务均不可用时,接口会读取兜底缓存保证正常的数据输出。
第二、如果API服务由于自身问题(例如宿主机异常、Redis服务异常、用户网络抖动等)导致无法提供正常的服务怎么办。为了避免这个问题,系统为API提供了一条新的访问途径-CDN API。CDN API会访问由Worker定时生成的静态结果集(File)输出数据。当前端异步加载数据感知常规线路异常后自动触发CDN API线路来保证接口可用性。
依据上面2种兜底逻辑,绘制如下流程图,此逻辑将首页API服务的可靠率提高至100%。
接口的降级:如下图所示,正常情况接口通过读取Cache、RPC数据、兜底Cache提供服务。但如果Cache和RPC服务均异常,接口的响应时间就大大浪费在前两阶段(10ms+100ms)。为了避免此情况的发生,系统通过配置中心(蜂巢系统)设置降级开关,当系统感知降级开关打开时,将直接读取兜底Cache,保证API的响应速度。
NGINX的容灾:NGINX容灾指系统监控到接口非200状态码的时候在NGINX层面执行兜底逻辑,此兜底逻辑可以读取(或代理)远程静态资源实现透明容灾。具体实现通过error_page指令完成,error_page指令可以在特定的状态码设置一个named location,并在其代码块中执行相应的兜底业务逻辑。
楼层容灾:在多模块楼层,前端会调用多个API进行页面渲染。如下图所示,此楼层一共包含4个模块,每个模块均提供独立的API接口。当其中一个模块API异常,即触发楼层隐藏动作,避免天窗的出现。(这里执行的是页面可以有损但必须完整的策略)
终极容灾(页面CDN兜底):在2016年,启动“永不消失的首页”项目,即不论情况如何极端(包括Redis服务异常、服务器异常、RPC异常、网络异常等等),系统均可快速响应并切换至历史页面来保证页面完整。
为实现历史快照,项目借鉴爬虫技术,定时抓取PC首页的完整数据,并将快照数据推送至静态服务器。当监控到系统异常时开启降级开关将页面及时回滚至特定历史版本。此降能绕开正常的服务流程,直接读取兜底的静态资源。具体流程如下:
(此项目自上线后尚未触发一次。在其他的业务场景中,需要考虑各自实际情况)
2.流畅的加载速度
既要保证页面完整性,也要保证页面以及API的加载速度。下面从性能方面讲解系统的优化方向。
技术选型
首页是一种重性能、轻逻辑的业务场景,没有过多的基础服务依赖,主要与Redis和上游RPC做交互。系统通过读取上游RPC数据后聚合、过滤、验证后输出,最终完成页面展示。用户请求简化流程图如下:
结合业务场景,京东首页在2015年开始调研并尝试使用OpenResty服务,基于NGINX的异步事件模型以及高性能的脚本语言LUA,OpenResty完美胜任京东首页的高并发场景。经过近几年的沉淀,OpenResty成为京东首页的基础架构,也以此沉淀了OpenLua开发框架。
如上图所示,OpenResty(Nginx)服务的请求处理拥有11个阶段之多,每个阶段都有其特定的业务场景。在init_by_lua*阶段,框架初始化环境变量、init_worker_by_lua*阶段初始化降级开关以及基础配置,并将其同步至共享cache(ngx.shared.DICT)、 init_write_by_lua*阶段初始化路由策略、access_by_lua*阶段实现访问权限验证,加解密等、content_by_lua*阶段实现主体业务逻辑、log_by_lua*阶段实现日志以及Ump信息的输出。
Redis HotKey(热key)优化:在多数的业务场景中都使用Redis集群为服务加速,通过集群的横向扩展能力增加系统吞吐率。但在特殊的业务场景会有热点数据的出现,导致流量倾斜,增加单个分片的压力,这样就极大制约API的效率,极端情况甚至可以拖垮Redis集群。如何避免热点数据有2种方案:1、通过复制热点数据将数据存放到不同的Redis分片,每次通过随机算法读取;2、热点数据前置、减少Redis的压力。由于第一种方案实现繁琐,系统使用第二种方案解决热点数据,也就是将发现的热点数据存储到本地cache中(ngx.shard.DICT),通过本地cache服务直接对外提供服务,由于ngx.shard.DICT效率极高,极大优化API的响应时间。
Redis BigKey优化:项目开发中BigKey是不可忽略的性能点,可能在前期开发以及压测时均可以完美达到设定值,但是线上环境效率不理想,这时候就要考虑bigkey的因素了。由于bigkey占用内存较多,不但会使网卡成为瓶颈,在set、get也会阻塞其他操作,直接导致Redis吞吐量下降。
在PC首页系统bigkey的定义范围为>5k,只要key的值大于5k均需要单独处理。处理方案依然是2种。1、业务上做切割。例如一个业务场景需要将一个大的商品列表放到Cache中, 一般做法是通过kv(set key value)保存到Redis中。这时业务优化方案是将一个key扩展到1+n个key,一个key存储id list,其余n个key存储id对应的详情信息,这样就将bigkey打散为多个key。2、技术上做切割。例如系统定义的bigkey为5k,通过算法将value以5k的界限做切割,然后系统存储一个关系key以及n个小key实现bigkey转小key的过程。
不管使用哪个方案,目标是一致的,避免bigkey的出现。在将bigkey转小key的过程中,合理使用管道技术减少redis的网路消耗。
分布式任务的使用:随着个性化推荐算法的推广,商城首页全面接入推荐算法。由于个性化算法基于实时计算,耗时较高,为了保证用户浏览的流畅度,系统引入分布式服务。如下图所示,用户在请求第一屏的时候将用户信息push到分布式任务系统,分布式任务利用时间差计算下面楼层的个性化数据并存储到Redis。当用户访问到特定楼层即可快速加载数据。
并发请求:每个API都会涉及多个上游RPC服务,为了避免串行请求带来的耗时累加,系统将每个上游RPC封装成单个子API服务,然后通过ngx.location.capture_multi命令实现并发请求来优化API耗时。
磁盘IO优化:为了减少磁盘io,系统日志模块使用批量写入策略来减少磁盘io的消耗。在OpenResty中每个请求(包含自请求)都会初始化一个 ngx.ctx全局表,首页应用将当前请求在不同阶段产生的日志内容统一写入ngx.ctx.Log表中,并在log_by_lua*阶段统一触发io操作将日志写入文件系统。
图片优化:电商系统页面会引入大量的图片,虽然图片系统引入CDN服务,但单个域在高并发的时候依然会有堵塞。为了解决单域问题,我们将图片部署到多个域上,例如img10.360buyimg.com、img11.360buyimg.com、img12.360buyimg.com等等。但多域会叠加DNS解析耗时,此时页面可以引入预解析指令(dns-prefetch)来减少dns的解析时间,提高图片加载速度。另外使用懒加载也是优化的一个技巧。
3.监控&报警
原有的报警信息通过 “系统日志->研发->产品->运营”的方式层层传递,不但处理问题时效长,而且占用研发资源。为了简化报警流程,现有系统直接将报警信息同步给产品&运营,减少信息流通环节,提高效率。
增加报警逻辑的同时不影响系统性能,系统通过异步非阻塞的ngx.socket.tcp组件实现消息同步。具体流程为系统将日志通过ngx.socket.tcp组件传递给分布式任务,分布式任务通过异步方式将日志同步到Elastic集群。报警系统根据报警规则触发报警信息发送。(注:使用ngx.socket.tcp组件请合理使用连接池,避免频繁建立连接)
小结
随着首页系统的迭代升级,团队沉淀了蜂巢系统平台以及OpenLua框架。蜂巢系统通过积木赋能、组件化思想搭建,可快速响应业务需求。OpenLua框架实现Lua的MVC分层结构,并融入京东内部组件,在满足API性能的同时提升开发效率。
继续前行,永不止步。在之后的的研发道路上,将继续沉淀业务需求,强化组件化、标准化思想,深耕蜂巢系统、OpenLua框架,使之更加灵活、高效、易用。
相关推荐
- 3分钟让你的项目支持AI问答模块,完全开源!
-
hello,大家好,我是徐小夕。之前和大家分享了很多可视化,零代码和前端工程化的最佳实践,今天继续分享一下最近开源的Next-Admin的最新更新。最近对这个项目做了一些优化,并集成了大家比较关注...
- 干货|程序员的副业挂,12个平台分享
-
1、D2adminD2Admin是一个完全开源免费的企业中后台产品前端集成方案,使用最新的前端技术栈,小于60kb的本地首屏js加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助...
- Github标星超200K,这10个可视化面板你知道几个
-
在Github上有很多开源免费的后台控制面板可以选择,但是哪些才是最好、最受欢迎的可视化控制面板呢?今天就和大家推荐Github上10个好看又流行的可视化面板:1.AdminLTEAdminLTE是...
- 开箱即用的炫酷中后台前端开源框架第二篇
-
#头条创作挑战赛#1、SoybeanAdmin(1)介绍:SoybeanAdmin是一个基于Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS的清新优...
- 搭建React+AntDeign的开发环境和框架
-
搭建React+AntDeign的开发环境和框架随着前端技术的不断发展,React和AntDesign已经成为越来越多Web应用程序的首选开发框架。React是一个用于构建用户界面的JavaScrip...
- 基于.NET 5实现的开源通用权限管理平台
-
??大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!??今天小编推荐一款基于.NE...
- StreamPark - 大数据流计算引擎
-
使用Docker完成StreamPark的部署??1.基于h2和docker-compose进行StreamPark部署wgethttps://raw.githubusercontent.com/a...
- 教你使用UmiJS框架开发React
-
1、什么是Umi.js?umi,中文可发音为乌米,是一个可插拔的企业级react应用框架。你可以将它简单地理解为一个专注性能的类next.js前端框架,并通过约定、自动生成和解析代码等方式来辅助...
- 简单在线流程图工具在用例设计中的运用
-
敏捷模式下,测试团队的用例逐渐简化以适应快速的发版节奏,大家很早就开始运用思维导图工具比如xmind来编写测试方法、测试点。如今不少已经不少利用开源的思维导图组件(如百度脑图...)来构建测试测试...
- 【开源分享】神奇的大数据实时平台框架,让Flink&Spark开发更简单
-
这是一个神奇的框架,让Flink|Spark开发更简单,一站式大数据实时平台!他就是StreamX!什么是StreamX大数据技术如今发展的如火如荼,已经呈现百花齐放欣欣向荣的景象,实时处理流域...
- 聊聊规则引擎的调研及实现全过程
-
摘要本期主要以规则引擎业务实现为例,陈述在陌生业务前如何进行业务深入、调研、技术选型、设计及实现全过程分析,如果你对规则引擎不感冒、也可以从中了解一些抽象实现过程。诉求从硬件采集到的数据提供的形式多种...
- 【开源推荐】Diboot 2.0.5 发布,自动化开发助理
-
一、前言Diboot2.0.5版本已于近日发布,在此次发布中,我们新增了file-starter组件,完善了iam-starter组件,对core核心进行了相关优化,让devtools也支持对IAM...
- 微软推出Copilot Actions,使用人工智能自动执行重复性任务
-
IT之家11月19日消息,微软在今天举办的Ignite大会上宣布了一系列新功能,旨在进一步提升Microsoft365Copilot的智能化水平。其中最引人注目的是Copilot...
- Electron 使用Selenium和WebDriver
-
本节我们来学习如何在Electron下使用Selenium和WebDriver。SeleniumSelenium是ThoughtWorks提供的一个强大的基于浏览器的开源自动化测试工具...
- Quick 'n Easy Web Builder 11.1.0设计和构建功能齐全的网页的工具
-
一个实用而有效的应用程序,能够让您轻松构建、创建和设计个人的HTML网站。Quick'nEasyWebBuilder是一款全面且轻巧的软件,为用户提供了一种简单的方式来创建、编辑...
- 一周热门
- 最近发表
- 标签列表
-
- kubectlsetimage (56)
- mysqlinsertoverwrite (53)
- addcolumn (54)
- helmpackage (54)
- varchar最长多少 (61)
- 类型断言 (53)
- protoc安装 (56)
- jdk20安装教程 (60)
- rpm2cpio (52)
- 控制台打印 (63)
- 401unauthorized (51)
- vuexstore (68)
- druiddatasource (60)
- 企业微信开发文档 (51)
- rendertexture (51)
- speedphp (52)
- gitcommit-am (68)
- bashecho (64)
- str_to_date函数 (58)
- yum下载包及依赖到本地 (72)
- jstree中文api文档 (59)
- mvnw文件 (58)
- rancher安装 (63)
- nginx开机自启 (53)
- .netcore教程 (53)