Redis 除了做缓存,还能做什么?
分布式锁:通过 Redis 来做分布式锁是一种比较常见的方式。通常情况下,我们都是基于 Redisson 来实现分布式锁。
限流:一般是通过 Redis + Lua 脚本的方式来实现限流。
消息队列:Redis 自带的 List 数据结构可以作为一个简单的队列使用。Redis 5.0 中增加的 Stream 类型的数据结构更加适合用来做消息队列。它比较类似于 Kafka,有主题和消费组的概念,支持消息持久化以及 ACK 机制。
延时队列:Redisson 内置了延时队列(基于 Sorted Set 实现的)。
分布式 Session :利用 String 或者 Hash 数据类型保存 Session 数据,所有的服务器都可以访问。
复杂业务场景:通过 Redis 以及 Redis 扩展(比如 Redisson)提供的数据结构,我们可以很方便地完成很多复杂的业务场景比如通过 Bitmap 统计活跃用户、通过 Sorted Set 维护排行榜。
如何保证redis和mysql数据一致
- 先删缓存再更新数据库/先更新数据库再删缓存。
- 先更新Redis,再更新MySQL。
- 只更新缓存,由缓存自己异步更新数据库。
SpirngCloud的五大核心组件
Eureka:服务注册中心
Ribbon:客户端负载均衡
Hystrix:熔断器,实现断路器模式,帮助服务依赖中出现的延迟和故障提供容错机制
Fegin:声明式的Http客户端
Zuul:服务网关
Archaius:外部化配置参数组件
alibaba集成的spring cloud组件有哪些?
1、Alibaba Nacos:Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。换句话说Nacos就是注册中心和配置中心的组合。等价于:Nacos=Eureka+SpringCloud Config+SpringCloud Bus。Nacos可以替代Eureka做服务注册中心,替代SpringCloud Config、Spri-ngCloud Bus做服务配置中心和消息中心,
2、Alibaba Sentinel:Sentinel是一个用于流量控制、熔断降级和系统负载保护的开源框架。
3、Alibaba RocketMQ:RocketMQ是一个分布式消息队列系统,可以实现高可靠性和高吞吐量的消息传递。
4、Alibaba Seata:Seata是一个用于分布式事务处理的解决方案。
5、Alibaba OSS:OSS是阿里云提供的对象存储服务,它可以与Spring Cloud一起使用,以实现文件存储和管理。
阻塞状态sleep与wait的区别
1、sleep()是Thread类的静态方法,wait()是Object类的实例方法
2、sleep()不会释放对象锁,wait()会释放对象锁
3、sleep()可以用在任何地方,wait()只能用在同步代码块中
sleep()就是当前线程进入阻塞状态,cpu不会继续执行当前线程,直到指定的时间超过才会重新执行当前线程,这个过程中不会释放对象锁,如果当前线程持有对象锁,那么其他需要此对象锁才能运行的线程就无法继续。
wait()是指在一个已经进入了同步代码块的线程让cpu停止执行当前线程转去执行其他线程,并且将当前线程所持有的对象锁释放,让其他需要此对象锁的线程能够正常运行,当其他线程调用notify()或notifyAll()时才会唤醒当前线程,但是并不会马上获得对象锁,只是进入就绪状态,准备抢锁。
什么情况下会导致索引失效,索引失效的原因
1、未使用索引字段进行查询
2、索引列使用了函数或表达式
3、使用了不等于(!= 或 <>)操作符
4、LIKE 操作符的模糊查询
5、对索引列进行了数据类型转换
6、使用 OR 连接多个条件
7、表中数据量较少
8、索引列上存在大量重复值
9、数据分布不均匀
10、索引列上存在过多的 NULL 值
11、索引字段与排序字段不匹配
12、索引列进行了隐式类型转换
Java集合,是对多个数据进行存储的结构,简称java容器
怎么解决超买超卖
1、每一个用户只能抢购一件商品的限制;在数据库减库存时加上库存数量判断,库存数量为0时阻止秒杀订单的生成。数据库加唯一索引:防止用户重复购买。SQL加库存数量判断:防止库存变为负数
2、将存库MySQL迁移到Redis中,所有的写操作放到内存中,由于Redis中不存在锁故不会出现互相等待,并且由于Redis的写性能和读性能都远高于MySQL,这就解决了高并发下的性能问题。然后通过队列等异步手段,将变化的数据异步写入到DB中。
如何用redis实现分布式锁
setnx(SET if Not eXists)命令、expire命令、getset命令、Lua脚本
如何解决高并发情况下的问题
1.负载均衡
负载均衡是指将多台服务器组成一个集群,通过某种策略将访问请求均匀地分发到各个服务器上,使每个服务器的负载均衡。负载均衡可以提高系统的可用性和性能。
2.缓存
缓存是将数据存储在高速缓存中,以便在需要时快速访问。缓存可以减少数据库的读写操作,从而提高系统的性能。可以使用内存缓存、分布式缓存等方式实现缓存功能。
3.数据库优化
数据库是高并发系统的瓶颈之一,因此对数据库进行优化是解决高并发问题的重要方法。可以通过分库分表、索引优化、SQL优化等方式来提高数据库的性能。
4.异步处理
异步处理是将处理请求放入消息队列中,由后台进程或线程异步处理,从而避免了同步处理带来的性能瓶颈。异步处理可以使用消息队列、定时任务等方式实现。
5.分布式架构
分布式架构是将系统拆分成多个独立的子系统,每个子系统都可以独立运行,从而提高系统的可扩展性和可用性。分布式架构可以使用微服务、分布式缓存等方式实现。
如何解决MySQL的慢查询
1、不使用子查询
2、读取适当的记录LIMIT M,N
3、分组统计可以禁止排序
4、禁止不必要的ORDER BY排序
5、尽量不要超过三个表join
6、在varchar字段上建立索引时,必须指定索引长度
7、不要使用 select *
8、排序请尽量使用升序
9、尽量使用数字型字段
10、避免索引失效
11、删除表所有记录请用 truncate,不要用 delete
12、存储过程和触发器设置
索引的数据结构是什么样的
二叉树、红黑树/AVL树、hash表、B树(B+树)。
二叉树特点是每个节点最多只能有两棵子树,且有左右之分。如果是顺序的插入数据,二叉树会退化成链表,那么查找其中的元素的时候,就会需要整体的遍历,显然不适合作为数据库的索引。
红黑树是一种平衡的二叉树。添加节点的时候,相比二叉树,节点间会进行自动的平衡,不会退化成链表,可以有效降低树的高度。但是红黑树本质还是二叉树,对于数据库来说,避免不了在数据量大的情况下,树的高度依然非常高的情况。
Hash表,对索引的key进行一次Hash计算就可以定位出数据存储的位置,查找效率非常高。
B树是一棵平衡的m路搜索树,它的子节点可以有多个,使得整颗树更加的扁平化。所有节点关键字是按递增次序排列,并遵循左小右大原则。B树(B+树)一般较多用在存储系统上,比如数据库或文件系统。
线程和进程的区别
进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。(进程是资源分配的最小单位)
线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。
Mybatis的动态sql标签
1、<trim>:通过修剪 SQL 语句的开头和结尾来动态生成 SQL 片段。它可以用于去除不必要的 SQL 关键字或条件语句,并提供了一些属性来定义修剪规则。
2、<where>:用于在生成的 SQL 语句中添加 WHERE 子句。它可以自动处理条件语句的前缀,并在有条件语句存在时添加 WHERE 关键字。
3、<set>:用于在生成的 SQL 语句中添加 SET 子句。它主要用于更新操作,可以根据条件来动态生成需要更新的列。
4、<foreach>:用于在生成的 SQL 语句中进行循环操作。它可以遍历集合或数组,并根据指定的模板将集合元素或数组元素插入到 SQL 语句中。
5、<if>:用于在生成的 SQL 语句中添加条件判断。可以根据指定的条件决定是否包含某个 SQL 语句片段。
6、<choose>:类似于 Java 中的 switch 语句,根据条件选择执行不同的 SQL 语句片段。它可以包含多个 <when> 和一个可选的 <otherwise> 标签。
7、<when>:用于在 <choose> 标签中定义条件分支。可以根据指定的条件判断是否执行特定的 SQL 语句片段。
8、<otherwise>:在 <choose> 标签中可选的标签,用于定义当没有任何 <when> 条件匹配时执行的 SQL 语句片段。
9、<bind>:用于将表达式的结果绑定到一个变量上。可以在 SQL 语句中使用这个变量,避免重复计算表达式。
java垃圾回收机制的算法有哪些
1、标记-清除(Mark-Sweep)算法: 这是最基础的垃圾回收算法,分为两个阶段:首先标记出所有需要回收的对象,随后清除这些被标记的对象。此算法可能导致内存碎片化,影响后续的大对象分配。
2、复制(Copying)算法: 将内存区域分为两块,每次只使用其中一块。当一块区域用尽时,将存活的对象复制到另一块未使用的区域上,然后一次性清理掉之前的区域。这种方法可以有效避免内存碎片,但是空间利用率只有50%。
3、标记-整理(Mark-Compact)算法: 结合了标记-清除算法和复制算法的优点,同样先标记出需要回收的对象,但在清除阶段,它会将存活对象向一端移动,然后直接清理边界外的内存空间,从而解决了碎片化问题。
4、分代收集(Generational Collection)算法: 根据对象的生存周期将内存划分为年轻代和老年代。年轻代中对象生存期短,频繁回收,通常使用复制算法;老年代中对象生存期长,回收频率低,适合使用标记-清除或标记-整理算法。这种策略能够提高垃圾回收的效率,因为不同代上的对象特性不同,可以针对性地选择最适合的算法。
5、增量收集(Incremental GC): 试图减少垃圾回收的停顿时间,通过将垃圾回收过程分成多个小步骤,每次只回收一部分,使得程序可以间歇性地继续执行。
6、并发标记-清除(Concurrent Mark-Sweep, CMS): 在老年代中使用,尽可能地与应用程序并发执行标记和清除过程,减少垃圾回收引起的暂停时间,适用于对响应时间有严格要求的应用。
7、G1(Garbage First): 是一种针对大内存应用的垃圾收集器,将堆内存分割成多个大小相等的区域,并使用复制和标记-整理算法的混合策略,以低延迟为目标进行垃圾回收。G1能够预测并主动管理内存碎片,避免长时间的STW(Stop-The-World)事件。
新生代怎么到的老年代
1、Eden区满时,进行Minor GC
当Eden和一个Survivor区中依然存活的对象无法放入到Survivor中,则通过分配担保机制提前转移到老年代中。
2.、对象体积太大, 新生代无法容纳
-XX:PretenureSizeThreshold即对象的大小大于此值, 就会绕过新生代, 直接在老年代分配, 此参数只对Serial及ParNew两款收集器有效。
3、Survivor区空间不足:如果Survivor区中经历了多次GC后仍然存活的对象数量过多,以至于无法容纳在一个Survivor区时,部分对象也会被提前晋升到老年代,即使它们没有达到年龄阈值。
4、动态对象年龄判定
在某些情况下,如果Survivor区中的对象空间占用超过了某一比例(比如,survivor空间的50%被占用),那么年龄较大的对象也可能在未达到最大年龄阈值时就被晋升到老年代。
泛型常用特点
1、类型安全:泛型在编译时期就能进行类型检查,可以在编译阶段捕获一些类型错误,避免在运行时出现类型转换异常。这使得代码更加稳定、可靠。
2、代码重用:泛型允许编写可以应用于多种数据类型的通用代码,无需为每种类型重复编写相同的逻辑,增强了代码的复用性和模块化。
3、可读性:使用泛型能够使代码更加清晰易懂,通过在代码中指定类型参数,可以清晰地表达出方法或类的意图。
4、集合类型安全:泛型广泛应用于集合类,例如`ArrayList<E>`、`HashMap<K, V>`等,通过指定元素类型或键值对类型,在编译时能够发现类型不匹配的错误。
5、代码优化:泛型能够提高代码性能,在编译时进行类型检查和类型擦除,可以减少运行时的类型转换,提高执行效率。
6、增强代码可维护性:通过使用泛型,可以使代码更易于维护和扩展,减少了对类型的依赖性,使得代码更灵活。
AOP是什么
AOP是面向切面编程,是一种编程范式,用于解决软件开发中的横切关注点(Cross-cutting Concerns)问题。横切关注点是指那些遍布于整个应用程序的多个模块中的功能,它们与核心业务逻辑关联不大,但却会在很多不同的地方重复出现,例如日志记录、安全性验证、事务管理、异常处理等。
在传统的面向对象编程(OOP)中,关注点通常被封装在单个类或对象中,但这对于处理横切关注点来说不够高效,因为这些功能的代码往往会散落在各个业务逻辑类中,造成代码重复,难以维护。AOP通过将这些横切关注点从业务逻辑中分离出来,集中进行管理和织入,实现了关注点的解耦。
AOP的关键概念包括:
1、切面(Aspect):切面是跨越多个对象的行为或关注点的模块化,比如日志记录切面、事务管理切面等。它封装了横切关注点的实现。
2、连接点(Joinpoint):在程序执行过程中可以插入切面操作的点,如方法调用、异常抛出等。
3、通知(Advice):在切面的某个特定连接点上执行的动作。通知有多种形式,比如前置通知(在方法调用前执行)、后置通知(在方法调用后执行)、环绕通知(围绕方法调用执行)等。
4、切入点(Pointcut):定义了切面中的通知应该在哪些连接点上执行的规则。例如,一个切入点可以表达“所有业务层方法的执行”。
5、织入(Weaving):将切面应用到目标对象并创建代理对象的过程。织入可以在编译时、类加载时或运行时进行。
通过AOP,开发者可以更加专注于业务逻辑的实现,而将诸如日志、安全等横切关注点的处理交给AOP框架自动完成,从而提高了代码的模块化程度、可维护性和可重用性。Spring框架是Java领域中广泛使用的实现AOP概念的框架之一。
OOP是什么
OOP是指面向对象程序设计,是一种计算机编程架构。面向对象编程强调的是通过对象的相互作用来解决问题,模拟现实世界的实体关系,使得程序设计更加直观,易于理解,便于维护和扩展。许多现代编程语言如Java、C++、C#等都支持面向对象编程。
面向对象的三大特性:
1、封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。
2、继承:提高代码复用性;继承是多态的前提。
3、多态:父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。
AOP与OOP的区别
OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。
AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差异。
1、面向目标不同:简单来说OOP是面向名词领域,AOP面向动词领域。
2、思想结构不同:OOP是纵向结构,AOP是横向结构。
3、注重方面不同:OOP注重业务逻辑单元的划分,AOP偏重业务处理过程的某个步骤或阶段。
重载与重写的含义与区别
重写(Overriding)是指在子类中重新定义一个与父类中同名、同参数列表的方法。重写的目的是为了实现多态性,子类可以重写父类中的方法,并且可以根据自己的需要进行修改或扩展。在重写中,子类方法的返回类型和参数列表必须与父类方法相同或者是其子类,而且子类方法的访问修饰符不能低于父类方法的访问修饰符。
重载(Overloading)是指在同一个类中,允许存在多个同名的方法,这些方法的参数列表必须不同。方法的返回类型、修饰符等可以不同,但这些不是重载的决定因素。编译器会根据方法调用时提供的参数类型和数量来决定调用哪个具体的方法。
区别总结
1、应用场景:重载用于同一类中方法功能相似但参数不同的情况,而重写用于子类修改或增强父类行为的情况。
2、方法签名:重载关注方法名相同但参数列表不同;重写要求方法名、参数列表及返回类型均与父类方法一致。
3、发生时间:重载的决定在编译期,属于静态绑定;重写则在运行时根据对象的实际类型确定,属于动态绑定。
4、访问权限与异常处理:重载对此没有特别限制;重写则要求访问权限不能更低,且抛出的异常不能比父类方法更广泛。
java多态的实现原理
Java中多态的实现原理主要基于以下几点核心概念:
1、继承(Inheritance):多态的实现基础是类的继承关系。一个类可以从父类继承属性和方法,同时可以扩展或覆盖父类的功能。
2、方法重写(Overriding):子类可以重写父类中的方法,提供自己的实现。这是多态表现的关键,允许子类对象对相同的请求做出不同的响应。
3、向上转型(Upcasting):将子类对象赋值给父类引用的过程。这实际上是一种隐式的类型转换,使得可以通过父类的引用调用子类重写的方法,从而实现多态行为。
4、动态绑定(Dynamic Binding)/ 运行时多态(Runtime Polymorphism):也称为晚期绑定。在Java中,非静态方法的调用(特别是被重写的方法)是在运行时绑定的。这意味着,决定调用哪个方法的实现是在程序运行时,根据对象的实际类型而非引用类型来决定。这一过程是由Java虚拟机(JVM)通过查阅对象的实际类型信息和虚方法表(Virtual Method Table, VMT)来实现的。
java的四种引用,强弱软虚用到的场景
1. 强引用(Strong Reference)
它是最常见的引用类型。当一个对象被一个强引用引用时,即使内存不足时,垃圾回收器也不会回收该对象。只有当该对象的所有强引用都被解除后,垃圾回收器才会回收该对象。强引用的应用场景通常是在对象的生命周期内都需要引用该对象的情况。
2. 软引用(Soft Reference)
软引用是一种相对较弱的引用类型。当一个对象被一个软引用引用时,只有当系统内存不足时,垃圾回收器才会回收该对象。软引用通常用来实现缓存或者高速缓存,当内存不足时可以释放一些缓存的对象。
3. 弱引用(Weak Reference)
弱引用也是一种相对较弱的引用类型。当一个对象被一个弱引用引用时,无论内存是否足够,垃圾回收器都可能回收该对象。弱引用通常用来实现一些特定的功能,如观察者模式。
4. 虚引用(Phantom Reference)
虚引用是最弱的引用类型。当一个对象被一个虚引用引用时,该对象在任何时候都可能被垃圾回收器回收。虚引用主要用于管理直接内存,当虚引用被回收时,可以触发一些特定的清理操作。
JVM流程
1、类加载器初始化:
JVM启动时,首先初始化Bootstrap ClassLoader(启动类加载器),它负责加载JVM自身需要的核心类(位于<JAVA_HOME>/jre/lib/rt.jar等位置)。随后,Extension ClassLoader(扩展类加载器)和Application ClassLoader(系统类加载器)也会被初始化,分别负责加载扩展类库和应用程序类路径上的类。
2、执行入口方法:
JVM会寻找并执行包含main方法的类,这个类通常由用户指定(比如通过命令行参数指定java MyClass)。main方法是Java应用程序的起点。
3、内存区域分配:
JVM会为运行的Java程序分配内存区域,包括堆(Heap)、栈(Stack)、方法区(Method Area/PermGen或Metaspace)、程序计数器(Program Counter Register)、本地方法栈(Native Method Stack)等。
4、类加载与初始化:
根据程序的需要,类加载器会逐步加载并链接(验证、准备、解析)所需的类,并进行类的初始化(执行类的静态初始化块和静态变量赋值)。
5、字节码解释执行或即时编译:
JVM读取类文件中的字节码,通过解释器逐条解释执行,或使用Just-In-Time (JIT) 编译器将热点代码编译成本地机器码以提高执行效率。
6、垃圾回收:
在程序运行过程中,JVM会自动管理内存,通过垃圾回收机制(GC)定期回收不再使用的对象所占用的内存空间,以保持内存的有效利用。
7、执行结束:
当main方法执行完毕,或者程序因异常退出,JVM开始关闭过程,包括执行所有已注册的Shutdown Hooks(关闭钩子),执行垃圾回收以回收剩余资源,最后JVM进程结束。
JVM调优
JVM(Java Virtual Machine)调优是指为了提高Java应用程序的性能,对Java虚拟机的配置参数和运行环境进行调整的过程。调优的目标通常包括减少内存消耗、提升应用响应速度、优化垃圾回收效率等。
堆和栈的区别
1、管理方式不同:栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏;
2、空间大小不同:每个进程拥有的栈大小要远远小于堆大小。理论上,进程可申请的堆大小为虚拟内存大小,进程栈的大小 64bits 的 Windows 默认 1MB,64bits 的 Linux 默认 10MB;
3、生长方向不同:堆的生长方向向上,内存地址由低到高;栈的生长方向向下,内存地址由高到低。
4、分配方式不同:堆都是动态分配的,没有静态分配的堆。栈有 2 种分配方式:静态分配和动态分配。静态分配是由操作系统完成的,比如局部变量的分配。动态分配由alloca()函数分配,但是栈的动态分配和堆是不同的,它的动态分配是由操作系统进行释放,无需我们手工实现。
5、存储内容的不同:栈在函数调用时,函数调用语句的下一条可执行语句的地址第一个进栈,然后函数的各个参数进栈,其中静态变量是不入栈的。而堆一般是在头部用一个字节存放堆的大小,堆中的具体内容是人为安排;
6、申请效率的不同:栈由系统自动分配,速度较快,而堆一般速度比较慢;
Eureka服务注册是什么
Eureka服务注册是一种服务发现机制,主要用于微服务架构中,以实现服务实例的自动注册与发现。它是Netflix开发的一款开源组件,现已被Spring Cloud集成并广泛应用于微服务生态中。
什么是SpringCloudRibbon
Spring Cloud Ribbon 是 Spring Cloud 生态系统中的一部分,它基于 Netflix Ribbon 实现,是一个客户端侧的负载均衡器。Ribbon 允许开发者在微服务架构中以客户端的方式实现负载均衡策略,从而透明地在多个服务实例之间分配请求。
1、Ribbon和Nginx负载均衡区别:
当后端服务是集群的情况下,前端页面调用后端请求,要做负载均衡的话,常用的就是Nginx。
Ribbon主要是在服务端内做负载均衡,举例:订单后端服务 要调用 支付后端服务,这属于后端之间的服务调用,压根根本不经过页面,而支付后端服务是集群,这时候订单服务就需要做负载均衡来调用支付服务,记住是订单服务做负载均衡 来调用 支付服务。
RabbitMQ消息处理流程
1、生产者发送:应用(生产者)发送消息到RabbitMQ服务器的一个Exchange(交换机),指定Routing Key(路由键)来指示消息应如何被路由。
2、交换机路由:Exchange根据Routing Key和自身类型(如Direct, Fanout, Topic等)规则,将消息路由到一个或多个Queue(队列)。
3、消息入队:消息被投递到对应的队列中存储,等待消费者处理。队列可以被配置为持久化,确保消息在服务器重启后仍能保留。
4、消费者订阅:应用(消费者)通过创建Channel(信道)订阅队列,准备接收消息。
5、消息分发与确认:RabbitMQ将队列中的消息分发给消费者,消费者处理后,通过ACK(确认)通知RabbitMQ消息已被成功处理,之后RabbitMQ可从队列中删除该消息。若未收到ACK且配置允许,RabbitMQ可能重发消息以确保消息至少被处理一次。
消息如何分发
1、生产者将消息发送至交换机,并指定路由键。
2、交换机依据类型(如直连、扇形、主题等)和路由键,决定将消息投递给哪些队列。
3、队列累积消息,等待消费者订阅。
4、消费者通过连接通道订阅队列,接收消息。
5、消息可采用轮询或公平分发等策略,由RabbitMQ分发给消费者。
6、消费者处理后,向RabbitMQ发送确认(ACK),确认后消息可从队列删除。
消息分发通常指的是消息如何从生产者(PubISner)发送到RabbitMQ服务器,并最终到达一个或多个队列的过程。
1.直接分发:生产者将消息直接发送到指定的队列中。
2.交换机分发:生产者将消息发送到交换机(Exchange),然后由交换机根据路由规则将消息路由到一个或多个队列。
消息路由是指消息在RabbitMQ内部的传递过程,这个过程涉及到交换机(Exchange)和队列(Queue)之间的绑定(Binding)关系。
1.路由键(Routing Key):当消息到达交换机时,通常会附带一个路由键。交换机根据这个路由键来决定如何将消息路由到队列。
2.绑定键(Binding Key):当队列绑定到交换机时,会指定一个绑定键。只有当消息的路由键与绑定键匹配时,消息才会被路由到该队列。
微服务框架的六种常用设计模式是什么
详解:https://blog.****.net/yeq2014/article/details/135734483
1.聚合器微服务设计模式
一种设计模式,用于通过聚合多个独立的微服务的响应来组成一个复杂的服务, 它可以是一个简单的Web页面,将检索到的数据进行处理展示。它也可以是一个更高层次的组合微服务,对检索到的数据增加业务逻辑后进一步发布成一个新的微服务,这符合DRY原则。
2.链式微服务设计模式
在此模式中,一个微服务的输出作为下一个微服务的输入,形成一个处理链。适合需要顺序执行多个服务操作的场景,每个步骤基于前一步的结果。
3.分支微服务设计模式
分支微服务设计模式是一种将复杂的业务逻辑拆解为多个微服务的架构设计模式。在该设计模式中,每个微服务负责处理不同的分支逻辑,即根据不同条件或参数的取值来执行不同的业务流程。
4.代理微服务设计模式
代理微服务设计模式是一种常用的微服务架构模式,用于提供对其他微服务的访问和控制。该模式的核心思想是通过引入代理服务来隐藏底层微服务的复杂性,并提供额外的功能和保护
5.异步消息传递微服务设计模式
异步消息传递微服务设计模式是一种架构模式,用于实现松耦合、高可扩展性和可靠性的微服务系统。在这种模式下,微服务之间通过消息队列或消息中间件进行通信,将消息作为传递机制,实现服务之间的解耦和异步通信。虽然REST设计模式非常流行,但它是同步的,会造成阻塞。
6.数据共享微服务设计模式
数据共享微服务设计模式是一种架构模式,旨在实现不同微服务之间有效地共享数据。在微服务架构中,每个微服务负责管理自己的数据,但有时候需要在多个微服务之间共享数据,这时候就需要使用数据共享微服务设计模式。
什么是TCP/IP和UDP
TCP/IP和UDP都是Internet协议套件中的传输层协议,负责在网络中端到端地传输数据。
1、TCP/IP (传输控制协议)
面向连接:在数据传输前,TCP要求建立一个连接,通过三次握手过程确保两端准备好通信。连接建立后,双方可以进行双向数据传输。
可靠性:TCP提供了高度的可靠性,通过序列号、确认应答、重传机制、错误校验以及流量控制等手段,确保数据正确无误、有序地到达目的地。
有序传输:TCP保证数据包按照发送顺序到达接收方,即使在网络中这些包可能以不同的顺序到达。
流控:TCP具有流量控制功能,可以防止发送方过快发送数据导致接收方无法处理,通过滑动窗口机制动态调整发送速率。
全双工:支持同时双向数据传输。
2、UDP (用户数据报协议)
无连接:UDP不建立连接,发送数据前无需握手过程,减少了延迟,但也不保证数据一定能到达对方。
不可靠:UDP不负责数据包的重传和错误校验,数据可能丢失、重复或乱序,适合对实时性要求高而对数据完整性要求较低的应用。
速度快:由于省去了建立连接和确认的过程,UDP的数据传输通常比TCP更快。
头部开销小:UDP头部只有8字节,而TCP头部至少20字节,这使得UDP在传输小数据包时更为高效。
多播和广播:UDP支持多播和广播,能够一次性向多个目标发送数据,适用于如实时音视频传输、DNS查询等场景。
应用场景:
1、TCP常用于需要高可靠性的应用,如Web浏览(HTTP/HTTPS)、电子邮件(SMTP/POP3/IMAP)、文件传输(FTP)、在线交易等。
2、UDP适用于对实时性要求较高、容许一定丢包的场景,如即时通讯、在线游戏、VoIP、视频流、DNS查询等。