Nacos整合OpenFeign入门使用

        在阅读本文前,请确保会使用Nacos的注册功能,如果不会,可以参考我的上一篇文章。链接

        OpenFeign是一个声明式的Web服务客户端,拥有可插拔的注解支持,支持可插拔的HTTP编码器和解码器,LoadBalancer的负载均衡,HTTP请求和相应压缩等功能,是目前主流的SpringCloud服务接口调用技术。OpenFeign官方文档

        在这篇文章中,我会使用一个消费者远程调用生产者的实际案例带大家了解Nacos整合OpenFeign

目录

1. 创建工程

1.1 父工程

1.2 生产者

        1.2.1 依赖

        1.2.2 application.yml文件

        1.2.3 主启动

        1.2.4 业务类

        1.3 commons工具项目(无需启动)

        1.3.1 依赖

        1.3.2 业务类

        1.4 消费者

        1.4.1 依赖

        1.4.2 application.yml文件

        1.4.3 主启动

        1.4.4 业务类(结合OpenFeign实现远程调用)

        1.4.5 restTemplate远程接口方式调用(了解)

 2. 测试

        2.1 生产者端测试

        2.2 消费者端测试

        2.3 负载均衡测试

3. OpenFeign高级特性

        3.1 超时控制

        3.2 OpenFeign重试机制

        3.3 默认HttpClient修改

        3.4  请求/响应压缩

        3.5 日志打印功能

        3.6 结合Sentinel服务降级

        4.总结


1. 创建工程

1.1 父工程

        用于控制各个子项目的版本依赖

        依赖:

 <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <lombok.version>1.18.26</lombok.version>
        <spring.boot.test.version>3.1.5</spring.boot.test.version>
        <spring.boot.version>3.1.7</spring.boot.version>
        <spring.cloud.version>2022.0.4</spring.cloud.version>
        <spring.cloud.alibaba.version>2023.0.1.2</spring.cloud.alibaba.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!--springboot 3.2.0-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--springcloud 2023.0.0-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--springcloud alibaba 2022.0.0.0-RC2-->
            <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>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>
            <!-- spring-boot-starter-test -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <version>${spring.boot.test.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

1.2 生产者

        1.2.1 依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.haishi</groupId>
            <artifactId>cloud-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

        1.2.2 application.yml文件

server:
  port: 9001  

spring:
  application:
    name: provider   #注册进Nacos的服务名称
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

        1.2.3 主启动

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

        1.2.4 业务类

@RestController
public class TestController {

    @Value("${server.port}")
    private String serverPort;

    @RequestMapping("/openFeign/test")
    public String test()  {
        System.out.println("进入" + serverPort);
        return "测试成功     生产者端口:"+serverPort+"     ";
    }
}

        1.3 commons工具项目(无需启动)

        创建一个通用的工具项目,用于在不同服务或模块之间共享的代码,存放公共配置文件,避免重复开发,减少配置的重复工作。

        1.3.1 依赖

    <dependencies>
        <!--SpringBoot通用依赖模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>4.0.4</version>
        </dependency>
    </dependencies>

        1.3.2 业务类

        实现一个接口,声明客户端对生产者的调用,使得开发者可以像调用本地方法一样使用FeignApi.test(),但是实际调用生产者的方法,并且不知道其中实现细节(比如一些真实数据库表结构),加强了安全性。 

@FeignClient(value = "provider")  //必须与生产者注册进Nacos的名称完全一致
public interface FeignApi {

    @RequestMapping("/openFeign/test")
    public String test();
}

        1.4 消费者

        1.4.1 依赖

        由于远程调用原理是先向Nacos中心获取服务提供者列表,然后选择一个服务提供者调用,因此各个远程调用依赖(如openFeign,LoadBalancer)都是装在消费者这侧

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- feign-hc5-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-hc5</artifactId>
            <version>13.1</version>
        </dependency>
        <!--loadbalancer-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!--自定义的工具项目-->
        <dependency>
            <groupId>com.haishi</groupId>
            <artifactId>cloud-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

        1.4.2 application.yml文件

server:
  port: 2001

spring:
  application:
    name: consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

        1.4.3 主启动

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //启用feign客户端,定义服务+绑定接口,以声明式的方法优雅而简单地实现服务调用
public class MainConsumer2001 {
    public static void main(String[] args) {
        SpringApplication.run(MainConsumer2001.class, args);
    }
}

        1.4.4 业务类(结合OpenFeign实现远程调用)

@RestController
public class TestController {

    @Value("${server.port}")
    private String port;

    @Resource
    private FeignApi feignApi;  //commons里编写的接口

    @GetMapping(value = "/consumer/openFeign/test")
    public String test()
    {
        System.out.println("进入consumer");
        return feignApi.test()+"  消费者端口:"+port;
    }

}

        1.4.5 restTemplate远程接口方式调用(了解)

        如果使用rest的调用方式就没有必要编写commons模块中的FeignApi接口了

        首先需要编写配置类

@Configuration
public class RestTemplateConfig
{
    @Bean
    @LoadBalanced //赋予RestTemplate负载均衡的能力
    public RestTemplate restTemplate()
    {
        return new RestTemplate();
    }
}

        然后在业务类里通过restTemplate.getForObject(网址生产者业务了返回值类型.class)调用

        网址具体的组成方式为:  http:// + 生产者 + 调用生产者业务类网址

        生产者服务名称一般写在application.yml中,再通过@Value注解添加进来,我这里就直接字符串写死了。

@RestController
public class TestController {
    
    @Value("${server.port}")
    private String port;

    @Resource
    private RestTemplate restTemplate;

    @GetMapping(value = "/consumer/rest/test")
    public String test2()
    {
        return restTemplate.getForObject("http://provider/openFeign/test",String.class)+"  消费者端口:"+port;
    }

}

        如果使用一些自定义类,那么消费者和生产者端都需要有对应的代码。这里还只是一个消费者,如果有多个消费者呢?那代码的膨胀性将是巨大的。因此OpenFeign通过commons远程调用,实现代码复用,提升安全性,无疑是优于restTemplate的,个人也十分推荐使用OpenFeign。

 2. 测试

        启动项目后,首先检查Nacos中心是否注册成功,然后再开始测试

        2.1 生产者端测试

        访问localhost:9001/openFeign/test

        2.2 消费者端测试

        访问localhost:2001/consumer/openFeign/test测试OpenFeign远程调用

        访问localhost:2001/consumer/rest/test测试restTemplate远程调用

        2.3 负载均衡测试

        OpenFeign天生支持SpringCloudLoadBalancer负载均衡

        首先多复制几个生产者

        如果不会IDEA快捷复制项目的可以参考这篇http://t.csdnimg.cn/YOobw

        刷新一下,可以看到成功调用其他生产者的服务

        因为生成的restTemplate带有@LoadBalancer注解,因此此时的restTemplate也带有负载均衡能力

        

3. OpenFeign高级特性

        3.1 超时控制

        在消费者模块中的application.yml中可以配置超时时间控制(每个版本默认值可能不同)

server:
  port: 2001

spring:
  application:
    name: consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    openfeign:
      client:
        config:
          # default 设置的全局超时时间
          default:
            connectTimeout: 4000 #连接超时时间(毫秒),默认是60s
            readTimeout: 4000 #请求处理超时时间(毫秒)
            # 为provider这个服务单独配置超时时间,单个配置的超时时间将会覆盖全局配置
          provider:
            connect-timeout: 2000  #连接超时时间(毫秒),默认是60s
            read-timeout: 2000  #请求处理超时时间(毫秒)

        3.2 OpenFeign重试机制

        编写FeignConfig配置类

@Configuration
public class FeignConfig {
    @Bean
    public Retryer myRetryer()
    {
        return Retryer.NEVER_RETRY; //默认配置,不走重试策略

        //最大请求次数为3(1+2),初始间隔时间为100ms,重试间最大间隔时间为1s
//        return new Retryer.Default(100,1,3);
    }
}

        3.3 默认HttpClient修改

        OpenFeign默认使用JDK自带的HttpURLConnection发送HTTP请求,由于其没有连接池,性能和效率上比较低,可以替代使用HttpClient5进行优化

        在消费者模块中的application.yml中进行配置

server:
  port: 2001

spring:
  application:
    name: consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
      httpclient:
        hc5:
          enabled: true #使用Apache HttpComponents HttpClient 5 优化http

        3.4  请求/响应压缩

        对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗

        在消费者模块中的application.yml中进行配置

server:
  port: 2001

spring:
  application:
    name: consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
      compression:
        request:
          enabled: true   #使用gzip压缩数据,提高性能
          min-request-size: 2048   #最小触发压缩的大小
          mime-types: text/xml,application/xml,application/json  #触发压缩数据类型

        3.5 日志打印功能

        OpenFeign提供了对Feign接口的调用情况进行监控和输出的功能

        首先在FeignConfig中添加

    @Bean
    Logger.Level feignLoggerLevel() {
        //        NONE          没有日志(默认)
        //        BASIC         仅记录请求方法、URL、响应状态码及执行时间
        //        HEADERS       新增监控请求和响应的头信息
        //        FULL          所有信息(新增请求和响应的正文及元数据)
        return Logger.Level.FULL;
    }

        然后在消费者模块中的application.yml中进行配置日志级别

server:
  port: 2001

spring:
  application:
    name: consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

  # feign日志以什么级别监控哪个接口
logging:
  level:
    com:  #包名
      haishi: #包名
        apis: #包名
          FeignApi: debug   #Feign接口名称:日志级别,只有在debug模式下会被打印

        3.6 结合Sentinel服务降级

        如果在Sentinel中为每个消费者微服务的每个业务类单独配置一个服务降级方法过于冗余,可以结合OpenFeign进行统一配置

        在commons模块中新增FeignSentinelApiFailBack类

public class FeignSentinelApiFallBack implements FeignApi{
    @Override
    public String test() {
        return "系统繁忙,请稍后再试o(╥﹏╥)o";
    }
}

        修改FeignApi的注解

@FeignClient(value = "provider",fallback =FeignSentinelApiFallBack.class )

       

        OpenFeign可以进行的高级设置远不止这些,这里仅作一些常用设置的分享,更多的可参考官方文档

        4.总结

        OpenFeign作为SpringCloud中的主流服务调用技术,能够以声明式的方式简化微服务间的通信。通过整合Nacos,OpenFeign不仅可以实现负载均衡,还能通过简单的注解和配置增强代码复用性、可维护性,并且隐藏了底层实现细节,提升了系统安全性。相比传统的RestTemplate方式,OpenFeign更加优雅和简洁,并且提供了高级特性进行灵活配置。

NacosOpenFeign是两个独立的开源项目,可以在Spring Cloud微服务架构中进行整合使用。 首先,需要在项目的pom.xml文件中引入相应的依赖。对于Nacos,可以通过以下方式引入: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> ``` 对于OpenFeign,可以通过以下方式引入: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> ``` 接下来,需要在启动类上添加相应的注解配置。对于Nacos,可以使用`@EnableDiscoveryClient`注解开启服务注册与发现功能。对于OpenFeign,可以使用`@EnableFeignClients`注解开启Feign客户端功能。 ```java @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } } ``` 然后,可以创建一个Feign客户端接口,用于定义与其他微服务交互的接口方法。使用`@FeignClient`注解指定要调用的微服务名称。 ```java @FeignClient("service-name") public interface YourFeignClient { @GetMapping("/api/your-api") String yourApiMethod(); } ``` 最后,在需要使用Feign客户端的地方注入该客户端接口,并直接调用定义的接口方法。 ```java @RestController public class YourController { private final YourFeignClient feignClient; public YourController(YourFeignClient feignClient) { this.feignClient = feignClient; } @GetMapping("/your-endpoint") public String yourEndpoint() { return feignClient.yourApiMethod(); } } ``` 以上就是NacosOpenFeign整合步骤。通过Nacos进行服务注册和发现,通过OpenFeign进行微服务间的远程调用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值