文章目录

  • 1. dubbo 高可用 zookeeper宕机与dubbo直连
  • 2. dubbo 高可用 负载均衡策略
  • 3. dubbo 高可用 服务降级
  • 4. dubbo 高可用 集群容错和hystrix
  • 4.1 集群容错
  • 4.2 hystrix配置
  • 5. RPC原理 和 Netty原理
  • 5.1 RPC原理
  • 5.2 netty通信原理
  • 6. dubbo 原理 框架设计
  • 7. dubbo 原理 启动解析(标签),加载配置信息
  • 8. dubbo 原理 服务暴露流程
  • 9. dubbo 原理 服务引用流程


1. dubbo 高可用 zookeeper宕机与dubbo直连


在注册中心全部宕机后,服务提供者和服务消费者仍然能通过本地缓存通讯。

  • 意思是在注册中心没有宕机之前,服务提供者和服务消费者通信过,就会有本地缓存记录了服务提供者的相关信息,这样当注册中心宕机后,依然可以通过本地缓存通讯。

dubbo-monitor监控中心宕机后,它是不会影响dubbo使用的,只是丢失了部分采样数据(监控数据)。


注册中心对等集群,任意一台宕机后,将会自动切换到另一台。当然全部宕机后,依然能通过本地缓存来通讯(前提是访问过一次。)。


dubbo直连:

  • dubbo不走zookeeper注册中心,直接根据ip和端口号直连到服务提供者。
  • 使用@Reference(url = “127.0.0.1:20880”)实现dubbo直连。
@Reference(url = "127.0.0.1:20880")
UserService userService;

2. dubbo 高可用 负载均衡策略


第一种:基于权重的轮询负载均衡机制

  • 不指定权重就是轮询依次访问。

第二种:最少活跃数-负载均衡机制。

  • 根据上次响应时间最小的,从而访问服务器。

第三种:一致性hash-负载均衡机制。

  • 可以让参数相同的请求每次都访问到相同的服务上面。

上面代码对应的机制源码如下图:

dubbo在什么时机本地缓存 dubbo本地缓存更新_java


对于设置这个轮询级别:

  • 可以直接从服务端/客户端服务级别,服务端/客户端方法级别设置loadbalance属性。
  • 对于注解,例如:@Reference直接加入loadbalance=“xxx”;@Service(loadbalance = “”,weight = 1)配置就可以。

还可以通过dubbo-admin管理者页面来操作一些权重啥的:

dubbo在什么时机本地缓存 dubbo本地缓存更新_dubbo_02


dubbo在什么时机本地缓存 dubbo本地缓存更新_学习_03

3. dubbo 高可用 服务降级


就是多个服务之间,可以屏蔽一些不关键或者不想让该服务器运行的一些服务。

dubbo在什么时机本地缓存 dubbo本地缓存更新_dubbo_04

mock=force:return+null是消费方对该服务的方法调用都直接返回null值,不发起远程调用。强制的意思。

mock=fail:return+null是消费方对该服务的方法调用失败后,再返回null值,不抛出异常。

注意:这两个策略都是针对服务消费者的操作!


可以通过dubbo-admin来给消费者设置策略:

dubbo在什么时机本地缓存 dubbo本地缓存更新_java_05


对应返回结果和效果和上面两个策略相同!

4. dubbo 高可用 集群容错和hystrix

4.1 集群容错


集群容错就是在集群调用失败时,dubbo给出多种容错方案:

  • Failover Cluster(默认缺省):失败自动切换,当出现失败,重试其它服务器。
  • Failfast Cluster:快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
  • Failsafe Cluster:失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
  • Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
  • Forking Cluster:并行调用多个服务器,只要一个成功即返回。
  • Broadcast Cluster:广播调用所有提供者,逐个调用,任意一台报错则报错。

配置这些集群容错模式:

dubbo在什么时机本地缓存 dubbo本地缓存更新_学习_06

4.2 hystrix配置


实际开发中,是通过整合hystrix来进行容错。

第一步:添加hystrix-starter的依赖。

dubbo在什么时机本地缓存 dubbo本地缓存更新_rpc_07


第二步:@EnableHystrix 注解开启服务容错。

package com.itholmes.gmall;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.ImportResource;

@EnableDubbo(scanBasePackages = "com.itholmes")
@EnableHystrix //开启服务容错
@SpringBootApplication
public class BootUserServiceProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(BootUserServiceProviderApplication.class, args);
    }
}

第三步:服务提供者或者服务消费者都可以使用@HystrixCommand注解标识用hystrix容错。

服务提供者演示:

package com.itholmes.gmall.service.impl;

import java.util.Arrays;
import java.util.List;
import com.itholmes.gmall.bean.UserAddress;
import com.itholmes.gmall.service.UserService;

import com.alibaba.dubbo.config.annotation.Service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

@Service
public class UserServiceImpl implements UserService{

	@HystrixCommand//这样该方法就会被hystrix容错
	public List<UserAddress> getUserAddressList(String userId) {
		//模拟返回收获地址数据
		UserAddress address1 = new UserAddress(1,"北京XXXX","1","李四","1283095748","Y");
		UserAddress address2 = new UserAddress(2,"德州XXXX","2","张三","1283095123123","N");
		return Arrays.asList(address1,address2);
	}
	
}

服务消费者演示:

package com.itholmes.gmall.service.impl;

import java.util.List;
import com.itholmes.gmall.bean.UserAddress;
import com.itholmes.gmall.service.OrderService;
import com.itholmes.gmall.service.UserService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;
import com.alibaba.dubbo.config.annotation.Reference;

@Service//这里使用spring的Service,不用dubbo的Service。
public class OrderServiceImpl implements OrderService {

	@Reference
	UserService userService;

	//当前出错以后会调用callbackMethod方法去。
	@HystrixCommand(fallbackMethod="callbackMethod")
	public List<UserAddress> initOrder(String userId) {
		System.out.println("用户ID:"+userId);
		//1.查询用户的收货地址,也就是调用user-service-provider项目中的查询收货地址的功能
		List<UserAddress> list = userService.getUserAddressList(userId);
		for(UserAddress user:list) {
			System.out.println(user);
		}
		return list;
	}
	
	//方便上面调用
	public List<UserAddress> callbackMethod(String userId) {
		// TODO Auto-generated method stub
		System.out.println("发生错误,调用了回调函数。");
		return null;
	}

	
}

5. RPC原理 和 Netty原理

5.1 RPC原理


dubbo就是一个RPC框架。

dubbo在什么时机本地缓存 dubbo本地缓存更新_rpc_08


之前的dubbo操作也只是1和9这两个步骤而已:

dubbo在什么时机本地缓存 dubbo本地缓存更新_rpc_09

5.2 netty通信原理


RPC底层是必须要有网络通信的,底层就是使用的netty框架来进行通信。


IO模式:

  • 本地IO:本地文件的IO操作。
  • 网络IO:网络间的IO操作。

两种IO模式:

  • BIO(Blocking IO):阻塞式IO。
  • dubbo在什么时机本地缓存 dubbo本地缓存更新_dubbo_10

  • NIO(Non-Blocking IO):非阻塞式IO。
  • dubbo在什么时机本地缓存 dubbo本地缓存更新_java_11

  • 上图就是多路复用的效果:
  • dubbo在什么时机本地缓存 dubbo本地缓存更新_dubbo_12


netty就是基于NIO实现的。

dubbo在什么时机本地缓存 dubbo本地缓存更新_dubbo在什么时机本地缓存_13

6. dubbo 原理 框架设计


原理图:

dubbo在什么时机本地缓存 dubbo本地缓存更新_rpc_14

dubbo整体设计介绍,每层概念:https://dubbo.apache.org/zh/docs/v2.7/dev/design/#m-zhdocsv27devdesign

7. dubbo 原理 启动解析(标签),加载配置信息


BeanDefinitionParser接口,下面有一个DubboBeanDefinitionParser实现类:

dubbo在什么时机本地缓存 dubbo本地缓存更新_java_15

其中在DubboBeanDefinitionParser勒种的parse会解析各种dubbo的标签:

dubbo在什么时机本地缓存 dubbo本地缓存更新_rpc_16


之后parse会进行各种判断,判断是哪个标签和对应的bean对象,该做什么事情等等。

dubbo在什么时机本地缓存 dubbo本地缓存更新_学习_17


在初始化之前会给封装很多值,对应上面的bean类和标签名啥的:

dubbo在什么时机本地缓存 dubbo本地缓存更新_dubbo_18

其实就是反射创建每个标签对应对象,并且配置对应属性而已。

8. dubbo 原理 服务暴露流程


服务暴露原理就要看ServiceBean类:

dubbo在什么时机本地缓存 dubbo本地缓存更新_学习_19

根据ServiceBean类一步步debug走,流程。

9. dubbo 原理 服务引用流程


dubbo在什么时机本地缓存 dubbo本地缓存更新_dubbo_20


同样debug一步步走,看过程。

此外,还有一个服务调用流程。