高并发 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的语法 ...
随机推荐
- TCP/IP协议族(一)
TCP/IP协议族(一) HTTP简介.请求方法与响应状态码 接下来想系统的回顾一下TCP/IP协议族的相关东西,当然这些东西大部分是在大学的时候学过的,但是那句话,基础的东西还是要不时的回顾回顾的. ...
- STL序列容器之vector
一,vector容器简介 1.vector容器的原理 vector是将元素置于一个动态数组中加以管理的容器. 2.vector容器的特点 vector容器可以随机存取元素,支持索引存取(即用数组下标的 ...
- 3 WCF一些基础铺垫
1首先上一张wcf通讯图 a.Proxy代理部分底层调用的是 xxxxClient=> ChannelFactory=>IInpuChannel/IOutChannel... b.Tran ...
- 使用Ocelot做网关
1首先创建一个json的配置文件,文件名随便取,我取Ocelot.json 这个配置文件有两种配置方式,第一种,手动填写 服务所在的ip和端口:第二种,用Consul进行服务发现 第一种如下: { & ...
- 如何停止处于stopping状态的windows服务(使用taskkill)
工作中有时需要启动和停止windows service,有时候会出现服务处于stopping或者starting的状态,但是,在services界面中,start service/stop servi ...
- linux下一个C语言要求CPU采用
部分 从灾难中 本来我想写一个小程序来测试CPU其他工具利用它可以检验类数据的性能.以后参考IPbench中间cpu_target_lukem插件实现我们的功能.原理非常简单:就是我们给程序设置了 ...
- 5亿英镑!Imagination同意出售给私募机构Canyon Bridge
集微网最新消息,据外媒 FT 报道,Imagination Technologies Group Plc(以下简称“Imagination”)同意由中国背景的私募基金Canyon Bridge Cap ...
- 算法 Tricks(六)—— 判断一个数是否为完全平方数
int(sqrt(n)) * int(sqrt(n)) == n ? 1:0; matlab 下判断一个数是否能开方的判断是: floor(sqrt(m))^2 == m
- Qt5该插件机制(7)--插件开发演示示例代码(Lower-level API)
插件代码 接口类的头文件 MyPluginInterface.h #ifndef INTERFACES_H #define INTERFACES_H #include <QtPlugin> ...
- SQL之Grant(分配权限)和Revoke(回收权限)
Grant Grant可以把指定的权限分配给特定的用户,如果这个用户不存在,则会创建一个用户 命令格式 grant 权限 on 数据库名.表名 to 用户名@登陆方式 identified by 'p ...