首页 存档 技术 查看内容

京东印尼M站技术细节

2018-3-30 13:00 |来自: 互联网 741 0

摘要: 京东印尼站于2015年10月上线,伴随着业务的不断发展,背后支撑的技术也在紧密变迁。很高兴能在这里给大家分享下M站的技术细节。2016年是印尼电商很重要的一年,这一年里我们举行多次的促销活动,用户量及pv也在不断 ...

京东印尼站于2015年10月上线,伴随着业务的不断发展,背后支撑的技术也在紧密变迁。很高兴能在这里给大家分享下M站的技术细节。2016年是印尼电商很重要的一年,这一年里我们举行多次的促销活动,用户量及pv也在不断增长,促销形式多样化,每一次活动都是对技术的考验。

印尼手机用户占比较高,因此M端承载了较多的用户流量,其中大部分流量集中在首页和商详页。印尼手机用户占比较高,因此M端承载了较多的用户流量,其中大部分流量集中在首页和商详页。M网站部分的架构如下:

我将从以下几个方面进行介绍:

一、防刷限流

在秒杀或者其他非常有吸引促销活动中,除了正常用户带来的流量洪峰外,还有很多黄牛党使用非正常渠道刷取活动资格、下单等,系统的访问量不能准确预估,因此需要事先经过多轮的压力测试得出系统各个节点的最大TPS,超出的部分需要进行流量引导或者限制。

Nginx自身提供了基于令牌桶算法的限流模块,可以方便的控制令牌速率,自定义调节限流,能很好的限制请求数量,不过这种方法只能做到单机的限流,无法做到集群维度,我们系统使用了nginx lua redis实现了限流以及ip黑白名单功能,另外还使用worker定时同步redis中限流阈值及黑名单数据到nginx,以达到准实时的根据系统负载动态调整阈值的功能。

不过,由于多个内网ip对应一个外网ip,若基于ip进行限流,对于办公室等人群集中的地方的用户可能会被限流误杀,所以基于ip限流使用需要谨慎,权衡下业务和系统承载能力的关系。


二、应用层灾备方案

系统级别的容灾通常有主备及异地多活等,业务场景不同会有差异。这里我主要介绍下M站在应用层的灾备方案,如下图。M站依赖于众多的外部接口,按照接口的重要性和实效性可以对其进行等级划分,并制定相应的灾备方案。

对于不重要且可降级的接口,可将降级开关前置,下放到客户端,当出现问题或者系统性能受到严重影响时,可以直接在客户端进行业务屏蔽。

对于库存等不可降级的接口,可以设置兜底数据,让用户能进行添加购物车操作,避免商详出现大面积无库存。

对于首页首屏、类目等非实时数据,可以在本地或者分布式缓存保存一份永久镜像并设置好刷新策略,当接口出现问题时,走镜像获取。

对于限流、升级维护、重大事故等,要配置对应的友好提示页面。

监控预警是整个灾备方案中最重要的一环,一定要对所有重要业务及系统性能做好监控。


三、性能提升

在做性能提升前,需要制定有效的压测模型,单压的时候每次尽可能少地使用测试变量,混合压测比例需要根据线上真实流量分别设置比例,根据压测模型压测得到的结果,性能优化才能有的放矢。

M站主要是io密集性,我们的优化主要从以下方面进行:

首屏原则。首屏做尽可能少的事情,将首屏需要的数据通过异步的方式加载到本地内存,CDN回源时,直接从内存快速获取。

惰性原则。惰性加载:浏览到哪里,才在哪里加载;惰性交互:用户点击后才请求;惰性执行:比如将首页需要的数据埋在vm中返回,在浏览器通过js渲染,避免在服务端生成大量的html标签。

静态资源压缩,Nginx 开启gzip压缩能有效的减少传输字节。另外可将静态资源请求合并为一个,多张图片组合为一个更大的复合图等减少io交互次数。

请求头优化。尽量少的使用cookie,必要时可以使用不同域名避免携带无用cookie,如京东主站就使用了3.cn查询价格。另外spring mvc3.1 @ResponseBody注解默认会生成大量Accept-Charset,可优化掉。

接口调用优化。尽量批量查询,对于同时依赖多个接口时,使用异步并行的方式,这样所有请求的响应时间只取决于最慢的那个接口,能大大提高响应速度。

同机房优先策略。jsf的服务端和客户端部署在多个机房时,可利用jsf的同机房调用优先策略,提升接口响应速度。

充分利用缓存。包括浏览器、nginx、内存缓存及分布式缓存。


四、下一步规划:

虽然目前我们的系统可以支撑目前的业务活动,但还是暴露出了一些不足,下面是几个痛点:

依赖不稳定。由于依赖接口太多,当服务端端出现抖动时,在M端抖动会被放大,可对依赖数据闭环,增量更新,对于实时数据尽量走http接口直接到达依赖服务端,不过M的后台。

Tomcat瓶颈:由于Tomcat并发线程数有限,当过多的请求到达后端时,容易积压,因此,处理代码的优化外,尽量将逻辑前置,在访问层直接返回。

新的架构可设计如下:

将依赖的外部通过消息等机制通过到异构数据库,比如redis,并做好缓存失效后的回源处理,使用lua-resty-template来做页面渲染,若是单纯的数据请求,直接从redis中获取即可。 另外需要设置好兜底,当redis和接口同时出问题时展示事先准备好的静态页。

以上是我本次分享的全部内容,旨在抛砖引玉,借此能够有一个和大家交流的机会,谢谢!






本文转载于微信公众号: 京东成都研究院(jd_cdrd),更多微信文章请扫描关注公众号:

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部