乐趣区

关于前端:SpringCloud微服务实战搭建企业级开发框架十一集成OpenFeign用于微服务间调用

  作为 Spring Cloud 的子项目之一,Spring Cloud OpenFeign 以将 OpenFeign 集成到 Spring Boot 利用中的形式,为微服务架构下服务之间的调用提供了解决方案。首先,利用了 OpenFeign 的申明式形式定义 Web 服务客户端;其次还更进一步,通过集成 Ribbon 或 Eureka 实现负载平衡的 HTTP 客户端。
  OpenFeign 能够使消费者将提供者提供的服务名假装为接口进行生产,消费者只需应用“Service 接口 + 注解”的形式。即可间接调用 Service 接口办法,而无需再应用 RestTemplate 了。其实原理还是应用 RestTemplate,而通过 Feign(假装)成咱们相熟的习惯。
  GitEgg 框架除了新建 Fegin 服务之外,还定义实现了消费者 Fegin-api,在其余微服务调用的时候,只须要引入 Fegin-api 即可间接调用,不须要在本人反复开发消费者调用接口。

1、在 GitEgg-Platform 工程的子工程 gitegg-platform-cloud 中引入 spring-cloud-starter-openfeign 依赖, 从新 install GitEgg-Platform 工程,而后 GitEgg-Cloud 我的项目须要从新在 IDEA 中执行 Reload All Maven Projects。

<?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>GitEgg-Platform</artifactId>
        <groupId>com.gitegg.platform</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gitegg-platform-cloud</artifactId>
    <name>${project.artifactId}</name>
    <version>${project.parent.version}</version>
    <packaging>jar</packaging>

    <dependencies>
        <!-- Nacos 服务注册发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- Nacos 分布式配置 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- OpenFeign 微服务调用解决方案 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

</project>

  咱们从零碎架构设计方面思考,GitEgg-Cloud 下的 gitegg-service 作为业务逻辑解决模块,gitegg-service-api 作为微服务对立对外提供接口的模块,这里在测试的时候须要用到两个微服务之间的调用,咱们这里在 gitegg-service 下 gitegg-service-base 外面新建测试代码,和 gitegg-service-system 之间互相调用。留神,这里须要阐明,gitegg-service-api 并不是继承 gitegg-service 做业务扩大,而是对外提供接口的形象,比方当初有 A、B、C 三个零碎 A、B 都须要调用 C 的同一个办法,如果依照业务逻辑来列举代码的话,那么就须要在 A 和 B 中写雷同的调用办法来调用 C,这里咱们抽出来一个 api 模块,专门寄存调用微服务 C 的调用办法,在应用时,A 和 B 只须要引入 C 的 jar 包即可间接应用调用办法。
2、在 gitegg-service-system-api 工程中,引入 SpringBoot,SpringCloud,Swagger2 的依赖,新建 ISystemFeign.java 和 ApiSystemDTO.java,作为 OpenFeign 调用微服务的公共办法:

<?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>GitEgg-Cloud</artifactId>
        <groupId>com.gitegg.cloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gitegg-service-api</artifactId>
    <name>${project.artifactId}</name>
    <version>${project.parent.version}</version>
    <packaging>pom</packaging>
    <modules>
        <module>gitegg-service-base-api</module>
        <module>gitegg-service-bigdata-api</module>
        <module>gitegg-service-system-api</module>
    </modules>

    <dependencies>
        <!-- gitegg Spring Boot 自定义及扩大 -->
        <dependency>
            <groupId>com.gitegg.platform</groupId>
            <artifactId>gitegg-platform-boot</artifactId>
        </dependency>
        <!-- gitegg Spring Cloud 自定义及扩大 -->
        <dependency>
            <groupId>com.gitegg.platform</groupId>
            <artifactId>gitegg-platform-cloud</artifactId>
        </dependency>
        <!-- gitegg swagger2-knife4j -->
        <dependency>
            <groupId>com.gitegg.platform</groupId>
            <artifactId>gitegg-platform-swagger</artifactId>
        </dependency>
    </dependencies>


</project>
package com.gitegg.service.system.api.feign;

import com.gitegg.platform.boot.common.base.Result;
import com.gitegg.service.system.api.dto.ApiSystemDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "gitegg-service-system")
public interface ISystemFeign {

    /**
     * OpenFeign 测试 Get
     *
     * @param id
     * @return
     */
    @GetMapping("/system/api/by/id")
    Result<Object> querySystemById(@RequestParam("id") Long id);

    /**
     * OpenFeign 测试 Post
     *
     * @param apiSystemDTO
     * @return ApiSystemDTO
     */
    @PostMapping("/system/api/by/dto")
    Result<ApiSystemDTO> querySystemByDto(@RequestBody ApiSystemDTO apiSystemDTO);
}
package com.gitegg.service.system.api.dto;

import lombok.Data;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

@Data
public class ApiSystemDTO {

    @NotNull
    @Min(value = 10, message = "id 必须大于 10")
    @Max(value = 150, message = "id 必须小于 150")
    private Long id;

    @NotNull(message = "名称不能为空")
    @Size(min = 3, max = 20, message = "名称长度必须在 3 -20 之间")
    private String name;
    
}

2、在 gitegg-service-system 工程中,批改 SystemController.java, 增加须要被微服务调用的办法:

package com.gitegg.service.system.controller;

import com.gitegg.platform.boot.common.base.Result;
import com.gitegg.service.system.dto.SystemDTO;
import com.gitegg.service.system.service.ISystemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping(value = "system")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Api(tags = "gitegg-system")
@RefreshScope
public class SystemController {

    private final ISystemService systemService;

    @Value("${spring.datasource.maxActive}")
    private String nacosMaxActiveType;

    @GetMapping(value = "list")
    @ApiOperation(value = "system list 接口")
    public Object list() {return systemService.list();
    }


    @GetMapping(value = "page")
    @ApiOperation(value = "system page 接口")
    public Object page() {return systemService.page();
    }

    @GetMapping(value = "exception")
    @ApiOperation(value = "自定义异样及返回测试接口")
    public Result<String> exception() {return Result.data(systemService.exception());
    }

    @PostMapping(value = "valid")
    @ApiOperation(value = "参数校验测试接口")
    public Result<SystemDTO> valid(@Valid @RequestBody SystemDTO systemDTO) {return Result.data(systemDTO);
    }

    @PostMapping(value = "nacos")
    @ApiOperation(value = "Nacos 读取配置文件测试接口")
    public Result<String> nacos() {return Result.data(nacosMaxActiveType);
    }

    @GetMapping(value = "api/by/id")
    @ApiOperation(value = "Fegin Get 调用测试接口")
    public Result<Object> feginById(@RequestParam("id") String id) {return Result.data(systemService.list());
    }

    @PostMapping(value = "api/by/dto")
    @ApiOperation(value = "Fegin Post 调用测试接口")
    public Result<Object> feginByDto(@Valid @RequestBody SystemDTO systemDTO) {return Result.data(systemDTO);
    }
}

3、参照 gitegg-service-system 工程,在 gitegg-service-base 工程下,引入 gitegg-service-system-api 依赖,新建 BaseController.java、GitEggBaseApplication.java、bootstrap.yml 作为服务调用方:
pom.xml:

    <dependencies>
        <!-- gitegg-service-system 的 fegin 公共调用办法 -->
        <dependency>
            <groupId>com.gitegg.cloud</groupId>
            <artifactId>gitegg-service-system-api</artifactId>
            <version>${project.parent.version}</version>
        </dependency>
    </dependencies>

BaseController.java:

package com.gitegg.service.base.controller;

import com.gitegg.platform.boot.common.base.Result;
import com.gitegg.service.system.api.dto.ApiSystemDTO;
import com.gitegg.service.system.api.feign.ISystemFeign;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping(value = "base")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Api(tags = "gitegg-base")
@RefreshScope
public class BaseController {

    private final ISystemFeign systemFeign;

    @GetMapping(value = "api/by/id")
    @ApiOperation(value = "Fegin Get 调用测试接口")
    public Result<Object> feginById(@RequestParam("id") Long id) {return Result.data(systemFeign.querySystemById(id));
    }

    @PostMapping(value = "api/by/dto")
    @ApiOperation(value = "Fegin Post 调用测试接口")
    public Result<Object> feginByDto(@Valid @RequestBody ApiSystemDTO systemDTO) {return Result.data(systemFeign.querySystemByDto(systemDTO));
    }

}

GitEggBaseApplication.java:

package com.gitegg.service.base;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;

/**
 * gitegg-base 启动类
 */
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.gitegg")
@ComponentScan(basePackages = "com.gitegg")
@MapperScan("com.gitegg.*.*.mapper")
@SpringBootApplication
public class GitEggBaseApplication {public static void main(String[] args) {SpringApplication.run(GitEggBaseApplication.class,args);
    }

}

bootstrap.yml:

server:
  port: 8002
spring:
  application:
    name: gitegg-service-base
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
        prefix: gitegg-service-system
        group: DEFAULT_GROUP
        enabled: true

4、别离启动 gitegg-service-base 和 gitegg-service-system 我的项目,关上浏览器,拜访 http://127.0.0.1:8002/doc.html(这里 gitegg-service-base 的端口设置为 8002,所以拜访 gitegg-service-base 的服务进行测试),在页面左侧菜单别离点击 Fegin Get 调用测试接口和 Fegin Post 调用测试接口,能够查看微服务调用胜利

本文源码在 https://gitee.com/wmz1930/GitEgg 的 chapter-11 分支。

退出移动版