分布式之网关介绍

一、网关简介

1、网关背景

  • 由于微服务“各自为政的特性”使微服务的使用非常麻烦。
  • 通常公司会有一个“前台小姐姐”作为统一入口,这就是网关

2、网关作用

  • 统一入口:为服务提供一个唯一的入口,网关起到外部和内部隔离的作用, 保障了后台服务的安全性。
  • 鉴权校验:识别每个请求的权限,拒绝不符合要求的请求。
  • 动态路由:动态的将请求路由到不同的后端集群中。
  • 减少客户端与服务端的耦合:服务可以独立发展,通过网关层来做映射。

3、网关优势

  • 路由和负载均衡:网关可以作为反向代理,接收客户端请求并将其路由到后端的多个服务器。通过使用负载均衡算法,网关可以根据服务器的负载情况分发请求,从而实现请求的平衡和优化。
  • 安全性和访问控制:网关可以充当安全层,通过在请求到达应用程序之前进行身份验证、授权和访问控制来保护应用程序。它可以拦截和阻止恶意请求、DDoS攻击和SQL注入等常见的安全威胁。
  • 协议转换和数据格式转换:网关可以处理不同的协议和数据格式之间的转换。它可以将来自客户端的请求从一种协议转换为另一种协议,或将后端服务的响应转换为适合客户端的数据格式,从而实现系统之间的无缝集成和通信。
  • 监控和分析:网关可以收集和监控来自客户端和后端服务的请求和响应数据。它可以记录日志、统计数据和指标,提供关于请求流量、性能和错误的实时监控和分析。这些信息可以帮助开发人员和管理员识别问题、优化性能和做出决策。

4、网关劣势

  • 在微服务这种去中心化架构中,成为瓶颈点:如果网关挂掉,将会影响整个系统的可用性。作为系统的入口点,网关的故障可能导致无法访问后端服务和应用程序。
  • 服务如果不是异步或者同步非阻塞,耦合度高:如果通过网关调用后端服务不可用或者响应时间超时,我们的连接数量是有限的,这时候网关处理能力下降这时候可能造成其他服务的不可用,严重者甚至导致雪崩效应

二、常见网关的对比

1、Netflix Zuul1.0

  • 中小厂落地案例丰富
  • 基于同步阻塞I0,性能差
  • Netflix已经停止了对Zuul 1.0的维护和开发

2、SpringCloud Gateway

  • 是Spring Cloud生态系统中的官方网关解决方案,与其他Spring Cloud组件(如Eureka、Ribbon、Hystrix等)无缝集成
  • 响应式支持:Spring Cloud Gateway基于Spring WebFlux框架,使用非阻塞式I/O和响应式编程模型,具有高性能和高吞吐量的特点

3、Netflix Zuul2.0

  • 基于非阻塞式I/O模型,性能接近SpringCloud Gateway
  • 它的开发和维护在2019年底停止了。Netflix推荐使用Spring Cloud Gateway作为替代方案,

4、综合对比

Zuul1.0Spring Cloud GatewayZuul2.0
长连接支持不支持支持支持
IO模型阻塞非阻塞非阻塞
性能
编程语言JavaJavaJava
协议支持HttpHttpHttp
流量管理需要二次开发需要二次开发需要二次开发
扩展性
成熟度
使用场景中小型流量项目大部分场景大部分场景

5、为什么自研网关

5.1 开源网关的不足

  • 限制性:开源网关通常具有一些默认的行为和规则,可能无法满足特定业务需求的定制化要求。某些功能可能无法直接扩展或修改,需要深入了解和修改源代码,这对于非开发人员来说可能是一项挑战。
  • 可靠性和稳定性:开源网关在稳定性和可靠性方面可能存在一些问题。尽管开源社区通常会及时修复和改进问题,但是在某些情况下,可能会遇到较长时间的修复周期或仍存在未解决的问题。这对于对高可用性和系统稳定性要求较高的应用来说可能是一个问题。
  • 技术支持和文档:相比商业解决方案,开源网关通常缺乏官方的技术支持和详细的文档。虽然开源社区通常提供一定的支持,但可能无法提供即时和全面的帮助。这对于在生产环境中使用开源网关的企业来说可能是一个潜在的风险。
  • 学习和培训成本:使用开源网关可能需要团队成员投入时间和精力来学习和理解其架构、配置和使用方式。这可能需要额外的培训和学习成本,特别是对于新加入的团队成员来说。
  • 安全性和漏洞:尽管开源网关通常经过广泛的社区审查,但仍然存在潜在的安全漏洞。由于开源代码的公开性,攻击者可以更容易地发现和利用其中的漏洞。这要求团队及时更新和升级网关,以确保应用的安全性。
  • 依赖和版本兼容性:开源网关可能依赖于其他的开源组件和库,可能需要处理版本兼容性和依赖冲突的问题。这可能需要额外的工作量来管理和升级依赖项,以确保系统的稳定性和一致性。

5.2 自研网关优势

  • 定制化能力:自研网关可以根据具体业务需求进行定制和扩展,满足特定场景的需求。你可以根据自己的业务逻辑、安全需求、性能要求等来设计和实现网关,确保网关与整个系统的需求高度匹配。
  • 灵活性和可扩展性:自研网关可以根据业务的发展和变化进行灵活调整和扩展。你可以根据需求添加新的功能、修改路由规则、引入新的协议等,而无需依赖第三方网关的更新和发布周期。
  • 性能和吞吐量:自研网关可以根据需求进行性能优化,以满足高并发和低延迟的要求。你可以选择合适的技术栈、采用非阻塞式I/O模型、引入异步处理等,以提升网关的性能和吞吐量。
  • 安全性和可控性:自研网关可以根据业务需求实现定制化的安全策略和访问控制机制。你可以集成各种认证和授权机制、请求过滤和防御机制,以确保系统的安全性,并根据具体需求进行调整和优化。
  • 增强的监控和调试能力:自研网关可以针对自身的需求添加详细的监控指标和调试功能。你可以收集和展示请求流量、性能指标、错误日志等数据,以便进行监控、故障排查和性能优化。
  • 技术栈选择:自研网关可以根据团队的技术栈和专长选择合适的技术和工具。你可以选择自己熟悉和喜欢的编程语言、框架和库,使网关的开发和维护更加高效和舒适。

三、网关整体设计

1、技术选型

1.1 基础框架

  • SpringIOC ,SpringAOP,Springmvc
  • Spring Boot
  • 原生Java

1.2 网络框架

  • 原生NIO
  • Mina
  • Netty

1.3 注册中心

  • Zookeeper:Zookeeper是一个分布式协调系统,可以用于服务注册与发现。它提供了一个可靠的分布式数据存储,并支持高可用性和一致性。由于他是强一致所以不适合,大数据量的注册
  • Eureka:Eureka是Netflix开源的服务注册与发现组件,被设计为在云环境中运行。它采用了基于REST的架构,具有简单的配置和易于使用的特点。Netflix在官方文档中已宣布停止对Eureka的更新和维护
  • Consul:Consul是一个开源的服务网格解决方案,提供了服务注册与发现、健康检查、键值存储、分布式一致性和多数据中心功能等,但是他是GO语言实现的
  • Nacos:Nacos是阿里巴巴开源的一个服务发现、配置管理和服务治理平台。它提供了统一的服务注册与发现、动态配置管理、服务健康监测和流量管理等功能,帮助构建和管理云原生应用和微服务架构

1.4 配置中心

  • Spring Cloud Config:Spring Cloud Config是Spring Cloud提供的配置管理工具用于集中管理和分发应用程序的配置,但是不支持动态刷新
  • Apollo
  • Nacos

2、高性能要点

2.1异步化处理

  • 单异步模式 (Future)
  • 双异步模式 (completeFuture)

image.png

Future接口在某些方面存在一些局限性,这些局限性包括:

  1. 阻塞式获取结果:Futureget()方法是阻塞的,这意味着如果任务的结果还没有准备好,调用 get()方法的线程将会被阻塞,直到结果可用。这可能会导致应用程序的性能下降,特别是当需要同时处理多个 Future对象时。
  2. 无法取消任务:Future接口提供了 cancel()方法来取消任务的执行,但是这个方法并不能真正地取消任务的执行。它只是尝试去取消任务,并返回一个表示取消成功与否的布尔值。如果任务已经开始执行或已经完成,那么 cancel()方法将无效。
  3. 缺乏异常处理:Future接口的 get()方法会抛出 InterruptedExceptionExecutionException异常。然而,这些异常并不提供足够的信息来了解任务失败的原因。当任务抛出异常时,我们无法在 Future对象上捕获和处理这些异常。
  4. 无法组合多个 Future对象:在某些情况下,我们可能需要组合多个异步任务的结果,例如并行执行多个任务并将它们的结果合并。Future接口本身并不提供直接的支持来处理这种情况,需要使用其他的方法,例如使用 CompletionService或者 CompletableFuture来实现。

为了克服这些局限性,Java 8 引入了 CompletableFuture类,它提供了更强大和灵活的功能,包括更好的异常处理、组合多个任务的结果以及异步任务的回调等。CompletableFuture类提供了一种更现代和易于使用的方式来处理异步编程任务。

CompletableFuture

CompletableFuture是Java编程语言中的一个类,它在Java 8中引入作为CompletableFuture API的一部分。它属于java.util.concurrent包,并提供了一种执行异步编程和处理异步计算结果的方式。

CompletableFuture代表了一个可能在未来完成的计算,并允许你将多个操作链接在一起形成一个流水线。每个操作都是异步执行的,这意味着它可以与其他操作或任务并发运行。

以下是关于CompletableFuture的一些关键特性和概念:

  1. 异步执行:CompletableFuture提供了一种异步执行任务的方式,这意味着你可以启动一个任务并继续执行其他操作,而不需要等待任务完成。
  2. 组合:你可以将多个CompletableFuture实例链接在一起,形成一个操作的流水线。这使得你可以表达复杂的异步工作流和任务之间的依赖关系。
  3. 完成动作:CompletableFuture允许你指定在CompletableFuture完成时应执行的动作,无论是正常完成还是异常完成。你可以附加回调函数,在计算结果可用时执行,或者处理任何发生的异常。
  4. 结果合并:CompletableFuture提供了多种方法,在多个CompletableFuture都完成时合并它们的结果。例如,你可以使用 thenCombine方法指定一个函数,将两个CompletableFuture的结果合并并产生一个新的结果。
  5. 异常处理:CompletableFuture提供了多种方法来处理计算过程中发生的异常。你可以使用 exceptionally方法指定一个备用值,或者使用 handle方法处理异常并基于异常产生一个结果。
  6. 异步执行模型:CompletableFuture支持不同的执行模型,例如使用单独的线程异步执行任务,或者利用线程池执行任务。

image.png

package com.msb;import java.util.concurrent.*;public class FutureTaskTest {public static void main(String[] args) throws ExecutionException, InterruptedException {// 创建任务T2 FutureTaskFutureTask<String> ft2 = new FutureTask<>(new T2Task());// 创建任务T1的 FutureTaskFutureTask<String> ft1 = new FutureTask<>(new T1Task(ft2));// 线程1 执行T2任务Thread t1 = new Thread(ft2);t1.start();// 线程2执行  任务他Thread t2 = new Thread(ft1);t2.start();//等待返回结果System.out.println(ft1.get());}}
// T1 任务 洗水壶,烧开水,泡茶class T1Task implements Callable<String>{FutureTask<String> ft2;public T1Task(FutureTask<String> ft2) {this.ft2 = ft2;}@Overridepublic String call() throws Exception {System.out.println("T1 洗水壶。。。。。");TimeUnit.SECONDS.sleep(1);System.out.println("T1 烧开水。。。。。");TimeUnit.SECONDS.sleep(2);// 获取T2线程String res = ft2.get();System.out.println("T1 拿到茶叶。。。" + res);System.out.println("T1 泡茶。。。。。");return "喝茶" + res;}
}
// T2任务 洗茶壶、洗茶杯、拿茶叶class T2Task implements Callable<String>{@Overridepublic String call() throws Exception {System.out.println("T2 洗茶壶。。。。。");TimeUnit.SECONDS.sleep(1);System.out.println("T2 洗茶杯。。。。。");TimeUnit.SECONDS.sleep(2);System.out.println("T2 拿茶叶。。。。。");TimeUnit.SECONDS.sleep(1);return "铁观音";}
}
package com.msb;import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;public class CompletableFutureTest {public static void main(String[] args) {// 任务1: 洗水壶 -> 烧开水CompletableFuture<Void> f1 = CompletableFuture.runAsync(() -> {System.out.println("T1 洗水壶。。。。。");sleep(1,TimeUnit.SECONDS);System.out.println("T1 烧开水。。。。。");sleep(2,TimeUnit.SECONDS);});// 任务2: 洗茶壶 -> 洗茶杯 -> 拿茶叶CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> {System.out.println("T2 洗茶壶。。。。。");sleep(1,TimeUnit.SECONDS);System.out.println("T2 洗茶杯。。。。。");sleep(2,TimeUnit.SECONDS);System.out.println("T2 拿茶叶。。。。。");sleep(1,TimeUnit.SECONDS);return "铁观音";});// 任务3: 任务1和任务2完成后执行:泡茶CompletableFuture<String> f3 = f1.thenCombine(f2, (__, tf) -> {System.out.println("T1 拿到茶叶。。。。" + tf);System.out.println("T1 泡茶");return "喝茶:" + tf;});// 等待任务3的执行结果System.out.println(f3.join());}static void sleep(int t ,TimeUnit u){try {u.sleep(t);} catch (InterruptedException e) {e.printStackTrace();}}
}

2.2 使用缓存机制

尽量使用内容作为缓存(Map、Queue) ,比如加载的配置

2.3 合理利用串行和并行化机制

  • 串行化使用场景

    耗时较小,性能要求较高的场景

  • 并行化使用场景

    耗时较久,任务之间没有依赖关系,比如远程RPC调用场景

3、整体架构

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/562677.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio 和 lombok 的版本适配、gradle依赖配置、插件安装及使用

文章目录 Intro注意事项Android Studio 和 lombok 的版本选择及下载下载链接 在 Android Studio 中安装一次 lombok 插件在每个 gradle 项目中添加 lombok 相关依赖(如要用到)使用ref Intro 用惯了 JavaMavenIDEA 开发后端服务&#xff0c;突然有一天用 JavaGradleAndroidStud…

优化选址问题 | 基于鹈鹕算法求解基站选址问题含Matlab源码

目录 问题代码问题 鹈鹕算法(Pelican Optimization Algorithm, POA)是一种相对较新的启发式优化算法,模拟了鹈鹕鸟觅食的行为。这种算法通常用于解决复杂的优化问题,如函数优化、路径规划、调度问题等。基站选址问题通常是一个复杂的优化问题,需要考虑覆盖范围、干扰、成…

MapReduce学习问题记录

1、如何跳过对某行数据的处理 第一行数据是字段名不需要处理&#xff0c;我们知道第一行偏移量是0&#xff08;行记录的时候是从数组首地址开始&#xff0c;到了行标识符进行一次计数&#xff0c;这个计数就是行偏移量&#xff0c;从0开始&#xff09;&#xff0c;我们根据偏移…

贪吃蛇(C语言超详细版)

目录 前言&#xff1a; 总览&#xff1a; API&#xff1a; 控制台程序&#xff08;Console&#xff09;&#xff1a; 设置坐标&#xff1a; COORD&#xff1a; GetStdHandle&#xff1a; STD_OUTPUT_HANDLE参数&#xff1a; SetConsoleCursorPosition&#xff1a; …

第十一届蓝桥杯大赛第二场省赛试题 CC++ 研究生组-子串分值和

solution1&#xff08;通过40%&#xff09; 依次求子串并统计出现过的字母个数 #include<iostream> #include<string> #include<set> using namespace std; int main(){string s, subs;cin >> s;int len s.size(), ans 0;for(int j 1; j < len…

大数据------javase基础------day18(完结)

类加载器 作用 负责将编译后的java文件&#xff08;即.class文件&#xff09;加载到内存中供虚拟机执行 类加载的时机------总结一句话&#xff1a;用到类就加载&#xff0c;不用就不加载 创建类的实例调用类的方法访问类或者接口的类变量&#xff0c;或者为该类变量赋值使用反…

列车票务信息管理系统设计与实现|jsp+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW调试部署环境&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java…

多线程和线程同步

文章目录 进程和线程线程的操作线程创建线程退出线程回收线程分离线程取消和ID比较 线程同步互斥锁死锁读写锁条件变量信号量 进程和线程 线程是轻量级的进程&#xff0c;在Linux环境下线程的本质还是进程。 在计算机上运行的程序是一组指令及指令参数的组合&#xff0c;指令按…

混合云构建-使用 Azure ExpressRoute 建立从本地到 Azure 虚拟网络的专用连接

如果有大量业务数据需要在本地数据中心和azure私有网络进行传输&#xff0c;同时保证带宽和时延的情况需要使用 ExpressRoute 设置从本地网络到 Azure 中的虚拟网络的专用连接。以下是实操步骤供参考&#xff1a; 一、创建和预配 ExpressRoute 线路 登录 Azure 门户。 在页面…

Vue3 + Django 前后端分离项目实现密码认证登录

1、功能需求 通常中小型前后端项目&#xff0c;对安全要求不高&#xff0c;也可以采用密码认证方案。如果只用django来实现非常简单。采用 Vue3 前后端分离架构&#xff0c;实现起来稍繁琐一点&#xff0c;好处是可以利用各种前端技术栈&#xff0c;如element-plus UI库来渲染…

ETH Gas 之 Base Fee Priority Fee

前情回顾 ETH网络 之 Gas EIP-1559 EIP-1559 EIP-1559是以太坊改进提案&#xff08;Ethereum Improvement Proposal&#xff09;&#xff0c;旨在改进以太坊的交易费用机制。该提案引入了一种新的交易费用模型&#xff0c;以提高交易费用的可预测性和网络的效率。我们本文各…

使用 PyOpenGL 进行 2D 图形渲染总结

一、说明 OpenGL是一个广泛使用的开放式跨平台实时 3D 图形库&#xff0c;开发于二十多年前。它提供了一个低级API&#xff0c;允许开发人员以统一的方式访问图形硬件。在开发需要硬件加速且需要在不同平台上运行的复杂 2D 或 3D 应用程序时&#xff0c;它是首选平台。它可以在…