百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

从RPC到服务化框架(rpc服务是什么)

ccwgpt 2024-10-01 08:00 34 浏览 0 评论

本文是对几年前我在公司做的服务框架的梳理。

本文假设你已经了解了什么是服务化,只阐述针对现有的服务框架所存在的问题,如何根据实际需求去考量并解决对应问题。

首先,我们先来聊一聊服务框架的核心RPC!

RPC

RPC全称是Remote Procedure Call,即远程过程调用。它和HTTP不是同级的概念。HTTP是协议,而RPC是一种远程调用方式。它可以基于HTTP来实现,也可以基于TCP来实现。

乍看之下RPC不就是个客户端调用服务端吗?实际上它确实就是客户端调用服务端而已,只不过,在大部分情况下,RPC在调用时看起来像是在调用本地方法/接口。

注意看上面的Consumer Stub和Provider Stub,这里可以理解为是代理,即

  • Consumer和Consumer Stub交互
  • Consumer Stub通过RPCLibrary将调用内容序列化,通过网络传输给Provider端
  • Provider端反序列化,然后根据传递的内容去调用实际的方法
  • 接着再将结果序列化后,通过网络回传给Consumer端
  • Consumer端接收到数据后,再反序列化获取到结果,然后进行后续的操作

一个具体的例子可以看SpringCloud套件中Feign的使用。

如下图所示,这里通过Feign定义了一个接口

可以直接通过方法调用的方式来调用,看起来和调用普通方法一样没有任何区别。

这里实际上就是进行了上面所述流程的操作,具体的源码流程,可以自行梳理,并不复杂。如果比较懒,可以等我后面SpringCloud的源码梳理,不过时间未定!

解释完RPC,我们就来看一看服务化框架。

服务化框架

上面所说的RPC还远远达不到框架的程度!

首先,Consumer是需要知道Provider的地址信息的,否则它无法将消息发送给Provider。这会导致什么问题呢?所有的Consumer都需要维护Provider地址信息。假设Provider地址信息发生了变化,则所有的Consumer都需要修改对应的配置信息。

其次,Consumer和Provider之间是直连的,假设Provider多了以后,则Consumer与Provider之间的连接将会很多,要人工维护会非常的麻烦。

另外,还有一个问题,Provider地址信息是配置到Consumer中的,那如果Provider挂了该怎么办?如何去除Provider的单点问题呢?

最后,Provider升级后,Consumer该如何处理?

如果你熟悉分布式系统的话,那答案是显而易见的,就是引入注册中心。

  • Provider启动后将自己的信息注册到注册中心,注册中心接收到消息后,将新的Provider信息列表推送到已经连接上来的Consumer
  • 同时Consumer启动时从注册中心获取Provider注册信息
  • Consumer内部实现了负载均衡,通过负载均衡算法,来选择合适的Provider来发送请求

服务框架的功能

上图的Consumer,Provider和Registry实际上就是一个服务框架所需要的三个必要组件。而一个较为完善的服务框架,需要至少提供如下功能:

实现

当初编写这个服务框架实际上是为了解决几个问题:

  • 一般服务框架的升级问题
  • 服务元数据管理问题
  • 模块化服务开发

我们从「服务升级」这个场景开始!服务升级应该算是服务化里最基本的功能了,我们以dubbo为例,看看使用dubbo框架的情况下,如何进行服务升级?

一般服务升级可以分为两种情况:

  • 服务修改保持兼容,也就是说接口不变,实现改变。
  • 另外一种情况是服务修改不兼容,即接口也改变了。

我们先看第一种情况,当服务保持兼容的情况下,我们的升级流程大致是什么样的!以下图为例,我们有三个服务节点和两个客户端:


  • 首先,停止一个服务节点,发布新服务,启动服务节点
  • 然后,再停止一个服务节点,发布服务,启动服务节点
  • 直到所有的服务节点都更新完成

而当服务不兼容的情况下,升级流程大致是这个样子:

  • 停止一个服务节点,发布新服务,启动服务节点。并保证当前客户端无法访问到这个新服务
  • 升级一个客户端到新版本,并将调用指向新服务
  • 重复如上步骤,直至全部发完

从上面的流程,我们可以发现如下几个问题:

  • 频繁重启容器,累积耗时很长:服务发布需要重启容器,而容器中一般不会只有一个服务,发布一个服务需要启动整个容器,耗时会比较长
  • 对同一服务节点下的其他服务有影响:上面提到一个容器下一般不会只有一个服务,当重启这个容器时,该容器内的其它服务也无法对外服务
  • 在进行升级的过程中,会导致服务容量减少,相对的负载增加:在服务节点停止后,无法对外服务,原本路由到该节点上的请求被分配到了其他节点上,变相增加了其他服务的负载压力

对于这个问题,我们该如何解决呢?

其实很简单,

  • 重启容器会使发布时间变长,那我们就不重启容器,直接发布服务,也就是「热部署」。
  • 而对于不兼容服务的发布,我们可以通过版本管理来处理。
  • 另外,我们希望能模块化的开发服务,使得服务能像积木一样的组合

对于如上的问题和需求,我们如何解决和实现呢?

如果你熟悉JVM的话,其实第一个想到的方法应该是自定义ClassLoader!而在我们服务框架的早期版本里,是使用OSGi来实现的。

现在应该很少有人了解OSGi了!在Java模块化出来之前,OSGi是Java模块化编程事实上的标准。eclipse就是基于OSGi来实现插件化的。

OSGi默认就提供了多版本管理,动态部署,模块化管理等功能(看起来很契合我们的需求)。它也是通过ClassLoader来实现的,不过和我们已经很熟悉Java的双亲委托模型不同,OSGi自己实现了一套网状的ClassLoader结构,通过这样的结构OSGi实现了上述功能。

我们来看下,在基于OSGi实现的服务框架下,服务发布的流程变成了什么样:

假设当前服务版本是1.0.0,欲发布2.0.0版本

  • 直接将2.0.0版本的服务添加到服务容器中,自动启动、注册、推送
  • 客户端目前版本为1.0.0,服务端目前包含了1.0.0和2.0.0版本的服务
  • 客户端会查找最符合要求的服务进行调用:
    • 如果版本号一致,则调用版本号一致的服务,
    • 否则调用版本号最新的服务。目前客户端会调用1.0.0版本的服务
  • 如果服务是兼容的,则可以直接卸载1.0.0版本的服务
  • 而不管服务兼容不兼容,通过将客户端升级到2.0.0版本即可完成服务升级.1.0.0版本的服务可删可不删,因为目前没有请求会调用它了

最终服务框架的架构如下,客户端,注册中心,服务端和其它框架无异,主要区别在使用了OSGi来作为服务发布的容器。

新的问题

这样看起来很完美,OSGi完美的实现了我们的需求。但是实际上,在实际使用过程中还有很多新问题:

  • OSGi增加开发复杂度

前面说了OSGi提供了多版本管理,动态部署,模块化管理等功能。而相应的带来了开发复杂度的提高。OSGi通过METAINF.MF文件来配置相关信息,而这些信息在Java中是静态的,通过这些信息,OSGi在运行时处理版本、导入导出等信息。导致的问题就是,开发修改了METAINF.MF文件后,不部署到OSGi容器内,无法确认配置是否正确。而每次发布都要打包,大大降低了开发效率。且由于需要发布到OSGi容器,所以只能远程调试。

如何解决这个问题呢?是继续为了使用OSGi带来的便利而忍受其带来的开发复杂度,还是放弃OSGi呢?

其实我们使用OSGi,需要的是它的多版本管理和热部署功能,模块化并不是强制需求,是我们的美好愿望,为了这个美好愿望牺牲开发效率值不值得呢?这是个问题。

最终我们放弃了OSGi,而使用自定义ClassLoader的方式来实现版本管理和热部署。

大致结构并不复杂,主要在ApplicationClassLoader下增加了BaseContainer和ServiceContainer,其中ApplicationClassLoader加载服务节点应用,主要负责通信,BaseContainer加载一些公共服务,例如日志,数据源等服务。ServiceContainer加载业务服务,在ServiceContainer加载的服务中,有一个比较特殊的服务,我们称为系统服务,它的作用是用来发布其他服务,具体作用后面再说。

  • 耗时服务导致超时

我们使用netty作为服务框架的通信框架,实现的是从Reactor模型,在服务端获取到客户端请求后,会首先将其丢到一个队列中,由消费线程去异步处理请求,如果某个服务耗时比较长,则会导致队列阻塞,影响其它的服务响应。这个问题在其他的服务化框架中应该也是存在的。在新版服务框架中,我们可以将耗时服务独立到一个队列中进行执行,使该服务不会影响其他服务的正常调用。具体操作只需要在提供的界面做些配置就可以动态调整了。

  • 服务发布分散

在我们发布服务时,我们需要登录每个需要发布服务的机器,进行发布服务的操作。公司的运维平台提供了界面可以操作发布,不过它是个运维平台,而不是业务平台,发布完成后如何确认服务都注册成功了呢?新版服务框架中提供了管理中心,实现在一处发布所有的服务。流程如下:

  1. 管理中心通知需要发布服务的节点,将需要发布的服务信息发送给节点
  2. 节点收到信息后,从Maven仓库下载需要发布的服务,进行部署
  • 缺少完善的服务治理

在服务发布完成后,如何确认服务都注册成功了呢?

举个例子:我们发布服务A,注册中心可以看到其下的服务接口1和服务接口2,当我们更新服务A后,注册中心只能看到服务接口1,那么请问,消失的服务接口2是注册失败?还是版本更新给删除了?这个问题目前的服务框架都没有处理。

在我们新版服务框架中,提供了基于元数据的服务监控与提醒,可以配置监控重要的服务接口,如果发布后服务接口消失,则通过监控来进行及时的提醒。

除了上面所说的问题,新版服务框架还提供了完善的服务治理,权重的动态调整,服务自动升降级,服务端管理,客户端管理等操作。

新版服务框架的架构如下:

  • 主要将注册中心升级为了管理中心
  • 管理中心包含了注册中心,一个WebApp提供给相关人员进行服务管理操作,一个LocalClient来进行通信
  • 这个LocalClient是个特殊的客户端,主要就是和上面提到的系统服务进行通信,来进行相关的管理操作

在新版服务框架下,所有的操作都可以在管理中心执行,结合公司管理平台提供的部署与监控,可以实现服务开发、部署、发布的闭环,大致流程如下:

  • 通过管理平台发布客户端,注册中心,服务端。通过相应的配置,发布完成后三者即可通信
  • 在管理中心服务页面,选择需要发布或更新服务的节点,进行发布或更新操作
  • 相应节点接收到消息后,从Maven仓库下载需要发布或更新的服务,进行发布或更新
  • 管理平台中可以查看服务调用的相关监控,同时如果出现了相关问题,例如上面提到的服务未注册成功,会及时通过管理平台通知相关人员

总结

本文主要是对之前开发的服务化框架的设计过程的一个梳理总结,并对一些特殊的考量做了特别说明。

相关推荐

谷歌正在为Play商店进行Material Design改造

谷歌最近一直忙于在其应用程序中完成MaterialDesign风格的改造,而Play商店似乎是接下来的一个。9to5Google网站报道,有用户在Play商店的最新版本中发现了新界面,暗示该应用和网...

企业网站免费搭建,定制化建站CMS系统

科腾软件企业网站CMS管理系统已完成开发工作,首次开源(全部源码)发布。开发工具:VisualStudioEnterprise2022数据库:SQLite(零配置,跨平台,嵌入式)开发...

您需要的 11 个免费 Chrome 扩展程序

来源:SEO_SEM营销顾问大师Chrome扩展程序是SEO的无名英雄,他们在幕后默默工作,使您的策略脱颖而出并提高您的努力效率。从竞争对手研究到审核您的网站,速度比您说“元描述”还快,这些小工具发...

户外便携设备抗干扰困境如何破局?CMS-160925-078S-67给出答案

  在户外复杂的电磁环境中,便携式设备中的扬声器需具备出色抗干扰能力,CUID的CMS-160925-078S-67在这方面表现突出。  从其结构设计来看,矩形框架虽主要为适配紧凑空...

一个基于NetCore开发的前后端分离CMS系统

今天给大家推荐一个开源的前后端分离架构的CMS建站系统。项目简介这是一个基于.Net3构建的简单、跨平台、模块化建站系统。系统业务简单、代码清晰、层级分明、全新架构便于二次扩展开发。支持多种数据库,...

本地Docker部署ZFile网盘打造个人云存储

前言本文主要介绍如何在LinuxUbuntu系统使用Docker本地部署ZFile文件管理系统,并结合cpolar内网穿透工具实现远程访问本地服务器上的ZFile传输与备份文件,轻松搭建个人网盘,无...

pcfcms企业建站系统 免费+开源的企业内容管理系统

项目介绍pcfcms是基于TP6.0框架为核心开发的免费+开源的企业内容管理系统,专注企业建站用户需求提供海量各行业模板,降低中小企业网站建设、网络营销成本,致力于打造用户舒适的建站体验。演示站...

【推荐】一个高颜值且功能强大的 Vue3 后台管理系统框架

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍SnowAdmin是一款基于Vue3、TypeScript、Vite5、Pinia、Arco-Desi...

java开源cms管理系统框架PublicCMS后台管理系统

一款使用Java语言开发的CMS,提供文章发布,图片展示,文件下载,用户权限、站点模块,内容管理、分类等功能。可免费用于商业用途maven工程数据库脚本在工程中database文件夹下代码结构:效果...

一定要大量读书:当我问Deepseek,它给出的高效阅读方法厉害了!

一年一度的世界读书日,总该写点什么。于是,我去问Deepseek给我推荐人生破局必读的10本书,结果它给了我回复,竟然10本推荐的书籍里,我都曾经浏览过,同时还给出破局关键。而说浏览过,不是读过,是因...

《搜神札记》:不应磨灭的惊奇(小说《搜神记》)

□黄勃志怪传说的书写一直是文人墨客的后花园,晚近尤盛,从张岱到袁枚到纪昀,收集那些或阴森或吊诡的行状故事,遂成一类,到民国年间,周作人挟此遗传,捋袖子拿希腊神话动刀,乃兄鲁迅不甘其后,《故事新编》虎...

《如何构建金字塔》之第三章总结(构建金字塔结构的方法有)

“没有什么比一套好理论更有用了。”——库尔特.勒温这篇读后感依然引用了这句库尔特.勒温名言,这句话也是我读芭芭拉.明托这本书的初衷。今天就“如何构建金字塔”,我来谈谈我的读后心得。我热爱写作,但是写...

《助人技术》第一章助人引论内容框架

第一章内容基本呈现如何成为助人者(心理咨询师)以及一些相关基础知识,对于进入这个行业有兴趣以及希望通过心理咨询寻求帮助但存有疑虑的当事人,都值得一读。心理咨询的三个阶段(不是说严格的三个阶段,而是广义...

AI助手重构读后感写作流程:从提纲到完整性思考的转换

大家好!你有没有遇到过读完一本书,想要写读后感,却不知道从何下手的情况呢?今天我们要来探讨一下如何利用稿见AI助手来重构读后感写作流程,从提纲到完整性思考的转换。让我们一起来看看这个全新而又实用的方法...

图解用思维导图做读书笔记技巧(图解用思维导图做读书笔记技巧视频)

做阅读笔记非常有利于读后进行有效的深入思考,而思维导图这一强大的工具其最大的特点就是架构清晰,在阅读过程中对文章的分析、总结、分类起着很大的辅助作用。思维导图读书笔记步骤:1、阅读大纲。首先要快速浏览...

取消回复欢迎 发表评论: