服务外并发
服务并行和并发
并行(同时发生多核):一边看书,一边听歌
并发(交替进行):又在看书,又看电视(任意时刻,只能做一件事)
集群
同质的(同样的配置,运行同样的程序,对外提供同样的服务)。
节点之间数据一致的问题,存储共享,一般是找第三方。
无状态:第一次来和第二次来没关系
有状态:第一次来和第二次来不一样,会根据第一次来反馈第二次
减轻服务端压力来说:无状态好些。动态扩缩容,水平扩容。
查询。
需求:固定任务,主动触发
思想:锁,外部唤醒(任务写接口,调用)
单一服务节点集群
数据会丢。有些历史数据可以丢(比如qq换个地方登陆)
容错性差
信息共享节点集群
节点和数据是互通的。
优点:提升 计算能力。cpu内存
缺点:存储会成为瓶颈。(mysql挂了-单点故障,都挂了)
信息一致节点集群
读多写少
阿里盘古
可以同步(zk),或者异步(消息队列)
在一定时间之后,能读取到变更,根据变更时间的长短,将一致性分为几类:
强一致性,最终一致性。
合适的时间,用合适的技术,不过度设计。
系统
分布式系统
用户还没请求,自己就崩了。
要修改发布,耦合度太高,要瞻前顾后很多,而且要全量测试。
分分合合。拆应用,做集群
如果子应用不够用,扛不住并发,那么做集群。
一个业务A->B->C 共同完成一个业务,分担压力
应用有从属关系。
下订单要积分,出现一种新的业务场景,下订单,不要积分。就出现下面的微服务,独立。(订单服务,积分服务)
微服务
应用和应用之间,相互独立
保证接口不变,其他随意。
根据不同的场景,进行不同的设计。混合使用没关系
如何拆:识别系统的隔离点,系统边界
应用内并发
CAP
CAP:分布式系统的。
一致性,可用性,分区容错性(不可能同时满足,必须有所取舍和平衡,最多兼顾两者)
P:分区容错性。允许分区节点之间偶尔网络不通,出错,而不影响系统的运行(网断了,系统还能运行)
分区:在一个分布式系统中,多个节点组成的网络,网络中的节点之间是相互连通的
存在网络的八大谬误:
- 网络是可靠的。
- 没有延迟。
- 带宽无限。
- 网络安全。
- 拓扑结构不变。
- 只有一个管理员。
- 传输代价没有,为0。
- 网络是同构的。
解决分区容错:做冗余
在发送网络分区之前,先做好备份
如果不解决P的话,只能是单体应用了。所以P必须满足
C:一致性,写操作之后,以后来所有读到的数据都是新写的数据。
事务。
保证同步数据的时候,客户端不能读,也就是不可用
一致性分哪几类:
- 强一致性:立马能看到最新的数据。
- 弱一致性:能容忍部分或者全部 看不到最新的数据。
- 最终一致性:经过一段时间,能看到最新的数据。
根据数据容忍度,来设计一致性
A:可用性。每次给节点发请求,都能得到响应
高可用,多做几个plan B
保证可用性,在同步数据的时候,不要锁定,还是可读,不过会出现旧数据。
AC冲突
AP,舍弃C。舍弃强一致性,保证最终一致性。
通过最终一致性,兼顾了三个特性
要实现强一致性,牺牲吞吐量,高并发做不到
用最终一致性,提升吞吐量。
场景应用
一般不用业务做说明。
开发中间件的时候,redis,mysql,mq。
互联网中大部分场景下:A>C。
保证用户的体验
舍弃P:单点数据库。但是 考虑 数据库集群的时候,就要考虑P
舍弃A:zk
舍弃C:Eureka Nacos CoachDB
并发
- 进程
1.操作系统分配资源的基本单元
2.进程开销大,进程切换会涉及到地址空间的切换
3.进程之间资源隔离
4.操作系统可以同时执行多个进程
5.创建进程时间长 - 线程
1.任务调度和执行的最小单位
2.线程开销小
3.线程之间资源共享
4.每个进程可以执行多个线程
5.创建线程时间短 - 协程
如何使用多进程
docker,不同端口启动(开多应用)进程之间资源隔离。
如何使用多线程
计价:按时长收费+路程收费=总费用
两个线程去计价,然后相加。
异步
注册成功,发邮件
目的:
1.提升效率:io读数据,cpu去计算,io输出
2.实现异步:主线程提前释放,后面还需要一个耗时很长的任务。降低了平均响应时间。主线程执行重要的任务,不重要的靠后。发邮件,记日志,与第三方的交互。
改成异步
线程数的计算
公式1
1.线程数=cpu核数 * cpu使用率 * (1+ w / c)
cpu使用率:1s 0.8在干活 80%
双核:1s 一个核使用了0.1秒,一个核使用了0.2秒,也就是0.3/2(两个一秒)=15%
实际经验:70%,开始预警。
平均负载:top 1min,5min,15min(单位时间内的进程数)
当平均负载大于 0.7cpu核数的时候,要开始排查原因,防止系统恶化
当大于1.0核数,解决
当大于5cpu核数,问题已经很严重了
w/c:等待时间/计算时间。
2核 50% 等待时间2ms 计算时间1ms
20.5(1+2/1)=3
公式2
2.线程数=cpu核数*(1-阻塞系数)
阻塞系数=w/w+c
其实不重要
实际中,先定一个数,然后再压测。以压测为准。
预估用户量,预估并发量,看cpu,看内存,看网络,看io,能不能扛的住。
一般压高并发的接口
协程
线程中的线程。java官方并没有推出。
方法级别的并发。
Quasar。jar包。
线程停下来,压栈和出站。中间捕获
进程>线程>协程。