中间件总结

2021/6/7 10:20:52

本文主要是介绍中间件总结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

中间件总结:

1.服务的远程调用:

gRPC:google的远程调用服务,使用http2.0协议传输二进制

dubbo:阿里的远程调用服务

简单理解:

为适应现在分布式,微服务应用开发,两台服务器上部署的不同应用之间的相互调用服务需要用到这部分的中间件;即服务器A发送请求参数--(序列化)-->(反序列化)调用服务器B的方法--(序列化)-->服务器A

其中序列化可以直接序列化为二进制,也可以通过protobuf进行序列化

2.注册中心

CAP

著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。在此Zookeeper保证的是CP, 而Eureka则是AP。

CAP分布式开发中有一个著名的CAP原理,C(一致性),A(可用性),P(分区容错性),这三者在开发中不可兼得,因此我们只能在A和C之间进行权衡。在此Zookeeper保证的是CP, 而Eureka则是AP。很容易的可以理解,如果要保证一致性,如zookeeper,需要选举leader的过程,并完成数据一致的同步,在这个过程中,zookeeper就是不可用的。一致性和可用性好理解,分布容错性是什么呢?所谓分布式容错性,就是在一个分布式集群中,一个节点崩溃,对整个分布式不会产生影响,又由于分区容错性是一个分布式系统所必须的条件,所以人们往往会在AC之间取舍。

注册中心原理

注册中心主要涉及到三大角色:
服务提供者
服务消费者
注册中心
它们之间的关系大致如下:
1、各个微服务在启动时,将自己的网络地址等信息注册到注册中心,注册中心存储这些数据。
2、服务消费者从注册中心查询服务提供者的地址,并通过该地址调用服务提供者的接口。
3、各个微服务与注册中心使用一定机制(例如心跳)通信。如果注册中心与某微服务长时间无法通信,就会注销该实例。
4、微服务网络地址发送变化(例如实例增加或IP变动等)时,会重新注册到注册中心。这样,服务消费者就无需人工修改提供者的网络地址了。

Zookeeper

核心--原子广播—Server之间的同步—。Zab协议:两种模式–》1.恢复模式(选主)2.广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复(选主)模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
补充:心跳检测能够监控服务的健康状况,同springcloud的Eureka服务器差不多功能.

ZooKeeper基于CP,不保证高可用,如果zookeeper正在选主,或者Zookeeper集群中半数以上机器不可用,那么将无法获得数据。Eureka基于AP,能保证高可用,即使所有机器都挂了,也能拿到本地缓存的数据。

作为注册中心,其实配置是不经常变动的,只有发版和机器出故障时会变。对于不经常变动的配置来说,CP是不合适的,而AP在遇到问题时可以用牺牲一致性来保证可用性,既返回旧数据,缓存数据。

所以理论上Eureka是更适合做注册中心。
而现实环境中大部分项目可能会使用ZooKeeper,那是因为集群不够大,并且基本不会遇到用做注册中心的机器一半以上都挂了的情况。所以实际上也没什么大问题。

3.消息中间件

为什么使用消息队列

核心的有 3 个:解耦、异步、削峰。

RabbitMq、ActiveMq、RocketMq、kafaka

如何保证消息队列消息不被重复消费
答案:一般消息队列都有自己的确认机制(正常情况下)。如果网络原因导致消费端没有确认到消息队列,也就是队列没有收到消息,那就导致了重复消费。

如何解决?

这个问题针对业务场景来答,分以下三种情况:
(1)比如,你拿到这个消息做数据库的insert操作,那就容易了,给这个消息做一个唯一的主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。
(2)再比如,你拿到这个消息做redis的set的操作,那就容易了,不用解决,因为你无论set几次结果都是一样的,set操作本来就算幂等操作。
(3)如果上面两种情况还不行,上大招。准备一个第三方介质,来做消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis.那消费者开始消费前,先去redis中查询有没有消费记录即可。

4.缓存

Redis

redis缓存击穿、穿透、雪崩

穿透:(布隆过滤)
什么是缓存穿透?怎么解决?
访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB【也不存在值】会挂掉。
解决方案:
(1)采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤;

(2)访问key未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间。

雪崩:(集群)
指:很多的key在同一时间失效了,导致DB访问激增

击穿:(互斥锁)
key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
当不存在时,暂时先别访问数据库,而是设置一个key(读的时候让其他的读的线程等待一定时间).然后再访问。或者设置热点数据

缓存的穿透,击穿,雪崩的策略:https://blog.csdn.net/zeb_perfect/article/details/54135506

布隆过滤器说明:是由n个hash函数和n个大小的二进制数组组成。原理:指由n个hash函数映射值在二进制数组上标记为1。也就是当数据量大的时候,会导致误判断的情况。怎么解决这个问题:使用白名单将肯能误判断的值记录下来。

布式锁的说明:使用官方推荐的Redisson来实现分布式锁,也具有续约的功能,原理是后台启动线程监控它的运行情况。实际上是采用的lua脚本来执行的。代码非常简单



这篇关于中间件总结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程