Java进阶之光!javaunicode码转字符

01 如何理解高并发?

高并发意味着大流量,需要运用技术手段抵抗流量的冲击,这些手段好比操作流量,能让流量更平稳地被系统所处理,带给用户更好的体验。

我们常见的高并发场景有:淘宝的双11、春运时的抢票、微博大V的热点新闻等。除了这些典型事情,每秒几十万请求的秒杀系统、每天千万级的订单系统、每天亿级日活的信息流系统等,都可以归为高并发。

很显然,上面谈到的高并发场景,并发量各不相同,那到底多大并发才算高并发呢?

1、不能只看数字,要看具体的业务场景。不能说10W QPS的秒杀是高并发,而1W QPS的信息流就不是高并发。信息流场景涉及复杂的推荐模型和各种人工策略,它的业务逻辑可能比秒杀场景复杂10倍不止。因此,不在同一个维度,没有任何比较意义。

2、业务都是从0到1做起来的,并发量和QPS只是参考指标,最重要的是:在业务量逐渐变成原来的10倍、100倍的过程中,你是否用到了高并发的处理方法去演进你的系统,从架构设计、编码实现、甚至产品方案等维度去预防和解决高并发引起的问题?而不是一味的升级硬件、加机器做水平扩展。

此外,各个高并发场景的业务特点完全不同:有读多写少的信息流场景、有读多写多的交易场景,那是否有通用的技术方案解决不同场景的高并发问题呢?

我觉得大的思路可以借鉴,别人的方案也可以参考,但是真正落地过程中,细节上还会有无数的坑。另外,由于软硬件环境、技术栈、以及产品逻辑都没法做到完全一致,这些都会导致同样的业务场景,就算用相同的技术方案也会面临不同的问题,这些坑还得一个个趟。

因此,这篇文章我会将重点放在基础知识、通用思路、和我曾经实践过的有效经验上,希望让你对高并发有更深的理解。

02 高并发系统设计的目标是什么?

先搞清楚高并发系统设计的目标,在此基础上再讨论设计方案和实践经验才有意义和针对性。

2.1 宏观目标

高并发绝不意味着只追求高性能,这是很多人片面的理解。从宏观角度看,高并发系统设计的目标有三个:高性能、高可用,以及高可扩展。

1、高性能:性能体现了系统的并行处理能力,在有限的硬件投入下,提高性能意味着节省成本。同时,性能也反映了用户体验,响应时间分别是100毫秒和1秒,给用户的感受是完全不同的。

2、高可用:表示系统可以正常服务的时间。一个全年不停机、无故障;另一个隔三差五出线上事故、宕机,用户肯定选择前者。另外,如果系统只能做到90%可用,也会大大拖累业务。

3、高扩展:表示系统的扩展能力,流量高峰时能否在短时间内完成扩容,更平稳地承接峰值流量,比如双11活动、明星离婚等热点事件。

这3个目标是需要通盘考虑的,因为它们互相关联、甚至也会相互影响。

比如说:考虑系统的扩展能力,你会将服务设计成无状态的,这种集群设计保证了高扩展性,其实也间接提升了系统的性能和可用性。

再比如说:为了保证可用性,通常会对服务接口进行超时设置,以防大量线程阻塞在慢请求上造成系统雪崩,那超时时间设置成多少合理呢?一般,我们会参考依赖服务的性能表现进行设置。

2.2 微观目标

再从微观角度来看,高性能、高可用和高扩展又有哪些具体的指标来衡量?为什么会选择这些指标呢?

2.2.1 性能指标

通过性能指标可以度量目前存在的性能问题,同时作为性能优化的评估依据。一般来说,会采用一段时间内的接口响应时间作为指标。

1、平均响应时间:最常用,但是缺陷很明显,对于慢请求不敏感。比如1万次请求,其中9900次是1ms,100次是100ms,则平均响应时间为1.99ms,虽然平均耗时仅增加了0.99ms,但是1%请求的响应时间已经增加了100倍。

2、TP90、TP99等分位值:将响应时间按照从小到大排序,TP90表示排在第90分位的响应时间, 分位值越大,对慢请求越敏感。

3、吞吐量:和响应时间呈反比,比如响应时间是1ms,则吞吐量为每秒1000次。

通常,设定性能目标时会兼顾吞吐量和响应时间,比如这样表述:在每秒1万次请求下,AVG控制在50ms以下,TP99控制在100ms以下。对于高并发系统,AVG和TP分位值必须同时要考虑。

另外,从用户体验角度来看,200毫秒被认为是第一个分界点,用户感觉不到延迟,1秒是第二个分界点,用户能感受到延迟,但是可以接受。

因此,对于一个健康的高并发系统,TP99应该控制在200毫秒以内,TP999或者TP9999应该控制在1秒以内。

2.2.2 可用性指标

高可用性是指系统具有较高的无故障运行能力,可用性 = 正常运行时间 / 系统总运行时间,一般使用几个9来描述系统的可用性。

对于高并发系统来说,最基本的要求是:保证3个9或者4个9。原因很简单,如果你只能做到2个9,意味着有1%的故障时间,像一些大公司每年动辄千亿以上的GMV或者收入,1%就是10亿级别的业务影响。

2.2.3 可扩展性指标

面对突发流量,不可能临时改造架构,最快的方式就是增加机器来线性提高系统的处理能力。

对于业务集群或者基础组件来说,扩展性 = 性能提升比例 / 机器增加比例,理想的扩展能力是:资源增加几倍,性能提升几倍。通常来说,扩展能力要维持在70%以上。

但是从高并发系统的整体架构角度来看,扩展的目标不仅仅是把服务设计成无状态就行了,因为当流量增加10倍,业务服务可以快速扩容10倍,但是数据库可能就成为了新的瓶颈。

像MySQL这种有状态的存储服务通常是扩展的技术难点,如果架构上没提前做好规划(垂直和水平拆分),就会涉及到大量数据的迁移。

因此,高扩展性需要考虑:服务集群、数据库、缓存和消息队列等中间件、负载均衡、带宽、依赖的第三方等,当并发达到某一个量级后,上述每个因素都可能成为扩展的瓶颈点。

03 高并发的实践方案有哪些?

了解了高并发设计的3大目标后,再系统性总结下高并发的设计方案,会从以下两部分展开:先总结下通用的设计方法,然后再围绕高性能、高可用、高扩展分别给出具体的实践方案。

3.1 通用的设计方法

通用的设计方法主要是从「纵向」和「横向」两个维度出发,俗称高并发处理的两板斧:纵向扩展和横向扩展。

3.1.1 纵向扩展(scale-up)

它的目标是提升单机的处理能力,方案又包括:

1、提升单机的硬件性能:通过增加内存、 CPU核数、存储容量、或者将磁盘 升级成SSD 等堆硬 件 的 方 式 来 提升 。

2、提升单机的软件性能:使用缓存减少IO次数,使用并发或者异步的方式增加吞吐量。

3.1.2 横向扩展(scale-out)

因为单机性能总会存在极限,所以最终还需要引入横向扩展,通过集群部署以进一步提高并发处理能力,又包括以下2个方向:

1、做好分层架构:这是横向扩展的提前,因为高并发系统往往业务复杂,通过分层处理可以简化复杂问题,更容易做到横向扩展。

上面这种图是互联网最常见的分层架构,当然真实的高并发系统架构会在此基础上进一步完善。比如会做动静分离并引入CDN,反向代理层可以是LVS+Nginx,Web层可以是统一的API网关,业务服务层可进一步按垂直业务做微服务化,存储层可以是各种异构数据库。

2、各层进行水平扩展:无状态水平扩容,有状态做分片路由。业务集群通常能设计成无状态的,而数据库和缓存往往是有状态的,因此需要设计分区键做好存储分片,当然也可以通过主从同步、读写分离的方案提升读性能。

3.2 具体的实践方案

下面再结合我的个人经验,针对高性能、高可用、高扩展3个方面,总结下可落地的实践方案。

3.2.1 高性能的实践方案

1、集群部署,通过负载均衡减轻单机压力。

2、多级缓存,包括静态数据使用CDN、本地缓存、分布式缓存等,以及对缓存场景中的热点key、缓存穿透、缓存并发、数据一致性等问题的处理。

3、分库分表和索引优化,以及借助搜索引擎解决复杂查询问题。

4、考虑NoSQL数据库的使用,比如HBase、TiDB等,但是团队必须熟悉这些组件,且有较强的运维能力。

5、异步化,将次要流程通过多线程、MQ、甚至延时任务进行异步处理。

6、限流,需要先考虑业务是否允许限流(比如秒杀场景是允许的),包括前端限流、Nginx接入层的限流、服务端的限流。

7、对流量进行 削峰填谷 ,通过 MQ承接流量。

8、并发处理,通过多线程将串行逻辑并行化。

9、预计算,比如抢红包场景,可以提前计算好红包金额缓存起来,发红包时直接使用即可。

10、 缓存预热 ,通过异步 任务 提前 预热数据到本地缓存或者分布式缓存中。

11、减少IO次数,比如数据库和缓存的批量读写、RPC的批量接口支持、或者通过冗余数据的方式干掉RPC调用。

12、减少IO时的数据包大小,包括采用轻量级的通信协议、合适的数据结构、去掉接口中的多余字段、减少缓存key的大小、压缩缓存value等。

13、程序逻辑优化,比如将大概率阻断执行流程的判断逻辑前置、For循环的计算逻辑优化,或者采用更高效的算法。

14、各种池化技术的使用和池大小的设置,包括HTTP请求池、线程池(考虑CPU密集型还是IO密集型设置核心参数)、数据库和Redis连接池等。

15、JVM优化,包括新生代和老年代的大小、GC算法的选择等,尽可能减少GC频率和耗时。

16、锁选择,读多写少的场景用乐观锁,或者考虑通过分段锁的方式减少锁冲突。

上述方案无外乎从计算和 IO 两个维度考虑所有可能的优化点,需要有配套的监控系统实时了解当前的性能表现,并支撑你进行性能瓶颈分析,然后再遵循二八原则,抓主要矛盾进行优化。

3.2.2 高可用的实践方案

1、对等节点的故障转移,Nginx和服务治理框架均支持一个节点失败后访问另一个节点。

2、非对等节点的故障转移,通过心跳检测并实施主备切换(比如redis的哨兵模式或者集群模式、MySQL的主从切换等)。

3、接口层面的超时设置、重试策略和幂等设计。

4、降级处理:保证核心服务,牺牲非核心服务,必要时进行熔断;或者核心链路出问题时,有备选链路。

5、限流处理:对超过系统处理能力的请求直接拒绝或者返回错误码。

6、MQ场景的消息可靠性保证,包括producer端的重试机制、broker侧的持久化、consumer端的ack机制等。

7、灰度发布,能支持按机器维度进行小流量部署,观察系统日志和业务指标,等运行平稳后再推全量。

8、监控报警:全方位的监控体系,包括最基础的CPU、内存、磁盘、网络的监控,以及Web服务器、JVM、数据库、各类中间件的监控和业务指标的监控。

9、灾备演练:类似当前的“混沌工程”,对系统进行一些破坏性手段,观察局部故障是否会引起可用性问题。

高可用的方案主要从冗余、取舍、系统运维3个方向考虑,同时需要有配套的值班机制和故障处理流程,当出现线上问题时,可及时跟进处理。

3.2.3 高扩展的实践方案

1、合理的分层架构:比如上面谈到的互联网最常见的分层架构,另外还能进一步按照数据访问层、业务逻辑层对微服务做更细粒度的分层(但是需要评估性能,会存在网络多一跳的情况)。

2、存储层的拆分:按照业务维度做垂直拆分、按照数据特征维度进一步做水平拆分(分库分表)。

3、业务层的拆分:最常见的是按照业务维度拆(比如电商场景的商品服务、订单服务等),也可以按照核心接口和非核心接口拆,还可以按照请求源拆(比如To C和To B,APP和H5 )。

Kafka实战笔记

关于这份笔记,为了不影响大家的阅读体验,我只能在文章中展示部分的章节内容和核心截图,如果你需要完整的pdf版本,戳这里即可免费领取。

image.png

  • Kafka入门
  • 为什么选择Kafka
  • Karka的安装、管理和配置

image.png

  • Kafka的集群
  • 第一个Kafka程序
  • image.png

afka的生产者

image.png

  • Kafka的消费者
  • 深入理解Kafka
  • 可靠的数据传递

image.png

image.png

  • Spring和Kalka的整合
  • Sprinboot和Kafka的整合
  • Kafka实战之削峰填谷
  • 数据管道和流式处理(了解即可)

image.png

  • Kafka实战之削峰填谷

image.png

7464257)]

  • Spring和Kalka的整合
  • Sprinboot和Kafka的整合
  • Kafka实战之削峰填谷
  • 数据管道和流式处理(了解即可)

[外链图片转存中…(img-omPEyuR2-1627017464257)]

  • Kafka实战之削峰填谷

[外链图片转存中…(img-7FC3lNxj-1627017464258)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/385532.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java进阶之光!java字符串类型转换为int

阿里巴巴篇 1.扎实的计算机专业基础,包括算法和数据结构,操作系统,计算机网络,计算机体系结构,数据库等2.具有扎实的Java编程基础,理解IO、多线程等基础框架3.熟练使用Linux系统的常用命令及shell有一定了…

Java进阶之光!mysql创建用户并授权建表

正文 MyBatis 的整体架构分为三层, 分别是基础支持层、核心处理层和接口层,如下图所示。 基础支持层 反射模块 该模块对 Java 原生的反射进行了良好的封装,提供了更加简洁易用的 API ,方便上层使调用,并且对反射操作…

Java进阶之光!mysql安装包安装教程

我听到的一些发声 你们赚的钱已经可以了: 我一个发小是做土木工程的,上海大学博士,参与很多著名建筑的工程,但是从薪资上看,还不如一些稍微像样的公司的6年多的高级开发。为什么?这就是行业的红利&#xf…

Java进阶学习资料!dockerjar内存

准备好套路 **①自我介绍:**千万不能筐瓢,一定要牢记,自然流畅地介绍自己的学习经历、工作经历、项目经历、个人优势等等; **②抽象概念:**当面试官问你是如何理解多线程的时候,你要知道从定义、来源、实…

管道(二)

无名管道 测试代码&#xff1a; #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <string.h>#define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0) #define TEST_SIZE 68*1024int mai…

Java进阶:java字符串定位语句

正文 模块&#xff08;Module&#xff09;、组件&#xff08;Component&#xff09;、包&#xff08;Package&#xff09;&#xff0c;这些概念对于我们技术同学并不陌生&#xff0c;但并不是所有人都能理解其要义。 深入理解之后&#xff0c;我才发现&#xff0c;其背后的深…

有名管道

一、有名管道 1. 为何提出有名管道的说法&#xff0c;目的是为了克服无名管道的不足之处&#xff1a; 无名管道只能是用于具有亲缘关系的进程之间&#xff0c;这就限制了无名管道的使用范围。有名管道可以使互不相关的两个进程互相通信&#xff0c;有名管道可以通过路径名来指…

Java进阶:mysql的事务隔离级别面试题

一面&#xff1a; 阿里巴巴面试答案文末可以领取&#xff01; 1. 触发新生代GC&#xff0c;如果存活对象总量大于survivor区容量&#xff0c;咋办 2. 如果任务很多&#xff0c;线程池的阻塞队列会撑爆内存的哪个区域 3. 栈在堆上吗 4. GC root有哪些 5. 实例变量可以是GC…

Java面试2021,java数据可视化项目

AOP简介 AOP (Aspect Oriented Programing) 称为&#xff1a;面向切面编程&#xff0c;它是一种编程思想。AOP 是 OOP&#xff08;面向对象编程 Object Oriented Programming)的思想延续 AOP采取横向抽取机制&#xff0c;取代了传统纵向继承体系重复性代码的编写方式&#xff0…

gcc的使用

一、gcc编译过程示意图 分析&#xff1a; hello程序是一个高级&#xff23;语言程序&#xff0c;这种形式容易被人读懂。为了在系统上运行hello.c程序&#xff0c;每条&#xff23;语句都必须转化为低级机器指令。然后将这些指令打包成可执行目标文件格式&#xff0c;并以二进…

Java面试2021,java黑马百度云

线程是否要锁住同步资源 锁住 悲观锁不锁住 乐观锁 锁住同步资源失败 线程是否要阻塞 阻塞不阻塞自旋锁&#xff0c;适应性自旋锁 多个线程竞争同步资源的流程细节有没有区别 不锁住资源&#xff0c;多个线程只有一个能修改资源成功&#xff0c;其它线程会重试无锁同一个线…

oppoJava面试题,java声明全局变量的关键字

蚂蚁一面 ⼀⾯就做了⼀道算法题&#xff0c;要求两⼩时内完成&#xff0c;给了⻓度为N的有重复元素的数组&#xff0c;要求输出第10⼤的数。典型的TopK问题&#xff0c;快排算法搞定。算法题要注意的是合法性校验、边界条件以及异常的处理。另外&#xff0c;如果要写测试⽤例&…

System V 消息队列

一、System V 消息队列 有一个队列&#xff0c;队列存放各种消息。每个进程可以把数据封存在消息中&#xff0c;再放入队列。每个进程都可以拿到消息队列&#xff0c;再从中取出/放入消息。 消息队列也有管道一样的不足&#xff0c;就是每个消息的最大长度是有上限的&#xf…

oppoJava面试题,java连接数据库详细步骤

美团一面&#xff08;50分钟左右&#xff09; 进程和线程死锁的必要条件网络&#xff0c;七层协议TCP和UDP的区别hashmap 详细讲一下hashmap底层是如何解决hash冲突的hashmap和linkedhashmap数据库的索引&#xff0c;为什么推荐自增id&#xff0c;有什么优点MySQL的引擎&#…

基本TCP套接字编程

1. socket函数原型&#xff1a; #include <sys/socket.h> int socket(int domain, int type, int protocol);2. bind函数原型&#xff1a; #include <sys/socket.h> int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);参数&#xff1a; ​ st…

oppoJava面试题,腾讯社招三面多久联系

梳理知识点&#xff0c;是快速提升技术的关键 前面讲过&#xff0c;快速提升自己的技术硬实力其实是有方法的。大致就是梳理知识点夯实基础进阶深入学习实战&#xff0c;下面我会一点点跟大家剖析&#xff0c;本文干货满满&#xff0c;大家仔细阅读。 ①梳理知识必备&#xff1…

oppoJava面试!传智播客java基础案例教程

零基础如何学习Java&#xff1f; 首先&#xff0c;你要明白一点&#xff0c;Java入门不难&#xff01; 无论你是从事哪个行业&#xff0c;兴趣一定是最好的老师&#xff0c;也是你学习的动力。 学习方式1&#xff1a;自学 自学模式其实我个人不建议绝大部分的人选择&#x…

Redis高级项目实战!北京java编程入门培训

Dubbo面试专题 JVM面试专题 Java并发面试专题 Kafka面试专题 MongDB面试专题 MyBatis面试专题 MySQL面试专题 Netty面试专题 RabbitMQ面试专题 Redis面试专题 Spring Cloud面试专题 SpringBoot面试专题 zookeeper面试专题 最后 给大家送一个小福利 资料都是免费分享的&#xf…

Redis高级项目实战,java配置jdk环境时

Spring Security观后感——手绘思维脑(供参考) Spring Security手绘思维脑图 手绘的思维导图&#xff0c;是我自己根据自身的情况读完这套阿里出品的Spring Security王者晋级文档之后所绘的&#xff0c;相当于是一个知识的总结与梳理&#xff0c;我将其分为***“核心组件”与“…

select函数(一)

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 参数&#xff1a; nfds&#xff1a;监控的文件描述符集里最大文件描述符加1&#xff0c;因为此参数会告诉内核检测前多少个文件文件描述符readfs&#xff1a;监控有读…