8.14日学习打卡---Spring Cloud Alibaba(二)

8.14日学习打卡

在这里插入图片描述

分布式服务调用

什么是服务调用

在这里插入图片描述
两大主流远程调用技术
在这里插入图片描述
RESTful

Http其实是一种网络传输协议,基于TCP,规定了数据传输的格式。 现在客户端浏览器与服务端通信基本都是采用Http协议,也可以用来进行远程服务调用。缺点是消息封装臃肿,优势是对服务的提供和调用方没有任何技术限定,自由灵活,更符合微服务理念。现在热门的Rest风格,就可以通过Http协议来实现。

实现方案
Java开发中,使用Http连接,访问第三方网络接口,通常使用的连接工具为RestTemplate、HttpClient和OKHttp。

RPC协议
Remote Produce Call远程过程调用,类似的还有RMI(remote method invoke)。自定义数据格式,基于原生TCP通信,速度快,效率高

在这里插入图片描述

基于RPC协议的相关框架

  • Dubbo:国内最早开源的 RPC 框架,由阿里巴巴公司开发并于 2011 年末对外开源,仅支持 Java 语言。
  • SpringCloud:国外 Pivotal 公司 2014 年对外开源的 RPC 框架,提供了丰富的生态组件。
  • gRPC:Google 于 2015 年对外开源的跨语言 RPC 框架,支持多种语言。

通信性能方面

从通信的性能上来分析基于Http传输协议,底层实现是Rest。从OSI 7层模型上来看Rest属于应用层。

注意
在高并发场景下性能不够理想,成为性能瓶颈。

  • Dubbo框架的通信协议采用RPC协议,属于传输层协议,性能上自然比Rest高。提升了交互的性能,保持了长连接,高性能。

注意
Dubbo性能更好,比如支持异步调用、Netty性能更好

什么是RPC

在这里插入图片描述
RPC(Remote Procedure Call)远程过程调用,它是一种通过网络从远程计算机程序上请求服务。

大白话理解就是:RPC让你用别人家的东西就像自己家的一样。

RPC两个作用:

  • 屏蔽远程调用跟本地调用的区别,让我们感觉就是调用项目内的方法
  • 隐藏底层网络通信的复杂性,让我们更加专注业务逻辑。

常用的RPC框架
RPC是一种技术思想而非一种规范或协议。

常见 RPC 技术和框架:

阿里的 Dubbo/Dubbox、Google gRPC、Spring Cloud。

什么是Dubbo

Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang、Rust 等多语言 SDK 实现。

为什么需要Dubbo,它能做什么?

按照微服务架构的定义,采用它的组织能够很好的提高业务迭代效率与系统稳定性,但前提是要先能保证微服务按照期望的方式运行,要做到这一点需要解决服务拆分与定义、数据通信、地址发现、流量管理、数据一致性、系统容错能力等一系列问题。

在这里插入图片描述
Dubbo 可以帮助解决如下微服务实践问题:

微服务编程范式和工具

Dubbo 支持基于 IDL 或语言特定方式的服务定义,提供多种形式的服务调用形式(如同步、异步、流式等)

高性能的 RPC 通信

Dubbo 帮助解决微服务组件之间的通信问题,提供了基于 HTTP、HTTP/2、TCP 等的多种高性能通信协议实现,并支持序列化协议扩展,在实现上解决网络连接管理、数据传输等基础问题。

微服务监控与治理

Dubbo 官方提供的服务发现、动态配置、负载均衡、流量路由等基础组件可以很好的帮助解决微服务基础实践的问题。除此之外,您还可以用 Admin 控制台监控微服务状态,通过周边生态完成限流降级、数据一致性、链路追踪等能力。

部署在多种环境

Dubbo 服务可以直接部署在容器、Kubernetes、Service Mesh等多种架构下。

活跃的社区

Dubbo 项目托管在 Apache 社区,有来自国际、国内的活跃贡献者维护着超 10 个生态项目,贡献者包括来自海外、阿里巴巴、工商银行、携程、蚂蚁、腾讯等知名企业技术专家,确保 Dubbo 及时解决项目缺陷、需求及安全漏洞,跟进业界最新技术发展趋势。

庞大的用户群体

Dubbo3 已在阿里巴巴成功取代 HSF 框架实现全面落地,成为阿里集团面向云原生时代的统一服务框架,庞大的用户群体是 Dubbo 保持稳定性、需求来源、先进性的基础。

Dubbo 不是什么?
在这里插入图片描述
不是应用开发框架的替代者

Dubbo 设计为让开发者以主流的应用开发框架的开发模式工作,它不是各个语言应用开发框架的替代者,如它不是 Spring/Spring Boot 的竞争者,当你使用 Spring 时,Dubbo 可以无缝的与 Spring & Spring Boot 集成在一起。

不仅仅只是一款 RPC 框架

Dubbo 提供了内置 RPC 通信协议实现,但它不仅仅是一款 RPC 框架。首先,它不绑定某一个具体的 RPC 协议,开发者可以在基于 Dubbo 开发的微服务体系中使用多种通信协议;其次,除了 RPC 通信之外,Dubbo 提供了丰富的服务治理能力与生态。

不是 gRPC 协议的替代品

Dubbo 支持基于 gRPC 作为底层通信协议,在 Dubbo 模式下使用 gRPC 可以带来更好的开发体验,享有统一的编程模型和更低的服务治理接入成本

不只有 Java 语言实现
自 Dubbo3 开始,Dubbo 提供了 Java、Golang、Rust、Node.js 等多语言实现,未来会有更多的语言实现。

任意通信协议

Dubbo 微服务间远程通信实现细节,支持 HTTP、HTTP/2、gRPC、TCP 等所有主流通信协议。与普通 RPC 框架不同,Dubbo 不是某个单一 RPC 协议的实现,它通过上层的 RPC 抽象可以将任意 RPC 协议接入 Dubbo 的开发、治理体系。
在这里插入图片描述
多语言 SDK

Dubbo 提供几乎所有主流语言的 SDK 实现,定义了一套统一的微服务开发范式。Dubbo 与每种语言体系的主流应用开发框架做了适配,总体编程方式、配置符合大多数开发者已有编程习惯。
在这里插入图片描述

将支付微服务集成Dubbo

创建公共接口子模块
新建jjy-interface子模块

编写接口
创建公共支付接口类。

/**
 * 支付接口
 */
public interface IPaymentService {


  /**
   * 根据订单id支付
   * @param id
   * @return
   */
  String payment(Integer id);


}

创建支付子模块
创建子模块jjy-payment-dubbo

引入依赖包

<dependencies>
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>


    <dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo-spring-boot-starter</artifactId>
    </dependency>


    <dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo-registry-nacos</artifactId>
    </dependency>


    <dependency>
      <groupId>com.itbaizhan</groupId>
      <artifactId>itbaizhan-interface</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>

编写配置文件
在main文件夹下面创建resources文件夹,在resources里面新建application.yml文件。

dubbo:
  application:
  #项目名字
   name: payment-service
  protocol:
  # 通讯协议
   name: dubbo
  # 端口号 设置端口为 -1 表示 dubbo 自动扫描并使用可用端口(从20880开始递增),避免了端口冲突的问题。
   port: -1
  registry:
  # 注册地址
   address: nacos://192.168.47.100:8848


server:
  port: 8004

编写主启动类

/**
 * 支付微服务主启动类
 */
@Slf4j
@EnableDubbo
@SpringBootApplication
public class PaymentSpringApplication {
  public static void main( String[] args )
   {
    SpringApplication.run(PaymentSpringApplication.class,args);
    log.info("************** 支付服务启动成功 ************");
   }
}

编写支付接口实现类

@DubboService
public class IPaymentServiceImpl implements IPaymentService{
  @Override
  public String payment(Integer id) {
    return " payment success ";
   }
}

控制台查看支付微服务
在浏览器输入http://192.168.47.100:8848/nacos查看支付微服务。
在这里插入图片描述

将订单微服务集成Dubbo

创建子模块
创建子模块jjy-order-dubbo

引入依赖包


<dependencies>
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo-spring-boot-starter</artifactId>
    </dependency>

    <dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo-registry-nacos</artifactId>
    </dependency>

    <dependency>
      <groupId>com.itbaizhan</groupId>
      <artifactId>itbaizhan-interface</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>

编写配置文件
在main文件夹下面创建resources文件夹,在resources里面新建application.yml文件。

dubbo:
  application:
  #项目名字
   name: order-service
  protocol:
  # 指定协议名称。默认使用dubbo 。
   name: dubbo
  # 端口号 设置端口为 -1 表示 dubbo 自动扫描并使用可用端口(从20880开始递增),避免了端口冲突的问题。
   port: -1
  registry:
  # 注册地址
   address: nacos://192.168.47.100:8848


server:
  port: 81

编写主启动类

/**
 * 订单微服务主启动类
 */
@Slf4j
@EnableDiscoveryClient//向注册中心注册该服务,并可以获取其他服务的调用地址
@SpringBootApplication
public class OrderSpringApplication
{
  public static void main( String[] args )
   {
    SpringApplication.run(OrderSpringApplication.class,args);
    log.info("************** 订单服务启动成功 ************");
   }
}

编写订单控制层
创建controller文件夹,在文件夹中创建OrderController类。

@RestController
public class OrderController {
  
  @DubboReference
  IPaymentService iPaymentService;


  @GetMapping("/getPayment")
  public String payment(){
    return iPaymentService.getPayment(1);
   }


}

浏览器进行测试
在浏览器输入http://localhost:81/getPayment查看支付情况。

Dubbo启动时检查

概述
Dubbo在启动时检查依赖得服务是否可用,Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check="true"

@DubboReference(check = false)
private IOrdersService iOrdersService;

注意
如果你的 Spring 容器是懒加载的,或者通过 API 编程延迟引用服务,请关闭 check,否则服务临时不可用时,会抛出异常,拿到 null 引用,如果 check="false",总是会返回引用,当服务恢复时,能自动连上。

Dubbo地址缓存

在这里插入图片描述
地址缓存
注册中心挂了,服务是否可以正常访问?

答案:

因为Dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后在调用则不会访问注册中心。服务提供者地址发生变化时,注册中心会通服务消费者。

演示
关闭注册中心

./shutdown.sh

远程调用服务
http://localhost:8080/findByUserId?userId=1

Dubbo超时时间与配置覆盖关系

超时机制在这里插入图片描述

问题:

  • 服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去。
  • 在某个峰值时刻,大呈的请求都在同时请求服务消费者,会造成线程的大呈堆积,势必会造成雪崩。

Dubbo解决机制
Dubbo利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接。

配置超时时间
服务生产者端
使用timeout属性配置超时时间,默认值1000,单位毫秒。

@DubboService(timeout = 3000)
public class PaymentServiceImpl implements IPaymentService{
  
    public String payment(String id) {
    //TODO 模拟数据库操作 突然数据库操作很慢
    try {
      Thread.sleep(4000);
     } catch (InterruptedException e) {
      throw new RuntimeException(e);
     }
    return "hello dubbo";
   }
}

消费端

@DubboReference(timeout = 2000)// 远程注入
private IOrderService iOrderService;

报错

com.alibaba.Dubbo.remoting.TimeoutException: Waiting server-side response timeout
com.alibaba.Dubbo.remoting.exchange.support.DefaultFuture.get(DefaultFuture.java:107) ~[Dubbo-2.5.3.jar:2.5.3]
com.alibaba.Dubbo.remoting.exchange.support.DefaultFuture.get(DefaultFuture.java:84) ~[Dubbo-2.5.3.jar:2.5.3]
com.alibaba.Dubbo.rpc.protocol.Dubbo.DubboInvoker.doInvoke(DubboInvoker.java:96) ~[Dubbo-2.5.3.jar:2.5.3]

超时设置的优先级
上面有提到Dubbo支持多种场景下设置超时时间,也说过超时是针对消费端的。那么既然超时是针对消费端,为什么服务端也可以设置超时呢?
在这里插入图片描述

总结:

这其实是一种策略,其实服务端的超时配置是消费端的缺省配置,即如果服务端设置了超时,任务消费端可以不设置超时时间,简化了配置。另外针对控制的粒度,Dubbo支持了接口级别也支持方法级别,可以根据不同的实际情况精确控制每个方法的超时时间

Dubbo重试机制

重试机制
在这里插入图片描述

超时问题
如果出现网络抖动,则会出现请求失败。

如何解决
Dubbo提供重试机制来避免类似问题的发生。

重试机制配置

@DubboReference(timeout = 3000,retries = 2)

注意:

Dubbo在调用服务不成功时,默认会重试2次。

Dubbo多版本

在这里插入图片描述

Dubbo提供多版本的配置,方便我们做服务的灰度发布,或者是解决不兼容的问题。

在这里插入图片描述

灰度发布(金丝雀发布):

当出现新功能时,会让一部分用户先使用新功能,用户反馈没问题时,再将所有用户迁移到新功能。

版本迁移步骤
1.在低压力时间段,先升级一半提供者为新版本
2.再将所有消费者升级为新版本
3.然后将剩下的一半提供者升级为新版本

多版本配置
老版本服务提供者配置

@DubboService(version = "1.0.0")
public class PaymentServiceImpl implements IPaymentService{




  /**
   * 支付
   * @param id 订单id
   * @return
   */
  @Override
  public String payment(String id) {
    return "hello dubbo";
   }




}

新版本服务提供者配置

@DubboService(version = "2.0.0")
public class PaymentServiceImpl implements IPaymentService{


  /**
   * 支付
   * @param id 订单id
   * @return
   */
  @Override
  public String payment(String id) {
    return "hello itbaizhan";
   }
}

新版本服务消费者配置

@DubboReference(version = "1.0.0")
private IPaymentService iPaymentService;

如果不需要区分版本,可以按照以下的方式配置 :

@DubboReference(version = "*")
private IOrderService iOrderService;// 订单服务

Dubbo负载均衡

在这里插入图片描述

Dubbo是一个分布式服务框架,能避免单点故障和支持服务的横向扩容。一个服务通常会部署多个实例。
在这里插入图片描述

问题:
订单服务生产者会出现单点故障。


如何从多个服务 Provider 组成的集群中挑选出一个进行调用,就涉及到一个负载均衡的策略。

Dubbo内置负载均衡策略
1.RandomLoadBalance:随机负载均衡,随机的选择一个,默认负载均衡。
2.RoundRobinLoadBalance:轮询负载均衡。
3.LeastActiveLoadBalance:最少活跃调用数,相同活跃数的随机。
4.ConsistentHashLoadBalance:一致性哈希负载均衡,相同参数的请求总是落在同一台机器上。

负载均衡策略配置
如果不指定负载均衡,默认使用随机负载均衡。我们也可以根据自己的需要,显式指定一个负载均衡。

生产者服务

@DubboService(loadbalance = "roundrobin")

消费者服务

@DubboReference(loadbalance = "roundrobin")

参数:

random:随机负载均衡 leastactive:最少活跃调用数,相同活跃数的随机 roundrobin:轮询负载均衡
consistenthash:一致性哈希负载均衡

Dubbo集群容错

在这里插入图片描述
集群容错模式

Dubbo框架为服务集群容错提供了一系列好的解决方案,在此称为Dubbo服务集群容错模式。
在这里插入图片描述
容错模式

  • Failover Cluster:失败重试。默认值。当出现失败,重试其它服务器,默认重试2次,使用retries配置。一般用于读操作
  • Failfast Cluster : 快速失败,只发起一次调用,失败立即报错。通常用于写操作。
  • Failsafe Cluster : 失败安全,出现异常时,直接忽略,返回一个空结果。日志不重要操作。
  • Failback Cluster : 失败自动恢复,后台记录失败请求,定时重发。非常重要的操作。
  • Forking Cluster:并行调用多个服务器,只要有一个成功即返回。
  • Broadcast Cluster:广播调用所有提供者,逐个调用,任意一台报错则报错。 同步要求高的可以使用这个模式。

集群容错配置
在消费者服务配置

@DubboReference(cluster = "failover")
private IOrderService iOrderService;

Dubbo中序列化协议安全

在这里插入图片描述
为什么需要序列化
网络传输的数据必须是二进制数据,但调用方请求的出入参数都是对象。
在这里插入图片描述

总结

序列化就是将对象转换成二进制数据的过程,而反序列就是反过来将二进制转换为对象的过程。

序列化反序列过程
在这里插入图片描述

流程
比如发快递,我们要发一个需要自行组装的物件。发件人发之前,会把物件拆开装箱,这就好比序列化;这时候快递员来了,不能磕碰呀,那就要打包,这就好比将序列化后的数据进行编码,封装成一个固定格式的协议;过了两天,收件人收到包裹了,就会拆箱将物件拼接好,这就好比是协议解码和反序列化。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中北萌新程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值