浅谈Spring Cloud OpenFeign
OpenFeign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。
Spring Cloud OpenFeign以将OpenFeign集成到Spring Boot应用中的方式。首先利用了OpenFeign的声明式方式定义Web服务客户端;其次还更进一步,通过集成Ribbon或Eureka实现负载均衡的HTTP客户端。
Feign底层是ribbon
Openfeign快速入门
Provider端
.yml
server:
port: 8080
spring:
application:
name: provider-server #应用名称
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
User(消费端)
server:
port: 8081
spring:
application:
name: user-server #应用名称
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
#设置超时时间
ribbon:
ReadTimeout: 3000 # 3秒
ConnectTimeout: 3000 #连接服务的超时时间
OpenFeign调用参数处理(重点)
@PathVariable注解:获取url中的数据
解决映射名称不一致问题(提交请求参数的action的形参名称不一致,使用@RequestParam注解解析)
Feign传参确保消费者和提供者的参数列表一致包括返回值方法签名要一致
1.通过URL传参数,GET请求,参数列表使用@PathVariable (“”)
2.如果是GET请求,每个基本参数必须加回 @Requestparam(“”)
3.如果是posT请求,而且是对象集合等参数,必须加@ Requestbody或者@ Requestparam
provider-service端
@RestController
public class ParamController {
//url传参
@GetMapping("param/{name}/{age}")
public String param(@PathVariable("name") String name,@PathVariable("age") int age){
System.out.println("姓名: "+name+" 年龄 "+age);
return "姓名: "+name+" 年龄 "+age;
}
@GetMapping("getParam")
public String getParam(@RequestParam(required = false) String name){
System.out.println("姓名: "+name);
return "姓名: "+name;
}
@GetMapping("twoParam")
public String twoParam(@RequestParam(required = false) String name,@RequestParam(required = false)int age){
System.out.println("姓名: "+name+" 年龄 "+age);
return "姓名: "+name+" 年龄 "+age;
}
@PostMapping("oneObject")
public String oneObject(@RequestBody User user){
System.out.println(user.toString());
return user + "";
}
}
User-service端
@FeignClient(value = "provider-server") //提供者的应用名称
public interface UserProviderFeign {
@GetMapping("provider")
public String provider();
@GetMapping("param/{name}/{age}")
public String paramUrl(@PathVariable("name") String name, @PathVariable("age") int age);
@GetMapping("getParam")
public String getParam(@RequestParam(required = false) String name);
@GetMapping("twoParam")
public String twoParam(@RequestParam(required = false) String name,@RequestParam(required = false)int age);
@PostMapping("oneObject")
public String oneObject(@RequestBody User user);
}
@GetMapping("paramTest")
public String paramTest(){
userProviderFeign.paramUrl("张三",20);
userProviderFeign.getParam("李四");
userProviderFeign.twoParam("小红",18);
User user = User.builder()
.name("小冰")
.age(18)
.time(new Date()).build();
userProviderFeign.oneObject(user);
return "provider";
}
Feign传递时间
@GetMapping("testTime")
public String testTime(@RequestParam Date date){
return date +"";
}
@GetMapping("time")
public String time(){
Date date =new Date();
System.out.println(date);
String s = userProviderFeign.testTime(date);
return s;
}
Feign日志处理
Feign提供了日志打印功能,我们在项目中可以通过配置来调整日志级别,从而了解Feign中http请求的细节 ,也就是说feign提供的日志功能可以对接口的调用情况进行监控和输出。
日志级别:
NONE: 默认的,不显示任何日志
BASIC:仅记录请求方法、URL、响应状态码以及执行时间
HEADERS:除了BASIC中定义的信息以外,还有请求和响应的头信息
FULL: 除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据
public Logger.Level level(){
return Logger.Level.FULL;
}
logging:
level:
com.example.feign.UserProviderFeign : debug
Hystrix介绍
Hystrix是一个用于处理分布式系统的延迟和容错的一个开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的稳定性。“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的,可处理的备选响应,而不是长时间等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
provider-service端
application.yml
server:
port: 8080
spring:
application:
name: provider-service01
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
hostname: localhost
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
Customer-service端
添加Hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
application.yml
server:
port: 8081
spring:
application:
name: c-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
hostname: localhost
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
feign:
hystrix:
enabled: true
Feign接口
@FeignClient(value = "provider-service01") //provider服务名
public interface CustomerToProviderFeign {
@GetMapping("Provider")
public String pro();
}
@Component
public class CustomerToProviderFeignHystrix implements CustomerToProviderFeign {
@Override
public String pro() {
return "熔断后备选方案";
}
}
controller
Hystrix常用配置
server:
port: 8081
spring:
application:
name: c-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
hostname: localhost
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
feign:
hystrix:
enabled: true
hystrix: #hysrix全局控制
command:
default:
circuitBreaker:
enabled: true #开启断路器
requestVolumeThreshold: 10 #失败次数
sleepWindowInMilliseconds: 20000 #窗口时间
errorThresholdPercentage: 60 #失败率
execution:
isolation:
Strategy: thread #隔离方式 thread线程格里尼集合和SEMAPHORE信号量隔离级别
thread:
timeoutInMilliseconds: 3000 #调用超时时长
fallback:
isolation:
semaphore:
maxConcurrentRequests: 1000 #信号量隔离级别最大并发数
ribbon:
ReadTimeout: 5000 #结合feign底层ribbon调用时长
ConnectTimeout: 5000
OpenFeign项目
eign-project01
Pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
pojo
api
Pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
UserOrderFeign
@FeignClient(value = "order-service",fallback = UserOrderFeignHystrix.class)
public interface UserOrderFeign {
@GetMapping("getOrderByUserId")
Order getOrderByUserId(@RequestParam int ID);
}
@Component
public class UserOrderFeignHystrix implements UserOrderFeign {
@Override
public Order getOrderByUserId(int ID) {
return null;
}
}
Order-center 提供者
Pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>project-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
@RestController
public class OrederController implements UserOrderFeign {
@Override
public Order getOrderByUserId(int ID) {
Order egg = Order.builder().ID(101).name("炸蛋").price(1.5).build();
return egg;
}
}
application.yml
server:
port: 8080
spring:
application:
name: order-service
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
probability: 1 #取值0-1 ,1为100%采集
rate: 10 #每秒间隔接受的trace量
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
hostname: localhost
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
User-center
Pom.xml
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>project-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
@RestController
public class UserController {
@Resource
public UserOrderFeign userOrderFeign;
@GetMapping("seek")
public Order seekOrder(){
Order orderByUserId = userOrderFeign.getOrderByUserId(101);
return orderByUserId;
}
}
application.yml
server:
port: 8081
spring:
application:
name: user-service
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
probability: 1 #取值0-1 ,1为100%采集
rate: 10 #每秒间隔接受的trace量
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
hostname: localhost
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
feign:
hystrix:
enabled: true #开启熔断
- 点赞
- 收藏
- 关注作者
评论(0)