Spring Cloud2024.x实战 | 微服务全套系列 | 第3篇:springcloud整合注册/配置中心nacos、网关gateway以及基于http的RPC工具OpenFeign

1 引言

在微服务架构中,服务之间的远程调用(RPC)((Remote Produce Call))是核心功能之一。本文将详细介绍RPC中的OpenFeign。

2 RPC是什么,什么时候用到?

在单体应用时代,所有代码都在一个项目里,函数调用都是本地的,非常简单。 但随着业务发展,单体应用变得越来越臃肿,难以维护和扩展。 😩 于是,微服务架构应运而生。 🚀

微服务架构将一个大型应用拆分成多个小的、独立的服务。 这些服务可能运行在不同的服务器上,使用不同的编程语言。 这时候,服务之间就需要相互通信才能完成业务逻辑。 🤝

常见的服务调用选择是使用 HTTP API。服务 A 通过 HTTP 请求调用服务 B 的 API。这种方式简单易懂,但存在一些问题:

  • 效率较低: HTTP 协议相对比较重,传输的数据量大,解析也比较耗时。
  • 灵活性差: HTTP API 通常需要定义明确的接口和数据格式,不够灵活。
  • 难以管理: 当服务数量增多时,API 的管理和维护变得困难。

RPC 的作用就体现出来了:

  • 解耦: 让服务之间独立运行,互不干扰。 一个服务的修改不会影响到其他服务。 🔗✂️
  • 提高可扩展性: 可以根据业务需求,独立地扩展某个服务。 ⬆️
  • 技术异构: 允许不同的服务使用不同的编程语言和技术栈。 🌐
  • 简化开发: 开发者可以专注于自己的服务逻辑,而不用关心底层通信细节。 ✨

RPC(Remote Procedure Call)是一种远程过程调用协议,它允许一个程序调用另一个程序中的函数或方法,而无需了解底层的网络细节。因此RPC的出现使得分布式系统中的各个组件之间的通信变得更加简单、高效和可靠。

并且RPC协议提供了更加丰富和灵活的功能,例如支持不同的序列化格式、支持异步调用、支持自定义的错误处理等等(**如:gRPC、Apache Thrift、CORBA…等),而平常普通的http请求等就很难实现。因此在为了需要自定义上述的的功能,亦或者在分布式系统中需要进行组件的通信时,就需要rpc。(但是这里RPC底层的传输协议其实是可以用HTTP协议的,这种方式被称为HTTP-RPC或者HTTP-based RPC。在这种方式中,HTTP协议被用来传输RPC请求和响应数据。)

举个例子:

假设你有一个电商网站,拆分成以下几个微服务:

  • 用户服务: 负责用户注册、登录等。 👤
  • 商品服务: 负责商品信息的管理。 📦
  • 订单服务: 负责处理订单的创建、支付等。 🛒
    当用户下单时,订单服务需要调用用户服务来验证用户信息,调用商品服务来获取商品信息。 如果没有 RPC,你需要自己编写复杂的网络通信代码来实现这些调用。 😫 有了 RPC,你只需要像调用本地函数一样,调用用户服务和商品服务的接口即可。 😊

3 RPC 能帮助我们什么?

  • 屏蔽底层通信细节: 开发者不用关心网络协议、序列化、反序列化等复杂细节,专注于业务逻辑。 🙈
  • 提高开发效率: 简化服务之间的调用,减少代码量。 ⚡
  • 提高系统稳定性: 通过负载均衡、故障转移等机制,提高系统的可用性。 🛡️
  • 方便服务治理: 可以对服务进行监控、限流、熔断等管理。 ⚙️

4 Feign和OpenFeign都是什么?

Feign是RPC框架中的一种,是Netflix开发的声明式、模板化的HTTP客户端,底层依然是走的HTTP调用,但表现形式是接口调用,可以帮助我们更加便捷、优雅地调用HTTP API,就像调用本地方法一样方便。

它通过扩展集成了Netflix Ribbon,从而拥有负载均衡的功能,默认是基于配置来提供服务实例列表。

OpenFeign是指Spring Cloud OpenFeign,是Spring Cloud开发的,对Feign进行了增强,使其支持Spring MVC注解,还整合了Spring Cloud Netflix Ribbon,从注册中心获取服务实例(在Spring Cloud Alibaba框架中的注册中心默认是Nacos),从而使得Feign与Spring Cloud整合。

5 HTTP调用 vs Feign(RPC)调用

回顾一下RestTemplate方式的服务调用(gg-user是服务名):

@Autowired
private RestTemplate restTemplate;

@GetMapping("/getUserName")
public String getUserName(@RequestParam("id") Integer id) {
   
   
    String url = String.format("http://%s/user?id=%s", "gg-user", id);
    return restTemplate.exchange(url, HttpMethod.GET, null, String.class).getBody();
}

换成Feign调用,感受一下效果:

@Autowired
private UserService userService;

@GetMapping("/getUserName")
public String getUserName(@RequestParam("id") Integer id) {
   
   
    return userService.getUserName(id);
}

What? Feign这个是远程调用?

对,这就是远程调用,丝毫看不出来,和调用本地方法一样的湿滑!
怎么实现的?如果你用过Mybatis,可以往Mybatis接口的实现类上思考,也许你能想到答案!

6 搭建工程

示例代码对应仓库:

  • 网关服务:oso-gateway
  • 认证中心:oso-auth
  • 会员中心:mall-ums

6.1 搭建父工程

创建oso-cloud项目,作为网关中心。最终项目代码如下图所示:

在这里插入图片描述

6.1.1 引入依赖

<?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>

    <groupId>com.oso.cloud</groupId>
    <artifactId>oso-cloud</artifactId>
    <version>${revision}</version>
    <packaging>pom</packaging>
    <name>oso-cloud</name>
    <description>oso-cloud</description>

    <url/>

    <licenses>
        <license/>
    </licenses>

    <developers>
        <developer/>
    </developers>

    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>

    <modules>
        <module>oso-gateway</module>
        <module>oso-auth</module>
        <module>oso-common</module>
    </modules>

    <properties>
        <revision>0.0.1</revision>
        <java.version>17</java.version>
        <maven.compiler.source>19</maven.compiler.source>
        <maven.compiler.target>19</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-boot.version>3.4.5</spring-boot.version>
        <spring-cloud.version>2024.0.1</spring-cloud.version>
        <spring-cloud-alibaba.version>2023.0.1.2</spring-cloud-alibaba.version>

        <hutool.version>5.8.35</hutool.version>
        <lombok.version>1.18.38</lombok.version>

        <knife4j.version>4.3.0</knife4j.version>
        <swagger.version>2.1.0</swagger.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- hutool 的依赖配置-->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-bom</artifactId>
                <version>${hutool.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

            <!-- API 接口文档 -->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-dependencies</artifactId>
                <version>${knife4j.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.oso.cloud</groupId>
                <artifactId>common-core</artifactId>
                <version>${project.version}</version>
            </dependency>

            <dependency>
                <groupId>com.oso.cloud</groupId>
                <artifactId>common-web</artifactId>
                <version>${project.version}</version>
            </dependency>

            <dependency>
                <groupId>com.oso.cloud</groupId>
                <artifactId>ums-api</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>

    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>public</id>
            <name>huawei nexus</name>
            <url>https://mirrors.huaweicloud.com/repository/maven/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>huawei nexus</name>
            <url>https://mirrors.huaweicloud.com/repository/maven/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

</project>


6.2 搭建公共模块

创建oso-common模块,作为公共依赖。最终项目代码如下图所示:
在这里插入图片描述

6.2.1 引入依赖

<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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.oso.cloud</groupId>
        <artifactId>oso-cloud</artifactId>
        <version>${revision}</version>
    </parent>

    <artifactId>oso-common</artifactId>
    <packaging>pom</packaging>

    <name>oso-common</name>
    <url>http://maven.apache.org</url>

    <modules>
        <module>common-core</module>
        <module>common-web</module>
    </modules>

    <dependencies>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

6.2.2 创建common-core子模块

在这里插入图片描述

6.2.2.1 引入依赖
<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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.oso.cloud</groupId>
        <artifactId>oso-common</artifactId>
        <version>${revision}</version>
    </parent>

    <artifactId>common-core</artifactId>

    <name>common-core</name>
    <url
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhuzhongji

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值