dubbo优势_Dubbo 迈出云原生重要一步 应用级服务发现解析

ee725736c34c743aa32fdd15407cfe58.png

作者 | 刘军(陆龟)  Apache Dubbo PMC

概述

社区版本 Dubbo 从 2.7.5 版本开始,新引入了一种基于实例(应用)粒度的服务发现机制,这是我们为 Dubbo 适配云原生基础设施的一步重要探索。版本发布到现在已有近半年时间,经过这段时间的探索与总结,我们对这套机制的可行性与稳定性有了更全面、深入的认识;同时在 Dubbo 3.0 的规划也在全面进行中,如何让应用级服务发现成为未来下一代服务框架 Dubbo 3.0 的基础服务模型,解决云原生、规模化微服务集群扩容与可伸缩性问题,也已经成为我们当前工作的重点。

既然这套新机制如此重要,那它到底是怎么工作的呢?今天我们就来详细解读一下。在最开始的社区版本,我们给这个机制取了一个神秘的名字 - 服务自省,下文将进一步解释这个名字的由来,并引用服务自省代指这套应用级服务发现机制。

熟悉 Dubbo 开发者应该都知道,一直以来都是面向 RPC 方法去定义服务的,并且这也是 Dubbo 开发友好性、治理功能强的基础。既然如此,那我们为什么还要定义个应用粒度的服务发现机制呢?这个机制到底是怎么工作的?它与当前机制的区别是什么?它能给我们带来哪些好处那?对适配云原生、性能提升又有哪些帮助?

带着所有的这些问题,我们开始本文的讲解。

服务自省是什么?

首先,我们先来解释文章开篇提到的问题:

  1. 应用粒度服务发现是到底是一种怎样的模型,它与当前的 Dubbo 服务发现模型的区别是什么?

  2. 我们为什么叫它服务自省?

所谓“应用/实例粒度” 或者“RPC 服务粒度”强调的是一种地址发现的数据组织格式。

580f43c7341805b0928c7658fdf7cd1f.png

以 Dubbo 当前的地址发现数据格式为例,它是“RPC 服务粒度”的,它是以 RPC 服务作为 key,以实例列表作为 value 来组织数据的:

"RPC Service1": [
{"name":"instance1", "ip":"127.0.0.1", "metadata":{"timeout":1000}},
{"name":"instance2", "ip":"127.0.0.1", "metadata":{"timeout":2000}},
{"name":"instance3", "ip":"127.0.0.1", "metadata":{"timeout":3000}},
]
"RPC Service2": [Instance list of RPC Service2],
"RPC ServiceN": [Instance list of RPC ServiceN]

而我们新引入的“应用粒度的服务发现”,它以应用名(Application)作为 key,以这个应用部署的一组实例(Instance)列表作为 value。这带来两点不同:

  1. 数据映射关系变了,从 RPC Service -> Instance 变为 Application -> Instance;

  2. 数据变少了,注册中心没有了 RPC Service 及其相关配置信息。

"application1": [
{"name":"instance1", "ip":"127.0.0.1", "metadata":{}},
{"name":"instance2", "ip":"127.0.0.1", "metadata":{}},
{"name":"instanceN", "ip":"127.0.0.1", "metadata":{}}
]

要进一步理解新模型带来的变化,我们看一下应用与 RPC 服务间的关系,显而易见的,1 个应用内可能会定义 n 个 RPC Service。因此 Dubbo 之前的服务发现粒度更细,在注册中心产生的数据条目也会更多(与 RPC 服务成正比),同时也存在一定的数据冗余。

简单理解了应用级服务发现的基本机制,接着解释它为什么会被叫做“服务自省”?

其实这还是得从它的工作原理说起,上面我们提到,应用粒度服务发现的数据模型有几个以下明显变化:数据中心的数据量少了,RPC 服务相关的数据在注册中心没有了,现在只有 application - instance 这两个层级的数据。为了保证这部分缺少的 RPC 服务数据仍然能被 Consumer 端正确的感知,我们在 Consumer 和 Provider 间建立了一条单独的通信通道:Consumer 和 Provider 两两之间通过特定端口交换信息,我们把这种 Provider 自己主动暴露自身信息的行为认为是一种内省机制,因此从这个角度出发,我们把整个机制命名为:服务自省。

为什么需要服务自省?

上面讲服务自省的大概原理的时候也提到了它给注册中心带来的几点不同,这几点不同体现在 Dubbo 框架侧(甚至整个微服务体系中),有以下优势:

  • 与业界主流微服务模型对齐,比如 SpringCloud、Kubernetes Native Service 等;

  • 提升性能与可伸缩性。注册中心数据的重新组织(减少),能最大幅度的减轻注册中心的存储、推送压力,进而减少 Dubbo Consumer 侧的地址计算压力;集群规模也开始变得可预测、可评估(与 RPC 接口数量无关,只与实例部署规模相关)。

1. 对齐主流微服务模型

自动、透明的实例地址发现(负载均衡)是所有微服务框架需要解决的事情,这能让后端的部署结构对上游微服务透明,上游服务只需要从收到的地址列表中选取一个,发起调用就可以了。要实现以上目标,涉及两个关键点的自动同步:

  • 实例地址,服务消费方需要知道地址以建立链接;

  • RPC 方法定义,服务消费方需要知道 RPC 服务的具体定义,不论服务类型是 rest 或 rmi 等。

3e2f98556952c0a7e318b1778d52119e.png

按照文章中的 4 级成熟度定义,Dubbo 当前基于接口粒度的模型可以对应到 L4 级别。

接下来,我们看看 Dubbo、SpringCloud 以及 Kubernetes 分别是怎么围绕自动化的实例地址发现这个目标设计的。

2. Spring Cloud

Spring Cloud 通过注册中心只同步了应用与实例地址,消费方可以基于实例地址与服务提供方建立链接,但是消费方对于如何发起 HTTP 调用(SpringCloud 基于 rest 通信)一无所知,比如对方有哪些 HTTP endpoint,需要传入哪些参数等。

RPC 服务这部分信息目前都是通过线下约定或离线的管理系统来协商的。这种架构的优缺点总结如下:

  • 优势:部署结构清晰、地址推送量小;

  • 缺点:地址订阅需要指定应用名, provider 应用变更(拆分)需消费端感知;RPC 调用无法全自动同步。

78f6358036764cb4e250e74e270f6423.png

3. Dubbo

Dubbo 通过注册中心同时同步了实例地址和 RPC 方法,因此其能实现 RPC 过程的自动同步,面向 RPC 编程、面向 RPC 治理,对后端应用的拆分消费端无感知,其缺点则是地址推送数量变大,和 RPC 方法成正比。

c99f9b74c2657f81a4d187555b787fb1.png

4. Dubbo + Kubernetes

Dubbo 要支持 Kubernetes native service,相比之前自建注册中心的服务发现体系来说,在工作机制上主要有两点变化:

  • 服务注册由平台接管,provider 不再需要关心服务注册;

  • consumer 端服务发现将是 Dubbo 关注的重点,通过对接平台层的 API-Server、DNS 等,Dubbo client 可以通过一个 Service Name(通常对应到 Application Name)查询到一组 Endpoints(一组运行 provider 的 pod),通过将 Endpoints 映射到 Dubbo 内部地址列表,以驱动 Dubbo 内置的负载均衡机制工作。

Kubernetes Service 作为一个抽象概念,怎么映射到 Dubbo 是一个值得讨论的点

Service Name - > Application Name,Dubbo 应用和 Kubernetes 服务一一对应,对于微服务运维和建设环节透明,与开发阶段解耦。

apiVersion: v1
kind: Service
metadata:
name: provider-app-name
spec:
selector:
app: provider-app-name
ports:
- protocol: TCP
port:
targetPort: 9376

Service Name - > Dubbo RPC Service,Kubernetes 要维护调度的服务与应用内建 RPC 服务绑定,维护的服务数量变多。

---
apiVersion: v1
kind: Service
metadata:
name: rpc-service-1
spec:
selector:
app: provider-app-name
ports: ##
...
---
apiVersion: v1
kind: Service
metadata:
name: rpc-service-2
spec:
selector:
app: provider-app-name
ports: ##
...
---
apiVersion: v1
kind: Service
metadata:
name: rpc-service-N
spec:
selector:
app: provider-app-name
ports: ##
...

c0b9986c41f8ebc0a53dc133fa9c96fe.png

结合以上几种不同微服务框架模型的分析,我们可以发现,Dubbo 与 SpringCloud、Kubernetes 等不同产品在微服务的抽象定义上还是存在很大不同的。SpringCloud 和 Kubernetes 在微服务的模型抽象上还是比较接近的,两者基本都只关心实例地址的同步,如果我们去关心其他的一些服务框架产品,会发现它们绝大多数也是这么设计的;

即 REST 成熟度模型中的 L3 级别。

对比起来 Dubbo 则相对是比较特殊的存在,更多的是从 RPC 服务的粒度去设计的。

对应 REST 成熟度模型中的 L4 级别。

如我们上面针对每种模型做了详细的分析,每种模型都有其优势和不足。而我们最初决定 Dubbo 要做出改变,往其他的微服务发现模型上的对齐,是我们最早在确定 Dubbo 的云原生方案时,我们发现要让 Dubbo 去支持 Kubernetes Native Service,模型对齐是一个基础条件;另一点是来自用户侧对 Dubbo 场景化的一些工程实践的需求,得益于 Dubbo 对多注册、多协议能力的支持,使得 Dubbo 联通不同的微服务体系成为可能,而服务发现模型的不一致成为其中的一个障碍。

5. 更大规模的微服务集群 - 解决性能瓶颈

这部分涉及到和注册中心、配置中心的交互,关于不同模型下注册中心数据的变化,之前原理部分我们简单分析过。为更直观的对比服务模型变更带来的推送效率提升,我们来通过一个示例看一下不同模型注册中心的对比:

2473243e70036c7b4dbd6adb4eacaecc.png

图中左边是微服务框架的一个典型工作流程,Provider 和  Consumer 通过注册中心实现自动化的地址通知。其中,Provider 实例的信息如图中表格所示:

应用 DEMO 包含三个接口 DemoService 1 2 3,当前实例的 ip 地址为 10.210.134.30。

  • 对于 Spring Cloud 和 Kubernetes 模型,注册中心只会存储一条 DEMO - 10.210.134.30+metadata 的数据;

  • 对于老的 Dubbo 模型,注册中心存储了三条接口粒度的数据,分别对应三个接口 DemoService 1 2 3,并且很多的址数据都是重复的。

可以总结出,基于应用粒度的模型所存储和推送的数据量是和应用、实例数成正比的,只有当我们的应用数增多或应用的实例数增长时,地址推送压力才会上涨。

而对于基于接口粒度的模型,数据量是和接口数量正相关的,鉴于一个应用通常发布多个接口的现状,这个数量级本身比应用粒度是要乘以倍数的;另外一个关键点在于,接口粒度导致的集群规模评估的不透明,相对于实i例、应用增长都通常是在运维侧的规划之中,接口的定义更多的是业务侧的内部行为,往往可以绕过评估给集群带来压力。

以 Consumer 端服务订阅举例,根据我对社区部分 Dubbo 中大规模头部用户的粗略统计,根据受统计公司的实际场景,一个 Consumer 应用要消费(订阅)的 Provier 应用数量往往要超过 10 个,而具体到其要消费(订阅)的的接口数量则通常要达到 30 个,平均情况下 Consumer 订阅的 3 个接口来自同一个 Provider 应用,如此计算下来,如果以应用粒度为地址通知和选址基本单位,则平均地址推送和计算量将下降 60% 还要多。

而在极端情况下,也就是当 Consumer 端消费的接口更多的来自同一个应用时,这个地址推送与内存消耗的占用将会进一步得到降低,甚至可以超过 80% 以上。

一个典型的几段场景即是 Dubbo 体系中的网关型应用,有些网关应用消费(订阅)达 100+ 应用,而消费(订阅)的服务有 1000+ ,平均有 10 个接口来自同一个应用,如果我们把地址推送和计算的粒度改为应用,则地址推送量从原来的 n  1000 变为 n  100,地址数量降低可达近 90%。

工作原理

1. 设计原则

上面一节我们从服务模型及支撑大规模集群的角度分别给出了 Dubbo 往应用级服务发现靠拢的好处或原因,但这么做的同时接口粒度的服务治理能力还是要继续保留,这是 Dubbo 框架编程模型易用性、服务治理能力优势的基础。

以下是我认为我们做服务模型迁移仍要坚持的设计原则:

  • 新的服务发现模型要实现对原有 Dubbo 消费端开发者的无感知迁移,即 Dubbo 继续面向 RPC 服务编程、面向 RPC 服务治理,做到对用户侧完全无感知;

  • 建立 Consumer 与 Provider 间的自动化 RPC 服务元数据协调机制,解决传统微服务模型无法同步 RPC 级接口配置的缺点。

2. 基本原理详解

应用级服务发现作为一种新的服务发现机制,和以前 Dubbo 基于 RPC 服务粒度的服务发现在核心流程上基本上是一致的:即服务提供者往注册中心注册地址信息,服务消费者从注册中心拉取&订阅地址信息。

这里主要的不同有以下两点:

  • 注册中心数据以“应用 - 实例列表”格式组织,不再包含 RPC 服务信息;

06645261771ee097ca182f6ae7709d80.png

以下是每个 Instance metadata 的示例数据,总的原则是 metadata 只包含当前 instance 节点相关的信息,不涉及 RPC 服务粒度的信息。

总体信息概括如下:实例地址、实例各种环境标、metadata service 元数据、其他少量必要属性。

{
"name": "provider-app-name",
"id": "192.168.0.102:20880",
"address": "192.168.0.102",
"port": 20880,
"sslPort": null,
"payload": {
"id": null,
"name": "provider-app-name",
"metadata": {
"metadataService": "{\"dubbo\":{\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"2.7.5\",\"port\":\"20881\"}}",
"endpoints": "[{\"port\":20880,\"protocol\":\"dubbo\"}]",
"storage-type": "local",
"revision": "6785535733750099598",
}
},
"registrationTimeUTC": 1583461240877,
"serviceType": "DYNAMIC",
"uriSpec": null
}
  • Client – Server 自行协商 RPC 方法信息。

在注册中心不再同步 RPC 服务信息后,服务自省在服务消费端和提供端之间建立了一条内置的 RPC 服务信息协商机制,这也是“服务自省”这个名字的由来。服务端实例会暴露一个预定义的 MetadataService RPC 服务,消费端通过调用 MetadataService 获取每个实例 RPC 方法相关的配置信息。

81d5159c64aa1c06582be86a4f145bad.png

当前 MetadataService 返回的数据格式如下:

[
"dubbo://192.168.0.102:20880/org.apache.dubbo.demo.DemoService?anyhost=true&application=demo-provider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=9585&release=2.7.5&side=provider&timestamp=1583469714314",
"dubbo://192.168.0.102:20880/org.apache.dubbo.demo.HelloService?anyhost=true&application=demo-provider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=9585&release=2.7.5&side=provider&timestamp=1583469714314",
"dubbo://192.168.0.102:20880/org.apache.dubbo.demo.WorldService?anyhost=true&application=demo-provider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=9585&release=2.7.5&side=provider&timestamp=1583469714314"
]

熟悉 Dubbo 基于 RPC 服务粒度的服务发现模型的开发者应该能看出来,

服务自省机制机制将以前注册中心传递的 URL 一拆为二:

  • 一部分和实例相关的数据继续保留在注册中心,如 ip、port、机器标识等;

  • 另一部分和 RPC 方法相关的数据从注册中心移除,转而通过 MetadataService 暴露给消费端。

理想情况下是能达到数据按照实例、RPC 服务严格区分开来,但明显可以看到以上实现版本还存在一些数据冗余,有些也数据还未合理划分。尤其是 MetadataService 部分,其返回的数据还只是简单的 URL 列表组装,这些 URL其实是包含了全量的数据。

以下是服务自省的一个完整工作流程图,详细描述了服务注册、服务发现、MetadataService、RPC 调用间的协作流程。

72b722b4377a6a6a4e8a65d17186aabc.png

  1. 服务提供者启动,首先解析应用定义的“普通服务”并依次注册为 RPC 服务,紧接着注册内建的 MetadataService 服务,最后打开 TCP 监听端口;

  2. 启动完成后,将实例信息注册到注册中心(仅限 ip、port 等实例相关数据),提供者启动完成;

  3. 服务消费者启动,首先依据其要“消费的 provider 应用名”到注册中心查询地址列表,并完成订阅(以实现后续地址变更自动通知);

  4. 消费端拿到地址列表后,紧接着对 MetadataService 发起调用,返回结果中包含了所有应用定义的“普通服务”及其相关配置信息;

  5. 至此,消费者可以接收外部流量,并对提供者发起 Dubbo RPC 调用。

在以上流程中,我们只考虑了一切顺利的情况,但在更详细的设计或编码实现中,我们还需要严格约定一些异常场景下的框架行为。比如,如果消费者 MetadataService 调用失败,则在重试知道成功之前,消费者将不可以接收外部流量。

服务自省中的关键机制

1. 元数据同步机制

Client 与 Server 间在收到地址推送后的配置同步是服务自省的关键环节,目前针对元数据同步有两种具体的可选方案,分别是:内建 MetadataService;独立的元数据中心,通过中细化的元数据集群协调数据。

  • 内建 MetadataService:MetadataService 通过标准的 Dubbo 协议暴露,根据查询条件,会将内存中符合条件的“普通服务”配置返回给消费者。这一步发生在消费端选址和调用前;

  • 元数据中心:复用 2.7 版本中引入的元数据中心,provider 实例启动后,会尝试将内部的 RPC 服务组织成元数据的格式到元数据中心,而 consumer 则在每次收到注册中心推送更新后,主动查询元数据中心。

注意 consumer 端查询元数据中心的时机,是等到注册中心的地址更新通知之后。也就是通过注册中心下发的数据,我们能明确的知道何时某个实例的元数据被更新了,此时才需要去查元数据中心。

8cddea0dfd061da8f236fde782545c3a.png

2. RPC 服务 < - > 应用映射关系

回顾上文讲到的注册中心关于“应用 - 实例列表”结构的数据组织形式,这个变动目前对开发者并不是完全透明的,业务开发侧会感知到查询/订阅地址列表的机制的变化。具体来说,相比以往我们基于 RPC 服务来检索地址,现在 consumer 需要通过指定 provider 应用名才能实现地址查询或订阅。

老的 Consumer 开发与配置示例:





新的 Consumer 开发与配置示例:





以上指定 provider 应用名的方式是 Spring Cloud 当前的做法,需要 consumer 端的开发者显示指定其要消费的 provider 应用。

以上问题的根源在于注册中心不知道任何 RPC 服务相关的信息,因此只能通过应用名来查询。

为了使整个开发流程对老的 Dubbo 用户更透明,同时避免指定 provider 对可扩展性带来的影响(参见下方说明),我们设计了一套 RPC 服务到应用名的映射关系,以尝试在 consumer 自动完成 RPC 服务到 provider 应用名的转换。

8da73c44b3f00fd54896a9ee19c1c77a.png

Dubbo 之所以选择建立一套“接口-应用”的映射关系,主要是考虑到 service - app 映射关系的不确定性。一个典型的场景即是应用/服务拆分,如上面提到的配置 ,PC Service 2 是定义于 provider-app-x 中的一个服务,未来它随时可能会被开发者分拆到另外一个新的应用如 provider-app-x-1 中,这个拆分要被所有的 PC Service 2 消费方感知到,并对应用进行修改升级,如改为 ,这样的升级成本不可否认还是挺高的。
到底是 Dubbo 框架帮助开发者透明的解决这个问题,还是交由开发者自己去解决,当然这只是个策略选择问题,并且 Dubbo 2.7.5+ 版本目前是都提供了的。其实我个人更倾向于交由业务开发者通过组织上的约束来做,这样也可进一步降低 Dubbo 框架的复杂度,提升运行态的稳定性。

总结与展望

应用级服务发现机制是 Dubbo 面向云原生走出的重要一步,它帮 Dubbo 打通了与其他微服务体系之间在地址发现层面的鸿沟,也成为 Dubbo 适配 Kubernetes Native Service 等基础设施的基础。

我们期望 Dubbo 在新模型基础上,能继续保留在编程易用性、服务治理能力等方面强大的优势。但是我们也应该看到应用粒度的模型一方面带来了新的复杂性,需要我们继续去优化与增强;另一方面,除了地址存储与推送之外,应用粒度在帮助 Dubbo 选址层面也有进一步挖掘的潜力。

作者简介

刘军,Github 账号 Chickenlj,Apache Dubbo PMC,项目核心开发,见证了Dubbo从重启开源到Apache毕业的整个流程。现任职阿里云云原生应用平台团队,参与服务框架、微服务相关工作,目前主要在推动 Dubbo 3.0 - Dubbo 云原生。

97618920d3d8400962d86d80b991ca9f.gif1ab9ebe67dad0ebb7f59b14c486ab16d.png 动动小手指 了解更多详情 !d78849819eacd46f9b17cb44541a38f9.gif

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

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

相关文章

看了《隐秘的角落》才知道,掉头发有多可怕!10个掉头发最快的专业!快看看你中枪了没有!...

全世界只有3.14 % 的人关注了爆炸吧知识专业选得好秃头秃得早我爱学习&#xff0c;学习使我快乐我爱学习&#xff0c;学习使我进步我爱学习&#xff0c;学习使我美丽学习&#xff1a;我TM还能使你脱发呢我&#xff1a;港真现在上个大学不掉点头发都枉为一个真正的大学生上课与睡…

WPF企业内训全程实录(中)

摘要 WPF企业内训全程实录由于文章比较长&#xff0c;所以一共拆分成了三篇&#xff0c;上篇WPF企业内训全程实录&#xff08;上&#xff09;主 要讲了基础&#xff0c;这篇作为该实录的中篇&#xff0c;起着承上启下的作用,主要讲解开发模式、团队协作及应用框架。其实如果大家…

.Net Core with 微服务 - 可靠消息最终一致性分布式事务

前面我们讲了分布式事务的2PC、3PCTCC 的原理。这些事务其实都在尽力的模拟数据库的事务&#xff0c;我们可以简单的认为他们是一个同步行的事务。特别是 2PC,3PC 他们完全利用数据库的事务能力&#xff0c;在一阶段开始事务后不进提交会严重影响应用程序的并发性能。TCC 一阶段…

[ JS 进阶 ] Repaint 、Reflow 的基本认识和优化 (2)

你是不是经常听师兄或一些前端前辈说不能用CSS通配符 *&#xff0c;CSS选择器层叠不能超过三层&#xff0c;CSS尽量使用类选择器&#xff0c;书写HTML少使用table&#xff0c;结构要尽量简单-DOM树要小....等这些忠告&#xff0c;以前我就大概知道使用通配符或者CSS选择器层次过…

vgh电压高了有什么_智能变频电源的功能是什么?

所谓的智能变频电源&#xff0c;其主要功能是将我国的城市电源(220V直流)转换为世界上其他国家的设备(110V&#xff0c;60Hz)&#xff0c;可以说&#xff0c;它的功能是一台很好的稳压器和调频设备。智能变频电源的功能是什么&#xff1f;著名的美国北宇实验室研究报告指出&…

PDC Party 即将在东莞登场

各位社区精英们&#xff0c; 我们即将在东莞举办PDC Party的活动&#xff0c;本次活动除了精彩的PDC Keynote Demo视频分享与微软技术趋势的讨论之外&#xff0c;还希望能够借此机会&#xff0c;与各位微软技术社区精英们面对面的交流&#xff0c;共同讨论后续的发展&#xff0…

你们数学老师当年是怎么叫这些符号的…

全世界只有3.14 % 的人关注了爆炸吧知识你们数学老师都是怎么叫这些符号的呢&#xff1f;

自主生态再进一步,龙芯中科完成.NET3.1-LoongArch64平台研发

近日&#xff0c;龙芯中科.NET团队完成了.NET3.1-LoongArch64平台研发工作&#xff0c;研发的成功标志着围绕龙芯自主指令系统LoongArch的生态建设成果再进一步。龙芯自主指令系统LoongArch基于龙芯二十年的CPU研制和生态建设积累&#xff0c;LoongArch从顶层架构&#xff0c;到…

keras 自定义层input_从4个方面介绍Keras和Pytorch,并给你选择其中一个学习库的理由...

全文共3376字&#xff0c;预计学习时长7分钟对许多科学家、工程师和开发人员而言&#xff0c;TensorFlow是他们的第一个深度学习框架。TensorFlow 1.0于2017年2月发布&#xff1b;但客观来说&#xff0c;它对用户不是非常友好。过去几年里&#xff0c;由于Keras和PyTorch比Tens…

KlayGE 4.0中Deferred Rendering的改进(五)完结篇:Post process

转载请注明出处为KlayGE游戏引擎上一篇分析了KlayGE中实现实时全动态GI的方法&#xff0c;本篇是这个系列的完结篇&#xff0c;主要讲流水线的最后一段&#xff1a;Post process。 Post process 在KlayGE 4.0的Deferred Rendering中&#xff0c;post process主要有HDR、AA和col…

Centos 手工创建新用户

当我们要创建一个用户时&#xff0c;通常使用useradd命令就可以自动创建了一个用户&#xff1b;实际上&#xff0c;在linux下&#xff0c;一切皆文件&#xff0c;设置好几个文件&#xff0c;也是可以创建出一个用户&#xff1a;文件如下&#xff1a;/etc/passwd :用户/etc/sha…

为了这个羞羞的项目,我差点成为“鉴黄师”

全世界只有3.14 % 的人关注了爆炸吧知识转自&#xff1a;大数据文摘编译&#xff1a;蒋宝尚、魏子敏给男同学们一个机器学习&#xff0c;他们能研究所有他们能想到的问题。当然&#xff0c;根据这本真实存在的畅销书&#xff0c;他们真的能想到的话题也不多????开个玩笑&am…

【.NET】实现CI/CD(二)运行镜像,自动化部署

&#xff08;一重山&#xff0c;两重山。&#xff09;书接上文&#xff0c;在上回中我们说到了《【Azure Core】实现CI/CD&#xff08;一&#xff09;构建镜像并推送仓库今天我们继续往下说&#xff0c;说下CD&#xff08;持续部署&#xff09;的流程&#xff0c;也是很简单。…

a*算法的时间复杂度_数据结构(1)——算法和时间复杂度

Data Structure1算法和时间复杂度01.什么是数据结构&#xff1f;程序设计 数据结构 算法数据结构是关系&#xff0c;是数据元素相互之间存在的一种或多种特定关系的集合。数据结构和算法凌驾于任何一种编程语言之上。02.逻辑结构和物理结构数据结构分为逻辑结构和物理结构。逻…

学会了!如果认错人了,就像这样亲一口!

1 千万不要用曲面屏炒股▼2 谁掏钱多就听谁的准没错▼3 你和你妈的通话记录▼4 em......陷入沉思▼5 人类1994年拍摄到的冥王星人类2018年拍摄到的冥王星▼6 猫&#xff1a;你滚开&#xff01;劳资不要运动&#xff01;▼7 吃下去长肉了你来找我我给你送实验室研究研究▼…

python循环语句嵌套_Python 循环语句

循环语句 ​循环语句主要是用于解决某些重复的代码工作&#xff0c;使需要重复的代码只写一遍即可。 Python循环语句主要有两种&#xff1a;while循环和for...in...循环。 一、while循环 主要用于不确定循环的次数时&#xff0c;根据条件进行判断&#xff0c;条件成立&#xff…

那些年,冒死拍过的老师逗逼搞笑照片 !

全世界只有3.14 % 的人关注了爆炸吧知识「你曾经拍到过老师哪个搞笑的瞬间」哈哈哈哈哈哈啊哈哈哈哈已笑疯了拍照的人最后真的都没有被打死吗_石小麦&#xff1a;这张&#xff1f;wanngsh-&#xff1a;当历史老师谈及日本女人2HyFMm&#xff1a;班主任扔实心球曹梓建&#xff1…

记一次 .NET 某上市工业智造 CPU+内存+挂死 三高分析

一&#xff1a;背景 1. 讲故事上个月有位朋友加wx告知他的程序有挂死现象&#xff0c;询问如何进一步分析&#xff0c;截图如下&#xff1a;看这位朋友还是有一定的分析基础&#xff0c;可能玩的少&#xff0c;缺乏一定的分析经验&#xff0c;当我简单分析之后&#xff0c;我发…

60佳优秀的 Photoshop 网页制作教程【下篇】

Photoshop 作为网页设计利器&#xff0c;是网页设计师必备。曾经和大分享过几篇优秀的 Photoshop 网页制作教程&#xff0c;喜欢的人非常多。今天这篇文章继续向大家分享优秀的 Photoshop 网页制作教程。其实&#xff0c;网页设计并没有你想的那么难&#xff0c;相信看完这些教…

android studio 创建.9文件,自己使用Android studio创建.9(点9)图片

本来标题想写"Mac版Android studio创建.9图片"&#xff0c;但是感觉区别应该不大&#xff0c;因为只需要拖拽一下鼠标就行了&#xff0c;键盘以及快捷键都不用不上。这篇文章其实也是自己看了其他文章后的一点补充&#xff0c;并不是所有人都会有的问题。既然是想标为…