当前位置: 首页 > news >正文

兰州市做网站的公司有哪些/淘宝运营培训班

兰州市做网站的公司有哪些,淘宝运营培训班,html5手机网站模板,提供网站建设搭建前言看到这个标题,你可能会有一些问题:什么是 RPC,是解决什么问题;什么是 Service Mesh,现代的 RPC 形态和它有什么关系。让我们通过下面这些内容来理解他们。服务架构的演化史;如何完成一次基本的 RPC 调用…

feb1a50f8750fa8b3ae7aacea5cfa6c9.png

前言

看到这个标题,你可能会有一些问题:

  1. 什么是 RPC,是解决什么问题;
  2. 什么是 Service Mesh,现代的 RPC 形态和它有什么关系。

让我们通过下面这些内容来理解他们。

  • 服务架构的演化史;
  • 如何完成一次基本的 RPC 调用;
  • 一些扩展需求:服务容错、监控和治理;
  • 基于 Docker 与 Service Mesh 之上的现代化 RPC 形态

服务架构的演化史

服务架构大体分为这么几个阶段:

  • 单体架构时代;
  • HTTP 接口通信架构时代;
  • "RPC", “消息队列” 承载的微服务架构时代;

单体架构

相信在几年前有过服务开发经验的同学,都有这样一段经历。那是个应用部署方式还比较匮乏的年代,大部分互联网公司开发、发布应用的方式是这样的。

所有的项目开发者会在一个项目中开发,通过 git 管理版本历史,在完成代码开发后,将代码编译打包,通过 scp 传递到云主机上,然后 ssh 到云主机上执行启动命令来完成发布。

项目还小的时候,这样的方式既快又省事。但随着项目逐渐变大,慢慢就会发现了一些问题:

  1. 系统庞大时,任何一次小改动都需要长时间的编译;
  2. 每次小功能的调整,都需要发布整个项目,增大引入问题的风险;
  3. 前后端的代码在一个项目中部署,前端页面更新也需要整个项目重新发布,增大引入问题的风险;
  4. 如果应用宕机,所有服务都将不可用。

似乎发现了这些问题,所以开发者也试图做一些改造。

HTTP 接口通信架构

最初的改造,是将单体服务按照大的模块进行拆分,然后模块与模块之间暴露出一些 HTTP 的服务,提供互相之间的功能调用的能力。

比如,一个电商网站的开发,将它拆成商品模块,订单模块和库存模块等等,这些服务分别启动在各自的域名之上,提供出 HTTP 的访问协议。

那么,用户完成一次下单操作,需要以 HTTP 的形式调用订单模块、商品模块和库存模块提供出来的 API。

这其实已经是微服务架构的原型了,但仍有一些问题:

  1. 每次 HTTP 接口调用,都包含域名解析和 LB 层转发的过程,增加了调用链路以及复杂度;
  2. HTTP 协议比较灵活,URL、headers(Cookies 和其他 headers)、body 都可以作为数据承载的载体,影响最终的服务调用结果,且出现问题时不容易追溯;
  3. 性能上,HTTP 1.0 的不复用连接的形式,也会给性能造成一些负担。

微服务架构

总结 HTTP 接口通信架构的一些问题:

  1. 域名解析与 LB 层转发带来的调用链路增加与 Response Time 的影响;
  2. HTTP 协议灵活,所以需要一套规范化传输方式;
  3. 连接不复用对于内网环境的服务调用不是一个好选择。

看起来问题的根因,是 HTTP 从设计之出,不是为服务间调用量身定制的。所以解决问题的方式,似乎就是设计一套专门用于内网之间服务调用的方案了。

这个方案其实早在 1988 年就有人在 RFC 中提出,即 RPC,全称 "Remote Procedure Call Protocol"。

完成一次基本的 RPC 调用

理解 RPC 调用,可以类比本地的函数调用。

function Add(a: number, b: number) {return a + b;
}const methods = {Add
};function call(method: string, args: []) {return methods[method](...args);
}call('Add', ['hello', 'world']);

而 RPC 做的事情,就是按照一定协议,允许你的程序调用非当前进程内、非当前主机内的函数。

笔者写了一个极简的 RPC 调用框架 - tiny-rpc。

之所以称其为及简的 RPC 框架,因为他只解决了 RPC 框架的两个基础问题:

  1. 解决数据通信的问题(使用 HTTP;
  2. 解决传输内容的序列化和反序列化的问题(使用 JSON 完成对象与字符串的转换;使用 utf8 编码完成字符串与二进制的转换。

下面是使用 tiny-rpc 完成的一个 RPC 调用的例子。

接口定义文件

要完成一次 RPC 调用,首先得定义有哪些接口,需要一份描述文件,这里我们用 JSON 来完成描述,如下:

import { createService } from 'tiny-rpc';const def = {"HelloRequest": {"fields": {"name": {"type": "string","id": 1}}},"HelloReply": {"fields": {"status": {"type": "string","id": 1}}},"AwesomeMessageService": {"methods": {"SayHello": {"requestType": "HelloRequest","responseType": "HelloReply"}}}
}export const service = createService(def, 'AwesomeMessageService');

服务端

然后是 RPC 的 Server 端,需要监听端口,启动一个网络服务,并在这个网络服务上实现对应的函数。

import { createServer } from "../../src";
import { service } from "./service";async function main() {const server = createServer(service, {impl: {sayHello(helloRequest: {name: string}): {status: string} {console.log('helloRequest:', helloRequest)return {status: '200'}}},port: 9090});server.serve();
}main().catch(console.error);

客户端

最后是 RPC 的 Client 端,适时地发起调用。

import { createClient } from "tiny-rpc";
import { service } from "./service";async function main() {const client = createClient(service, {transport: 'http',target: '127.0.0.1:9090'});const resp = await client.callMethod('sayHello', {name: 'my-name'});console.log(resp);
}main().catch(console.error);

最后我们发起依次执行 Server 和 Client,调用成功。

3d37fbbd6243b08d04d858360ba226c1.png

然后打开抓包工具重试,印证了前面提到的基于 HTTP 传输。

a8c65453d2eca7cb8d0c2c3bd9a4f540.png

很多人可能会提出疑问,既然还是使用了 HTTP 作为通信协议,那 RPC 调用和 HTTP 调用有什么区别吗?

  • RPC 侧重的是收敛具体协议的差异,只是服务间调用的一个约定。而具体的通信的协议,既可以是 HTTP,也可以是基于 TCP/UDP 自己封装一套;
  • 相对于 HTTP,RPC 调用的使用方式更统一,更容易记录,对于实际的问题更容易追溯;
  • RPC 重视调用的服务容错和服务治理,提供可靠的应用层通信方式。

一些扩展需求:服务容错、监控和治理

回顾一下上述提出的一些问题是否得到解决:

  1. 域名解析与 LB 层转发带来的调用链路变长与 Response Time 的影响;
  2. HTTP 协议灵活,所以需要一套规范化传输方式;
  3. 连接不复用对于内网环境的服务调用不是一个好选择。

看起来只有第一个、第二个问题得到了解决:

  1. 通过 IP 直接寻址到到目标主机,不需要中间的 LB 层和 DNS 解析服务;
  2. RPC 协议方式限制了调用方式,减少了影响结果的变量,易于追踪/排查问题;

依然会留下一些改进点:

  1. 由于依然使用了 HTTP 协议作为通信协议,连接不复用的方式依然是一个优化点;
  2. 硬编码 IP:PORT 的方式会使程序极难维护;
  3. 如何做更可靠服务调用;
  • 调用追溯,易于出现问题时的排查与定位;
  • 服务局部 / 全部不可用时的保障措施;
  • 服务调用安全性保障(防止伪造;

连接复用 - HTTP2, 自定义 TCP, UDP 协议

这个问题解决的方式也比较多,有这么几个思路:

  1. 使用 HTTP 1.1 的 连接池 和 Pipeline 功能,来实现并发连接和连接复用;
  2. 使用 HTTP 2 的多路复用解决。但尽量也不要只开一个连接;否则当下游路由器/交换机出现丢包、超时时,TCP 本身的拥塞控制的机制会造成当前连接的滑动窗口急剧缩小;
  3. 基于 TCP 自定义协议,自己建立连接池和多路复用的机制;
  4. 基于 UDP 实现上层通信协议,实现可靠传输,自定义拥塞控制,从某些角度优化 TCP 连接的一些性能,比如 HTTP 请求 1RTT 和 HTTPS 3RTT 的延时问题,参考 QUIC;

“硬编码 IP:PORT” 改进方案 - 服务发现

通常在 HTTP 场景下的解法是 DNS 与 七层负载均衡(Nginx)。但这我们前面提到是会使调用链路变长的,所以不能开这个倒车。

但借鉴我们可以借鉴这个解法:

  1. 参考 DNS 服务的方式,每次调用服务前能够从一个服务中获取到要调用服务的所有 IP:PORT 地址;
  2. 在调用侧中做一层负载均衡,每次从这个列表中选一个节点出来作为目标服务。

这样的服务我们称之为注册中心,可选的有:zookeeper/etcd/consul。

值得注意的是:

  1. 服务下线需要有优雅停机的过程,即:从注册中心上摘除节点后,隔一段时间后再停止服务,给调用方一个切换目标服务的时间;
  2. 服务建议以集群方式部署,减少单点故障带来的影响;

让服务调用可追溯 - Trace, Metrics, Logs

监控的黄金三角,Trace, Metrics 和 Logs,理解他们主要是从需求场景触发。

调用链路与时间线概览 - Trace

第一个需求是对整个调用链路有直观的感受。

f8c2b525b7025993822be702e4a7d368.png
chain

第二个需求是对整体的调用时间的直观把握。

3a71e3c1c24128bb4fba82cd73d6cff8.png
timing line

值得注意的是,Trace 是需要采样的(一般 1% 的采样率即可),这也和他的需求场景息息相关。只是从调用链路宏观上感知需求,而不是细节到每个请求链路都要统计出来。

公司内如果没有相应的基建可以考虑直接部署 opentracing。然后使用官方 Client 进行上报。

监控打点, 指标汇总, 异常报警 - Metrics

Metrics 的需求场景来自所有一切可聚合场景的监控,比如:

  1. RPC 调用的成功率,失败率监控,调用平均耗时、p95 耗时、p99 耗时等等;
  2. 以及下文提到的一些其他服务治理需求触发的概率;

相应的需要用到的 Metric 统计类型有 Counter, Meter, Histogram。

一般是需要较为实时地离线处理,以便触发告警。公司内如果没有相应的基建可以考虑部署使用 elk, filebeat 作为日志采集和聚合工具,并作为 grafana 的数据源,由 grafana 提供可视化图标展示和告警的能力。

日志查询 - Logs

日志的需求来自出现异常后的链路排查,通常需要在 LB 层通过一个统一算法确定一个的 logid / reqid,写入到请求的 headers 之上,后续所有服务调用不断透传这个 logid。

实时性相对 Metrics 可以低一点,一般出现 Metrics 触发的报警后,用户会通过进入日志查询到调用相关的日志,并通过 logid,串联所有调用链日志,方便问题排查。

上文描述的 elk, filebeat 本身已经提供了日志采集和聚合机制,可以复用。

服务保障手段 - 熔断, 超时重试, 限流, 降级

熔断

熔断的需求场景有点类似 TCP 的拥塞控制。

TCP 的拥塞控制

我们知道 IP 协议是尽力而为的不可靠协议,所以保障数据的可靠传输 TCP 协议需要做一些事情。

在路由器在接收到源服务 TCP segment 时,先存储到本地内存开辟一个队列,等待之前的报文转发完成后,会查询本地路由表后,经过 NAT 记录表、转换 TCP 报文源 IP 处理后,转发到下一跳。

而此时如果路由器的队列满了,可能就会出现包被丢弃的情况,这个时候源服务就会触发 ACK 超时,或者接收到另一端的重复 ACK 的报文。TCP 层的拥塞控制就会做一些处理,将控制 TCP 流量的滑动窗口急剧缩小,后续再慢慢地把滑动窗口放大,直至恢复正常大小。

RPC 的熔断机制

同样地,我们在 RPC 操作中做的做类似的处理就叫熔断。

上文提到依托于服务发现,我们可以得到一个实例的列表。每次以软负载的机制决定要访问的实例。

虽然 TCP 协议是可靠协议,但他保障的只是 IP 协议的丢包、乱序问题。真正触发调用时,也会出现一些问题。比如服务异常退出的时候。此时,仍然需要上层程序做一些处理。

具体的做法是为每一个实例,建立一个熔断器,当目标服务多次超时、服务不可用时触发熔断,熔断后,当前实例不再参与到软负载选举过程中。后续由定时器,逐渐将流量放大,直到服务正常。

超时重试

超时重试的需求通常需要接口幂等,否则可能会出现重复创建订单、重复创建用户的情况。

实际处理的时候,可以和熔断结合,当超时触发时,自然需要换一个实例重试,同一个实例在一段时间内达到多少次重试次数的时候就需要启用熔断机制了。

降级

重试几次后,调用仍然异常,则需要考虑降级。降级可以理解为是调用目标服务出错了,但是可以返回给用户一个无伤大雅的响应。但记住,不是所有的接口都是可以降级的。

限流

限流是对目标服务的保障措施,一般两种:

  1. 主动限流 - 开发者配置一个最大的 QPS 限制,超出这个限制,启动限流措施;
  2. 被动限流 - 结合熔断机制,可以又一个被动限流的效果,当大部分服务都被熔断之后,自然对目标服务的限流就得到了控制。

惯用的手段有:令牌桶限流、漏桶限流。

安全性保障

服务可用性有了一定保障,接下来要处理安全的一些措施了。

允许特定服务访问 - 服务访问权限

需求是,我的服务不能所有人访问,要指定特定的人才能访问。

实现起来比较简单。

  1. 允许服务配置一些白名单/黑名单;
  2. 客户端服务在调用服务时带上自己服务名;
  3. 服务接收到调用时,校验该服务名是否可以放行;

防服务冒充 - 服务访问权限鉴定

但会碰到一个问题,客户端可以伪造这个服务名。

这个时候怎么办?引入服务鉴定。

比较容易实现的方案,在调用服务前后经过一个统一的鉴权服务,由这个服务来做处理。

防中间人 - 传输加密

如果有人偷偷 ssh 登陆上你的服务器,然后部署了一段 tcp 的抓包脚本,怎么办?

在 TCP 建连成功后,引入 TLS 层加密...

但会增加 2RTT 的 TLS 握手时间消耗,可以考虑直接使用 QUIC 作为协议,天然解决加密问题,和带来 0RTT 实现握手的特性。

基于 Docker 与 Service Mesh 之上的现代化 RPC 形态

上面介绍了一些服务追溯、容错、治理的需求,我们会发现仍然会遗留一些问题。

Service Mesh 的背景

  • 看起来,服务治理相关的工作量不小,且有持续升级增加功能的趋势,日后持续升级是个问题;
  • 而 RPC 本身是不限定语言的,go, java, Node.js,重复实现是个问题;
  • 服务可访问权限的鉴定如果没有一个中间方,可能不会实施,但我们前面提到引入网络中的中间方会带来调用链和 Response Time 的增加。

所以,为了解决这些问题,2019 年的 RPC 形态发生了一些改变。

Service Mesh 的打开方式

基本架构

bddde435319417c62625e285eae80605.png

我们知道, TCP / IP 的网络分层,网络层做数据通信时的原则是,尽力而为,也就是说是不可靠的数据传输。不可靠体现在:

  1. 路由器在存储转发时,可用内存满了,发生丢弃;
  2. TCP 传输过来的 Segment 太大了,超出了一个 MTU 的限制,发生分包;
  3. 同一个 TCP 的数据报文,经过分包后,走了不同的传输路线,发生乱序。

所以,TCP 层需要做一些事情,来保障可靠网络传输,比如乱序时的 ACK 重传,丢包时的超时机制,网络繁忙时的拥塞控制等等。

而 Service Mesh 要做的事情,就是在 Docker 容器下完成应用层可靠通信,可以结合上面提到的服务容错、治理手段理解。

RPC in Mesh 相对于传统模式有什么优势

  • SDK 分离,避免各个语言重复开发;
  • Docker 的整套体系下,升级会非常容易;
  • 其他调用方式,如 HTTP 也可以轻松地复用服务治理的能力;
  • ...

可选方案

  • Envoy & Istio: 业界使用较多的 Mesh 组合方案
    • Sidecar: Envoy
    • Control Panel: Istio
  • SofaMesh
  • ...

参考资料

  • RPC: Remote Procedure Call Protocol Specification - 1988年4月1050
  • RPC: Remote Procedure Call Protocol Specification Version 2 - May 2009
  • a definition of this new architectural term

插播一条广告。字节跳动诚邀优秀的前端工程师和Node.js工程师加入,一起做有趣的事情,欢迎有意者私信联系,或发送简历至 xujunyu.joey@bytedance.com

校招戳 这里 (同样欢迎实习生同学。

好了,我们下期再会。

http://www.lbrq.cn/news/906319.html

相关文章:

  • 做策划网站推广怎么写简历/各国足球世界排名
  • 保定网站建设方案咨询/seo技术培训广东
  • wordpress建个人网站/百度广告位价格表
  • 电子政务与网站建设经验/seo网课培训
  • 做网站后开办会员/线上广告宣传方式有哪些
  • 怎么做网站公司宣传资料/百度搜索广告价格
  • 域名永久买入要多少钱/自己怎么给网站做优化排名
  • 手机端微网站设计模板/百度官方客服平台
  • 菜鸟是什么网站/win7优化
  • 国内电商网站跳出率是多少/百度搜索风云榜小说总榜
  • 郑州网站推广 汉狮网络/seo查询排名软件
  • 政府网站建设应该/谷歌浏览器下载手机版app
  • 南宁网站建设_seo优化服务公司/it培训班
  • 哈尔滨市松北区政府网/重庆seo网络营销
  • 高新网站开发1年经验/百度普通收录
  • 谷歌优化网站链接怎么做/正规的教育机构有哪些
  • 网站制作需要多长时间/网站内部seo优化包括
  • 德网站建设/免费网站在线观看人数在哪直播
  • 如何购买域名和备案/免费优化网站排名
  • 建网站的外包公司/北京做网站公司哪家好
  • 做网站要多少的分辨率/淘宝app官方下载
  • 网站维护服务基本内容/百度网登录入口
  • 网站被墙怎么做跳转/河南今日头条最新消息
  • 桂城网站建设/2024年4月新冠疫情结束了吗
  • 公司网页制作哪家靠谱/滕州网站建设优化
  • 3340网站建设与管理/网站开发建站
  • firework做网站教程/中国重大新闻
  • 温州做网站公司哪家好/成都seo公司
  • 哪个网站做系统/杭州seo首页优化软件
  • 深圳网站关键词推广/南宁百度网站推广
  • LIN通信协议入门
  • qt 中英文翻译 如何配置和使用
  • 同济医院R语言训练营第三期开讲!上交大张维拓老师主讲
  • AI-Compass LLM训练框架生态:整合ms-swift、Unsloth、Megatron-LM等核心框架,涵盖全参数/PEFT训练与分布式优化
  • HR数字化转型:3大痛点解决方案与效率突破指南
  • [源力觉醒 创作者计划]_文心大模型4.5开源部署指南:从技术架构到实战落地