基于SpringCloud Alibaba dubbo 和 zookeeper的集群容错,负载均衡,服务降级简单使用
内容基于Gradle 创建的工程
上一篇 Dubbo 的简单使用
服务提供者
application.properties
dubbo.protocol.port=9001
dubbo.protocol.name=dubbo
dubbo.application.name=sample-cloud-dubbo-provide
dubbo.application.id=sample-cloud-dubbo-provide
spring.application.name=sample-cloud-dubbo-provide
spring.cloud.zookeeper.discovery.register=true
spring.cloud.zookeeper.connect-string=xx.xx.xx.xx:2181
工程的引用
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter'
implementation 'com.alibaba.cloud:spring-cloud-starter-dubbo'
implementation 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
implementation project(':alibb-dubbo-mineserviceapi')//依赖同一个父模块的子模块
}
import com.study.alibbdubbomineserviceapi.demo.SampleCloudDemoService;
import org.apache.dubbo.config.annotation.Service;
/**集群容错:在分布式服务调用中,服务异常(消费者调用服务接口导致)对应的处理方式的选择
Dubbo 中提供了6种模式可以选择,用@Service中的cluster 属性进行标志
1.failover(默认) : 失败切换,服务调用失败后,自动切换到集群中其他的服务提供者上进行尝试,
默认的重试次数是2 ,可以使用retries = 3 进行修改,调用失败会增加响应延时,这种操作一般
用于读操作(写操作可能会造成数据重复之类的问题)。
例子:@Service(cluster = "failover",retries = 2)
2. failfast :快速失败,服务调用失败后,直接报错,只发起一次请求。一般写操作使用
例子;@Service(cluster = "failfast")
3.failsafe :失败安全。出现异常 直接忽略
例子:@Service(cluster = "failsafe")
4.failback :失败后自动回复。服务调用出现异常之后再后台记录这个请求,并定时重发这个请求,
保证操作一定成功。适用于消息的通知处理
5.forking :并行调用集群中的服务,只要有一个服务调用成功就直接返回
例子:@Service(cluster = "forking")
6.broadcast :广播调用所有的服务,任一一个服务调用失败都算服务调用失败
例子:@Service(cluster = "broadcast")
也可以在服务消费者方配置 @Reference 中有对应的配置(但是建议和负载均衡一起配置在服务提供者)
负载均衡:访问量较大的时候,将流量按照某种策略分配到不同的节点
Dubbo 提供的配置模式
1.random:随机算法,可以给性能较好的服务器节点设置较大的权重
例子:@Service(cluster = "failfast", loadbalance = "random",weight = 2)
2.roundrobin:轮询。按照设置的权重进行轮询
例子:@Service(cluster = "failfast", loadbalance = "roundrobin",weight = 2)
3.leastactive:最少活跃调用书。处理较慢的节点会接受到更少的请求
例子: @Service(cluster = "failfast", loadbalance = "leastactive")
4.consistenthash:一致性hash,相同参数的请求总是会发送到同一个服务器
例子:@Service(cluster = "failfast", loadbalance = "consistenthash")
*/
@Service(cluster = "failfast", loadbalance = "random",weight = 2)
public class SampleCloudProvide implements SampleCloudDemoService {
@Override
public String sayHello() {
return "sample cloud hello";
}
}
// 启动类
import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@DubboComponentScan
public class SampleCloudDubboProvideApplication {
public static void main(String[] args) {
SpringApplication.run(SampleCloudDubboProvideApplication.class, args);
}
}
服务消费者
application.properties
server.port=8081
dubbo.protocol.name=dubbo
#name 和 id 得写,不然启动会报错
dubbo.application.name=sample-cloud-dubbo-provide
dubbo.application.id=sample-cloud-dubbo-provide
#服务(应用名)订阅列表,用,分割
dubbo.cloud.subscribed-services=sample-cloud-dubbo-provide
spring.application.name=sample-cloud-dubbo-consume
#开启zookeeper注册中心
spring.cloud.zookeeper.discovery.register=true
spring.cloud.zookeeper.connect-string=xx.xx.xx.xx:2181
工程的引用
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter'
implementation 'com.alibaba.cloud:spring-cloud-starter-dubbo'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
implementation project(':alibb-dubbo-mineserviceapi')//依赖同一个父模块的子模块
}
import com.study.alibbdubbomineserviceapi.demo.SampleCloudDemoService;
/**
* 服务降级:
* 当服务提供者方出现状况无法正常提供服务的时候,为保证客户端的正常操作,可以进行默认数据的返回(兜底数据)
* 简单说就是:用于服务调用出错的时候的服务降级
*
*/
public class SampleCloudMockProvide implements SampleCloudDemoService {
public SampleCloudMockProvide(){
System.out.println("确认一下 SampleCloudMockProvide 的创建次数");
}
@Override
public String sayHello() {
return "SampleCloudMockProvide Hello";
}
}
import com.study.alibbdubbomineserviceapi.demo.SampleCloudDemoService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/samplecloud")
public class SampleCloudApi {
//mock :服务降级使用的服务实现
@Reference(mock = "com.study.sampleclouddubboconsume.samplecloud.mock.SampleCloudMockProvide")
private SampleCloudDemoService sampleCloudDemoService;
@RequestMapping("/sayhello")
public String sayHello(){
return sampleCloudDemoService.sayHello();
}
}
import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@DubboComponentScan
public class SampleCloudDubboConsumeApplication {
public static void main(String[] args) {
SpringApplication.run(SampleCloudDubboConsumeApplication.class, args);
}
}