什么是分布式系统:
分布式系统就是若干独立计算机的集合,这些计算机对于用户来说就像单个的相关系统
dubbo(分布式服务框架)就是来管理分布式系统这些独立的计算机之间关系的框架
RPC :远程过程调用 不同服务器的功能调用
注册中心:用来寻找相关业务在哪台服务器上,并检查是否可用
命令
-
create -e /节点名 值 ( 创建临时节点 )
create -e /study 123456
springboot整合1 :注解
- 暴露服务注解 相当于xml中的 <dubbo:service interface="…"/>
import com.alibaba.dubbo.config.annotation.Service;
@Service
public class UserServiceImpl implements UserService {
// dubbo 包下的Service注解 暴露服务,
相当于xml的
<bean:service interface="com....." ref="..."/>
- 开启基于注解的dubbo功能的注解
@EnableDubbo // 开启基于注解的dubbo功能
@SpringBootApplication
public class BootUserApplication {...}
- 从注册中心调用服务注解 相当于xml中的 <dubbo:refrence interface="…"/>
@Service
public class OrderServiceImpl implements OrderService {
// @Autowired
@Reference // 从注册中心调用服务
UserService userService;
配置
优先级 :以timeout为例,其他的还有retries(重试次数),oadbalance,actives等都类似
精确优先(方法级优先,接口级次之,全局配置再次之)
消费者设置优先(如果级别一样,则消费方优先,提供方次之)
-
启动检查 chack=“false”
启动检查,检查注册中心中是否有需要调用的服务,如果开启检查,则项目一启动就开始检查,如果没有则抛出异常,启动检查默认是开启的,关闭检查,则是项目启动并不检查,只有当需要使用到这项服务时才会去检查 <dubbo:reference interface="com.study.order.service.UserService" id="userService" check="false"> </dubbo:reference> 这样每项服务都配置一遍很麻烦 当前消费者的统一配置 <dubbo:consumer check="false"></dubbo:consumer> 也可以统一检查配置注册中心 <dubbo:registry check="false"></dubbo:registry>
-
超时时间 timeout=“1000” (单位毫秒)
如果提供者此时网络异常,或者项目代码需要大量时间运行,没有及时的提供服务,大量的消费者都在等待,会造成堵塞,为了避免堵塞,提高效率,就可以设置timeout,默认一秒超时,如果超过一秒钟没有获取到服务则抛出异常 <dubbo:reference interface="com.study.order.service.UserService" id="userService" timeout="1000"></dubbo:reference> 也可以统一配置,全体有效 <dubbo:consumer check="false"></dubbo:consumer> 超时时间服务提供者也可以配置
-
重试次数 (retries)
如果请求服务超时,设置了retries,就可以再次请求服务,retries=“3” 第一次运行时不算在3的次数中的 如果有多个相同服务的提供者,retries在第一个提供者重试失败后,会再到其他的提供者去重试 <dubbo:reference interface="com.study.order.service.UserService" id="userService" retries="3"></dubbo:reference>
应该在什么情况下设置重试次数?
幂等:方法不管运行多少次,结果都应该是一个效果,(比如,查询、删除、修改… )就算重复执行也不会改变结果
非幂等:运行多次会改变结果,比如(增加,)增加一个用户,如果超时之后 再次请求的过程中,添加请求已经进到数据库,这样不断重试,会让数据库有很多重复的数据
所以幂等可以设置重试此时,非幂等则 不可以 -
多版本 (version)
灰度发布,让消费者调用不同版本的服务
<dubbo:service interface="com.study.order.service.UserService" ref="userServiceImpl" version="1.0.0"></dubbo:service> <dubbo:service interface="com.study.order.service.UserService2" ref="userServiceImpl2" version="2.0.0"></dubbo:service>
<dubbo:reference interface="com.study.order.service.UserService" id="userService" version="1.0.0"></dubbo:reference> version="*" 则是随机调用版本
-
本地存根
…
springboot整合2 配置
方法 1:
导入dubbo-starter依赖
使用Service 和reference 等一些注解
方法 2:
保留xml文件
xml 中的一些配置无法单独用注解完成,就可以在springboot中也配置一个xml配置文件来详细的配置dubbo
在springboot中使用配置文件需要加上注解@ImportResource(“配置文件名”)
加上这个注解后,可以不用加@EnabelDubbo 和 @Service 等一些dubbo的注解了
//@EnableDubbo // 开启基于注解的dubbo功能
@ImportResource("provider.xml")
@SpringBootApplication
public class BootUserApplication {
方法 3:
创建一个config配置类 每项配置都有对应的方法名,去方法中单独配置即可
@Configuration
public class MyDubboConfig {
@Bean
public ApplicationConfig applicationConfig(){
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("boot-user");
return applicationConfig;
}
@Bean
public ServiceConfig serviceConfig(UserService userService){
ServiceConfig<UserService> serviceConfig = new ServiceConfig<>();
// 暴露服务
serviceConfig.setInterface(UserService.class);
// 服务实例,UserServiceImpl中有Component注解,注册到了容器中,所以可以再容器中找到UserService
serviceConfig.setRef(userService);
serviceConfig.setVersion("1.0.0");
//配置每一个method信息
MethodConfig methodConfig = new MethodConfig();
methodConfig.setName("getUserAddressList");
methodConfig.setTimeout(1000);
List<MethodConfig> methodConfigList = new ArrayList<>();
serviceConfig.setMethods(methodConfigList);
return serviceConfig;
}
....
每项配置都大同小异
想要使用这些配置方法,需要在主程序中加上包扫描注解@DubboComponentScan(“com.study.bootuser.service.impl”)
@SpringBootApplication
//@DubboComponentScan("com.study.bootuser.service.impl")
@EnableDubbo(scanBasePackages = "com.study.bootuser.service.impl") // 这个注解中包含了DubboComponentScan注解,所以直接写这个注解即可
public class BootUserApplication {
zookeeper宕机与dubbo直连
高可用
zookeeper宕机与dubbo直连
现象: zookeeper注册中心宕机,还可以消费dubbo暴露的服务。原因:
健壮性
监控中心宕掉不影响使用,只是丢失部分采样数据
数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务注册中心对等集群,任意一台宕掉 后,将自动切换到另一台
注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯服务提供者无状态,任意一台宕掉后,不影 响使用
服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复高可用:通过设计,减少系统不能提供服务的时间
dubbo直连就是在消费者 @Reference 后面加上url (“127.0.0.1:20881”)指定提供者的地址和端口号即可 绕过zookeeper
负载均衡
reference(loadbalance=“random”) 默认随机负载
roundrobin 轮转机制 A B C 顺序负载
权重分配:权重数量平均分配
A (50) B (100) C (200) 权重分 可以在监控中心调整,也可以在Service(width=“100”)调整
1/7 2/7 4/7 权重比例
服务降级
通过牺牲某个服务,来成全其他的核心服务
当服务器的负载达到上限,或者某个服务出现错误等等,效率边缓慢时,可以通过服务降级来屏蔽某个业务缓解
有两种服务降级的方式 (可以在监控中心设置)
1、
屏蔽不重要的服务,不发起远程调用,消费方调用该服务的方法全部返回null值
2、
消费方对该服务的方法调用在失败后,再返回null值,不抛异常,用来容忍不重要服务不稳定时对调用方的影响
容错服务 Hystrix
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
- 提供者配置
public class UserServiceImpl implements UserService {
@HystrixCommand // 提供者加上HystrixCommand注解,如果服务出现异常,就启动容错机制
@Override
public List<UserAddress> getUserAddressList(String userId) {
// 测试容错服务,随机数超过0.5就抛出异常
if(Math.random()>0.5){
throw new RuntimeException();
}
- 消费者配置
@EnableHystrix // 主程序类中加上注解
public class BootOrderApplication {
@HystrixCommand(fallbackMethod = "hello") // 容错注解,并加上回调方法,如果调用的服务出现错误,就让容错机制去调用哪个服务
@Override
public List<UserAddress> initOrder(String userId) {
System.out.println(userId);
List<UserAddress> userAddressList = userService.getUserAddressList(userId);
return userAddressList;
}
// 让容错机制
public List<UserAddress> hello(String userId) {
return Arrays.asList(new UserAddress(001,"测试地址","测试","测试","测试","Y"));
}
原理__标签解析
spring 标签解析器 BeanDefinitionParser.class 下有 DubboBeanDefinitionparser.class 专门解析dubbo标签的解析器
dubbbo解析器中有一个parse方法,spring容器一启动来专门解析dubbo的标签, 解析后会一次获取标签,以及标签的id 名字,没有名字会有一个默认名,之后会有一个判断,每一个标签对应着一个Bean.class,如果获取到的标签等于什么配置.class(Service.class、protocol.class …),就获取这个标签里面的一些属性,往bean里面添加,定义一些值…
在标签解析器之前,会运行一个Dubbo命名空间处理器,里面有很多的标签解析器,解析到什么标签,就用DubboBeanDefinitionParse 来封装这个标签的内容
总的来说就是,解析出来一些东西,在往里添加,定义一些东西,在保存到XXXConfig.class 里面
ServiceBean.class 就是获取都之前解析完的标签,在把里面的内容保存起来