前几章讲到了通过Spring Cloud Ribbon和resttemplate实现客户端消费者调用,生产者提供的服务,而Spring Cloud openFeign还提供了一种比Ribbon更简单的服务调用方式 ——— 声明式服务调用
创建openfeign消费者服务cloud-feign-order80
第一步创建pom文件
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloud</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-feign-order80</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--swagger 整合swagger需要的依赖-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>cloud-api-conmmon</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--feign声明式服务的调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<fork>true</fork> <!-- fork: 如果没有配置该项配置,devtools不会起作用的,即应用不会restear -->
</configuration>
</plugin>
</plugins>
</build>
</project>
创建application.yml文件
server:
port: 80
spring:
application:
name: cloud-order-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
serviceUrl:
defaultZone: http://eureka7001.com:7001/eureka/ #集群版
编写启动类开启feign功能
package com.shiwen;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author wangjie
* @Title: OpenFeignApplication
* @Description: openfeign声明式服务的调用
* @company: 西安石文软件有限公司
* @date 2020/10/1411:11
*/
@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
public class OpenFeignApplication {
public static void main(String[] args) {
SpringApplication.run(OpenFeignApplication.class,args);
}
}
编写controller消费,服务提供者的接口
package com.shiwen.controller;
import com.shiwen.entity.CommonResult;
import com.shiwen.service.FeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author wangjie
* @Title: FeignController
* @Description: openfeign服务的调用
* @company: 西安石文软件有限公司
* @date 2020/10/1411:13
*/
@RestController
@RequestMapping("/order")
public class FeignController {
@Autowired
private FeignService feignService;
@GetMapping("/selete/{id}")
public CommonResult getUserById(@PathVariable Long id){
return feignService.selectOne(id);
}
}
使用fegin调用服务提供者的服务就是需要编写对应的service
package com.shiwen.service;
import com.shiwen.entity.CommonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @author wangjie
* @Title: FeignService
* @Description: feign接口
* @company: 西安石文软件有限公司
* @date 2020/10/1411:19
*/
@FeignClient("CLOUD-PAYMENT-SERVICE")
public interface FeignService {
@GetMapping("payment/select-one/{id}")
CommonResult selectOne(@PathVariable("id") Long id);
}
service中的 CLOUD-PAYMENT-SERVICE 服务提供者注册到eureka的服务名,@GetMapping("payment/select-one/{id}") 服务提供者的controller接口地址
启动单机版的eureka注册中心

启动cloud-provider-payment8001 和打包启动cloud-provider-payment8001 使用application-8002.yml配置文件启动 给注册中心注册两个服务8001,8002
访问http://localhost:80/order/selete/1

再次访问http://localhost:80/order/selete/1

也能实现两个服务的负载均衡调用,因为feign底层使用的还是ribbon的默认的轮巡算法实现负载调用的
openFeign的超时控制,openFeign默认消费者调用是1秒,超过1不在等待,直接报错连接超时
第一步再服务提供方写一个超时的接口
/**
* 编写超时程序
*/
@GetMapping("timeout")
public CommonResult timeOutMethods(){
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new CommonResult(200,"超时服务",serverPort);
}
第二不 openFeign调用服务
@RestController
@RequestMapping("/order")
public class FeignController {
@Autowired
private FeignService feignService;
@GetMapping("/selete/{id}")
public CommonResult getUserById(@PathVariable Long id){
return feignService.selectOne(id);
}
@GetMapping("/timeout")
public CommonResult getTimeOut(){
return feignService.timeOutMethods();
}
}
@FeignClient("CLOUD-PAYMENT-SERVICE")
public interface FeignService {
@GetMapping("payment/select-one/{id}")
CommonResult selectOne(@PathVariable("id") Long id);
@GetMapping("payment/timeout")
CommonResult timeOutMethods();
}
配置ribbon的超时时间
ribbon:
ConnectTimeout: 5000
ReadTimeout: 5000
如果没有配置就会报连接超时的错误,配置了消费者调用还会等待
openFeign日志打印功能
日志的级别

配置日志bean
package com.shiwen.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author wangjie
* @Title: OpenFeignConfig
* @Description: feign的日志配置bean
* @company: 西安石文软件有限公司
* @date 2020/10/1511:52
*/
@Configuration
public class OpenFeignConfig {
/**
* 日志的级别
* @return
*/
@Bean
Logger.Level feignLevel(){
return Logger.Level.FULL;
}
}
application.yml开启日志
logging:
level:
com.shiwen.config.OpenFeignConfig: debug
