高并发的理解和使用场景-----特意区别和多线程的关系
一,高并发的理解
1.概念:就是短时间内遇到大量操作请求,导致站点服务器/db服务器资源被占满甚至严重时直接导致宕
2.影响:没有做高并发预处理的系统会给用户很差的体验感;
3.系统好坏的衡量:衡量一个系统的好坏,除了业务外,还有就是系统的吞吐量(单位时间内处理的请求数)-----QPS(每秒钟能处理的请求数)和响应时间
二,区分一下高并发和多线程的关系----曾经我也是单纯的理解高并发就是多线程,错的很离谱
1.多线程的理解:
多线程是java的特性,因为现在cpu都是多核多线程的,可以同时执行几个任务,为了提高jvm的执行效率,java提供了这种多线程的机制,以增强数据处理效率。
多线程对应的是cpu,高并发对应的是访问请求,可以用单线程处理所有访问请求,也可以用多线程同时处理访问请求。
在过去单CPU时代,单任务在一个时间点只能执行单一程序。之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程。虽然并不是真正意义上的“同一时间点”,而是多个任务或进程共享一个CPU,并交由操作系统来完成多任务间对CPU的运行切换,以使得每个任务都有机会获得一定的时间片运行。
再后来发展到多线程技术,使得在一个程序内部能拥有多个线程并行执行。一个线程的执行可以被认为是一个CPU在执行该程序。当一个程序运行在多线程下,就好像有多个CPU在同时执行该程序
2.多线程和高并发的关系
要想系统能够适应高并发状态,则需要从各个方面进行系统优化,包括,硬件、网络、系统架构、开发语言的选取、数据结构的运用、算法优化、数据库优化等…而多线程只是其中解决方法之一。
3.并发编程的几个要素
- 原子性原子,即一个不可再被分割的颗粒。在Java中原子性指的是一个或多个操作要么全部执行成功要么全部执行失败。
- 有序性程序执行的顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序)
- 可见性当多个线程访问同一个变量时,如果其中一个线程对其作了修改,其他线程能立即获取到最新的值
4.使用多线程技术编程需要注意的几个点
4.1 清楚一个线程的五个状态
4.2 理解悲观锁和乐观锁
4.3懂线程之间的协作(wait/sleep/notify等)
4.4 知道什么时候使用线程池
5.高并发的场景
一般像火车票抢票,秒杀 系统,双11或者京东618活动等这种太明显不过了,这种还是正常的业务范围,蛮好理解的,还有一种就是恶意的攻击,导致系统的某个功能近乎瘫痪,比如验证码的请求等,
假设系统的一些架构方便的并发措施都做到位了,例如,重要系统配备了好的资源(高质量服务器),同时使用集群方式提供服务,增加了redis集群配置等,最后需要处理的就是底层数据库那块了,
不然前面那么多请求都吃下来了,到了底层掉链子跟不上那也不行:
在此,个人理解为并发无非就是并发读和并发写,并发读还好,一般使用缓存就可以搞定,并发写技术就比较多了;
一般我们都知道 并发时最怕的就是对共享变量的同时访问导致脏数据的产生,所以一般会加锁:对象锁(例如:syncrinized等关键字)和 分布式锁(数据库锁,redis,zookeeper)
对象锁顾名思义就是锁住当前对象--只能用在单服务器上,对于分布式系统或者单系统分布式部署时对共享资源的访问就必须使用分布式锁了,此时对象锁没法用了
像秒杀系统可以使用缓存让还有数量时都可以看到,而在开抢后得看个人运气了(网络等原因),此时使用乐观锁(共享锁)就搞定了嘛
像银行的消费后更新银行卡余额,使用悲观锁(排斥锁)就可以
具体想搞清楚分布式锁的请看下面这个链接:https://www.cnblogs.com/toutou/archive/2018/09/24/9554974.html
6.高并发的技术解决方案
a.分布式缓存:redis、memcached等,
b.系统采用水平方向扩展,尽量使用集群来分散处理多请求。
c.应用拆分:一个工程被拆分为多个工程部署,利用dubbo解决多工程之间的通信。
d.数据库分库分表等。
e .数据库读写分离,解决大数据的查询问题。
f.还可以利用nosql ,例如mongoDB配合mysql组合使用。
g.还需要建立大数据访问情况下的服务降级以及限流机制等。
h.消息队列中间件:activeMQ等,解决大量消息的异步处理能力。
.............