微服务Spring Cloud配置Feign
我们在使用Spring Cloud Ribbon时,通常都会利用它对RestTemplate的请求拦截来实现对依赖服务的接口调用,而RestTemplate已经实现了对HTTP请求的封装处理,形成了一套模版化的调用方法。在之前的例子中,我们只是简单介绍了RestTemplate调用对实现,但是在实际开发中,由于对服务依赖对调用可能不止于一处,往往一个接口会被多处调用,所以我们通常都会针对各个微服务自行封装一些客户端累来包装这些依赖服务的调用。这个时候我们会发现,由于RestTemplate的封装,几乎每一个调用都是简单的模版化内容。综合上述这些情况,Spring Cloud Fegin在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义。在Spring Cloud Feign的实现下,我们只需创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了在使用Spring Cloud Ribbon时自行封装服务调用客户端的开发量。Spring Cloud Feign具备可插拔的注解支持,包括Feign注解和JAX-RS注解。同时,为了适应Spring的广大用户,它在Netflix Feign的基础上扩展了对Spring MVC的注解支持。这对于习惯于Spring MVC的开发者来说,无疑是一个好消息,你我这样可以大大减少学习适应它的成本。另外,对于Feign自身的一些主要组件,比如编码器和解码器等,它也以可插拔的方式提供,在有需求等时候我们以方便扩张和替换它们
1.首先,创建一个Spring Boot基础工程,取名为kyle-service-feign,并在pom.xml中引入spring-cloud-starter-eureka和spring-cloud-starter-feign依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.5.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
- 定义HelloServiceFeign,接口@FeignClient(value=“微服务对外提供的接口”)注解指定服务名来绑定服务,然后再使用Spring MVC的注解来绑定具体该服务提供的REST接口。
@FeignClient(value = "hello-service-provider")
public interface HelloServiceFeign {
@RequestMapping(value = "/demo/getHost", method = RequestMethod.GET)
public String getHost(String name);
@RequestMapping(value = "/demo/postPerson", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Person postPerson(String name);
}
注意:这里服务名不区分大小写,所以使用hello-service-provider和HELLO-SERVICE-PROVIDER都是可以的。另外,在Brixton.SR5版本中,原有的serviceId属性已经被废弃,若要写属性名,可以使用name或value。
3.接着,创建一个RestClientController来实现对Feign客户端的调用。使用@Autowired直接注入上面定义的HelloServiceFeign实例,并在postPerson函数中调用这个绑定了hello-service服务接口的客户端来向该服务发起/hello接口的调用。
@RestController
public class RestClientController {
@Autowired
private HelloServiceFeign client;
/**
* @param name
* @return Person
* @Description: 测试服务提供者post接口
* @create date 2018年5月19日上午9:44:08
*/
@RequestMapping(value = "/client/postPerson", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Person postPerson(String name) {
return client.postPerson(name);
}
/**
* @param name
* @return String
* @Description: 测试服务提供者get接口
* @create date 2018年5月19日上午9:46:34
*/
@RequestMapping(value = "/client/getHost", method = RequestMethod.GET)
public String getHost(String name) {
return client.getHost(name);
}
}
4.创建应用主类Application,并通过@EnableFeignClients注解开启Spring Cloud Feign的支持功能。
@EnableEurekaClient
@SpringBootApplication
@EnableFeignClients(basePackages = { "com.kyle.client.feign.inter" })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
最后,同Ribbon实现的服务消费者一样,需要在application.properties中指定服务注册中心,并定义自身的服务名为feign-service-provider,为了方便本地调试与之前的Ribbon消费者区分,端口使用8868。
#spring.application.name=ribbon-service-provider
eureka.instance.appname=feign-service-provider
eureka.instance.virtualHostName=feign-service-provider
eureka.instance.secureVirtualHostName=feign-service-provider
server.port=8868
eureka.instance.instance-id=${spring.cloud.client.ipAddress}:ribbon-service-provider-peer:${server.port}
#注册到另外两个节点,实现集群
eureka.client.serviceUrl.defaultZone=http://localhost:8887/eureka/,http://localhost:8888/eureka/,http://localhost:8889/eureka/
总结:Feign集成了Ribbon
利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息.并且通过轮询实现了客户端的负载均衡,而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以生成明的方法,简单实现了服务调用
OpenFeign服务接口调用(微服务调用接口+注解)
1.首先,创建一个Spring Boot基础工程,取名为cloud-consumer-feign-order80(消费端使用)
pom依赖修改:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
yml文件配置修改:
#spring.application.name=ribbon-service-provider
server.port=80
#注册到另外两个节点,实现集群
eureka.client.register-with-eureka: false
eureka.client.serviceUrl.defaultZone=http://localhost:8887/eureka/,http://localhost:8888/eureka/,http://localhost:8889/eureka/
主启动类添加注解@EnableFeignClients
2.新增paymentFeignService接口配置@FeignClient
调用提供者的接口
@component
@FeignClient(value = "微服务名称")
public interface PaymentFeignService{
@GetMapping(value = "/payment/get/{id}")
CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}
3.配置Controller层
@Restcontroller
public class OrderFeignController{
@Resource
private PaymentFeignService paymentFeignService;
@GetMapping(value = "/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
return paymentFeignService.getPaymentById(id);
}
}
OpenFeign超时控制
默认Feign客户端只等待一秒钟,但是服务端处理需要超过1秒钟,导致feign客户端不想等待了,直接返回报错,为了避免,需要设置feign客户端超时控制
yml文件开启配置
#设置feign客户端超时时间(openfeign默认支持ribbon)
ribbon:
#值的是建立连接所使用的的时间,适用于网络状况正常的情况,两端连接所使用的时间
ReadTimeout: 5000
#指的是建立连接后从服务器读取到可用资源所使用的时间
Connectimeout: 5000
OpenFeign日志打印功能
# 日志级别有四个
yml文件配置:
logging:
level:
#feign日志以什么级别监控哪个接口
com.atguigu.springcloud.service.PaymentFeignService: debug
添加配置类:
@Configuration
public class FeignConfig{
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}