文章目录
上一节学习了注册中心,我们知道服务器A调用服务器B之前,会从注册中心获取到服务B的IP,然后服务器A向服务B发出请求。
那么服务器A是怎么向服务B发出请求的呢?
这是本节要解决的主要问题。
在这个项目中,采用OpenFeign这个组件完成服务间的调用,OpenFeign是对Http请求的封装。
一,OpenFeign的简介
OpenFeign是一个声明式的 HTTP 客户端,它的目的就是让远程调用更加简单。
Feign 提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好 HTTP 请求的参数、格式、地址等信息。
Feign 整合了 Ribbon(负载均衡)和 Hystrix(服务熔断),可以让我们不再需要显式地使用这两个组件。
SpringCloudFeign 在 NetflixFeign 的基础上扩展了对 SpringMVC 注解的支持,在其实现下,我们只需创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定。简化了SpringCloudRibbon 自行封装服务调用客户端的开发量。
二,OpenFeign的使用步骤
1,场景说明
我们以一个场景化的问题学习OpenFeign的使用,假设会员服务
要调用优惠券服务
的一个接口,这个接口返回了会员的能使用的优惠券信息。
这个优惠券的接口如下,这是一个用来测试的接口,没有真实的业务逻辑。
bash
@RequestMapping("member/list")
public R list(){
CouponEntity couponEntity = new CouponEntity();
couponEntity.setCouponName("慢100减80");
return R.ok().put("page", Arrays.asList(couponEntity));
}
启动服务后,可以使用下面的url在浏览器访问这个接口。
bash
http://localhost:7000/coupon/coupon/member/list
浏览器调用这个接口,发出的是Http请求。
会员服务要使用这个接口,也要想优惠券服务发出Http请求,如果没有OpenFeign,我们需要自己封装Http请求,并解析Http响应,会非常复杂。
使用OpenFeign可以大大简化这个过程。
2,引入依赖
考虑到所有模块都需要这个依赖,所以把这个依赖声明放在common模块最为合适。
bash
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2,开启OpenFeign
需要在启动类加上类注解@EnableFeignClients
,并通过basePackages属性明确feign接口所在的包。
bash
@EnableFeignClients(basePackages = "com.atguigu.gulimall.pms.feign")
@EnableFeignClients
是激活OpenFeign的关键,在 Spring Boot 应用的启动类加上这个注解,就相当于告诉 Spring:"嘿,我要开始使用 Feign 啦!请帮我找到所有用 @FeignClient 标记的接口,并为它们创建代理对象。"
这样,Spring 就会扫描basePackages指定的包下的所有类,寻找那些用 @FeignClient 注解过的接口。对于每一个这样的接口,Spring 都会创建一个代理类,这个代理类看起来就像你在调用本地方法一样,但实际上它是在发起远程调用。
总结一下,@EnableFeignClients
的作用就是:
- 开启 Feign 的功能;
- 扫描并注册所有用 @FeignClient 标记的接口;
- 创建代理类,使得你能够以声明式的方式调用远程服务,就像调用本地方法一样简单。
3,编写Feign接口
首先在会员工程下新建一个包,名为feign,我们把所有Feign声明相关的类都放在这个包下,便于管理。
如下图所示。
- ①所有的远程调用相关的类都定义在feign包下
- ②与优惠券相关的远程调用接口的定义都可以放在这个类中,通过这个类调用优惠券服务的接口
- ③使用注解@FeignClient指定这个类下的接口要调用是哪个服务,在FeignClient中指定服务名,需要根据服务名从注册中心获取IP
- ④Feign相关的类是一个接口,不需要提供具体的实现
- ⑤声明远程接口,注意通过url指定需要调用的接口
bash
@FeignClient("gulimall-coupon")
public interface CouponFeign {
@RequestMapping("/coupon/coupon/member/list")
public R list();
}
4,使用feign调用远程接口
一般情况下,我们会在Service中调用Feign接口,但理论上,我们可以在任何地方调用Feign接口。
接下来,为了演示的方便,我们在Member会员服务的Controller接口中调用Feign接口。
如下,我们在MemberController中编写演示代码。
bash
@Autowired
private CouponFeign couponFeign;
@RequestMapping("/coupons")
public R coupons(){
return couponFeign.list();
}
- ① 注入CouponFeign对象
- ② 调用CouponFeign的list方法,就像调用本地接口一样,OpenFeign底层会将这个调用封装为Http请求,并接收、封装响应
通过这个例子,我们可以体验到使用OpenFeign进行远程调用是非常简单的,语法和调用本地接口一样。
5,验证
启动会员服务,在浏览器输入:
bash
http://localhost:8000/member/member/coupons
我们调用的是会员服务的接口,但是会员服务通过OpenFeign实现对优惠券服务的远程调用。