grpc命名规范,grpc详解

http://www.itjxue.com  2023-01-06 06:29  来源:未知  点击次数: 

Uber实时推送平台是如何打造的

原文:Uber’s Real-Time Push Platform

译者:LZM

Uber 建立的出行平台每天在处理全球数以百万计的打车订单。

实时打车市场是一个十分活跃的市场。一次行程包括多个参与者(乘客、司机),他们需要能在 APP 上实时查看、修改当前旅程的状态。因此,Uber 需要保证每个参与者和他们的 APP 实时同步相关信息,无论是接车时间、达到时间还是行驶路线和附近的司机。

今天,手机端呈现的功能日益丰富,而这些功能对实时信息同步的需求也逐渐增多。本文将介绍 Uber 工程团队如何把 Uber 平台信息同步机制从轮询转为基于 gRPC 的双向消息流协议。

在 Uber 后台,一个行程连接了现实世界中的乘客和司机。在行程过程中,这两个实体需要实时更新后台系统的信息。

我们思考一个场景:乘客发出打车请求,而司机在系统上等待接单。Uber 配对系统在后台自动匹配二者,向司机发送订单。到此为止,每一方(乘客、司机、后台)应该彼此同步他们的内容。

如果一个新订单带来,司机 APP 会每隔几秒轮询一次信息以及时更新订单状态。与此同时,乘客 APP 也会每隔几秒轮询一个信息来查看司机时候接单。

轮询的频率由数据改变的速率决定。对于一个大型 APP(例如 Uber APP),这个变化速率从几秒到几个小时不等,变化范围十分宽泛。

80% 的后台 API 请求都是来自客户端的轮询请求。激进的轮询策略能让 APP 的消息保持最新,但也会导致服务器资源耗尽。任何轮询过程中的 bug 都可能频繁导致后台负载显著加剧,甚至崩溃。随着需要动态实时数据的功能的增加,这个方法变得不再可行。

轮询会导致更快的电池消耗、应用程序延迟和网络级拥塞。这在城市中使用 2G/3G 网络或网络不稳定的地方尤其明显。在这些地方,应用程序每次尝试拉取信息时,都会重试多次。

随着功能增加,开发者们尝试重载轮询 API 或重建一个新的 API。在高峰期,APP 同时向多个 API 发送轮询请求。每个 API 负载数个功能。这些轮询 API 本质上成为一组分片负载 API。但是,在 API 级别上保持一致性和逻辑分离仍然是一个越来越大的挑战。

冷启动问题是其中最具挑战性的问题之一。每当 APP 启动,所有功能都希望从后台获取最新状态,以渲染用户界面。这导致多个 API 并发竞争,APP 不能成功渲染出正常界面,直到关键组件的消息被返回。在没有优先级的情况下,因为所有的 API 都有一些关键信息,所以应用加载时间会持续增加。糟糕的网络条件会进一步恶化冷启动问题。

很明显,我们需要一个彻头彻尾的、对消息同步机制的改变。我们开启了建立一个全新的实时推送平台的旅程。在这个平台上,服务器可以根据需要向应用程序发送数据。当我们采用这种新架构时,我们发现效率有显著的改进,同时也解决了不同的问题和挑战。

接下来,来看看我们对推送平台的几代改进以及该平台是如何演变的。

虽然使用消息推送是取代轮询的自然选择,但在如何构建推送机制上有很多需要考虑的问题。四个主要设计原则如下:

1)从轮询到推送的简单迁移

目前存在大量端设备在进行轮询。新系统必须利用现有的、分配给轮询 API 的负载和逻辑,而不是完全推倒重来。

2)简易开发

与开发轮询 API 相比,开发人员在推送数据方面不应该做截然不同的事情。

3)可靠性

所有消息应该通过网络可靠地发送到客户的 APP 上,并在发送失败时重试。

4)高效率

随着 Uber 在发展中国家的迅速发展,数据使用成本对我们的用户来说是一个挑战,对于每天要在 Uber 平台上呆上几个小时的司机来说尤其如此。新协议必须最小化服务器和移动应用程序之间的数据传输量。

我们将这个消息推送系统命名为 RAMEN (Realtime Asynchronous MEssaging Network,实时异步消息网络)。

任何时候,实时信息都在变化。消息的生命周期开始于决定生成一条信息的那一刻。微服务 Fireball 用于决定何时推送消息。很大部分决策都由配置文件决定。Fireball 在系统间监听多种类型的事件,并决定是否推送给该消息涉及的客户。

例如,当一个司机加单,司机和行程的状态都会改变,并触发 Fireball。之后,根据配置文件的内容,Fireball 决定何类消息应该推送给客户。通常,一个触发器会向多个用户发送多个消息。

任何事件都可能被触发器捕获,例如一些客户行为(如发出打车请求、打开 APP)、定时器到期、消息总线上的后端业务事件或是地理上的驶出 / 驶入事件。所有这些触发器都被过滤并转换为对各种后台 API 的调用。这些 API 需要客户的上下文信息,如设备定位、设备的操作系统以及 APP 的版本号,来生成一个响应。Fireball 获取设备上下文 RAMEN 服务器,并在调用 API 时将它们添加到头部。

所有来自 Uber APP 的服务器调用都由我们的 API 网关提供。推送有效负载以同样的方式生成。一旦 Fireball 决定了推送消息的对象和时间,API 网关就负责决定推送什么。网关会调用各类域服务来生成正确的推送负载。

网关中的所有 API 在如何生成有效负载方面是相似的。这些 API 分为拉取式和推送式两种。。拉取式 API 由移动设备调用来执行任何 HTTP 操作。推送 API 由 Fireball 调用,它有一个额外的 “推送” 中间件,可以拦截拉取式 API 的响应,并将其转发给推送消息系统。

将 API 网关介乎于二者之间有以下好处:

l? 拉式和推式 API 共享端设备上的大部分业务逻辑。一个给定的负载可以从拉式 API 无缝切换到推式 API。例如,无论你的 APP 是通过拉式 API 调用拉出一个客户对象,还是 Fireball 通过推式 API 调用发送一个客户对象,他们都使用相同的逻辑。

l? 网关负责处理大量业务逻辑,如推送消息的速率、路由和消息验证。

在适当的时候,Fireball 和网关一起生成发送给客户的推送消息。负责将这些信息传递到移动设备的是 “推送消息传递系统”。

每条消息推送会根据不同的配置执行,这些配置项包括:

1)优先级

由于为不同的用例生成了数百个不同的消息负载,因此需要对发送到 APP 的内容进行优先排序。我们将在下一节中看到,我们采用的协议限制在单个连接上发送多个并发负载。此外,接收设备的带宽是有限的。为了给人一种相对优先级的感觉,我们将信息大致分为三个不同的优先级:

l? 高优先级:核心功能数据

l? 中优先级:其他有助于提升客户体验的功能数据

l? 低优先级:需要发送的数据规模大且使用频率不高

优先级配置用于管理平台的多种行为。例如,连接建立后,消息按照优先级降序排列在套接字(socket)中。在 RPC 失败的情况下,通过服务器端重试,高优先级消息变得更加可靠,并且支持跨区域复制。

2)存活时间

推送消息是为了改善实时体验。因此,每个消息都有一个预先定义的生存时间,从几秒到半个小时不等。消息传递系统将消息持久化并在发生错误时重试传递消息,直到有效值过期为止。

3)去重复

当通过触发器机制或重传机制多次生成相同的消息时,此配置项确定是否应该删除重复的消息推送。对于我们的大多数用例,发送给定类型的最新推送消息足以满足用户体验,这允许我们降低总体数据传输速率。

消息推送系统的最后一个组件是实际的有效负载交付服务。该服务维持着与世界各地数百万 APP 程序的活跃连接,并在它们到达时将有效信息同步。世界各地的移动网络提供了不同级别的可靠性,因此传输系统需要足够鲁棒以适应故障。我们的系统保证 “至少一次” 交货。

为了保证可靠传输,我们必须基于 TCP 协议,建立从应用程序到数据中心的持久连接。对于 2015 年的一个应用协议,我们的选择是使用带有长轮询、网络套接字或最终服务器发送事件 (SSE) 的 HTTP/1.1。

基于各种考虑,如安全性、移动 SDK 的支持和数据大小的影响,我们决定使用 SSE。Uber 已经支持了 HTTP + JSON API 栈,它的简单性和可操作性使它成为我们当时的选择。

然而,SSE 是一种单向协议,即数据只能从服务器发送到应用程序。为了提供之前提到的 “至少一次” 的保障,需要确认和重传机制以构建到应用程序协议之上的交付协议中。在 SSE 的基础上,我们定义了一个非常优雅和简单的协议方案。

客户端开始接收第一个 HTTP 请求的消息 /ramen/receive?seq=0,在任何新会话开始时序列号为 0。服务器以 HTTP 200 和 “Content-Type: text/event-stream” 响应客户端以维护 SSE 连接。接下来,服务器将按照优先级降序发送所有挂起的消息并依次递增序列号。由于底层传输协议是 TCP 协议,如果没有交付带有 seq#3 的消息,那么该连接应该已断开、超时或失败。

客户端期望在下一个看到的带有最大序列号重新连接 (在本例中 seq=2)。这就告诉了服务器,即使编号 3 写到了套接字上,它也没有被正常传递。然后服务器将重新发送相同的消息或以 seq=3 开始的任何更高优先级的消息。该协议构建了流连接所需的可恢复性,服务器负责大部分的存储工作,在客户端实现起来非常简单。

为了获知链接是否存活,服务器每 4 秒会发送一个心跳包,这类数据包大小只有一个比特。如果超过 7 秒没有收到来自服务器的消息或心跳,客户端会认定服务终端并重新发起链接。

在上面的协议中,每当客户端重新以一个更高的序列号发起连接时,它就充当服务器刷新旧消息的确认机制。在一个环境良好的网络中,用户可能会保持连接数分钟,从而导致服务器不断积累旧消息。为了缓解这个问题,应用程序会每 30 秒一次调用 /ramen/ack?seq=N,不管连接质量如何。协议的简单性允许用许多不同的语言和平台非常快速地编写客户端。

在设备上下文存储上,RAMEN 服务器在每次建立连接时存储设备上下文,并将此上下文暴露给 Fireball。每个设备上下文的 id 是用户及其设备参数对应的唯一哈希值。这允许隔离推送消息,即使用户在不同的设置下同时使用多个设备或应用程序。

第一代 RAMEN 服务器使用 Node.js 编写,并使用 Uber 内部的一致性哈西 / 分片框架 Ringpop。Ringpop 是一个去中心化的分片系统。所有连接都使用用户的 UUID 进行分片,并使用 Redis 作为持久性数据存储。

在接下来的一年半时间里,消息推送平台在整个公司得到了广泛的应用。高峰期时,RAMEN 系统通过维持高达 60 万个并发数据流连接,每秒向三种不同类型的应用程序推送超过 70000 个 QPS 消息。该系统很快成为服务器 - 客户端 API 基础结构中最重要的部分。

随着通信量和持久连接的快速增加,我们的技术选择也需要扩展。基于 Ringpop 的分布式分片是一个非常简单的架构,不会随着 ring 中的节点数量的增加而动态扩展。Ringpop 库使用一种 gossip 协议来评估成员资格。gossip 协议的收敛时间也随着环的大小增加而增加。

此外,Node.js 是单线程的,并且会有更高级别的事件循环延迟,从而进一步延迟成员信息的收敛。这些问题可能引发拓扑信息不一致,进而导致消息丢失、超时和错误。

2017 年初,我们决定重新启动 RAMEN 协议的服务器实现,以继续扩大应用规模。在这次迭代中,我们使用了以下技术:Netty、Apache Zookeeper、Apache Helix、Redis 和 Apache Cassandra。

1)Netty: Netty 是一个用于构建网络服务器和客户端的高性能库。Netty 的 bytebuf 允许零拷贝缓冲区,这使得系统非常高效。

2)Apache ZooKeeper: Apache ZooKeeper 对网络连接进行一致性哈希,可以直接传输数据,不需要任何存储层。但是与分散的拓扑管理不同,我们选择了 ZooKeeper 的集中共享。ZooKeeper 是一个非常强大的分布式同步和配置管理系统,可以快速检测连接节点的故障。

3)Apache Helix: Helix 是一个健壮的集群管理框架,运行在 ZooKeeper 之上,允许定义自定义拓扑和重新平衡算法。它还很好地从核心业务逻辑中抽象出拓扑逻辑。它使用 ZooKeeper 来监控已连接的工作者,并传播分片状态信息的变化。它还允许我们编写一个自定义的 Leader-Follower 拓扑和自定义的渐进再平衡算法。

4)Redis 和 Apache Cassandra: 当我们为多区域云架构做准备时,有必要对消息进行正确的复制和存储。Cassandra 是一个持久的跨区域复制存储。Redis 被用作 Cassandra 之上的容量缓存,以避免分片系统在部署或故障转移事件中常见的群发问题。

5)Streamgate: 这个服务在 Netty 上实现了 RAMEN 协议,并拥有所有与处理连接、消息和存储相关的逻辑。该服务还实现了一个 Apache Helix 参与者来建立与 ZooKeeper 的连接并维护心跳。

6)StreamgateFE (Streamgate Front End): 该服务充当 Apache Helix 的旁观者,从 ZooKeeper 上侦听拓扑变化。它实现了反向代理。来自客户机 (火球、网关或移动应用程序) 的每个请求都使用拓扑信息进行分片,并路由到正确的 Streamgate 工作程序。

7)Helix Controllers: 顾名思义,这是一个 5 节点的独立服务,单独负责运行 Apache Helix Controller 进程,是拓扑管理的大脑。无论何时任何 Streamgate 节点启动或停止,它都会检测到更改并重新分配分片分区。

在过去的几年中,我们一直在使用这种架构,并且实现了 99.99% 的服务器端可靠性。我们推动基础设施的使用持续增长,支持 iOS、Android 和 Web 平台上的十多种不同类型的应用程序。我们已经使用超过 1.5M 的并发连接来操作这个系统,并且每秒推送超过 250,000 条消息。

服务器端基础设施一直保持稳定运行。随着我们为更多新城市提供各种各样的网络服务和应用程序,我们的重点将是继续提高向移动设备消息推送机制的长尾可靠性。我们一直在试验新协议、开发新方法,以弥合和现实需求的差距。在检查以往的不足时,我们发现以下方面是导致可靠性下降的原因。

1)缺乏认证

RAMEN 协议在减少数据传输进行了优化,仅在每 30 秒或客户端重新连接时才发送确认消息。这将导致延迟确认,在某些情况下无法确认消息达到,因此很难区分是真正的消息丢失还是确认失败。

2)连接不稳定

维持客户端和服务器的正常连接至关重要。跨不同平台的客户端实现方式在处理错误、超时、后退或应用生命周期事件 (打开或关闭)、网络状态更改、主机名和数据中心故障转移等方面有许多细微差别。这导致了不同版本间的性能差异。

3)传输限制

由于该协议在 SSE 协议基础上实现,因此数据传输是单向的。但是,许多新的应用程序要求我们启用双向消息传输机制。没有实时的往返行程时间测量,确定网络状况、传输速度、缓解线路阻塞都是不可能的。SSE 也是一个基于文本的协议,它限制了我们传输二进制有效负载的能力,不需要使用像 base64 这样的文本编码,从而获得更大的有效负载。

2019 年底,我们开始开发下一代 RAMEN 协议以解决上述缺点。经过大量考量,我们选择在 gRPC 的基础上进行构建。gRPC 是一个被广泛采用的 RPC 栈,具有跨多种语言的客户端和服务器的标准化实现,对许多不同的 RPC 方法提供了一流的支持,并具有与 QUIC 传输层协议的互操作性。

新的、基于 gRPC 的 RAMEN 协议扩展了以前基于 SSE 的协议,有几个关键的区别:

l? 确认消息立即通过反向流发送,提高了确认的可靠性,而数据传输量几乎没有增加。

l? 实时确认机制允许我们测量 RTT,了解实时的网络状况。我们可以区分真正的消息损失和网络损失。

l? 在协议之上提供了抽象层,以支持流多路传输等功能。它还允许我们试验应用级网络优先级和流控制算法,从而在数据使用和通信延迟方面带来更高的效率。

l? 协议对消息有效负载进行抽象,以支持不同类型的序列化。将来,我们会探索其他序列化方法,但要将 gRPC 保留在传输层。

l? 不同语言的客户端实现也让我们能够快速支持不同类型的应用程序和设备。

目前,这项开发工作处于 beta 版阶段,很快就能上线。

消息推送平台是 Uber 出行体验的组成部分之一。今天有数百种功能建立在该平台的基础服务之上。我们总结了消息推送平台在 Uber 出行生态中取得巨大成功的几个关键原因。

1)职能分离

消息触发、创建和传递系统之间明确的职责分离允许我们在业务需求发生变化时将注意力转移到平台的不同部分。通过将交付组件分离到 Apache Helix 中,数据流的拓扑逻辑和核心业务逻辑被很好的区分开,这允许在完全相同的架构上使用不同的有线协议支持 gRPC。

2)行业标准技术

构建在行业标准技术之上使我们的实现更加鲁棒且低成本。上述系统的维护开销非常小。我们能够以一个非常高效的团队规模来传递平台的价值。根据我们的经验,Helix 和 Zookeeper 非常稳定。

我们可以在不同的网络条件下扩展到数百万用户的规模,支持数百个功能和几十个应用程序。该协议的简单性使其易于扩展和快速迭代。

原文:

Go - Micro微服务框架实践 - API(十三)

Micro的api就是api网关

API参考了 API网关模式 为服务提供了一个单一的公共入口。基于服务发现,使得micro api可以提供具备http及动态路由的服务。

Micro的API基于HTTP协议。请求的API接口通过HTTP协议访问,并且路由是基于服务发现机制向下转发的。 Micro API在 go-micro 之上开发,所以它集成了服务发现、负载均衡、编码及基于RPC的通信。

因为micro api内部使用了go-micro,所以它自身也是可插拔的。 参考 go-plugins 了解对gRPC、kubernetes、etcd、nats、及rabbitmq等支持。另外,api也使用了 go-api ,这样,接口handler也是可以配置的。

ACME( Automatic Certificate Management Environment)是由 Let’s Encrypt 制定的安全协议。

可以选择是否配置白名单

API服务支持TLS证书

API使用带分隔符的命名空间来在逻辑上区分后台服务及公开的服务。命名空间及http请求路径会用于解析服务名与方法,比如 GET /foo HTTP/1.1 会被路由到 go.micro.api.foo 服务上。

API默认的命名空间是 go.micro.api ,当然,也可以修改:

我们演示一个3层的服务架构:

完整示例可以参考: examples/greeter

先决条件:我们使用Consul作为默认的服务发现,所以请先确定它已经安装好了,并且已经运行,比如执行 consul agent -dev 这样子方式运行。

向micro api发起http请求

HTTP请求的路径 /greeter/say/hello 会被路由到服务 go.micro.api.greeter 的方法 Say.Hello 上。

绕开api服务并且直接通过rpc调用:

使用JSON的方式执行同一请求:

micro api提供下面类型的http api接口

请看下面的例子

Handler负责持有并管理HTTP请求路由。

默认的handler使用从注册中心获取的端口元数据来决定指向服务的路由,如果路由不匹配,就会回退到使用”rpc” hander。在注册时,可以通过 go-api 来配置路由。

API有如下方法可以配置请求handler:

通过 /rpc 入口可以绕开handler处理器。

API处理器接收任何的HTTP请求,并且向前转发指定格式的RPC请求。

RPC处理器接收json或protobuf格式的HTTP POST请求,然后向前转成RPC请求。

代理Handler其实是内置在服务发现中的反向代理服务。

事件处理器使用go-micro的broker代理接收http请求并把请求作为消息传到消息总线上。

Web处理器是,它是内置在服务发现中的HTTP反向代理服务,支持web socket。

/rpc 端点允许绕过主handler,然后与任何服务直接会话。

示例:

更多信息查看可运行的示例: github.com/micro/examples/api

解析器,Micro使用命名空间与HTTP请求路径来动态路由到具体的服务。

API命名的空间是 go.micro.api 。可以通过指令 --namespace 或者环境变量 MICRO_NAMESPACE= 设置命名空间。

下面说一下解析器是如何使用的:

RPC解析器示例中的RPC服务有名称与方法,分别是 go.micro.api.greeter , Greeter.Hello 。

URL会被解析成以下几部分:

带版本号的API URL也可以很容易定位到具体的服务:

代理解析器只处理服务名,所以处理方案和RPC解析器有点不太一样。

URL会被解析成以下几部分:

python后端开发需要学什么?

可以参考下面的路径去学习,祝你学有所成,公司最近在人工智能和自然语言处理的项目后端项目,我也是网上找了很多知识,最后给自己列了一个学习的目录,按照这个在复习并在总结,希望能帮到你:

计算机基本认知,环境搭建 ? ?python环境搭建

计算机基本认识,进制转换

python注释使用

python变量使用

python数据类型_Number

python数据类型 ? ?str字符串类型

容器类型数据list,tuple,str

容器类型数据set,dict

变量缓存机制

自动类型转换

Number强制类型转换 ?

python运算符的使用 ? ?容器类型数据强制类型转换

字典强转等长二级容器

运算符_算数_比较

运算符_赋值_成员

运算符_身份_逻辑

运算符_位运算_优先级 ?

python流程控制 ? ?代码块

流程控制if

多项巢状分支

循环结构while

循环判断经典题

字符串的相关操作 ?

python循环结构? ??

关键字continue_break_pass

for循环的遍历_range ?

字符串,列表内置方法? ??

字符串函数

format字符串格式化

format特殊符号的使用

列表的操作

列表函数 ?

字典,集合内置方法+文件操作? ??

字典的相关函数

集合操作_函数

文件操作

文件加号模式 ?

函数,函数参数 ? ?文件相关函数?

函数

形参实参

默认形参_关键字形参

收集参数

命名关键字参数

全局/局部变量,闭包 ? ?return返回值

函数名的使用

局部变量_全局变量

函数的嵌套LEGB

关键字nonlocal

闭包函数 ?

递归,匿名函数? ??

locals和globals

闭包特点意义

递归含义

斐波那契_尾递归

匿名函数lambda ?

迭代器,高阶函数 ? ?迭代器

高阶函数_map

高阶函数_reduce

高阶函数_sorted

高阶函数_filter ?

推导式 ? ?列表推导式

推导式题

集合_字典推导式

生成器表达式

生成器函数 ?

内置方法,linux基本命令 ? ?内置函数

可滑动序列

面试题演练

linux安装

linux基本命令 ?

python模块 ? ?序列化模块

数学模块

随机模块

time模块 ?

python模块 ? ?os模块

os_shutil

os.path模块

计算文件夹大小

zipfile

tarfile ?

导入模块包,oop面向对象认知? ??

import_from绝对导入

import_from相对导入(单入口)

oop面向对象

类的封装性

oop之封装,继承 ? ?类的相关操作

对象和类的删除操作

单继承

多继承

菱形继承

oop之多态,魔术方法 ? ?多态

魔术方法__new__

单态模式

析构方法__del__ ?

oop之魔术方法,异常处理 ? ?魔术方法__call__

魔术方法__str__repr__

魔术方法__bool_add_len__

了解异常

异常处理语法

主动抛出异常

装饰器 ?

装饰器

静态绑定方法

property?

正则表达式 ? ?单个字符匹配

多个字符匹配

匹配分组

命名分组

正则函数

正则计算器小程序

认识网络 ? ?bs_cs流程

传输数据流程

交换机和局域网的网络通讯

arp协议 ?

认识tcp/udp协议 ?

tcp基本语法

tcp循环发消息

udp基本语法

udp循环发消息

黏包 ?

基于tcp协议下的应用 ? ?socketserver并发

文件校验

服务器合法性校验

tcp登录

并发编程之进程 ? ?进程

join

守护进程

lock锁

Semaphore

生产者消费者模型 ? ?Event事件

进程队列Queue

生产者和消费者模型

JoinableQueue

Manager.py

并发编程之线程

.线程

用类定义线程

守护线程

lock保证线程数据安全

信号量_Semaphore

死锁,互斥锁,递归锁

线程池,进程池,协成的使用

事件Event

线程队列

进程池和线程池

回调函数

协程

协程的爬虫案例

mysql安装(linux+windows+xshell+navicat) ?

掌握数据库mysql基本操作

mysql登录,服务启动

创建账户,用户授权

数据库,数据表,数据的增删改查

认识常用数据类型 ?

数据库的存储引擎和约束 ?

字段约束

约束的删减

存储引擎区别用法

数据表之间的关系 ?

查询数据表 ?

单表查询

多表联查

子查询

带EXISTS关键字的子查询

python操作mysql ?

python连接mysql的事务处理

sql注入

python连接mysql增删改查

mysql数据恢复 ?

HTML/CSS? ? html文档介绍,html标签,body标签,head标签介绍,head标签中的meta标签和link标签和title标签介绍,body中的标签分类,基础标签,img、a、列表、表格、input、label、select等标签,作业讲解,form标签介绍和示例讲解,css介绍,引入,css选择器,背景设置,高度宽度,字体效果,边框、盒子模型、display属性、float属性等 ?

CSS ? ?伪类选择器,文字装饰、a标签补充、定位、权重、小米商城导航栏讲解,原型头像示例讲解 ?

JS基础/BOM和DOM操作 ? ?小米商城作业,js介绍和js引入,js数据类型、流程控制、函数等操作,js中的JSON,BOM对象的弹框、location对象、定时器、直接查找选择器、间接查找选择器、值操作、类值操作、样式操作、button按钮补充、事件和绑定事件的两种方式,常用事件练习 ?

jQuery/Bootstrap ? ?作业讲解,jquery介绍,引入、选择器、筛选器、值操作、文档操作、删除和清空标签、逻辑运算符、克隆、事件冒泡和事件委托、绑定事件的方式,作业讲解和模态对话框示例,input事件和页面载入事件补充、bootstrap介绍和引入、全局css样式、组件和常用插件

自定义web框架 ? ?作业讲解、web框架介绍、自定义web框架实现、动态页面、返回不同的html页面、函数版、多线程版、返回静态文件版,wsgiref版等web框架通过socket来实现,还有jinja2的简单使用 ?

django下载安装和URL路由系统 ? ?django介绍、MTV和MVC框架介绍、常用指令、目录结构、pycharm创建django项目、request的常用属性介绍、登录示例、url路由系统介绍、有名分组和无名分组, ?

视图/模板 ? ?request对象的常用方法和属性、响应方法介绍和使用,CBV和FBV、CBV和FBV加装饰器,CBV源码讲解,模板渲染系统介绍,语法、简单示例、内置过滤器、for循环标签、if标签、with标签、自定义过滤器和标签、模板继承等 ?

Dajngo的ORM(1) ? ?orm介绍,数据库同步指令使用和流程分析、配置连接mysql模型类中的属性介绍和常用参数说明,创建表和数据、增加的两种方法、删除、更新的两种方法、查询的13个api接口 ?

Dajngo的ORM(2) ? ?单表图书管理系统展示和添加作业讲解、choices属性、auto_now_add和auto_now参数讲解、url别名和反向解析,基于双下划线的模糊查询,多表结构介绍,图书管理系统编辑和删除作业讲解、多表关系模型类创建和字段说明和参数介绍、多表数据的添加操作,多表的删除和修改、基于对象的跨表查询、双下划线跨表查询、查看原生sql语句的方法、聚合查询、分组查询、F查询、Q查询等 ?

Ajax与Django/ 中间件 ? ?ajax的介绍和简单示例,ajax登录示例、列表数据展示示例,ajax操作cookie的补充、中间件介绍、自定义中间件的方法、5个中间件方法的介绍和使用、基于中间件的session登录认证?

cookie、session以及用户认证组件 ? ?cookie介绍,cookie的流程解析,django操作cookie和其他参数介绍、session的说明、django的session操作等,多表图书管理系统作业讲解 ?

vue初识、es6基本语法、指令系统 ? ?let、const、v-if、v-for、v-html、v-text、v-model、v-show、生命周期钩子函数、 ?

组件化开发、组件传值、axios简单使用 ? ?组件化开发、组件传值、axios简单使用、vue-router使用、vue-cli安装 ?

项目初始化/首页 ? ?项目介绍、创建、初始化、element-ui的使用,单文件组件的使用和axios在单文件中的使用和配置、vue-cli的介绍和使用、路飞项目顶部导航栏页面效果搭建,轮播图组件的使用和调整、购物车页面搭建和课程详情页面搭建,vue-video-player视频播放插件 ?

drf组件 ? ?序列化器、drf简单示例、restful规范、反序列化的校验机制 ?

drf组件 ? ?apiview、request和response对象、modelserializer、序列化器保存数据、read_only和write_only的参数 ?

drf组件 ? ?viewset、drf路由功能、viewset视图基类的使用、视图子类、通用视图类genericapiview/排序、django-filter过滤器、频率组件、分页组件、接口文档、异常处理、xadmin的安装和使用、认证组件和权限组件 ?

git、消息队列 ? ?git企业中的使用模式,rabbimq消息队列的应用 ?

rpc通信,grpc组件 ? ?rpc的概念以及通信模式,最火的grpc组件使用?

轻量级Flask框架 ? ?Werkzeug服务介绍、Flask框架介绍 ?

路由系统、自定义路由扩展 ?

Cookie、Session、Http请求和响应 ?

蓝图、消息闪现、中间件 ?

Flask常用扩展、WTForms、使用SQLAchemy ORM ?

Admin、Restful、websocket原理、magic string, payload len,masking key? ?

请求和上下文、多app应用、离线脚本、自定义扩展?

服务端项目搭建,项目配置(session、数据库、日志相关),项目初始化 ?

jsonrpc模块基本配置和使用,客户端展示首页及登录注册叶绵,APICloud页面控制管理

python进阶 ? ?并发、同步、异步、锁,线进程概念以及协程实现原理 ?

mysql进阶课 ? ?基础知识梳理、索引、执行计划 ?

mysql进阶课 ? ?存储引擎、日志管理、备份恢复、主从赋值、优化 ?

redis,mongodb ? ?事务和发布订阅、RDB和AOF持久化、缓存击穿、缓存雪崩等原理介绍、 用户管理和复制集(RS)总结、sharding cluster 分片集群的搭建、分片使用和相关策略等 ?

算法与设计模式 ? ?链表、二叉树、常见算法、二分查找、插入排序、希尔排序、快排、堆排序、哈希查找 ?

算法与设计模式 ? ?设计模式,单例模式、工厂模式、策略模式、观察者模式 ?

算法与设计模式 ? ?leetcode经典算法解析 ?

知识体系差不多就这么多了,再就是项目部分,具体项目要看需求了,学会了钓鱼的方法,不怕钓不到鱼哦,无论在哪个行业做什么样的项目都没问题呢!

我自己也搜集了一些经典的资料,要是想要加我百度网盘:艾美电商,我发给你!

从Docker到Kubernetes

2013 年,随着PaaS发展壮大,这个领域的从业者们发现了 PaaS 中最为棘手也最亟待解决的一个问题:究竟如何给应用打包?无论是 Cloud Foundry、OpenShift,还是 Clodify,面对这个问题都没能给出一个完美的答案。一个并不引人瞩目的 PaaS 创业公司 dotCloud,却选择了开源自家的一个容器项目 Docker,正好提供了一种非常便利的打包机制,然后就一发不可收拾,围绕着 Docker 项目进行集成与创新涌现出来,包括Mesosphere公司的Mesos项目等等,Docker 公司也顺势推出了Docker Compose、Swarm 和 Machine“三件套”,docker生态圈很快发展起来了,开启了一个新的容器时代。

2014年6月,谷歌公司正式宣告了Kubernetes项目的诞生。这个时候容器出现多样化,包括google公司lmctfy容器,coreos的rkt容器。Google公司提出和Docker合作,与Docker公司共同推进一个中立的容器运行时库作为Docker项目的核心依赖。此时Docker并不担心,因为它维护的 Docker 社区也足够庞大,Docker项目已是容器生态的标准。于是,2015 年 6 月 22 日,由 Docker 公司牵头,CoreOS、Google、RedHat 等公司共同宣布,Docker 公司将 Libcontainer 捐出,并改名为 RunC 项目,交由一个完全中立的基金会管理,然后以 RunC 为依据,大家共同制定一套容器和镜像的标准和规范,这就是OCI。明显OCI的成立容器玩家们出于自身利益进行干涉的一个妥协结果,所以尽管Docker 是 OCI 的发起者和创始成员,但并没有很积极的去推动,Docker注重是它商业价值。

2015年12月11日,Google、RedHat 等开源基础设施领域玩家们,共同牵头发起了一个名为 CNCF(Cloud Native Computing Foundation)的基金,主要是以kubernetes项目为基础打造一个平台级生态。由于Kubernates项目焕然一新的设计理念和号召力,2016年以后kubernates社区得到了空前的发展。

2016年6月,Docker v.1.12发布,直接内置Docker Swarm(多主机多容器的编排解决方案)

2016年12月, Kubernetes 发布 CRI (Container Runtime Interface, 容器运行时接口)

2017年,Docker 分拆了 Containerd,支持CNI,将这个组件分解为一个单独的项目,使得 Docker 将容器的管理功能移出 Docker 引擎,并移入一个单独的守护进程中,即 Containerd,并将其捐赠给了CNCF社区。同时Docker公司宣布将Docker项目改名为Moby,交给社区自行维护。

2017年10月,Docker公司将自己的主打产品Docker EE 内置Kubernetes项目,预示着Kubernetes的胜出,成为容器编排的标准。

2017年11月 ,K8s支持containerd

2018年 k8s集成containerd,正式GA,把CRI plugin嵌入 containerd中

2019年 rkt 终止使命被CNCF归档

2019 年 Mirantis 收购 Docker 的企业服务

OCI 代表 开放容器标准 , 它标准化了容器工具和底层实现(technologies)之间的大量接口。 他们维护了打包容器镜像(OCI image-spec)和运行容器(OCI runtime-spec)的标准规范。 他们还以 runc 的形式维护了一个 runtime-spec 的真实实现, 这也是 containerd 和 CRI-O 依赖的默认运行时。 CRI 建立在这些底层规范之上,为管理容器提供端到端的标准

全称Container Runtime Interface,(容器运行时接口)是一个用来扩展容器运行时的接口,能让 kubelet 无需重新编译就可以广泛使用各种容器运行时的插件接口。CRI 由 protocol buffers 和 gRPC API 还有 streaming 库 构成。用户不需要关心内部通信逻辑,而只需要实现定义的接口就可以,包括 RuntimeService 和 ImageService。

其实准确来讲,Docker和容器不是一回事,但Docker普及了Linux容器这种技术模式,并在开发底层技术方面发挥了重要作用。 容器的生态相比于单纯的 Docker,已经进化到了一个更宽广的领域

2020年 Kubernates 宣布移除dockershim,现在1.20版本以后,能使用但是kubelet会打印警告日志。最新消息dockershim 计划在 Kubernetes 1.24 版被移除, 请参阅 移除 Kubernetes 增强方案 Dockershim

主流的容器运行时有 containerd,docker engine,cri-o,Mirantis Container Runtime(商业版)

Containerd是一个工业标准的容器运行时,它强调简单性、健壮性和可移植性。它可以在宿主机中管理完整的容器生命周期:容器镜像的传输和存储、容器的执行和管理、存储和网络等,是目前适用最广泛。

Containerd 的配置文件默认为 /etc/containerd/config.toml[^ssh-copy-id]

containerd 将容器相关的数据持久化在 /var/lib/containerd/中(docker 默认在 /var/lib/docker/)

containerd 提供ctr CLI。

containerd 相比docker, 多了 namespace 概念, 每个image和container 都会在各自的namespace下可见, 目前k8s会使用k8s.io 作为命名空间。

容器时依赖task,task 管理容器,删除容器,得先终止task

CRI Tools是社区针对 CRI 接口开发的CLI及验证工具。

它包括两个工具:crictl 和 critest。crictl 是一个容器运行时命令行接口,适用所有CRI兼容的容器运行时,与Docker cli类似功能,但是docker cli只适用于Docker运行时。由于Kubernetes 是支持所有CRI兼容的容器运行时,所以推荐crictl用于 Kubernetes 节点上 pod、容器以及镜像的除错工具。

针对pod操作如下:

critest 则是一个容器运行时的验证测试工具,用于验证容器运行时是否符合 Kubelet CRI 的要求。除了验证测试,critest 还提供了 CRI 接口的性能测试,比如 critest -benchmark

根据上文内容知道Docker也是依赖Containerd,因此安装Docker同时也安装Containerd,那么切Containerd就可以不用再安装,当然你也可以将 Docker 和 containerd 完全卸载掉,然后重新安装。

Containerd 中默认已经实现了 CRI,但是是以 plugin 的形式配置的,之前 Docker 中自带的 containerd 默认是将 CRI 这个插件禁用掉了的(使用配置 disabled_plugins = ["cri"]),所以这里我们重新生成默认的配置文件来覆盖掉, 具体查看上面Containerd 配置

接下来配置kubelet,修改/etc/sysconfig/kubelet,container-runtime指定容器运行时,默认值是docker, --container-runtime-endpoint指定运行时套接字地址,containerd套接字unix:///run/containerd/containerd.sock

配置完成后启动containerd和kubelet

重启完成后查看节点状态

(责任编辑:IT教学网)

更多

相关网络工程师文章

推荐网络工程师文章