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

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 作为Spring Cloud的子项目之一,Spring Cloud OpenFeign以将OpenFeign集成到Spring Boot应用中的方式,为微服务架构下服务之间的调用提供了解决方案。首先,利用了OpenFeign的声明式方式定义Web服务客户端;其次还更进一步,通过集成Ribbon或Eureka实现负载均衡的HTTP客户端。

作为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调用测试接口,可以查看微服务调用成功


微信图片_20220518092321.png

image.png


微信图片_20220518092325.png

image.png

相关文章
|
1月前
|
运维 监控 Go
Go语言微服务实战与最佳实践
【2月更文挑战第14天】本文将深入探讨使用Go语言进行微服务实战中的最佳实践,包括服务拆分、API设计、并发处理、错误处理、服务治理与监控等方面。通过实际案例和详细步骤,我们将分享如何在Go语言环境中构建高效、稳定、可扩展的微服务系统。
|
20天前
|
Java fastjson 数据安全/隐私保护
【Dubbo3技术专题】「云原生微服务开发实战」 一同探索和分析研究RPC服务的底层原理和实现
【Dubbo3技术专题】「云原生微服务开发实战」 一同探索和分析研究RPC服务的底层原理和实现
38 0
|
1月前
|
开发框架 移动开发 JavaScript
SpringCloud微服务实战——搭建企业级开发框架(四十六):【移动开发】整合uni-app搭建移动端快速开发框架-环境搭建
正如优秀的软件设计一样,uni-app把一些移动端常用的功能做成了独立的服务或者插件,我们在使用的时候只需要选择使用即可。但是在使用这些服务或者插件时一定要区分其提供的各种服务和插件的使用场景,例如其提供的【uni-starter快速开发项目模版】几乎集成了移动端所需的所有基础功能,使用非常方便,但是其许可协议只允许对接其uniCloud的JS开发服务端,不允许对接自己的php、java等其他后台系统。
136 2
|
1月前
|
人工智能 负载均衡 Java
【Spring实战】动手拥有自己的ai小站!使用Springboot整合Spring Cloud Gateway实现对接open ai并实现令牌记量和限制对话次数
【Spring实战】动手拥有自己的ai小站!使用Springboot整合Spring Cloud Gateway实现对接open ai并实现令牌记量和限制对话次数
|
1月前
|
安全 Java 数据安全/隐私保护
【Spring底层原理高级进阶】【SpringCloud整合Spring Security OAuth2】深入了解 Spring Security OAuth2:底层解析+使用方法+实战
【Spring底层原理高级进阶】【SpringCloud整合Spring Security OAuth2】深入了解 Spring Security OAuth2:底层解析+使用方法+实战
|
2月前
|
Java API 调度
从Spring Cloud 开始,聊一聊微服务架构的设计与实战
随着互联网的发展,网站应用的规模也在不断的扩大,进而导致系统架构也在不断的进行变化。
366 1
从Spring Cloud 开始,聊一聊微服务架构的设计与实战
|
11天前
|
API 数据库 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第8天】 随着现代软件开发的复杂性日益增加,传统的单体应用架构面临着可扩展性、维护性和敏捷性的挑战。为了解决这些问题,微服务架构应运而生,并迅速成为后端开发领域的一股清流。本文将深入探讨微服务架构的设计原则、实施策略及其带来的优势与挑战,为后端开发者提供一种全新视角,以实现更加灵活、高效和稳定的系统构建。
18 0
|
25天前
|
负载均衡 测试技术 持续交付
高效后端开发实践:构建可扩展的微服务架构
在当今快速发展的互联网时代,后端开发扮演着至关重要的角色。本文将重点探讨如何构建可扩展的微服务架构,以及在后端开发中提高效率的一些实践方法。通过合理的架构设计和技术选型,我们可以更好地应对日益复杂的业务需求,实现高效可靠的后端系统。
|
25天前
|
监控 持续交付 API
构建高效可扩展的微服务架构
在当今快速迭代和竞争激烈的软件市场中,构建一个高效、可扩展且易于维护的后端系统变得尤为重要。微服务架构作为一种流行的分布式系统设计方式,允许开发者将应用程序划分为一系列小型、自治的服务,每个服务负责执行特定的业务功能。本文将探讨如何利用现代技术栈搭建一个符合这些要求的微服务架构,并讨论其潜在的挑战与解决方案。我们将涵盖服务划分策略、容器化、服务发现、API网关、持续集成/持续部署(CI/CD)以及监控和日志管理等关键主题,以帮助读者构建出既可靠又灵活的后端系统。
|
9天前
|
Kubernetes 安全 Java
构建高效微服务架构:从理论到实践
【4月更文挑战第9天】 在当今快速迭代与竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性及容错性,成为众多企业转型的首选。本文将深入探讨如何从零开始构建一个高效的微服务系统,覆盖从概念理解、设计原则、技术选型到部署维护的各个阶段。通过实际案例分析与最佳实践分享,旨在为后端工程师提供一套全面的微服务构建指南,帮助读者在面对复杂系统设计时能够做出明智的决策,并提升系统的可靠性与维护效率。