Spring Cloud OpenFeign (Hoxton版) 使用

Spring Cloud Hoxton.SR4 Spring Boot 2.3.0.RELEASE

GitHub:shpunishment/spring-cloud-learning/spring-cloud-openfeign-test

1. 简介

Spring Cloud OpenFeign 是声明式的服务调用工具,它集成了Ribbon、Hystrix、Eureka和Spring Cloud LoadBalancer,以在使用Feign时提供负载平衡和服务容错的http客户端。

2. 使用

先用IDEA创建一个Spring Boot的项目,可以随意引用一个Spring Cloud的组件,之后也会删掉。

创建完,删掉除了pom.xml以外的其他文件,再修改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>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
    </parent>
    <groupId>com.shpun</groupId>
    <artifactId>spring-cloud-openfeign-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-cloud-openfeign-test</name>
    <description>spring cloud openfeign test</description>
    <!--修改打包方式为pom-->
    <packaging>pom</packaging>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-cloud.version>Hoxton.SR4</spring-cloud.version>
    </properties>

    <modules>
        <!--后续添加子模块用-->
    </modules>

    <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>
</project>

2.1 eureka-server

创建子模块eureka-server

修改pom继承

<parent>
    <groupId>com.shpun</groupId>
    <artifactId>spring-cloud-openfeign-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

再添加依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

修改application.yml

server:
  port: 8100

spring:
  application:
    name: eureka-server

eureka:
  instance:
    hostname: localhost
  client:
    # 是否从注册中心获取服务(注册中心不需要开启)
    register-with-eureka: false
    # 是否将服务注册到注册中心(注册中心不需要开启)
    fetch-registry: false

在启动类上添加@EnableEurekaServer注解来启用Euerka注册中心功能。

2.2 user-service

创建子模块user-service

修改pom继承

<parent>
    <groupId>com.shpun</groupId>
    <artifactId>spring-cloud-openfeign-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

再添加依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.2</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
    <scope>runtime</scope>
</dependency>

修改application.yml

server:
  port: 8101

spring:
  application:
    name: user-service
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:4306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: root

eureka:
  instance:
    # 是否优先使用ip来作为主机名
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://localhost:8100/eureka

mybatis:
  typeAliasesPackage: com.shpun.model
  mapper-locations: classpath:mapper/**.xml

Model,Mapper,Service等省略。

UserController 完成对User的CURD接口。

@RequestMapping("/api/user")
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/add")
    public ResultVo<?> add(@RequestBody User user) {
        userService.insertSelective(user);
        return ResultVo.ok();
    }

    @GetMapping("/delete/{userId}")
    public ResultVo<?> delete(@PathVariable("userId") Integer userId) {
        userService.deleteByPrimaryKey(userId);
        return ResultVo.ok();
    }

    @PostMapping("/update")
    public ResultVo<?> update(@RequestBody User user) {
        userService.updateByPrimaryKeySelective(user);
        return ResultVo.ok();
    }

    @GetMapping("/{userId}")
    public ResultVo<User> get(@PathVariable("userId") Integer userId) {
        User user = userService.selectByPrimaryKey(userId);
        return ResultVo.okData(user);
    }

	@GetMapping("/getByUserIdList")
    public ResultVo<List<User>> getByUserIdList(@RequestParam("userIdList") List<Integer> userIdList) {
        List<User> userList = userService.getByUserIdList(userIdList);
        return ResultVo.okData(userList);
    }
}

在启动类上添加@EnableDiscoveryClient注解表明是一个服务发现的客户端。

2.3 openfeign-service

创建子模块openfeign-service

修改pom继承

<parent>
    <groupId>com.shpun</groupId>
    <artifactId>spring-cloud-openfeign-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>

再添加依赖

<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-openfeign</artifactId>
</dependency>

修改application.yml,也可以添加Ribbon和Hystrix的配置。

server:
  port: 8200

spring:
  application:
    name: openfeign-service

eureka:
  instance:
    # 是否优先使用ip来作为主机名
    prefer-ip-address: true
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8100/eureka/

feign:
  hystrix:
    # 开启Hystrix
    enabled: true
  compression:
    request:
      # 是否对请求进行GZIP压缩
      enabled: false
      # 指定压缩的请求数据类型
      mime-types: text/xml,application/xml,application/json
      # 超过该大小的请求会被压缩
      min-request-size: 2048
    response:
      # 是否对响应进行GZIP压缩
      enabled: false
  client:
    config:
      # 全局配置,可以指定具体应用名
      default:
        # 连接超时
        connectTimeout: 5000
        # 读取超时
        readTimeout: 5000
        # 指定feign日志级别
        loggerLevel: full

logging:
  level:
    com.shpun: debug

UserFeignService 注解@FeignClient中value指定这是对user-service服务的接口调用客户端,fallback指定服务降级实现类。

@FeignClient(value = "user-service", fallback = UserFeignServiceFallback.class)
public interface UserFeignService {

    @PostMapping("/api/user/add")
    ResultVo<?> add(@RequestBody User user);

    @GetMapping("/api/user/delete/{userId}")
    ResultVo<?> delete(@PathVariable("userId") Integer userId);

    @PostMapping("/api/user/update")
    ResultVo<?> update(@RequestBody User user);

    @GetMapping("/api/user/{userId}")
    ResultVo<User> get(@PathVariable("userId") Integer userId);

    @GetMapping("/api/user/getByUserIdList")
    ResultVo<List<User>> getByUserIdList(@RequestParam("userIdList") List<Integer> userIdList);
}

UserFeignServiceFallback 服务降级实现类

@Component
public class UserFeignServiceFallback implements UserFeignService {

    @Override
    public ResultVo<?> add(User user) {
        return ResultVo.failure(500, "add 服务调用异常");
    }

    @Override
    public ResultVo<?> delete(Integer userId) {
        return ResultVo.failure(500, "delete 服务调用异常");
    }

    @Override
    public ResultVo<?> update(User user) {
        return ResultVo.failure(500, "update 服务调用异常");
    }

    @Override
    public ResultVo<User> get(Integer userId) {
        return ResultVo.build(500, null,"get 服务调用异常");
    }

    @Override
    public ResultVo<List<User>> getByUserIdList(List<Integer> userIdList) {
        return ResultVo.build(500, null,"getByUserIdList 服务调用异常");
    }
}

在启动类上添加@EnableDiscoveryClient注解表明是一个服务发现的客户端,@EnableFeignClients注解启用Feign的客户端功能。

测试

@RequestMapping("/api/user")
@RestController
public class UserFeignController {

    @Autowired
    private UserFeignService userFeignService;

    @PostMapping("/add")
    public ResultVo<?> add(@RequestBody User user) {
        return userFeignService.add(user);
    }

    @GetMapping("/delete/{userId}")
    public ResultVo<?> delete(@PathVariable("userId") Integer userId) {
        return userFeignService.delete(userId);
    }

    @PostMapping("/update")
    public ResultVo<?> update(@RequestBody User user) {
        return userFeignService.update(user);
    }

    @GetMapping("/{userId}")
    public ResultVo<User> get(@PathVariable("userId") Integer userId) {
        return userFeignService.get(userId);
    }

    @GetMapping("/getByUserIdList")
    public ResultVo<List<User>> getByUserIdList(@RequestParam("userIdList") List<Integer> userIdList) {
        return userFeignService.getByUserIdList(userIdList);
    }
}

参考:
Spring Cloud OpenFeign 官方文档
Spring Cloud入门-OpenFeign服务消费者(Hoxton版本)

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页