SpringCloud Alibaba | Nacos(三):Nacos集成OpenFeign

1. 前言

上一章Spring Cloud项目中Nacos作为注册中心 在使用Naocs作为注册中心的时候我们使用 RestTemplate+Ribbon 的方式访问到了procider发布的服务, 但是在实际开发中不可能使用这种方式进行服务调用,所以这章我们讲一下:使用 Naocs集成OpenFeign 来完成调用服务发布的接口。

1.1 OpenFeign

官网地址: https://docs.spring.io/spring-cloud-openfeign/docs/2.2.10.BUILD-SNAPSHOT/reference/html

OpenFeign: 自身整合了RibbonHystrix, 为服务调用提供了更优雅的方式
Ribbon:负载均衡
Hystrix: 断路器,Hystrix能够保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

这里简单说一下Feign
Feign集成了RibbonRestTemplate实现了负载均衡的执行Http调用,只不过对原有的方式(Ribbon+RestTemplate)进行了封装,开发者不必手动使用RestTemplate调服务,而是定义一个接口,在这个接口中标注一个注解即可完成服务调用,这样更加符合面向接口编程的宗旨,简化了开发。但遗憾的是Feign现在停止迭代了。

OpenFeign是SpringCloud在Feign 的基础上支持了SpringMVC的注解,如@RequestMappong等,OpenFeign的@FeignClient 可以解析SpringMVC的@RequstMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡应调用其他服务。

OpenFeign 的传参方式

注解参数形式
@RequestBodyJSON传参方式 默认
@SpringQueryMapPOJO表单传参方式
@RequestHeader请求头传参
@RequestParamGET请求传参
@PathVariable请求路径上
OpenFeign 还提供了很多propertires 、yml参数配置
官方地址: https://docs.spring.io/spring-cloud-openfeign/docs/2.2.10.BUILD-SNAPSHOT/reference/html/appendix.html

OpenFeign 默认开启Apache HttpClient
如果想使用 OkHttpClient 的话 就需要配置 feign.okhttp.enabled 默认false在这里插入图片描述

上一章 创建了 服务发布者 provider 服务消费者 consumer
这一章 我们重新创建一个新的 集成OpenFeign的消费者

demo项目git地址: https://gitee.com/yijiecaomin/nacos-demo

2. 创建项目

2.1 pom.xml

<?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>
        <groupId>com.example</groupId>
        <artifactId>nacos-demo</artifactId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>open-fegin</artifactId>
    <groupId>com.example.consumer</groupId>
    <version>0.0.1-SNAPSHOT</version>
    <name>open-fegin</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
     
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
    </dependencies>

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

</project>

2.2 appliaction.properties

server.port=8030
spring.application.name=open-fegin

###nacos 配置
## 名称空间
spring.cloud.nacos.discovery.namespace=evone
## nacos 链接账号   没有设置不可以不选
spring.cloud.nacos.username=evone
# nacos 链接 密码   没有设置不可以不选
spring.cloud.nacos.password=evone123456
# spring.cloud.nacos.server-addr=192.168.104.110:8848  使用的nacos改了端口号,   默认端口 8848
spring.cloud.nacos.server-addr=192.168.104.110:16848

###ribbon 配置
#请求处理的超时时间
ribbon.ReadTimeout=6000
#请求连接的超时时间
ribbon.ConnectTimeout=4000
#对当前实例的重试次数
ribbon.MaxAutoRetries=2
#切换实例的重试的次数  1 就切换一次实例   2 切换两次(如果只有两个服务就会切换会刚刚请求的那个服务) 一次类推
ribbon.MaxAutoRetriesNextServer=1

###hystrix 配置
# 开启 hystrix
feign.hystrix.enabled=true
# hystrix 超时时间 一般 hystrix超时时间 = (1 + MaxAutoRetries + MaxAutoRetriesNextServer+MaxAutoRetries) * ReadTimeout
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=9000
#设置所有实例的默认值
hystrix.command.default.execution.timeout.enabled=true

2.3 启动类

package com.example.fegin;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient// 开启nacos 服务发现
@EnableFeignClients(basePackages = "com.example.fegin")
public class OpenFeginApplication {

    public static void main(String[] args) {
        SpringApplication.run(OpenFeginApplication.class, args);
    }

}

2.4 Cotrolller 接口类

package com.example.fegin.controller;

import com.example.fegin.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FeginContoller {

    @Autowired
    private DemoService demoService;

    @GetMapping("/test/{id}")
    public Object test(@PathVariable String id) {

        String forObject = demoService.test(id);

        return forObject;
    }
}

2.5 open-feign实现令牌中继

2.5.1 什么是令牌中继

令牌中继通俗的讲则是让令牌在微服务链路调用中传递下去,保证各个微服务能够获取令牌中的用户信息。在通俗点就是 将请求头信息透传到被调用的微服务中
在这里插入图片描述
客户端携带令牌请求网关,网关鉴权成功后会将令牌中的用户信息解析出来放在请求头中下发给订单服务,同样的,订单服务需要将用户信息传递给账户服务获取该用户的账户信息。

令牌在OpenFeign调用过程中是不能自动中继的,因此必须手动的将令牌信息传递下去。

/**
 * 用于实现令牌信息中继
 */
@Component
public class FeignRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        //当feign 开启 hyxtr
        //当Feign开启Hystrix支持时, RequestContextHolder.getRequestAttributes 就会为null
        //原因在于 Hystrix的默认隔离策略是THREAD 。而 RequestContextHolder 源码中,使用了两个血淋淋的ThreadLocal 。
        //Hystrix官方强烈建议使用THREAD作为隔离策略
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //获取RequestContextHolder中的信息
        Map<String, String> headers = getHeaders(request);
        //放入feign的RequestTemplate中
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            System.out.println("令牌中继 机制 key:"+entry.getKey()+" value:" +entry.getValue());
            template.header(entry.getKey(), entry.getValue());

        }

    }

    /**
     * 获取原请求头
     */
    private Map<String, String> getHeaders(HttpServletRequest request) {
        Map<String, String> map = new LinkedHashMap();
        Enumeration<String> enumeration = request.getHeaderNames();
        if (enumeration != null) {
            while (enumeration.hasMoreElements()) {
                String key = enumeration.nextElement();
                String value = request.getHeader(key);
                map.put(key, value);
            }
        }
        return map;
    }
}

注意: OpenFeign 在开启熔断降级后内部调用开启了子线程,因此传统方案直接下RequestInterceptor中设置是不可行的。也就是说: OpenFeign 开启Hystrix后就拿不到上下文
原因在于 Hystrix的默认隔离策略是THREAD 。而 RequestContextHolder 源码中,使用了两个血淋淋的ThreadLocal 。

解决方案

  • 取消熔断 feign.hystrix.enabled=false
  • 切换隔离等级 hystrix.command.default.execution.isolation.strategy=SEMAPHORE
  • 其他的太复杂 自己百度吧

启动测试

在这里插入图片描述

总结& 使用注意事项

Spring Cloud Openfegin 自动集成了 Ribbon 与 Hystrix;
Openfegin 默认开启 Ribbon
Openfegin 默认不开启 Hystrix
Openfegin 默认 HttpClient

在pom坐标使用过程中 OpenFegin 要使用与 nacos-discovery 的版本不一样的话 可能造成依赖jar包坐标版本冲突,导致依赖jar 下不下来 出现各种各样的问题 例如

java.lang.ClassNotFoundException: com.netflix.config.CachedDynamicIntProperty
在这里插入图片描述
需要单独引入引入

<dependency>
    <groupId>com.netflix.archaius</groupId>
    <artifactId>archaius-core</artifactId>
    <version>0.7.6</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </exclusion>
    </exclusions>
</dependency>
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Spring Cloud AlibabaSpring Cloud的一个子项目,它是阿里巴巴微服务生态的重要组成部分,提供了一系列基于Spring BootSpring Cloud的微服务组件,如服务注册与发现、配置管理、负载均衡、服务调用、熔断器等。而Nacos作为一个新兴的服务发现和配置中心,可以方便地进行服务治理。 Spring Cloud Alibaba整合Nacos的过程相对简单,只需要引入相关依赖,并在代码中使用对应的注解进行配置即可。 首先,在pom.xml文件中添加以下依赖: ```xml <!-- Nacos Discovery --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- Nacos Config --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> ``` 然后,在启动类上使用@EnableDiscoveryClient注解启用Nacos服务注册与发现功能: ```java @SpringBootApplication @EnableDiscoveryClient public class DemoApplication{ public static void main(String[] args){ SpringApplication.run(DemoApplication.class,args); } } ``` 接下来就可以使用@NacosValue注解注入配置信息: ```java @RestController public class DemoController{ @NacosValue(value="${config.key}",autoRefreshed=true) private String configValue; @GetMapping("/config") public String getConfig(){ return configValue; } } ``` 这样就可以通过Nacos Config来动态修改配置信息了。另外,Spring Cloud Alibaba还提供了一些其他有用的组件,如Sentinel、Seata等,可以方便地进行服务治理和分布式事务管理。 总的来说,Spring Cloud Alibaba整合Nacos是一个极为方便且实用的方式,它可以大大简化微服务应用的开发和部署,提高了系统的可靠性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一介草民丶

谢谢老板的一分钱

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

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

打赏作者

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

抵扣说明:

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

余额充值