关于rpc:极光笔记-聊一聊推送系统中事件驱动架构的应用

微服务间通信形式次要有2种:RPC和消息传递。 通常来说在申请/响应的场景下应用RPC更加适合,具体实现通常是REST API或者基于长链接的协定(例如gRPC/Thrift/Zero ICE等)。两个服务有比拟强的依赖关系, 调用者依赖被调用者的处理结果,调用者解决该申请被梗塞以期待响应后果,同时还要进行负载平衡、限流、熔断、错误处理等。通常是同步的、一对一的交互,异步RPC实质也是要期待响应后果能力持续解决该申请。消息传递以异步音讯作为载体,通过事件代理(消息中间件)连贯音讯解决的上游和上游,上游和上游涣散耦合,通常上游的解决逻辑不依赖上游的处理结果,具体实现通常有发布者/订阅者和事件流等。而事件驱动架构(EDA)就是基于消息传递,通过解耦生成、传输和处理事件,协调事件生产者、消息中间件、消费者工作的一种架构模式,具备涣散耦合、流量削峰、非阻塞、易于扩大、更高的弹性和错误处理能力等长处。不过也带来性能损耗、复杂性等方面的问题。 推送零碎的业务状态在推送零碎中,一个推送申请的解决流程大抵如下: 接管申请,进行用户身份认证、参数校验、申请权限校验申请解析,构建推送工作依据推送工作,筛选推送指标用户,以及获取推送指标用户的根本信息依据推送策略以及各推送指标用户的信息抉择推送通道执行推送工作各推送通道负责具体的推送操作。从业务场景看,极光推送均匀每秒接管2万~3万的推送申请,包含regid、tag、alias、播送等推送形式。各推送指标的推送指标用户数量也不同,少则几个,多则几千万甚至上亿的指标数量。极光反对多推送通道,客户能够依据须要抉择应用哪个通道进行推送,各个通道因为服务质量、地区间隔等方面的因素,申请耗时、稳定性各有不同,此外还有各自的限速逻辑。业务面临着很大的挑战: 接管内部推送申请数大,峰值尖刺甚至可能翻倍一个推送申请可能产生大量的音讯,例如一个播送或者一个大tag推送,有千万级别的指标用户,意味着一个推送申请扩充为千万级别的零碎外部申请。整个零碎中同时解决的音讯体量十分大,常态化的业务峰值超过千万级别,并且一天工夫有多个峰值,不可准确预测。解决流程中波及多个解决环节,各个环节的处理速度并不相同,甚至有可能有微小的差别,例如某些推送通道解决快,某些通道推送解决绝对慢。 推送零碎如何应用事件驱动晋升零碎的整体性能从客户的需要和产品需要登程,心愿每个申请可能疾速、正确地响应并解决,可能及时地把音讯推送给每个指标用户。因而咱们须要解决大量音讯以最快的速度推送的问题。 从业务的角度看,能够从租户分级、租户隔离、推送形式、推送指标规模等维度进行部署隔离,减小各租户、各申请间的相互影响,更加疾速更加稳固地解决整个推送申请,提供更好的服务质量。 从纯技术角度看,采纳了多种技术手段和策略,包含缓存优化、异步解决、并行处理等,晋升整体性能,实现更高效的推送操作和更好的零碎稳定性。 其中采纳事件驱动架构来组织整个解决流程,并行、异步解决,实现零碎整体性能的晋升,并且在突增流量、异样解决方面都可能很不便地应答。 推送流程的EDA实现首先,将上述流程简化为多个外围解决环节,并构建为服务,通过消息中间件进行交互。 pushAPI 接管申请,构建推送工作segmentGateway 筛选推送指标用户,抉择推送通道,执行推送工作pushChannel 负责各个推送通道的推送操作,其中蕴含多个具体的推送通道。各服务基于事件传递状态转移 (Event Carried State Transfer)或者事件告诉(Event Notification)模式生成事件音讯,而后投递到消息中间件中。同时各服务通过音讯队列或者订阅的形式从消息中间件生产音讯,依据理论须要由消息中间件推送事件音讯给消费者或者由消费者被动拉取事件音讯。对于反复音讯的解决,通常有Exactly once和At least once +业务幂等性解决,倡议以第二种形式解决。注:消息中间件的选型、音讯投递服务质量的原理不在本文的形容范畴,未开展阐明。 pushAPI接管推送申请,生成推送工作事件音讯,而后投递到消息中间件。消息中间件依据相干信息发送到指定队列中。 segmentGateway生产指定队列,生产其中的事件音讯。通过解决后(查问指标用户和相干根本信息),批量填充各推送通道的指标用户到推送工作,并生成新的推送工作事件音讯投递到消息中间件中。消息中间件依据相干信息发送到各推送通道相干的队列中。 pushChannel的各推送通道服务生产各自的队列,执行推送操作。 以上流程中,事件音讯的生产者不须要消费者的处理结果,消费者也不依赖生产者,齐全解耦。 EDA解决推送零碎的痛点并行处理: 各服务多节点部署,并行处理申请/音讯,当服务呈现性能不足以解决业务时,K8S环境下减少节点正本数横向扩容即可;此外同一个推送申请通过不同推送通道推送时,多个推送通道并行推送音讯。 异步解决: 各服务专一本人的业务逻辑,不依赖业务上游,通常也不受上游的影响,无需期待处理结果,整个流程异步解决,缩小闲暇等待时间,能够最大化利用资源。 异样解决: 当有突增流量时,申请流量压力过大,超过了某个解决环节的所有服务节点的解决能力;或者某个推送通道因为网络抖动、网络中断等解决慢。这些服务节点作为消息中间件的消费者,因为解决能力有余或者解决变慢,未来得及解决的申请沉积在消息中间件,期待扩容或者采取其余解决措施。缓存申请到消息中间件中,从某种程度上也是背压(Back Pressure)模式的一种解决形式,当然还能够进一步的向上游反馈负载压力信息,由上游采取解决措施。例如大量音讯须要推送到苹果的推送服务,因为网络稳定或者苹果服务器限流,可能呈现推送变慢,这个时候推送iOS音讯可能会沉积在消息中间件中;其余推送通道并不受此影响,仍然可能失常地疾速推送音讯给其余通道。其余: 涣散耦合使各服务更加独立,在进行业务变更时(包含代码逻辑变更和公布变更)通常影响面很小,某些状况下甚至可能不影响上下游逻辑,例如某些推送通道没有进行推送速率的限度,当减少限速逻辑时只影响该通道的服务,对于其余通道和上游服务都不影响。借助EDA,极光推送可能轻松解决高并发推送申请,实现数千万级别的音讯的疾速推送,有更大的弹性应答不可预测的、更大流量的音讯推送,以及有更好的异样解决能力。 将来的瞻望:ServiceMesh/EvenMesh混合架构,对立平台化实际上,在极光推送零碎中,同时存在2种通信形式,例如在下面的推送流程中,须要依据推送形式获取推送指标用户以及相干根本信息,须要从其余子系统服务通过RPC进行查问获取后果。整个推送零碎的其余性能也是如此,依据业务场景、数据/业务量级做衡量取舍,抉择适合的架构模式来构建零碎,保证系统整体性能以及零碎的可用性、可维护性。为了让开发者更专一地解决外围的业务代码逻辑,缩小各种通信交互的解决细节(例如超时解决、限流等),目前申请/响应的模式比拟支流的做法是Service Mesh,并且经验了Sidecar/Proxyless/Sidecarless几种模式的倒退,也做了各种衡量取舍。 EDA也有绝对应的模式,Event Mesh就是其中之一,通过创立可能高效牢靠地解决工作的网状代理网络,解决大规模事件驱动架构的挑战,包含事件路由、发现和交付,实现跨简单分布式系统的事件驱动通信。 咱们的推送零碎实际上是混合2个通信形式的架构,更现实、更适宜咱们的架构应该是二者并存。咱们也继续关注相干技术,在充沛验证的状况下引入相干技术,放弃架构继续更新优化,防止架构腐化,保障推送零碎的高性能、高可用性、高可维护性。 对于极光 极光(Aurora Mobile,纳斯达克股票代码:JG)成立于2011年,是中国当先的客户互动和营销科技服务商。成立之初,极光专一于为企业提供稳固高效的音讯推送服务,凭借先发劣势,曾经成长为市场份额遥遥领先的挪动音讯推送服务商。随着企业对客户触达和营销增长需要的不断加强,极光前瞻性地推出了音讯云和营销云等解决方案,帮忙企业实现多渠道的客户触达和互动需要,以及人工智能和大数据驱动的营销科技利用,助力企业数字化转型。

September 26, 2023 · 1 min · jiezi

关于rpc:RPC-调用

什么是RPC调用?和Http申请有什么不同?

August 26, 2023 · 1 min · jiezi

关于rpc:优雅-gRPC-接口调试指南让你事半功倍

目前市面上可能兼容 gRPC 接口的接口调试与管理工具非常无限,而 gRPC 现已广泛应用于微服务架构中,并且能够预感的是,它会变得越来越风行。 作为业界当先的接口管理工具,Apifox 现已上线 gRPC 接口调试能力,全面兼容以下四种调用类型: Unary:一元调用Server Streaming:服务端流Client Streming:客户端流Bidirectional Streaming:双向流兴许你对 gRPC 接口还不太熟悉,那么咱们无妨先来简略理解一下! 什么是 gRPC?gRPC 是一个由谷歌开发的古代开源高性能 RPC 近程过程调用 ( Remote Procedure Calls) 框架,具备良好的兼容性,可在多个开发环境下运行。 gRPC 的利用场景相较于目前支流的 HTTP API 接口,gRPC 接口采纳了当先的 HTTP/2 底层架构设计作为底层传输协定,可能在大规模数据传输场景(例如视频流传输)和大量服务互相调用的微服务架构场景下大展身手。 数据交换采纳轻量化的 Protobuf 序列化协定,使得它可能在资源受限场景(常见于手机等挪动端设施)提供更快的数据处理速度的同时,缩小网络传输的数据量并节俭网络带宽,从而降低功耗并晋升电池寿命。 在正式开始介绍 gRPC 之前,咱们无妨先弄清楚到底什么是 RPC 以及它的作用,这对于后续的了解非常有帮忙。 什么是 RPC?RPC 协定是一种近程过程调用的实现形式。假如当初有两台服务器 A 和 B。部署在 A 服务器上的服务,想调用正在 B 服务器上运行的另一个过程。但因为单方服务并不在一个内存空间而导致无奈间接调用,那么就必须通过网络通讯来达到调用成果。 要建设网络通讯无非是在传输层发动 TCP 连贯。TCP 的握手机制确保了数据包能牢靠地传输给对方,并且它具备以下三个特点:面向连贯、牢靠、基于字节流。后面两种个性都能够胜任这个场景,但唯独在基于字节流这一点恐怕值得商讨。为什么? 因为它没有边界。字节流实质上是在传输层双向通道中流淌的数据,也就是计算机可能了解的二进制 0 1 数据。所以当发送端应用 TCP 发送“南京市”+“长江大桥”字符时,接收端有可能收到的就是“南京市长”+“江大桥”,也有可能是“南京市长江大桥”等。 过于简略的 TCP 连贯过程无奈保障信息的唯一性和确定性,因而才须要在数据中定义音讯头、音讯体,并且发送方与接管方独特认可这套沟通形式,由此衍生出了HTTP 协定和 RPC 调用等计划,它们实质上都是对数据的传递和调用形式作出了规范化定义,避免出现信息失真。 例如当初有一个购物网站,存在订单服务与用户服务(例如账号治理) 两项微服务。订单服务须要查问到用户服务下的一些数据,然而两者相隔离。此时订单服务就必须通过近程调用的形式获取数据。 ...

July 7, 2023 · 1 min · jiezi

关于rpc:GO语言开源API网关

简介开源Apinto API网关具备优异的性能体现、良好的扩展性以及极低的应用和保护老本,Apinto Dashboard 作为配套可视化控制台我的项目,相比于Apinto Dashboard v1.x版本,它提供了优良的用户体验,更加敌对的交互体验,更加简洁的配置流程,操作简略,上手难度极低,更好地帮忙用户和企业简略、疾速、低成本、低危险地实现:零碎微服务化、系统集成、向合作伙伴、开发者凋谢性能和数据。 本次公布亮点性能是插件治理、插件模板两大模块性能。用户可依据集体需要增加插件,并反对集群治理网关插件的生命周期。此外,还提供插件模板治理性能,用户能够将一个或多个API绑定到具备雷同性能的插件模板上。 性能介绍插件治理插件治理帮忙用户治理着网关应用到的插件,基于零碎架构,零碎内置了利用、拜访、熔断、限流、灰度等插件。零碎提供几十款罕用网关插件,用户可依据需要增加插件,删除插件。 插件治理列表插件可通过高低拖动调整插件的程序 ,如果A插件依赖B插件,那么B插件不可拖动到A插件的上方,插件间的程序扭转后,须要在网关集群的插件治理公布插件才会失效。 当该插件在集群是禁用状态且未被插件模板援用时,是反对删除,插件可公布到不同的网关集群失效。 增加插件扩大ID:网关提供的插件ID,同一个插件可被增加屡次成为用户自定义的插件。 依赖插件:要增加的插件是否依赖其余插件才会失效,如服务治理中拜访策略、灰度策略等用到的拜访插件、灰度插件依赖利用插件。 保留:点击保留后,新增加的插件会同步到网关集群的插件治理里,公布状态为未公布,状态为禁用;欲使其在网关集群失效,须要更改状态为启用或全局启用,而后公布到网关集群才会真正失效。 网关集群-插件治理反对批改插件配置和公布,同时反对查看更改历史和公布历史。更多应用教程可参考:https://help.apinto.com/docs/dashboard-v2/basic/cluster.html 插件模板用户能够将一个或多个API绑定到具备雷同性能的插件模板上,公布插件模板到集群失效。更多应用教程可参考:https://help.apinto.com/docs/dashboard-v2/api/plugin-template... API绑定插件模板 总结Apinto网关开箱即用,喜爱或感兴趣的小伙伴们连忙去下载安装体验吧!为了反对Apinto团队提供更好的开源体验,记得fork一下噢。开源地址:https://github.com/eolinker/apinto

April 4, 2023 · 1 min · jiezi

关于rpc:深入浅出RPC服务-不同层的网络协议

导读:本系列文章从RPC产生的历史背景开始解说,波及RPC外围原理、RPC实现、JSF的实现等,通过图文类比的形式分析它的外部世界,让大家对RPC的设计思维有一个宏观的意识。 作者:王禹展   京东衰弱 网络协议为什么须要网络协议?网络协议是为计算机网络中进行数据交换而建设的规定、规范或约定的汇合。 网络中一个微机用户和一个大型主机的操作员进行通信,因为这两个数据终端所用字符集不同,因而操作员所输出的命令彼此不意识。为了能进行通信,规定每个终端都要将各自字符集中的字符先变换为规范字符集的字符后,才进入网络传送,达到目标终端之后,再变换为该终端字符集的字符。就像咱们谈话用某种语言一样,在网络上的各台计算机之间也有一种语言,这就是网络协议,不同的计算机之间必须应用雷同的网络协议能力进行通信。 一次申请都须要用到那些协定?1.要传输数据,首先如何晓得对应的机器的地址?通过IP能够确认具体的机器(网络层的IP层协定)。 2.找到指标机器后,须要晓得该机器上那个程序承受本次申请?通过端口就能确定具体的程序(传输层的TCP层协定)。 3.确定完程序后,怎么辨别不同的申请,每一个申请如何关联对应的响应呢?(应用层的RPC协定)通过音讯id辨别。 4.以上这些最初是由物理层的光缆、电缆、无线信道等反对的,如何管制信号在物理层之上的传递,还须要PPP协定、ARP协定等。 不同层的协定简介 应用层的协定HTTP协定超文本传输协定(Hyper Text Transfer Protocol,HTTP)是一个简略的申请-响应协定,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的音讯以及失去什么样的响应。 HTTPS协定全称:Hyper Text Transfer Protocol over SecureSocket Layer,是以平安为指标的 HTTP 通道,在HTTP的根底上通过传输加密和身份认证保障了传输过程的安全性 。HTTPS 在HTTP 的根底下退出SSL,HTTPS 的平安根底是 SSL,因而加密的具体内容就须要 SSL。 HTTPS 存在不同于 HTTP 的默认端口及一个加密/身份验证层(在 HTTP与 TCP 之间)。这个零碎提供了身份验证与加密通信办法。它被宽泛用于万维网上平安敏感的通信,例如交易领取等方面。 RPC协定一种通过网络从近程计算机程序上申请服务,而不须要理解底层网络技术的协定。 RTMP协定全称:Real Time Messaging Protocol(实时音讯传输协定)。该协定基于TCP,是一个协定族,包含RTMP根本协定及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,次要用来在Flash/AIR平台和反对RTMP协定的流媒体/交互服务器之间进行音视频和数据通信。反对该协定的软件包含Adobe Media Server/Ultrant Media Server/red5等。RTMP与HTTP一样,都属于TCP/IP四层模型的应用层。 P2P协定点对点技术又称对等互联网络技术,是一种网络新技术,依赖网络中参与者的计算能力和带宽,而不是把依赖都汇集在较少的几台服务器上。P2P网络通常用于通过Ad Hoc连贯来连贯节点。这类网络能够用于多种用处,各种档案分享软件曾经失去了宽泛的应用。P2P技术也被应用在相似VoIP等实时媒体业务的数据通信中。 DNS协定DNS是一种能够将域名和IP地址互相映射的以层次结构散布的数据库系统。DNS零碎采纳递归查问申请的形式来响应用户的查问,为互联网的运行提供关键性的根底服务。目前绝大多数的防火墙和网络都会凋谢DNS服务,DNS数据包不会被拦挡,因而能够基于DNS协定建设荫蔽信道,从而顺利穿过防火墙,在客户端和服务器之间传输数据。 GTP协定全称:GPRS隧道协定(GPRSTunnelingProtocol),能够分解成三种独立的协定,GTP-C(管制面)、GTP-U(用户面)及GTP'(计费传输)。GTP-C用于GPRS外围网络中,用于不同网络节点之间的信令数据。GTP-U 用于承载用户数据。 GTP能够用在UDP或TCP上,GTP v1仅用于UDP上。用于 GPRS(2.5代通信技术)、UMTS(3G挪动通信技术)、LTE(3G与4G技术之间的过渡) 和 5G 网络。 DHCP协定全称:Dynamic Host Configuration Protocol(动静主机配置协定),通常被利用在大型的局域网络环境中,次要作用是集中地治理、调配IP地址,使网络环境中的主机动静的取得IP地址、Gateway地址、DNS服务器地址等信息,并可能晋升地址的使用率。 其它协定FTP·、Gopher IMAP4 、 IRC 、 NNTP 、XMPP 、POP3 、SIP 、SMTP 、SNMP 、SSH 、TELNET 、RTCP 、RTP 、RTSP 、 SDP 、 SOAP 、STUN 、 NTP 、SSDP 、BGP等。 ...

March 24, 2023 · 1 min · jiezi

关于rpc:开源API网关APINTO应用管理

问题:公司的业务零碎比拟多,各种业务零碎彼此调用,还有调用了第三方厂商的OpenAPI,当初公司面临着无奈监控这些零碎的调用关系以及调用量统计。 更为要害的是,这些零碎的鉴权不对立,每次开拓一条业务线,新上线零碎必须与其余零碎联调,新加盟的经销商同样面临着这些问题,对研发和运维来说,效率极其低下。 Apinto网关提出利用治理概念,对立治理利用及其生命周期。利用作为业务通信的发起者角色,始终贯通着整个调用链,Apinto网关对利用申请的流量进行鉴权认证,并对其所申请的流量进行服务治理,同时还对其监控告警,统计利用调用状况。 Apinto网关中的利用治理完满解决公司治理各业务零碎所面临的问题,这也是领导赞美Apinto网关的其中一个方面,那接下来就把最近钻研的Apinto的利用治理模块具体介绍一下。 配置:2.1 利用列表网关通过申请流量中的鉴权信息,来辨认是哪个利用,利用必须上线到指定的网关集群且是未禁用状态时才真正失效。   网关对匿名利用和其余利用解决逻辑:当没有利用上线(包含匿名利用),此时不须要鉴权,所有申请被放行。 当有利用上线,此时匿名利用开启上线,此时可鉴权可不鉴权,若鉴权失败,则走匿名应用逻辑。 当有利用上线,此时匿名利用开启上线,且给匿名利用配置了拜访策略,仅容许匿名利用拜访失效范畴内的API,其余API申请都须要利用鉴权。当有利用上线,此时匿名利用禁用下线,此时必须要做鉴权 2.2 配置带有鉴权信息的test利用并上线2.3 下线匿名利用,测试test利用调用状况下线匿名利用并且禁用掉,那么不带test这个利用的鉴权,调用testAPI这个API是调不通的报403,看后果:在申请头加上test利用的鉴权信息,应该能够胜利调用,看后果:测试后果如预期个别,必须带有鉴权信息且是正确的鉴权才能够调用API。下回钻研利用的监控调用统计,到时候分享给大家。 总结:对于公司来说,必须监控谁平安合规调用了业务API,什么时段的调用量。好货色必须关注,好了,省得大家去搜,间接提供github地址。开源地址:https://github.com/eolinker/apinto

March 23, 2023 · 1 min · jiezi

关于rpc:最简最速搭建grpc分布式服务的Mac系统开发环境

[TOC] 环境详情golang 1.18macOS Big Surprotobuf 3基本原理整个RPC过程就是: 客户端 发送 数据(以字节流的形式)服务端接管,并解析。 依据约定晓得要晓得执行什么。而后把后果返回客户端RPC就是把—— 上述过程封装下,使其操作更加优化应用一些大家都认可的协定 使其规范化那么——GRPC框架中采纳了protobuf作为这个过程中消息传递的数据结构。 什么是 ProtobufProtobuf是Protocol Buffers的简称,它是Google公司开发的一种数据描述语言,用于形容一种轻便高效的结构化数据存储格局,并于2008年对外开源。Protobuf能够用于结构化数据串行化,或者说序列化。它的设计十分实用于在网络通讯中的数据载体,很适宜做数据存储或 RPC 数据交换格局,它序列化进去的数据量少再加上以 K-V 的形式来存储数据,对音讯的版本兼容性十分强,可用于通信协定、数据存储等畛域的语言无关、平台无关、可扩大的序列化构造数据格式。开发者能够通过Protobuf附带的工具生成代码并实现将结构化数据序列化的性能。 本教程将在接下来的内容中形容 .proto 文件的语法以及如何通过 .proto 文件生成数据拜访类和 grpc 服务类,并以此为根底搭建繁难的 grpc 服务端开发环境。 工具装置新建工程,抉择 go modules,配置 GOPROXY 等操作不再赘述; 下载grpc依赖go get -u google.golang.org/grpc@v1.51.0brew 装置 protocolbrew install protobuf装置后能够执行命令protoc,作为protocol编译器应用,可能通过两头文件 .proto 转译成各种语言的grpc文件 brew install protoc-gen-go转译两头文件成go文件的插件 brew install protoc-gen-go-grpc转译两头文件成go-grpc文件的插件。 留神:如果装置失败那可能是依赖装置失败,间接brew intall 装置依赖即可。 至此,工具和依赖装置结束,接下来将构建工程。 环境搭建工程 go-rpc-server 构造: . ├── client.go ——用于编写客户端测试 ├── go.mod ├── go.sum ├── main.go ——服务端的启动 ├── pbfiles ——该目录用于搁置原始proto文件 ...

January 13, 2023 · 2 min · jiezi

关于rpc:这次我设计了一款TPS百万级别的分布式高性能可扩展的RPC框架

作者:冰河 博客地址:https://binghe001.github.io 大家好,我是冰河~~ 没错,这次冰河又要搞事件了,这次筹备下手的是RPC框架我的项目。为什么要对RPC框架我的项目下手呢,因为在现在分布式、微服务乃至云原生一直倒退的过程中,RPC作为底层必不可少的通信组件,被广泛应用在分布式、微服务和云原生我的项目中。 为啥要开发RPC框架事件是这样的,在开发这个RPC框架之前,我破费了不少工夫算是对Dubbo框架彻底钻研透彻了。 冰河在撸透了Dubbo2.x和Dubbo3.x的源码之后,原本想给大家写一个Dubbo源码解析的专栏。为此,我其实私下筹备了一个多月:画流程图、剖析源码、写测试Demo,本人在看Dubbo源码时,也为Dubbo源码增加了十分具体的正文。这里,就蕴含Dubbo2.x和Dubbo3.x的源码。 当我就这么熬夜肝文一个多月后,忽然发现一个问题:Dubbo通过多年一直的迭代开发,它的源码曾经十分多了,如果以文章的模式将Dubbo的源码八面玲珑的剖析到位,那还不晓得要写到何年何月去了。当我写文章剖析Dubbo的最新版本3.x时,可能写到专栏的中后期Dubbo曾经更新到4.x、5.x,设置有可能是6.x、7.x了。 与其这么吃力吧咧的剖析源码,还不如从零开始带着大家一起手撸一个可能在理论生产环境应用的、分布式、高性能、可扩大的RPC框架。这样,大家也可能直观的感触到一个可能在理论场景应用的RPC框架是如何一步步开发进去的。 置信大家在学完《RPC手撸专栏》后,本人再去看Dubbo源码的话,就相对来说简略多了。你说是不是这样的呢? 你能学到什么?既然是整个专栏的开篇嘛,必定是要通知你在这个专栏中可能学习到哪些实用的技术的。这里,我就画一张图来直观的通知你在《RPC手撸专栏》可能学到哪些技术吧。 《RPC手撸专栏》整体框架技术全貌如图所示,退出星球后与冰河一起从零实现它,搞定它,当你紧跟冰河节奏搞定这个RPC框架后,你会发现:什么Dubbo、什么gRPC、什么BRPC、什么Hessian、什么Tars、什么Thrift、什么motan、什么hprose等等等等,市面上支流的RPC框架,对你来说就都不叫事儿了,跟紧冰河的节奏,你能够的。 置信小伙伴们看到《RPC手撸专栏》波及到的知识点,应该可能理解到咱们这个从零开始的《RPC手撸专栏》还是比拟硬核的吧? 另外,咱这RPC我的项目反对同步调用、异步调用、回调和单向调用。 同步调用异步调用 回调 单向调用 对,没错,咱们《RPC手撸专栏》最终实现的RPC框架的定位就是尽量能够在理论环境应用。通过这个专栏的学习,让大家深刻理解到可能在理论场景应用的RPC框架是如何一步步开发进去的。 代码构造我将这个bhrpc我的项目的定位为可在理论场景应用的、分布式、高性能、可扩大的RPC框架,目前总体上曾经开发并欠缺的性能达到60+个子我的项目,大家看图吧。 我的项目大量应用了对标Dubbo的自定义SPI技术实现高度可扩展性,各位小伙伴能够依据本人的须要,依照SPI的设计要求增加本人实现的自定义插件。 演示成果说了那么多,咱们一起来看看这个RPC框架的应用成果吧,因为咱们这个RPC框架反对的调用形式有:原生RPC调用、整合Spring(XML/注解)、整合SpringBoot、整合SpringCloud、整合SpringCloud Alibaba,整合Docker和整合K8S七种应用形式。 这里,咱们就以 整合Spring注解的形式 来给大家演示下这个RPC框架。 RPC外围注解阐明为了让大家更好的理解这个RPC框架,我先给大家看下RPC框架的两个外围注解,一个是RPC的服务提供者注解@RpcService,一个是RPC的服务调用者注解@RpcReference。 (1)服务提供者注解@RpcService的外围源码如下所示。 /** * @author binghe * @version 1.0.0 * @description bhrpc服务提供者注解 */@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Componentpublic @interface RpcService { /** * 接口的Class */ Class<?> interfaceClass() default void.class; /** * 接口的ClassName */ String interfaceClassName() default ""; /** * 版本号 */ String version() default "1.0.0"; /** * 服务分组,默认为空 */ String group() default ""; /** * 提早公布,预留 */ int delay() default 0; /** * 是否导出rpc服务,预留 */ boolean export() default true;}(2)服务调用者注解@RpcReference的外围源码如下所示。 ...

August 24, 2022 · 3 min · jiezi

关于rpc:基于RPC接口的业务侧流量回放

背 景\在产品需要迭代过程中,功能测试与回归测试是必不可少的两个环节。对于改变较大的我的项目,首先,确保性能的实现合乎产品逻辑并做到100%没有问题离不开无效的功能测试;其次,我的项目中很多逻辑的改变都是在原有性能的根底上进行的,这时候就须要肯定的回归测试。通常,在功能测试时,人工case不能模仿线上用户的所有行为,且具备肯定的主观性;回归测试时,采纳全面回归的形式往往也随同着测试老本的减少。一个好的形式就是利用线上流量来验证。 一方面,通过记录线上流量,在沙箱或者测试环境回放,来发现新分支代码是否可能让零碎性能失常运行,从而升高代码变动给整体零碎带来的危险;另一方面,通过线上流量进行线下回归测试能够在保障全面回归的状况下无效的节约测试老本。 简 介流量回放应用实在的线上流量进行线下回放测试,节约回归测试老本,保障代码品质,进而缩小线上事变。 流量平台搭建老本全链路流量平台具备的能力 能录制线上实在流量;能实现海量数据的并发申请;能反对常见协定的申请;对线上尽量利用通明,也就是说无侵入性;工具应用简略,可能满足各场景流量回放。 能够看出依照以上的能力需要搭建一个流量平台须要投入肯定的老本,而咱们目前思考的是针对某一个我的项目的疾速流量回放,可能并不需要设计这么简单并且重量级的流量平台。那么,如何疾速的实现满足业务需要的流量回放呢?基于RPC接口的流量回放,简略、快捷、容易上手。接下来我将通过理论的业务场景来介绍下流量回放在采货侠卖场侧的业务利用。流量回放的利用1、我的项目背景采货侠卖场侧新增后盾配置性能且还波及到对成拍逻辑的改变,须要验证新性能的正确性并对多种成单场景进行肯定的回归测试。 回归工作量大须要无效的伎俩进步测试效率;成单逻辑不容出错须要100%的保障。 2、 计划流量回放 回归测试:应用实在的线上流量进行线下回放测试,比照不反对议价性能的商品线上、线下成单后果的一致性;功能测试:应用实在的线上流量进行线下新性能的验证。线上放弃原有Apollo配置逻辑,线下利用新开发经营后盾的配置性能。放弃雷同配置利用线上流量数据通过新开发分支代码运行获取相应的成单后果,验证补贴后盾和议价后盾性能的正确性。 长处 能够高度联合业务逻辑,实现细粒度定制化流量复制;解放局部回归测试的人力老本,晋升测试效率;对业务的用例场景更加主观,保障代码品质,进而缩小线上事变。 3、外围性能流量采集 通过云窗获取相应要求的线上商品信息以及对应的最高出价和成单后果将云窗所得线上数据的相干信息写入到数据库对应的字段中 流量回放 代码设计逻辑 首先,通过读取线上商品的保底价映射成雷同价格的线下商品参拍暗拍卖场,接着模仿用户在采货侠卖场中的实在行为进行流量回放,并将线下的商品数据和成单后果写入数据库表;整个过程中采纳了多线程以及数据库表批量减少、查找来进步运行效率。 数据存储后果 表中线上、线下数据一一对应存储,清晰、明了有利于后果剖析。 后果剖析后果剖析思路:调用开发分支在测试环境进行流量回放,失去相应的冀望后果后和线上同一商品的相应后果进行比拟,判断后果是否统一。校验的字段可依据理论需要场景进行相应的变更,在本次案例中验证的字段是成单后果和补贴金额。 回归测试验证逻辑 读取不议价商品的流量回放成单后果和线上相应数据的成单后果进行比照,判断后果是否统一。如下图所示为成单验证后果:线上和线下的成单后果全副是统一的,这阐明新需要代码的开发未影响到原有不议价商品成单逻辑的正确性。此外,采纳该办法进行测试使原打算进行回归测试的工夫缩短了3倍多,这无效的节约了回归测试的老本。 功能测试验证逻辑 为了做进一步的性能保障。通过获取线上实在的用户流量,在保障线上原有配置和线下经营后盾统一的状况下,调用新分支代码实现线下流量回放失去相应的预期后果,而后和线上后果进行比对。首先,比照线上、线下成单后果是否统一来验证成单逻辑的正确性;其次通过比拟线上、线下补贴金额是否统一来验证经营后盾补贴配置性能的正确性。本次验证不关怀成单后商品的状态流转,而线上局部商品状态曾经流转,所以验证成单后果时,能够把生成订单后流转的一些状态重置为成单状态和线下成单后果进行比对。逻辑如下: 验证后果如下: 首次验证后果中呈现了局部商品线上、线下成单后果不统一,需进一步剖析解决问题1: 线下局部商品状态始终在售卖中起因: 有局部商品调用完结竞拍没有胜利解决: 商品调用完结竞拍失败后持续从新调用问题2: 线上商品成单,线下商品却是流拍起因: 线下经营后盾局部价格段的设置没有和线上的保持一致解决: 保障线上、线下各价格段补贴、议价金额统一确保线上、线下配置统一的状况下,应用优化后的代码从新进行流量回放,能够失去雷同成单后果和补贴后果。阐明经营后盾配置性能的代码实现以及成单逻辑都是正确的。

August 19, 2022 · 1 min · jiezi

关于rpc:面试官让我手写一个RPC框架

现在,分布式系统大行其道,RPC 有着无足轻重的位置。Dubbo、Thrift、gRpc 等框架各领风骚,学习RPC是老手也是老鸟的必修课。本文带你手撸一个rpc-spring-starter,深刻学习和了解rpc相干技术,包含但不限于 RPC 原理、动静代理、Javassist 字节码加强、服务注册与发现、Netty 网络通讯、传输协定、序列化、包压缩、TCP 粘包、拆包、长连贯复用、心跳检测、SpringBoot 主动装载、服务分组、接口版本、客户端连接池、负载平衡、异步调用等常识,值得珍藏。RPC定义近程服务调用(Remote procedure call)的概念历史已久,1981年就曾经被提出,最后的目标就是为了调用近程办法像调用本地办法一样简略,经验了四十多年的更新与迭代,RPC 的大体思路曾经趋于稳定,现在百家争鸣的 RPC 协定和框架,诸如 Dubbo (阿里)、Thrift(FaceBook)、gRpc(Google)、brpc (百度)等都在不同侧重点去解决最后的目标,有的想极致完满,有的谋求极致性能,有的偏差极致简略。 RPC基本原理让咱们回到 RPC 最后的目标,要想实现调用近程办法像调用本地办法一样简略,至多要解决如下问题: 如何获取可用的近程服务器如何示意数据如何传递数据服务端如何确定并调用指标办法上述四点问题,都能与当初分布式系统炽热的术语一一对应,如何获取可用的近程服务器(服务注册与发现)、如何示意数据(序列化与反序列化)、如何传递数据(网络通讯)、服务端如何确定并调用指标办法(调用办法映射)。笔者将通过一个简略 RPC 我的项目来解决这些问题。 首先来看 RPC 的整体零碎架构图: 图中服务端启动时将本人的服务节点信息注册到注册核心,客户端调用近程办法时会订阅注册核心中的可用服务节点信息,拿到可用服务节点之后近程调用办法,当注册核心中的可用服务节点发生变化时会告诉客户端,防止客户端持续调用曾经生效的节点。那客户端是如何调用近程办法的呢,来看一下近程调用示意图: 客户端模块代理所有近程办法的调用将指标服务、指标办法、调用指标办法的参数等必要信息序列化序列化之后的数据包进一步压缩,压缩后的数据包通过网络通信传输到指标服务节点服务节点将承受到的数据包进行解压解压后的数据包反序列化成指标服务、指标办法、指标办法的调用参数通过服务端代理调用指标办法获取后果,后果同样须要序列化、压缩而后回传给客户端通过以上形容,置信读者应该大体上理解了 RPC 是如何工作的,接下来看如何应用代码具体实现上述的流程。鉴于篇幅笔者会抉择重要或者网络上介绍绝对较少的模块来讲述。 RPC实现细节1. 服务注册与发现作为一个入门我的项目,咱们的零碎选用 Zookeeper 作为注册核心, ZooKeeper 将数据保留在内存中,性能很高。在读多写少的场景中尤其实用,因为写操作会导致所有的服务器间同步状态。服务注册与发现是典型的读多写少的协调服务场景。Zookeeper 是一个典型的CP零碎,在服务选举或者集群半数机器宕机时是不可用状态,绝对于服务发现中支流的AP零碎来说,可用性稍低,然而用于了解RPC的实现,也是入不敷出。 ZooKeeper节点介绍长久节点( PERSISENT ):一旦创立,除非被动调用删除操作,否则始终长久化存储。长期节点( EPHEMERAL ):与客户端会话绑定,客户端会话生效,这个客户端所创立的所有长期节点都会被删除除。节点程序( SEQUENTIAL ):创立子节点时,如果设置SEQUENTIAL属性,则会主动在节点名后追加一个整形数字,下限是整形的最大值;同一目录下共享程序,例如(/a0000000001,/b0000000002,/c0000000003,/test0000000004)。ZooKeeper服务注册在 ZooKeeper 根节点下依据服务名创立长久节点 /rpc/{serviceName}/service ,将该服务的所有服务节点应用长期节点创立在 /rpc/{serviceName}/service 目录下,代码如下(为不便展现,后续展现代码都做了删减): public void exportService(Service serviceResource) { String name = serviceResource.getName(); String uri = GSON.toJson(serviceResource); String servicePath = "rpc/" + name + "/service"; zkClient.createPersistent(servicePath, true); String uriPath = servicePath + "/" + uri; //创立一个新的长期节点,当该节点宕机会话生效时,该长期节点会被清理 zkClient.createEphemeral(uriPath);}注册成果如图,本地启动两个服务则 service 下有两个服务节点信息: ...

July 21, 2022 · 6 min · jiezi

关于rpc:哈希趣投游戏系统开发逻辑源码搭建哈希游戏开发系统方案程序代码

 Hash,个别翻译做“散列”,也有间接音译为“哈希”的(刘森:I8O薇2857電8624掂)就是把任意长度的输出(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输入,该输入就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输出的空间,不同的输出可能会散列成雷同的输入,而不可能从散列值来惟一的确定输出值。简略的说就是一种将任意长度的消息压缩到某一固定长度的音讯摘要的函数。 散列函数能使对一个数据序列的拜访过程更加迅速无效,通过散列函数,数据元素将被更快地定位。罕用Hash函数有: 1.间接寻址法。取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key)=a·key+b,其中a和b为常数(这种散列函数叫做本身函数) 2.数字分析法。剖析一组数据,比方一组员工的出生年月日,这时咱们发现出生年月日的前几位数字大体雷同,这样的话,呈现抵触的几率就会很大,然而咱们发现年月日的后几位示意月份和具体日期的数字差异很大,如果用前面的数字来形成散列地址,则抵触的几率会明显降低。因而数字分析法就是找出数字的法则,尽可能利用这些数据来结构抵触几率较低的散列地址。 3.平方取中法。取关键字平方后的两头几位作为散列地址。 4.折叠法。将关键字宰割成位数雷同的几局部,最初一部分位数能够不同,而后取这几局部的叠加和(去除进位)作为散列地址。 5.随机数法。抉择一随机函数,取关键字作为随机函数的种子生成随机值作为散列地址,通常用于关键字长度不同的场合。 6.除留余数法。取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即H(key)=key MOD p,p<=m。不仅能够对关键字间接取模,也可在折叠、平方取中等运算之后取模。对p的抉择很重要,个别取素数或m,若p选的不好,容易产生碰撞。 public class ConsistentHashingWithoutVirtualNode{ //待增加入Hash环的服务器列表 private static String[]servers={"192.168.0.1:8888","192.168.0.2:8888", "192.168.0.3:8888"}; //key示意服务器的hash值,value示意服务器 private static SortedMap<Integer,String>sortedMap=new TreeMap<Integer,String>(); //程序初始化,将所有的服务器放入sortedMap中 static{ for(int i=0;i<servers.length;i++){ int hash=getHash(servers); System.out.println("["+servers+"]退出汇合中,其Hash值为"+hash); sortedMap.put(hash,servers); } } //失去该当路由到的结点 private static String getServer(String key){ //失去该key的hash值 int hash=getHash(key); //失去大于该Hash值的所有Map SortedMap<Integer,String>subMap=sortedMap.tailMap(hash); ...

June 7, 2022 · 1 min · jiezi

关于rpc:大厂学苑-RPC框架核心源码深度解析

大厂学苑 -RPC框架外围源码深度解析超清原画 残缺无密 包含所有视频课件以及源码 MP4格局 获取ZY:网盘链接hashCode() 和 equals()的区别equals()equals() 方法用于比较两个对象是否相等,它与 == 相等比较符有着本质的不同。 在万物皆对象的 Java 体系中,零碎把判断对象是否相等的权力交给程序员。具体的措施是把 equals() 方法写到 Object 类中,并让所有类继承 Object 类。 这样程序员就能在自定义的类中重写 equals() 方法, 从而实现自己的比较逻辑。 hashCode()hashCode() 的意义是哈希值, 哈希值是经哈希函数运算后失去的后果,哈希函数能够保障雷同的输出能够失去雷同的输入(哈希值),然而不能够保障不同的输出总是能得出不同的输入。 当输出的样本量足够大时,是会产生哈希冲突的,也就是说不同的输出产生了雷同的输入。 暂且不谈冲突,就雷同的输出能够产生雷同的输入这点而言,是及其宝贵的。它使得零碎只需要通过简略的运算,在工夫复杂度O(1)的情况下就能得出数据的映射关系,根据这种个性,散列表应运而生。 一种支流的散列表实现是:用数组作为哈希函数的输入域,输出值通过哈希函数计算后失去哈希值。而后根据哈希值,在数组种找到对应的存储单元。当发生冲突时,对应的存储单元以链表的形式保存冲突的数据。 两者关系在大多数编程实践中,归根结底会落实到数据的存取问题上。 在汇编语言期间,你需要老诚恳实地对每个数据操作编写存取语句。 而随着期间发展到明天,咱们都用更便利灵活的高级语言编写代码,比如 Java。 Java 以面向对象为中心思想,封装了一系列操作数据的 api,升高了数据操作的复杂度。 但在咱们对数据进行操作之前,首先要把数据按照肯定的数据结构保存到存储单元中,否则操作数据将无从谈起。 然而不同的数据结构有各自的个性,咱们在存储数据的时候需要抉择合适的数据结构进行存储。 Java 根据不同的数据结构提供了丰富的容器类,便利程序员抉择适合业务的容器类进行开发。 通过继承关系图咱们看到 Java 的容器类被分为 Collection 和 Map 两大类,Collection 又可能进一步分为 List 和 Set。 其中 Map 和 Set 都是不容许元素重复的,严格来说Map存储的是键值对,它不容许重复的键值。 值得注意的是:Map 和 Set 的绝大多数实现类的底层都会用到散列表结构。 讲到这里咱们提取两个关键字不容许重复和散列表结构, 回顾 hashCode() 和 equals() 的个性,你是否想到了些什么货色呢?equals()力不从心下面提到 Set 和 Map 不存放重复的元素(key),这些容器在存储元素的时必须对元素做出判断:在以后的容器中有没有和新元素雷同的元素? ...

May 1, 2022 · 1 min · jiezi

关于rpc:RPCX源码学习server端

意识RPCRPC是什么货色? RPC: Remote Procedure Call(近程过程调用),是一个计算机通信协议。协定的次要内容是什么? 该协定容许运行于一台计算机中的程序调用另一个地址空间(通常为一个凋谢网络中的一台计算机)的子程序,而程序员就像调用本地程序一样,无需额定的为这个交互作用编程(无需关注细节)。次要用来解决什么问题? 解决分布式系统中服务之间的调用问题。 使近程调用像本地办法调用一样不便,暗藏底层网络通信的复杂性,使咱们更专一于业务。一次rpc通信会波及到哪些角色?流程是什么样的? client: 客户端程序,调用的发起者 client-stub: 将调用参数和办法依照约定的协定进行编码,而后传输到server server: 服务端程序,解决client的调用 server-stub: 收到client的音讯后,依照约定的协定进行解码,而后调用本地办法进行解决 RPCX框架简介rpcx是一个分布式的RPC框架,由go语言开发,反对Zookepper、etcd、consul多种服务发现形式,多种服务路由形式,是目前性能最好的RPC框架之一。 详情见官网介绍: https://books.studygolang.com...server端源码分析从入口开始,咱们启动一个rpc服务时,须要通过NewServer办法去创立一个Server对象,源码如下: // NewServer returns a server.func NewServer(options ...OptionFn) *Server { s := &Server{ // 创立一个Server对象,给一些字段赋默认值 Plugins: &pluginContainer{}, options: make(map[string]interface{}), activeConn: make(map[net.Conn]struct{}), doneChan: make(chan struct{}), serviceMap: make(map[string]*service), router: make(map[string]Handler), AsyncWrite: false, // 除非你想benchmark或者极致优化,否则倡议你设置为false } for _, op := range options { op(s) } // 设置tcp连贯的keepAlive参数 if s.options["TCPKeepAlivePeriod"] == nil { s.options["TCPKeepAlivePeriod"] = 3 * time.Minute } return s}Server构造如下: ...

April 21, 2022 · 7 min · jiezi

关于rpc:NextRPC-RPC多段返回的创新和探索

作者:吴欣蔚(蓄昂) NextRPC 是对 RPC 申请模式的翻新和摸索,它能够像多级火箭一样,返回 Payload 多段数据,从不同的网络通道申请/应答多段返回,最终实现业务场景交付。外面的“Next”有双关的意思: 外围的区别于传统 RPC,申请的特点是让申请响应以流式多段返回给客户端,在流式的语义外面数据不停地通过 Next -> Next -> Next 的模式来响应;Next 有下一代的意思,NextRPC 是传统单响应的下一代 RPC 模式。目前,NextRPC 曾经在手淘的局部交易场景上线,如:下单换购业务在2021年4月初上线,经验9.9、11.11两次大促,业务模式曾经稳固。在2021年的双十一大促中,通过 NextRPC 链路给业务整体带来超过5%的 uv 转化晋升,在多商品中抉择一个最优商品透出的场景下,uv 转化晋升达25%以上。 业务背景在一些交易外围链路如 购物车、订单 等场景,冀望引入导购链路的举荐算法,基于店铺维度针对单品、多品SKU、跨店场景进行个性化举荐,推出如“棘手买一件”的个性化举荐产品 或 其余优惠信息的透出,晋升uv转化率。 问题与挑战当 外围交易场景 遇上 个性化举荐 ,交易 和 导购 的场景碰撞,会产生以下新的问题: 用户体验的抵触:个性化举荐算法服务RT高,不满足外围交易链路对RT的要求;服务质量的抵触:引入个性化举荐,会使得交易链路的上游零碎变得更加简单,对系统的稳定性带来新的挑战;同时,导购链路的「个性化举荐业务」容忍局部不确定性(如申请超时/失败),而「外围交易链路」则对稳定性和确定性要求极高,每一次的失败可能都会错失交易;机器资源的抵触:交易、导购 的多地部署构造不一样,机器容量和散布存在差异化。上述的这些问题,引出了新的技术挑战:如何在一次申请中同时反对对「用户体验」、「服务质量」、「资源」要求不一样的多个业务撑持零碎。 技术选型1、RPC模式分析以下针对五种常见的RPC模型开展比照剖析: 2、申请解决模型剖析申请解决模型次要剖析 串行解决、并行处理两种模型。 串行解决:数据的依赖深度决定了整体可优化的最小rt;并行处理:通过并行化(并发度n),来将对应档次上的rt升高为原来的 max(RTn)。 3、NextRPC的多段返回模式NextRPC联合了 单申请异步推送数据流 的RPC模式和 并行处理 的申请解决模型,解决了新的业务场景带来的挑战: 单申请异步推送数据流:-能够将 外围业务逻辑 和 非核心业务逻辑 解耦,保障外围数据同步响应,非核心数据异步响应,解决服务质量问题; -交易链路、导购链路逻辑解耦,外部跨利用调用,解决机器资源问题; 并行处理:-业务逻辑可并行化解决,节俭串行等待时间,解决交易链路用户体验问题。 NextRPC架构1、客户端架构技术架构网络层,抹平Mtop/Accs通道,对业务通明;数据整流层,管制 单个申请多个返回的时序(其中异步副返回蕴含了异步的业务数据流);数据编排层,管制 多申请间 异步数据的合并。 数据流和多实例一个页面反对多个 NextRPC 实例,多页面可创立多个 NextRPC 实例;一个 NextRPC 实例可进行多个不同申请,接管不同的副响应推送。 ...

March 14, 2022 · 1 min · jiezi

关于rpc:RPC基础概念问答

RPC 原理图 上面的两张原理图是一样的。从第一张原理图中能够看到 rpc 传输过程中应用的传输协定,从第二张原理图中 sockets 是在 Kernel 中,也就是在操作系统的内核中。 什么是RPC?? 近程过程调用。一个服务器应用另一台服务器上的提供的服务或办法。 RPC 解决的什么问题?? 让分布式或微服务零碎中不同服务之间的调用像本地调用一样简略。 为什么要应用 RPC?? 因为两个服务器不是同一个操作系统,也不在一个内存空间,所以不能间接调用,须要通过网络来传递数据。 RPC 怎么解决通信?? 在客户端和服务器之间建设 TCP 连贯,rpc 所有传输的数据都在 TCP 连贯中传输。连贯能够是按需连贯,调用完结后就断开,也能够是和长连贯,多个rpc 共享同一个连贯。 因为客户端和服务器是通过网络进行传输的,所以须要一个传输层,把函数id和序列化后的参数传递给服务器,并把序列化后的调用后果传回客户端。所以 TCP(大部分框架应用)和UDP都能够,也能够应用 http2(grpc应用) RPC 怎么解决寻址的问题?? 客户端上的利用通知 rpc 框架,服务器的主机/IP地址、端口号、办法名称,这样就能够实现调用。 网络协议是基于二进制的,内存中的参数的值须要序列化成二进制的模式。 服务器收到申请后,要对参数进行反序列化,把二进制变成内存中的参数,把参数复原成内存中的表达方式,而后找到对应的办法(寻址的一部分),进行本地调用,失去返回值。 服务器将返回值(序列化后)发给客户端,客户端收到返回值后,进行反序列化,而后传递给它下面的利用。 java的序列化形式:json。 RPC 和 socket 的区别?? socket是两个主机不同过程之间进行通信的形式。 rpc 是建设在 socket 之上的。rpc 通过 socket 实现通信, 也能够不必 socket,而应用其余的通信形式,比方命名管道(windows零碎中)。 RPC 和 HTTP 的分割和区别?? http 协定是应用层的协定。http 是实现 rpc 的一种形式。能够应用 http 协定,也能够应用 TCP / UDP 协定。 ...

January 20, 2022 · 1 min · jiezi

关于rpc:java-从零开始手写-RPC-02netty4-实现客户端和服务端

阐明上一篇代码基于 socket 的实现非常简单,然而对于理论生产,个别应用 netty。 至于 netty 的长处能够参考: 为什么抉择 netty?http://houbb.github.io/2019/05/10/netty-definitive-gudie-04-why-netty 代码实现maven 引入<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>${netty.version}</version></dependency>引入 netty 对应的 maven 包,此处为 4.1.17.Final。 服务端代码实现netty 的服务端启动代码是比拟固定的。 package com.github.houbb.rpc.server.core;import com.github.houbb.log.integration.core.Log;import com.github.houbb.log.integration.core.LogFactory;import com.github.houbb.rpc.server.constant.RpcServerConst;import com.github.houbb.rpc.server.handler.RpcServerHandler;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.*;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;/** * rpc 服务端 * @author binbin.hou * @since 0.0.1 */public class RpcServer extends Thread { private static final Log log = LogFactory.getLog(RpcServer.class); /** * 端口号 */ private final int port; public RpcServer() { this.port = RpcServerConst.DEFAULT_PORT; } public RpcServer(int port) { this.port = port; } @Override public void run() { // 启动服务端 log.info("RPC 服务开始启动服务端"); EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(workerGroup, bossGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) throws Exception { ch.pipeline().addLast(new RpcServerHandler()); } }) // 这个参数影响的是还没有被accept 取出的连贯 .option(ChannelOption.SO_BACKLOG, 128) // 这个参数只是过一段时间内客户端没有响应,服务端会发送一个 ack 包,以判断客户端是否还活着。 .childOption(ChannelOption.SO_KEEPALIVE, true); // 绑定端口,开始接管进来的链接 ChannelFuture channelFuture = serverBootstrap.bind(port).syncUninterruptibly(); log.info("RPC 服务端启动实现,监听【" + port + "】端口"); channelFuture.channel().closeFuture().syncUninterruptibly(); log.info("RPC 服务端敞开实现"); } catch (Exception e) { log.error("RPC 服务异样", e); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } }}为了简略,服务端启动端口号固定,RpcServerConst 常量类内容如下: ...

October 9, 2021 · 3 min · jiezi

关于rpc:java-从零开始手写-RPC-01-基于-websocket-实现

RPC解决的问题RPC 次要是为了解决的两个问题: 解决分布式系统中,服务之间的调用问题。近程调用时,要可能像本地调用一样不便,让调用者感知不到近程调用的逻辑。这一节咱们来学习下如何基于 websocket 实现最简略的 rpc 调用,后续会实现基于 netty4 的版本。 开源地址: https://github.com/houbb/rpc残缺流程 其中右边的Client,对应的就是后面的Service A,而左边的Server,对应的则是Service B。 上面一步一步具体解释一下。 Service A的应用层代码中,调用了Calculator的一个实现类的add办法,心愿执行一个加法运算;这个Calculator实现类,外部并不是间接实现计算器的加减乘除逻辑,而是通过近程调用Service B的RPC接口,来获取运算后果,因而称之为Stub;Stub怎么和Service B建设近程通信呢?这时候就要用到近程通信工具了,也就是图中的Run-time Library,这个工具将帮你实现近程通信的性能,比方Java的Socket,就是这样一个库,当然,你也能够用基于Http协定的HttpClient,或者其余通信工具类,都能够,RPC并没有规定说你要用何种协定进行通信;Stub通过调用通信工具提供的办法,和Service B建设起了通信,而后将申请数据发给Service B。须要留神的是,因为底层的网络通讯是基于二进制格局的,因而这里Stub传给通信工具类的数据也必须是二进制,比方calculator.add(1,2),你必须把参数值1和2放到一个Request对象外头(这个Request对象当然不只这些信息,还包含要调用哪个服务的哪个RPC接口等其余信息),而后序列化为二进制,再传给通信工具类,这一点也将在上面的代码实现中体现;二进制的数据传到Service B这一边了,Service B当然也有本人的通信工具,通过这个通信工具接管二进制的申请;既然数据是二进制的,那么天然要进行反序列化了,将二进制的数据反序列化为申请对象,而后将这个申请对象交给Service B的Stub解决;和之前的Service A的Stub一样,这里的Stub也同样是个“假玩意”,它所负责的,只是去解析申请对象,晓得调用方要调的是哪个RPC接口,传进来的参数又是什么,而后再把这些参数传给对应的RPC接口,也就是Calculator的理论实现类去执行。很显著,如果是Java,那这里必定用到了反射。RPC接口执行结束,返回执行后果,当初轮到Service B要把数据发给Service A了,怎么发?一样的情理,一样的流程,只是当初Service B变成了Client,Service A变成了Server而已:Service B反序列化执行后果->传输给Service A->Service A反序列化执行后果 -> 将后果返回给Application,结束。简略实现假如服务 A,想调用服务 B 的一个办法。 因为不在同一个内存中,无奈间接应用。如何能够实现相似 Dubbo 的性能呢? 这里不须要应用 HTTP 级别的通信,应用 TCP 协定即可。 common专用模块,定义通用对象。 Rpc 常量public interface RpcConstant { /** * 地址 */ String ADDRESS = "127.0.0.1"; /** * 端口号 */ int PORT = 12345;}申请入参public class RpcCalculateRequest implements Serializable { private static final long serialVersionUID = 6420751004355300996L; /** * 参数一 */ private int one; /** * 参数二 */ private int two; //getter & setter & toString()}服务接口public interface Calculator { /** * 计算加法 * @param one 参数一 * @param two 参数二 * @return 返回后果 */ int add(int one, int two);}server服务接口的实现public class CalculatorImpl implements Calculator { @Override public int add(int one, int two) { return one + two; }}启动服务public static void main(String[] args) throws IOException { Calculator calculator = new CalculatorImpl(); try (ServerSocket listener = new ServerSocket(RpcConstant.PORT)) { System.out.println("Server 端启动:" + RpcConstant.ADDRESS + ":" + RpcConstant.PORT); while (true) { try (Socket socket = listener.accept()) { // 将申请反序列化 ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream()); Object object = objectInputStream.readObject(); System.out.println("Request is: " + object); // 调用服务 int result = 0; if (object instanceof RpcCalculateRequest) { RpcCalculateRequest calculateRpcRequest = (RpcCalculateRequest) object; result = calculator.add(calculateRpcRequest.getOne(), calculateRpcRequest.getTwo()); } // 返回后果 ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); objectOutputStream.writeObject(result); } catch (Exception e) { e.printStackTrace(); } } }}启动日志: ...

October 8, 2021 · 2 min · jiezi

关于rpc:B端产品业务

B端的日常场景B端设计的技术:编程语言;数据,数据库,数据仓库,关系型非关系型;客户端技术:PC,安卓,服务端B端正真要思考的流程是什么,怎么更好的服务企业:工作中波及的所有的都要思考.客户不明确的也无需要,商业需要,对于含糊两可的需要,如何召开业务调研:1.专家势力推给客户;2.密集确认(口头复数,文字描述,demo);3.多方推动(找干系人各个击破);4.分步施行,拆分对于B端的定制产品和根底标品的两条铲平线的产品经理侧重点有什么不同:规范是共产主义,定制是米饭咸菜;标准化能力是本身技能的晋升,价值的发明.做得是内容风控的审核台,方向过于窄了,想拓展:举一反三,多看多学axure原型对于B端产品经理更重要:都重要,传递信息工具,能传递分明都行1.客户定制化需要把规范产品改的面目全非;2.没有成就感:1.需要解决,满足客户需要的同时,零碎架构更加正当;2.不能仅仅听业务的1.我的项目进入开发阶段后,因为业务流程比较复杂,不分明流程图该精密到什么水平,是否每个判断都须要变现进去;2.想进步B端产品的外围竞争力,在哪方面花工夫:1.风控;如果必要风控独自画一个2.行业教训,业务知识,产品技能B端是否真的没有想C端那么看重用户体验:与c段相比要弱一些我的项目开发如何做到精确评估需要,并实现客户称心: 开始不会准,逐步精确.;客户称心是另一回事,干系人冀望治理的方法论1.对业务了解不粗浅;2.对数据类的技术常识短少;3.优化零碎,不晓得从那个角度去优化:优化比0-1更难,听听用户声音

August 13, 2021 · 1 min · jiezi

关于rpc:基于RPC的抖音直播爬虫

本案例是基于RPC的抖音web直播数据采集。 文章内容仅供参考学习,如有侵权请分割作者进行删除\可采集内容和页面出现内容雷同,包含用户评论、关注、谁来了、送礼物等数据。RPC(Remote Procedure Call)是近程调用的意思。 在Js逆向时,咱们本地能够和浏览器以服务端和客户端的模式通过websocket协定进行RPC通信,这样能够间接调用浏览器中的一些函数办法,不用去在意函数具体的执行逻辑,能够省去大量的逆向调试工夫。 像抖音直播间的数据传输采纳的是protobuf,如果齐全解析的话切实是浪费时间,不适宜做案例教程。 还有重要的一点是,通过RPC的办法能够不必搞加密参数signature,开一个页面就能够了。 接口分析首先通过控制台进行抓包,一般的get申请。有加密参数signature,不过咱们不须要搞。 然而返回的是通过 protobuf 序列化数据。 更多内容请订阅专栏,查看原文。 专栏链接:https://blog.csdn.net/weixin_... 原文链接:https://blog.csdn.net/weixin_...

August 11, 2021 · 1 min · jiezi

关于rpc:RPC框架的IDL与IDLless

IDL,Interface description language,即接口描述语言。 IDL是一种很有用的工具,它提供了对接口的形容,约定了接口协议。使得通信单方通信时,无需再发送 scheme,无效进步了通信数据的荷载比。 但对于RPC框架而言,IDL又不仅仅是一个接口描述语言。对于市面上绝大多数的RPC框架而言,IDL还是一个工具和一种应用过程,专指依据 IDL 形容文件,用指定的开发语言,生成对应的服务端接口模块,和客户端程序。这样的益处是,便于开发者疾速开发。 初衷是好的,然而,问题随同而来。 首先,根据 IDL 生成对应的客户端和接口模块,这个实质是编译。 但对于编译和语言的惯例了解和意识,却导致了问题的复杂化:IDL成了一门“编译型”的语言,倒退出了一套简单的规定和语法。而且不同 RPC 框架的 IDL 语言不齐全一样。每用一个新的框架,就有一套新的IDL语法和规定,就得重新学习一遍。 其次,市面上绝大多数的IDL语法,对于可选参数和可变类型参数,以及不定长参数存在着不同水平的反对问题。 晚期的 IDL,所有的接口字段必须存在。即便是无用的,也须要赋予一个诸如 'nil' 一类的值。否则就是违反 IDL 的标准。随着技术的倒退,之后的 IDL,呈现了 optional 关键字,但仅仅是不得已的状况下,才被举荐应用。而此时,被强烈推荐应用的却是关键字 require 以及 required。比方 Thrift,ProtoBuf 1.0 都是典型的代表。直到技术一直倒退,RPC 畛域的教训积攒越来越多,关键字 require 以及 required 才不再被持续举荐应用,而关键字 optional 成为 IDL 的新宠。可选参数,到目前为止还没有遇到什么问题。直到 IDL 开始编译,生成对应的客户端和接口代码时,新的问题呈现。 接口代码的生成,确实不便了网络服务和接口调用的开发。但适度简单的接口代码,间接导致了接口的强耦合:所有的业务都依赖于 IDL 生成的客户端和服务端的接口,如果一个变动,其余的须要全副追随变动。如果一个接口被改变,与之关联的所有服务和客户端,必须全副从新编译,否则极有可能在 IDL 生成的代码中,呈现不兼容的问题。 最典型的就是,加了一个新的参数,但不在协定数据的开端,那绝大多数 RPC 框架原有的接口在解决新版接口数据时,便会呈现兼容性谬误。 当然,这在很长一段时间内被视为天经地义。 但视之“天经地义”,却不障碍开发者们对其导致的问题熟视无睹,于是不少IDL为了绕过这个问题,创造了“序号/字段编号”这种本不应该存在的语言标识。 此外,传统的 IDL 一旦遇到参数的缩小,或者参数类型的更改,IDL 所生成的 RPC 框架的接口代码,则往往须要两个独立的接口处理函数,能力同时解决新旧两个版本的数据。所以,为了更加“优雅”的解决参数的删除和类型的扭转,局部 IDL 加强了对“序号/字段编号”这种本不应该存在的语言标识的依赖。字段编号不可反复,一旦确定了,便不能批改。于是字段编号的保护,便成了开发者历史包袱的一部分。 而后对于不定类型的参数,反对该个性的 IDL 会选用 Oneof 或 Union 等来实现,而剩下的 IDL 则间接弃疗。 ...

August 6, 2021 · 2 min · jiezi

关于rpc:分布式RPC服务调用框架选型使用Dubbo实现分布式服务调用

Dubbo概念Dubbo是一个高性能,轻量级的RPC分布式服务框架提供了三外围能力: 面向接口的近程办法调用(@Reference)智能容错负载平衡Dubbo特点: 依照分层的形式来架构,能够使各个层之间解耦合Dubbo的角色: 提供方:Provider生产方:ConsumerDubbo的提供非常简单的服务模型,要么是提供方提供服务,要么是生产方生产服务 Dubbo的服务治理通明近程调用: 调用近程办法就像调用本地办法一样,只需简略配置,没有任何API侵入负载平衡机制: Client端LB,在内网代替F5等硬件负载均衡器容错重试机制: 服务Mock数据,重试次数,超时机制主动注册发现: 注册核心基于接口名查问服务提供者的IP地址,能够增加和删除服务提供者性能日志监控: Monitor,统计服务的调用次数和调用工夫的监控核心服务治理核心: 路由规定,动静配置,服务降级,访问控制,权重调整,负载平衡 Dubbo的外围性能Remoting: 近程通信,提供对多种NIO框架形象封装,包含"同步转异步"和"申请-响应"模式的信息替换形式Cluster: 服务框架,提供基于接口办法的通明近程过程调用,包含:多协定反对,软负载平衡,容错重试,路由规定,动静配置等集群反对Registry: 服务注册核心,服务主动发现.基于注册核心目录服务,使服务生产方能动静地查找服务提供方,使地址通明,使服务提供方能够平滑地减少和缩小机器 通信模型:BIO : 同步并阻塞NIO : 异步并阻塞AIO : 异步非阻塞通信框架 : nettyDubbo组件角色组件角色阐明Provider裸露服务的服务提供方Consumer调用近程服务的服务生产方Registry服务注册与发现的注册核心Monitor统计服务调用次数和调用工夫的监控核心Container服务运行容器组件调用关系阐明服务容器Container负责启动,加载,运行服务提供者服务提供者Provider在启动时,向注册核心注册本人提供的服务服务消费者Consumer在启动时,向注册核心订阅本人所需的服务注册核心Registry返回服务提供者地址列表给消费者,如果有变更,注册核心将基于长连贯推送变更数据给消费者服务消费者Consumer从提供者地址列表中,基于负载平衡算法,抉择一台提供者进行调用,如果调用失败,再选另一台进行调用服务消费者Consumer和服务提供者Provider,在内存中累计调用次数和调用工夫,定时每分钟发送一次统计数据到监控核心 Dubbo Admin治理控制台治理控制台的次要性能: 路由规定动静配置服务降级访问控制权限调整负载平衡

May 18, 2021 · 1 min · jiezi

关于rpc:工商银行分布式服务C10K场景的解决方案

简介:将来,中国工商银行将继续致力于 Dubbo 的金融级规模化利用。 作者:颜高飞,微服务畛域架构师,次要从事服务发现、高性能网络通信等研发工作,善于 ZooKeeper、Dubbo、RPC 协定等技术方向。 Dubbo是一款轻量级的开源Java服务框架,是泛滥企业在建设分布式服务架构时的首选。中国工商银行自2014年开始摸索分布式架构转型工作,基于开源Dubbo自主研发建设了分布式服务平台。Dubbo框架在提供方生产方数量较小的服务规模下,运行稳固、性能良好。 随着银行业务线上化、多样化、智能化的需要越来越旺盛,在可预感的将来,会呈现一个提供方为数千个、甚至上万个生产方提供服务的场景。在如此高负载量下,若服务端程序设计不够良好,网络服务在解决数以万计的客户端连贯时、可能会呈现效率低下甚至齐全瘫痪的状况,即为C10K问题。那么,基于dubbo的分布式服务平台是否应答简单的C10K场景?为此,咱们搭建了大规模连贯环境、模仿服务调用进行了一系列摸索和验证。 C10K场景下Dubbo服务调用呈现大量交易失败筹备环境: 应用dubbo2.5.9(默认netty版本为3.2.5.Final)版本编写服务提供方和对应的服务生产方。提供方服务办法中无理论业务逻辑、仅sleep 100ms;生产方侧配置服务超时工夫为5s,每个生产方启动后每分钟调用1次服务。筹备1台8C16G服务器以容器化形式部署一个服务提供方,筹备数百台8C16G服务器以容器化形式部署7000个服务生产方。启动dubbo监控核心,以监控服务调用状况。 定制验证场景,察看验证后果: 验证状况不尽如人意,C10K场景下dubbo服务调用存在超时失败的状况。如果分布式服务调用耗时长,从服务生产方到服务提供方全链路节点都会长工夫占用线程池资源,减少了额定的性能损耗。而当服务调用并发突增时,很容易造成全链路节点梗塞,从而影响其余服务的调用,并进一步造成整个服务集群性能降落甚至整体不可用,导致产生雪崩。服务调用超时问题不可漠视。因而,针对该C10K场景下dubbo服务调用超时失败状况咱们进行了详细分析。 C10K场景问题剖析依据服务调用交易链路,咱们首先狐疑交易超时是因为提供方或生产方本身过程卡顿或网络存在提早导致的。 因而,咱们在存在交易失败的提供方、生产方服务器上开启过程gc日志,屡次打印过程jstack,并在宿主机进行网络抓包。 察看gc日志、jstack 提供方、生产方过程gc时长、gc距离、内存应用状况、线程堆栈等无显著异样,临时排除gc触发stop the world导致超时、或线程设计不当导致阻塞而超时等猜测。 针对以上两种场景下的失败交易,别离察看网络抓包,对应有以下两种不同的景象:针对场景1:提供方稳固运行过程中交易超时。 跟踪网络抓包及提供方、生产方交易日志。生产方发动服务调用申请发动后,在提供方端迅速抓到生产方申请报文,但提供方从收到申请报文到开始解决交易耗时2s+。 同时,察看交易申请响应的数据流。提供方业务办法处理完毕后到向生产方发送回包之间也耗时2s+,尔后生产方端迅速收到交易返回报文。但此时交易总耗时已超过5s、超过服务调用超时工夫,导致抛出超时异样。 由此,判断导致交易超时的起因不在生产方侧,而在提供方侧。 针对场景2:提供方重启后大量交易超时。 服务调用申请发动后,提供方迅速收到生产方的申请报文,但提供方未失常将交易报文递交给应用层,而是回复了RST报文,该笔交易超时失败。 察看在提供方重启后1-2分钟内呈现大量的RST报文。通过部署脚本,在提供方重启后每隔10ms打印established状态的连接数,发现提供方重启后连接数未能迅速复原到7000,而是通过1-2分钟后连接数才复原至失常数值。而在此过程中,逐台生产方上查问与提供方的连贯状态,均为established,狐疑提供方存在单边连贯状况。 咱们持续别离剖析这两种异样场景。 场景1:提供方理论交易前后均耗时长、导致交易超时细化收集提供方的运行状态及性能指标: 在提供方服务器上每隔3s收集服务提供方jstack,察看到netty worker线程每60s左右频繁解决心跳。同时打印top -H,察看到占用cpu工夫片较多的线程排名前10中蕴含9个netty worker线程。因提供方服务器为8C,dubbo默认netty worker线程数为9个,即所有9个netty worker线程均较繁忙。部署服务器零碎性能采集工具nmon,察看到cpu每隔60秒左右产生毛刺;雷同工夫网络报文数也有毛刺。部署ss -ntp间断打印网络接管队列、发送队列中的数据积压状况。察看到在耗时长的交易工夫点左近队列沉积较多。Dubbo服务框架中提供方和生产方发送心跳报文(报文长度为17)的周期为60s,与以上距离靠近。联合网络抓包,耗时长的交易工夫点左近心跳包较多。依据Dubbo框架的心跳机制,当生产方数量较大时,提供方发送心跳报文、需应答的生产方心跳报文将会很密集。因而,狐疑是心跳密集导致netty线程繁忙,从而影响交易申请的解决,继而导致交易耗时减少。 进一步剖析netty worker线程的运行机制,记录每个netty worker线程在解决连贯申请、解决写队列、解决selectKeys这三个关键环节的解决耗时。察看到每距离60s左右(与心跳距离统一)解决读取数据包较多、耗时较大,期间存在交易耗时减少的状况。同一时间察看网络抓包,提供方收到较多的心跳报文。 因而,确认以上狐疑。心跳密集导致netty worker线程繁忙,从而导致交易耗时增长。 场景2:单边连贯导致交易超时剖析单边连贯产生的起因 TCP建设连贯三次握手的过程中,若全连贯队列满,将导致单边连贯。 全连贯队列大小由零碎参数net.core.somaxconn及listen(somaxconn,backlog)的backlog取最小值决定。somaxconn是Linux内核的参数,默认值是128;backlog在创立Socket时设置,dubbo2.5.9中默认backlog值是50。因而,生产环境全连贯队列是50。通过ss命令(Socket Statistics)也查得全连贯队列大小为50。 察看TCP连贯队列状况,证实存在全连贯队列溢出的景象。 即:全连贯队列容量有余导致大量单边连贯产生。因在本验证场景下,订阅提供方的生产方数量过多,当提供方重启后,注册核心向生产方推送提供方上线告诉,所有生产方简直同时与提供方重建连贯,导致全连贯队列溢出。 剖析单边连贯影响范畴 单边连贯影响范畴多为生产方首笔交易,偶发为首笔开始间断失败2-3笔。建设为单边的连贯下,交易非必然失败。三次握手全连贯队列满后,若半连贯队列闲暇,提供方创立定时器向生产方重传syn+ack,重传默认5次,重传距离以倍数增长,1s..2s..4s..共31s。在重传次数内,若全连贯队列复原闲暇,生产方应答ack、连贯建设胜利。此时交易胜利。 在重传次数内,若全连贯队列依然繁忙,新交易达到超时工夫后失败。达到重传次数后,连贯被抛弃。尔后生产方发送申请,提供方应答RST。后交易达到超时工夫失败。 依据Dubbo的服务调用模型,提供方发送RST后,生产方抛出异样Connection reset by peer,后断开与提供方的连贯。而生产方无奈收到以后交易的响应报文、导致超时异样。同时,生产方定时器每2s检测与提供方连贯,若连贯异样,发动重连,连贯复原。尔后交易失常。 C10K场景问题剖析总结总结以上造成交易超时的起因有两个: 心跳机制导致netty worker线程繁忙。在每个心跳工作中,提供方向所有1个心跳周期内未收发过报文的生产方发送心跳;生产方向所有1个心跳周期内未收发过报文的提供方发送心跳。提供方上所连贯的生产方较多,导致心跳报文沉积;同时,解决心跳过程耗费较多CPU,影响了业务报文的解决时效。全连贯队列容量有余。在提供方重启后该队列溢出,导致大量单边连贯产生。单边连贯下首笔交易大概率超时失败。 下一步思考针对以上场景1:如何能升高单个netty worker线程解决心跳的工夫,减速IO线程的运行效率?初步构想了如下几种计划:• 升高单个心跳的解决耗时• 减少netty worker线程数,升高单个IO线程的负载• 打散心跳,防止密集解决针对以上场景2:如何躲避首笔大量半连贯导致的交易失败?构想了如下计划:• 减少TCP全连贯队列的长度,波及操作系统、容器、Netty• 进步服务端accept连贯的速度 交易报文解决效率晋升逐层优化基于以上构想,咱们从零碎层面、dubbo框架层面进行了大量的优化,以晋升C10K场景下交易解决效率,晋升服务调用的性能容量。优化内容包含以下方面: 具体波及优化的框架层如下: 经对各优化内容逐项验证,各措施均有不同水平的晋升,成果别离如下: 综合优化验证成果综合使用以上优化成果最佳。在此1个提供方连贯7000个生产方的验证场景下,重启提供方后、长时间运行无交易超时场景。比照优化前后,提供方CPU峰值降落30%,生产方与提供方之间解决时差管制在1ms以内,P99交易耗时从191ms降落至125ms。在晋升交易成功率的同时,无效缩小了生产方等待时间、升高了服务运行资源占用、晋升了零碎稳定性。 ...

April 29, 2021 · 1 min · jiezi

关于rpc:Thrift-框架的学习

因为一些历史起因须要在不同服务器之间建设rpc通道,来满足不定时、不定量且数据量可能会大的函数须要。在简略比照了之后投向了thrift,尽管网上大佬们说thrift的文档做的很烂,但具体有多烂这个我也不晓得,可能根底需要来讲也不重要。 Q: 为什么抉择rpc而不是RESTful API的形式?A:资源粒度。RPC 就像本地办法调用,RESTful API 每一次增加接口都可能须要额定地组织凋谢接口的数据,这相当于在利用视图中再写了一次办法调用,而且它还须要保护开发接口的资源粒度、权限等;流量耗费。RESTful API 在应用层应用 HTTP 协定,哪怕应用轻型、高效、传输效率高的 JSON 也会耗费较大的流量,而 RPC 传输既能够应用 TCP 也能够应用 UDP,而且协定个别应用二制度编码,大大降低了数据的大小,缩小流量耗费。Thrift的网络栈构造: 上面两层的数据传输: TTransport层代表thrift的数据传输方式,thrift定义了如下几种罕用数据传输方式 TSocket: 阻塞式socket;TFramedTransport: 以frame为单位进行传输,非阻塞式服务中应用;TFileTransport: 以文件模式进行传输;TProtocol层代表thrift客户端和服务端之间传输数据的协定,艰深来讲就是客户端和服务端之间传输数据的格局(例如json等),thrift定义了如下几种常见的格局 TBinaryProtocol: 二进制格局;TCompactProtocol: 压缩格局;TJSONProtocol: JSON格局;TSimpleJSONProtocol: 提供只写的JSON协定;thrift反对的Server模型thrift次要反对以下几种服务模型 TSimpleServer: 简略的单线程服务模型,罕用于测试;TThreadPoolServer: 多线程服务模型,应用规范的阻塞式IO;TNonBlockingServer: 多线程服务模型,应用非阻塞式IO(须要应用TFramedTransport数据传输方式);THsHaServer: THsHa引入了线程池去解决,其模型读写工作放到线程池去解决,Half-sync/Half-async解决模式,Half-async是在解决IO事件上(accept/read/write io),Half-sync用于handler对rpc的同步解决;thrift IDL文件thrift IDL不反对无符号的数据类型,因为很多编程语言中不存在无符号类型,thrift反对以下几种根本的数据类型 byte: 有符号字节i16: 16位有符号整数i32: 32位有符号整数i64: 63位有符号整数double: 64位浮点数string: 字符串此外thrift还反对以下容器类型: list: 一系列由T类型的数据组成的有序列表,元素能够反复;set: 一系列由T类型的数据组成的无序汇合,元素不可反复;map: 一个字典构造,Key为K类型,Value为V类型,相当于java中的HashMap;应用python编写thrift客户端代码执行thrift --gen py src/thrift/data.thrift生成对应的python代码,并引入到python工程当中,代码构造如下图所示python客户端代码 # -*- coding:utf-8 -*-__author__ = 'kpzhang'from py.thrift.generated import PersonServicefrom py.thrift.generated import ttypesfrom thrift import Thriftfrom thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TCompactProtocolimport sysreload(sys)sys.setdefaultencoding('utf8')try: tSocket = TSocket.TSocket("localhost", 8899) tSocket.setTimeout(900) transport = TTransport.TFramedTransport(tSocket) protocol = TCompactProtocol.TCompactProtocol(transport) client = PersonService.Client(protocol) transport.open() person = client.getPersonByUsername("张三") print person.username print person.age print person.married print '---------------------' newPerson = ttypes.Person(); newPerson.username = "李四" newPerson.age = 30 newPerson.married = True client.savePerson(newPerson) transport.close()except Thrift.TException, tx: print '%s' % tx.message参考:thrift基本原理 ...

February 25, 2021 · 1 min · jiezi

关于rpc:RPC设计概要

前言RPC全程近程办法调用,曾经在各大小公司被宽泛应用,品种也是很多比方:Dubbo,Spring cloud那一套,GRPC,Thrift,可能还有很多公司自研的等等;每个公司都可能依据本人的业务需要,场景抉择本人适合的RPC框架;但大体的考查维度无非就这么几个:性能,可扩展性,跨平台,功能性,可监控,应用性;所以咱们如果要设计一个RPC框架,能够从这几个角度去思考。 性能作为微服务中的外围组件,在一个零碎中RPC的调用量往往是很高的,所以性能是一个很重要的思考点;既然是近程调用,必然牵扯到网络连接,而I/O模型的抉择间接影响到性能,网络的长连贯短连贯,序列化形式也都影响性能; 1.I/O模型常见的Unix5种I/O模型别离是:阻塞I/O,非阻塞I/O,I/O复用(select,poll,epoll等反对I/O多路复用),信号驱动I/O,异步I/O;从晚期的阻塞I/O形式只能创立大量的线程来保障每个用户互不影响,到当初宽泛应用的I/O多路复用模型,再到异步I/O;从select模型到当初支流的epoll模型,性能有了质的降级;当然咱们没必要本人去实现,能够间接应用网络通讯框架Netty,Mina等; 2.长连贯短连贯短连贯示意每次通信完就敞开连贯,而长连贯通信完持续放弃连贯,这样下次再通信就不须要从新建设连贯了,如果通信频繁,很显著长连贯性能更高;然而长连贯须要做一些额定的工作,比方保活解决;另外就是如果客户端太多的话,服务器端是无奈撑持的。 3.序列化形式网络传输中的数据都须要通过序列化和反序列化解决,所以这一块的性能也很重要;常见的序列化包含:json和二进制形式,json常见的如fastjson,jackson等,二进制如protobuf,thrift ,kryo等;这个能够别离从序列化的性能,大小,以及应用方便性思考;当然稳定性和安全性也须要思考,比方fastjson频繁爆出安全漏洞; 4.协定这里次要讲的是应用层协定,RPC个别都会自定义协定,当然也有间接应用现有协定的比方http协定;自定义协定能够本人掌控,协定能够做的很小很精简,当然解码和编码须要本人去实现;如果应用现有的http协定,相对来说整个协定包是比拟大的,然而曾经是一种标准了,很多货色能够间接拿来用,更加通用; 可扩展性可扩展性能够从两个角度来看,一个是服务提供方和生产方的负载平衡策略;另一个就是用户能够对框架进行自定义扩大; 1.负载平衡RPC的两个外围组件服务提供方和生产方,须要提供横向扩大的机制,用以达到更高的负责,比方Spring Cloud、Dubbo提供的注册核心,而后再联合容错机制达到负载平衡的成果,很容易达到横向扩大; 2.SPI机制一个好的框架是反对用户自定义的,用户依据本人的需要实现自定义扩大;JDK提供了SPI机制,很常见的一个场景就是数据库驱动;另外Dubbo在此基础上提供了更加弱小的SPI机制;这种扩大对RPC来说是多方面的,能够是底层的通信框架扩大,序列化扩大,注册核心扩大,容错机制扩大,协定扩大等等; 跨平台当初开发语言多种多样,如果能做成跨平台,当然是一大劣势,然而可能往往为了跨平台,会在一些中央做衡量退让,当然难度也更大;所以咱们在实现一个RPC时须要明确本人的定位,就是针对某一种语言的还是跨平台反对;常见的反对跨平台的RPC框架如GRPC,Thrift;实现机制能够参考一下,都有本人的一套接口定义语言IDL而后通过不同的代码生成器,生成各种编程语言生产端和服务器端代码,来保障不同语言间接的相干通信。 功能性作为一个RPC框架,除了最外围的通信模块,序列化模块之外,功能性模块也很重要,往往为开发者节俭了大量的工夫,开发者可能因为RPC的某个性能而抉择用此框架;常见的性能包含:容错机制,负载平衡机制,同步异步调用,后果缓存,路由规定,服务降级,多版本,线程模型等; 1.容错机制在盘根错节的网络环境中,近程调用失败再失常不过了,容错机制就显得十分有必要了,常见的容错机制比方:失败重试,疾速失败,失败间接疏忽,并行调用多个服务器只有一个胜利即返回等;用户能够依据需要抉择本人适合的容错计划; 2.负责平衡下面提到服务提供方和生产方的可扩展性,生产方面对多个提供方的时候须要有肯定的负载平衡策略,来保证系统的稳定性;常见的策略如:随机,轮询,起码沉闷调用数,一致性hash等; 3.同步异步调用常见的同步调用有些场景无奈满足需要,比方同时须要调用多个近程办法,而这其中可能有些执行比较慢的;这时候异步调用就显得重要了,能够同时异步发送多个申请,等待时间就是响应最慢的申请;具体能够通过Future,CompletableFuture来实现; 4.后果缓存缓存始终是性能的不二法宝,某些场景下可能对服务提供方响应的数据实时要求性并不高,这时候如果能够在服务提供端提供后果的缓存机制,那么在性能上是一个很大的晋升;能够本人设计一个本地缓存,当然也能够间接整合第三方缓存框架比方ehcache,jcache等; 5.路由规定服务提供方往往是很多的,用户可能有一些非凡的需要,能够依照本人定义个规定来做路由,比方咱们常常做的灰度公布,联合RPC提供的路由规定来实现会很简略;此规定可能是条件表达式,脚本,标签等,咱们设计的RPC框架须要有一个给用户定义规定的中央,比方通过注册核心来实时推送,另外还须要相干的引擎来解决规定,比方脚本引擎; 6.服务降级零碎的高可用性准则中,很重要的一条就是降级解决,在一些非核心的性能中,能够在呈现超时/故障时或者间接设置为降级服务,给一个对立的响应,这样能够把贵重的资源留给那些外围的性能;能够参考Dubbo的实现,向注册核心写入动静配置笼罩规定,从而实现实时降级解决; 7.多版本接口降级时常有的事件,咱们可能会为了兼容之前的版本搜索枯肠,但有时候还是无能为力,这时候多版本就显得很重要了,能够让两个版本同时存在,等到适合的机会在缓缓降级;像dubbo这种服务的维度就是服务名+版本号,所以很好实现多版本;而Spring Cloud维度没有到版本号,能够通过路由规定去实现; 8.线程模型在零碎的高可用准则中,线程隔离是一条重要的准则,为什么要做隔离,能够拿Dubbo及其底层通信框架netty为例,netty作为通信框架自身是有本人的线程模型,如果业务解决线程间接应用底层的通信线程模型,这样就会呈现因为业务阻塞而导致通信线程模型阻塞;这时Dubbo提供本人的线程模型就尤为重要,能够做到线程隔离,业务线程不影响通信线程; 当然作为一个RPC框架实现的性能能够很多,这里次要讲一些咱们平时用的比拟多的性能; 可监控一个运行稳固的零碎,没有一个专门的监控平台是不行的,当然RPC也不例外,常见的比方dubbo的monitor模块,Spring Cloud Admin等;对于一个RPC咱们次要监控:服务提供者有哪些,服务消费者有哪些,以及它们的状态,最好还有一些统计性能比方一段时间内的调用量,成功率,失败率,均匀响应工夫,最大响应工夫,最大并发量等等; 应用性最初说一下,咱们设计进去的框架最终还是要给用户应用的,所以用户是否能够不便的应用也是一个很重要的点,某些框架可能就是因为应用繁琐导致最终被弃用;比方注解的形式相比拟xml的形式就简略不少;还有比方服务维度来说:dubbo维度是接口,而Spring cloud维度是利用,整体来看Spring cloud应用起来更加不便;当然简略的API,文档以及Demo对开发者来说也是必不可少的; 总结RPC实质上其实就是一次网络调用,很多设计其实都是在围绕,如何把它变成一个高可用,高并发的框架;其实这些设计实践实用于大部分的零碎,都在为达到此指标而致力。 感激关注能够关注微信公众号「回滚吧代码」,第一工夫浏览,文章继续更新;专一Java源码、架构、算法和面试。

December 15, 2020 · 1 min · jiezi

关于rpc:grpc-opentrace-jaeger实现

1) RPCRemote Procedure Call 1) 概览 2) 劣势简略、通用、平安、效率2) GRPC1) 简介gRPC 是一个高性能、开源和通用的 RPC 框架,面向挪动和 HTTP/2 设计ps: 多语言反对 C++C#DartGoJavaNode.jsObjective-CPHPPythonRuby2) 概览 3) Protocol BuffersProtocol Buffers是一种与语言无关,平台无关的可扩大机制,用于序列化结构化数据。应用Protocol Buffers能够一次定义结构化的数据,而后能够应用非凡生成的源代码轻松地在各种数据流中应用各种语言编写和读取结构化数据 示例 example.proto syntax = "proto3"; // 版本申明,应用Protocol Buffers v3版本package pb; // 包名// 定义服务service Trainee { // 办法 rpc Sing (HelloRequest) returns (HelloReply) {} // 办法 rpc Dance (HelloRequest) returns (HelloReply) {} // 办法 rpc Rap (HelloRequest) returns (HelloReply) {}}// 申请音讯message HelloRequest { string name = 1;}// 响应音讯message HelloReply { string message = 1;}3) gongjiayun-notification工家云音讯零碎 ...

November 30, 2020 · 1 min · jiezi

关于rpc:杂记

这几天看一个rpc库(https://github.com/rpclib/rpc...,server端的注册函数返回类型以及参数类型能够任意,client端只有填充对应类型的参数即可实现调用:Server: #include <iostream>#include "rpc/server.h"void foo() { std::cout << "foo was called!" << std::endl;}int main(int argc, char *argv[]) { // Creating a server that listens on port 8080 rpc::server srv(8080); // Binding the name "foo" to free function foo. // note: the signature is automatically captured srv.bind("foo", &foo); // Binding a lambda function to the name "add". srv.bind("add", [](int a, int b) { return a + b; }); // Run the server loop. srv.run(); return 0;}Client: ...

November 15, 2020 · 2 min · jiezi

关于rpc:RPC-笔记

如何发现服务繁难实现:指定服务者的IP和端口。调用时提供办法名和参数。简单实现:通过服务注册和发现核心拉去信息失败解决与调用次数At Least Once 起码一次RPC调用期待指定工夫在指定工夫后如果没有返回后果,重试若干次在重试均失败后,返回谬误提醒仅适宜于申请操作是幂等性的,也就是说屡次调用都会返回雷同的后果,因而通常适宜读取操作。 At Most Once 最多一次调用最多进行一次——要么齐全不执行,要么执行一次。须要测验反复的数据包,比方对于反复的申请会返回之前的响应而不是从新进行解决。

September 30, 2020 · 1 min · jiezi

关于rpc:被喷了聊聊我开源的RPC框架那些事

前段时间利用业余时间写了一个简略的 RPC 框架,破费了不少精力。开源进去之后,少部分不太敌对的技术人站在上帝视角说了风凉话。就很好受,兄弟,谁还没有一个玻璃心。 简略吐槽一波,给大家聊聊对于 guide-rpc-framework 的一些事件。 01 我的自定义 RPC 框架近况关注我的大部分小伙伴应该都晓得,3个月前,我利用业余时间手写一个简略的 RPC 框架(玩具),名字叫做 guide-rpc-framework。 目前的话,这个我的项目曾经有 0.5k 的 star。感激小伙伴们的反对! 写这个 RPC 框架的次要目标是为了集体学习,开源进去的目标次要是想帮忙到更多人。 02 开源的魅力开源进去之后,大部小伙伴都是比较支持的,有很多小伙伴都参加了进来一起欠缺。 这里点名褒扬一下Github用户名为 sakuragi1111 和 smile2coder 这两位老哥。 sakuragi1111 这位老哥通过参考 Dubbo 源码实现了 SPI 机制。 smile2coder 这位老哥为 guide-rpc-framework 增加了通过注解实现服务生产的性能。 目前的话, guide-rpc-framework 曾经反对通过注解进行服务生产和注册。 程序世界,什么样的人都有,有人感激你,也会有人贬斥你。 03 不那么好的声音在我的 guide-rpc-framework 开源之后,也常常会受到像:“你有本事别用现成的框架写一个啊?”、“你这个写的一点亮点都没有,有啥意思?”、“都有了 Dubbo 之后,为啥还要本人写一个?”、“反复造轮子没意义”......之类的不太友善的话语。 说句心里话,个别说进去这种话的人往往技术水平很低。 如果,你指出我哪里写的不好,我很乐意地去批改。然而,你站在上帝视角说着风凉话,那就是人品有问题了。 1.为什么不能利用现成的框架呢?(比方为啥不必 JDK NIO 而用 Netty?) 毫不夸大地说:开源进去的货色,就是整体技术人独特的财产。 Netty 比 NIO 更好用、更欠缺,我为啥还要间接应用 NIO呢?咱们平时常常接触的 Dubbo、RocketMQ、Elasticsearch、gRPC 等等都用到了 Netty 啊。 ...

September 17, 2020 · 1 min · jiezi