3、Open Feign服务调用

作为Spring Cloud的子项目之一,Spring Cloud OpenFeign以将OpenFeign集成到Spring Boot应用中的方式,为微服务架构下服务之间的调用提供了解决方案。首先,利用了OpenFeign的声明式方式定义Web服务客户端;其次还更进一步,通过集成Ribbon或Eureka实现负载均衡的HTTP客户端。

Feign,假装、伪装。OpenFeign可以使消费者将提供者提供的服务名伪装为接口进行消费,消费者只需使用“Service接口 + 注解”的方式即可直接调用Service接口方法,而无需再使用RestTemplate了。

Ribbon与OpenFeign

说到OpenFeign,不得不提的就是Ribbon。Ribbon是Netflix公司的一个开源的负载均衡项目,是一个客户端负载均衡器,运行在消费者端。
OpenFeign也是运行在消费者端的,使用Ribbon进行负载均衡,所以OpenFeign直接内置了Ribbon。即在导入OpenFeign依赖后,无需再专门导入Ribbon依赖了

@FeignClient 标注用于声明Feign客户端可访问的Web服务。

@EnableFeignClients 标注用于修饰Spring Boot应用的入口类,以通知Spring Boot启动应用时,扫描应用中声明的Feign客户端可访问的Web服务。

准备

eureka注册中心:

cloud-eureka-server-7001

服务提供者:

cloud-eureka-client-provider-8001

cloud-eureka-client-provider-8002

上述服务配置:https://blog.csdn.net/m0_45097637/article/details/112574536

配置OpenFeign服务调用

cloud-consumer-feign-order-80

端口: 80

服务名: consumer-feign-order

pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!--继承父工程-->
    <parent>
        <groupId>com.mxd</groupId>
        <artifactId>cloud-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.mxd</groupId>
    <artifactId>cloud-consumer-feign-order-80</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>cloud-consumer-feign-order-80</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2020.0.0</spring-cloud.version>
    </properties>

    <dependencies>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
controller
package com.mxd.cloudconsumerfeignorder80.controller;

import com.mxd.cloudconsumerfeignorder80.service.OrderFeignService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class OrderFeignController {
    // 注意,这里使用的是Feign接口,而不是业务接口
    @Resource
    private OrderFeignService orderFeignService;

    @GetMapping("/consumer/provider/get/{id}")
    public String provider(@PathVariable("id") int id) {
        return orderFeignService.provider(id);
    }
}
service
package com.mxd.cloudconsumerfeignorder80.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@Component
@FeignClient(value = "EUREKA-PROVIDER-SERVICE")
public interface OrderFeignService {
    // 这里的接口名称,及方法名可以随意定义,但方法参数与方法上的注解必须要与其提供者端对应方法的相同
    @GetMapping("/provider/get/{id}")
    public String provider(@PathVariable("id") int id);
}
启动类
package com.mxd.cloudconsumerfeignorder80;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients // 开启Feign客尸骗,也可以指定service所在的包
public class OrderFeignMain80 {

    public static void main(String[] args) {
        SpringApplication.run(OrderFeignMain80.class, args);
    }
}
application.yml
server:
  port: 80

spring:
  application:
    name: consumer-feign-order

eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/ #注册地址
启动

依次启动一下服务

cloud-eureka-server-7001

cloud-eureka-client-provider-8001

cloud-eureka-client-provider-8002

cloud-consumer-feign-order-80

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x7io2TOV-1612105561818)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210131230136413.png)]

测试

eureka注册中心 http://localhost:7001/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NqY2J5JC-1612105561822)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210131230220039.png)]

不断请求 http://localhost/consumer/provider/get/5 ,观察变化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LYCwCvfm-1612105561828)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20210131230316001.png)]

Open Feign超时控制

修改yml

server:
  port: 80

spring:
  application:
    name: consumer-feign-order

eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/ #注册地址

#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
  #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
  ReadTimeout: 5000
  #指的是建立连接后从服务器读取可用资源所用的时间
  ConnectTimeout: 5000

修改cloud-eureka-client-provider-8001和cloud-eureka-client-provider-8002

controller添加

@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeOut(){
    try {
        TimeUnit.SECONDS.sleep(3);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return serverPort;
}

修改controller

package com.mxd.cloudconsumerfeignorder80.controller;

import com.mxd.cloudconsumerfeignorder80.service.OrderFeignService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class OrderFeignController {

    @Resource
    private OrderFeignService orderFeignService;

    @GetMapping("/consumer/provider/get/{id}")
    public String provider(@PathVariable("id") int id) {
        return orderFeignService.provider(id);
    }
    // 添加的
    @GetMapping(value = "/consumer/payment/feign/timeout")
    public String paymentFeignTimeOut() {
        return orderFeignService.paymentFeignTimeOut();
    }
}

修改 serivice

package com.mxd.cloudconsumerfeignorder80.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@Component
@FeignClient(value = "EUREKA-PROVIDER-SERVICE")
public interface OrderFeignService {

    @GetMapping("/provider/get/{id}")
    public String provider(@PathVariable("id") int id);
    // 添加的
    @GetMapping(value = "/payment/feign/timeout")
    public String paymentFeignTimeOut();
}

测试

依次重启

cloud-eureka-client-provider-8001

cloud-eureka-client-provider-8002

cloud-consumer-feign-order-80

多次请求,可以发现,每次请求都要等待3s才会响应,如果yml没有设置feign客户端超时时间,则会直接报错

http://localhost/consumer/payment/feign/timeout

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值