面试被问过的问题

 

目录

 

其他

什么是幂等

限流

分布式事务?

分布式锁

JDK

单例

volatile 

ThreadLocal

jvm 内存模型

双亲委派模型

内存模型为什么分两块内存

堆和栈的区别主要有五大点

jvm垃圾回收器

synchronized

HashMap

ArrayList

CAS

设计模式:

Java中的线程的生命周期大体可分为5种状态

HashMap和HashTable的区别

concurrentHashmap

Java中的线程的生命周期大体可分为5种状态

线程池原理

线程池提交策略

TCP三次握手和4次挥手

nio和bio的区别

8种基本类型所占字节数及取值范围

final、finally与finalize区别

设计模式都有哪些?

REDIS

redis保留策略

spring

aop

JDK动态代理和CGLIB动态代理的区别

Spring切面可以应用5种类型的通知:

Spring框架支持以下五种bean的作用域:

SpringBootApplication 注解

spring bean的生命周期?

循环依赖

Dubbo

dubbo 负载策略

dubbo zk当注册中心有什么问题

Mybatis/mysql

mybatis中的#和$的区别或者锁怎么防止sql注入

mysql 表锁和行锁的区别

rocketMq

消息队列应用场景?

如何保证消息的顺序性?

事务消息

rocketmq 原理

rocketmq和kafka区别


其他

  • 什么是幂等

什么是幂等,什么情况下需要幂等,如何实现幂等
在微服务架构下,我们在完成一个订单流程时经常遇到下面的场景:
一个订单创建接口,第一次调用超时了,然后调用方重试了一次
在订单创建时,我们需要去扣减库存,这时接口发生了超时,调用方重试了一次
当这笔订单开始支付,在支付请求发出之后,在服务端发生了扣钱操作,接口响应超时了,调用方重试了一次
一个订单状态更新接口,调用方连续发送了两个消息,一个是已创建,一个是已付款。但是你先接收到已付款,然后又接收到了已创建
全局唯一ID
如果使用全局唯一ID,就是根据业务的操作和内容生成一个全局ID,在执行操作前先根据这个全局唯一ID是否存在,来判断这个操作是否已经执行。如果不存在则把全局ID,存储到存储系统中,比如数据库、redis等。如果存在则表示该方法已经执行。
去重表
这种方法适用于在业务中有唯一标的插入场景中,比如在以上的支付场景中,如果一个订单只会支付一次,所以订单ID可以作为唯一标识。这时,我们就可以建一张去重表,并且把唯一标识作为唯一索引,在我们实现时,把创建支付单据和写入去去重表,放在一个事务中,如果重复创建,数据库会抛出唯一约束异常,操作就会回滚。

  • 限流

guava RateLimiter限流,限定每秒有多少访问可以获取到许可证

https://www.cnblogs.com/toutou/p/springboot_rateLimiter.html

  • 分布式事务?

参考rocketmq 事务消息

  • 分布式锁

redis 创建一个key 有效期,其他程序查看是否可以获得到这个key

JDK

  • 单例

  • volatile 

每个线程有本地内存和共享主内存,线程间通讯需要靠主内存变量通讯
原子性:对变量的写操作不依赖于当前值线程安全的,如果依赖当前值i++那么是线程不安全的,
可见性:如果一个线程修改了变量,其他线程获取是最新的
有序性:内存模型允许编译器对指令重排序,如果两个操作访问同一个变量,且这两个操作有一个为写操作,此时这两个操作就存在数据依赖性,禁止重排序

  • ThreadLocal

ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
内存泄漏
ThreadLocalMap的key使用弱引用,key值被回收了,value未被回收,为了解决此问题在 get set remove方法中清理key为null的value

  • jvm 内存模型

1、程序计数器:指向当前线程正在执行的字节码指令。线程私有的。
2、虚拟机栈:虚拟机栈是Java执行方法的内存模型。每个方法被执行的时候,都会创建一个栈帧,把栈帧压人栈,当方法正常返回或者抛出未捕获的异常时,栈帧就会出栈。
3、本地方法栈:调用本地native的内存模型
4、方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据
5、堆(Heap):Java对象存储的地方

新生代
分为Eden、Survivor From、Survivor To,比例默认为8:1:1
垃圾回收
第一个阶段是可达性分析,分析该对象是否可达
当对象没有重写finalize()方法或者finalize()方法已经被调用过,虚拟机认为该对象不可以被救活,因此回收该对象。(finalize()方法在垃圾回收中的作用是,给该对象一次救活的机会)
GC使用时对程序的影响?
垃圾回收会影响程序的性能,Java虚拟机必须要追踪运行程序中的有用对象,然后释放没用对象,这个过程消耗处理器时间
标记-清除算法
思想:标记清除算法分为两个阶段,标记阶段和清除阶段。标记阶段任务是标记出所有需要回收的对象,清除阶段就是清除被标记对象的空间。
复制清除算法
将可用内存划分为大小相等的两块,每次只使用其中的一块。当进行垃圾回收的时候了,把其中存活对象全部复制到另外一块中,然后把已使用的内存空间一次清空掉。
思想:先标记存活对象,然后把存活对象向一边移动,然后清理掉端边界以外的内存。
类加载机制
加载:查找并加载类的二进制数据(把class文件里面的信息加载到内存里面)
验证:确保被加载的类的正确性。
准备:为类的静态变量分配内存,并将其初始化为默认值
解析:把类中的符号引用转化为直接引用
初始化:为类的静态变量赋予正确的初始值。

  • 双亲委派模型

当一个类加载器收到类加载请求的时候,它首先不会自己去加载这个类的信息,而是把该请求转发给父类加载器,依次向上。
类加载器:
根类加载器 负责加载虚拟机的核心库,比如java.lang.Object
扩展类加载器 Java编写的,从指定目录中加载类库 <JAVA_HOME>/lib/ext
系统加载器(System)或者应用加载器:从环境变量或者class.path中加载类
SPI接口在java核心库,实现类一般是由系统类加载器来加载的。启动加载器找不到实现类。引入上线文加载器,获取当前线程的类加载器从父线程继承的,一般就是系统加载器

  • 内存模型为什么分两块内存

线程内存是在cpu高速缓存中运行非常快 ,CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中
主内存是物理内存容量大

  • 堆和栈的区别主要有五大点

  1. 堆内存用来存放由new创建的对象和数组。 
  2. 栈内存用来存放方法或者局部变量等 
  3. 堆是先进先出,后进后出,栈是先进后出,后进先出
  4. 请方式的不同。栈由系统自动分配,而堆是人为申请开辟
  5. 申请大小的不同。栈获得的空间较小,而堆获得的空间较大
  6. 申请效率的不同。栈由系统自动分配,速度较快,而堆一般速度比较慢
  7. 存储内容的不同。栈在函数调用时,函数调用语句的下一条可执行语句的地址第一个进栈,然后函数的各个参数进栈,其中静态变量是不入栈的。而堆一般是在头部字节存放堆的大小,雄中的具体内容是人为安
  8. 底层不同。栈是连续的空间,而维是不连续的空间

 

  • jvm垃圾回收器

新生代
Serial 收集器
单线程收集器 复制算法 使用client 单核服务器
parnew
是serial多线程版本 默认开启线程数和cpu数量一致
Parallel Scavenge 收集器
jdk8 默认,并行的多线程收集器,复制算法 GC自适应调节策略:虚拟机会根据系统的运行状况收集性能监控信息,动态设置这些参数以提供最优的停顿时间和最高的吞吐量,这种调节方式称为GC的自适应调节策略
老年代
Serial Old 收集器
单线程  标记-整理算法
Parallel Old 收集器
jdk8 默认,多线程 标记-整理算法 吞吐量
CMS收集器 
标记-清除算法 并发收集 低停顿 缺点会有空间碎片
G1 新生代老年代
服务端应用的垃圾收集器。
并行与并发:G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU来缩短Stop-The-World停顿时间。部分收集器原本需要停顿Java线程来执行GC动作,G1收集器仍然可以通过并发的方式让Java程序继续运行。
分代收集:G1能够独自管理整个Java堆,并且采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。
空间整合:G1运作期间不会产生空间碎片,收集后能提供规整的可用内存。
可预测的停顿:G1除了追求低停顿外,还能建立可预测的停顿时间模型。能让使用者明确指定在一个长度为M毫秒的时间段内,消耗在垃圾收集上的时间不得超过N毫秒。

  • synchronized

每个对象都有一个monitor监视器,调用monitorenter就是尝试获取这个对象,成功获取到了就将值+1,离开就将值减1。如果是线程重入,在将值+1,说明monitor对象是支持可重入的。
同步方法由方法调用指令读取运行时常量池中方法的 ACC_SYNCHRONIZED 标志来隐式实现的,获取它的monitor,所以本质上是一样的
锁的状态总共有四种,无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁
偏向锁:如果一个线程获得了锁,那么锁就进入偏向模式,当这个线程再次请求锁时,无需再做任何同步操作,即获取锁的过程
轻量级锁:轻量级锁所适应的场景是线程交替执行同步块的场合
重量级锁是依赖依赖操作系统的MutexLock(互斥锁)来实现的,需要从用户态转换到内核态 比较耗时

  • HashMap

由链表+数组如果链表长度大于8转为红黑树 初始大小 16因子0.75 扩大2倍
put 先计算hash值找到数组下表,在链表或红黑树中equals比较相等插入 如果没有在最后插入

  • ArrayList

创建为0,初始是10 扩大为1.5倍

arraylIst 的size方法
就是返回size 在增加元素的时候size++ remove的时候size--

  • CAS

CAS有三个操作数,内存值V,旧的预期值A,要修改的新值B,当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

  • aqs

AQS队列内部维护的是一个FIFO的双向链表,这种结构的特点是每个数据结构都有两个指针,分别指向直接的后继节点和直接前驱节点。 Node
head节点表示获取锁成功的节点,当头结点在释放同步状态时,会唤醒后继节点,如果后继节点获得锁成功,会把自己设置为头结点
tail是最后一个节点

  • 设计模式:

工厂模式:集中创建对象,主要解决接口选择的问题
单例模式:一个类仅有一个实例,并提供一个访问它的全局访问点。主要解决:一个全局使用的类频繁地创建与销毁。
适配器模式:作为两个不兼容的接口之间的桥梁。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。
装饰器模式:动态地给一个对象添加一些额外的职责。一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀
策略模式:类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
模板模式:一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现
 

  • Java中的线程的生命周期大体可分为5种状态

新建(NEW):新创建了一个线程对象。
可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。
运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种: 
(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
死亡(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

 

  • HashMap和HashTable的区别

hashMap允许null 是线程不安全的 扩容2倍
hashtable 不允许为null 方法都是Synchronize的 不会转红黑树

  • concurrentHashmap

CAS+Synchronized来保证并发更新的安全,底层依然采用数组+链表+红黑树的存储结构。
先根据key的hash值定位桶位置,然后cas操作获取该位置头节点,接着使用synchronized锁锁住头节点,遍历该位置的链表或者红黑树进行插入操作。
如果是线程并发量不大的情况下,那么Synchronized因为自旋锁,偏向锁,轻量级锁的原因,不用将等待线程挂起,偏向锁甚至不用自旋,所以在这种情况下要比ReentrantLock高效

  • Java中的线程的生命周期大体可分为5种状态

新建(NEW):新创建了一个线程对象。
可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。
运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种: 
(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
死亡(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

  • 线程池原理

  • 线程池提交策略

ThreadPoolExecutor.AbortPolicy 丢弃任务,并抛出 RejectedExecutionException 异常。
ThreadPoolExecutor.CallerRunsPolicy:该任务被线程池拒绝,由调用 execute方法的线程执行该任务。
ThreadPoolExecutor.DiscardOldestPolicy : 抛弃队列最前面的任务,然后重新尝试执行任务。
ThreadPoolExecutor.DiscardPolicy,丢弃任务,不过也不抛出异常。

  • TCP三次握手和4次挥手

第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
四次握手断开连接:
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当 然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但此时主动关闭方还可以接受数据。
第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。
第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。
TCP的可靠性是通过顺序编号和确认(ACK)来实现的

  • nio和bio的区别

  • 8种基本类型所占字节数及取值范围

类型字节数位数取值范围
Byte18-2的7次方到2的7次方-1
Short216-2的15次方到2的15次方-1
Int432-2的31次方到2的31次方-1
Long864-2的63次方到2的63次方-1
Float4323.402823e+38 ~ 1.401298e-45
Double8641.797693e+308~ 4.9000000e-324
char216 
boolean1(前7位是0)10/1

float 单精度浮点数在机内占 4 个字节,用 32 位二进制描述。
double 双精度浮点数在机内占 8 个字节,用 64 位二进制描述。

  • final、finally与finalize区别

final 
修饰类:表明该类不能被其他类所继承。
修饰方法:把方法锁定,以防止继承类对其进行更改。
final成员变量:只能被赋值一次,赋值后其值不再改变。
finally关键字用在异常处理中,用于处理异常后的清理工作 一定执行
finalize()是Object中的方法,当垃圾回收器将要回收对象所占内存之前被调用

  • 设计模式都有哪些?

单例模式
1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例
 使用场景:1、要求生产唯一序列号。 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
工厂模式
对实现了同一接口的一些类进行实例的创建。
模板方法模式
模板方法模式是指定义一个模板结构,将具体内容延迟到子类去实现。
提高代码复用性:将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中;
实现了反向控制:通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制并且符合开闭原则。
代理模式
代理模式是给某一个对象提供一个代理,并由代理对象控制对原对象的引用。
优点:
代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度;
可以灵活地隐藏被代理对象的部分功能和服务,也增加额外的功能和服务。
缺点:
由于使用了代理模式,因此程序的性能没有直接调用性能高;
使用代理模式提高了代码的复杂度。

 

REDIS

数据类型有 String list Hash set sortedSet

  • redis保留策略

noeviction:当内存使用达到阈值的时候,所有引起申请内存的命令会报错。
allkeys-lru:在主键空间中,优先移除最近未使用的key。(推荐)
volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。
allkeys-random:在主键空间中,随机移除某个key。
volatile-random:在设置了过期时间的键空间中,随机移除某个key。
volatile-ttl:在设置了过期时间的键空间中,具有更早过期时间的key优先移除。

spring

  • aop

Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法

 

  • JDK动态代理和CGLIB动态代理的区别

jdk代理实现接口InvocationHandler 通过invoke()方法反射来调用目标类中的代码
CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
singleton的代理对象或者具有实例池的代理,因为无需频繁的创建代理对象,所以比较适合采用CGLib动态代理

 

  • Spring切面可以应用5种类型的通知:

前置通知(Before):在目标方法被调用之前调用通知功能;
后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;
返回通知(After-returning ):在目标方法成功执行之后调用通知;
异常通知(After-throwing):在目标方法抛出异常后调用通知;
环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。

  • Spring框架支持以下五种bean的作用域:

singleton : bean在每个Spring ioc 容器中只有一个实例。
prototype:一个bean的定义可以有多个实例。
request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

 

  • SpringBootApplication 注解

@SpringBootConfiguration
读取配置文件,配置文件的路径是当前根目录
EnableAutoConfiguration
开启自动配置,扫描当前的所有依赖的jar包给容器导入META-INF/spring.factories 里定义的自动配置类。
ComponetScan
@ComponentScan自动扫描 @Component和子类注解
spring boot 源码
springapplication 构造方法 指定环境类型 加载META-INF/spring.factories 获取ApplicationContextInitialize 获取监听器
创建并启动计时监控类
创建所有 Spring 运行监听器并发布应用启动事件
初始化参数    
加载环境变量
创建上下文 ConfigurableApplicationContext 根据环境类型创建
准备上下文 prepareContext()
刷新上下文 refreshContext() dogetbean
刷新之后的处理 afterRefresh()

  • spring bean的生命周期?

  • 循环依赖

1、构造器注入和prototype类型的field注入发生循环依赖时都无法初始化
2、field注入单例的bean时,尽管有循环依赖,但bean仍然可以被成功初始化
3、Spring通过将实例化后的对象提前暴露给Spring容器中的singletonFactories,解决了循环依赖的问题。

Dubbo

  • dubbo 负载策略

随机均衡算法
权重轮循算法
最小活跃数算法
一致性hash算法

  • dubbo zk当注册中心有什么问题

zookeeper 注册中心并没有在阿里内部长时间运行的可靠性保障,此 Zookeeper 桥接实现只为开源版本提供,其可靠性依赖于 Zookeeper 本身的可靠性。

Mybatis/mysql

  • mybatis中的#和$的区别或者锁怎么防止sql注入

#{}正是用了?占位符
$方式一般用于传入数据库对象,例如传入表名.
一般能用#的就别用$,若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击
简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。
MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。

  • mysql 表锁和行锁的区别

InnoDB 支持表锁和行锁,使用索引作为检索条件修改数据时采用行锁,否则采用表锁。

行锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
表锁:开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。

rocketMq

  • 消息队列应用场景?

  • 如何保证消息的顺序性?

顺序消息分为两类:
全局顺序:对于指定的一个Topic,所有消息按照严格的先入先出FIFO(First In First Out)的顺序进行发布和消费。
分区顺序:对于指定的一个Topic,所有消息根据Sharding Key进行区块分区。同一个分区内的消息按照严格的FIFO顺序进行发布和消费。Sharding Key是顺序消息中用来区分不同分区的关键字段,和普通消息的Key是完全不同的概念。

  • 事务消息

  • rocketmq 原理

RocketMQ架构上主要分为四部分
Producer:Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投递,投递的过程支持快速失败并且低延迟。
Producer与NameServer集群中的其中一个节点(随机选择)建立长连接,定期从NameServer获取Topic路由信息,并向提供Topic 服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署
Consumer:支持以push推,pull拉两种模式对消息进行消费。同时也支持集群方式和广播方式的消费,它提供实时消息订阅机制,可以满足大多数用户的需求。

NameServer:NameServer是一个非常简单的Topic路由注册中心,,支持Broker的动态注册与发现。主要包括两个功能:
Broker管理,NameServer接受Broker集群的注册信息并且保存下来作为路由信息的基本数据。然后提供心跳检测机制,检查Broker是否还存活;
路由信息管理,每个NameServer将保存关于Broker集群的整个路由信息和用于客户端查询的队列信息。
BrokerServer:Broker主要负责消息的存储、投递和查询以及服务高可用保证,为了实现这些功能,Broker包含了以下几个重要子模块。
Remoting Module:整个Broker的实体,负责处理来自clients端的请求。
Client Manager:负责管理客户端(Producer/Consumer)和维护Consumer的Topic订阅信息
Store Service:提供方便简单的API接口处理消息存储到物理硬盘和查询功能。
HA Service:高可用服务,提供Master Broker 和 Slave Broker之间的数据同步功能。
Index Service:根据特定的Message key对投递到Broker的消息进行索引服务,以提供消息的快速查询。

  • rocketmq和kafka区别

性能对比 
kafka 百万条/秒 消息大小10个字节 顺序写随机读
rocketmq 7万/秒
数据可靠性
rocketmq支持同步刷盘异步刷盘
kafka 异步刷盘
消息类型
rocketmq 普通 定时 延时 事务
kafka 普通消息
编写语音
Kafka采用Scala编写
RocketMQ采用Java语言编写

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值