1.1Dubbo 介绍
Dubbo是阿里巴巴公司开源的一个高性能、轻量级的 Java RPC 框架。
致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。
2011年10月27日,阿里巴巴开源了自己的SOA服务化治理方案的核心框架Dubbo
2012年10月23日Dubbo2.5.3发布后,在Dubbo开源将满一周年之际,阿里基本停止了对Dubbo的主要升级。只在之后的2013年和2014年更新过2次对Dubbo2.4的维护版本,然后停止了所有维护工作。Dubbo对Spring 的支持也停留在了Spring 2.5.6版本。
阿里停止维护和升级Dubbo期间,当当网开始维护自己的Dubbo分支版本Dubbox,支持了新版本的Spring,并对外开源了Dubbox。同时,网易考拉也维护了自己的独立分支Dubbok,可惜并未对外开源。
随着微服务的火热兴起,在国内外开发者对阿里不再升级维护Dubbo的吐槽声中,阿里终于开始重新对Dubbo的升级和维护工作。在2017年9月7日,阿里发布了Dubbo的2.5.4版本,距离上一个版本2.5.3发布已经接近快5年时间了。在随后的几个月中,阿里Dubbo开发团队以差不多每月一版本的速度开始快速升级迭代,修补了Dubbo老版本多年来存在的诸多bug,并对Spring等组件的支持进行了全面升级。
2018年1月8日,Dubbo2.6.0版本发布,并将之前当当网开源的Dubbo分支Dubbox进行了合并,实现了Dubbo版本的统一整合。
官网:http://dubbo.apache.org
1.2架构
二 Dubbo 快速入门 2.1 zookeeper安装
Dubbo默认支持五种注册中心:推荐使用 Zookeeper 注册中心
Zookeeper 是 Apache Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。
安装步骤 :
1)上传jdk安装包jdk-8u171-linux-x64.tar.gz到linux系统并解压
# 进入/usr/local 目录 cd /usr/local tar -zxvf jdk-8u171-linux-x64.tar.gz
2)设置环境变量:
vi /etc/profile
JAVA_HOME=/usr/local/jdk1.8.0_171 PATH=$JAVA_HOME/bin:$PATH CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export JAVA_HOME export PATH export CLASSPATH
3)使得环境变量生效
source /etc/profile
4)验证
java -version
5)安装zk
# 进入/usr/local cd /usr/local # 把压缩包上传到linux系统,解压 tar -zxvf zookeeper-3.4.6.tar.gz # 进入zookeeper-3.4.6目录 cd zookeeper-3.4.6
# 进入conf目录 cd conf # 把zoo_sample.cfg 改名为 zoo.cfg mv zoo_sample.cfg zoo.cfg # 打开zoo.cfg文件, 修改dataDir属性 vi zoo.cfg
# 设置zoo.cfg放置数据的目录 dataDir=/usr/local/zookeeper-3.4.6/data # wq保存退出
./zkServer.sh stop # 停止服务 ./zkServer.sh status # 查看服务状态2.2 服务提供者
实现步骤
1)创建maven工程:dubbo-service-user,添加依赖
4.0.0 org.springframework.boot spring-boot-starter-parent2.1.6.RELEASE cn.itcast dubbo-service-user1.0-SNAPSHOT org.springframework.boot spring-boot-starter-weborg.apache.dubbo dubbo-spring-boot-starter2.7.5 org.apache.curator curator-recipes4.2.0 org.apache.zookeeper zookeeper3.4.6
注意事项:如果出现zookeeper not connected主要是 jdk版本和zookeeper版本不匹配,jdk1.8以后,pom中zookeeper依赖不能超过3.4+,不然就会报错。此外3.3+的版本依赖包阿里云中没有,所以建议使用3.4+版本的。
2)创建application.yml配置文件,并添加配置如下
# springboot项目对外暴漏的端口(web项目就是访问端口) server: port: 9001 dubbo: application: # 项目名称,用于计算服务的依赖关系。(区分不同项目的服务) name: dubbo-service-user # 指定zk注册中心地址 registry: address: zookeeper://192.168.12.134:2181 protocol: # 对外暴漏的服务使用的协议:dubbo协议, 官网推荐 name: dubbo # 对外暴漏服务的端口 port: 20881 # dubbo包扫描,会扫描dubbo提供的@Service注解 scan: base-packages: cn.itcast.api
3)编写Api接口
package cn.itcast.api; public interface UserApi { String sayHi(String name); }
4)编写Api接口实现类
package cn.itcast.api.impl; import cn.itcast.api.UserApi; import org.apache.dubbo.config.annotation.Service; @Service public class UserApiImpl implements UserApi { @Override public String sayHi(String name) { return "hi," + name; } }
5)启动类
package cn.itcast; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class UserServiceApplication { public static void main(String[] args) { SpringApplication.run(UserServiceApplication.class, args); } }
启动后的执行流程:
1、Spring容器启动
2、Dubbo自动配置类开始执行
3、读取yml中相关配置,扫描包路径:cn.itcast.api
4、找到加了@Service注解的实现类:UserApiImpl
5、将UserApiImpl作为一个提供的服务接口放到zk中,指定使用dubbo协议,20881端口,key为cn.itcast.api.UserApi,
value: dubbo://localhost:20881/userApiImpl
2.3 服务消费者4.0.0 org.springframework.boot spring-boot-starter-parent2.1.6.RELEASE cn.itcast order-web-manager1.0-SNAPSHOT org.springframework.boot spring-boot-starter-weborg.apache.dubbo dubbo-spring-boot-starter2.7.5 org.apache.curator curator-recipes4.2.0 org.apache.zookeeper zookeeper3.4.6
2)编写application.yml
server: port: 8080 dubbo: # 项目名称,用于计算服务的依赖关系。(区分不同项目的服务) application: name: order-web-manager # 注册中心地址 registry: address: zookeeper://192.168.12.134:2181
3)编写api接口
注意:服务消费者的接口名称、接口方法名称、包路径必须要与服务提供者一致,否则生成代理对象调用报错。
所以:这里的接口最好从服务提供者那里拷贝,不要手动去编写。
package cn.itcast.api; public interface UserApi { String sayHi(String name); }
4)编写控制器
package cn.itcast.controller; import cn.itcast.api.UserApi; import org.apache.dubbo.config.annotation.Reference; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("order") public class OrderController { @Reference private UserApi userApi; @GetMapping public String hello(){ // 执行RPC远程调用, 获取dubbo服务返回结果. 在浏览器显示 String result = userApi.sayHi("Tom"); return result; } }
5)启动类
package cn.itcast; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @SpringBootApplication public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
6)访问http://localhost:8080/order
执行流程:
1、Spring容器启动
2、Dubbo自动配置类开始执行,加载相关配置。
3、初始化OrderController时,发现有个属性加了@Reference注解,处理该属性
4、根据加载的相关配置,从zk中获取已经注册上去的信息,生成代理对象,并设置到OrderController的属性中。
5、调用hello方法时,执行RPC远程调用服务提供端,得到返回结果。
2.4. 优化项目结构创建Api接口工程:dubbo-service-api,抽取接口UserApi,将其放入dubbo-service-api
package cn.itcast.api; public interface UserApi { String sayHi(String name); }
2)优化服务提供者
dubbo-service-user 工程删除UserApi, 然后添加依赖:
cn.itcast dubbo-service-api1.0-SNAPSHOT
3)优化服务消费者
order-web-manager 工程删除UserApi, 然后添加依赖:
三 Dubbo-admin 管理平台(了解) 3.1介绍cn.itcast dubbo-service-api1.0-SNAPSHOT
我们在开发时,需要知道Zookeeper注册中心都注册了哪些服务,有哪些消费者来消费这些服务。我们可以通过部署一个管理中心来实现。其实管理中心就是一个web应用,部署到tomcat即可。
3.2 安装安装步骤如下:
1)将资料中的dubbo-admin-2.6.0.war文件复制到tomcat的webapps目录下
2)启动tomcat,此war文件会自动解压。 注意:Tomcat不要放到中文目录!!!
3)修改WEB-INF下的dubbo.properties文件,注意dubbo.registry.address对应的值需要对应当前使用的Zookeeper的ip地址和端口号
dubbo.registry.address=zookeeper://192.168.134.129:2181 dubbo.admin.root.password=root dubbo.admin.guest.password=guest
4)重启tomcat
3.3 使用*** 作步骤:
1)访问http://localhost:6080/dubbo-admin-2.6.0/,输入用户名(root)和密码(root)
2)启动服务提供者工程和服务消费者工程,可以在查看到对应的信息
四 Dubbo 高级特性(重点) 4.1 序列化在订单服务中,需要查询用户信息。现在需要在dubbo服务提供者中添加一个根据用户id查询用户的方法,并交给订单系统远程调用。这里需要注意:dubbo服务提供端与消费端之间传递的对象,必须要实现序列化接口。
4.1.2 dubbo-service-api 接口工程
1)创建实体类,注意: 这里的实体类必须实现序列化接口,否则报错。
package cn.itcast.pojo; import java.io.Serializable; public class User implements Serializable { private Long id; private String name; private Integer age; private Integer sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
2)编写接口,在接口添加一个方法:findById()
package cn.itcast.api; import cn.itcast.pojo.User; public interface UserApi { String sayHi(String name); User findById(Long id); }
4.1.3 dubbo-service-user服务工程
1)改造UserApiImpl
package cn.itcast.api.impl; import cn.itcast.api.UserApi; import cn.itcast.pojo.User; import org.apache.dubbo.config.annotation.Service; @Service public class UserApiImpl implements UserApi { @Override public User findById(Long id) { User user = new User(); user.setId(1l); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } @Override public String sayHi(String name) { return "hello, " + name; } }
2)重启服务
4.1.4 order-web-manager消费者工程
1)改造UserApiImpl
package cn.itcast.api.impl; import cn.itcast.api.UserApi; import cn.itcast.pojo.User; import org.apache.dubbo.config.annotation.Service; @Service public class UserApiImpl implements UserApi { @Override public User findById(Long id) { User user = new User(); user.setId(1l); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } @Override public String sayHi(String name) { return "hello, " + name; } }
2)重启服务
6.1.4 order-web-manager消费者工程
1)修改控制器
package cn.itcast.controller; import cn.itcast.api.UserApi; import cn.itcast.pojo.User; import org.apache.dubbo.config.annotation.Reference; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("order") public class OrderController { @Reference private UserApi userApi; @GetMapping("/user/{id}") public User findUserById(@PathVariable("id") Long id){ User user = userApi.findById(id); return user; } @GetMapping public String hello(){ // 执行RPC远程调用, 获取dubbo服务返回结果, 在浏览器显示 String result = userApi.sayHi("Tom"); return result; } }
2)重启服务,访问http://localhost:8080/order/user/1
4.1.5 无序列化报错示例
cause:java.lang.IllegalStateException: Serialized class cn.itcast.pojo.User must implement java.io.Serializable4.2 地址缓存
4.2.1 介绍
提问:注册中心挂了,服务是否可以正常访问?
可以,因为dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后在调用则不会访问注册中心。
当服务提供者地址发生变化时,注册中心会通知服务消费者。
4.2.2 演示步骤
1)执行命令,关闭注册中心
[root@itcast bin]# ./zkServer.sh stop
2)测试访问order服务,依然可以调用服务
4.3 超时与重试
4.3.1 介绍
服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去,相关线程得不到释放。
在某个峰值时刻,大量的请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩。
dubbo 利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接。 使用timeout属性配置超时时间,默认值1000,单位毫秒。
设置了超时时间,在这个时间段内,无法完成服务访问,则自动断开连接。
如果出现网络延迟,则这一次请求就会失败。
Dubbo 提供重试机制来避免类似问题的发生。
通过 retries 属性来设置重试次数。默认为 2 次。
4.3.2 演示步骤
1)重启zk(之前关闭了)
2)服务提供端dubbo-service-user 中添加睡眠时间,再重启该服务
package cn.itcast.api.impl; import cn.itcast.api.UserApi; import cn.itcast.pojo.User; import org.apache.dubbo.config.annotation.Service; @Service public class UserApiImpl implements UserApi { @Override public User findById(Long id) { User user = new User(); user.setId(id); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } @Override public String sayHi(String name) { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("111"); return "hello, " + name; } }
3)重启服务消费端 order-web-manager
4)调用http://localhost:9002/hello,发现报错
5)服务提供端dubbo-service-user 服务提供端添加超时、重试配置
package cn.itcast.api.impl; import cn.itcast.api.UserApi; import cn.itcast.pojo.User; import org.apache.dubbo.config.annotation.Service; @Service(timeout = 30000, retries = 0) // 设置超时时间(默认1000),重试次数(默认2次) public class UserApiImpl implements UserApi { @Override public User findById(Long id) { User user = new User(); user.setId(id); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } @Override public String sayHi(String name) { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("111"); return "hello, " + name; } }
6)依次重启服务提供端、服务消费端,继续访问发现可以访问成功了。
注意事项
1)Debug时设置超时时间大一点,否则容易超时,因为debug中间停了下来。
2)Debug时重试次数设置为0次。
3)在服务提供端的@Service注解以及服务调用方的@Reference注解上都可以添加超时、重试配置(都加了以调用方为主)。
4)建议配置添加在服务提供端。
4.4 多版本4.4.1 介绍
4.4.2 演示步骤
演示:启动2次服务,同时指定版本。消费者可以根据版本调用新老服务。
1)修改dubbo-service-user 工程的UserApiImpl
@Service(version = "1.0") // version指定服务版本 public class UserApiImpl implements UserApi { @Override public User findById(Long id) { System.out.println("UserApiImpl服务版本1.0"); User user = new User(); user.setId(id); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } }
2)修改dubbo-service-user中的application.yml配置
server: port: ${port:9001} # 表示端口默认为9001;如果运行时期通过VM Option传入port参数,以传入为主。 dubbo: application: name: dubbo-service-user protocol: name: dubbo port: ${dport:20881} # 表示端口默认为20881;dport是动态传入的参数名称,可以随意定义 registry: address: zookeeper://192.168.12.134:2181 scan: base-packages: cn.itcast.api
3)启动dubbo-service-user工程,直接运行run方法即可(基于1.0版本代码)。
4)再次修改实现类,并指定版本与提示信息。
@Service(version = "2.0") // version指定服务版本 public class UserApiImpl implements UserApi { @Override public User findById(Long id) { System.out.println("UserApiImpl服务版本2.0"); User user = new User(); user.setId(id); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } }
5)再次启动dubbo-service-user工程(基于2.0版本代码),注意:不要直接启动。直接启动没法传入port、dport两个参数,会报端口冲突的错误。启动前先修改VM Options参数:
启动后服务列表如下:
6)最后,消费者通过版本号来调用指定版本服务提供者(实际项目中可以将消费者做集群,部分服务去调用提供者1.0版本,部分服务去调用提供者2.0版本)
@RestController @RequestMapping("order") public class OrderController { // @Reference(version = "1.0") @Reference(version = "2.0") // 修改版本后重启 private UserApi userApi; @GetMapping("/user/{id}") public User findById(@PathVariable("id") Long id){ return userApi.findById(id); } }
7)测试,访问服务消费者,发现在9002(即2.0版本)的控制台中打印了文字,说明被调用了。
4.5 负载均衡4.5.1 介绍
问题:当服务提供者搭建集群时,我们该调用哪个服务呢?这就需要负载均衡
负载均衡策略(4种):
random :按权重随机,默认值。按权重设置随机概率。
roundrobin :按权重轮询。
leastactive:最少活跃调用数,相同活跃数的随机。
consistenthash:一致性 Hash,相同参数的请求总是发到同一提供者。
演示:准备二个服务提供端,权重分别是100/200,测试负载均衡策略。本例使用random随机。
4.5.2 服务提供者一
1)设置权重 weight = 100
@Service(weight = 100) public class UserApiImpl implements UserApi { @Override public User findById(Long id) { System.out.println("服务提供端1:权重100"); User user = new User(); user.setId(id); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } ... }
2)重启服务
4.5.2 服务提供者二
1)重新修改服务提供者UserApiImpl,设置权重weight = 200
@Service(weight = 200) public class UserApiImpl implements UserApi { @Override public User findById(Long id) { System.out.println("服务提供端2:权重200"); User user = new User(); user.setId(id); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } ... }
2)启动服务启动者2: VM Option 需要配置 -Dport=9002 -Ddport=20882 (多版本时候已经配了)。
4.5.4 服务消费者
@RestController @RequestMapping("order") public class OrderController { @Reference(loadbalance = "random") // 按照权重随机 private UserApi userApi; @GetMapping("/user/{id}") public User findById(@PathVariable("id") Long id){ return userApi.findById(id); } }
访问 http://localhost:8080/order/user/1 10次,运行结果如下,提供端2打印了6次,提供端1打印了4次,发现调用到提供端2的次数多一些(不一定是2:1,但调用非常多次时,大概是2:1的比例)
服务提供者1:
服务提供者2:
说明:负载均衡算法设置同样可以添加在提供端,建议加在消费端
4.6 集群容错集群容错模式:
Failover Cluster:失败重试。默认值。当出现失败,重试其它服务器 ,默认重试2次,使用 retries 配置。一般用于读 *** 作
Failfast Cluster :快速失败,只发起一次调用,失败立即报错。通常用于写 *** 作。(不重试)
Failsafe Cluster :失败安全,出现异常时,直接忽略。返回一个空结果。(一般用于不太重要的 *** 作,比如消息通知)
Failback Cluster :失败自动恢复,后台记录失败请求,定时重发。(一般用于非常重要的 *** 作)
Forking Cluster :并行调用多个服务器,只要一个成功即返回。
Broadcast Cluster :广播调用所有提供者,逐个调用,任意一台报错则报错。
4.6.2 案例描述
测试集群容错模式:Failover Cluster:失败重试。
需求:
1)准备两个服务提供者,第一个的实现类中设置线程睡眠时间,模拟超时调用失败。第二个实现类中不设置睡眠时间。
2)如果来自消费者的请求第一次调用了第一个服务提供者会超时,自动进行失败重试,进行重试,可能找到第一个,也可能找到第二个,如果找到的还是第一个,又会重试。
3)如果来自消费者的请求第一次调用了第二个服务提供者,那直接成功了,不会有后续 *** 作了。
6.6.3 演示步骤
1) 修改服务提供者一,然后重启
@Service public class UserApiImpl implements UserApi { @Override public User findById(Long id) { System.out.println("服务提供端1"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } User user = new User(); user.setId(id); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } ... }
2)修改服务提供者二,然后重启
@Service public class UserApiImpl implements UserApi { @Autowired private UserMapper userMapper; @Override public User findById(Long id) { System.out.println("服务提供端2"); User user = new User(); user.setId(id); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } ... }
3)修改服务消费者集群容错模式为failover,失败重试
@RestController @RequestMapping("order") public class OrderController { @Reference(cluster = "failover") private UserApi userApi; @GetMapping("/user/{id}") public User findById(@PathVariable("id") Long id){ return userApi.findById(id); } }
4)测试,访问http://localhost:8080/order/user/1
查看控制台,可以发现它最开始可能是调用9001或9002,然后超时了进行重试,可能接下来继续调用9002,也可能9001,如果再调不通,又会重试一次。
4.7 服务降级4.6.1 介绍
当服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度!
当下游的服务因为某种原因响应超时或不可用,上游主动调用本地的一些降级逻辑,避免等待或出错,迅速返回给用户!
参考官网:服务降级 | Apache Dubbo
降级 Dubbo 服务:可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。
其中:
mock=force:return null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
mock=fail:return null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
4.6.2 演示
演示1: mock=force:return null
测试后发现:dubbo服务提供端控制台没有任何输出,且服务消费端没有报错,说明服务被降级了,没有调用服务提供端。
@RestController @RequestMapping("order") public class OrderController { // 表示不发起远程调用,直接返回null @Reference(mock = "force:return null") private UserApi userApi; }
演示2:mock=fail:return null
@Service public class UserApiImpl implements UserApi { @Override public User findById(Long id) { System.out.println("服务提供端2"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } User user = new User(); user.setId(1l); user.setName("张三"); user.setAge(20); user.setSex(1); return user; } }
步骤2:服务的方法调用超时后,再返回 null 值,不抛异常
@RestController @RequestMapping("order") public class OrderController { // 服务的方法调用在失败后,再返回 null 值,不抛异常 @Reference(mock = "fail:return null") private UserApi userApi; }
步骤3:访问测试
因为调用服务超时,自动重试2次。最终调用服务失败,返回null
五 面试题(重点)问题1: Dubbo只能从注册中心获取服务吗?
不是,也可以使用直连,直连方式是不需要从注册中心获取服务。
在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时可能需要点对点直连方式。@Reference(url = "dubbo://localhost:24567")
private IUserservice userservice;直连方式会失去负载均衡的能力,所以不适合生产环境。
问题2: Dubbo服务提供者一定要需要先开启动,消费者后启动吗?
不需要,如果在@Reference中添加check=false,可以先启动消费者,再启动提供者
问题3: Dubbo默认调用服务超时时长是多少?
服务超时时长是: 1000毫秒
问题4: Dubbo集群容错模式有哪些? 默认容错模式是什么?
Dubbo集群容错模式有6种:
Failover(失败重试、读 *** 作)
Failfast(快速失败、写 *** 作、不重试)
Failsafe(失败安全,忽略本次失败的请求)
Failback(失败自动恢复,记录失败请求,定时重发)
Forking(并行调用每个服务提供者,只要一个成功就返回)
Broadcast(广播模式,逐个调用,任意一个报错就报错)
默认容错模式是: Failover(失败重试)
问题5: Dubbo注册中心有哪些?
Dubbo默认支持五种注册中心:
1. Multicast
2. Zookeeper(推荐)
3. Nacos
4. Redis
5. Simple
问题6: Dubbo注册中心zookeeper挂掉,消费者还可以正常调用服务提供者吗?
可以正常调用,因为消费者从注册中心,获取服务地址后会在本地缓存。(地址缓存)
问题7: Dubbo如何实现服务降级?
心如死灰了, 不发起远程调用,直接返回null值。
mock=force:return null在远程调用失败后,返回null值,对消费者不产生调用影响。
mock=fail:return null
问题8: Dubbo负载均衡策略有哪些,默认负载均衡策略是什么?
负载均衡策略有4种:
1. random(随机,按照权重随机,相当于翻牌子)
2. roundrobin(轮询,按照权重逐个调用,挨个来)
3. leastactive(最少活跃数,性能好的机器能处理更多的请求)
4. consistanthash(一致性hash,相同参数的请求都发给同一个)默认负载均衡策略是: random (随机)
问题9: Dubbo项目灰度发布?
使用服务提供者的版本号隔离,调用时指定版本号。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)