在业务量越来越大的时候,零碎访问量同时大了起来,这个时候就要思考零碎如果解决高并发的申请。
性能
性能的话分为两个,一个是利用,一个是数据库。单个利用的性能晋升下来了,那集群的整体性能晋升作用会更大。
利用就是咱们的代码优化,比方算法的优化,代码的设计形式,jvm 的优化。
数据库就是 sql 的优化,比方表构造怎么建,索引怎么建,sql 语句怎么写等方面。
这些标准能够参考阿里巴巴 Java 开发手册
拆分
架构演进之路和数据库演进之路提到了为了进步零碎并发解决能力,对利用和数据库进行了程度拆分和垂直拆分。
应用层
对利用的拆分会有以下几个问题:
- 分布式事务:在单机利用中,咱们的订单服务和库存服务是一起的,通过数据库的 ACID 来保障事务,然而拆分后,就没方法通过数据库的 ACID 来了,所以要如何保障分布式事务?罕用的有 2PC/3PC、TCC、Saga
- 分布式锁:在分布式系统下,java 提供的各自锁曾经没方法解决这些共享资源的并发问题,所以要如何保障分布式锁呢?罕用的有数据库加锁、zookeeper 加锁、redis 加锁、etcd 加锁。
- 分布式作业调度:一个定时工作部署多份,比方 ABC,如何保障他们的定时工作不反复执行?比方罕用的有 elastic-job、xxl。
数据库
对数据库拆分会有以下几个问题:
- 读写拆散:如何保证数据的一致性。
- 分库分表:分布式下的主键是怎么生成的、分库分表后怎么跨库分页、分库分表是怎么做的?分库分表的中间件有哪些(mycat、sharding-jdbc)。
负载平衡
在高可用中,咱们提到了冗余,然而仅仅只是当 master 挂了 slave 顶上去用,那这个资源就很节约了,所以咱们就想,通过负载平衡让多个服务同时启用,既达到了高可用的目标,也用于解决高并发的申请。
但并不是多个服务一起用他就等于能够解决高并发的,比方 mysql 的主从,因为是异步更新的,所以 salve 的数据总是提早于 master 的,如果强一致性要求高的话,就不能用了。如果强一致性没什么要求的话能够用,相似的 reidis 也一样。
所以 无状态 对于高并发来说,就很重要了。当申请量一上来,咱们就做多个节点就好了。比方咱们用 nginx 做负载平衡,压力上来了,就多加几个 tomcat 退出集群就好了,只是咱们要思考到,在这种状况下,session 要如何解决?
负载平衡罕用的硬件和软件如下:
- 硬件:F5
- 软件:nginx、apache、lvs、haproxy
平衡策略(见 dubbo)如下:
- Random LoadBalance:随机,按权重设置随机概率。
- RoundRobin LoadBalance:* 轮询,按公约后的权重设置轮询比率。
- LeastActive LoadBalance:起码沉闷调用数,雷同沉闷数的随机,沉闷数指调用前后计数差。
- ConsistentHash LoadBalance:一致性 Hash,雷同参数的申请总是发到同一提供者。
缓存
缓存对于读服务来说,是抗流量的银弹。然而如何用好缓存,也是很重要的。比方咱们引入了 redis,咱们必须保障 redis 是高可用(redis – 哨兵(高可用)、redis – 集群(一))的,不然 reidis 挂了怎么办。咱们同样也要保障 redis 的高并发,要让他扛得住流量(redis – 主从(高性能))。咱们要保障 reids 挂了能够疾速复原(redis – 长久化)。引入 redis,咱们要思考数据库和 reids 的数据一致性(缓存的数据一致性)。咱们要思考到缓存雪崩了怎么办,缓存穿透了怎么办。
音讯队列
音讯队列的次要几个场景有异步、解耦、流量削峰。
跟 redis 一样,咱们同样也要保障音讯队列的高可用,比方 ActiveMQ – MasterSlave、RabbitMQ 集群、RabbitMQ 故障转移。ActiveMQ – 音讯可靠性、RabbitMQ – 发送方的可靠性、RabbitMQ – 音讯确认为了保障音讯的可靠性,发送方或者第三方中间件会反复发送音讯,咱们要保障接管方的幂等性,这个幂等性能够参考接口幂等设计。