导航:首页 > 操作系统 > linuxgrpc

linuxgrpc

发布时间:2022-11-16 22:16:39

python后端开发需要学什么

第一阶段:Python语言基础


主要学习Python最基础知识,如Python3、数据类型、字符串、函数、类、文件操作等。阶段课程结束后,学员需要完成Pygame实战飞机大战、2048等项目。


第二阶段:Python语言高级


主要学习Python库、正则表达式、进程线程、爬虫、遍历以及MySQL数据库。


第三阶段:Pythonweb开发


主要学习HTML、CSS、JavaScript、jQuery等前端知识,掌握python三大后端框架(Django、 Flask以及Tornado)。需要完成网页界面设计实战;能独立开发网站。


第四阶段:linux基础


主要学习Linux相关的各种命令,如文件处理命令、压缩解压命令、权限管理以及Linux Shell开发等。


第五阶段:Linux运维自动化开发


主要学习Python开发Linux运维、Linux运维报警工具开发、Linux运维报警安全审计开发、Linux业务质量报表工具开发、Kali安全检测工具检测以及Kali 密码破解实战。


第六阶段:Python爬虫


主要学习python爬虫技术,掌握多线程爬虫技术,分布式爬虫技术。


第七阶段:Python数据分析和大数据


主要学习numpy数据处理、pandas数据分析、matplotlib数据可视化、scipy数据统计分析以及python 金融数据分析;Hadoop HDFS、python Hadoop MapRece、python Spark core、python Spark SQL以及python Spark MLlib。


第八阶段:Python机器学习


主要学习KNN算法、线性回归、逻辑斯蒂回归算法、决策树算法、朴素贝叶斯算法、支持向量机以及聚类k-means算法。


关于python后端开发需要学什么的内容,青藤小编就和您分享到这里了。如果您对python编程有浓厚的兴趣,希望这篇文章可以为您提供帮助。如果您还想了解更多关于python编程的技巧及素材等内容,可以点击本站的其他文章进行学习。

Ⅱ 区块链技术入门,涉及哪些编程语言

Go语言

Go语言(Golang)是谷歌2009年推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:“我们之所以开发Go,是因为过去10多年间软件开发的难度令人沮丧。”

除比特币是由C++开发以外,目前最主流坊的客户端均有go语言开发,足以可见Go语言在整个区块链行业的地位。

C++

C++ 进一步扩充和完善了 C 语言,是一种面向对象的程序设计语言。C++ 可运行于多种平台上,如 Windows、MAC 操作系统以及 UNIX 的各种版本。C++是一种使用十分广泛的计算机程序设计语言。它是一种通用程序设计语言,支持多重编程模式,例如过程化程序设计、数据抽象、面向对象程序设计、泛型程序设计和设计模式等。

大多数的区块链企业都选择用C++编写区块链的底层,最着名的有比特币、ripple等,主要体现的是强计算性。

Java

Java不同于一般的编译语言或解释型语言。它首先将源代码编译成字节码,然后依赖各种不同平台上的虚拟机来解释执行字节码,从而实现了“一次编写,到处运行”的跨平台特性。而区块链项目的开发,对Java有着明显的依赖性。

其他的还有Python、系统架构、以太坊、Linux、hyperledger、JavaScript等都会有涉及。

Ⅲ 服务产生大量TIME_WAIT如何解决

当TIME_WAIT超过linux系统tw数量的阀值(可用数量不会大于65535),系统会把多余的time-wait socket 删除掉,并且显示警告信息,如果是NAT网络环境又存在大量访问,会产生各种连接不稳定断开的情况,从而影响了服务的稳定性。

一、状态的产生

要解决TIME_WAIT状态过多的问题,先来研究下TIME_WAIT状态的产生,下面是TCP连接断开时的四次挥手状态转换图,说明一点,途中显示的是客户端主动断开连接,tcp连接也可以由服务器端主动断开连接。我们先来描述一下断开的状态:

1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命,RFC规定一个MSL为2min,linux中一般设置为30s)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

可以看到TIME_WAIT状态产生是在tcp连接主动关闭的一端产生的正常tcp状态,超过两个MSL之后,就会关闭,释放占用的端口。基于以上的分析我们可以推断,在我们的应用中产生大量TIME_WAIT状态的根本原因是频繁创建断开连接TCP连接。要解决TIME_WATIT状态过多的问题,就要分析我们的应用把频繁创建的短连接改为长连接。

二、常见的短连接产生的场景

1.服务连接服务

后台业务服务器,通常需要调用redis、mysql以及其他http服务和grpc服务,在服务相互调用中,如果使用的是短连接,高并发时就会产生大量TIME_WAIT,如何解决呢?一般情况下,redis等客户端会有连接池,我们要做的是设置好相关的连接服用参数,一般会有连接数、连接重用时间、连接空闲数等。所以在应用中通过设置合理的连接池参数可以避免TIME_WAIT状态过多的问题:

1.检查http连接池

2.检查grpc连接池

3.检查redis连接池

4.检查mysql连接池

...

我们来查看一个mysql连接池配置信息,最大连接数100,最大空闲连接数10,测试的并发数50,产生的效果如下:

可以看到TIME_WAIT状态快速上升,我们查看redis客户端的连接情况:

{MaxOpenConnections:100 OpenConnections:1 InUse:0 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:0 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:17 InUse:15 Idle:2 WaitCount:0 WaitDuration:0s MaxIdleClosed:48 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:51 InUse:44 Idle:7 WaitCount:0 WaitDuration:0s MaxIdleClosed:82 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:51 InUse:50 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:90 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:50 InUse:49 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:126 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:51 InUse:49 Idle:2 WaitCount:0 WaitDuration:0s MaxIdleClosed:131 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:50 InUse:49 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:181 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:51 InUse:51 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:233 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:51 InUse:51 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:240 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:46 InUse:38 Idle:8 WaitCount:0 WaitDuration:0s MaxIdleClosed:296 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:51 InUse:50 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:313 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:51 InUse:50 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:363 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:51 InUse:50 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:409 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:50 InUse:48 Idle:2 WaitCount:0 WaitDuration:0s MaxIdleClosed:438 MaxLifetimeClosed:0}

{MaxOpenConnections:100 OpenConnections:49 InUse:49 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:494 MaxLifetimeClosed:0}

分析发现MaxIdleClosed数据持续上升,此为mysql客户端连接池配置不合理产生大量TIME_WAIT状态的例子

2.网络抖动

      网络情况不好时,如果主动方无TIME_WAIT等待,关闭前个连接后,主动方与被动方又建立起新的TCP连接,这时被动方重传或延时过来的FIN包过来后会直接影响新的TCP连接。同样网络情况不好并且无TIME_WAIT等待,关闭连接后无新连接,当接收到被动方重传或延迟的FIN包后,会给被动方回一个RST包,可能会影响被动方其它的服务连接。

网络抖动问题比较好排查,直接使用ping命令可以观察到。

Ⅳ docker构建与运行grpc-gateway项目

趁着实习摸鱼(啊不是)之际,简单学习一下曾经很想入门的 docker 。

在上一篇有关 DevOps 的博客中,曾提到:docker 容器的出现,推动了 DevOps 的发展。而 docker 的功劳不仅如此,它的出现可以说是:具有划时代的意义。

很早之前,我就想学习 docker 。但,那时 docker 还未完全支持 Windows 平台,奈何电脑又太差,不敢给 Linux 虚拟机分配太高配置,导致 docker 学习一直被搁置。

如今,docker 已经推出了完美的 Windows 桌面版,而公司电脑配置也完全足够。天时地利人和,此时不学,更待何时。

同时,作为实践,我将用 docker 构建和运行 grpc-gateway 项目。

环境如下:

常用的命令示例:

docker 中很多命令是有相同效果的,比如: docker images == docker image ls 、 docker rmi == docker image rm 、 docker ps -a == docker container ls -a 等,可自行尝试。

Dockerfile 用于构建镜像。镜像既可以通过容器 commit 构建,也可以通过 Dockerfile 构建,但更推荐后者(前者黑盒)。

Dockerfile 常用命令如下:

Dockerfile 编写指南: 一般性的指南和建议

项目地址: https://gitee.com/dounineli/grpcDemo.git

Dockerfile 如下:

利用 Dockerfile 的多阶段构建,减少镜像体积(编译型语言,运行环境不需要复杂的编译环境)。

总共分为三个阶段:

生成镜像时,我们只需构建 server 和 gateway 两个运行阶段即可,两个阶段依赖的 builder 阶段镜像会自动构建,并在构建完成后自动删除。分别得到 grpc 服务端和 grpc-gateway 网关镜像:

由于 grpc-gateway 网关需要访问 grpc 服务端,因此:

用 postman 进行接口测试:

不得不说,docker 的出现,让很多事情变得轻而易举。举一个很简单的例子:如果你想在电脑上安装 MySQL ,直接运行 docker 的 MySQL 镜像即可,几行命令搞定,再也不用麻烦地配置环境了。

Ⅳ 深入剖析Kubernetes

容器,其实是一种特殊的进程而已。很多人会把Docker项目称为轻量级虚拟化技术的原因,实际上就是把虚拟机的概念套用在了容器上。

Linux 容器中用来实现“隔离”的技术手段:Namespace。Namespace 技术实际上修改了应用进程看待整个计算机“视图”,即它的“视线”被操作系统做了限制,只能“看到”某些指定的内容。“敏捷”和“高性能”是容器相较于虚拟机最大的优势,也是它能够在 PaaS 这种更细粒度的资源管理平台上大行其道的重要原因。

基于 Linux Namespace 的隔离机制相比于虚拟化技术也有很多不足之处,其中最主要的问题就是:隔离得不彻底。
首先,既然容器只是运行在宿主机上的一种特殊的进程,那么多个容器之间使用的就还是同一个宿主机的操作系统内核。其次,在 Linux 内核中,有很多资源和对象是不能被 Namespace 化的,最典型的例子就是:时间。

容器的“限制”问题
Linux Cgroups 就是 Linux 内核中用来为进程设置资源限制的一个重要功能。它最主要的作用,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。

Docker 在镜像的设计中,引入了层(layer)的概念。也就是说,用户制作镜像的每一步操作,都会生成一个层,也就是一个增量 rootfs。
通过“分层镜像”的设计,以 Docker 镜像为核心,来自不同公司、不同团队的技术人员被紧密地联系在了一起。而且,由于容器镜像的操作是增量式的,这样每次镜像拉取、推送的内容,比原本多个完整的操作系统的大小要小得多;而共享层的存在,可以使得所有这些容器镜像需要的总空间,也比每个镜像的总和要小。这样就使得基于容器镜像的团队协作,要比基于动则几个 GB 的虚拟机磁盘镜像的协作要敏捷得多。

一个进程,可以选择加入到某个进程已有的 Namespace 当中,从而达到“进入”这个进程所在容器的目的,这正是 docker exec 的实现原理。
Volume 机制,允许你将宿主机上指定的目录或者文件,挂载到容器里面进行读取和修改操作。
一个正确的时机,进行一次绑定挂载,Docker 就可以成功地将一个宿主机上的目录或文件,不动声色地挂载到容器中。

在整个“开发 - 测试 - 发布”的流程中,真正承载着容器信息进行传递的,是容器镜像,而不是容器运行时。这个重要假设,正是容器技术圈在 Docker 项目成功后不久,就迅速走向了“容器编排”这个“上层建筑”的主要原因:作为一家云服务商或者基础设施提供商,我只要能够将用户提交的 Docker 镜像以容器的方式运行起来,就能成为这个非常热闹的容器生态图上的一个承载点,从而将整个容器技术栈上的价值,沉淀在我的这个节点上。

从一个开发者和单一的容器镜像,到无数开发者和庞大的容器集群,容器技术实现了从“容器”到“容器云”的飞跃,标志着它真正得到了市场和生态的认可。
容器就从一个开发者手里的小工具,一跃成为了云计算领域的绝对主角;而能够定义容器组织和管理规范的“容器编排”技术,则当仁不让地坐上了容器技术领域的“头把交椅”。

Kubernetes 项目依托着 Borg 项目的理论优势,才在短短几个月内迅速站稳了脚跟,进而确定了一个如下图所示的全局架构:

在 Kubernetes 项目中,kubelet 主要负责同容器运行时(比如 Docker 项目)打交道。
此外,kubelet 还通过 gRPC 协议同一个叫作 Device Plugin 的插件进行交互。
而 kubelet 的另一个重要功能,则是调用网络插件和存储插件为容器配置网络和持久化存储
从一开始,Kubernetes 项目就没有像同时期的各种“容器云”项目那样,把 Docker 作为整个架构的核心,而仅仅把它作为最底层的一个容器运行时实现。
Kubernetes 项目最主要的设计思想是,从更宏观的角度,以统一的方式来定义任务之间的各种关系,并且为将来支持更多种类的关系留有余地。
在 Kubernetes 项目中,这些容器则会被划分为一个“Pod”,Pod 里的容器共享同一个 Network Namespace、同一组数据卷,从而达到高效率交换信息的目的。Pod 是 Kubernetes 项目中最基础的一个对象。Kubernetes 项目的做法是给 Pod 绑定一个 Service 服务,而 Service 服务声明的 IP 地址等信息是“终生不变”的。这个 Service 服务的主要作用,就是作为 Pod 的代理入口(Portal),从而代替 Pod 对外暴露一个固定的网络地址。
围绕着容器和 Pod 不断向真实的技术场景扩展,我们就能够摸索出一幅如下所示的 Kubernetes 项目核心功能的“全景图”。

在 Kubernetes 项目中,我们所推崇的使用方法是:首先,通过一个“编排对象”,比如 Pod、Job、CronJob 等,来描述你试图管理的应用;然后,再为它定义一些“服务对象”,比如 Service、Secret、Horizontal Pod Autoscaler(自动水平扩展器)等。这些对象,会负责具体的平台级功能。这种使用方法,就是所谓的“声明式 API”。这种 API 对应的“编排对象”和“服务对象”,都是 Kubernetes 项目中的 API 对象(API Object)。

Ⅵ grpc-源码-网络模型

golang 的grpc库是 https://github.com/grpc/grpc-go

grpc server端和服务端网络协议是在tcp基础上的 http2协议,http2协议负责grpc基础的数据传输、连接管理、流控等, 具体的业务层service 定义是基于 protobuf的

整个的网络过程和关键点如下图

说明:

TCP KeepAlive则是为了探测/保鲜(心跳检测,连接错误检测):用于探测对端的状态及网络情况(有可能客户端崩溃、强制关闭了应用、主机不可达等等),也有保鲜功能。比如如防止nat超时。TCP keepalive则是通过发送发送侦测包实现。在Linux中通过net.ipv4.tcp_keepalive_intvl,net.ipv4.tcp_keepalive_probes,net.ipv4.tcp_keepalive_time配置。比如gnet 网络框架中的实现 https://github.com/panjf2000/gnet/blob/master/netpoll/netpoll_unix.go

Ⅶ Protobuf协议实现原理

protobuf 是Google开源的一款支持跨平台、语言中立的结构化数据描述和高性能序列化协议,此协议完全基于二进制,所以性能要远远高于JSON/XML。由于出色的传输性能所以常见于微服务之间的通讯,其中最为着名的是Google开源的 gRPC 框架。

那么protobuf是如何实现高性能的,又是如何实现数据的编码和解码的呢?

基于128bits的数据存储方式(Base 128 Varints)

Varint 是一种紧凑的表示数字的方法。它用一个或多个字节来表示一个数字,值越小的数字使用越少的字节数。这能减少用来表示数字的字节数。

比如对于 int32 类型的数字,一般需要 4 个 byte 来表示。但是采用 Varint,对于很小的 int32 类型的数字,则可以用 1 个 byte 来表示。当然凡事都有好的也有不好的一面,采用 Varint 表示法,大的数字则需要 5 个 byte 来表示。从统计的角度来说,一般不会所有的消息中的数字都是大数,因此大多数情况下,采用 Varint 后,可以用更少的字节数来表示数字信息

Varint 中的每个 byte 的最高位 bit 有特殊的含义,如果该位为 1,表示后续的 byte 也是该数字的一部分,如果该位为 0,则结束。其他的 7 个 bit 都用来表示数字。因此小于 128 的数字都可以用一个 byte 表示。大于 128 的数字,比如 300,会用两个字节来表示:1010 1100 0000 0010。

另外如果从数据大小角度来看,这种表示方式比实现的数据多了一个bit, 所以其实际传输大小就多14%(1/7 = 0.142857143)。

数字1表示方式:0000 0001

对于小的数据比较好理解,正常情况下1的二进制是 0000 0001,使用128bits表示的话,首位结束标识位也是0,所以两者结果是一样的 0 000 0001。

数字 300 表示方式:1010 1100 0000 0010

<figcaption>300</figcaption>

这个有点不太好理解了,这是因为原本用一个字节(8bit)就可以表示,但由于使用128bits表示方法,需要对每个字节的最高位添加一个结束标识位来表示,所以一个字节已经不够用了,需要占用两个字节来表示,其中两个字节最高位都是结束标识位。

如果正向推算的话,我们知道数字300的二进制值 1 0010 1100,用两个字节表示完整值则为
0000 0001 0010 1100 # 二进制
_000 0010 _010 1100 # 二进制每个字节的最高位向左移动一个位置,放入结束标识位
0 000 0010 1 010 1100 # 转换为128bits方式,1:结束,0:未结束
1 010 1100 0 000 0010 # 转换为 小端字节序 , 低字节在前,高字节在后

注意这里是先添加结束标识符,然后再转为小端字节序。

消息经过序列化后会成为一个二进制数据流,该流中的数据为一系列的 Key-Value 对。如下图所示:

采用这种 Key-Pair 结构无需使用分隔符来分割不同的 Field。 对于可选的 Field,如果消息中不存在该 field,那么在最终的 Message Buffer 中就没有该 field ,这些特性都有助于节约消息本身的大小。

Key 用来标识具体的 field,在解包的时候,客户端创建一个结构对象,Protocol Buffer 从数据流中读取并反序列化数据,并根据 Key 就可以知道相应的 Value 应该对应于结构体中的哪一个 field。

而Key也是由以下两部分组成

Key 的定义如下:

| 1 | (field_number << 3) | wire_type |

可以看到 Key 由两部分组成。第一部分是 field_number 。第二部分为 wire_type 。表示 Value 的传输类型。

一个字节的低3位表示数据类型,其它位则表示字段序号。

Wire Type 可能的类型如下表所示:

在我们的例子当中,field id 所采用的数据类型为 int32,因此对应的 wire type 为 0。细心的读者或许会看到在 Type 0 所能表示的数据类型中有 int32 和 sint32 这两个非常类似的数据类型。Google Protocol Buffer 区别它们的主要意图也是为了减少 encoding 后的字节数。

每个数据头同样采用128bits方式,一般1个字节就足够了,

本例中字段a 的 序号是1

如上创建了 Test1 的结构并且把 a 的值设为 2,序列化后的二进制数据为
0 000 1000 0 000 0010

Key 部分是 0000 1000
value 部分是 0000 0010, 其中字节最高位是结束标识位,即10进制的2,我们在转换的时候统一将符号位转为0即可。

协议规定数据头的低3位表示wire_type, 其它字段表示字段序号field_number,因此
0000 1000
_000 1000 # 去掉结束标识符位
_000 1000 # 000 表示数据类型, 这里是Varint
_000 1000 # 0001 这四位表示字段序号

https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/

原文: https://blog.haohtml.com/archives/20215

Ⅷ 【知识总结】6.服务注册发现框架比较(Consul/Zookeeper/etcd/Eureka)

服务发现就是服务提供者将自己提供的地址post或者update到服务中介,服务消费者从服务中介那里get自己想要的服务的地址。

但是有两个问题:
第一个问题:如果有一个服务提供者宕机,那么中介的key/value中会有一个不能访问的地址,该怎么办?

心跳机制: 服务提供者需要每隔5秒左右向服务中介汇报存活,服务中介将服务地址和汇报时间记录在zset数据结构的value和score中。服务中介需要每隔10秒左右检查zset数据结构,踢掉汇报时间严重落后的地址。这样就可以保证服务列表中地址的有效性。

第二个问题是服务地址变动时如何通知消费者。有两种解决方案。

第一种是轮询,消费者每隔几秒查询服务列表是否有改变。如果服务地址很多,查询会很慢。这时候可以引入服务版本号机制,给每个服务提供一个版本号,在服务变动时,递增这个版本号。消费者只需要轮询这个版本号的变动即可知道服务列表是否发生了变化。

第二种是采用pubsub。这种方式及时性要明显好于轮询。缺点是每个pubsub都会占用消费者一个线程和一个额外的连接。为了减少对线程和连接的浪费,我们使用单个pubsub广播全局版本号的变动。所谓全局版本号就是任意服务列表发生了变动,这个版本号都会递增。接收到版本变动的消费者再去检查各自的依赖服务列表的版本号是否发生了变动。这种全局版本号也可以用于第一种轮询方案。

CAP理论
CAP理论是分布式架构中重要理论

关于P的理解,我觉得是在整个系统中某个部分,挂掉了,或者宕机了,并不影响整个系统的运作或者说使用,而可用性是,某个系统的某个节点挂了,但是并不影响系统的接受或者发出请求,CAP 不可能都取,只能取其中2个。原因是

(1)如果C是第一需求的话,那么会影响A的性能,因为要数据同步,不然请求结果会有差异,但是数据同步会消耗时间,期间可用性就会降低。

(2)如果A是第一需求,那么只要有一个服务在,就能正常接受请求,但是对与返回结果变不能保证,原因是,在分布式部署的时候,数据一致的过程不可能想切线路那么快。

(3)再如果,同事满足一致性和可用性,那么分区容错就很难保证了,也就是单点,也是分布式的基本核心,好了,明白这些理论,就可以在相应的场景选取服务注册与发现了。

平时经常用到的服务发现的产品进行下特性的对比,首先看下结论:

补充:
(1)运维和开发如果是 Java 更熟,也更多 Java 的应用,那毫无疑问应该用 ZK;如果是搞 Go 的,那么还是 etcd 吧,毕竟有时候遇到问题还是要看源码的。
(2)在创建一百万个或更多键时,etcd可以比Zookeeper或Consul稳定地提供更好的吞吐量和延迟。此外,它实现了这一目标,只有一半的内存,显示出更高的效率。但是,还有一些改进的余地,Zookeeper设法通过etcd提供更好的最小延迟,代价是不可预测的平均延迟。
(3)
一致性协议: etcd 使用 Raft 协议,Zookeeper 使用 ZAB(类PAXOS协议),前者容易理解,方便工程实现;
运维方面:etcd 方便运维,Zookeeper 难以运维;
数据存储:etcd 多版本并发控制(MVCC)数据模型 , 支持查询先前版本的键值对
项目活跃度:etcd 社区与开发活跃,Zookeeper 感觉已经快死了;
API:etcd 提供 HTTP+JSON, gRPC 接口,跨平台跨语言,Zookeeper 需要使用其客户端;
访问安全方面:etcd 支持 HTTPS 访问,Zookeeper 在这方面缺失;

与 Eureka 有所不同,Apache Zookeeper 在设计时就紧遵CP原则,即任何时候对 Zookeeper 的访问请求能得到一致的数据结果,同时系统对网络分割具备容错性,但是 Zookeeper 不能保证每次服务请求都是可达的。

从 Zookeeper 的实际应用情况来看,在使用 Zookeeper 获取服务列表时,如果此时的 Zookeeper 集群中的 Leader 宕机了,该集群就要进行 Leader 的选举,又或者 Zookeeper 集群中半数以上服务器节点不可用(例如有三个节点,如果节点一检测到节点三挂了 ,节点二也检测到节点三挂了,那这个节点才算是真的挂了),那么将无法处理该请求。所以说,Zookeeper 不能保证服务可用性。

当然,在大多数分布式环境中,尤其是涉及到数据存储的场景,数据一致性应该是首先被保证的,这也是 Zookeeper 设计紧遵CP原则的另一个原因。

但是对于服务发现来说,情况就不太一样了,针对同一个服务,即使注册中心的不同节点保存的服务提供者信息不尽相同,也并不会造成灾难性的后果。

因为对于服务消费者来说,能消费才是最重要的,消费者虽然拿到可能不正确的服务实例信息后尝试消费一下,也要胜过因为无法获取实例信息而不去消费,导致系统异常要好(淘宝的双十一,京东的618就是紧遵AP的最好参照)。

当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30~120s,而且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。

在云部署环境下, 因为网络问题使得zk集群失去master节点是大概率事件,虽然服务能最终恢复,但是漫长的选举事件导致注册长期不可用是不能容忍的。

Spring Cloud Netflix 在设计 Eureka 时就紧遵AP原则。Eureka是在Java语言上,基于Restful Api开发的服务注册与发现组件,由Netflix开源。遗憾的是,目前Eureka仅开源到1.X版本,2.X版本已经宣布闭源。

Eureka Server 也可以运行多个实例来构建集群,解决单点问题,但不同于 ZooKeeper 的选举 leader 的过程,Eureka Server 采用的是Peer to Peer 对等通信。这是一种去中心化的架构,无 master/slave 之分,每一个 Peer 都是对等的。在这种架构风格中,节点通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的 serviceUrl 指向其他节点。每个节点都可被视为其他节点的副本。

在集群环境中如果某台 Eureka Server 宕机,Eureka Client 的请求会自动切换到新的 Eureka Server 节点上,当宕机的服务器重新恢复后,Eureka 会再次将其纳入到服务器集群管理之中。当节点开始接受客户端请求时,所有的操作都会在节点间进行复制(replicate To Peer)操作,将请求复制到该 Eureka Server 当前所知的其它所有节点中。

当一个新的 Eureka Server 节点启动后,会首先尝试从邻近节点获取所有注册列表信息,并完成初始化。Eureka Server 通过 getEurekaServiceUrls() 方法获取所有的节点,并且会通过心跳契约的方式定期更新。

默认情况下,如果 Eureka Server 在一定时间内没有接收到某个服务实例的心跳(默认周期为30秒),Eureka Server 将会注销该实例(默认为90秒, eureka.instance.lease-expiration-ration-in-seconds 进行自定义配置)。

当 Eureka Server 节点在短时间内丢失过多的心跳时,那么这个节点就会进入自我保护模式。

Eureka的集群中,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:

Eureka不再从注册表中移除因为长时间没有收到心跳而过期的服务;
Eureka仍然能够接受新服务注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用);
当网络稳定时,当前实例新注册的信息会被同步到其它节点中;
因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使得整个注册服务瘫痪。

Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X)。
Consul采用主从模式的设计,使得集群的数量可以大规模扩展,集群间通过RPC的方式调用(HTTP和DNS)。

Consul 内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等),使用起来也较为简单。

Consul 遵循CAP原理中的CP原则,保证了强一致性和分区容错性,且使用的是Raft算法,比zookeeper使用的Paxos算法更加简单。虽然保证了强一致性,但是可用性就相应下降了,例如服务注册的时间会稍长一些,因为 Consul 的 raft 协议要求必须过半数的节点都写入成功才认为注册成功 ;在leader挂掉了之后,重新选举出leader之前会导致Consul 服务不可用。

默认依赖于SDK

Consul本质上属于应用外的注册方式,但可以通过SDK简化注册流程。而服务发现恰好相反,默认依赖于SDK,但可以通过Consul Template(下文会提到)去除SDK依赖。

Consul Template

Consul,默认服务调用者需要依赖Consul SDK来发现服务,这就无法保证对应用的零侵入性。

所幸通过 Consul Template ,可以定时从Consul集群获取最新的服务提供者列表并刷新LB配置(比如nginx的upstream),这样对于服务调用者而言,只需要配置一个统一的服务调用地址即可。

Consul强一致性(C)带来的是:

Eureka保证高可用(A)和最终一致性:

其他方面,eureka就是个servlet程序,跑在servlet容器中; Consul则是go编写而成。

etcd是一个采用http协议的分布式键值对存储系统,因其易用,简单。很多系统都采用或支持etcd作为服务发现的一部分,比如kubernetes。但正事因为其只是一个存储系统,如果想要提供完整的服务发现功能,必须搭配一些第三方的工具。

比如配合etcd、Registrator、confd组合,就能搭建一个非常简单而强大的服务发现框架。但这种搭建操作就稍微麻烦了点,尤其是相对consul来说。所以etcd大部分场景都是被用来做kv存储,比如kubernetes。

etcd 比较多的应用场景是用于服务发现,服务发现 (Service Discovery) 要解决的是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务如何才能找到对方并建立连接。和 Zookeeper 类似,etcd 有很多使用场景,包括:
配置管理
服务注册发现
选主
应用调度
分布式队列
分布式锁

按照官网给出的数据, 在 2CPU,1.8G 内存,SSD 磁盘这样的配置下,单节点的写性能可以达到 16K QPS, 而先写后读也能达到12K QPS。这个性能还是相当可观。

etcd 提供了 etcdctl 命令行工具 和 HTTP API 两种交互方法。etcdctl命令行工具用 go 语言编写,也是对 HTTP API 的封装,日常使用起来也更容易。所以这里我们主要使用 etcdctl 命令行工具演示。

(1)注册中心ZooKeeper、Eureka、Consul 、Nacos对比
https://zhuanlan.hu.com/p/165217227?utm_source=wechat_session
(2)常用的服务发现对比(Consul、zookeeper、etcd、eureka)
https://blog.csdn.net/gaohe7091/article/details/101197107

Ⅸ 在Ubuntu的环境下怎么交叉编译grpc到cortex-a9架构

1、 解压工具链压缩包
$ cd ~
$ mkdir toolchain
$ cd toolchain
gcc-4.6.4.tar.xz拷贝到toolchain目录下并解压
$ tar xvf gcc-4.6.4.tar.xz

2、 环境变量的添加
修改文件/etc/bash.bashrc添加如下内容
export PATH=$PATH:/home/linux/toolchain/gcc-4.6.4/bin
重启配置文件
$ source /etc/bash.bashrc

Ⅹ 北大青鸟设计培训:linux编程应该掌握哪些编程开发工具

随着对linux系统的不断普及和应用,我们在linux编程方面也取得了很大的进展,今天我们就一起来了解一下,在linux编程开发领域都有哪些开发工具值得我们学习和掌握。
但大多数人使用Nginx都停留在这几个级别:一:使用Nginx配置简单的反向代理服务或者静态资源服务,当扩展功能时发现新增的指令Nginx不支持,但又不懂如何增加Nginx模块,如何分析access日志。
二:可以根据源码定制安装Nginx,对网上流传的大众配置做一些个性化的修改,但遇到修改proxy_pass后的URL上游服务不正常等问题时就束手无策,不清楚Nginx各个目录的意义,也不清楚Nginx的进程结构。
三:能够顺畅地使用Nginx的常用功能,但不清楚三方模块发生冲突时的解决方案、stale过期缓存的用法、Nginx诸多变量是如何被赋值的、听说if指令是邪恶的却不知道它的设计理念及正确用法等等。
四:可以正确地使用Nginx的功能及三方模块,并按照网络上常见的优化参数优化性能,但对如何系统化地优化性能没有头绪,对于Nginx、Linux提供的内存缓冲区、网络类等诸多指令和参数的优化没有头绪。
五:可以熟练使用Nginx,但对OpenResty的Lua模块如何与Nginx结合使用以及对Nginx性能影响不太清楚,对Nginx源码的理解没有达到由点到面的程度。
六、提高Nginx能力需要从以下方面开始1、深入理解Nginx架构了解事件驱动机制是深入优化Nginx性能、判定三方模块性能的基础。
而了解Nginx的进程结构,则是我们对Nginx做日常维护的必要条件,也是我们优化Nginx性能的理论基础。
另外,变量是Nginx实现模块间解耦合的关键。
这些知识都需要我们牢固掌握,为后面的进阶学习打下坚实基础。
2、对HTTP模块要了如指掌HTTP请求处理过程中分为11个阶段。
理解每个HTTP模块所处的阶段,并清楚该模块在这一阶段中的位置顺序,有助于我们定位指令不生效或者与预期功能不符等问题,提高定位各种Bug的效率,也可以帮我们熟悉缺乏文档的三方模块。
3、反向代理与负载均衡反向代理有一套通用的处理流程,郑州IT培训http://www.kmbdqn.cn/认为需要掌握反向代理处理请求的完整流程,能让我们熟练使用HTTP协议反向代理,以及熟悉如memcached、gRPC等同类的反向代理,在优化性能时,也能对相关缓存、超时等指令更有针对性的做个性化配置。

阅读全文

与linuxgrpc相关的资料

热点内容
dvd光盘存储汉子算法 浏览:757
苹果邮件无法连接服务器地址 浏览:963
phpffmpeg转码 浏览:672
长沙好玩的解压项目 浏览:145
专属学情分析报告是什么app 浏览:564
php工程部署 浏览:833
android全屏透明 浏览:737
阿里云服务器已开通怎么办 浏览:803
光遇为什么登录时服务器已满 浏览:302
PDF分析 浏览:486
h3c光纤全工半全工设置命令 浏览:143
公司法pdf下载 浏览:382
linuxmarkdown 浏览:350
华为手机怎么多选文件夹 浏览:683
如何取消命令方块指令 浏览:350
风翼app为什么进不去了 浏览:779
im4java压缩图片 浏览:362
数据查询网站源码 浏览:151
伊克塞尔文档怎么进行加密 浏览:893
app转账是什么 浏览:163