JAVA—Spring—SpringCloud—一. 分布式系统

1.最开始的服务架构是一个应用整个放在一台服务器上


2.应用复杂之后,换为集群架构  一个应用放在多台服务器上 负载均衡


3.再复杂之后,把应用的核心业务(这个应用的功能)抽取出来做成一个个单独的应用部署在一台台服务器上,需要调用哪一块的功能就调用哪个应用,这个时候由于每个应用之间并不是在同一个服务器内,调用时就需要RPC;


RPC:远程过程调用


通信效率,序列化反序列化


RPC框架 Dubbo gRpc(goole) Thrift(Facebook) HSF(alibaba)


4.当随着抽取的核心应用越来越多,部署的服务器也越来越多,就需要有一个管理控制中心(DUBBO)来监控每个服务的使用量,进而控制服务器资源,避免资源浪费


二.Dubbo简介


作用:服务治理


分布式系统中多个服务之间需要由一个服务治理中心来管理所有的服务


官网: http://dubbo.apache.org/zh-cn/index.html


Dubbo官网上的设计架构



Provider

暴露服务的服务提供方

Consumer

调用远程服务的服务消费方

Registry

服务注册与发现的注册中心

Monitor

统计服务的调用次数和调用时间的监控中心

Container

服务运行容器


需要注意的是注册与发现服务是异步  调用过程是同步


三.使用


环境搭建:


注册中心:zookeeper


监控中心:dubbo_admin



测试项目


一个springboot项目中构建三个子模块:




api-1 模块:所有的服务模型,服务接口,服务异常存放


consumer-1 模块:服务消费者


provider-1 模块:服务提供者


1.搭建项目中遇到一些困难


1.springboot 子模块依赖父模块后无法获得父模块中引用的依赖


解决办法:


加入依赖即可


2.服务提供者启动报错


java.lang.NoClassDefFoundError: org/apache/curator/framework/CuratorFrameworkFactory


原因: 未引入连接zookeeper注册中心的客户端导致


引入curator即可


 

    org.apache.curator

    curator-recipes

    4.2.0


3.必须先启动服务提供者,在启动消费者否则会报错




这是因为dubbo 默认在消费者启动的时候检查是否由服务可用


可以通过配置 check=false 来修改启动时是否检查服务可用


duboo:

  consumer:

    check: false


2.dubbo配置


#服务名称

dubbo:

  application:

    name: dubbo-provider

#注册中心地址

  registry:

    address: 121.199.20.51:2181

#注册中心通信协议 支持dubbo, multicast, zookeeper, redis, consul(2.7.1), sofa(2.7.2),

#etcd(2.7.2), nacos(2.7.2)等协议

    protocol: zookeeper


#服务提供者协议

  protocol:

    name: dubbo

    port: 20880



#监控中心 如果配置protocal为registry 则表示从注册中心发现服务 否则需要配置监控中心地址直连监控中心

  monitor:

    protocol: registry


3.两个注解


@Reference


代替@Autowired 引入远程Bean


@Service(Dubbo包下)


暴露服务


注意:包不要引错


1.配置的加载优先级




命令行参数>外部化配置>程序中配置>dubbo.properties


2.消费者和服务提供者的配置优先级


  • 方法级优先,接口级次之,全局配置再次之。
  • 如果级别一样,则消费方优先,提供方次之。


3.retries 设置重试次数


dubbo:

  consumer:

    retries: 3


概念:


幂等:例如查询  无论重试多少次都不会影响数据的操作


非幂等:例如新增  重试多次会影响到数据的变化


4.多版本(灰度发布)


上述dubbo暴露接口和远程调用服务的两个注解


@Service和@Reference都有版本的概念


当服务提供者由多版本的时候可以使用此功能实现灰度发布


消费者调用时


@Reference(version = "1.0.0")


服务提供者暴露接口


@Service(version = "1.0.0")


如果指定消费者version = * 则随机调用服务提供者的服务\


5.dubbo 与 springboot 集成的三种方式


  1. 引入dubbo-spring-boot-starter,开启@EnableDubbo,在yml/properties中配置服务,并使用@Service,@Referenece暴露或调用远程服务
  2. 保留dubbo的xml配置文件,在springboot启动类上使用@ImportResource 引入dubbo的配置文件,同样使用@Service,@Referenece暴露或调用远程服务
  3. 使用@Bean的方式配置dubbo


6.dubbo的高可用


当dubbo的注册中心宕机之后,消费者和服务提供者之间依然可以通过本地缓存通讯,不会因为宕机影响到服务


7.直连dubbo


@Reference(url = "127.0.0.1:20880")


当dubbo宕机之后也可以使用@Refenence url属性直连服务提供者


8.负载均衡


Random LoadBalance 根据权重随机的调用服务


RoundRobin LoadBalance 轮询  循环调用服务


LeastActive LoadBalance 最少活跃数 每次调用相应最快的服务


ConsistentHash LoadBalance 一致性哈希 所有的相同请求交给一个服务处理


一致性Hash解析:


把所有的服务的ip地址进行hash计算,得到每个ip地址的hash值,然后映射到一个由0到最大正整数的hash环上,




当调用服务时,首先根据请求的参数计算路由规则(例如用户Id)的hash值,这个hash值落在上述hash环的某一个地方,然后由最近的ip服务处理


9.服务降级


当一台服务器上由多个服务时,在高并发服务器压力比较大的时候可以通过屏蔽某一个或多个不关键的服务,来缓解服务器压力从而保证核心业务不受影响,这就是服务降级


10.集群容错


当调用服务出错时,dubbo由多种容错机制:


使用cluster设置容错机制


@Reference(timeout = 1000,retries = 1,cluster = "failfast")


  1. Failover cluster
    失败重试:当失败时会重试,可以通过retries=2设置重试次数(不包含第一次连接)
    同等级别下消费者配置优先级是要高于服务提供者配置的
    这种容错机制适合用于幂等操作,可以重复操作
    Dubbo默认也是这种容错机制

@Service(retries = 3)

@Referene(retries = 1)

  1. Failfast cluster
    快速失败:只调用一次 不会重复连接
  2. Failsafe :安全失败  失败直接忽略,就是不会报错

  3. 失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
    并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。
    广播调用所有提供者,逐个调用,任意一台报错则报错 [2]。通常用于通知所有提供者更新缓存或日志等本地资源信息。

Failback Cluster

Forking Cluster

Broadcast Cluster


11.切换nacos注册中心


引入依赖


    com.alibaba

    dubbo-registry-nacos

    0.0.2


    com.alibaba.nacos

    nacos-client

    [0.6.1,)


修改配置文件连接注册中心地址和协议


dubbo:

  registry:

    address: 121.199.20.51:8848

    protocol: nacos


四.Dubbo原理


1.框架设计




  1. business 业务层,开发只需要关注这一层
  2. RPC层
    1. config Dubbo的配置信息层
    2. Proxy Dubbo创建为消费者和服务提供者创建代理层
    3. Registry 注册中心层 Dubbo的消费者和provier都需要注册到注册中心
    4. Cluster 负载均衡 这一层负责实现负载均衡
    5. Monitor 监控层
    6. Protocol 调用层 这一层真正意义上的远程调用方法
  1. Remoting 通信层 主要由Netty实现
    1. Exchange 数据交换
    2. Transport 传输数据
    3. Serialize 序列化层


2.源码分析


没理解

上一篇:SSO场景系列:实现Microsoft AD到阿里云的单点登录


下一篇:(十) Spring Cloud构建分布式微服务架构 - SSO单点登录之OAuth2.0登录认证(1)