Spring Cloud微服务之Feign——声明式服务间调用

目录

写在前面

服务间调用常见的方案

方案一:HttpClient

方案二:RestTemplate

方案三:Feign

框架版本问题及可能遇到的坑

搭建服务注册中心

搭建服务1——service-a

搭建服务2——service-b

在service-b中通过Feign调用service-a

进阶:Feign服务间调用—传递各种参数

再次进阶:引入Hystrix熔断器

总结


写在前面

在之前的 Spring Cloud微服务入门级教程(零基础,最详细,可运行) 文章中,我们搭建了一套基于Spring Cloud的微服务项目。在那个项目中,我们有两个相同的服务提供者和一个网关(Gateway),然后客户端直接访问我们的网关,由网关转发到两个相同的服务节点。这种情况其实只适用于所有API接口都混合在同一个服务下的项目,我们只是提供了多个服务实例来达到负载均衡,并没有真正的按照功能进行拆分。

在真正的微服务项目开发中,我们绝对不只是提供多个服务实例去负载均衡,要不然直接用Nginx不就行了吗?大部分情况是根据业务维度进行拆分,所以在特定的业务场景下就会出现服务间相互调用的需求。比如服务A需要调用服务B的接口,那么我们应该如何实现呢?

服务间调用常见的方案

方案一:HttpClient

这里说的HttpClient,指的是一类产品或方案,比如还有OkHttp系列的。这种方案,是最暴力的实现方式,直接通过Java代码模拟浏览器去调用接口,也是在最早的分布式系统中所使用的,因为那时候没有服务治理框架,只能这样去调用。但是这种方式,暴力不代表不合理。在当下,依赖第三方接口的开发只能用这种方式去调用,比如微信公众号开发中的相关API接口。

这种方式呢,调用一个接口比较繁琐,大体的流程一致:先获取一个client对象,然后要构建request对象、接收response对象,如果有请求头还需要Header对象,如果是https的还要处理SSL。传参的话也不是很灵活,get请求还好说,post请求简直就是噩梦,特别是写到请求体里的body传参方式……

方案二:RestTemplate

在微服务的架构下,我们有服务治理中心,当然不会通过上面的方式去调用啦……

RestTemplate是Spring Cloud提供的一种服务间调用解决方案,它虽然利用了服务治理中心来调取服务,但是我感觉它就是穿着华丽外衣的HttpClient,看一下它的调用方式:

它在调用接口的时候,依然会让你传入一个url,只不过通过HttpClient调用接口时传入的url是一个可以外网访问的唯一http地址,而RestTemplate传入的url,是把域名换成了服务名,然后根据服务名去注册中心找对应的服务。

什么意思呢?下面看一个例子。

假如我们有一个服务,在注册中心的服务名叫做service-a,这个service-a服务下面有一个接口,地址是/student/list,假设域名www.test.com可以直接定位到service-a服务。同时注册中心有service-b,需要调用service-a的这个接口,那么如果我们通过HttpClient去调用这个服务接口,那传入的url就是http://www.test.com/student/list,这样显然没有通过我们的注册中心来获取服务;如果我们通过RestTemplate去调用,那就是http://service-a/student/list。

上面的例子,RestTemplate就会根据服务名称去注册中心寻找对应的服务,将请求转发过去。如果运用了Ribbon的话,还会实现负载均衡的效果:注册中心将所有此名称的服务实例清单返回,然后从这些服务清单中任选一个服务进行请求转发。

RestTemplate的传参、请求体的设置、请求头的设置,和HttpClient的流程如出一辙,比较繁琐,不够优雅,区别就是可以利用服务治理中心来达到了负载均衡。

方案三:Feign

接下来说说我们今天的主角,Feign。它是对RestTemplate和Ribbon的封装,让我们的服务间调用更加方便、更加简洁,实现声明式的服务调用,具体什么意思呢?

我们在使用Feign进行服务间调用时,只需要在调用方建一个interface接口,并且加上@FeignClient注解将其声明为一个服务调用客户端,并且进行相关的注解赋值,就可以调用其他服务了!

实践出真知,下面我们就来代码实战。

框架版本问题及可能遇到的坑

笔者使用的Spring Boot版本是2.2.2.RELEASE,Spring Cloud版本是Hoxton.RELEASE,JDK版本是10,不同版本的框架所使用的maven依赖可能是不同的,如果你的版本不对,可能会导致依赖下载不下来。

另外笔者用的是IDEA自带的maven,不是自己安装配置的,所以如果你也要使用的话,请在如下地方进行设置:

如果大家在搭建过程中遇到其他问题,请在下方进行评论留言或私信,我会及时查看。

搭建服务注册中心

开发工具是IDEA,怎样创建项目我就不说了,在Spring Cloud微服务入门级教程(零基础,最详细,可运行)里写的很详细。需要注意的是,在创建项目的时候要勾选上eureka依赖:

项目创建好之后,目录结构如下:

然后我们在启动类上面添加注解@EnableEurekaServer,表明这是一个服务注册中心:

package com.demo.feign.register;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;


@SpringBootApplication
@EnableEurekaServer
public class DemoRegisterApplication {

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

}

然后在配置文件填写如下配置(注意我的后缀是yml,如果你的是properties请修改格式):

# 端口8080
server:
  port: 8080

# 禁止注册自己
eureka:
  client:
    fetch-registry: false
    register-with-eureka: false
    service-url:
      defaultZone: http://localhost:8080/eureka/

搭建服务1——service-a

这里我们将service-a作为一个服务,待会建一个service-b来调用service-a。

这里我们选择的依赖有Web、eureka-client、lombok(需单独在IDEA进行安装),对应的依赖如下:

然后我们需要在启动类添加注解,表明这是一个服务客户端:

package com.cloud.feign.servicea;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
public class ServiceAApplication 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值