专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

基础架构组件篇之RPC

  RPC基础功能数据传输序列化反序列化客户端代理类请求映射分发RPC产品功能
  除了RPC基础功能为,RPC还具备八大功能模块
  Consumer:连接管理、负载均衡、请求路由、超时处理
  Provider:队列线程池、超时丢弃、优雅关闭、过载保护Consumer核心设计
  完整的consumer功能模块图
  请求路由通过一系列规则过滤出可以选择的provider节点列表,在应用隔离,读写分离灰度发布中发挥关键作用。匹配规则规则描述待比较属性运算符属性匹配值匹配节点数据结构设计链表
  以IP分流规则举例
  行为链表连接管理
  保持与Provider的长连接,用于传输数据和返回结果,通常情况下基于tcp连接,udphttp也可以实现。初始化时机饿汉模式服务间连接、数据库连接懒汉模式网关连接连接数维护服务连接池数据库连接池心跳断线重连机制client线程模型负载均衡
  确保多个Provider实例节点流量均匀合理(并非绝对平均);支持节点扩容缩容与灰度发布(调整流量权重比例)轮询按顺序轮流分发请求随机随机选择分发请求取模请求数实例数得到集群下标,将请求分发给指定下标的集群实例。权重根据实例的性能设置权重值进行请求分发一致性hash根据hash值将0232次方按照实例数划分为不同的hash范围,根据范围值分发请求超时处理对于长时间没有响应的请求,需要作异常处理,及时释放资源。工作线程阻塞位置等待响应通知超时逻辑工作线程等待通知数据返回终止等待超时抛出异常数据结构Mapkey:sessionID,value:WindowDataProvider核心设计队列线程池
  将不同类型的请求,放入各自的队列,每个队列分配独立的线程池,进行资源隔离。这里的ThreadPool并非指java中的线程池对象,这里是真正的线程池。
  Provider作为服务提供方,对调用方的信息是无感知的,随业务发展可能会有N个consumer对provider进行调用,工作线程有限,因而需要设计数据结构(队列)对请求进行存放。
  数据结构设计分析:请求量多大?是否需要削峰填谷缓存请求?是否存在请求顺序性要求?请求之间相互隔离?不同的请求放不同的队列,不同队列使用不同线程池,资源隔离
  线程与线程之间什么样的通信方式是最安全的?
  通过通信方式来共享内存,不要通过共享内存来通信。线程与线程之间通过队列方式通信是最好的。补充知识:OS分配资源的基本单位是进程,cpu调度的基本单位是线程。
  线程分配的合理数:
  线程数CPU核数22;线程过多会造成线程等待和上下文切换的资源开销;线程太少又无法充分利用cpu资源。
  这里就不提供压测截图了,关于压测有兴趣可以百度自行了解,或者找测试同学沟通
  QPS队列线程2w5w8w11w单队列多线程1640。00s0。010。00s0。050。00s0。190。01s多队列单线程6410。00s0。010。00s0。020。000。070。01s
  在QPS8w时单队列多线程模型的耗时明显比多队列单线程高超时丢弃
  快速失败已超时的请求,缓解队列的压力
  IO线程处理反序列化后将请求放入队列(reqQueue)
  入队代码publickvoidrun(Groupgroup,IAsyncHandlerhandler){构造AsyncTask对象放入队列AsyncTasktasknewAsyncTask(taskTimeout,handler);balance(group,task);}异步任务构造方法publicAsyncTask(inttimeout,IAsyncHandlerhandler){super();if(timeout0){timeout1000;}this。timeouttimeout;超时时间this。handlerhandler;this。addTimeSystem。currentTimeMillis();入队时间}当线程池中工作线程从队列中取出请求进行处理时,判断当前请求是否超时。超时则丢弃,未超时则调用服务处理
  出队代码publicvoidrun(){while(!isStop){AsyncTasktasknull;try{tasktaskQueue。poll(1500,TimeUnit。MILLISECONDS);取出队列任务if(null!task){execTimeoutTask(task);判断任务是否超时}}catch(InterruptedExceptione){logger。error(haserror!,e);}catch(Throwableex){if(task!null){task。getHandler()。exceptionCaught(ex);}}}}publicvoidexecTimeoutTask(AsyncTasktask)throw{当前时间减去入队时间是否大于超时时间超时回调超时if(System。currentTimeMillis()task。getAddTime()task。getTimeout()){task。getHandler()。exceptionCaught(newTimeoutException(threadFactoryNameasynctasktimeout!));return;}else{没有超时回调处理任务Objectobjtask。getHandler()。run();task。getHandler()。messageReceived();}}
  对于consumer而言,一个请求调用的超时时间请求队列排队时间(主要耗时)程序处理时间优雅关闭
  进程结束前应确保队列中的的请求全部处理完成,这路的处理完成是直接回复并非处理逻辑。
  如何通知调用方?返回数据中带关闭信息建议专门关闭协议通知调用方不建议服务提供方对调用方是无感知的;即便是在知道调用方的情况下这样的设计也会造成循环依赖,且调用可能失败,系统复杂度过高。
  返回数据中带关闭信息可以复用现有RPC通道优雅关闭Server端实现监听关闭信号kill12ComponentpublicclassSignalConfig{AutowiredprivateSignalRegistrysignalRegistrypublicvoidinit(){signalRegistry。register();}}监听关闭信号publicvoidregister(){try{if(StringUtils。isNotBlank(osName)(!isMac()!isWindows())){SignalsignewSignal(USR2);这里的USR2其实就是12代表的是用户自定义信号这表示当用户通过kill12来结束某个进程时回调operateSignalHandler函数进行处理Signal。handle(sig,operateSignalHandler);Signalsig2newSignal(STKFLT);Signal。handle(sig2,breakHeartbeatSignal);}}catch(Exceptione){logger。error(signalregisterfailed!,e)}}改变服务状态改变服务状态ComponentpublicclassOperateSignalimplementsSignalHandler{privatestaticLoggerloggerLoggerFactory。getLogger(OperateSignal。class);AutowiredprivateRpcContextrpcContetx;Overridepublicvoidhandle(SingalsingalName){logger。info(server:{}currentstateis:{},newObject〔〕{rpcContext。getServiceName(),rpcContext。getServerState()});设置当前服务状态为重启rpcContext。setServerState(ServerStateType。Reboot);logger。info(server:{}willreboot!,newObject〔〕{rpcContext。getServiceName()});}}通知客户端超时处理判断请求没有超时时调用service方法处理请求publicObjectinnerInvoke(RpcContextrpcContext,MethodSignaturemethodSignature)throwException{这里使用责任链模式维护了RPC上下文对象requestFilter(context);Objectresponsenull;RPCContext。setThreadLocal(context);。。。。。省略。。。。。context。getResponseProtocol()。setSdpEntity(response);responseFilter(context);RpcContext。clear();returncontext;}protectedvoidrequestFilter(RpcContextcontext)throwsExcpetion{logger。debug(beginrequestFilters);for(IFilterfilter:requestFilters){if(context。getExecFilter()ExecFilterType。ALLcontext。getExecFilter()ExecFilterType。RequestOnly){filter。filter(context);}logger。debug(endrequestFilters);}}publicvoidfilter(RpcContextcontext)throwsException{if(serviceContext。getServerState)ServerStateType。Reboot(protocol。getPlatformType()PlatformType。Javaprotocol。getPlatformType()PlatformType。PHP)){封装RPC响应RpcResponseresponsenewRpcResponse();ResetProtocolrpnewResetProtocol();rp。setMsg(Thisserverisreboot!);responseProtocol。setSdpEntity(rp);response。setResponseBuffer(responseProtocol。toBytes(false,null));context。setRpcResponse(response);context。setExecFilter(ExecFilterType。None);不再继续过滤context。setDoInvoke(false);}}
  程序启动后初始化,初始化时初始化容器、初始化插件、初始化监听信号(重要)、初始化服务
  解释:通常结束进程我们用kill9命令这里的9其实就是一种信号量,用户可以自定义信号量发送给操作系统,可以自定义实现优雅关闭client端实现根据返回改变节点状态publicProtocolrequest(ProtocolrequestProtocol)throwsException{判断服务节点状态if(ServerState。RebootstateServerState。Deadstate){thrownewRebootException();};。。。。注册窗口事件socket。registerRec(requestProtocol。getSessionID());异步发送请求socket。send(data);。。。。接收数据,等待数据到达事件byte〔〕buffersocket。receive(requestProtocol。getSessionID()。currUserCount);ProtocolreceiveProtocolProtocol。fromBytes(buffer,socket。isRights(),socket。getDESKey());接收回包首先判断类型是否是重启SDPTypesdpTypereceiveProtocol。getSDPType();if(sdpTypeSDPType。Reset){如果是重启服务节点置为不可用this。asReboot();logger。info(server:〔{}〕,address:〔{}〕wasrebooted,willchooseanotherone!,newObject〔〕{this。getName(),this。getAddress()});抛出服务重启异常thrownewRebootException();}}
  设置服务器为重启状态publicvoidasReboot(){if(ServerState。Reboot!this。getState()){this。setState(ServerState。Reboot);this。setDeadTime(System。currentTimeMillis());this。setWeight(1);this。getSocketPool()。destroy();ServerStateDetector。instance()。add(this);logger。debug(thisserverisreboot!host:this。getAddress());}}节点探索过载保护
  服务提供方为保证正常运行,主动丢弃超出处理能力的请求。
  这里的主动丢弃与超时丢弃不同。每个请求入队时判断队列中的请求数是否达到阈值,超过则直接丢弃。
  入队任务代码publickvoidrun(Groupgroup,IAsyncHandlerhandler){构造AsyncTask对象放入队列AsyncTasktasknewAsyncTask(taskTimeout,handler);balance(group,task);}publicvoidbalance(Groupgroup,AsyncTasktask){if(groupGroup。HIGH){balanceTask(highFactor。getAndIncrement(),groupHighWorkers,task);}elseif(groupGroup。DEFAULT){balanceTask(defaultFactor。getAndIncrement(),defaultWorkers,task);}}publicvoidbalanceTask(intfactor,AsyncWorker〔〕workers,AsyncTasktask){intidxfactorworkers。length;如果预设值大于0if(limitSize0){workers〔idx〕。addTask(task,limitSize,mode);}else{worker〔idx〕。addTask(task);}}voidaddTask(AsyncTasktask,intlimitSize,booleanabortNewTask){如果请求队列长度超出了预设值抛弃新来的任务if(this。taskQueue。size()limitSize){if(abortNewTask){task。getHandler()。exceptionCaught(newTimeoutException(threadFactoryNameabortthistask,becausethequeueisfull!));}else{elimintateOldTask(task);}}else{this。queue。offer(task);}}

爷爷天天带孙子玩游戏,5岁娃说话成语张嘴就来,这方法太牛了爷爷天天带孙子玩游戏5岁娃说话成语张嘴就来,这方法太牛了闺蜜小周,和我从小一起长大,结婚生子的时间也差不多,所以为人母的我们,在有了孩子后,彼此的关系就更亲密了,经常在一起讨论育儿DNF史上最成功的脱坑潮,策划为求玩家回归,每人直送两万点券DNF这游戏真的是个非常神奇的游戏,虽然这游戏一直都不被大家所看好,甚至经常有玩家预言这游戏活不了多久就要凉了。但现实还是很让人意外的,这款不被大家所看好的游戏却成功的火到了现在。万圣节和恐怖游戏最配,恐怖手游佳作推荐又是一年万圣节,在国内可能并没有几个人真正在现实中体验过这个节日,与它接触最多的地方是在各个游戏的万圣节活动中。不过,在游戏里体验万圣节的恐怖氛围也是一家你不错的事,今天要给大家推白菜会加重胃部症状吗?若想养护胃部,平时应该吃些什么呢?想必大家对于白菜这种蔬菜应该是不算陌生的,特别是北方地区的人们对于白菜好像有一种情有独钟的感情,甚至很多东北地区的家庭,每当冬天来临之前都会买很多大白菜放在家里,什么时候想吃了随时南非大股东看好腾讯未来,然而要继续清盘在腾讯股价跌到股民们濒临绝望的边缘时,各种利好消息就接踵而至了。首先是投资人发现最近的一个月时间,腾讯的大股东Naspers居然没有减持,月初持股和月末持股一致,真是意外和惊喜。难1毛钱撬动上亿元收入快递电子面单变广告位一张巴掌大小的快递面单,也能成为快递企业网点老板的增收来源。近日,北京商报记者注意到,趁着双11大促流量,快递企业在面单上为客户打起了二维码小广告,连一些快递网点也趁机接起了定制面栀子花开后的一味良药栀子花纯白芬芳,让人赏心悦目四川省内江市湖南省岳阳市湖南省常德市等城市均选栀子花为他们城市的市花而在栀子花开过之后,结出的栀子也是一味良药。栀子味苦性寒,归心肺三焦经,单泡开水做茶郭晶晶亮相贵妇聚会!穿红裙戴鸽子蛋终于高调一回,美貌意外输了10月31号,顶级名媛冯余慕庄高调的在社交平台上,晒出了自己参加宴会的美照,从曝光的照片来看,参加的这一次聚会真的是非常有排面,宴会地点,碧树环绕,空气十分清新,现场布置的也是相当太极拳练的好不好?看眉宇间就知道眉宇间的放松,是人在练太极拳过程中能够看得见感觉得到的一个现象。它既是习拳的内在要领,更是身心息整体进入练拳状态的一种外在表现。放松体感意感以及气息的感觉无不体现在眉宇之间。毫无疑iOS16。1续航评测出炉,结果令人意外苹果上周发布了iOS16。1正式版,带来了一些新功能。根据用户反馈来看,无论是优化后的电量百分比功能,还是新增的粘贴弹窗管理功能,都受到了大家的一致好评。而众所周知的是,每逢新系统保密工作做不好,计划再完美也没用资治通鉴保密工作做不好,计划再完美也没用资治通鉴发生时间公元一七九年通鉴解析公元一七九年,东汉末年,汉灵帝时期。尚书令阳球,正在暗中谋划一次大清洗,而这次大清洗的目标,就是暴虐无道,以曹节
秋天护肤不踩雷,水光焕肤YYDS秋天真的是我最爱也是最讨厌的季节了!我爱万里无云,落叶缤纷的浪漫,但我也是真的受不了秋天干燥到不留一丝水分的天气。天干物燥,我的脸也燥!干痒泛红,喷个保湿水刺痛刺痛的,让我每天的护多彩袁畈的缔造密码!金秋十月走进安陆市烟店镇袁畈村村道整洁绿树环绕一座座产业大棚密布一口口塘堰碧波荡漾辣椒馆科普馆村史馆诉说着辉煌位于白兆山景区公路边上的袁畈村。刘小平摄作为安陆市共同缔造试点村,袁畈明日霜降,天冷要忌嘴,少吃生姜和柿子,多吃3根,健康迎冬秋风萧瑟天气凉,草木摇落露为霜,时间如白驹过隙,不知不觉即将迎来秋季的最后一个节气霜降。此时枫叶层林尽染,菊花迎风开放,而其他植物逐渐退去夏日的翠绿变得枯黄开始凋零。秋冬转换,天气秋天少吃南瓜红薯,多吃地下苹果,买20斤晒成干,炖肉吃真香导语秋天,遇见这菜别手软,维C是苹果9倍,买20斤晒成干,炖肉吃真香!秋天是丰收的季节,各种瓜果蔬菜和农作物大量上市!每天去菜市场买菜时,都有很多的新鲜蔬菜可以选择,而土豆就是其中安徽人游安徽黄山浪漫秋叶让你过足眼瘾冉冉秋光留不住,满阶红叶暮这是古人关于秋的诗句。一向美丽绚烂的黄山之秋,诚然也是短暂的,而越是短暂就越显得珍贵。蒋鹏涛摄汪兴国摄蔡季安摄当下,随着气温逐渐降低,秋的韵味越发的浓郁。如何通过编程思维解决数学问题头条创作挑战赛如何通过编程思维解决数学问题问题描述一个停车场,现有6辆车来了两辆车走了三辆车,总共是多少辆车?问题分析设置total是现有的车辆数量第一次来了两辆,第二次开走了三辆面试被问到线程池是怎样实现线程复用的,如何回答?如果你只知道线程池的几个参数,面试被问到再深一点的内容就回答不上来了,那么本系列文章带你熟悉线程池源码,更深入的了解线程池。ThreadPoolExecutor将分几篇文章做解析,价格亲民!配0。5小时快充,爆225马力,带你看AIONV在购车的时候,很多消费者都会通过各种渠道对这些车型有点了解,增加我们对此的知识,方便购买到配置更好性价比更高的东西。今天我们就来看看由广汽集团旗下的子公司广汽埃安生产的AIONV2docker从入门到实战万字长文全面介绍docker入门及高阶用法docker简介一什么是docker官方地址httpsdocs。docker。comDocker是一个基于go语言开发的开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一给老婆选车推荐你看看这款,颜值不输欧拉好猫,只要7。39万!现在的购车群体中女性车主数量增长迅速,所以现在有很多汽车的外观都比较符合女性的喜好,奇瑞新能源里面的小蚂蚁(图片配置询价)2022款甜粉款微糖版三元锂28。8kWh30kW301k考上了!日本驸马第3次法考通过,日网狂夸你是日本的宝21日下午,万众瞩目的日本驸马小室圭第三次法律考试,结果公布。这一次,他终于通过了!合格消息一出,立马冲上日本推特热搜第一位,全球热搜第二位,很快,真子的名字也冲上了热搜。足见全球
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网