Dubbo

作者: 技术灭霸 | 来源:发表于2020-04-25 23:48 被阅读0次

    1、如何自己设计一个类似dubbo的rpc框架?

    image.png

    可以从几方面去思考:
    1、服务订阅发布(注册中心)
    2、服务路由
    3、负载均衡(随机、轮询、最少活跃调用数、一致性哈希负载均衡)
    4、集群容错(失败重试、限流降级)
    5、服务调用(同步调用、异步调用、参数回调、事件通知)
    6、多协议
    7、序列化方式
    8、统一配置
    9、动态代理
    10、限流降级

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

    使用内存队列,强制排队来保证他们的顺序性

    3、分布式服务接口的幂等性如何设计?

    1、对于每个请求必须有一个唯一的标识
    2、每次处理完请求之后,必须有一个记录标识这个请求处理过了。常见的方案是在 mysql 中记录个状态
    3、每次接收请求需要进行判断,判断之前是否处理过。
    4、插入一条支付流水,order_id 建一个唯一键 unique key。你在支付一个订单之前,先插入一条支付流水
    5、写一个标识到 redis 里面,先查 redis有没有

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

    服务治理

    1. 调用链路自动生成
    2. 服务访问压力以及时长统计
    3. 服务分层(避免循环依赖)
    4. 调用链路失败监控和报警
    5. 每个服务的可用性的监控

    服务降级

    • 我们调用接口失败的时候,可以通过 mock 统一返回 null。
    • mock 的值也可以修改为 true,然后再跟接口同一个路径下实现一个 Mock 类,命名规则是 接口名称+Mock 后缀。然后在 Mock 类里实现自己的降级逻辑。

    失败重试和超时重试

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

    5、 dubbo 的 spi 思想是什么?

    spi 机制一般用在哪儿?插件扩展的场景,比如说你开发了一个给别人使用的开源框架,如果你想让别人自己写个插件,插到你的开源框架里面,从而扩展某个功能,这个时候 spi 思想就用上了。

    上面那行代码就是 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 注解,就是说那俩接口会被代理实现。

    dubbo动态代理策略
    默认使用 javassist 动态字节码生成,创建代理类。

    但是可以通过 spi 扩展机制配置自己的动态代理策略。

    6、ProtoBuf 和 XML的区别

    1. XML、JSON、ProtoBuf 都具有数据结构化和数据序列化的能力
    2. XML、JSON 更注重数据结构化,关注人类可读性和语义表达能力。ProtoBuf 更注重数据序列化,关注效率、空间、速度,人类可读性差,语义表达能力不足(为保证极致的效率,会舍弃一部分元信息)
    3. ProtoBuf 的应用场景更为明确,XML、JSON 的应用场景更为丰富。

    7、Dubbo的上下文RpcContext

    RpcContext 是一个 ThreadLocal 的临时状态记录器,当接收到 RPC 请求,或发起 RPC 请求时,RpcContext 的状态都会变化。如:方法名、参数类型、真实参数、本端/对端地址等。这些数据仅属于一次调用。
    比如:A调B,B再调C,则B机器上,在B调C之前,RpcContext记录的是A调B的信息,在B调C之后,RpcContext记录的是B调C的信息。

    消费端在执行Rpc调用之前,经过Filter处理, 会将信息写入RpcContext.见ConsumerContextFilter:
    服务端在执行调用之前,也会经过Filter处理,将信息写入RpcContext. 见ContextFilter类

    8、dubbo的限流与降级怎么实现的?

    1. dubbo的服务者与消费者 service的配置,最大连接数 与 请求数目配置
    2. dubbo的超时设置 + 配置mock 类。 请求超时后会执行mock,并返回
      3,dubbo可以通过扩展Filter的方式引入Hystrix,具体代码如下:https://github.com/yskgood/dubbo-hystrix-support

    9、如何解决Dubbo中生产者未启动,消费者启动报错

    在配置类中添加如下的信息就可以了,代码如下所示:

    /**
     * 消费者配置不主动监督zookeeper服务
     *
     * @return
     */
    @Bean
    public ConsumerConfig consumerConfig() {
       ConsumerConfig consumerConfig = new ConsumerConfig();
       consumerConfig.setCheck(false);
       consumerConfig.setTimeout(20000);
       return consumerConfig;
    }
    

    这样就可以了,不管是服务提供者还是服务消费者谁先启动,都可以通过@Reference实例化的对象。加上这个之后,测试环境终于没有出现500的null指针错误了。这边还有一点需要注意的是:很多时候服务提供者既是服务消费者,所以都得加上上面给出的代码。

    相关文章

      网友评论

          本文标题:Dubbo

          本文链接:https://www.haomeiwen.com/subject/dpcdihtx.html