SpringCloud(26.分布式服务框架Dubbo面试题简析)

news2024/11/22 16:10:27

上一篇:25. 简述 Seata 的原理

下一篇:27. Redis 和 ZK 分布式锁

文章目录

  • 1. 为什么要将系统进行拆分?
  • 2. 如何进行系统拆分?
  • 3. 拆分后不用 dubbo 可以吗?
  • 4. dubbo 工作原理
  • 5. 注册中心挂了可以继续通信吗?
  • 6. dubbo 支持的序列化协议
  • 7. dubbo 支持不同的通信协议
  • 8. 说一下 Hessian 的数据结构
  • 9. dubbo 负载均衡策略
  • 10. dubbo 集群容错策略
  • 11. dubbo动态代理策略
  • 12. dubbo 的 spi 思想是什么?
    • 12.1 spi 是什么?
    • 12.2 dubbo 的 spi 思想
    • 12.3 如何自己扩展 dubbo 中的组件
  • 13. 如何基于 dubbo 进行服务治理、服务降级、失败重试以及超时重试?
    • 13.1 服务治理
    • 13.2 服务降级
    • 13.3 失败重试和超时重试
  • 14. 分布式服务接口的幂等性如何设计(比如不能重复扣款)?
  • 15. 分布式服务接口请求的顺序性如何保证?
  • 16. 如何自己设计一个类似 Dubbo 的 RPC 框架?

1. 为什么要将系统进行拆分?

  • 要是不拆分,一个大系统几十万行代码,20 个人维护一份代码,简直是悲剧啊。代码经常改着改着就冲突了,各种代码冲突和合并要处理,非常耗费时间;经常我改动了我的代码,你调用了我的,导致你的代码也得重新测试,麻烦的要死;然后每次发布都是几十万行代码的系统一起发布,大家得一起提心吊胆准备上线,几十万行代码的上线,可能每次上线都要做很多的检查,很多异常问题的处理,简直是又麻烦又痛苦;而且如果我现在打算把技术升级到最新的 spring 版本,还不行,因为这可能导致你的代码报错,我不敢随意乱改技术。

  • 拆分了以后,整个世界清爽了,几十万行代码的系统,拆分成 20 个服务,平均每个服务就 1~2 万行代码,每个服务部署到单独的机器上。20 个工程,20 个 git 代码仓库,20 个开发人员,每个人维护自己的那个服务就可以了,是自己独立的代码,跟别人没关系。再也没有代码冲突了,爽。每次就测试我自己的代码就可以了,爽。每次就发布我自己的一个小服务就可以了,爽。技术上想怎么升级就怎么升级,保持接口不变就可以了,真爽。

  • 所以简单来说,一句话总结,如果是那种代码量多达几十万行的中大型项目,团队里有几十个人,那么如果不拆分系统,开发效率极其低下,问题很多。但是拆分系统之后,每个人就负责自己的一小部分就好了,可以大幅度提升复杂系统大型团队的开发效率。

  • 但是同时,也要提醒的一点是,系统拆分成分布式系统之后,大量的分布式系统面临的问题也是接踵而来,所以后面的问题都是在围绕分布式系统带来的复杂技术挑战在说。

2. 如何进行系统拆分?

  • 系统拆分为分布式系统,拆成多个服务,拆成微服务的架构,是需要拆很多轮的。并不是说上来一个架构师一次就给拆好了,而以后都不用拆。
  • 大部分的系统,是要进行多轮拆分的,第一次拆分,可能就是将以前的多个模块该拆分开来了,比如说将电商系统拆分成订单系统、商品系统、采购系统、仓储系统、用户系统,等等吧。
  • 但是后面可能每个系统又变得越来越复杂了,比如说采购系统里面又分成了供应商管理系统、采购单管理系统,订单系统又拆分成了购物车系统、价格系统、订单管理系统。
  • 个人建议,一个服务的代码不要太多,1 万行左右,两三万撑死了吧。

3. 拆分后不用 dubbo 可以吗?

  • 当然可以了,大不了最次,就是各个系统之间,直接基于 spring mvc,就纯 http 接口互相通信呗,还能咋样。但是这个肯定是有问题的,因为 http 接口通信维护起来成本很高,你要考虑超时重试、负载均衡等等各种乱七八糟的问题,
  • 所以 dubbo 说白了,是一种 rpc 框架,就是说本地就是进行接口调用,但是 dubbo 会代理这个调用请求,跟远程机器网络通信,给你处理掉负载均衡、服务实例上下线自动感知、超时重试等等乱七八糟的问题。那你就不用自己做了,用 dubbo 就可以了。

4. dubbo 工作原理

Dubbo 分层:

  • 第一层:service 层,接口层,给服务提供者和消费者来实现的
  • 第二层:config 层,配置层,主要是对 dubbo 进行各种配置的
  • 第三层:proxy 层,服务代理层,无论是 consumer 还是 provider,dubbo 都会给你生成代理,代理之间进行网络通信
  • 第四层:registry 层,服务注册层,负责服务的注册与发现
  • 第五层:cluster 层,集群层,封装多个服务提供者的路由以及负载均衡,将多个实例组合成一个服务
  • 第六层:monitor 层,监控层,对 rpc 接口的调用次数和调用时间进行监控
  • 第七层:protocal 层,远程调用层,封装 rpc 调用
  • 第八层:exchange 层,信息交换层,封装请求响应模式,同步转异步
  • 第九层:transport 层,网络传输层,抽象 mina 和 netty 为统一接口
  • 第十层:serialize 层,数据序列化层

工作流程

  • 第一步:provider 向注册中心去注册
  • 第二步:consumer 从注册中心订阅服务,注册中心会通知 consumer 注册好的服务,consumer 会将 provider 的 IP 、端口号存在本地
  • 第三步:consumer 通过代理与 provider 的代理进行网络通信,此过程中,会利用集群层实现负载均衡,将请求均匀的分配给 provider
  • 第四步:consumer 和 provider 都异步通知监控中心
    在这里插入图片描述

5. 注册中心挂了可以继续通信吗?

可以,因为刚开始初始化的时候,消费者会将提供者的地址等信息拉取到本地缓存,所以注册中心挂了可以继续通信。

6. dubbo 支持的序列化协议

  • dubbo 支持 hessionJava 二进制序列化jsonSOAP 文本序列化多种序列化协议。
  • 但是 hessian 是其默认的序列化协议。
  • 序列化
    • 就是把数据结构或者是一些对象,转换为二进制串的过程,而反序列化是将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程
      在这里插入图片描述

7. dubbo 支持不同的通信协议

  • dubbo 协议

    • 默认就是走 dubbo 协议单一长连接,进行的是 NIO 异步通信,基于 hessian 作为序列化协议。

    • 使用的场景是:传输数据量小(每次请求在 100kb 以内),但是并发量很高。

    • 为了要支持高并发场景,一般是服务提供者就几台机器,但是服务消费者有上百台,可能每天调用量达到上亿次!此时用长连接是最合适的,就是跟每个服务消费者维持一个长连接就可以,可能总共就 100 个连接。然后后面直接基于长连接 NIO 异步通信,可以支撑高并发请求。

    • 长连接,通俗点说,就是建立连接过后可以持续发送请求,无须再建立连接。
      在这里插入图片描述

    • 而短连接,每次要发送请求之前,需要先重新建立一次连接。请求完成就断开连接。
      在这里插入图片描述

  • rmi 协议

    • 走 Java 二进制序列化,多个短连接,适合消费者和提供者数量差不多的情况,适用于文件的传输,一般较少用。
  • hessian 协议

    • 走 hessian 序列化协议,多个短连接,适用于提供者数量比消费者数量还多的情况,适用于文件的传输,一般较少用。
  • http 协议

    • 走 json 序列化。
  • webservice

    • 走 SOAP 文本序列化。

8. 说一下 Hessian 的数据结构

Hessian 的对象序列化机制有 8 种原始类型:

  • 原始二进制数据
  • boolean
  • 64-bit date(64 位毫秒值的日期)
  • 64-bit double
  • 32-bit int
  • 64-bit long
  • null
  • UTF-8 编码的 string

另外还包括 3 种递归类型:

  • list for lists and arrays
  • map for maps and dictionaries
  • object for objects

还有一种特殊的类型:

  • ref:用来表示对共享对象的引用。

9. dubbo 负载均衡策略

  • random loadbalance(默认)
    随机调用实现负载均衡,可以对 provider 不同实例设置不同的权重,会按照权重来负载均衡,权重越大分配流量越高,一般就用这个默认的就可以了。

  • roundrobin loadbalance
    这个的话默认就是均匀地将流量打到各个机器上去,但是如果各个机器的性能不一样,容易导致性能差的机器负载过高。所以此时需要调整权重,让性能差的机器承载权重小一些,流量少一些。

  • leastactive loadbalance
    这个就是自动感知一下,如果某个机器性能越差,那么接收的请求越少,越不活跃,此时就会给不活跃的性能差的机器更少的请求。

  • consistanthash loadbalance
    一致性 Hash 算法,相同参数的请求一定分发到一个 provider 上去,provider 挂掉的时候,会基于虚拟节点均匀分配剩余的流量,抖动不会太大。如果你需要的不是随机负载均衡,是要一类请求都到一个节点,那就走这个一致性 Hash 策略。

10. dubbo 集群容错策略

  • failover cluster 模式(默认)
    失败自动切换,自动重试其他机器,默认就是这个,常见于读操作。(失败重试其它机器)

    可以通过以下几种方式配置重试次数:

    <dubbo:service retries="2" />
    

    或者

    <dubbo:reference retries="2" />
    

    或者

    <dubbo:reference>
        <dubbo:method name="findFoo" retries="2" />
    </dubbo:reference>
    
  • failfast cluster 模式
    一次调用失败就立即失败,常见于非幂等性的写操作,比如新增一条记录(调用失败就立即失败)

  • failsafe cluster 模式
    出现异常时忽略掉,常用于不重要的接口调用,比如记录日志。

    配置示例如下:

    <dubbo:service cluster="failsafe" />
    

    或者

    <dubbo:reference cluster="failsafe" />
    
  • failback cluster 模式
    失败了后台自动记录请求,然后定时重发,比较适合于写消息队列这种。

  • forking cluster 模式
    并行调用多个 provider,只要一个成功就立即返回。常用于实时性要求比较高的读操作,但是会浪费更多的服务资源,可通过 forks=“2” 来设置最大并行数。

  • broadcacst cluster
    逐个调用所有的 provider。任何一个 provider 出错则报错(从2.1.0 版本开始支持)。通常用于通知所有提供者更新缓存或日志等本地资源信息。

11. dubbo动态代理策略

  • 默认使用 javassist 动态字节码生成,创建代理类。
  • 但是可以通过 spi 扩展机制配置自己的动态代理策略。

12. dubbo 的 spi 思想是什么?

12.1 spi 是什么?

  • spi,简单来说,就是 service provider interface
  • 说白了是什么意思呢,比如你有个接口,现在这个接口有 3 个实现类,那么在系统运行的时候对这个接口到底选择哪个实现类呢?这就需要 spi 了,需要根据指定的配置或者是默认的配置,去找到对应的实现类加载进来,然后用这个实现类的实例对象。

12.2 dubbo 的 spi 思想

  • dubbo 也用了 spi 思想,不过没有用 jdk 的 spi 机制,是自己实现的一套 spi 机制。

    Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
    
  • Protocol 接口,在系统运行的时候,dubbo 会判断一下应该选用这个 Protocol 接口的哪个实现类来实例化对象来使用。

  • 它会去找一个你配置的 Protocol,将你配置的 Protocol 实现类,加载到 jvm 中来,然后实例化对象,就用你的那个 Protocol 实现类就可以了。

  • 上面那行代码就是 dubbo 里大量使用的,就是对很多组件,都是保留一个接口和多个实现,然后在系统运行的时候动态根据配置去找到对应的实现类。如果你没配置,那就走默认的实现好了,没问题。

    @SPI("dubbo")  
    public interface Protocol {  
        int getDefaultPort();  
        @Adaptive  
        <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;  
        @Adaptive  
        <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;  
        void destroy();  
    }  
    
  • 在 dubbo 自己的 jar 里,在/META_INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol文件中:

    dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
    http=com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
    hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol

  • 所以说,这就看到了 dubbo 的 spi 机制默认是怎么玩儿的了,其实就是 Protocol 接口,@SPI("dubbo") 说的是,通过 SPI 机制来提供实现类,实现类是通过 dubbo 作为默认 key 去配置文件里找到的,配置文件名称与接口全限定名一样的,通过 dubbo 作为 key 可以找到默认的实现类就是 com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol

  • 如果想要动态替换掉默认的实现类,需要使用 @Adaptive 接口,Protocol 接口中,有两个方法加了 @Adaptive 注解,就是说那俩接口会被代理实现。

  • 啥意思呢?

  • 比如这个 Protocol 接口搞了俩 @Adaptive 注解标注了方法,在运行的时候会针对 Protocol 生成代理类,这个代理类的那俩方法里面会有代理代码,代理代码会在运行的时候动态根据 url 中的 protocol 来获取那个 key,默认是 dubbo,你也可以自己指定,你如果指定了别的 key,那么就会获取别的实现类的实例了。

12.3 如何自己扩展 dubbo 中的组件

  • 自己写个工程,要是那种可以打成 jar 包的,里面的 src/main/resources 目录下,搞一个 META-INF/services,里面放个文件叫:com.alibaba.dubbo.rpc.Protocol,文件里搞一个my=com.bingo.MyProtocol。自己把 jar 弄到 nexus 私服里去。

  • 然后自己搞一个 dubbo provider 工程,在这个工程里面依赖你自己搞的那个 jar,然后在 spring 配置文件里给个配置:

    <dubbo:protocol name=”my” port=”20000” />
    
  • provider 启动的时候,就会加载到我们 jar 包里的my=com.bingo.MyProtocol 这行配置里,接着会根据你的配置使用你定义好的 MyProtocol 了,这个就是简单说明一下,你通过上述方式,可以替换掉大量的 dubbo 内部的组件,就是扔个你自己的 jar 包,然后配置一下即可。
    在这里插入图片描述

  • 更多配置查看官方文档:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/

13. 如何基于 dubbo 进行服务治理、服务降级、失败重试以及超时重试?

13.1 服务治理

  • 服务治理大致需要做到以下几点

1. 调用链路自动生成

  • 一个大型的分布式系统,或者说是用现在流行的微服务架构来说吧,分布式系统由大量的服务组成。那么这些服务之间互相是如何调用的?调用链路是啥?说实话,几乎到后面没人搞的清楚了,因为服务实在太多了,可能几百个甚至几千个服务。
  • 那就需要基于 dubbo 做的分布式系统中,对各个服务之间的调用自动记录下来,然后自动将各个服务之间的依赖关系和调用链路生成出来,做成一张图,显示出来,大家才可以看到对吧。
    在这里插入图片描述

2. 服务访问压力以及时长统计

  • 需要自动统计各个接口和服务之间的调用次数以及访问延时,而且要分成两个级别。

    • 一个级别是接口粒度,就是每个服务的每个接口每天被调用多少次,TP50/TP90/TP99,三个档次的请求延时分别是多少;
    • 第二个级别是从源头入口开始,一个完整的请求链路经过几十个服务之后,完成一次请求,每天全链路走多少次,全链路请求延时的 TP50/TP90/TP99,分别是多少。
  • 这些东西都搞定了之后,后面才可以来看当前系统的压力主要在哪里,如何来扩容和优化啊。

3. 其它

  • 服务分层(避免循环依赖)
  • 调用链路失败监控和报警
  • 服务鉴权
  • 每个服务的可用性的监控(接口调用成功率?几个 9?99.99%,99.9%,99%)

13.2 服务降级

  • 比如说服务 A 调用服务 B,结果服务 B 挂掉了,服务 A 重试几次调用服务 B,还是不行,那么直接降级,走一个备用的逻辑,给用户返回响应。

13.3 失败重试和超时重试

  • 所谓失败重试,就是 consumer 调用 provider 要是失败了,比如抛异常了,此时应该是可以重试的,或者调用超时了也可以重试。配置如下:

    <dubbo:reference id="xxxx" interface="xx" check="true" async="false" retries="3" timeout="2000"/>
    
  • 一般来说这两个字段值这样设置:

    • timeout:一般设置为 200ms,我们认为不能超过 200ms 还没返回。
    • retries:设置 retries,一般是在读请求的时候,比如你要查询个数据,你可以设置个 retries,如果第一次没读到,报错,重试指定的次数,尝试再次读取。

14. 分布式服务接口的幂等性如何设计(比如不能重复扣款)?

  • 这个不是技术问题,这个没有通用的一个方法,这个应该结合业务来保证幂等性。

  • 所谓幂等性,就是说一个接口,多次发起同一个请求,你这个接口得保证结果是准确的,比如不能多扣款、不能多插入一条数据、不能将统计值多加了 1。这就是幂等性。

  • 其实保证幂等性主要是三点:

    • 对于每个请求必须有一个唯一的标识,举个栗子:订单支付请求,肯定得包含订单 id,一个订单 id 最多支付一次,对吧。
    • 每次处理完请求之后,必须有一个记录标识这个请求处理过了。常见的方案是在 mysql 中记录个状态啥的,比如支付之前记录一条这个订单的支付流水。
    • 每次接收请求需要进行判断,判断之前是否处理过。比如说,如果有一个订单已经支付了,就已经有了一条支付流水,那么如果重复发送这个请求,则此时先插入支付流水,orderId 已经存在了,唯一键约束生效,报错插入不进去的。然后你就不用再扣款了。
  • 实际运作过程中,你要结合自己的业务来,比如说利用 redis,用 orderId 作为唯一键。只有成功插入这个支付流水,才可以执行实际的支付扣款。

  • 要求是支付一个订单,必须插入一条支付流水,order_id 建一个唯一键 unique key。你在支付一个订单之前,先插入一条支付流水,order_id 就已经进去了。你就可以写一个标识到 redis 里面去,set order_id payed,下一次重复请求过来了,先查 redis 的 order_id 对应的 value,如果是 payed 就说明已经支付过了,你就别重复支付了。

15. 分布式服务接口请求的顺序性如何保证?

  • 首先,一般来说,个人建议是,你们从业务逻辑上设计的这个系统最好是不需要这种顺序性的保证,因为一旦引入顺序性保障,比如使用分布式锁,会导致系统复杂度上升,而且会带来效率低下,热点数据压力过大等问题。

  • 下面提供两个方案吧

1. 使用 Hash 分发 + 队列

  • 简单来说,首先你得用 dubbo 的一致性 hash 负载均衡策略,将比如某一个订单 id 对应的请求都给分发到某个机器上去,接着就是在那个机器上,因为可能还是多线程并发执行的,你可能得立即将某个订单 id 对应的请求扔一个内存队列里去,强制排队,这样来确保他们的顺序性。
    在这里插入图片描述
  • 但是这样引发的后续问题就很多,比如说要是某个订单对应的请求特别多,造成某台机器成热点怎么办?解决这些问题又要开启后续一连串的复杂技术方案…曾经这类问题弄的我们头疼不已,所以,还是建议什么呢?
  • 最好是,一个订单的插入和删除操作,能不能合并成一个操作,就是一个删除,或者是其它什么,避免这种问题的产生。

2. 分布式锁

  • 在前端向后端发送请求时,不但要加上唯一键,还要加上当前请求需要排在第几个执行
  • 当请求发送到不同的机器上后,这些机器开始争抢锁,抢到锁后,先判断一下自己前面的任务有没有执行,若没有执行则释放锁,让其他线程继续枪锁;若执行过了,则继续执行当前操作

在这里插入图片描述

16. 如何自己设计一个类似 Dubbo 的 RPC 框架?

  • 其实问到你这问题,你起码不能认怂,因为是知识的扫盲,那我不可能给你深入讲解什么 kafka 源码剖析,dubbo 源码剖析,何况我就算讲了,你要真的消化理解和吸收,起码个把月以后了。

  • 所以我给大家一个建议,遇到这类问题,起码从你了解的类似框架的原理入手,自己说说参照 dubbo 的原理,你来设计一下,举个例子,dubbo 不是有那么多分层么?而且每个分层是干啥的,你大概是不是知道?那就按照这个思路大致说一下吧,起码你不能懵逼,要比那些上来就懵,啥也说不出来的人要好一些。

  • 举个栗子,我给大家说个最简单的回答思路:

    • 上来你的服务就得去注册中心注册吧,你是不是得有个注册中心,保留各个服务的信息,可以用 zookeeper 来做,对吧。
    • 然后你的消费者需要去注册中心拿对应的服务信息吧,对吧,而且每个服务可能会存在于多台机器上。
    • 接着你就该发起一次请求了,咋发起?当然是基于动态代理了,你面向接口获取到一个动态代理, 这个动态代理就是接口在本地的一个代理,然后这个代理会找到服务对应的机器地址。
    • 然后找哪个机器发送请求?那肯定得有个负载均衡算法了,比如最简单的可以随机轮询是不是。
    • 接着找到一台机器,就可以跟它发送请求了,第一个问题咋发送?你可以说用 netty 了,nio 方式;第二个问题发送啥格式数据?你可以说用 hessian 序列化协议了,或者是别的,对吧。然后请求过去了。
    • 服务器那边一样的,需要针对你自己的服务生成一个动态代理,监听某个网络端口了,然后代理你本地的服务代码。接收到请求的时候,就调用对应的服务代码,对吧。
  • 这就是一个最最基本的 rpc 框架的思路,先不说你有多牛逼的技术功底,哪怕这个最简单的思路你先给出来行不行?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/540089.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Drone】ubuntu 20.x 版本下 通过docker-compose方式部署drone的全流程 整合gitee

一、前期准备 1、ubuntu环境 确定是否具有 ssh&#xff1a; service ssh start&#xff0c;如果没有&#xff0c;使用&#xff1a;apt install openssh-server 进行安装查看 Linux 的 IP 地址&#xff1a; ifconfig&#xff0c;命令不可用时&#xff0c;通过&#xff1a;apt …

pdf太大,怎么压缩的小一点,这几个方法高效便捷

pdf太大&#xff0c;怎么压缩的小一点呢&#xff1f;我们在日常办公中&#xff0c;使用到pdf文件的情况很多。因为pdf文件可以在几乎所有操作系统和设备上打开&#xff0c;这使得它们非常方便。而且PDF 文件的内容和格式在不同设备之间始终保持一致&#xff0c;这意味着无论在哪…

PowerShell install 一键部署virtualbox

VirtualBox 前言 VirtualBox 是一款开源虚拟机软件。VirtualBox 是由德国 Innotek 公司开发&#xff0c;由Sun Microsystems公司出品的软件&#xff0c;使用Qt编写&#xff0c;在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。Innotek 以 GNU General Public Licens…

优思学院|什么是8D报告?

企业中的问题&#xff0c;就像生活中的麻烦事&#xff0c;总是层出不穷&#xff0c;让人头疼不已。有时候&#xff0c;我们可能会遇到一些棘手的问题&#xff0c;简单的方法已经无法解决了&#xff0c;这时候&#xff0c;8D问题解决法就是一把利器。 所以&#xff0c;我们不应…

档案室库房十防要求及措施

档案室“十防”措施 根据档案保护技术的要求&#xff0c;结合本公司档案实际&#xff0c;现制定“十防”措施如下&#xff1a; 一、 防火 1、 指定专人负责防火安全工作。 2、 定期检查手动灭火器&#xff0c;发现灭火器表压低于绿色区域时&#xff0c;必须及重新充装。 3、…

Consule系列:Consul实现详解

Consul 的实现 Consul 使用 Consensus 协议提供一致性(Consistency)—— CAP 定义的一致性。Consensus 协议是基于 “Raft: In search of an Understandable Consensus Algorithm” 实现的。 Consul Protocol Raft 算法 Raft 是基于 Paxos 的一致性算法。 与 Paxos 相比&#x…

Java每日一练(20230518) 移除元素、跳跃游戏II、复原IP地址

目录 1. 移除链表元素 &#x1f31f; 2. 跳跃游戏 II &#x1f31f;&#x1f31f; 3. 复原 IP 地址 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 移…

在 Mac M2 (arm64架构)上编译安装 GmSSL 工具

GmSSL是一个开源密码工具包&#xff0c;为GM/T系列标准中规定的中国国家密码算法和协议提供一级支持。作为OpenSSL项目的一个分支&#xff0c;GmSSL提供了与OpenSSL的API级兼容性&#xff0c;并维护了所有功能。现有的项目&#xff0c;如ApacheWeb服务器&#xff0c;只需稍加修…

前端面试题整理3

目录 1.不使用promise怎么实现一个异步编程? 2.this的指向有哪些&#xff1f; 3.Ref和reactive响应式的区别&#xff1f; 4.首屏加载优化。如何处理&#xff1f; 5.axios封装&#xff1f; 6.css为什么使用预处理&#xff1f; 7.从1000-9999里面取出AAAA这种数字&#xf…

从价格战中突围,仅10个月开发出一款车,安全性能靠谱吗?

经历了2023年初的价格战&#xff0c;一场关于智能汽车的淘汰赛似乎正式开始了。 尽管“降价热潮”还在继续&#xff0c;但简单的价格竞争毕竟非长久良策。 一方面&#xff0c;为了维持收益&#xff0c;部分车企通过减配、降低服务成本&#xff0c;甚至将降本压力给到上游供应…

【这个命令的 7 种用法!你确定不会用?】

可以很肯定地说&#xff0c;find 命令是 Linux 后台开发人员必须熟知的操作之一&#xff0c;除非您使用的是 Windows Server。 对于技术面试&#xff0c;它也是一个热门话题。让我们看一道真题&#xff1a; 如果你的 Linux 服务器上有一个名为 logs 的目录&#xff0c;如何删…

Spring 事务和事务传播机制

1.什么是事务&#xff08;为什么要有事务&#xff09; 事务就是将一组操作封装成一个执行单元&#xff08;封装到一起&#xff09;&#xff0c;要么一起成功&#xff0c;要么一起失败。 在打账的情景上&#xff0c;A向B转账200 元&#xff0c;A的账户-200.B的账号200&#xff…

基于直流微电网的光伏并网功率转换装置设计与运行仿真

摘要 微电网是目前国内外应用较为广泛的一种绿色可再生能源&#xff0c;近几年我国微电网产业的发展十分迅速。然后&#xff0c;越来越多的微电网系统建立并网&#xff0c;微电网产生的电能受外界因素影响较大&#xff0c;具有一定的随机性和波动性&#xff0c;给并网后的电力系…

SaaS 产品如何选择设计协作工具?

文章内容转载腾讯 CoDesign 随着互联网及其衍生技术的发展&#xff0c;企业比以往更依赖内容去吸引、去培养自己的用户&#xff0c;寻求转化。小鹅通就是在微信生态中帮助企业通过知识服务去实现内容分发和流量聚合&#xff0c;帮助企业沉淀用户&#xff0c;提供深度私域运营服…

回收站清空了怎么找回文件?3种办法恢复彻底删除文件!

电脑回收站大家都有一定的了解&#xff0c;只要在回收站的文件没有被删除的时候是可以还原的&#xff0c;但是回收站删除了&#xff0c;文件就无法直接恢复。回收站清空了怎么找回文件? 别着急&#xff0c;今天小编就分析几种恢复回收站删除数据的办法&#xff1a; 方法一&am…

(转载)从0开始学matlab(第8天)—matlab画图入门

1.基本画图方式 MATLAB 的扩展性和机制独立的画图功能是一个极其重要的功能.这个功能使数据画图变得十分简单 . 画一个数据图 , 首先要创建两个向量&#xff0c;由 x, y 构成 , 然后使用 plot 函数. 例如 , 假设我们要画出函数 yx -10x10 的图象 , 定义域为&#xff3b; …

分享两组不同的3D VR卡片

最近某音上出现了很多VR视频&#xff0c;转动手机可以看到手机界面未显示出来的场景。这种事情我觉得我们也可以做到。 所以两种不同的3D VR卡片来了&#xff1a; 第一种是横向或上下可以拖动极大的距离。卡片上的信息会随着拖动移动&#xff0c;但不会显示更多的信息&#x…

二、LLC 谐振变换器

半桥 LLC 谐振变换器主电路结构 如图所示&#xff0c;半桥 LLC 谐振变换器主电路可以分为四个部分&#xff0c;即&#xff1a;逆变网络、谐振网络、变压器及整流滤波网络。两个 MOSFET&#xff08;S1、S2&#xff09;以及它们的体二极管&#xff08;D1、D2&#xff09;和寄生电…

svn清理以下路径失败显示乱码问题

报错&#xff1a; svn作为我们经常使用的版本管理服务器&#xff0c;在使用过程中经常需要通过clean up操作来完成本地文件与服务器文件信息及版本信息同步&#xff0c; 然而有时右键会在执行清理命令时提示“清理以下路径失败&#xff1a; xxx 文件名、目录名或卷标语法不…

DevOps 的道术法器,探寻 DevOps “立体化”实践之旅

​引言 随着业务的发展&#xff0c;软件发布迭代的频率越来越高&#xff0c;传统的瀑布型模式已经不能满足快速交付的需求&#xff0c;DevOps 也因此受到持续关注。越来越多的公司开始接受并尝试使用 DevOps&#xff0c;期望能使得软件开发中的构建、测试与发布工作变得更加快捷…