热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

讨伐Java多线程与高并发——MQ篇

本文是学习Java多线程与高并发知识时做的笔记。这部分内容比较多,按照内容分为5个部分:多线程基础篇JUC篇同步容器和并发容器篇线程池篇MQ篇本篇

本文是学习Java多线程与高并发知识时做的笔记。

这部分内容比较多,按照内容分为5个部分:


  1. 多线程基础篇
  2. JUC篇
  3. 同步容器和并发容器篇
  4. 线程池篇
  5. MQ篇

本篇为MQ篇。

目录

1 MQ

1.1 什么是MQ?

1.2 为什么要使用MQ?

1.2.1 传统的http请求有哪些缺点?

1.2.2 多线程异步任务处理

1.2.3 MQ异步任务处理

1.3 MQ核心概念

1.4 MQ的简单实现

1.4.1 Maven依赖

1.4.2 多线程实现本地MQ

1.5 当前的主流MQ

1.5.1 ActiveMQ

1.5.2 Kafka

1.5.3 RocketMQ

1.5.4 RabbitMQ




1 MQ


1.1 什么是MQ?

MQ,message queue,表示消息队列。通过典型的生产者和消费者模型,生产者不断地向消息队列中生产消息,消费者不断地从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,轻松地实现系统间解耦。又称为消息中间件,通过利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。


1.2 为什么要使用MQ?


1.2.1 传统的http请求有哪些缺点?

1) http请求基于request-response模型,在高并发的情况下,客户端向服务端发送大量请求,可能导致服务端请求堆积。在请求堆积过多的情况下,可能会造成服务器崩溃。


一般会在服务端入口处实现限流、整合服务以保护框架。


2) 在http请求的处理逻辑比较耗时的情况下,可能造成客户端响应超时。所以耗时的业务逻辑尽量交给多线程或者MQ处理。


1.2.2 多线程异步任务处理

某个电商平台在新用户申请注册时,客户端发送请求到服务器端,服务器会执行一系列操作:


  1. 插入会员信息,需要1s时间
  2. 发送登录短信提醒,需要3s时间
  3. 发送新人优惠券,需要3s时间

服务器端响应客户端请求一共需要7s时间,在这7s内客户端阻塞,影响到用户体验。

如果使用多线程进行异步处理:

向数据库中插入会员数据后,单独开启一个线程发送登录短信和新人优惠券。

服务器端响应客户端请求只需要1s时间。

但这么做的缺点是:单独开启线程会消耗服务器CPU资源,在处理大量请求时,服务器压力巨大。


1.2.3 MQ异步任务处理

如果使用MQ进行异步处理:

先向数据库中插入会员数据,然后向MQ投递消息,MQ服务器端将消息推送给消息的消费者后,由消费者发送登录短信和新人优惠券。【异步、解耦】

服务器端响应客户端请求只需要1s时间,而且不消耗CPU资源。

MQ如何实现抗高并发?

MQ消费者根据自身的能力情况,拉取MQ服务器端的消息进行处理。

这种 量力而行 有效地提升了消息中间件的抗高并发能力,但这么做的缺点是可能会造成消息处理延迟。【削峰】

提升MQ消费者任务处理速度的方法:


  • 搭建消费者集群提升处理速率
  • 设置消费者批量获取消息(默认情况下,消费者一次获取一条消息)

1.3 MQ核心概念

Message:消息,应用之间传送的数据,比较常用的数据格式是JSON。

Broker:MQ服务器端,提供了消息的接收、存储、拉取等功能。

Producer:生产者,投递消息到Broker。

Consumer:消费者,从Broker获取消息,处理业务逻辑。

Topic:主题,Broker收到某个主题的消息后,会把消息推送给订阅了该主题的消费者。


JSON(Javascript Object Notation),JS对象简谱。是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

示例:(在线json格式化校验:https://www.bejson.com/)

{"group1": [{"name": "LiMing","gender": "male","age": "9"}, {"name": "Janny","gender": "female","age": "8","nationality": "Canada"}, {"name": "Danny","gender": "male","age": "10","species": "dinosaur"}],"group2": [{"name": "Kangkang","gender": "male","age": "14"}, {"name": "Michael","gender": "male","age": "14","nationality": "America"}, {"name": "Jane","gender": "female","age": "14","nationality": "Australia"}, {"name": "Maria","gender": "female","age": "15","nationality": "Cuba"}],"group3": {"name": "LiHua","gender": "female","age": "18","remarks": "eternalGod"}
}


1.4 MQ的简单实现


1.4.1 Maven依赖

com.alibabafastjson1.2.62

1.4.2 多线程实现本地MQ

思路:

创建一个阻塞队列作为Broker;创建两个线程,一个作为Producer,另一个作为Consumer。

Producer向Broker发送消息,再由Consumer消费该消息。

代码演示:

import com.alibaba.fastjson.JSONObject;import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;public class MyMQ {/*** Broker*/private static LinkedBlockingQueue broker &#61; new LinkedBlockingQueue<>();public static void main(String[] args) {/*** Producer*/Thread producer &#61; new Thread(() -> {while (true) {JSONObject data1 &#61; new JSONObject();JSONObject data2 &#61; new JSONObject();JSONObject data3 &#61; new JSONObject();JSONObject data4 &#61; new JSONObject();data1.put("name", "Kangkang");data1.put("gender", "male");data1.put("age", 14);data2.put("name", "Michael");data2.put("gender", "male");data2.put("age", 14);data3.put("name", "Jane");data3.put("gender", "female");data3.put("age", 14);data4.put("name", "Maria");data4.put("gender", "female");data4.put("age", 15);JSONObject data &#61; new JSONObject();Object[] array &#61; {data1, data2, data3, data4};data.put("group2", array);broker.offer(data);try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}}}, "生产者");producer.start();/*** Consumer*/Thread consumer &#61; new Thread(() -> {while (true) {JSONObject data &#61; broker.poll();if (data !&#61; null) {System.out.println(Thread.currentThread().getName() &#43; "获取到数据&#xff1a;" &#43; data.toJSONString());}}}, "消费者");consumer.start();}
}

运行结果&#xff1a;(每5s输出一次)

消费者获取到数据&#xff1a;{"group2":[{"gender":"male","name":"Kangkang","age":14},{"gender":"male","name":"Michael","age":14},{"gender":"female","name":"Jane","age":14},{"gender":"female","name":"Maria","age":15}]}


1.5 当前的主流MQ


1.5.1 ActiveMQ

ActiveMQ是Apache的产品&#xff0c;是完全支持JMS(Java Message Service)规范的消息中间件&#xff0c;提供了丰富的API&#xff0c;支持各种各样的客户端去调用&#xff0c;还提供了多种集群架构模式&#xff0c;可以说是目前行业内最流行、能力最强劲的开源消息总线。

但是ActiveMQ在近几年的发展过程中&#xff0c;它的性能一直受人诟病——它的吞吐量并不高&#xff0c;所以大型的互联网公司一般都不会去用&#xff0c;而在中小型企业中比较受欢迎。


1.5.2 Kafka

Kafka目前属于Apache顶级项目。Kafka追求高吞吐量&#xff0c;一开始的目的就是用于日志的收集和传输。

虽然Kafka的性能特别高&#xff0c;但它不支持事务&#xff0c;对消息的重复、丢失、错误没有严格要求。


1.5.3 RocketMQ

RocketMQ是阿里开源的消息中间件&#xff0c;它是纯Java开发&#xff0c;具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于Kafka&#xff0c;但并不是Kafka的一个Copy&#xff0c;它对消息的可靠传输及事务性做了优化&#xff0c;目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。


1.5.4 RabbitMQ

RabbitMQ是使用Erlang语言开发的开源消息队列&#xff0c;基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内对数据一致性、稳定性和可靠性要求很高的场景&#xff0c;对性能和吞吐量的要求还在其次。

 

【暂时写到这里&#xff0c;如果以后有时间写写RabbitMQ和Kafka】

加油&#xff01;(ง •_•)ง


推荐阅读
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 关于CMS收集器的知识介绍和优缺点分析
    本文介绍了CMS收集器的概念、运行过程和优缺点,并解释了垃圾回收器的作用和实践。CMS收集器是一种基于标记-清除算法的垃圾回收器,适用于互联网站和B/S系统等对响应速度和停顿时间有较高要求的应用。同时,还提供了其他垃圾回收器的参考资料。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • java drools5_Java Drools5.1 规则流基础【示例】(中)
    五、规则文件及规则流EduInfoRule.drl:packagemyrules;importsample.Employ;ruleBachelorruleflow-group ... [详细]
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
  • 三、查看Linux版本查看系统版本信息的命令:lsb_release-a[root@localhost~]#lsb_release-aLSBVersion::co ... [详细]
  • java线程池的实现原理源码分析
    这篇文章主要介绍“java线程池的实现原理源码分析”,在日常操作中,相信很多人在java线程池的实现原理源码分析问题上存在疑惑,小编查阅了各式资 ... [详细]
author-avatar
手机用户2502912197
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有