在业务开发的时候,经常会遇到某一个接口不能对外暴露,只能内网服务间调用的实际需求。面对这样的情况,我们该如何实现呢?今天,我们就来理一理这个问题,从几个可行的方案中,挑选一个来实现。

1. 内外网接口微服务隔离

将对外暴露的接口和对内暴露的接口分别放到两个微服务上,一个服务里所有的接口均对外暴露,另一个服务的接口只能内网服务间调用。

该方案需要额外编写一个只对内部暴露接口的微服务,将所有只能对内暴露的业务接口聚合到这个微服务里,通过这个聚合的微服务,分别去各个业务侧获取资源。

该方案,新增一个微服务做请求转发,增加了系统的复杂性,增大了调用耗时以及后期的维护成本。

2. 网关 + redis 实现白名单机制

在 redis 里维护一套接口白名单列表,外部请求到达网关时,从 redis 获取接口白名单,在白名单内的接口放行,反之拒绝掉。

该方案的好处是,对业务代码零侵入,只需要维护好白名单列表即可;

不足之处在于,白名单的维护是一个持续性投入的工作,在很多公司,业务开发无法直接触及到 redis,只能提工单申请,增加了开发成本;另外,每次请求进来,都需要判断白名单,增加了系统响应耗时,考虑到正常情况下外部进来的请求大部分都是在白名单内的,只有极少数恶意请求才会被白名单机制所拦截,所以该方案的性价比很低。

3. 方案三 网关 + AOP

相比于方案二对接口进行白名单判断而言,方案三是对请求来源进行判断,并将该判断下沉到业务侧。避免了网关侧的逻辑判断,从而提升系统响应速度。

我们知道,外部进来的请求一定会经过网关再被分发到具体的业务侧,内部服务间的调用是不用走外部网关的(走 k8s 的 service)。

根据这个特点,我们可以对所有经过网关的请求的header里添加一个字段,业务侧接口收到请求后,判断header里是否有该字段,如果有,则说明该请求来自外部,没有,则属于内部服务的调用,再根据该接口是否属于内部接口来决定是否放行该请求。

该方案将内外网访问权限的处理分布到各个业务侧进行,消除了由网关来处理的系统性瓶颈;同时,开发者可以在业务侧直接确定接口的内外网访问权限,提升开发效率的同时,增加了代码的可读性。

当然该方案会对业务代码有一定的侵入性,不过可以通过注解的形式,最大限度的降低这种侵入性。

具体实操

下面就方案三,进行具体的代码演示。

首先在网关侧,需要对进来的请求header添加外网标识符: from=public

点击查看代码
@Component
public class AuthFilter implements GlobalFilter, Ordered {
    @Override
    public Mono < Void > filter ( ServerWebExchange exchange, GatewayFilterChain chain ) {
         return chain.filter(
         exchange.mutate().request(
         exchange.getRequest().mutate().header("id", "").header("from", "public").build())
         .build()
         );
    }
 
    @Override
    public int getOrder () {
        return 0;
    }
 }

最后,在只能内网访问的接口上加上@OnlyIntranetAccess注解即可

点击查看代码
@GetMapping ( "/role/add" )
@OnlyIntranetAccess
public String onlyIntranetAccess() {
    return "该接口只允许内部服务调用";
}
posted @ 2024-07-10 22:27 周XX 阅读(40) 评论(0) 推荐(0) 编辑
摘要: 以理服人 链式法则是微积分中用于求导的重要法则,它适用于复合函数的导数求解。 设有两个函数:y = f(u) 和 u = g(x),则复合函数 y = f(g(x))。 我们要求导复合函数 y 对于 x 的导数,即求 dy/dx。 根据链式法则,dy/dx = dy/du * du/dx。 其中,d 阅读全文
posted @ 2023-12-06 20:20 周XX 阅读(468) 评论(0) 推荐(0) 编辑
摘要: 上了篇尝试了利用穷举法来求较好的模型,但是穷举法的效率很低。还有一种更高效的方法,梯度下降法(Gradient Descent)。 算法过程 代码实现 x = [338., 333., 328., 207., 226., 25., 179., 70., 208., 606.] y = [640., 阅读全文
posted @ 2023-11-15 23:33 周XX 阅读(9) 评论(0) 推荐(0) 编辑
摘要: 样本:有十个点 假设有十个点,用matplotlib画出来 import matplotlib.pyplot as plt cp = [338., 333., 328., 207., 226., 25., 179., 70., 208., 606.] y = [640., 633., 619., 3 阅读全文
posted @ 2023-11-15 00:17 周XX 阅读(18) 评论(0) 推荐(0) 编辑
摘要: numpy.meshgrid函数用于从表示笛卡尔索引或矩阵索引的两个给定一维数组中创建矩形网格。网格函数是从MATLAB中得到启发的。 语法 numpy.asarray(arr,dtype=None,order=None) 参数 x1, x2,…, xn: array_like 表示网格坐标的一维数 阅读全文
posted @ 2023-11-08 22:53 周XX 阅读(56) 评论(0) 推荐(0) 编辑
摘要: numpy.asaray()函数用于将输入转换为数组。输入可以是列表、元组列表、元组、元组的元组、列表和数组的元组。 语法 numpy.asarray(arr,dtype=None,order=None) 参数 arr:[array_like]输入数据,可以转换为数组的任何形式。这包括列表、元组列表 阅读全文
posted @ 2023-11-08 00:20 周XX 阅读(51) 评论(0) 推荐(0) 编辑
摘要: 通常而言,数据不会以处理好的形式出现,所以我们需要在训练前对数据进行预处理,以适应训练 所有 TorchVision 的 Dataset 都会有两个参数—— transform 用于修改特征,target_transform 用于修改标签——它们接受包含转换逻辑的可调用对象(其实就是接受函数对象)。 阅读全文
posted @ 2023-06-05 23:37 周XX 阅读(33) 评论(0) 推荐(0) 编辑
摘要: Dataset 和 DataLoader 用于处理数据样本的代码可能会变得凌乱且难以维护;理想情况下,我们希望数据集代码与模型训练代码解耦,以获得更好的可读性和模块化。PyTorch提供的torch.utils.data.DataLoader 和 torch.utils.data.Dataset允许 阅读全文
posted @ 2023-04-10 00:25 周XX 阅读(98) 评论(0) 推荐(0) 编辑
摘要: 张量 张量是一种特殊的数据结构,与数组和矩阵非常相似。 在 PyTorch 中,我们使用张量对模型的输入和输出以及模型的参数进行编码。 张量类似于 NumPy 的 ndarray,此外张量可以在 GPU 或其他硬件加速器上运行。事实上,张量和 NumPy 数组通常可以共享相同的底层内存,无需复制数据 阅读全文
posted @ 2023-04-08 23:59 周XX 阅读(89) 评论(0) 推荐(0) 编辑
摘要: 本文主要介绍机器学习中常见任务的API。 处理数据 PyTorch有两个处理数据的方式:torch.utils.data.DataLoader 和torch.utils.data.Dataset 。 Dataset存储样本及其相应的标签, DataLoader 在Dataset的外层用迭代器进行包装 阅读全文
posted @ 2023-04-08 22:41 周XX 阅读(167) 评论(0) 推荐(0) 编辑
点击右上角即可分享
微信分享提示