涂鸦智能落地 Koupleless 合并部署,实现云服务降本增效

7bef22ee2c89070f8e6258b0b38dc3a5.gif

文|八幡、朵拉

杭州涂鸦智能技术专家

主要研究微服务与可观测、消息引擎、任务调度、数据层中间件等领域。 

本文 5389 字 阅读 15 分钟

当前涂鸦通过 Koupleless 的静态合并部署能力,很好地解决了资源浪费问题。

为了进一步提升研发效率,涂鸦与 Koupleless 正在开发动态合并部署能力,为公有云大规模合并部署打下基础,也为未来更长远的 Serverless 能力提供基座。

44e8ddd0a3b6bf720871228b7fcfae68.gif

Koupleless 在涂鸦智能的落地效果探讨

背景     

Background

涂鸦智能是全球领先的云平台服务提供商,致力于构建智慧解决方案的开发者生态,赋能万物智能。基于全球公有云,涂鸦开发者平台实现了智慧场景和智能设备的互联互通,承载着每日数以亿计的设备请求交互;拥有亿级海量数据并发处理能力,为用户提供高稳定性的不间断计算服务。

f2a62ddaf03b34d7e92a89287a741f39.png

涂鸦智能不仅服务于公有云用户,同时也为大客户提供混合云及私有云解决方案,满足不同层次客户的需求。因此,涂鸦需要同时关注公有云和私有云服务中潜在的问题。

公有云用户基数大、设备多、核心业务服务实例多,但也符合二八原则——20%的服务承担了 80%的流量。还有大量的配套周边管理服务及正处于发展中的业务等,虽然服务实例数量少,但为了保障业务的稳定性及可用性,至少得部署 2 个实例。

私有云在服务刚落地时,通常规模较小,随着业务的逐步发展,接入的用户数和设备数才会随之上涨。如果一开始就生搬硬套公有云的交付模式,将上百个服务部署在私有云客户环境中,基础设施成本占比太大,不仅造成了硬件资源成本浪费,同时也提升了运维复杂度。 

综合考虑公有云部分服务和私有云前期服务存在的硬件资源利用率低、弹性扩容慢等问题,涂鸦开始着手调研解决方案。 

方案调研 

Research

首先看下内存占用情况:

内存占用分析

涂鸦绝大部分业务应用都是采用 Java 语言实现的,基于微服务架构,部署在 K8S 上。来看下内存占用情况:

  • 每个 POD 都需要启动精简的 Linux 系统,约几十兆初始内存;

  • K8S 节点一般会附带一些 POD 监控、日志收集 Agent,约几十兆初始内存;

  • Java Agent 之类的字节码增强消耗的初始内存;

  • JVM 类库,Spring、Netty、Dubbo 等框架,内嵌 WEB 容器,占用的 Metaspace 和堆栈空间;

  • 业务应用代码启动占用的 Metaspace 和堆栈空间;

  • 业务流量处理产生的堆栈空间。

从上面分析可以看出,除了业务应用代码本身和业务流量处理之外,其他的内存占用当然是越少越好。一个简单的控制台应用内存占用如下图所示:

0f64c12d39c5e8b693b1b952c8ee1f34.png

在微服务架构的视角下,Java 应用不但没有百多兆的 JRE 和框架之类的基础内存需要问题,更重要的是,单个微服务也不再需要再数十 GB 的内存。有了高可用的服务集群,也无须追求单个服务 7×24 小时不间断运行,在一天内随着业务流量的波动、高峰和低谷,服务随时可以进行弹性扩缩容。

但相应地,Java 的启动时间相对较长、需要预热才能达到最高性能等特点就显得相悖于这样的应用场景。在无服务架构中,矛盾则可能会更加突出,比起服务,一个函数的规模通常会更小,执行时间会更短。在这样的场景下,我们看下有哪些方案可以降本增效:

⭕️ 搁浅方案:Native Image

⭕️无法支持全场景、Spring 支持不足、异常难预见、问题难排查。

提前编译(Ahead of Time Compilation,AOT)可以减少即时编译带来的预热时间,减少 Java 应用长期给用户带来的“第一次运行慢”的不良体验,让用户能放心地进行很多全程序的分析行为,使用更大的优化措施。而随着 Graal VM 技术的成熟,它能显著降低内存占用及启动时间。由于 HotSpot 本身就会有一定的内存消耗(通常约几十 MB),根据 Oracle 官方给出的测试数据,运行在 Substrate VM 上的小规模应用,其内存占用和启动时间与运行在 HotSpot 相比有了 5 倍到 50 倍的下降。

但是提前编译的坏处也很明显,它破坏了 Java“一次编写,到处运行”的承诺,必须为每个不同的硬件、操作系统去编译对应的发行包。它也显著降低了 Java 链接过程的动态性,要求加载的代码必须在编译期就是全部已知的,而不能再是运行期才确定,大多数运行期对字节码的生成和修改操作也不再行得通。特别是在整个 Java 的生态系统中,数量庞大的第三方库要一一进行适配。随着 Graal VM 团队与来自 Pivotal 的 Spring 团队的紧密合作,解决了 Spring 全家桶在 Graal VM 上的运行适配问题。

为此,我们进行了 JDK17 升级,并将 SpringBoot 升至 3.x 版本,Dubbo 升至 3.x 版本。在验证过程中出现了许多组件的兼容性问题,如 Apollo、Guava、Jedis、MyBatis 等,也进行了逐一解决。

虽然该方案在简单的内部应用上验证通过,并上线试运行了一段时间,取得了一定的效果。但业务应用使用的第三方库数量众多,达到数百个,在如 GroovyShell、BouncyCastle、Agent 等场景上还无法很好地支持。同时 Spring 的支持不足,如 Spring XML Bean 的构造参数或 properties 配置出现 TypedStringValue 类型无法识别,Spring-AOT 不支持 setter-inject 方式的循环依赖等,导致需要对应用进行较大调整和修改,另外会出现一些无法预见的异常,且出现问题时不方便定位排查。最后涂鸦还是决定暂时搁浅该方案。

✅ 使用中:Koupleless

Koupleless 是一种模块化的 Serverless 技术解决方案,它能让普通应用以比较低的代价演进为 Serverless 研发模式,让代码与资源解耦,轻松独立维护,与此同时支持秒级构建部署、合并部署、动态伸缩等能力为用户提供极致的研发运维体验,最终帮助企业实现降本增效。

不同模块支持完全类隔离加载,对于应用开发来说相对透明,当然 Koupleless 也提供了更多插件机制,还有进程间跨 ClassLoader 的 JVM 调用能力。主要有如下优势:

  • 类隔离:通过对业务应用的类隔离加载,原有业务系统几乎无侵入支持合并部署;

  • 插件机制:通过插件机制解决依赖冲突问题;

  • 基座和模块:可以将中间件和基础框架下沉到基座,框架与中间件升级维护成本降低。通过进程内 JVM 调用替代远程调用,节省网络 IO 和序列化反序列化成本,提升性能和稳定性。见下图:

0a42106e5d5e7b2a6a021e623b4d14d2.png

  • 静态合并部署:方便快速验证,简化部署,适合私有云环境;

  • 动态合并部署:支持模块的热更新,提高发布效率,降低启动时间,适合公有云环境。

就内存节省效率方面来说,可以节省 POD 容器、Tomcat 容器、公共类库加载 Metaspace 等内存资源,主要是节省启动内存开销。对于低流量业务,几个应用合并部署到一个,资源利用更充分:10 个低流量 1C2G 应用,合并后仅需能一个 2C4G 就能搞定;单个应用突发的高流量可以有更大的水位池,稳定性也会提升。而对于高流量业务,虽然在内存方面优势不大,但可以实现极速弹性,更有利于 Serverless 架构。

❌ 其他弃选方案

  • 代码合并:简单粗暴,降本优势明显,但同时也降低了开发和运维效率,不利于维护和业务快速发展

  • 基于代码组织的模块化:服务打成 jar 包引入,但没有 ClassLoader 隔离,容易造成类库依赖冲突,beanName 冲突等

  • 基于 Tomcat 的多 WAR 包部署:业务系统无任何侵入,也能一定程度上节省多个应用的 POD 和应用内置 Tomcat 内存。但脱离了主流的 DevOps 体系,需要针对这种部署方式提供额外支持,同时能节省的内存也非常有限。


综合考虑,涂鸦决定使用 Koupleless 进行改造升级。

改造升级

Adaption

Koupleless 是一种多应用的架构,而传统的中间件可能只考虑了一个应用的场景,故在一些行为上无法兼容多应用共存的行为,会发生共享变量污染、ClassLoader 加载异常、Class 判断不符合预期等问题。由此,在使用 Koupleless 中间件时,我们需要对一些潜在的问题做补丁,覆盖掉原有中间件的实现,使开源的中间件和自研的组件也能兼容多应用的模式,涉及到以下的使用方式,可能需要多模块化适配改造:

适配点

系统变量被共享

在使用的时候,需要考虑到全局共享的情况下是否会与别的模块冲突,包括但不限于:Appid 、环境变量、System 配置等。

静态变量、静态单例、静态缓存被共享

正常情况下公共代码都是由基座进行加载,而基座的类加载器是唯一的,所以不同的模块对静态变量的操作都是施加在同一个对象上的,解决方案如下:

  • 公共包从基座引用改成每个应用单独引入

  • 将静态变量调整为按 ClassLoader 进行缓存,每次操作只对当前线程的 ClassLoader 对应的对象进行操作。

类找不到异常

一般存在于通过基座加载相应的类或者静态调用的情况下。由于基座类加载器无法访问到模块的类加载器,所以在公共代码中加载类时优先使用 Thread.currentThread().getContextClassLoader()

  • XX Class Not Found

  • XX Class No Defined

  • ServiceLoader 异常

日志适配

  • logback 通过 condition 进行适配

<if condition='property("sofa.ark.embed.enable").contains("true")'><then><springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="NO_APP_CONFIG"/><property name="BASE_PATH" value="${user.home}/logs/${APP_NAME}"/></then><else><springProperty scope="context" name="loggingRoot" source="logging.file.path"/><property name="BASE_PATH" value="${loggingRoot}/"/></else></if>
  • log4j 通过 properties 进行适配

<Property name="loggingRoot">${sys:user.home}/logs/${spring:tuya.sofa.ark.app:-}</Property>
  • log4j2 和 logback 日志在同一个基座中混用

一般应用使用 logback,但是存在某些应用使用 log4j2 的情况,目前 Koupleless 不支持两种应用放在一个基座中,可以考虑在 Koupleless 上调整日志系统的判断,或在 Koupleless 上调整由模块决定某些 plugin 是否被加载。

健康检查

提供基座应用的健康检查实现:

  • 静态部署模式:合并部署的所有应用的状态都健康,健康检查才会通过。

  • 动态部署模式:提供配置,让用户自行决定模块热部署结果是否影响应用整体健康状态(默认配置为:不影响整体应用原本的健康状态)

Web 容器共享

  • 多 Host 模式:使用多个 port 进行区分。该模式的问题首先在于重复创建了 Tomcat 相关的资源,造成资源的浪费;其次是每个 Biz 有自己的端口,不利于整个 Ark 包应用整体对外提供服务。

  • 单 Host 模式:Koupleless 提供了类似独立 Tomcat 部署多 webapp 的方式。所有 Biz 共用同一个 Server 及 Host,每个 Biz 只创建自己的 Context,通过 Context 中的 contextPath 将自身接口与其它 Biz 接口做区分。

c3ef2ae1e0427a5bf114e0003c8d79a8.png

考虑到资源共享及整体性,我们采用了单 Host 模式。

实践心得

  • 将下沉的组件配置抽离到父 POM 中,方便统一管控;

  • 基座的 AutoConfig 被模块的依赖触发,但是初始化的时候报错,基座需要 exclude 相应的 AutoConfig。建议使用 Spring Boot 框架的自动装配功能时将相应组件下沉到基座;

  • ContextPath:可以通过参数动态配置,方便应用运行在单模块独占基座多模块合并部署场景中;

3a3c820cb730c0de22f591eea6c314ce.png

  • 模块需要开启 https 协议时:用于支持自定义证书场景,可以在模块获取到 web server 并主动添加一个新的 Connector。

f1197c3a6410e5c713e0149d2b89bdb5.png

DevOps 改造

Adaption of DevOps

测试应用验证通过后,涂鸦团队开始着手进行发布系统的改造。由于静态合并部署比较适合部署相对稳定不频繁的场景(如私有云),而公有云更适合动态合并部署模式。但为了给私有云交付打前战,涂鸦一期先在公有云上实现静态合并部署,快速试点验证。而静态合并部署是需要所有模块和基座一起发布的,为了尽可能不影响开发同学效率,我们同时支持单模块独占基座多模块合并部署两种发布模式,方便在开发、日常、预发、线上等环境进行实地试运行,完整验证业务链路。 

首先按业务域及流量情况将应用拆分为基座或模块:

bbede363efe4f03dbaeaaaafc617b578.png

然后发布系统根据基座与模块的映射关系,进行打包发布。目前我们是通过 K8S 部署服务的,源代码经过编译打包成 Docker 镜像再进行发布,为复用原有流程,快速上线,模块和基座都打包为镜像。模块由模块负责人进行打包,基座由业务域负责人打包,并根据迭代节奏进行定期发布。

13623ff828d3f1a16998311b05fa4170.png

InitContainert 先启动模块镜像,再将模块的 ark 包拷贝到/home/docker/module/biz目录下:

38ae5ad2a05e431292760cf67044c96e.png

通过-Dcom.alipay.sofa.ark.static.biz.dir 参数实现合并部署:

132adeeda04fac4e503c7cbdeb6e5eab.png

日志目录

日志路径由原来的 home/docker/logs,在合并模块部署后调整为 home/docker/logs/appname/,日志收集模板按此进行调整。std 输出的日志会打印在基座应用的 std 中,比如异常类的 printStackTrace,所以尽量避免使用 stdout 和 stderr。

域名切换

由于应用合并,原来的域名需要切换到新的域名上来。由单一应用过渡到合并部署模式的发布过程中需要注意对等的流量切换。

有两种域名切换方式:  

1、调用方切换到新域名。✅优点:简单,不需要路由。❌缺点:需要调用方配合调整,应用模块与基座关系调整时同样需要再次调整。

2、域名路由。调用方还是访问原域名,通过内部网关路由到新域名。✅优点:灵活。❌缺点:多一次调用。

我们最终采用路由的方式来进行域名切换。 

上线实施  

Implementation

目前一期按业务域划分为 18 个基座,60 多个模块在一些数据中心(如中国区、美西区等)进行合并部署后稳定运行。

9a716251ac6558f746cb1d6e4c0aa5a1.png

如某基座合并部署了 8 个模块:

b94839a57d035f4213aa4d81705b214a.png

合并后,每个模块由原来的 1C2G 变为 2C4G,节省资源 6C12G。  

a73d5f90342bd049495116285a0fd478.png

8 个模块非合并部署前的启动时间如下图 8 条记录显示,在 1-3 分钟之间。 ‍

837c0846b0c3c01962b44849d1c4cf90.jpeg

而静态合并部署后的基座启动时间见下图,约 2 分 45 秒。8 个模块分别交付,每个 1-3 分钟,统一成 2 分 45 秒一次性完成交付,大大提高了整体交付效率

89c3c508e9293a671d1b03aa93385803.jpeg

总体来说,在内存方面,对于应用初始启动内存占总消耗内存比例较高、低流量的业务场景,应用合并部署的内存节省收益越大。60 个模块共节省 70G 内存。线上 POD 数约有 6000 多个,预计可节省 6000 多 G 内存。相应地在 CPU 资源利用率方面,大部分业务应用都是 IO 密集型,而合并部署能将 CPU 较为充足地利用起来,线上 Pod 合并部署后能节省 3000 核

在调用性能和网络 IO 优化上,大流量的业务场景从远程调用变成本地调用,网络 IO、序列化反序列的 CPU 开销以及调用性能、稳定性上都能得到大幅度提升

后续演进 

Evolution

当前我们完成的是静态合并部署能力,很好地解决了资源浪费问题。为了进一步提升研发效率,我们正在开发动态合并部署能力,为公有云大规模合并部署打下基础,也为未来更长远的 Serverless 能力提供基座。

为了打造对开发者更友好的 Serverless 能力和平台:

1、我们需要增强模块热卸载能力。

2、进一步的模块瘦身,将更多的通用组件下沉到基座中,减少公共类库和框架加载和初始化运行开销。不但节省内存,还能加速子模块的启动速度,如尝试复用基座数据源和基座拦截器。

3、弹性伸缩,目前依赖应用的 CPU、内存等指标对进程进行弹性伸缩,而合并部署后,可以通过预热基座的方式,让模块的扩缩容速度更快。另外由于模块级别资源的监控指标较难获取,也可以考虑 QPS 等其他维度的指标。 

在整个调研、升级改造及实施的过程中,社区同学多次和我们进行线上和线下交流讨论,提供了许多蚂蚁内部和其他外部企业的最佳实践, 给予了我们很多帮助与指导,在共同的努力下最终成功落地 Koupleless!

希望后续社区在模块应用的卸载稳定性上有进一步的优秀表现,为我们的动态发布打下坚实的基础!也欢迎更多同学加入社区,一起参与共建!

Koupleless Star 一下✨:

https://github.com/koupleless/koupleless

  本周推荐阅读  

635ae863ce683b5f70af267d7d63deb5.png

深度案例解读 Koupleless 在南京爱福路的落地实践

1ea4f4e36dc5ad96e9a83818dd9b1abc.png

Koupleless 单进程多应用如何解决兼容问题

9d771756dcc76e93c314cce0515b6595.png

Koupleless 模块化隔离与共享带来的收益与挑战

b47a3b4edf9ccdae6510e7f0b462e262.png

Koupleless 带来拆分插件,帮你提高协作开发效率!

b486df0724dc45a27a391830b1f6eb36.png

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

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

相关文章

MYSQL 拼接函数

目录 1、CONCAT 2、CONCAT_WS 1、CONCAT 解释&#xff1a;用于拼接两个或多个字符串成一个字符串。如果任何一个参数为 NULL&#xff0c;则 CONCAT 函数的结果也会是 NULL。 语法格式&#xff1a;SELECT concat(column_name1,column_name2,...) FROM table_name 中文注释&…

关于Docker

文章目录 DockerWSLWMWare虚拟机CentOS7安装dockerdocker基础命令docker数据卷挂载本地目录或文件 Docker Docker是一个快速构建、运行、管理应用的工具。 能够快速部署项目、项目依赖的组件、项目运行的环境。 项目传统的部署方式缺点&#xff1a; 各类环境、组件命令太多&…

具体应用案例:树莓集团助力传统制造业数字化转型

以一家传统制造业企业为例&#xff0c;在树莓集团的支持下&#xff0c;该企业逐步完成了数字化转型&#xff1a; 1. 生产智能化&#xff1a; 通过树莓集团提供的物联网和智能制造解决方案&#xff0c;企业的生产线实现了全面数字化&#xff0c;实时监控设备状态&#xff0c;进行…

CasADi库C++用法整理学习---以NMPC代码为例

参考几个使用方法博客 1 官方文档写的很清楚 对SM&#xff0c;DM&#xff0c;XM数据类型疑惑。什么时候使用什么样的类型&#xff0c;还是都可以&#xff1f; x MX.sym(“x”) 这将创建一个 11 矩阵&#xff0c;即一个包含名为 x 的符号基元的标量。这只是显示名称&#xff…

关键词提取技术:TF-IDF 详解

1. 什么是TF-IDF&#xff1f; TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xff09; 是一种统计方法&#xff0c;用于评估单词在文档集或语料库中的重要性。它是自然语言处理和信息检索中的核心技术之一。 TF-IDF主要基于以下两个概念&#xff1a; TF&a…

书籍推荐:《从零构建大型语言模型》附免费PDF下载

通过从头开始构建一个大型语言模型&#xff0c;了解如何创建、训练和调整大型语言模型 &#xff08;LLMs&#xff09;&#xff01; 一、构建大型语言模型&#xff08;从头开始&#xff09; 在《构建大型语言模型&#xff08;从头开始&#xff09;》中&#xff0c;你将了解如何…

C++ —— 关于继承(inheritance)

目录 1. 继承的概念及定义 1.1 继承的概念 1.2 继承的定义格式 1.3 继承基类成员访问方式的变化 1.4 类模板的继承 2.基类与派生类的转换 3. 继承中的作用域 3.1 隐藏规则 4. 派⽣类的默认成员函数 4.1 4个常见默认成员函数 4.2 实现⼀个不能被继承的类 5. 继承与友元…

webpack 学习入门

webpack 1. 简介1.1 webpack 是什么1.2 webpack 五个核心概念1.2.1 入口 - Entry1.2.2 出口 - Output1.2.3 Loader1.2.4 插件 - Plugins1.2.6 模式 - Mode 2. webpack 初体验2.1 初始化配置2.1.1. 准备2.1.2. 写代码2.1.3 编译打包应用 3. webpack 开发环境的基本配置3.1 打包样…

HTML(七)表格

https://chatgai.lovepor.cn/ 在HTML中&#xff0c;表格的标准形式如下&#xff1a; <table></table> 使用上面的语言&#xff0c;就已经生成了一个表格&#xff0c;只不过这个表格什么都没有 那么&#xff0c;该如何让表格存在东西呢&#xff1f; 首先&#xf…

springboot 整合spring ai实现 基于知识库的客服问答

rag 需求产生的背景介绍&#xff1a; 在使用大模型时&#xff0c;常遇到的问题之一是模型可能产生幻觉&#xff0c;即生成的内容缺乏准确性。此外&#xff0c;由于大模型不直接访问企业的专有数据&#xff0c;其响应可能会显得泛泛而谈&#xff0c;不够精准或具体&#xff0c;…

基于YOLOv10的农场实时目标检测系统(python+pyside6界面+系统源码+可训练的数据集+也完成的训练模型)

摘要&#xff1a; 基于YOLOv10的农场实时目标检测系统&#xff0c;利用4393张图片&#xff08;3905张训练集&#xff0c;488张验证集&#xff09;进行模型训练&#xff0c;最终开发出一个高效的农场目标检测模型。为了方便用户操作和实时检测&#xff0c;本系统还开发了基于Pyt…

VSCode运行QT界面

VSCode用久了,感觉Qt Creator的写起代码来还是不如VSCode得心应手,虽然目前还是存在一些问题,先把目前实现的状况做个记录,后续有机会再进一步优化。 当前方式 通过QtCreator创建一个CMake项目,然后使用CMake的方式在VSCode中进行编译。 claude给出的建议 左上角的名字会…

SiLM27212 270V 4A/4A 支持高频信号输入 集成自举二极管的高低边门极驱动器

SiLM27212系列选型&#xff1a; SiLM27212LEK-DG SiLM27212EK-DG SiLM27212LCA-DG SiLM27212CA-DG SiLM27212LCB-DG SiLM27212CB-DG SiLM27212系列是一款支持高频信号输入的高低边N沟道MOSFET驱动器&#xff0c;有着优异的性能&#xff0c;广泛应用于各类模…

Linux查看下nginx及使用的配置文件

1、查到nginx进程 ps -aef | grep nginx2、通过进行pid查到nginx路径 pwdx <pid>3、根据路径得到配置文件 path***/nginx -t如下&#xff1a;

MacOS虚拟机安装Windows停滞在“让我们为你连接到网络”,如何解决?

1. 问题描述 MacOS在虚拟机安装win11过程中&#xff0c;停止在“让我们为你连接到网络”步骤&#xff0c;页面没有任何可以点击的按钮&#xff0c;进行下一步操作。 2. 解决方案&#xff08;亲测有效&#xff09; 到达该界面&#xff0c;按下ShiftF10&#xff08;Windows&…

【机器学习】深入浅出讲解贝叶斯分类算法

0. 前言 1.贝叶斯分类器介绍 贝叶斯分类是一类分类算法的总称&#xff0c;这类算法均以贝叶斯定理为基础&#xff0c;故统称为贝叶斯分类。而朴素贝叶斯&#xff08;Naive Bayes&#xff09;分类是贝叶斯分类中最简单&#xff0c;也是常见的一种分类方法。 一些很常见的分类…

整理—计算机网络

目录 网络OSI模型和TCP/IP模型 应用层有哪些协议 HTTP报文有哪些部分 HTTP常用的状态码 Http 502和 504 的区别 HTTP层请求的类型有哪些&#xff1f; GET和POST的使用场景&#xff0c;有哪些区别&#xff1f; HTTP的长连接 HTTP默认的端口是什么&#xff1f; HTTP1.1怎…

哪科竞赛含金量更高?五大学科竞赛含金量排名

2024年五大学科竞赛赛事已经渐渐拉开帷幕&#xff0c;本月底国内不少地区即将举行生物竞赛预赛的赛事。今天我们一起来看看五大学科竞赛哪科竞赛含金量更高。 高中五大学科竞赛&#xff08;数物化生信&#xff09;是升学路上的硬通货&#xff0c;比如说在强基破格中需要五大竞赛…

揭秘提升3DMAX效率的6款必备神级插件!

对于3DMax新手来说,掌握一些高效、实用的插件能够大大提升工作效率和创作质量。以下是6个不能错过的神级插件推荐: 第1个:3DMAX造山地形插件Mountain是一款专为3dMax设计的插件,旨在帮助用户轻松快速地创建逼真的山脉地形。以下是对该插件的详细介绍: 一、插件概述 Mou…

Xilinx远程固件升级(一)——QuickBoot方案

Xilinx 7系FPGA远程更新方案——QuickBoot方式远程更新bit 一、远程更新背景和架构 对于非ZYNQ系列的常规FPGA来说&#xff0c;对于bit的更新一般使用JTAG进行烧录。而作为商用产品&#xff0c;想要进行OTA升级时&#xff0c;使用JTAG的升级方式显然不适合&#xff0c;因此&a…