Dubbo
阿飞Sirx
追求自我,超越自我
展开
-
Dubbo构造调用链源码
//保存引用,后续用于把真正的调用者保存到过滤器链的最后Invoker<T> last = invoker;List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.gerUrl(),key,group);if(!filters.isEmpty()){ for(int i = filters.size();i>=0;i--)原创 2022-01-04 18:55:53 · 224 阅读 · 0 评论 -
Dubbo的服务端上下文的获取和使用
public class DemoServiceImpl implements DemoService{ public void hello(){ //判断是否为服务端 boolean isProviderSide = RpcContext.getContext().isProviderSide(); //获取当前服务配置信息,所有配置信息都将转化为url参数 String clientIp = RpcContext.getContext().getRemoteH原创 2022-01-04 16:19:30 · 1063 阅读 · 0 评论 -
Dubbo的异步回调服务端实现
public interface CallbackService{ void addListener(String key,CallbackListener listener);}public interface CallbackListener{ void changed(String msg);}public class CallbackServiceImpl implements CallbackService{ private final Map<String,Call原创 2022-01-04 16:08:50 · 920 阅读 · 0 评论 -
Dubbo的高级特性汇总
1.服务分组和版本支持同一个服务有多个分组和多个版本,用于服务强制隔离,服务多个版本实现2.参数回调当消费方调用服务提供时,支持服务提供方能够异步回调到当前消费方,用于stub做热数据缓存3.隐士参数支持客户端隐士传递参数到服务端4.异步调用并行发起多个请求,但只使用一个线程,用于业务请求非阻塞场景5.上下文信息上下文中存放的是当前调用过程中所需要的环境信息6.结果缓存结果缓存,用于加速热门数据的访问速度,Dubbo提供声明式缓存,以减少用户加缓存的工作量...原创 2022-01-04 15:45:23 · 392 阅读 · 0 评论 -
Dubbo的Registry层扩展点
Registry层可以理解为注册层,这一层中最重要的扩展点就是org.apache.dubbo.registry.RegistryFactory.整个框架的注册与服务发现都是由这个扩展点负责创建的。该扩展点有@Adaptive({“protocol”})注解,可以根据URL中的protocol参数创建不同的注册中心客户端。例如protocol=redis,该工厂会创建基于redis的注册中心客户端。因此,如果我们扩展了自定义的注册中心,那么只需要配置不同的protocol即可@SPI("dubbo")原创 2022-01-04 14:38:44 · 1460 阅读 · 0 评论 -
Dubbo的ProxyFactory接口
@SPI("javaassist")public interface ProxyFactory{ @Adaptive({Constants.PROXY_KEY}) <T> T getProxy(Invoker<T> invoker) throws RpcException; @Adaptive({Constants.PROXY_KEY}) <T> T getProxy(Invoker<T> invoker,boolean generic)原创 2022-01-04 14:31:52 · 99 阅读 · 0 评论 -
Dubbo种的Mock用法
在cluster中,具有MockClusterWrapper,由它实现了Dubbo的本地伪装。这个功能的使用场景较多,通常用于以下两种场景:1.服务降级,部分非关键服务全部不可用,希望主流程继续进行2.在下游某些节点调用异常时,可以用Mock结果返回配置方式//文件中配置<dubbo:reference interface="com.foo.BarService" mock="true" /><dubbo:reference interface="com.foo.BarSer原创 2021-12-30 20:50:51 · 1423 阅读 · 0 评论 -
Dubbo的merger实现
当一个接口有多个实现,消费者又需要同时引用不同的实现时,可以用group来区分不同的实现<dubbo:service group=“group1” interface=“com.xxx.testService” /><dubbo:service group=“group2” interface=“com.xxx.testService” />如果我们需要并行调用不同的group服务,并且要把结果集合起来,则需要用到Merger特性,merger实现了多个服务调用后结果合并的逻原创 2021-12-29 14:46:49 · 291 阅读 · 0 评论 -
Dubbo的一致性hash负载均衡
一致性hash负载均衡可以让参数相同的请求每次都陆由到相同的机器上。这种负载均衡的方式可以让请求相对平均,相比直接使用hash而言,当某些节点下线时,请求会平均到其他服务提供者。普通一致性hash会把每个服务节点散列到环形上,然后把请求的客户端散列到环上,顺时针往前找第一个节点就是要调用的节点。普通一致性hash也有一定的局限性,它的散列不一定均匀,容易造成某些节点压力大。因此Dubbo框架使用了优化过的ketama一致性hash,这种算法会为每个真实节点创建多个虚拟节点,让节点分配更均匀一致性has原创 2021-12-29 14:28:51 · 700 阅读 · 0 评论 -
Dubbo的LeastActive负载均衡
LeastActive负载均衡称为最少活跃调用数负载均衡,即框架会记下每一个invoker的活跃数,每次只从活跃数最少的invoker里选择一个节点...for(int i = 0;i<length;i++){ ... //获得invoker的活跃数、预热权重 if(leastActive == -1 || active < leastAcive){ //发现有更小的活跃数,这里置空之前的计数 ... }else if(active == leastActiv原创 2021-12-28 15:05:56 · 568 阅读 · 0 评论 -
Dubbo的RoundRobin负载均衡
Dubbo的轮询负载均衡现在采用的平滑权重轮询如下是RoundBin负载均衡的步骤(1)初始化权重缓存Map,以每个Invoker的URL为key,权重对象为value,生成ConcurrentMap,并把这个Map保存到全局的methodWeightMap中,ConcurrentMap<String,ConcurrentMap<String,WeightedRoundRobin>> methodWeightMap.methodWeightMap的key是每个接口的方法名,这一步原创 2021-12-27 16:58:33 · 552 阅读 · 0 评论 -
Dubbo的Random负载均衡
Random负载均衡是按照权重设置随机概率做负载均衡的。这种负载均衡算法并不能精确地平均请求,但是随着请求数量的增加,最终结果是大致平均的。计算步骤如下1.计算总权重并判断每个Invoker的权重是否一样。遍历整个Invoker列表,求和总权重。遍历过程中,会对比每个Invoker的权重,判断所有Invoker的权重是否相同2.如果权重相同,则说明每个Invoker的概率都一样,因此直接用nextInt随机选一个Invoker返回即可3.如果权重不同,则首先得到偏移值,然后根据偏移值找到对应的Invo原创 2021-12-26 19:22:40 · 326 阅读 · 0 评论 -
Dubbo的负载均衡结构
Dubbo现在内置了4种负载均衡算法,用户也可以自行扩展,LoadBalance接口上有@SPI注解@SPI(RandomLoadBalance.NAME)public interface LoadBalance{ @Adaptive("loadbalance") <T> Invoker<T> select(List<> invokers,URL url,Invocation invocation) throws RpcException;}从代码中我们原创 2021-12-25 12:40:10 · 462 阅读 · 0 评论 -
Dubbo负载均衡的总流程
在整个集群容错的流程中,首先经过Directory获取所有的Invoker列表,然后经过Router根据路由规则过滤Invoker,最后幸存下来的Invoker还需要经过负载均衡这一关,选出最终要调用的Invoker包装的负载均衡负载均衡获取可用的服务实际是调用了AbstractClusterInvoker中定义的Invoker select方法,而不是直接使用LoadBalance方法。因为抽象父类在LoadBalance的基础上又封装了一些新特性粘滞连接 Dubbo中有一种特性叫粘滞连接粘原创 2021-12-24 14:38:41 · 333 阅读 · 0 评论 -
Dubbo的failback策略
Failback如果调用失败,则会定期重试。FailbackClusterInvoker里面定义了一个ConcurrentHashMap,专门用来保存失败的调用。定外定义了一个线程池,默认每5秒把所有失败的调用拿出来,重试一次。如果调用重试成功,则会从ConcurrentHashMap中移除,doInvoke的调用逻辑如下:1.首先校验传入的参数。校验从AbstractClusterInvoker传入的Invoker列表是否为空。2.负载均衡调用select方法做负载均衡,得到要调用的节点。3.远程原创 2021-12-20 15:58:47 · 402 阅读 · 0 评论 -
Dubbo的failsafe容错策略
Failsafe调用时如果出现异常,则会直接忽略,实现也很简单,流程如下:1.校验传入的参数,校验从AbstractClusterInvoker传入的Invoker列表是否为空2.负载均衡。调用select方法做负载均衡,得到要调用的节点3.远程调用。在try代码块中调用invoker#invoke方法做远程调用,catch到任何异常都直接吞掉,返回一个空的结果集failsafe调用源码:public Result doInvoke(Invocation invocation,List<In原创 2021-12-19 16:37:48 · 377 阅读 · 0 评论 -
Dubbo的Failover策略
Cluster接口上有SPI注解@SPI(FailoverCluster.NAME),既默认实现是Failover,该策略的代码逻辑如下:(1)校验。校验从AbstractClusterInvoker传入的Invoker列表是否为空(2)获取配置参数。从调用URL中获取对应的retries重试次数(3)初始化一些集合和对象。用于保存调用过程中出现的异常、记录调用了哪些节点(4)使用for循环实现重试,for循环的次数就是重试的次数。成功则返回,否则继续循环。如果for循环完,还没有一个成功的返回,则原创 2021-12-18 15:48:16 · 645 阅读 · 0 评论 -
Dubbo容错机制
Dubbo容错机制能增强整个应用的健壮性,容错过程对上层用户是完全透明的,但用户也可以通过不同的配置来选择不同的容错机制。每种容错机制又有自己的个性化配置项。Dubbo中现有failover,failfast,failback,failsafe,forking,broadcast,mock,available,mergeable实现1.Failover当出现失败时,会重试其他服务器,用户可以通过retries=2设置重试次数,这是dubbo的默认容错机制,会对请求做负载均衡。通常使用在读操作和幂等的写操原创 2021-12-17 16:26:38 · 2211 阅读 · 0 评论 -
Dubbo集群容错的整体流程
1.生成Invoker对象,不同的Cluster实现会生成不同类型的ClusterInvoker对象并返回,然后调用ClusterInvoker的Invoker方法,正式开始调用流程。2.获得可调用的服务列表。首先会做前置校验,检查远程服务是否已经销毁,然后通过Directory#list方法获取所有可用的服务列表。接着使用router接口处理该服务列表,根据路由规则过滤掉一部分服务,并最终返回可用服务列表3.做负载均衡,在第二部中得到的服务列表还要通过不同的负载均衡策略选出一个服务,用作最后的调用。首原创 2021-12-16 15:01:17 · 203 阅读 · 0 评论 -
Dubbo心跳逻辑处理
Dubbo默认客户端和服务器端都会发送心跳报文,用来保持TCP长连接状态。在客户端和服务端,Dubbo内部开启一个线程循环扫描并检测连接是否超时,在服务端如果发现超时则会主动关闭客户端连接,在客户端发现超时则会主动重新创建连接。默认心跳检测60s,具体应用可以通过heartbeat配置Dubbo在服务端和客户端都复用心跳实现代码,抽象成HeartBeatTask任务进行处理@Overridepublic void run(){ try{ long now = Systtem.current原创 2021-12-15 18:16:01 · 1654 阅读 · 0 评论 -
Dubbo的RPC调用流程
首先在客户端启动时会从注册中心拉去和订阅对应的服务列表,Cluster会把拉取到的服务列表聚合成一个cluster,每次RPC调用前会通过Directory#list获取providers地址(已经生成好的invoker列表),获取这些服务列表给后续路由和负载均衡使用,框架内部另外一个实现Directory接口是RegistryDirectory类,它和接口名是一对一的关系,主要负责拉取和订阅服务提供者,动态配置和路由项在dubbo发起服务调用时,所有路由和负载均衡都是在客户端实现的,客户端服务调用会先.原创 2021-12-07 20:10:14 · 1579 阅读 · 0 评论 -
Dubbo优雅停机原理解析
优雅停机特性是所有RPC框架中非常重要的特性之一,因为核心业务在服务器中正在执行时突然中断可能会出现严重后果Dubbo中实现的优雅停机机制主要包含6个步骤:(1)收到kill 9 进程退出信号,Spring容器会触发容器销毁事件。(2)provider端会取消注册服务元数据信息(3)consumer端会收到最新地址列表,不包含准备停机的地址(4)Dubbo协议会发送readonly事件报文通知consumer服务不可用(5)服务端等待已经执行的任务结束并拒绝新任务执行...原创 2021-12-06 21:34:47 · 315 阅读 · 0 评论 -
Dubbo直连服务消费原理
Dubbo可以绕过注册中心直接向指定服务(直接指定目标IP和端口)发起RPC调用,使用直连模式可以方便在某些场景下使用,比如压测指定机器等,Dubbo框架也支持同时指定直连多台机器进行服务调用//直连服务消费private T createProxy(Map<String,String> map){ ... if(url != null && url.length() > 0){ String[] us = Constants.SEMICOLON_SPL原创 2021-12-06 21:23:51 · 159 阅读 · 0 评论 -
Dubbo远程服务的暴露机制(二)
注册中心在做服务暴露时依次做了以下几件事情:1.委托具体协议进行服务暴露,创建NettyServer监听端口和保存服务实例2.创建注册中心对象,与注册中心创建TcP连接3.注册服务元数据到注册中心4.订阅configurators节点,监听服务动态属性变更事件5.服务销毁收尾工作,比如关闭端口,反注册服务...原创 2021-12-04 16:50:57 · 1316 阅读 · 0 评论 -
Dubbo远程服务的暴露机制(一)
整体上看,Dubbo框架作服务暴露分为两部分,第一步,将持有的服务实例通过代理转化成Invoker,第二步会把invoker通过具体的协议转化成Exporter,框架做了这层抽象也大大方便了扩展。Dubbo支持多注册中心同时写,如果配置了多个注册中心,则会在ServiceConfig#doExportUrls中依次暴露private void doExportUrls(){ //获取当前服务对应的注册中心实例 List<URL> registryURLs = loadReg.原创 2021-12-02 20:10:41 · 1242 阅读 · 0 评论 -
Dubbo的配置信息承载初始化优先级
不管在服务暴露还是服务消费场景下,Dubbo框架都会根据优先级对配置信息做聚合处理,目前默认配置策略遵循以下原则:(1)-D传递给JVM参数优先级最高,比如-Ddubbo.protocol.port=20880(2) 代码或XML配置优先级次高,比如Spring的XML文件,指定<dubbo:protocol port=20880>(3)配置文件优先级最低,比如dubbo.properties文件指定dubbo.protocol.port=20880一般推荐使用dubbo.prope原创 2021-12-02 19:54:34 · 207 阅读 · 0 评论 -
Dubbo的SPI用例
1.在META-INF/dubbo/internal下建立配置文件com.test.spi.PrintService文件内容:impl = com.test.spi.PrintServiceImpl@SPI("impl")public interface PrintService{ void printInfo();}public class PrintServiceImpl implements PrintServcie{ @Override public void prin原创 2021-11-25 22:08:37 · 416 阅读 · 0 评论 -
Dubbo注册中心的工作流程
服务提供者启动时,会向注册中心写入自己的元数据信息,同时会订阅配置元数据信息消费者启动时,也会向注册中心写入自己的元数据信息,并订阅服务提供者,配置元数据信息和路由服务治理中心(dubbo-admin)启动时,会同时订阅所有消费者,服务提供者,路由和配置元数据信息当有服务提供者离开或者新的服务提供者加入时,注册中心服务提供者目录会发生变化,同时变化信息会动态通知给消费者,服务治理中心当消费方发起服务调用时,会异步将调用,统计信息等上报给监控中心(dubbo-monitor-simple)..原创 2021-11-21 12:06:15 · 1245 阅读 · 0 评论 -
基于Api实现dubbo简例
Providerpublic class EchoProvider{ public static void main() throws Exception{ ServiceConfig<EchoService> service = new ServiceConfig<>(); service.setApplication(new ApplicationConfig("java-echo-provider")); service.原创 2021-11-20 19:52:11 · 1414 阅读 · 0 评论 -
基于注解实现dubbo简例
服务端1.基于注解标记服务//使用servcie注解后,由dubbo将这个实现类提升为spring容器管理的bean,并且负责配置初始化和服务暴露@Servicepublic class EchoServiceImpl implements EchoService{ public String echo(String msg){ return msg; }}2.注解方式生成du bbo配置信息public class AnnotationProvider{原创 2021-11-20 19:21:13 · 1190 阅读 · 0 评论 -
基于XML实现Dubbo简例
##服务端dubbo框架是面向接口的rpc调用框架,需要提供接口EchoService来作为服务暴露使用1.接口定义public interface EchoService{ String echo(String message);}public class EchoServiceImpl implements EchoService{ public String echo(String message){ String now = new SimpleDateFormat("原创 2021-11-18 21:13:13 · 4893 阅读 · 0 评论