文章目录
前言:
Spring Cloud系列教程的所有博客均在下方的目录链接中,方便大家查找和阅读。建议按照顺序学习,对于项目搭建有疑问的可以着重看目录里的第二篇博客。
Spring cloud学习专栏目录
一、简介
Feign是Netflix开发的声明式的Http客户端,使用时只需要创建一个接口,并在接口上添加注解就可以。Feign支持自带的注解和JAX-RS注解等。Spring cloud对Feign进行了增强,Feign支持了Spring MVC的注解,并且整合了Ribbon和Eureka,从而让Feign的使用更加方便。
二、对服务消费者添加Feign支持
问题回顾:
之前我们在服务消费者(车牌微服务)中是使用 RestTemplate调用REST服务,并且在启动类中添加了RestTemplate的实例。通过使用feign我们就不需要使用RestTemplate了。
2.1 pom文件添加依赖
找到服务消费者的父工程的pom文件,添加feign的依赖。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<groupId>com.springcloud</groupId>
<artifactId>microservice-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>microservice-provide-user</module>
<module>microservice-consumer-ticket</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- 导入Spring Cloud的依赖管理 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- web支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot 整合eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--整合hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- 健康监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- hystrix仪表盘 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!--整合fegnin客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 资源文件拷贝插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- springboot插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2 创建接口UserFeignClient
在服务消费者中新创建一个包,这里我起名为com.spring.ticketservice.feign
新建一个接口名为UserFeignClient,添加注解@FeignClient(value = " ") 其中value的值为用户微服务的application.name。接口的请求地址、返回值、参数等均参照UserController中定义的接口进行编写。
package com.spring.ticketservice.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.spring.ticketservice.pojo.User;
@FeignClient(value = "microservice-provide-user")
public interface UserFeignClient {
@RequestMapping(value = "/queryUserInfo/{id}", method = RequestMethod.GET)
public User queryUserInfo(@PathVariable("id") Long id);
}
2.3 修改服务消费者的service方法
删除RestTemplate的注入,注入刚编写好的UserFeignClient。
删除原先调用用户微服务接口的代码,改为调用UserFeignClient中的方法。
package com.spring.ticketservice.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.spring.ticketservice.feign.UserFeignClient;
import com.spring.ticketservice.pojo.User;
@Service
public class TicketService {
// @Autowired
// private RestTemplate restTemplate;
@Autowired
private UserFeignClient userFeignClient;
@Autowired
private LoadBalancerClient loadBalancerClient;
/*
* 查询车票信息时查询用户的信息(这里为了简化操作就不对车票信息进行查询,直接去调用查询用户信息的接口)
*/
@HystrixCommand(fallbackMethod = "queryTicketInfoFallbackMethod")
public User queryTicketInfo(Long id) {
String serviceId = "microservice-provide-user";
ServiceInstance serviceInstance = this.loadBalancerClient.choose(serviceId);
//打印出请求了哪个端口的用户微服务
System.out.println("请求了" + serviceInstance.getPort());
//向用户微服务中的接口发送请求的地址
// String url = "http://microservice-provide-user/getUserInfo/"+ id;
// return restTemplate.getForObject(url, User.class);
return userFeignClient.queryUserInfo(id);
}
/*
* 处理请求失败的方法
*/
public User queryTicketInfoFallbackMethod(Long id) {
User user = new User(0l,"出错了");
return user;
}
}
2.4 修改服务消费者的启动类
添加注解@EnableFeignClients,并且删除先前RestTemplate对象的添加。
2.5 启动服务进行测试
启动Eureka微服务、用户微服务、车票微服务。
访问车票微服务中的接口,可以看到请求成功。
2.6 注意事项
2.6.1 注解的使用
编写UserFeignClient时我们使用了注解@RequestMapping(value = “/queryUserInfo/{id}”, method = RequestMethod.GET),我们知道@GetMapping(value = “/queryUserInfo/{id}”)是一个组合注解,也就是说,这两个其实是一样的但是这里不能使用@GetMapping这种组合注解否则启动会报错。
2.6.2 多参数构造及复杂参数构造
当你的传参为如下所示的对象User时,你需要使用post方法,如果你使用了get方法会报错。因为这种情况下他会默认以post方法进行提交,而你规定的时get方法所有就会有冲突。
如果你想使用get方法,那么就把User对象中的参数一个一个写出来加上@RequestParam注解就可以了
三、设置统一的Hystrix fallback接口
问题回顾:
之前我们写fallback方法时是放在服务消费者(车票微服务)中的service类中。
但这样太杂乱不利用统一的管理,现在我们要把fallback方法单独拿出来放在一个类中。
3.1 修改服务消费者(车票微服务)的service方法
删除@hystrix注解以及之前编写的fallback方法
3.2 创建一个类TicketServiceFallback来管理fallback方法
新建一个包com.spring.ticketservice.fallback然后创建TicketServiceFallback类让他实现UserFeignClient接口,添加@Component注解并实现其中的方法。其实也就是把之前删掉的fallback方法移到了这里。
package com.spring.ticketservice.fallback;
import com.spring.ticketservice.feign.UserFeignClient;
import com.spring.ticketservice.pojo.User;
@Component
public class TicketServiceFallback implements UserFeignClient{
@Override
public User queryUserInfo(Long id) {
User user = new User(0l,"出错了");
return user;
}
}
3.3 修改UserFeignClient
3.4 修改配置文件
修改车票微服务的配置文件,开启断路器
# 配置api端口号
server.port=8082
# tomcat
server.tomcat.uri-encoding=UTF-8
# 服务名称,也就是在eureka
spring.application.name=microservice-consumer-ticket
# 是否启动注册,这是一个客户端需要注册
eureka.client.register-with-eureka=true
# 是否检索服务
eureka.client.fetch-registry=true
# 服务注册中心的地址
eureka.client.service-url.default-zone=http://localhost:8761/eureka
#eureka.client.service-url.default-zone=http://admin:123456@localhost:8761/eureka
#开放所有的节点
management.endpoints.web.exposure.include=*
#显示详细的健康信息
management.endpoint.health.show-details=always
#开启hystrix断路器
feign.hystrix.enabled=true
3.5 启动服务开始测试
启动eureka微服务、用户微服务、车票微服务。
首先访问 http://localhost:8082/getTicketInfo/1 可以看到现在接口是正常的。
———————————————————————————————————
然后我们将用户微服务停掉,再次访问可以看到fallback方法是生效的