案例03-fegin调用报404问题

简介: fegin调用报404问题

一、背景介绍

       在项目当中经常使用Nacos来管理配置文件。Nacos从中起到了两个作用一个是注册中心,一个是配置中心。配置中心将配置从应用中抽离出来,交给nacos统一的来管理配置,可以配置多套环境,发生改变各个微服务各自到nacos配置中心拉取相关配置,实现配置中心化避免频繁修改配置文件;作为注册中心实现服务调用者对服务提供者远程调用,项目中出现了两台使用同一个命名空间的nacos只更新了一台,导致请求到了没更新的那一台导致了404问题的出现。

0eed4814bdb34c2587631b396642b98a.png

二、Fegin调用

准备一个Spring Cloud项目,包含一个消费者,一个服务提供者,使用nacos作为服务发现和配置中心

59050561c1b647899c691ba6567c9f1d.png

Invoker模块

1.引入的依赖

<artifactId>Invoker</artifactId>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <java.version>1.8</java.version>
        <latest.version>0.2.10</latest.version>
        <!-- Spring Cloud 版本信息 -->
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
        <!--  Spring Cloud Alibaba 版本信息 -->
        <spring.cloud.alibaba.version>2.1.0.RELEASE</spring.cloud.alibaba.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!-- Spring Cloud begin-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- Spring Cloud end-->
            <!-- Spring Cloud Alibaba begin-->
            <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>
            <!-- Spring Cloud Alibaba end -->
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!--SpringMVC-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--工具包-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>
        <!-- nacos注册中心依赖包 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- 监控检查-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- nacos配置中心依赖支持 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- feign调用 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

2.bootstrap.yml文件

8b5f904272bb405fa02435ccb40d22e6.png

3.启动类

@SpringBootApplication
@EnableDiscoveryClient
//扫描标有@FeignClient的接口
@EnableFeignClients("com.ctsi.sddx.feign")
public class NacosApplication {
    public static void main(String[] args) {
        SpringApplication.run(NacosApplication.class, args);
    }
}

4.Feign接口

@FeignClient(value = "arpro-provider-one")//value为Feign调用的服务名,也是注册到nacos中的服务名
public interface UserFeign {
    @GetMapping("user/get")
    String findAll();
}

5.UserController类

@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserFeign userFegin;
    @PostMapping("feign")
    public String getDeviceListByPage() {
        return userFegin.findAll();
    }
}

Provider模块

1.引入的依赖

<artifactId>provider</artifactId>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <!-- Spring Cloud 版本信息 -->
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
        <!--  Spring Cloud Alibaba 版本信息 -->
        <spring.cloud.alibaba.version>2.1.0.RELEASE</spring.cloud.alibaba.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!-- Spring Cloud begin-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- Spring Cloud end-->
            <!-- Spring Cloud Alibaba begin-->
            <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>
            <!-- Spring Cloud Alibaba end -->
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!--SpringMVC-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- mybatis-plus begin-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.0</version>
        </dependency>
        <!--MySQL连接包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>
        <!-- nacos注册中心依赖包 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- 监控检查-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- nacos配置中心依赖支持 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>nacos-config-spring-boot-starter</artifactId>
            <version>0.2.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>nacos-discovery-spring-boot-starter</artifactId>
            <version>0.2.1</version>
        </dependency>
    </dependencies>

2.bootstrap.yml文件

e829177e7ce74e7e8249dd7c78649f66.png

3.启动类

@EnableDiscoveryClient
@SpringBootApplication
public class TestFeignApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestFeignApplication.class, args);
    }
}

4.UserController类

@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping("/get")
    public String findAll() {
        return "服务调用成功";
    }
}

运行程序

ca256d9ce0b44830b1e8746c68b7f2c6.png

启动两个服务,在nacos上可以看到两个服务都已经注册上去了。

7313e3f1cc6d4f9fac00c98abfa31b2a.png

通过Invoker服务的UserFeign接口就可以调用到Provider服务的findAll方法了。

三、问题复现

1.准备两个程序,分别为test-feign-2 和 test-feign-5。在代码上完全一致,服务的端口号不一致。

3794fc189b3a4e52b5d4f677ba37ee91.png

2. 将四个服务都注册到nacos上

ce080fe320ec4456b62c3a892856c00a.png

3.nacos进行负载均衡配置,根据权重进行分发

c993cc159b624074a059205b48f1b739.png

4.修改 服务端口为9009的代码注释掉

@RestController
@RequestMapping("/user")
public class UserController {
//    @GetMapping("/get")
//    public String findAll() {
//        return "服务调用成功";
//    }
}

5.调用服务,验证报错情况

第一次调用,走的是没有注释代码的服务

4b5c34235fd4431eb12950fc7a90e7fb.png

第二次调用,走的是注释代码的服务,产生了404的报错

c0dfbbcbf8cf4a1e9fb13cec5e3eedb5.png

四、总结提升

1.功能一致性:保持代码一致性可以确保两套服务在功能上完全相同。这对于提供一致的用户体验和功能可用性至关重要。如果两套服务的代码不一致,可能会导致功能差异,用户在不同服务间的体验不一致,甚至可能导致某些功能在其中一套服务中无法正常运行。

2.数据一致性:代码一致性也有助于保持数据的一致性。如果两套服务的代码不一致,可能导致数据处理逻辑的差异,进而导致数据的不一致。例如,某个服务对某个数据进行了更新,而另一个服务没有相应的更新操作,就会导致两套服务之间的数据不一致。

3.维护和调试的便利性:代码一致性使得维护和调试变得更加简单。如果两套服务的代码一致,当出现问题时,只需要对一套代码进行调试和修复,就可以同时解决两套服务的问题。而如果代码不一致,需要分别对两套代码进行调试和修复,增加了维护的复杂性和工作量。

4.部署和扩展的灵活性:代码一致性还有助于实现灵活的部署和扩展。如果两套服务的代码一致,可以更方便地进行部署和升级操作。例如,可以使用自动化工具对两套服务进行统一的部署,减少了部署的复杂性和风险。同时,如果需要扩展服务的规模,也可以更容易地进行水平扩展,保持两套服务的一致性。


相关文章
|
7月前
|
Java Spring
Spring5源码(37)-SpringAop代理调用过程(一)
Spring5源码(37)-SpringAop代理调用过程(一)
45 0
|
7月前
|
Java Spring
Spring5源码(38)-SpringAop代理调用过程(二)
Spring5源码(38)-SpringAop代理调用过程(二)
46 0
|
4月前
|
Dubbo JavaScript Java
SpringBoot 调用外部接口的三种方式
SpringBoot不仅继承了Spring框架原有的特性,还简化了应用搭建与开发流程。在SpringBoot项目中,有时需要访问外部接口或URL。本文介绍三种不使用Dubbo的方式:一是利用原生`httpClient`发起请求;二是使用`RestTemplate`,支持GET和POST请求,包括`getForEntity`、`getForObject`及`postForEntity`等方法;三是采用`Feign`客户端简化HTTP请求,需引入相关依赖并在启动类上启用Feign客户端。这三种方式均能有效实现对外部服务的调用。
182 0
|
消息中间件 Java Kafka
SpringBoot中使用异步方法优化Service逻辑,提高接口响应速度
异步方法适用于逻辑与逻辑之间可以相互分割互不影响的业务中, 如生成验证码和发送验证码组成的业务, 其实无需等到真正发送成功验证码才对客户端进行响应, 可以让短信发送这一耗时操作转为异步执行, 解耦耗时操作和核心业务;
|
7月前
|
数据中心
Feign调用
Feign调用
33 0
|
7月前
|
Java Spring
SpringBoot+async异步调用接口以及几个任务同时完成和异步接口实现和调用
SpringBoot+async异步调用接口以及几个任务同时完成和异步接口实现和调用
139 0
|
7月前
|
监控 Java
【十一】springboot整合异步调用并获取返回值
【十一】springboot整合异步调用并获取返回值
151 0
|
Java API Apache
springboot 调用外部接口的21种方式
springboot 调用外部接口的21种方式
775 0
|
JSON Java Apache
SpringCloud - Feign 调用服务及传递参数踩坑记录(上)
SpringCloud - Feign 调用服务及传递参数踩坑记录(上)
2522 0