前言: 微服务会把一个大项目拆分成多个独立的小服务,这些小服务之间的调用采用的是Http Restful和RPC调用。一般来说,各大企业内部服务调用为了保证性能会采用PRC,而对外开放的API接口则会采用Restful风格。Spring Cloud Alibaba不仅支持基于Ribbon的OpenFegin代表的Rest方式,也可以用Dubbo组件代替Rest方式。这样既可保证到RPC服务调用的卓越性能,还可以享受到SpringCloud微服务的一站式解决方案

一、Ribbon、Feign和OpenFeign的区别

Spring Cloud提供了Ribbon+RestTemplate 服务调用的Rest方式,其中Ribbon是一个负载均衡的客户端,RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版。

1.1、Ribbon客户端负载均衡

Ribbon 是 Netflix开源的基于HTTP和TCP等协议负载均衡组件,可以用来做客户端负载均衡,需要配合RestTemplate一起使用,可以调用注册中心的服务。

Ribbon的使用需要代码里手动调用目标服务,直接用的服务名替代了具体的url地址,在发起请求时Ribbon根据服务名来选择具体服务实例的url替换掉服务名。

1.2、Feign服务调用,负载均衡

Feign是Netfilx开源中的一个轻量级RESTful的HTTP客户端。Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。

Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务。Feign本身不支持Spring MVC的注解,它有一套自己的注解。

1.3、OpenFeign

OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等等,故推荐直接使用OpenFeign

OpenFeign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。

OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。


二、OpenFeign快速集成

前面已经搭建Spring Cloud Alibaba项目骨架如下:

 并且两个微服务order-service和product-service已经注册到Nacos服务中心:

 2.1、order-service引入OpenFeign依赖

  <!--openfeign服务调用 -->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>

2.2、主启动类加上注解@EnableFeignClients注解,开启Feign支持

@EnableFeignClients申明该项目是Feign客户端,扫描对应的Feign Client。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

2.3 创建FeignClient接口,并添加注解(指定需要调用的服务和接口)

新增服务提供者API接口,我们需要集中化管理API,就可以通过接口统一管理,需要新增商品服务的接口类ProductService。

首先添加@FeignClient(name="product-service")注解,其中name就是我们要访问的微服务提供者的名称;然后hiProduct方法中@RequestMapping("product")和服务提供者product-service中的接口路径是一样的。

package com.hs.order.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

//value:指定要调用的微服务的名称
@FeignClient(value ="product-service")
public interface ProductService {

    //指定服务提供者的接口和访问路径,以进行后续的远程访问
    @RequestMapping("/product")
    String hiProduct();

}

2.4、在Controller中注入后,发起远程调用

import com.hs.order.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OrderController {

    @Autowired
    private ProductService productService;

    @RequestMapping(value = "/remoteProduct")
    public String remoteProduct()
    {
        String str = productService.hiProduct();
        return str;
    }
}

2.5、RestfulTool进行测试:访问http://localhost:9001/remoteProduct

 我们可以看到已经利用Openfeign 成功进行远程微服务调用

2.6、OpenFeign超时控制

OpenFeign远程调用的默认等待时长为1秒,超时后报错

 解决方案:在消费者服务的application.yml文件中设置超时时间

# 设置fegin客户端的超时时间
ribbon:
  # 设置获取资源超时时间
  ReadTimeout: 5000
  # 设置建立连接的超时时间
  ConnectTimeout: 5000

三、Spring Cloud Alibaba整合Dubbo实现RPC服务调用

3.1、Spring Cloud Alibaba整合Dubbo进行服务通信

Spring Cloud Alibaba的服务间通信也可以用dubbo组件代替Rest风格。这样既可保证到RPC服务调用的卓越性能,还可以享受到SpringCloud微服务的一站式解决方案。

很早以前,在刚开始搞Spring Cloud基础教程的时候,写过这样一篇文章:《微服务架构的基础框架选择:Spring Cloud还是Dubbo?》,可能不少读者也都看过。之后也就一直有关于这两个框架怎么选的问题出来,其实文中我有明确的提过,Spring Cloud与Dubbo的比较本身是不公平的,主要前者是一套较为完整的微服务架构方案,而Dubbo只是服务治理与RPC实现方案。

由于Dubbo在国内有着非常大的用户群体,但是其周边设施与组件相对来说并不那么完善。很多开发者用户又很希望享受Spring Cloud的生态,因此也会有一些Spring Cloud与Dubbo一起使用的案例与方法出现,但是一直以来大部分Spring Cloud整合Dubbo的使用方案都比较别扭。这主要是由于Dubbo的注册中心采用了ZooKeeper,而开始时Spring Cloud体系中的注册中心并不支持ZooKeeper,所以很多方案是存在两个不同注册中心的,之后即使Spring Cloud支持了ZooKeeper,但是由于服务信息的粒度与存储也不一致。所以,长期以来,在服务治理层面上,这两者一直都没有一套完美的融合方案。直到Spring Cloud Alibaba的出现,才得以解决这样的问题。

在之前的教程中,我们已经介绍过使用Spring Cloud Alibaba中的Nacos来作为服务注册中心,并且在此之下可以如传统的Spring Cloud应用一样地使用Ribbon或Feign来实现服务消费。这篇,我们就来继续说说Spring Cloud Alibaba下额外支持的RPC方案:Dubbo。       

                                                                                            ——引用这段话来源于下面大神的博客Spring Cloud与Dubbo的完美融合之手「Spring Cloud Alibaba」

通过上面所示的例子,如果你曾经同时玩过Spring Cloud和Dubbo,一定会深有感触。你不用再同时顾虑Eureka和Zookeeper的配置,也不同同时关注这两个中间件的健康,只需要关注和维护好Nacos一个即可。而对于Dubbo的配置和使用来说,配置还是相当简单的,而代码编写上与以往的Dubbo没什么大的不同。在Spring Cloud Alibaba的整合之下,Dubbo用户既可以享受到原本RPC带来性能优势,又可以更好的享受Spring Cloud的各种福利;而对于Spring Cloud用户来说,在服务治理层面,又对了一个不错的可选项。可以说这块的整合是真正的让这两大用户群体得到了很好的融合,起到了互相成就的作用。

3.2、Dubbo简介

Dubbo是阿里巴巴公司开源的一个高性能优秀的RPC服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。

①Dubbo架构

Provider: 暴露服务的服务提供方。

Consumer: 调用远程服务的服务消费方。

Registry: 服务注册与发现的注册中心。(常见Zookeeper作为注册中心)

Monitor: 统计服务的调用次数和调用时间的监控中心。(Dubbo Admin)

②Dubbo调用流程

0.服务容器负责启动,加载,运行服务提供者。

1.服务提供者在启动时,向注册中心注册自己提供的服务。

2.服务消费者在启动时,向注册中心订阅自己所需的服务。

3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

6 Dubbo程序开发

③Dubbo项目结构

主要分三大模块:

dubbo-api : 存放公共接口;(本地的jar包上传到公司maven仓库)

dubbo-provider : 提供远程服务;

dubbo-consumer :调用远程服务。

④ Dubbo 服务接口简介

Dubbo 服务接口是服务提供方与消费方的远程通讯契约,通常由普通的 Java 接口(interface)来声明,如 EchoService 接口:

为了确保契约的一致性,推荐的做法是将 Dubbo 服务接口打包在第二方或者第三方的 artifact(jar)中,如以上接口就存放在 artifact spring-cloud-dubbo-sample-api 之中。

对于服务提供方而言,不仅通过依赖 artifact 的形式引入 Dubbo 服务接口,而且需要使用Dubbo的@Service注解将其实现。对应的服务消费端,同样地需要依赖该 artifact,并加上Dubbo的@Reference注解以接口调用的方式执行远程方法。


参考链接:

Ribbon快速入门

SpringCloud远程调用-OpenFeign

Dubbo使用Nacos注册中心  (重点)

Springboot+Dubbo+Nacos 注解方式实现微服务调用  (重点)

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐