首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

Java高级面试(一)消息队列问题整合

①消息队列运用场景: 比如有一个订单系统,每次下一个订单的时候就会发送一条消息队列里面(activeMQ)然后又有一个库存系统负责获取消息队列里面的消息,最后更新库存 ②为什么使用消息队列: 解耦: 在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。消息队列在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。 冗余: 有时在处理数据的时候处理过程会失败。除非数据被持久化,否则将永远丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。在被许多消息队列所采用的"插入-获取-删除"范式中,在把一个消息从队列中删除之前,需要你的处理过程明确的指出该消息已经被处理完毕,确保你的数据被安全的保存直到你使用完毕。 扩展性: 因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的;只要另外增加处理过程即可。不需要改变代码、不需要调节参数。扩展就像调大电力按钮一样简单。 灵活性 & 峰值处理能力: 当你的应用上了Hacker News的首页,你将发现访问流量攀升到一个不同寻常的水平。在访问量剧增的情况下,你的应用仍然需要继续发挥作用,但是这样的突发流量并不常见;如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住增长的访问压力,而不是因为超出负荷的请求而完全崩溃。 可恢复性: 当体系的一部分组件失效,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。而这种允许重试或者延后处理请求的能力通常是造就一个略感不便的用户和一个沮丧透顶的用户之间的区别。 送达保证: 消息队列提供的冗余机制保证了消息能被实际的处理,只要一个进程读取了该队列即可。在此基础上,IronMQ提供了一个"只送达一次"保证。无论有多少进程在从队列中领取数据,每一个消息只能被处理一次。这之所以成为可能,是因为获取一个消息只是"预定"了这个消息,暂时把它移出了队列。除非客户端明确的表示已经处理完了这个消息,否则这个消息会被放回队列中去,在一段可配置的时间之后可再次被处理。 排序保证: 在许多情况下,数据处理的顺序都很重要。消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。IronMO保证消息浆糊通过FIFO(先进先出)的顺序来处理,因此消息在队列中的位置就是从队列中检索他们的位置。 缓冲: 在任何重要的系统中,都会有需要不同的处理时间的元素。例如,加载一张图片比应用过滤器花费更少的时间。消息队列通过一个缓冲层来帮助任务最高效率的执行--写入队列的处理会尽可能的快速,而不受从队列读的预备处理的约束。该缓冲有助于控制和优化数据流经过系统的速度。 理解数据流: 在一个分布式系统里,要得到一个关于用户操作会用多长时间及其原因的总体印象,是个巨大的挑战。消息系列通过消息被处理的频率,来方便的辅助确定那些表现不佳的处理过程或领域,这些地方的数据流都不够优化。 异步通信: 很多时候,你不想也不需要立即处理消息。消息队列提供了异步处理机制,允许你把一个消息放入队列,但并不立即处理它。你想向队列中放入多少消息就放多少,然后在你乐意的时候再去处理它们。 ③消息队列的优缺点: 优点: 1)解耦 场景:当A系统需要发送数据到BCD三个系统时。 如果使用接口调用,A系统是和BCD系统耦合在一起的,需要考虑BCD系统挂了怎么办?BCD系统消费失败怎么办?如果E系统也需要这个数据?如果B系统现在不需要这个数据? 如果使用MQ,A系统产生的数据,只要保证消息成功发送到MQ中。各个系统需要数据,自己到MQ中消费。如果新系统需要数据,直接从MQ里消费,如果老系统不需要数据了,直接取消对MQ的消费。 通过MQ,A系统和其他系统彻底解耦了。 2)异步 场景:A系统接到请求,需要在本系统写库,还需要在BCD三个系统写库。 自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。如果同步调用,最终请求总延时是 3 + 300 + 450 + 200 = 953ms。 如果使用MQ,A系统发送三个消息到三个MQ,假设耗时5ms,则A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms。 3)消峰 场景:每天 0:00 到 12:00,A 系统风平浪静,每秒并发请求数量就 50 个。结果每次一到 12:00 ~ 13:00 ,每秒并发请求数量突然会暴增到 5k+ 条。但是系统是直接基于 MySQL 的,大量的请求涌入 MySQL,每秒钟对 MySQL 执行约 5k 条 SQL。 一般的 MySQL,扛到每秒 2k 个请求就差不多了,如果每秒请求到 5k 的话,可能就直接把 MySQL 给打死了,导致系统崩溃,用户也就没法再使用系统了。 如果使用 MQ,每秒 5k 个请求写入 MQ,A 系统每秒钟最多处理 2k 个请求,因为 MySQL 每秒钟最多处理 2k 个。A 系统从 MQ 中慢慢拉取请求,每秒钟就拉取 2k 个请求,不要超过自己每秒能处理的最大请求数量就 ok,这样下来,哪怕是高峰期的时候,A 系统也绝对不会挂掉。 缺点: 1)系统可用性降低 外部依赖的系统多了,增加了消息队列系统。 2)系统复杂度提高 你怎么保证消息没有重复消费?怎么处理消息丢失的情况?怎么保证消息传递的顺序性? 3)一致性问题 数据可能不一致。 ③kafka、activemq、rabbitmq 、rocketmq优缺点: ④如何保证消息队列的高可用: RabbitMQ 的高可用性 RabbitMQ 是比较有代表性的,因为是基于主从(非分布式)做高可用性的,我们就以 RabbitMQ 为例子讲解第一种 MQ 的高可用性怎么实现。 RabbitMQ 有三种模式:单机模式、普通集群模式、镜像集群模式。 单机模式 单机模式,就是 Demo 级别的,一般就是你本地启动了玩玩儿的?,没人生产用单机模式。 普通集群模式(无高可用性) 普通集群模式,意思就是在多台机器上启动多个 RabbitMQ 实例,每个机器启动一个。你创建的 queue,只会放在一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据(元数据可以认为是 queue 的一些配置信息,通过元数据,可以找到 queue 所在实例)。你消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从 queue 所在实例上拉取数据过来。 这种方式确实很麻烦,也不怎么好,没做到所谓的分布式,就是个普通集群。因为这导致你要么消费者每次随机连接一个实例然后拉取数据,要么固定连接那个 queue 所在实例消费数据,前者有数据拉取的开销,后者导致单实例性能瓶颈。 而且如果那个放 queue 的实例宕机了,会导致接下来其他实例就无法从那个实例拉取,如果你开启了消息持久化,让 RabbitMQ 落地存储消息的话,消息不一定会丢,得等这个实例恢复了,然后才可以继续从这个 queue 拉取数据。 所以这个事儿就比较尴尬了,这就没有什么所谓的高可用性,这方案主要是提高吞吐量的,就是说让集群中多个节点来服务某个 queue 的读写操作。 镜像集群模式(高可用性) 这种模式,才是所谓的 RabbitMQ 的高可用模式。跟普通集群模式不一样的是,在镜像集群模式下,你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,就是说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像,包含 queue 的全部数据的意思。然后每次你写消息到 queue 的时候,都会自动把消息同步到多个实例的 queue 上。 那么如何开启这个镜像集群模式呢?其实很简单,RabbitMQ 有很好的管理控制台,就是在后台新增一个策略,这个策略是镜像集群模式的策略,指定的时候是可以要求数据同步到所有节点的,也可以要求同步到指定数量的节点,再次创建 queue 的时候,应用这个策略,就会自动将数据同步到其他的节点上去了。 这样的话,好处在于,你任何一个机器宕机了,没事儿,其它机器(节点)还包含了这个 queue 的完整数据,别的 consumer 都可以到其它节点上去消费数据。坏处在于,第一,这个性能开销也太大了吧,消息需要同步到所有机器上,导致网络带宽压力和消耗很重!第二,这么玩儿,不是分布式的,就没有扩展性可言了,如果某个 queue 负载很重,你加机器,新增的机器也包含了这个 queue 的所有数据,并没有办法线性扩展你的 queue。你想,如果这个 queue 的数据量很大,大到这个机器上的容量无法容纳了,此时该怎么办呢? Kafka 的高可用性: Kafka 一个最基本的架构认识:由多个 broker 组成,每个 broker 是一个节点;你创建一个 topic,这个 topic 可以划分为多个 partition,每个 partition 可以存在于不同的 broker 上,每个 partition 就放一部分数据。 这就是天然的分布式消息队列,就是说一个 topic 的数据,是分散放在多个机器上的,每个机器就放一部分数据。 实际上 RabbmitMQ 之类的,并不是分布式消息队列,它就是传统的消息队列,只不过提供了一些集群、HA(High Availability, 高可用性) 的机制而已,因为无论怎么玩儿,RabbitMQ 一个 queue 的数据都是放在一个节点里的,镜像集群下,也是每个节点都放这个 queue 的完整数据。 Kafka 0.8 以前,是没有 HA 机制的,就是任何一个 broker 宕机了,那个 broker 上的 partition 就废了,没法写也没法读,没有什么高可用性可言。 比如说,我们假设创建了一个 topic,指定其 partition 数量是 3 个,分别在三台机器上。但是,如果第二台机器宕机了,会导致这个 topic 的 1/3 的数据就丢了,因此这个是做不到高可用的。 Kafka 0.8 以后,提供了 HA 机制,就是 replica(复制品) 副本机制。每个 partition 的数据都会同步到其它机器上,形成自己的多个 replica 副本。所有 replica 会选举一个 leader 出来,那么生产和消费都跟这个 leader 打交道,然后其他 replica 就是 follower。写的时候,leader 会负责把数据同步到所有 follower 上去,读的时候就直接读 leader 上的数据即可。只能读写 leader?很简单,要是你可以随意读写每个 follower,那么就要care 数据一致性的问题,系统复杂度太高,很容易出问题。Kafka 会均匀地将一个 partition 的所有 replica 分布在不同的机器上,这样才可以提高容错性。 这么搞,就有所谓的高可用性了,因为如果某个 broker 宕机了,没事儿,那个 broker上面的 partition 在其他机器上都有副本的。如果这个宕机的 broker 上面有某个 partition 的 leader,那么此时会从 follower 中重新选举一个新的 leader 出来,大家继续读写那个新的 leader 即可。这就有所谓的高可用性了。 写数据的时候,生产者就写 leader,然后 leader 将数据落地写本地磁盘,接着其他 follower 自己主动从 leader 来 pull 数据。一旦所有 follower 同步好数据了,就会发送 ack 给 leader,leader 收到所有 follower 的 ack 之后,就会返回写成功的消息给生产者。(当然,这只是其中一种模式,还可以适当调整这个行为) 消费的时候,只会从 leader 去读,但是只有当一个消息已经被所有 follower 都同步成功返回 ack 的时候,这个消息才会被消费者读到。 看到这里,相信你大致明白了 Kafka 是如何保证高可用机制的了,对吧?不至于一无所知,现场还能给面试官画画图。要是遇上面试官确实是 Kafka 高手,深挖了问,那你只能说不好意思,太深入的你没研究过。 ⑤怎么确保消息的顺序性: 举个例子: 有一个mysql binlog 同步系统,压力是非常大的,日同步数据达到了上亿级别,就是将数据从一个 mysql 库当中原封不动的同步到另一个 mysql 库当中去(比较常见的就是大数据组需要干的事情)。 假设在 mysql 当中增删改了一条数据,对应的生产了三条 增删改的 binlog 日志,接着这三条 binlog 发送到 MQ 里面去,然后进行消费。这时候就得保证消息队列的顺序性了。不然本来是:增加、修改、删除;你愣是换了顺序给执行成删除、修改、增加,不全错了么。 再来看看顺序会错乱的俩场景: RabbitMQ:一个 queue,多个 consumer。比如,生产者向 RabbitMQ 里发送了三条数据,顺序依次是 data1/data2/data3,压入的是 RabbitMQ 的一个内存队列。有三个消费者分别从 MQ 中消费这三条数据中的一条,结果消费者2先执行完操作,把 data2 存入数据库,然后是 data1/data3。这不明显乱了。具体如下图所示: Kafka:比如说建了一个 topic,有三个 partition。生产者在写的时候,其实可以指定一个 key,比如说我们指定了某个订单 id 作为 key,那么这个订单相关的数据,一定会被分发到同一个 partition 中去,而且这个 partition 中的数据一定是有顺序的。消费者从 partition 中取出来数据的时候,也一定是有顺序的。到这里,顺序还是 ok 的,没有错乱。接着,我们在消费者里可能会搞多个线程来并发处理消息。因为如果消费者是单线程消费处理,而处理比较耗时的话,比如处理一条消息耗时几十 ms,那么 1 秒钟只能处理几十条消息,这吞吐量太低了。而多个线程并发跑的话,顺序可能就乱掉了。具体如下图: 解决方案: RabbitMQ: 拆分多个 queue,每个 queue 一个 consumer,就是多一些 queue 而已,确实是麻烦点;或者就一个 queue 但是对应一个 consumer,然后这个 consumer 内部用内存队列做排队,然后分发给底层不同的 worker 来处理。具体如下图: Kafka: 一个 topic,一个 partition,一个 consumer,内部单线程消费,单线程吞吐量太低,一般不会用这个。 写 N 个内存 queue,具有相同 key 的数据都到同一个内存 queue;然后对于 N 个线程,每个线程分别消费一个内存 queue 即可,这样就能保证顺序性。具体如下图所示:

优秀的个人博客,低调大师

sagacity-sqltoy 4.17.8 发布,Java ORM 框架

sagacity-sqltoy 4.17.8 已经发布,此版本更新内容包括: 1、支持缓存翻译未匹配模板设置为空白或空字符串: uncached-template=""(之前空白当成无效设置,依旧返回xxkey 未匹配) <translate cache="dictCache" cache-type="POST_TYPE" columns="POST_TYPE" uncached-template="" /> sqltoy-orm是比hibernate+myBatis更加贴合项目的orm框架(依赖spring),具有jpa式的对象CRUD的同时具有比myBatis(plus)更直观简洁性能强大的查询功能。 支持以下数据库: oracle 11g+ db2 9.5+,建议从10.5 开始 mysql(mariadb/innosql)支持5.6、5.7、8.0 版本 postgresql(greenplum) 支持9.5 以及以上版本 sqlserver 支持2008到2019版本,建议使用2012或以上版本 sqlite DM达梦数据库 elasticsearch 只支持查询,版本支持5.7+版本,建议使用7.3以上版本 clickhouse oceanBase guassdb tidb kingbase mongodb (只支持查询) sybase_iq 支持15.4以上版本,建议使用16版本 详情查看:https://gitee.com/sagacity/sagacity-sqltoy/releases/4.17.8

优秀的个人博客,低调大师

pacebox-springboot 2020.0.0.0 发布,java 生态框架

pacebox-springboot 融合封装已发布,旨在提供快速开发脚手架、打造更好的开源生态环境。 希望有志同道合的朋友一起维护该软件、打造一款快速应用开发级生态框架。 此版本对应spring cloud 2020.0.0版本,命名与spring cloud对应最后位为当时做的集成版 案例 inter-boot-demo boot版demo inter-micro-demo cloud版demo(nacos+sentinel体系+权限管理+elasticsearch日志+数据加解密+分布式追踪(基于opentracing)) inter-boot-generator 代码在线生成平台 inter-boot-fastdfs FastDFS权限文件管理(后续改名attachment、支持所有文件种类) inter-boot-demo 主要提供权限管理(菜单、角色、用户),elasticsearch入参出参日志,数据加解密,分布式追踪(基于opentracing), 文件存储一包集成(支持阿里云OSS,百度云BOS,腾讯COS支持、本地存储)、 短信存储一键集成(支持阿里、百度、腾讯短信云)合并接入等方式 跨域配置 1:支持cors跨域配置,只需配置pacebox.cors.enable=true一步开启跨域 BUG修复 1:修复JWT在AuthFilter中跨域问题 2:修复使用RestTemplate不支持text/plain问题 3:调整微信通用包部分错误 组件更新 1:springboot 2.3.5升级到2.4.1 2:knife4j 2.0.8升级到3.0.2 3:pacebox-core 1.0.8升级到1.0.9 4:springcloud H9升级到2020.0.0 案列参考 OSS&短信使用说明 可根据自身要求引入自己所使用的包、类似boot案例引入阿里云 然后在properties中指定采用的配置 最后在代码中进行使用 大家可根据自身的配置进行使用、对应的type对应bean-map中aliyun的key、支持多环境进行调用方式、并提交扩展拦截方式、比如短信 oss与短信基本一致、oss提供上传、下载、删除等拦截器、可自行实现、也可自行扩展自己所需的短信、OSS实现方式

优秀的个人博客,低调大师

Beetl 3.3.1.RELEASE,Java 模板引擎 Beetl

本次发布增强了HTML标签,调整了HTML标签export的含义,允许覆盖模板前面export的变量 <#html:set value="${user.name}" export="name" /> <#html:set value="${user.age}" export="name" /> ${name} 如上html:set 定义了name变量,之前版本不允许再次定义,按照使用者的建议,这次版本发布允许再次定义 <dependency> <groupId>com.ibeetl</groupId> <artifactId>beetl</artifactId> <version>3.3.1.RELEASE</version> </dependency> Beetl是一款全功能,高性能优秀的国产模板引擎,可以广泛用于动态页面生成,静态页面生成,代码生成,文本转换,脚本语言和规则引擎等,从2011年来,一直维护,并得到国内公司用户的肯定 性能测试 Benchmark (outputType) Mode Cnt Score Error Units Beetl.benchmark 1 thrpt 10 86499.426 ± 819.202 ops/s Beetl.benchmark 2 thrpt 10 53523.776 ± 365.894 ops/s Beetl.benchmark 3 thrpt 10 97586.864 ± 947.663 ops/s Freemarker.benchmark 1 thrpt 10 23655.886 ± 118.846 ops/s Freemarker.benchmark 2 thrpt 10 19697.882 ± 115.250 ops/s Handlebars.benchmark 1 thrpt 10 22828.835 ± 220.474 ops/s Handlebars.benchmark 2 thrpt 10 22885.014 ± 194.975 ops/s Rocker.benchmark 1 thrpt 10 50437.848 ± 475.690 ops/s Rocker.benchmark 2 thrpt 10 31419.460 ± 95.329 ops/s Rocker.benchmark 3 thrpt 10 88109.687 ± 645.572 ops/s Thymeleaf.benchmark 1 thrpt 10 7199.343 ± 77.446 ops/s Thymeleaf.benchmark 2 thrpt 10 5481.519 ± 44.072 ops/s Velocity.benchmark 1 thrpt 10 7928.416 ± 126.237 ops/s Velocity.benchmark 2 thrpt 10 7110.021 ± 99.296 ops/s

优秀的个人博客,低调大师

Beetl 3.3.0.RELEASE,Java 模板引擎 Beetl

引入百度小伙伴对代码风格进行的微调整。 删除核心类GroupTemplate的所有Deprecated方法,可能会导致不兼容,需要使用推荐的API <dependency> <groupId>com.ibeetl</groupId> <artifactId>beetl</artifactId> <version>3.3.0.RELEASE</version> </dependency> Beetl是一款全功能,高性能优秀的国产模板引擎,可以广泛用于动态页面生成,静态页面生成,代码生成,文本转换,脚本语言和规则引擎等,从2011年来,一直维护,并得到国内公司用户的肯定 性能测试 Benchmark (outputType) Mode Cnt Score Error Units Beetl.benchmark 1 thrpt 10 86499.426 ± 819.202 ops/s Beetl.benchmark 2 thrpt 10 53523.776 ± 365.894 ops/s Beetl.benchmark 3 thrpt 10 97586.864 ± 947.663 ops/s Freemarker.benchmark 1 thrpt 10 23655.886 ± 118.846 ops/s Freemarker.benchmark 2 thrpt 10 19697.882 ± 115.250 ops/s Handlebars.benchmark 1 thrpt 10 22828.835 ± 220.474 ops/s Handlebars.benchmark 2 thrpt 10 22885.014 ± 194.975 ops/s Rocker.benchmark 1 thrpt 10 50437.848 ± 475.690 ops/s Rocker.benchmark 2 thrpt 10 31419.460 ± 95.329 ops/s Rocker.benchmark 3 thrpt 10 88109.687 ± 645.572 ops/s Thymeleaf.benchmark 1 thrpt 10 7199.343 ± 77.446 ops/s Thymeleaf.benchmark 2 thrpt 10 5481.519 ± 44.072 ops/s Velocity.benchmark 1 thrpt 10 7928.416 ± 126.237 ops/s Velocity.benchmark 2 thrpt 10 7110.021 ± 99.296 ops/s

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册