Feign如何区分业务调用

2 篇文章 0 订阅
2 篇文章 0 订阅

前言

需求背景。我们有两个网关系统,一个是内网使用的,一个是外网使用。如果是内部系统使用调用的内网网关。但是作为网关管理平台,需要和两个网关系统都进行交互。如果对外接口,则和外部网关交互。
网关本身提供的restful接口,便于使用,我们使用OpenFeign进行调用。但是带来一个问题。调用的时候如何指定内网还是外网网关?

方案一

写一个FeignClient,地址是一台nginx。然后再加个Feign拦截器,调用的时候判断,该调内网网关的时候,在path前加上/inner。
nginx做代理配置,如果path前缀是/inner,则将请求转到内网网关。
上代码

client

package com.org.demo.clients;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * 网关app客户端
 *
 * @author dzh
 * @date 2022/12/2 16:37
 */
@FeignClient(url = "https://server.local", 
        name = "gatewayClient", 
        configuration = GatewayConfig.class,
        fallback = GatewayClientFallback.class)
public interface GatewayClient {
    
    // 用来标识调用哪个网关
    ThreadLocal<Boolean> out = new ThreadLocal<>();
    @GetMapping(value = "something/msg")
    String msg();
}

config

package com.org.demo.clients;

import feign.RequestInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;

/**
 * @author dzh
 * @date 2022/12/2 17:24
 */
@Slf4j
public class GatewayConfig {

    @Value("${gateway.auth}")
    private String auth;

    @Bean
    @Order(1000)
    public RequestInterceptor getRequestInterceptor() {
        return template -> {

            // 鉴权消息头
            template.header("Authorization", auth);
            String path = template.path();

            if (GatewayClient.out.get()) {
                GatewayClient.out.remove();
                template.uri("outside" + path);
            } else {
                GatewayClient.out.remove();
                template.uri("inside" + path);
            }
        };
    }
}

方案二

大家觉着第一个方案不太好,还要依赖nginx,但是碍于项目工期,先那样上线了。所有有了后续的方案
写两个FeignClient。有个问题,因为两个网关系统出了ip不同,其他都是一样的,写两个就会有冗余代码。那其实有个偷懒的办法。基于方案一得代码,再写两个实现,分别是内网和外网的客户端。
此方案不用依赖nginx,url直接配置对应网关系统的地址。
这个方案需要在调用的Service中注入两个client,需要哪个调用哪个。
因为是基于之前的方案升级的,不可能一下子全改了,所以在使用@Resource GatewayClient gatewayClient的地方,都需要制定beanId,否则因为容器中有桑格GatewayClient实例,启动会失败。
这样就实现了过度,当都改成方案二的调用方式,就可以删除多余的拦截器了

内网

package com.org.demo.clients;

import org.springframework.cloud.openfeign.FeignClient;

@FeignClient(url = "https://server.local",
        name = "gatewayInsideClient",
        qualifiers = "gatewayInsideClient",
        fallback = GatewayClientFallback.class)
public interface GatewayInsideClient extends GatewayClient {
}

外网

package com.org.demo.clients;

import org.springframework.cloud.openfeign.FeignClient;

@FeignClient(url = "https://server.local",
        name = "gatewayOutsideClient",
        qualifiers = "gatewayOutsideClient",
        fallback = GatewayClientFallback.class)
public interface GatewayOutsideClient extends GatewayClient {
}

方案三

以上两个方案已经实践过是么有问题的。方案三目前只停留在理论阶段。方案二因为指定的是ip地址,而且只能指定一个,所以存在风险,如果服务器宕机那就糟了。
SpringCloud有服务发现的机制,也可以将网关的服务注册到Nacos,然后client做对应的修改问题就解决了。

后续

我比较了一下,三中方案没有谁是最好的,只是看合适不合适
方案一:如果我们有十个八个网关,使用该方案还是比较合适的
方案二:如果少量的网关服务,这个方案还是比较好的
方案三:解决方案二单点的问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值