在业务量越来越大的时候,零碎访问量同时大了起来,这个时候就要思考零碎如果解决高并发的申请。
性能
性能的话分为两个,一个是利用,一个是数据库。单个利用的性能晋升下来了,那集群的整体性能晋升作用会更大。
利用就是咱们的代码优化,比方算法的优化,代码的设计形式,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 - 音讯确认为了保障音讯的可靠性,发送方或者第三方中间件会反复发送音讯,咱们要保障接管方的幂等性,这个幂等性能够参考接口幂等设计。