`
lokki
  • 浏览: 59951 次
  • 来自: ...
社区版块
存档分类
最新评论

RPC框架中request submit后,request received和timeout、长连接LifeCycle

    博客分类:
  • java
阅读更多

我写代码还算比较细致的,经常用肉眼和模拟细节的运行情况,对于不通的问题也严于律己,找到解决方案,或 say no

进程里,只要存在这种跨线程的两步模式“发送 --> 接收到”,就可能会出现接收不到,而发送方也不能感知的情况,特别是通过网络进行的RPC框架。
RPC肯定是跨了线程的,在“应用 至 rpc框架”这个集成点,如果要实现可靠的发送方感知,那得实现应用层的“三路握手”,即必须要有“request received”的反馈包。而即使实现了这种反馈包,在同一进程的3线程协同上也得处理很复杂,3线程是:request线程、正常response线程、“request received”反馈包线程。

同时,即使有“request received”反馈包,在业务处理上都可能出现处理超时的情况。

情景:“request submitted”后的下一行代码,submit方,他关注的是“我下一步要怎么做,才能让我的工作/下一步是正确的”,由于处理超时的情况,是不可能避免的,所以为了能让submit方做好他的工作,异步(跨线程)时,一定要能够返回“超时”信息。而对于submit方细分“网络超时”和“业务处理超时”,如果提供了“网络超时”给submit方,肯定是错的,画蛇添足的。因为你无法保证“只有”你脑里想像到的“网络超时”“业务处理超时”两种状况。

对于应用sumbit后的这行代码,RPC框架方能确保的是,有业务response,无业务response。没,就返回(抛)TimeoutException。

所以,跨了线程,做“request received”反馈包是多余并大大增加了复杂性的事情。

从“RPC 至 submit应用方,返回结果”这个方向上,要么是业务respone,要么是timeout。

那在应用sumbit后的这行代码,RPC框架要能让应用方处理,就得提供TimeoutException类,让应用方catch。如果是显式RPC request,那TimeoutException可为CheckException。如果是隐式,TimeoutException是绝对要为RuntimeException的。

因为对于一行调用,如果声明上没这个CheckException,而应用方又想写下catch这异常的代码,是编译通不过的。

所以必须是RuntimeException时,用文档交代清楚即可。

对于CheckException和RuntimeException,少出现的东西,应该用RuntimeException异常。并且使用方随时可以在任何地方都能写下catch RuntimeException的代码,能预先写好,也很好,不能预先考虑到,但发现情况时再加上,也能的。关于RuntimeException的说明,从“是编译通不过的”起,以上已基本将观点/原因介绍完毕了,不再写新blog了。“编译通不过”,java通过这个透露了他的一些思想/思维。

很多人比较纠结,“不想用RuntimeException”,觉得这是对使用方“交代得不够清楚”。不过,代码是机器执行,不是人执行,不是“你”钻进CPU里执行,你担保不了。不要纠结于"我显式抛了RuntimeException,那别人不知道,没catch,那线程终结了,怎么办",你无意的写错代码的NPE,这个也是你造成的错误,也是无法预先告知的。能做到“让别人知道”,就很不错了。

你能"担保对"的是,“我提供了RuntimeException型的TimeoutException,你考虑是否要catch并处理”。能担保的是“没抛TimeoutException时,那业务肯定被执行了”,做这个担保时,不说这句话也没关系:“如果request所在的进程/线程如果没有被kill”,这句话说多说少改变不了事实。

如果你根本没能力担保,但又拍下胸膛,这就不对了。

我做过一个RPC,开始时没把TimeoutException这个类暴露出来,这是我的错,想清晰后待再搞新的RPC,就不会再错了。

长连接RPC的stopping lifecycle:
引起以上思考,主要是进程stop时,长连结RPC服务端要怎么细致细节处理。
正确的原则还是:先关入口,然后等待内部已经在运行中的,处理完。

正确的处理/顺序总结如下
(1)先将listen端口 停掉/unbind。

(2)shutdown boss/worker线程池,这样就不会再处理新业务了,如果有网络包(完整接收完了的)进来而没有线程处理,会有(3)中“本连接停止服务包”迅速反馈了回去。
而IO boss/worker的线程是可以为daemon,但业务处理的线程是不能为daemon的。
这里只是shutdown线程池而已,不是在这步close socket。

(3)给各个长连接发“本连接停止服务包”,让客户端给此connection打上个标记,并从connection list holder中释放(去掉)此connection instance,这样client clustering 路由选址时就不再选中此连接。

这条获得的思考结果是“本连接停止服务”或者“服务器端连接池已满”这种技术消息,应该是RPC Framework的client处接收到并再路由选址,而不是立刻就抛给“request submitted”应用方。以前的RPC由于没有这个消息,所以有点不好。

(4)unregister ResourceLocator上的“服务活着记录”。
ResourceLocator,很多同义词的,比如一些人叫name service、WS上叫register和discovery、zookeeper、address service、tracker等等。

如果有(1)(2)(3)做好的前提下,这里和ResourceLocator的处理超时,问题已经不大了。这个也可以从(1)起,就并行进行。

(5)服务器端等待各个进行中的业务线程处理完后(判断ThreadPoolExecutor是否终止完毕),close 各长连接。这一步是否超时,已不重要,你也没办法。
但无论怎样,另一个地方:client和server端对于socket的异常是要处理精细并且不出现交叉错误的。“交叉错误”的意思时,有时候为了做好这个要求,结果这个要求是做好了,但产生了bug,让另一个去承受。

selector wakeup和close socket的细节,看着办。

(6)在客户端的易用性可靠性措施方面,很多RPC是当发现一个服务IP不可用时,是重新选址几次(比如3次)试图建立长连接,如果还是没办法把request送出去,就抛“找不到服务地址”这个异常给应用方,让应用方自己处理。这样和应用方交互的“找不到服务地址”这个消息,也是明确的:你的请求还没被业务处理。

“找不到服务地址”这个异常也肯定是RuntimeException,并且要暴露class给应用方catch。

从以上总结下来,长连接里的包只需要:心跳包、“本连接停止服务包”和正常response包即可。

在request submited交互处,RPC framework要抛给应用方的消息是:“TimeoutException”和“找不到服务地址”。

只限于RPC framework的server端和client端的技术交互消息是:心跳包、“本连接停止服务包”。
心跳包可以从client处来发,接收端完全不需要处理,而是让操作系统早点发现此socket有问题,发出socket异常消息给RPC Framework。心跳包的作用是让client发出的消息及早发现网络错误,重新选址,迅速点把这个request消费出去,不堵在client端。其实从server端发出心跳包没有很大作用,server端一发出正常repsone,就发现网络错误了,socket异常处理,会处理好的。

这里仅说正常停止的处理过程,对于异常格式的处理,这里说的少,得以后再说。
分享到:
评论

相关推荐

    Retrofit2+Rxjava2+Rxandroid+okhttp3+Lifecycle 的MVP网络框架,精简Google官方AAC框架

    本框架使用Retrofit2+Rxjava2+Rxandroid+okhttp3+Lifecycle 的MVP网络框架,精简Google官方AAC(Android Architecture Components)框架,实现APP生命周期的管理

    Android中的生命周期LifeCycle

    本文将深入探讨Android中的生命周期(LifeCycle)机制,以及如何利用相关工具进行调试和优化。 Android Activity的生命周期是其从创建到销毁的一系列状态变化。主要包含以下几个关键状态: 1. **初始化态...

    flutter plugin-android-lifecycle

    Flutter的flutter_plugin_android_lifecycle插件是一个Flutter插件,用于访问Android Lifecycle objects。它可以帮助其他Flutter插件在Android上更好地集成。 要使用flutter_plugin_android_lifecycle插件,需要将...

    Android框架组件Lifecycle的使用详解

    Android框架组件Lifecycle是Google推出的一系列框架组件之一,主要用于感知Activity和Fragment的生命周期。Lifecycle组件能够解决生命周期方法变臃肿的问题,使代码更加优雅。 一、Lifecycle概述 Lifecycle是...

    Servlet_LifeCycle_Demo

    总结,`Servlet_LifeCycle_Demo`项目是学习和实践Servlet生命周期的绝佳起点。通过运行和分析代码,你可以深入掌握Servlet如何响应HTTP请求,以及如何在整个生命周期中管理自身状态。这对于任何想要成为Java Web...

    tomcat 生命周期,和事件管理—— lifeCycle & event

    例如,可以监听启动和停止事件来执行日志记录或数据库连接的初始化和关闭。 博客链接 "<https://yjhexy.iteye.com/blog/669427>" 可能提供了更深入的讨论,包括如何自定义LifeCycleListener,以及在实际项目中如何...

    iOS中的View Controller Lifecycle

    在iOS开发中,View Controller(视图控制器)生命周期是开发者必须深入理解的重要概念。View Controller是Apple提供的一个关键组件,用于管理屏幕上的UI元素和用户交互。本文将详细阐述iOS中View Controller生命周期...

    viewModel,liveData,lifecycle的简单使用demo

    ViewModel、LiveData 和 Lifecycle 是 Android 开发中的三个关键组件,它们都是 Android Jetpack 库的一部分,旨在帮助开发者构建更稳定、更健壮的应用程序。在这个"viewModel,liveData,lifecycle的简单使用demo"中...

    androidx-lifecycle-common-2.1.0.jar

    androidx-lifecycle-common-2.1.0.jar

    Dell Lifecycle Controller 设置 Dell PowerEdge 服务器

    Dell Lifecycle Controller 是一种先进的嵌入式系统管理技术 , 借助这种技术 , 可以通过 integrated Dell Remote Access Controller (iDRAC) 来实现远程服务器管理。在使用 Lifecycle Controller 的情况下 ...

    20210826-dell 14G服务器使用Lifecycle安装windows server .pdf

    DELL 14G服务器通过F10 Lifecycle Controller安装Windows Server是服务器管理中常见的操作,这一过程涉及到服务器的初始化配置、RAID设置以及操作系统安装。本文档提供了详细步骤,适用于2021年8月26日的最新更新。 ...

    vRealize Suite Lifecycle Manager技术白皮书.pdf

    vRealize Suite Lifecycle Manager随附在VMware vRealize Suite Standard、Advanced和Enterprise版本中。要获取更多信息或购买VMware产品,请访问https://www.vmware.com/cn/products/vrealize-suite.html。 VMware...

    Product Lifecycle Management资料

    **产品生命周期管理**(Product Lifecycle Management,简称PLM),是一种集成化的信息系统,旨在帮助制造型企业全面管理和优化从产品概念设计到报废回收整个生命周期中的所有数据、信息和流程。它不仅仅是对产品的...

    androidx-lifecycle-livedata-2.0.0.aar

    androidx-lifecycle-livedata-2.0.0.aar

    takari-lifecycle-plugin-1.0.5.zip

    【标题】"takari-lifecycle-plugin-1.0.5.zip" 提供的是 Takari 插件的一个版本,这是针对 Maven 构建系统的一个扩展。Takari 生命周期插件致力于改进 Maven 的构建过程,使其更加高效和用户友好。这个版本(1.0.5)...

    Solid Edge 培训资料 01610-框架设计.pdf

    在完成框架设计后,用户需要指定框架部件类型和尺寸。可以从命令条上的列表中选择横截面,或者浏览标准库部件进行选择。用户还可以使用框架原点命令来应用框架部件属性,并向库中添加定制部件。 6. 拐角处理选项:...

    androidx-lifecycle-livedata-core-2.0.0.aar

    androidx-lifecycle-livedata-core-2.0.0.aar

    Lifecycle-Sorter,.zip

    项目中的"Lifecycle-Sorter-master"目录可能是项目的主分支,包含着项目的核心代码、资源文件、文档和其他相关组件。以下是可能包含的一些关键部分: 1. **源代码**:项目的核心算法和实现位于此处,可能包括一个或...

    flex3_4 lifecycle

    在IT行业中,Flex是Adobe开发的一个用于构建富互联网应用程序(RIA)的框架,主要基于ActionScript和MXML。Flex 3和Flex 4是两个重要的版本,它们在生命周期管理上有显著的区别,对于开发者来说理解这一概念至关重要...

    生命周期LifeCycle

    在Android应用开发中,"生命周期"是至关重要的概念,它涉及到Activity、Service、BroadcastReceiver以及Fragment等组件的行为和状态变化。这些组件的生命周期由系统控制,开发者需要理解并正确处理各个生命周期方法...

Global site tag (gtag.js) - Google Analytics