文章目录

  • 高并发场景以及应对技巧
  • 高并发现实生活中的场景
  • 1 高并发基础
  • 1.1 并发与并行
  • 1.2 什么是高并发
  • 1.3 从服务端视角看高并发
  • 1.4 高并发带来的问题
  • 1.5 高并发问题层面
  • 2.高并发应对技巧
  • 2.1应对思路
  • 2.1.1 客户端
  • 2.1.2 服务端
  • 2.1.3 服务端处理基本原则
  • 2.2 应对手段
  • 2.2.1 客户端
  • 2.2.2 服务端(CDN、Nginx)
  • 2.2.3 服务端(Web Server)
  • 2.2.4 服务端(业务服务)
  • 2.2.5 服务端(数据库)
  • 3. 高并发场景
  • 3. 1 秒杀
  • 3. 2 秒杀设计理念与思路
  • 3. 3 秒杀应对方案
  • SpringCloud高可用架构图
  • 一、Spring Cloud是什么?
  • 二、为什么用Spring Cloud?
  • 三、Spring Cloud技术架构图(分布式系统架构)


高并发场景以及应对技巧

高并发现实生活中的场景

我们总是喜欢从软件开发层面理解高并发,其实高并发是解决大数据量业务的一种思路,源于现实生产生活中的场景。高并发现实生产生活中的场景,包括但不仅限于如下内容:战争、新冠疫情防控、医院看病、完成工作任务、工厂生产、参加庙会、乘坐公共交通等等。如何提高这些现实生产生活中高并发场景的效率、消除弊病,都是我们需要解决的问题。

1 高并发基础

1.1 并发与并行

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_微服务

Erlang之父 Joe Armstrong 用一张5岁小孩都能看懂的图解释了并发与并行的区别。

并发是两个队列交替使用一台咖啡机,并行是两个队列同时使用两台咖啡机,如果串行,一个队列使用一台咖啡机,那么哪怕前面那个人便秘了去厕所待半天,后面的人也只能等着他回来才能去接咖啡,这效率无疑是最低的。

并行(parallelism):

所谓并行,就是同时执行的意思。判断程序是否处于并行的状态,就看同一时刻是否有超过一个“工作单位”在运行。所以,单线程永远无法达到并行状态。要达到并行状态,最简单的就是利用多线程和多进程。

并发(concurrency):

并发指的是程序的“结构”。当我们说这个程序是并发的,实际上,这句话应当表述成“这个程序采用了支持并发的设计”。好,既然并发指的是人为设计的结构,那么怎样的程序结构才是支持并发的设计?正确的并发设计的标准是:使多个操作可以在重叠的时间段内进行。

1.2 什么是高并发

高并发(High Concurrency)一般是指,通过设计保证系统能够同时并行处理很多请求。评价高并发处理能力的一些指标有响应时间(Response Time)、吞吐量(Throughput)、每秒查询率QPS(Query Per Second)、并发用户数等。

响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统的响应时间。

吞吐量:单位时间内处理的请求数量。

QPS:每秒响应请求数。在互联网领域,这个指标和吞吐量区分不太明显。

并发用户数:同时承载正常使用系统功能的用户数量。例如一个即时通讯系统,同时在线量一定程度上代表了系统的并发用户数。

高并发:同时或者在极短时间内,有大量的请求到达服务器,每个请求都需要服务端耗费资源进行处理,并做出相应的反馈。

1.3 从服务端视角看高并发

服务端处理请求需要耗费服务端的资源,比如能同时开启的进程数、能同时运行的线程数、网络连接数、CPU、I/O、内存等等,由于服务端资源是有限的,那么服务端能同时处理的请求也是有限的。

高并发问题的本质就是:资源的有限性。

1.4 高并发带来的问题

高并发问题描述的是客户端请求服务端的问题,并非我们常说的Web浏览器到服务器的请求。高并发问题也不是互联网应用独有的。

客户端同时大量请求服务端,服务端的处理和响应会越来越慢,甚至会丢弃部分请求不予处理,更严重的会导致服务端崩溃。

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_服务端_02

1.5 高并发问题层面

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_Java_03


从“Web请求”层开始,到“Web应用”层,“Web应用”层可以分为“Web前端”和“Web后端”,再到“业务服务”层,最后到“数据库”层。

分层架构下的客户端、服务端解释如下:

  • “Web请求”层与“Web前端”层互为客户端、服务端;
  • “Web前端”层与“Web后端”层互为客户端、服务端;
  • “Web后端”层与“业务服务”层互为客户端、服务端;
  • “业务服务”层与“数据库”层互为客户端、服务端。

2.高并发应对技巧

2.1应对思路

2.1.1 客户端

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_Java_04


同为客户端的应对思路有:

尽量减少请求数量,比如:依靠客户端自身的缓存或处理能力,过滤非正常请求;

尽量减少对服务端资源的不必要耗费,比如:重复使用某些资源,如连接池;客户端处理的基本原则就是:能不访问服务端就不要访问。

2.1.2 服务端

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_Java_05


同为服务端的应对思路有:

增加资源供给,比如:

(1)更大的网络带宽;

(2)使用更高配置的服务器、高性能的服务器;

(3)使用高性能的数据库服务器。

请求削峰限流,比如:漏斗桶、令牌桶、计数器、消息队列。

请求分流,比如:

(1)使用集群;

(2)分布式的系统架构。

应用优化,比如:

(1)使用更高效的编程语言;

(2)优化处理业务逻辑的算法;

(3)优化访问数据库的SQL。

2.1.3 服务端处理基本原则

服务端处理基本原则是:削峰限流、分而治之,并提高单个请求的处理速度。

2.2 应对手段

后续将按照每个层面来谈谈应对的具体手段,不是高并发应对方案,方案是要结合具体的应用,综合分析,选择合适的手段组合起来的。

同时,以下提到的每个层面的应对手段都是“包含但不限于”。

2.2.1 客户端

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_Java_06

  • 尽量利用浏览器的缓存功能,减少访问服务端,比如:js、css、图片等;
  • 可以考虑利用压缩传输的功能,减少网络流量,也会提高传输速度;
  • 考虑使用异步请求,分批获取数据。

2.2.2 服务端(CDN、Nginx)

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_高并发_07

  • 使用CDN服务;
  • 动静分离,部分静态资源可以直接从Nginx返回;
  • 按请求的不同,分发到不同的后端进行处理,比如:负载均衡、业务拆分访问等;
  • 前面再加上一层来做多个Nginx的负载均衡,比如:LVS、F5、Keepalived等;
  • 对动态内容进行缓存,尽量减少访问后端服务(或采用其他中间件)。

2.2.3 服务端(Web Server)

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_spring cloud_08

  • 使用最新的JVM,并进行配置优化,Java优化;
  • 动态内容静态化;
  • 对Web后台服务器进行配置优化,比如:调整内存数量、线程数量等;
  • 对Web后台服务器进行集群,或者提供多个能提供相同服务的Web服务器,以实现负载均衡;
  • 仔细规划Web后台服务器上部署的应用规模;
  • 提供专门的图片、文件、视频等静态资源服务器。

2.2.4 服务端(业务服务)

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_微服务_09

  • 使用最新的JVM,并进行配置优化、Java优化;
  • 动态内容静态化;
  • 优化处理业务逻辑的算法;
  • 合理高效的利用缓存;
  • 优化访问数据库的Sql,可以考虑利用存储过程等数据库的能力;
  • 合理使用多线程,加快业务处理;
  • 部分业务可以考虑内存数据库,或者进行纯内存处理;
  • 尽量避免远程调用、大量I/O等耗时的操作;
  • 合理规划事务等较为耗资源的操作;
  • 合理使用异步处理;
  • 对部分业务考虑采用预处理或者预计算的方式,减少实时计算量;
  • 内部系统间的业务尽量直接调用、直接处理,减少WebService、工作流等;
  • 对业务服务器进行集群,或者提供多个能提供相同服务的业务服务器,同样借助Nginx以实现负载均衡。

2.2.5 服务端(数据库)

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_微服务_10

  • 合理选择数据库的引擎,比如MySQL的InnoDB与MyISAM引擎;
  • 进行性能配置优化;
  • 可以考虑使用存储过程来处理复杂的数据逻辑;
  • 数据库集群,进行读写分离;
  • 合理设计数据库的表结构、索引等;
  • 分库、分表,降低单库、单表的数据量;
  • 合理使用NoSql。

3. 高并发场景

以下篇幅通过分析秒杀业务场景为例,针对性地采用上面提到的一些知识,提供秒杀业务场景的应对方案,当然同样是包括并不仅限于这些内容。

3. 1 秒杀

秒杀场景一般会在电商网站举行一些活动或者节假日在12306网站上抢票时遇到。对于电商网站中一些稀缺或者特价商品,电商网站一般会在约定时间点对其进行限量销售,因为这些商品的特殊性,会吸引大量用户前来抢购,并且会在约定的时间点同时在秒杀页面进行抢购。

秒杀特点:

  • 秒杀时大量用户会在同一时间同时进行抢购,网站瞬时访问流量激增;
  • 秒杀一般是访问请求数量远远大于库存数量,只有少部分用户能够秒杀成功;
  • 秒杀业务流程比较简单,一般就是下订单减库存。
3. 2 秒杀设计理念与思路

限流: 鉴于只有少部分用户能够秒杀成功,所以要限制大部分流量,只允许少部分流量进入服务后端。

分流:负载就是问题,高并发问题。均衡就是解决手段。

削峰:对于秒杀系统瞬时会有大量用户涌入,所以在抢购一开始会有很高的瞬间峰值。高峰值流量是压垮系统很重要的原因,所以如何把瞬间的高流量变成一段时间平稳的流量也是设计秒杀系统很重要的思路。实现削峰的常用的方法有利用缓存和消息中间件等技术。(nginx的漏斗原理)

异步处理:秒杀系统是一个高并发系统,采用异步处理模式可以极大地提高系统并发量,其实异步处理就是削峰的一种实现方式。(可以把数据放入表里面,后台排队处理)

内存缓存:秒杀系统最大的瓶颈一般都是数据库读写,由于数据库读写属于磁盘IO,性能很低,如果能够把部分数据或业务逻辑转移到内存缓存,效率会有极大提升。

可拓展:当然如果我们想支持更多用户、更大的并发,最好将系统设计成弹性可拓展,如果流量来了,拓展机器就行。像淘宝、京东等,双十一活动时会增加大量机器应对交易高峰。(上云容器化,高度可扩展性)

3. 3 秒杀应对方案
  • 准备工作:
    – 系统最好独立部署;
    – 做好系统性能容量规划(一般7折计算),系统优化,容灾过载保护;
    – 做好系统拆分,比如:按功能模块、按实时/非实时、按动态/静态等等;
    – 设置定时上架的时间;
    – 服务器时钟同步;
    – 动态生成下单页面的URL。
  • Web应用层:
    – F5/LVS + Nginx来接收高并发的请求,并做负载均衡;
    – Nginx + Lua + Redis 来做请求队列,并实现一些基本控制,比如:限流、账号参加次数检查、同一IP请求数检查等;
    – Nginx、Varnish或者其他中间件来缓存静态页面和静态资源;
    – 进入Tomcat集群,先做一个预处理,就是判断这些账户是否能参与活动,比如:账号等级是否足够、账号行为是否正常、是否在黑名单上等。
  • 业务服务层:
    按照Redis的请求队列进行先后处理;
    纯内存操作 + 异步;
    控制超卖;
    Redis里面存放着SKU的库存数据;
    处理成功的信息也存放在Redis里面。
  • 其他全局考虑:
    合理设计接口;
    应当时告知用户结果;
    考虑业务规则,比如减库存的时机;
    服务器尽量集群,并做HA,避免雪崩;
    库存预热,秒杀前,通过定时任务或者运维人员提前把商品的库存加载到Redis中,让整个流程都在Redis里面;缓存服务器如果要重启,也要做预热;
    对抗作弊,比如:同一账户同时发多个请求、同一IP同时发大量请求、秒杀器采用多账户多IP发送请求等;
    服务单一原则,秒杀就是秒杀服务,商品就是商品服务,一个服务挂了,不至于把其他服务搞崩溃;
    削峰填谷MQ,你可以把它放入消息队列,然后一点点消费去改库存就好,不过单个商品其实一次修改就够了,这里说的是某个点多个商品一起秒杀的场景。

SpringCloud高可用架构图

一、Spring Cloud是什么?

spring cloud是微服务架构的一整套微服务解决方案的技术栈,是这些技术栈的框架集合,包含了服务治理、注册中心、配置中心、客户端负载均衡、网关、限流熔断、分布式链路追踪、分布式事务等技术栈,这些技术栈提供了微服务架构存在的各种问题的解决方案。

二、为什么用Spring Cloud?

  1. 单体架构的开发流程
    回想我们以前单体架构的项目,所有功能都在一个项目里面,包括前端页面和后端的各个管理模块。部署的时候直接打成一个war包,然后重启tomcat服务器。这样的单体架构优点对小项目来说,开发维护简单。但是对大型项目来说,每个模块紧密耦合,每修改一个小点的功能后重新部署导致整个系统不可用,水平扩展的时候不能针对某一个模块,要整个项目(包含各个模块)一起水平扩展,导致资源浪费。
  2. 微服务架构,以及微服务架构后出现的问题
    针对单体架构的问题,我们微服务架构针对每个模块进行了原子划分,每个模块划分为一个微服务,整个系统可以划分为很多个微服务。使用了微服务架构后系统更容易拓展,但是也增加了开发和维护的难度,出现了很多新的问题。
    1)首先,微服务多了之后,我们如何知道这些微服务的健康状态,管理这些微服务
    2)每个微服务之前如何进行远程调用其他微服务,微服务成百上千,IP地址和端口号不能单体架构一样写死调用了
    3)众多微服务,如果进行参数配置,如何快速修改配置文件?逐个配置是很麻烦的
    4)客户端如何访问我们这些众多的微服务,如果写死访问的每个微服务的IP在客户端,那么当微服务的IP和端口变化的时候也要修改客户端,而且微服务众多
    5)微服务之间相互调用,如果有一些微服务出错了或宕机了,可能导致出现雪崩,从而影响整个微服务系统,如何解决
    6)多个微服务之间的服务调用,如何保证分布式事物的数据一致性

注:我下面描述的是SpringCloud、SpringCloud Alibaba针对这些问题的解决方案

  1. 针对这些问题,Spring Cloud的解决方案
    1). 在SpringCloud里面,通过注册中心来管理微服务,每个微服务提供自己的IP和端口向注册中心注册,如果微服务关掉了,会剔除出注册中心,SpringCloud提供了Eureka、Nacos的注册中心来解决微服务治理的问题方案
    2)在微服务中实现远程服务调用,SpringCloud提供了Ribbon、Feign组件来处理的解决方案。这些远程调用向注册中心发现服务,获取相关服务的IP地址、端口的列表,然后客户端负载均衡进行调用其他服务。
    3)针对分布式配置,SpringCloud提供了Spring Cloud Config的解决方案以及使用Nacos配置中心的方案,管理每个微服务的配置
    4)外网客户端访问,都经过网关,然后网关也会从注册中心发现要访问的服务的IP列表,通过网关转发这些请求到相关内部的服务,SpringCloud提供的解决方案是Spring Cloud Gateway
    5)SpringCloud提供的Hystrix进行熔断保护以及SpringCloudAlibaba提供了Sentinel的微服务容错的解决方案
    6)SpringCloudAlibaba提供了Seata组件来保证分布式事务一致性

三、Spring Cloud技术架构图(分布式系统架构)

springcloud针对上面的问题,提供了一站式的解决方案,集成了这些方案后的系统架构是怎么样的,根据我目前遇到过的分布式系统架构,画一张大概的架构图,如下:

springcloud gateway nacos高并发如何降低cpu使用率 springcloud高并发高可用_Java_11