高并发 Nginx+Lua OpenResty系列(9)——HTTP服务
此处我说的HTTP服务主要指如访问京东网站时我们看到的热门搜索、用户登录、实时价格、实时库存、服务支持、广告语等这种非Web页面,而是在Web页面中异步加载的相关数据。这些服务有个特点即访问量巨大、逻辑比较单一;但是如实时库存逻辑其实是非常复杂的。在京东这些服务每天有几亿十几亿的访问量,比如实时库存服务曾经在没有任何IP限流、DDos防御的情况被刷到600多万/分钟的访问量,而且能轻松应对。支撑如此大的访问量就需要考虑设计良好的架构,并很容易实现水平扩展。
架构
此处介绍下Nginx+JavaEE的架构。
1. 单DB架构
早期架构可能就是Nginx直接upstream请求到后端Tomcat,扩容时基本是增加新的Tomcat实例,然后通过Nginx负载均衡upstream过去。此时数据库还不是瓶颈。当访问量到一定级别,数据库的压力就上来了,此处单纯的靠单个数据库可能扛不住了,此时可以通过数据库的读写分离或加缓存来实现。
2. DB+Cache数据库读写分离架构
此时就通过使用如数据库读写分离或者Redis这种缓存来支撑更大的访问量。使用缓存这种架构会遇到的问题诸如缓存与数据库数据不同步造成数据不一致(一般设置过期时间),或者如Redis挂了,此时会直接命中数据库导致数据库压力过大;可以考虑Redis的主从或者一致性Hash 算法做分片的Redis集群;使用缓存这种架构要求应用对数据的一致性要求不是很高;比如像下订单这种要落地的数据不适合用Redis存储,但是订单的读取可以使用缓存。
3. Nginx+Lua+Local Redis+Mysql集群架构
首先Nginx通过Lua读取本机Redis缓存,如果不命中才回源到后端Tomcat集群;后端Tomcat集群再读取Mysql数据库。Redis都是安装到和Nginx同一台服务器,Nginx直接读本机可以减少网络延时。Redis通过主从方式同步数据,Redis主从一般采用树的方式实现:
在叶子节点可以做AOF持久化,保证在主Redis挂时能进行恢复;此处假设对Redis很依赖的话,可以考虑多主Redis架构,而不是单主,来防止单主挂了时数据的不一致和击穿到后端Tomcat集群。这种架构的缺点就是要求Redis实例数据量较小,如果单机内存不足以存储这么多数据,当然也可以通过如尾号为1的在A服务器,尾号为2的在B服务器这种方式实现;缺点也很明显,运维复杂、扩展性差。
4. Nginx+Lua+ Redis集群+Mysql集群架构
和之前架构不同的点是此时我们使用一致性Hash算法实现Redis集群而不是读本机Redis,保证其中一台挂了,只有很少的数据会丢失,防止击穿到数据库。Redis集群分片可以使用Twemproxy;如果 Tomcat实例很多的话,此时就要考虑Redis和Mysql链接数问题,因为大部分Redis/Mysql客户端都是通过连接池实现,此时的链接数会成为瓶颈。一般方法是通过中间件来减少链接数。
Twemproxy与Redis之间通过单链接交互,并Twemproxy实现分片逻辑;这样我们可以水平扩展更多的Twemproxy来增加链接数。
此时的问题就是Twemproxy实例众多,应用维护配置困难;此时就需要在之上做负载均衡,比如通过LVS/HAProxy实现VIP(虚拟IP),可以做到切换对应用透明、故障自动转移;还可以通过实现内网DNS来做其负载均衡。
本文没有涉及Nginx之上是如何架构的,对于Nginx、Redis、Mysql等的负载均衡、资源的CDN化不是本文关注的点,有兴趣可以参考
很早的Taobao CDN架构
Nginx/LVS/HAProxy负载均衡软件的优缺点详解
高并发 Nginx+Lua OpenResty系列(9)——HTTP服务的更多相关文章
- 高并发 Nginx+Lua OpenResty系列(11)——流量复制/AB测试/协程
流量复制 在实际开发中经常涉及到项目的升级,而该升级不能简单的上线就完事了,需要验证该升级是否兼容老的上线,因此可能需要并行运行两个项目一段时间进行数据比对和校验,待没问题后再进行上线.这其实就需要进 ...
- 高并发 Nginx+Lua OpenResty系列(10)——商品详情页
本章以京东商品详情页为例,京东商品详情页虽然仅是单个页面,但是其数据聚合源是非常多的,除了一些实时性要求比较高的如价格.库存.服务支持等通过AJAX异步加载加载之外,其他的数据都是在后端做数据聚合然后 ...
- 高并发 Nginx+Lua OpenResty系列(3)——模块指令
Nginx Lua 模块指令 Nginx共11个处理阶段,而相应的处理阶段是可以做插入式处理,即可插拔式架构:另外指令可以在http.server.server if.location.locatio ...
- 高并发 Nginx+Lua OpenResty系列(2)——Nginx Lua API
Nginx Lua API 和一般的Web Server类似,我们需要接收请求.处理并输出响应.而对于请求我们需要获取如请求参数.请求头.Body体等信息:而对于处理就是调用相应的Lua代码即可:输出 ...
- 高并发 Nginx+Lua OpenResty系列(1)——环境搭建
OpenResty是一款基于Nginx的高性能负载均衡服务器容器,简单来说是Nginx+Lua.结合了Lua语言来对Nginx进行扩展,使得在Nginx上具有web容器功能. OpenResty运行环 ...
- 高并发 Nginx+Lua OpenResty系列(8)——Lua模版渲染
模版渲染 动态web网页开发是Web开发中一个常见的场景,比如像京东商品详情页,其页面逻辑是非常复杂的,需要使用模板技术来实现.而Lua中也有许多模板引擎,如目前京东在使用的lua-resty-tem ...
- 高并发 Nginx+Lua OpenResty系列(5)——Lua开发库Redis
Redis客户端 lua-resty-redis是为基于cosocket API的ngx_lua提供的Lua redis客户端,通过它可以完成Redis的操作.默认安装OpenResty时已经自带了该 ...
- 高并发 Nginx+Lua OpenResty系列(4)——Lua 模块开发
在实际开发中,不可能把所有代码写到一个大而全的lua文件中,需要进行分模块开发:而且模块化是高性能Lua应用的关键.使用require第一次导入模块后,所有Nginx 进程全局共享模块的数据和代码,每 ...
- 高并发 Nginx+Lua OpenResty系列(7)——Lua开发库json
JSON库 在进行数据传输时JSON格式目前应用广泛,因此从Lua对象与JSON字符串之间相互转换是一个非常常见的功能:目前Lua也有几个JSON库,如:cjson.dkjson.其中cjson的语法 ...
随机推荐
- 关于js的window.open()
window.open是javascript函数,该函数的作用是打开一个新窗口或这改变原来的窗口,不过一般用来的是打开新窗口,因为修改原来的网页地址,可以有另一个函数,那就是window.locati ...
- Linux下Qt5.6 Fcitx无法输入中文输入解决办法
Qt5.6的解决办法和之前的版本有点不同,方法如下:首先安装 fcitx-frontend-qt5.然后执行: 123 sudo cp /usr/lib/x86_64-linux-gnu/qt5/pl ...
- 使用XCA(X Certificate and key management)可视化项目经理SSL 凭证(4)--凭借自身的凭证管理中心的定义(Certificate Authority)签名证书申请
随着XCA(X Certificate and key management)可视化项目经理SSL 证书系列文章(2)和(3)中.我们学习了怎样用XCA(X Certificate and key m ...
- 使用Eclispe 查看api技巧
使用eclispe都会知道当我们把鼠标的光标放到指定发方法上时程序会弹出一个提示,大家不要无论这个提示这个提示就是源码中的说明包含了函数參数使用方法 非常多时候我们碰到一个不会的方法的时候第一步都会选 ...
- 双显卡安装Fedora 20
电脑CPU上有核芯显卡,独立显卡是Nvidia的GeForce.在安装Fedora 20 64位的时候,通常会有一个优先级.在电脑BIOS中有一个显卡的启动选项,PCIe或者IGFX,PCIe是独立显 ...
- NYOJ 24 素数的距离问题
素数的距离问题 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描写叙述 如今给出你一些数.要求你写出一个程序,输出这些整数相邻近期的素数,并输出其相距长度.假设左右有等距离长 ...
- python 教程 第七章、 数据结构
Python中有三种内建的数据结构——列表.元组和字典. 1) Lists列表 [,] 列表是序列的一种 shoplist = ['apple', 'carrot', 'banana'] pri ...
- JScript运行批处理命令的做法
作者:朱金灿 来源:http://blog.csdn.net/clever101 有时需要在JScript调用批处理命令,因为这样可以将二者的优势结合起来.今天发现调用WScript.Shell对象的 ...
- WPF 自定义的图表(适用大量数据绘制)下
原文:WPF 自定义的图表(适用大量数据绘制)下 上一篇文章中讲了WPF中自定义绘制大量数据的图标,思路是先将其绘制在内存,然后一次性加载到界面,在后续的调试过程中,发现当数据量到达10W时,移动鼠标 ...
- HDOJ 2189 悼念512四川汶川大地震遇难者——来生一起走 【生成函数】
意甲冠军:没有解释的很清楚. 策略:如果, 这是改变一个简单的生成函数. 这道题做了好久,才明确是那有毛病.还是理解的不够深刻. AC代码: #include<stdio.h> #incl ...