只需要3位来表示所需的数据类型,因此标记= (id
泛型序列化
泛型序列化是指在类中序列化具有非特定类型成员变量的对象(Java中的基类对象)。
在SCF中,完全限定的类名哈希用于为每个类生成唯一的typeId。写泛型成员时,先写类的typeId,再写值数据。读取时,就像读取typeId一样,找到具体的类型,然后根据类型读取值数据。
服务注册和发现
当呼叫者通过网络呼叫服务器时,在发起呼叫之前,必须知道服务器节点的IP列表。最初的方式是通过在调用者上使用配置文件来指定,但是这种方式在实际使用中不能动态感知服务节点的变化,不够灵活,不能自动伸缩时间服务的容量。
服务注册和发现是指自动发现服务的节点信息,呼叫者可以及时感知服务节点的变化,自动调整流量切换到新的节点。
SCF使用ETCD集群来管理服务节点。每个服务节点对应于ETCD的一个密钥,并为该密钥设置一个TTL到期时间。通过心跳刷新TTL来维护服务节点的在线状态。为了将ETCD集群从业务部署环境中隔离出来,避免由于服务节点的增加而导致ETCD集群的连接数过高的问题,封装了一层服务管理节点作为代理来转发服务心跳,并维护服务提供商和呼叫者的状态信息。
当服务节点离线时,ETCD集群将相应的密钥通知服务管理节点,服务管理节点将最新的服务节点列表信息实时推送给主叫,主叫动态更新和切换流量。同时,为了兼容推送失败的异常情况,增加了调用者根据时间戳定期检查pull的策略,以保证服务节点信息的最终一致性。
监控数据采集和存储
服务在生产环境中运行正常吗?目前的服务流量是多少?有没有异常通话或超时?这些都是服务负责人需要注意的问题。
数据采集
对于服务端,一个服务有多个方法,同时部署在多个节点上,不同的调用方会调用不同的方法。同样,一个调用者会同时调用多个服务的不同方法。这样一来,整体收集维度就是服务和来电者的产品订单,如何有效收集数据?
下面介绍一下58RPC框架的调用数据收集方案。
从整体架构图可以看出,为了避免流量数据采集的压力,尽可能充分利用各层的计算能力,分担统一汇总的压力。
收集插件充分利用服务节点的计算能力,先进行本地数据聚合,以分钟为单位进行数据上报。插件上报根据服务名 hash,尽可能保证相同服务不同节点的数据发送到同一个收集服务器,收集服务器再进行一次聚合,进一步减少 Cache 统一计数的压力。数据存储
首先,对于服务的呼叫信息,我们来看看一个呼叫需要存储的数据。
对于同维度的监控数据,只有上述字段中的时间戳、次数、耗时数据与实际流量相关,服务名称+服务节点+功能名称+调用者+类型标识对于同维度是相同的。因此,为了减少数据存储,我们定义了一个映射规则(s[demo]sn[10.0.0.1]SF[ServiCe . get()]c[callerdemo]是指服务器demo的10 . 0 . 0 . 1机器上的Service.get()方法由调用方caller demo调用),将上述五个收集到的元信息映射到一个唯一的维度,然后将所有的维度字符串分别生成一个唯一的cid,用cid替换实际存储的监控数据中上述五个收集到的元信息。
在实际应用中,初始版本只存储被调用的元数据,显示时根据显示的维度进行数据查询聚合,导致监控数据显示特别慢,因为需要大量的数据查询和合并。为了加快监控数据的查询速度,使用了写扩散,对一个叫做元数据的进行如下图所示的扩散:
从上图可以看出,在实际存储中,将计算出未来经常需要显示的数据,直接存储在数据库中,显示时可以根据维度的cid直接查询结果,有效提高了查询速度。
总结
SCF框架作为58分布式架构的基本组成部分,支持58集团一万级节点的网络调用。本文主要介绍基本呼叫和监控相关内容。还有负载均衡、网络管理、故障节点排除、服务认证、服务限流等很多模块。经过多次迭代,SCF框架会从一开始最简单的远程调用,到服务治理外围功能的改进,不断优化。欢迎有兴趣的同学互相交流。
作者简介
谭志超,58集团TEG框架组件部,资深后端开发工程师,专注于微服务、RPC框架等领域。本文转载自58建筑师公众号。
1.《SCF 58集团RPC框架SCF的设计与实践》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《SCF 58集团RPC框架SCF的设计与实践》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/fangchan/1511234.html