[准备]
首先我们要考虑的是为什么要解决高并发, 高并发瓶颈出现在哪里, 有了解过的朋友肯定知道是在数据库, 因为在大量请求去操作数据库时会出现数据的错乱, 超卖, 系统崩溃, MySQL 死锁等现象.
[思路]
(一), 页面静态化: 就是将整个页面存储到 Redis 中, 下次访问时去读取 Redis 中的页面值
(二), 主要对整个网站的静态资源文件进行加速, 如图片, CSS,JS 等
(三), 数学验证码: 用户在计算验证码结果时可以减少大量请求同时进入, 减少 Redis, MySQL, 服务器的压力.
(四), 库存标识: 这是一个巨大优化, 通过标识来判断 Redis 的库存是否足够, 如不足就中断去读取 Redis 库存. 例: boolean over = map.get(goodsId); 当我们 map 通过 key 读取到 value 值为 true 的时候, 就返回错误提示给用户, if(over) { return Result.error('库存不足'); }..... 这样不管以后有多个请求进入都只运行两行代码, 以下的操作无法进入.
(五), 生成动态 url: 主要是防止恶意用户通过固定 url 进行提前秒杀商品 (安全方面问题这个不可掉以轻心, 你连安全措施都没做好以下的那些操作都是白搭的)
(六), Redis 预减库存: 在用户秒杀商品前去 Redis 获取当前的库存数量, 然后在秒杀时候直接减去 Redis 存储的库存 (大家放心这里 Redis 和 MySQL 数据是同步的, 只要进入 MQ 队列操作完成下单, MySQL 数据库会 - 1 数量), 从而避开去 MySQL 读取库存数据.
(七),MQ 消息队列: 它是一个中间消息键, 通过生产者发送消息给消费者, 进行业务操作, 而生产者无需知道执行结果, 也就是用户点击秒杀之后等待处理结果, 之后再去轮询查询处理结果 (异步操作), 这样就避开了不断请求去操作数据库.(这里的轮询查询也是直接从 Redis 里面去查询, 因为秒杀成功之后会将秒杀的结果放到 Redis 中, 轮询时候通过 key 去查询)
(八),Nginx: 解决高并发的好方法, 也就是我们多增加几个 tomcat 服务器. 当用户访问的时候, 请求可以提交到空闲的 tomcat 服务器上.
(九), 数据库集群, 库表散列
1大型网站都有复杂的应用, 这些应用必须使用数据库, 那么在面对大量访问的时候, 数据库的瓶颈很快就能显现出来, 这时一台数据库将很快无法满足应用, 于是我们需要使用数据库集群或者库表散列.
2在数据库集群方面, 很多数据库都有自己的解决方案, Oracle,Sybase 等都有很好的方案, 常用的 MySQL 提供的 Master/Slave 也是类似的方案, 您使用了什么样的 DB, 就参考相应的解决方案来实施即可.
3上面提到的数据库集群由于在架构, 成本, 扩张性方面都会受到所采用 DB 类型的限制, 于是我们需要从应用程序的角度来考虑改善系统架构, 库表散列是常用并且最有效的解决方案.
4我们在应用程序中安装业务和应用或者功能模块将数据库进行分离, 不同的模块对应不同的数据库或者表, 再按照一定的策略对某个页面或者功能进行更小的数据库散列, 比如用户表, 按照用户 ID 进行表散列, 这样就能够低成本的提升系统的性能并且有很好的扩展性.
(十), 负载均衡
负载均衡将是大型网站解决高负荷访问和大量并发请求采用的高端解决办法.
(十一) 反向代理
客户端直接访问的服务器并不是直接提供服务的服务器, 它从别的服务器获取资源, 然后将结果返回给用户.
代理服务器和反向代理服务器:
代理服务器是代我们访获取资源, 然后将结果返回. 例如, 访问外网的代理服务器. 反向代理服务器是我们正常访问一台服务器的时候, 服务器自己调用了别的服务器.
反向代理就是说, 用户的请求请求到负载均衡的设备上, 负载均衡设备再讲请求分发到空闲的应用服务器上处理, 处理完成之后再通过负载均衡设备返回给用户, 这样对于用户来说, 后来的分发是不可见的.
反向代理的实现
1) 需要有一个负载均衡设备来分发用户请求, 将用户请求分发到空闲的服务器上
2) 服务器返回自己的服务到负载均衡设备
3) 负载均衡将服务器的服务返回用户
代理服务器我们主动使用, 是为我们服务的, 不需要有自己的域名; 反向代理是服务器自己使用的, 我们并不知道, 有自己的域名.
来源: http://www.bubuko.com/infodetail-3094309.html