第1页
Golang+Lua 在分类列表中 最佳实践
谢刚@JD
2016-10-18
第3页
目录
CONTENTS
1 分类列表介绍
2 分类列表架构 3 Golang应用 4 Lua(OpenResty)应用 5 前端优化
第4页
分类列表介绍
分类列表是承接京东用户访问的主要流量之一
分类列表特点
发 商品数量多,分类多 发 业务复杂,不同分类逻辑不一样 发 请求量大 发 实时性要求
第5页
列表页入口
第6页
目录
CONTENTS
1 分类列表介绍
2 分类列表架构
3 Golang应用 4 Lua(OpenResty)应用 5 前端优化
第7页
架构-搜索版架构
Nginx Nodejs Search Service
第8页
架构设计—设计目的
系统架构改造
发 分布式(数据分片、各层水平扩容) 发 高可用(双机房双活部署) 发 响应迅速 发 数据闭环(线上服务不依赖外部API接口) 发 运维便捷(通过配置中心灵活切换集群)
数据提升
发 GMV 发 转化率 发 客单价
第9页
架构设计– 新版架构
Config Center
Nginx+lua
MSG Receiver
Data Worker
Score Worker
Go Cluster1 GO
Go Cluster2
Jimdb
Hadoop
Mysql
MSG Handler
Miss Worker
第10页
架构设计– 新版拓扑
mjq Nginx+Lua
平滑切换
Cluster1
Go1
Cluster2
Go2
Jimdb
Jimdb
Hadoop—Offline
数据模型
排序算法 机器学习
Users CDN LVS+Haproxy
MQ MSG
lf Nginx+Lua
平滑切换
Cluster1
Go1
Cluster2
Go2
Jimdb
Jimdb
MYSQL
Data Worker
第11页
数据处理流程
Hadoop
1 MYSQL 2 3
Go(Offline) 44
Go(Online)
Data Worker
MQ MSG
第12页
Date Worker
Score Worker
Sku_Log
Sku
Virt_sku
Large_Sku
API SkuDetail Stock Price Tag FBP
http http
http JSF JSF
Data Worker
SKU
第13页
目录
CONTENTS
1 分类列表介绍 2 分类列表架构
3 Golang应用
4 Lua(OpenResty)应用 5 前端优化
第14页
选择Golang
特性
发 Golang并发能力 发 Golang性能
开源
发 Beego 发 Ffjson 发 redigo
第15页
商品筛选
第16页
主要功能
Loading Data Query Data Update Data
第17页
数据加载
Go Service1
index
Go Service2
index
MYSQL
Jimdb
…
index
Go ServiceN
index
第18页
内存数据
Sku 索引数据
字典数据
分类数据 分类字典数据 分类扩展属性 分类自定义属性
Brand
Publish
Large limit
质销价 上
量 分 排 序
量 排 序
格 排 序
架 时 间
数数数 数
组组组 组
第19页
数据查询
查询 解析参数 过滤sku 聚合属性 Mget 获取数据 组装数据
返回
第20页
数据更新
优化前
MSG Receiver
优化后
MSG Receiver
MSG Handler
QUEUE
MSG Handler
第21页
Golang – 遇到的坑
一、JSON的序列化性能低下 Golang内置的encoding/json、encoding/gob,采用ffjson
二、GC问题 减少内存对象。减少对象申请,两个作用:减少内存使用,减少内存碎片
三、字符串拼接 尽量使用byte数组,不要用String,由于String会创建新对象
四、Go占用OS内存释放慢 执行:debug.freeOSMemory()
五、Goroutine闪退 goroutine闪退,导致应用进程闪退,异常捕获
六、并发处理map 必须加读写锁(sync.RWMutex)
第22页
目录
CONTENTS
1 分类列表介绍 2 分类列表架构 3 Golang应用
4 Lua(OpenResty)应用
5 前端优化
第23页
选择Lua(OpenResty)
Lua优点
1.轻量级 2.协程 3.嵌入式、可调用其他API 4.开发效率
OpenResty OpenResty将Nginx核心、LuaJIT、许多有用的Lua库和Nginx第三方模块打包在一起的web应用开 发框架 生态
ngx_lua lua-resty-redis lua-resty-memcached
lua-resty-template lua-resty-limit-traffic lua-resty-mysql
第24页
主要功能
模板渲染
缓存模块
异常处理
其他
第25页
模板渲染
使用的模板引擎 https://github.com/bungle/lua-resty-template
Nginx配置
第26页
模板渲染
第27页
缓存
FirstPage Cache1
FirstPage Cache2
...
FirstPage CacheN
Nginx+Lua
Key Cache
Jimdb
Go Service
OtherPage Cache1
OtherPage Cache2
...
OtherPage CacheN
第28页
异常处理
Nginx
location /
Lua 读取缓存
后端接口数据
模板渲染
返回html
正常流程
内部跳转
报错
location @static
读取缓存 Nginx配有置缓存 无缓存
返回html 跳转京东首页
展示缓存流程
报错
location @jd
跳转京东首页
跳转首页流程
第29页
其他模块
限流 (lua-resty-limit-traffic)
定时任务(ngx.timer.at)
防爬虫
第30页
目录
CONTENTS
1 分类列表介绍 2 分类列表架构 3 Golang应用 4 Lua(OpenResty)应用
5 前端优化
第31页
优化原则
时间
0~100ms 100~300ms 300~1000ms >1000ms >10000ms
感觉
很快 有一点点慢 机械在工作呢 先干点别的吧
不能用了
首屏优先 惰性交互 惰性执行 惰性滚屏
精简和瘦身页面,首屏优先展示出来 需用户交互的部分惰性加载 能不执行的先别执行,惰性执行 滚屏惰性加载
第32页
首屏优先
目的
尽快渲染出页面并达到可交互的状态
方法
1、只生成首屏需要的HTML数据 2、优先获取资源、提前解析 3、优先安排关键网络资源,尽早分派请求并取得页面 4、服务端渲染耗时短,性能才会好
第33页
首屏优先
第34页
惰性交互
定义 目的 方法
惰性交互,即对需用户交互的部分进行惰性加载
提升服务端性能,减少数据传输
品牌只渲染18个品牌 属性筛选只渲染5行
第35页
惰性执行
定义 能不执行的先不执行
目的 方法
页面瘦身,提升渲染时间
1.数据通过Json方式嵌入到页面 2.JS惰性执行渲染 3.减少网络请求
第36页
惰性滚屏
定义 目的 方法
鼠标滑动时加载 节省服务器带宽和压力,提升页面整体渲染时间 用户向下滚动页面时加载
1. 60个商品区域的图片 2. 猜你喜欢 3. 浏览记录 4. 页面尾部
第37页
细节优化工作
页面层
1.将一些JS/CSS资源直接嵌入页面 2.对引入的资源排定优先次序 3.应用JS缓存来存储公有属性和商品信息属性 4.AJAX接口最优调用
网络层
1.DNS预解析 2.减少HTTP重定向 3.使用CDN
把数据放到离用户地理位置更近的地方,可以显著减少每次TCP连接的网络延迟, 增大吞吐量 4.传输压缩过的内容(Gzip压缩)
减少60%~80%文件大小,建议Nginx设置为1-4
第38页
细节优化工作
5. 去掉不必要的资源
任何请求都不如没有请求快,把一些非必须、可异步、可延迟的尽量延迟请求
6. 在客户端缓存资源
对静态资源CSS/JS或变化不频繁的HTML块放到前端localstorage
7. 并行处理请求和响应
请求和响应的排队都会导致延迟,无论是客户端还是服务器端
8. 无状态域名 减少请求的HTTP首部数据 Cookie 是额外负担 如列表页依赖的价格、库存接口,采用3.cn无状态域名
9. 域名分区 浏览器同时只能打开6个连接池 如:对图片进行域名分区调用 http://img11.360buyimg.com/ http://img13.360buyimg.com/
http://img10.360buyimg.com/ http://img12.360buyimg.com/ http://img14.360buyimg.com/
第39页
细节优化工作
10. 拼合和连接 多个JavaScript 或CSS 文件组合为一个文件 多张图片组合为一个更大的复合的图片
11. 服务端写相关信息到header
第40页
Web性能监控
前端监控的两个方向
用WebKit内核模拟浏览器,定时抓取设定的页面
1.一个中心服务,多个终端服务 2.是否打开正常(请求超时、返回非200) 3.页面HTML关键元素是否丢失,页面是否出现乱码 4.验证规则
前端JS植入监控
1.白屏时间 2.首屏加载时间 3.每个AJAX异步方法调用耗时和请求状态码
第41页
Q&A