当前位置: 首页 > news >正文

seo网站内部优化方案个人网站制作的步骤

seo网站内部优化方案,个人网站制作的步骤,建立企业的网站有哪几种方案,广州微信小程序开发工作室项目流程和架构设计 1.服务端的功能#xff1a; 1.提供rpc调用对应的函数 2.完成服务注册 服务发现 上线/下线通知 3.提供主题的操作 (创建/删除/订阅/取消订阅) 消息的发布 2.服务的模块划分 1.网络通信模块 net 底层套用的moude库 2.应用层通信协议模块 1.序列化 反序列化数…项目流程和架构设计 1.服务端的功能         1.提供rpc调用对应的函数         2.完成服务注册 服务发现 上线/下线通知         3.提供主题的操作 (创建/删除/订阅/取消订阅) 消息的发布 2.服务的模块划分         1.网络通信模块 net 底层套用的moude库         2.应用层通信协议模块 1.序列化 反序列化数据 解决tcp中的粘包问题。2.客户端/服务端对消息进行处理就需要设置一个oMessage回调函数对收到的数据进行应用层协议处理。         3.消息分发模块  Dispatcher收到消息 根据不同的消息类型去调用不同的回调函数         4.远程调用路由模块 RpcRouter 提供Rpc请求的处理回调函数  并返回执行完的结果         5.服务注册/发现模块 Register—Discovery 针对 服务请求进行处理         6.发布订阅模块 Publish--subcribel 针对发布订阅请求进行处理 并提供一个回调函数给Dis模块 设计项目原因 对底层网络通信和分布式架构感兴趣为了对客户端-服务端通信机制更了解 就实现了这个支持注册中心 发布订阅 异步调用功能的JsonRPC框架。 RPC 调用流程简要总结简洁专业版 客户端通过统一接口call进行rpc调用把函数名method参数(参数名值)封装进RpcRequest并用JSON:Value格式存储再进行序列化把JOSN:Value转化为string对象最后通过应用层通信协议LVProtocol添加上报头通过TCP发送到服务端。 rpc服务端接收到数据后先根据LV协议从缓冲区中获取完整的报文去掉报头 获取正文body字段再进行反序列化转为JSON:Value格式根据里面的method字段 路由找本地对应的服务描述对象 进行参数检测 没有问题进行函数调用返回的结果也是JSON:Value类型序列化 添加报头 TCP返回给客户端。 一、项目背景与整体架构 你这个 RPC 框架项目的初衷是什么你为什么要做这个项目 主要是想了解一下网络通信和分布式架构为了对服务端-客户端的通信机制更了解就实现了这个rpc项目。 你的 RPC 框架支持哪些核心功能模块请简要介绍每个模块的作用和之间的协作流程。 主要有三个大的功能1.rpc调用模块 2.服务发现/注册模块 3.主题发布与订阅模块。 1.rpc模块对内本地维护了一张表函数名method对应服务描述对象包含method 参数类型 返回值类型  回调函数 参数的检测check()给Dispathcer消息派发模块提供处理rpc请求的回调函数根据请求中的method函数中找到对应的服务描述对象进行调用并返回结果应答。 2.服务发现/注册模块 整个rpc的流程不是客户端直接向服务端发送rpc请求。而是1.服务提供者也就是rpc服务端先向注册中心发送注册请求让注册中心知道我能提供什么服务。2.客户端要先向注册中心发起服务发现请求注册中心再返回能提供该服务的主机地址列表这里会有一个轮询服务 来选择其中一个主机地址 让客户端进行rpc调用。给Dispatcher提供服务发现/注册请求的回调处理函数。 3.主题操作模块  我们这个rpc框架会提供关于主题的操作我们可以创建主题/取消主题/订阅/取消订阅 主题消息发布。对内会维护好两种表1.maptopic_name,topic主题名 主题间的映射 2.mapconn,subcribe连接  订阅者这样就知道每个主题的订阅者有哪些每个订阅者的订阅主题有哪些。进行主题消息发布时根据topic中的订阅者列表给订阅者主动推送消息进行广播。给Disathcer提供回调函数处理主题操作/发布请求 你为什么选择自定义 JSON-RPC 协议和 gRPC 或 Thrift 相比你的设计有什么优势或不足 用JSON的话JSON反序列化和序列化操作更简单 其他的没有了解过。 二、客户端与服务端机制 客户端是如何发起一个 RPC 调用的整个请求从发起到响应的流程是怎样的 1.首先要先获取rpc服务端的地址有两种情况1.通过服务发现进行获取服务端地址。具体流程是 rpc客户端里面是有个服务发现客户端向注册中心进行服务发现注册中心返回能提供该服务的主机地址服务发现客户端再根据负载均衡策略 也就简单的轮询 选择其中的一个给rpc客户端进行rpc调用。2.或者rpc不启动服务发现直接传入服务端地址 进行rpc调用。 2.创建服务端和客户端连接先从连接池中有没有对应的连接有获取 没有创建连接进行rpc调用结束后放入连接池。 3.创建rpc请求并发送rpc客户端给外部提供call函数 里面是通过Requestor模块的send()函数进行发送rpc请求的。 4.Dispatcher模块进行消息派发Dispathcer模块消息回调函数onMessage 获取消息根据消息的类型进行派发调用对应服务端提供的回调函数也就是rpc服务端rpc_router向Dispatcher模块注册的onRpcRequest()函数. 5.rpc服务端进行本地路由根据请求消息里面的method函数 找对应的服务描述对象进行参数检测并调用生成结果响应并返回。 6.Dispatcher派发应答Requstor请求消息发送的模块提供onResponse()处理返回的应答根据消息唯一的ID找对应的请求消息并设置结果/进行回调。 你在服务端如何注册一个服务方法具体在哪个模块处理服务注册 1.首先rpc服务端模块 里面会包含一个服务注册的客户端当服务端本地新上线了一个服务 除了本地进行记录还得向服务注册中心通过服务注册客户端发送服务注册消息。 2.服务注册中心会像Dispathcer模块注册onServiceRequest()回调函数处理服务注册/发现的请求消息后续操作就是跟新该服务的服务提供者列表并给发现过该服务的发现者进行服务上线通知。 客户端怎么实现“同步调用”你是怎么保证调用阻塞等待返回的用了哪些 C 特性 1.rpc客户端会提供3中call函数 其中同步call里面创建msg消息并调用Requestor模块中的同步send但这个同步send里面就是调用异步send外部等待get()进行阻塞等结果响应返回过来 在请求描述中的promise对象进行set_value设置结果后 外部get()解除阻塞 从而达到同步的效果。 2.这里我是采用了promisefuture来完成阻塞等待返回的future对象get()进行阻塞等待 直到promise对象set_value才会停止阻塞。 3.同步send()调用异步send()体现函数重载 C多态特性 三、消息处理与分发机制 Dispatcher 模块的作用是什么你是如何实现“消息类型到回调函数”的映射的 1.Dispathcer模块 简单来说是消息分发处理模块根据消息的类型调用对应模块注册的回调函数进行派发处理。 2.这里我们用一共哈希表map完成消息类型到回调函数的映射的但这里有两中处理方法。 第一种就是map的value值就是存储的回调函数但这就需要注册的所有回调函数类型相同才能统一存储在map中。回调函数的参数都是两个1.BaseConnect::ptr连接可以基类接收 2.消息类型 当然也可以用BaseMessage::ptr基类接收但实际上传入的对象的对应的子类对象。这样虽然可以用map统一管理但我们必须在回调函数中进行判断传入的消息对象是不是对应的子类类型我们必须要去猜是不是如果不是需要怎么处理后续新增了其它消息子类是不是还需要更改逻辑处理这明显不符合开闭原则。 这里项目中采用的第二种方法即第二个参数就是用对应子类对象指针来接收。但这样函数类型不一样还这么统一管理 这里我是通过map存储一个同一个父类指针通过虚函数调用机制调用对应的子类对象 里面的回调函数。我先创建一个父类 里面有一个虚函数用模板类根据消息类型创建对应的子类这些子类继承于父类 并重写父类里面的虚函数写入自己回调函数的处理逻辑。 简单来说就是 多态(虚函数调用机制)模板类继承 让map统一管理不同类型的回调函数 你是怎么实现类型安全的消息派发机制的为啥不用函数指针而是用多态模板 各个模块在创建时 向Dispatcher模块注册处理消息的回调函数 传入的参数有1.消息类型 2.回调函数。Dispatcher里面通过模板函数根据消息类型 生成不同的子类里面重写的虚函数再调用传入的回调函数。在map存储子类对象 用它们的父类统一接收。 后面调用的时候根据类型找到map存储的父类指针根据虚函数调用机制 调用对应子类重写的虚函数 完成回调处理。 为什么不用函数指针主要还是不想让回调函数用BaseMessgae::ptr接收子类对象接收了里面还得判断 把父类指针dynamic_pointer_cast转换为子类指针如果转换失败了 会返回空指针需额外判断处理。 JsonRequest 和 JsonResponse 有哪些子类它们的继承结构设计的初衷是什么 1.JsonRequest 请求类有三个子类 分别对应三个主要功能。1.RpcRequest rpc调用请求         2.ServiceRequest 服务请求类 3.TopicRequest 消息请求类. 2.同理JsonResponse 应答类也根据功能分为三个。 这样根据父类生成子类主要还是让一些共同需要的部分放在基类中子类再根据自己需要来自己实现函数 成员变量。比如说应答类都需要rcode响应码就可以放在响应基类中 check()检测响应字段是否正确。如果子类需要根据自己定义的字段实现check()也可以重写。 这样的好处 新增子类类型只需继承父类并实现即可符合开闭原则。整体的结构也更清晰。 四、注册中心与服务发现机制 服务注册中心是如何工作的服务端是如何注册自己的服务信息的 注册中心PDManager可以分为两个部分1.ProviderManager服务提供者管理 2.DiscovererManager服务发现者管理。完成服务注册 服务发现 服务上线/下线操作。 1.Pro服务提供者管理 有两张表mapmethod,vectorPro服务方法能被哪些服务提供者提供mapconn,Pro连接到提供者。Pro里面有自己能提哪些方法的列表vectormethod。 2.Dis服务发现者管理 也是有两种表mapmethod,vectorDis该method方法被哪些发现者发现了mapconn,Dis连接到发现者。Dis里面有自己发现过哪些方法的列表vectormethod 根据这些结构 并给Dispatcher模块注册onServiceRequset()回调函数处理服务发现/注册请求消息。 1.服务注册(conn给注册中心说自己能提供method方法) 根据conn从mapconn,Pro找提供者mapmethod,vectorPro新增method服务提供者Pro提供者内部新增提供方法服务上线通知 给发现过该method方法的发现者进行通知返回注册成功应答         1.根据conn从mapconn,Pro找提供者先找连接的提供者如果没有就新建并加入map中         2.mapmethod,vectorPro新增服务提供者从mapmethod,vectorPro方法对应的提供者列表中新增服务者         3.Pro提供者内部新增方法对Pro里面的方法提供列表vectormethod新增方法         4.服务上线通知Dis服务发现者中1.从mapmethod,Dis找该方法被哪些发现者发现了并从每个Dis发现者客户端发送服务上线通知         5.给服务注册客户端 发送注册成功应答 2.服务发现(conn想发现能提供method方法的提供者地址) 根据conn从mapconn,Dis找发现者mapmethod,vectorDis新增method服务发现者Dis发现者内部新增发现的方法返回应答(包含该method方法提供者地址)         1.根据conn从mapconn,Dis找发现者先找连接的发现者如果没有就新建并加入map中         2.mapmethod,vectorDis新增method服务发现者从mapmethod,vectorDis方法对应的发现者列表中新增发现者         3.Dis发现者内部新增发现的方法对Dis里面的方法发现列表vectormethod新增发现         4.返回应答(包含该method方法提供者地址)根据method从服务提供者管理的mapmethod,vectorPro找到能提供该method方法的方法提供者从中获取host地址 组成应答并返回。 3.连接断开(连接断开的回调函数) 分为提供者断开 发现者断开         1.提供者断开提供者的所有方法都要下线 根据发现者管理中mapmethod,vectorDis找每个method方法的发现者进行服务下线通知。最后删除提供者管理中mapconn,Pro服务提供者的管理。         2.发现者断开发现者断开连接不需要通知任何人直接在发现者管理中mapconn,Dis删除对发现者的管理就行。 如果服务端宕机注册中心会怎么处理你做了哪些“心跳检测”或“服务下线”机制 针对这种情况我的项目中没有实现相关的处理但我可以对这种情况处理提个思路心跳检测机制。 服务端每隔一段时间5s会给注册中心发送心跳包 表示自己还可以提供服务注册中心记录每个服务端最后一次心跳时间由定时任务或事件循环周期性检查如果超过一定时间(10s)没上报心跳 就将服务端视为异常注册中心就会断开连接 触发连接断开回调1.服务端提供的每个method中的提供者列表去除该提供者 2.并删除mapconn,Pro对该提供者的管理 3.最后给发现该提供者的方法的客户端发送服务下线的通知。 客户端如何进行服务发现请求发送到注册中心返回的是什么信息 服务发现客户端 构建服务发现请求消息并通过Requestor模块中同步send进行发送Dispatcher模块根据消息类型调用 注册中心注册的回调函数onServiceRequest()处理服务发现请求。 请求发送到注册中心返回的是客户端进行发现method方法的提供者host地址列表后面通过轮询的负载均衡策略选择一个给客户端。 五、主题发布/订阅模块Pub/Sub 你的框架实现了“主题发布/订阅”机制这一块和传统 RPC 调用有什么区别 1.通信方式传统的RPC调用 一般是一个服务端对应一个客户端而主题消息发布是一个服务端对应多个客户端 对订阅该主题的所有客户端进行广播。 2.控制方向传统RPC是客户端端主动发送请求消息而服务端是被动返回应答的。而在主题信息发布中服务端是接收到消息发布请求对订阅主题的客户端是主动进行发送消息。 3.同步 耦合相比传统的同步RPC请求-应答模型我们的主题发布/订阅是基于事件驱动模型异步非阻塞 客户端不需要阻塞等待响应由服务端主动推送。解耦性强 发布者不需要知道订阅者是谁只需要向主题服务端发布消息就可以。 对比维度传统 RPC 调用主题发布/订阅控制方向客户端主动请求服务端主动推送通信方式一对一一对多同步性同步阻塞等待异步事件驱动耦合性紧耦合松耦合适用场景精准调用事务请求广播、推送、订阅通知实现关键请求封装 回调映射主题管理 回调路由 多个客户端订阅同一个主题你是如何处理每个客户端的回调函数的 首先客户端订阅一个主题服务端接收主题消息发布 向订阅者客户端进行广播主动发送消息如何处理消息需要客户端自己定义。也就是订阅者客户端会向Dispatcher模块注册onPublish()回调函数处理服务端主动推送的消息客户端本地会有哈希表maptopic_name,cb维护主题名到对应回调函数的映射让本地对应的回调函数处理推送的消息。 简单来说就是每个客户端本地会维护好一张哈希表 主题名-该主题回调函数的映射。 客户端发布主题消息服务端是如何进行广播的如何避免回调未注册问题 1.服务端接收到主题发布请求消息会对所有订阅该主题的订阅者客户端进行广播。就要先找到订阅该主题的所有订阅者这就要先说明主题服务端的两种表和两个结构体。         1.订阅者列表mapconn,subcriber::ptr对订阅者进行管理。结构体subcriber订阅者中有订阅的主题名称列表vectortopic_name.         2.主题列表maptopic_name,topic::ptr对主题进行管理。结构体topic主题中有订阅该主题的订阅者列表vetorsub 提供主题列表maptopic_name,topic找到对应主题topic里面就有对应该主题的所有订阅者遍历订阅者列表直接通过底层send进行发送消息。 2.对应服务端主动推送过来的主题消息发布既要在Dispathcer模块注册onPuhlish回调接收还有在本地进行路由调用对应主题的回调消息进行处理。如果我们在订阅后再注册本地对应主题的处理函数有可能刚订阅了主题立马推送过来消息但本地的主题处理函数还没注册成功导致找不到回调函数处理该主题消息。 所以必须在订阅主题前注册主题回调处理函数。如果订阅失败可以del删除刚注册的回调函数。 六、网络与协议设计 你使用了 muduo 网络库它的 Reactor 模型你理解吗客户端和服务端的 loop 有什么区别 Reactor 模型是一种基于事件驱动的并发编程模型它通过事件分发器如 epoll监听所有 socket 的 IO 事件当某个 socket 可读/写时调用事先注册的回调函数进行处理。提供一种 非阻塞、事件驱动 的结构用一个或少量线程高效处理大量并发连接 Muduo 是一个基于 Reactor 模型的高性能 C 网络库 1.muduo网络库中服务端中用的是主从Reactor模型主Reactor是专门监听连接事件的有客户端想要建立连接 就accpet()获取创建连接并返回套接字socket后面就直接交给从Reactor监听连接后续的IO事件。在客户端中也有一个 Reactor即 EventLoop用于管理发送请求、接收响应、处理推送等事件。 2.服务端和客户端的loop最大区别是是否在前台阻塞循环运行。1.服务端是直接把loop线程放在前台循环运行的 2.而客户端是后台运行loop因为客户端需要主动发起连接、请求、注册回调函数等操作具体操作的执行和返回结果处理都是在循环线程中处理的。如果loop循环线程放在客户端前台就会导致阻塞 将影响主线程逻辑。而服务端就是为了处理客户端发送的消息可以循环运行。 你如何解决 TCP 粘包问题数据接收后如何区分一条完整的 JSON 消息 针对TCP粘包问题我是自己定义了应用层通信协议LVProtocol采用定长头部 变长正文的形式。具体来说是 固定头部由三个4字节字段组成消息长度、类型、ID长度后两个变长字段 消息IDbody正文。 接收数据后我们会放在缓冲区中通过访问前4字节获取该报文的长度 再对比当前缓冲区存储数据的大小如果缓冲区存储数据大小该报文长度就认为缓冲区中至少有一条完整消息。 你在客户端和服务端的协议抽象层如 BaseProtocol里做了哪些处理 BaseProtocol里面实现了接口的统一这样上层具象层不需要管底层实现是怎么样的直接用BaseProtocol提供的统一接口就可以 具体接口有3个 1.canProcessed判断缓冲区是否有完整报文 2.onMessage从缓冲区中解析完整报文(去报头反序列化) 3.serialize 准备应答(序列化添报头)。BaseProtocol底层具体实现是自定义实现的LVProtocol协议后续换其它协议只需实现对应的 BaseProtocol 子类即可不会影响上层代码 符合开闭原则。 七、扩展性与项目亮点 你这个框架的扩展性在哪里体现如果后续想加负载均衡或限流模块怎么接入 我的项目解耦性好新增业务时 不会影响原有业务把消息的回调处理函数注册给Dispatcher模块就可以新增消息类型 继承父类并实现自己需要的字段/函数就行。 这个不了解。 标准回答 一、框架扩展性的体现 我的框架在架构设计上非常注重模块解耦与可扩展性主要体现在以下几个方面 ✅ 1. Dispatcher 模块实现了消息分发中心 所有模块之间不直接调用彼此的逻辑而是通过 Dispatcher 注册和派发消息 每类消息有唯一的 mtype 类型编号 每个模块通过 dispatcher.registerHandlerMessageType(type, callback) 注册自己的消息处理函数 新增功能只需要 定义新的消息类型继承 JsonMessage 实现处理逻辑 注册到 Dispatcher 即可无需改动原有代码。 体现了开闭原则对扩展开放对修改封闭。 ✅ 2. 消息继承体系保证扩展性和统一性 所有消息统一继承自 BaseMessage - JsonMessage 不同功能子模块RPC、服务注册、发布订阅都基于该结构 如果未来要增加新的子系统如监控、配置下发只需要继承 JsonMessage 并实现新的 Request/Response 即可 统一的编码/解码流程由 BaseProtocol 层抽象新增协议或更换底层实现对业务层完全无感。 二、如何扩展限流、负载均衡模块 ✅ 1. 负载均衡模块扩展方式 客户端发起 RPC 请求前会先调用服务发现模块获取服务地址列表如 3 个提供者 IP。 当前默认是 轮询策略在 RpcClient 模块中选择一个服务端。 扩展方式 定义一个策略接口类如 class LoadBalancer { virtual Address select(const vectorAddress) 0; } 实现不同策略子类如轮询、最小连接数、权重 hash 在 RpcClient::call() 或 RpcClient::getConnection() 内注入该策略类 实际运行时按配置动态切换策略甚至可热更新。 ✅ 体现策略模式 运行时可插拔能力 ✅ 2. 限流模块扩展方式 限流属于“请求前过滤控制”目标是防止系统过载可通过以下几种方式接入 接入点在客户端发送请求前即 Requestor::send() 之前判断是否允许发送 实现方式 可以通过一个 RateLimiter 类控制 QPS 支持令牌桶、漏桶算法 拒绝请求时立即返回错误消息 服务端也可以接入限流模块在 Dispatcher 注册的 onRpcRequest() 中判断当前负载情况是否超出阈值做保护性熔断。 你在整个开发过程中最有成就感或最难解决的问题是什么你是怎么解决的 1.异步生命周期管理 2.客户端连接资源管理 1.Rpc调用模块的客户端中会提供 异步future调用call函数promise异步设置结果 上层future get()获取结果。在call函数内部用make_shared创建promise对象并用shared_ptr指针进行管理用输出行参数result返回和promise管理的future对象给上层。由Requestor的send()发送请求并对请求描述对象进行管理。等服务端处理返回应答时Requestor模块接收到响应并找到请求描述对象取出里面promise进行set_value设置结果上层future就绪get()就可以获取结果了。 但问题在于我们的shared_ptrpromiseJSON::Value对象是一个局部对象出了作用域就会析构后面回调函数给promise对象设置结果时promise对象为空这样上层永远获取不到结果。 针对这种情况我采用的是bind值绑定外部保存资源 延长生命周期。bind绑定指向promise对象的shared_ptr指针 。本质就是 让一个生命周期更长的shared_ptr指向promise对象引用计数不为0 promise对象就不会析构从而达到延长生命周期的效果。 这里要注意两点 1.bind值绑定 2.外部拷贝保存资源 1.bind不要用引用绑定如果是引用绑定shared_ptr可能会出现悬垂引用外部还没进行保存就析构了。 2.bind值绑定并不会延长promise对象的生命周期必须在外部保存一份资源 让一个生命周期更长的shared_ptr指向promise才能延长生命周期。具体就是在Requestor里面保存的请求描述对象中拷贝了promise的shared指针。 因此我们的异步futuer调用call函数不是走异步furtuer的send函数而是走异步回调函数。应答返回过来时调用bind绑定的回调函数 在里面set_value设置结果而不是直接设置。 2.关于客户端连接 选择短链接还是长连接 一开始我是选择短链接的方案即客户端调用完就关闭。但这就会有一个问题在rpc调用的时候rpc客户端用Requestor模块send发送完消息 rpc调用结束后该客户端就会析构。但后面服务端返回应答Requestor模块的回调函数中虽然找到请求描述对象 设置结果但客户端没了后续怎么get()获取结果呢回调函数中设置的结果也就没有意义了。 所以在我的项目中 我选择的方案是长连接客户端调用完时连接也不会进行析构。连接不会析构我们就需要对这些客户端连接进行管理。这里我是用连接池对客户端连接进行管理的这样的好处是下次再调用时 相同的话可以复用连接客户端进行rpc调用时 获取到目标主机的地址不是直接建立于目标主机服务端的连接而是在连接池中找有没有连接可以进行复用没有再创建并加入连接池中。后续服务提供者断开连接了处理服务下线的回调函数中会调用_offline_cb删除连接池中的客户端连接。 客户端发起rpc调用时 把连接加入连接池客户端处理服务下线时会删除连接池中对应的连接。 综合以上无论是功能实现还是效率上选择长连接都是更合适的。 1.能支持异步调用 get()获取结果。 2.可以从连接池中复用之前的连接  不用频繁的创建和释放连接提高效率。         如果像短连接频繁创建释放一是会浪费资源 降低效率。二是如果客户端频繁进行rpc调用客户端连接会出现大量TIME_WAIT状态 占用端口号不释放(等待2MSL时间后才会完全关闭 释放端口号)导致端口号资源耗尽 无法向服务端建立起连接。 项目拓展 1.发布/订阅模块如果先启动发布者再启动订阅者能否收到消息怎么做才能让收到消息 不能收到消息 因为目前的做法是当我们发布一条消息到服务器之后服务器会遍历所有的订阅者将这条消息转发给订阅者此时订阅者列表为空当订阅者启动订阅的时候这条消息已经没有了本质上是因为我们在服务器没有对消息进行持久化存储。 每个 Topic 绑定一个消息队列进行消息发布时进行入队操作。每个sub订阅者维护一个消费位置offset 表示读到第几条消息了。进行订阅时 服务端会订阅者的offset开始从队列中取出所有未消费的消息主动推送给订阅者topic主题中还保存每个订阅者的offsetmapconn,offset 推送消息出队列时更新订阅者接收到消息时更新offset这样服务端客户端都保存offset。 简单来说服务端topic用一个队列存储主题消息发布时入队订阅时出队移动offset表示逻辑出队列。 2.为什么要有心跳检测机制 因为rpc调用时 服务端可能会出现故障不再处理请求消息但注册中心还会认为服务端存在 就导致发送到该主机的请求全部失败或超时。引入心跳检测机制让服务端每各一定时间就向注册中心发送消息 表示我还在。注册中心维护一张表 记录服务端也就是服务提供者的状况如果有服务端长时间没有发送心跳检测消息还没断开注册中心就会认为该服务端异常 断开连接并给对应发现者进行服务下线通知 以及删除对该服务的管理。 在实际的 RPC 框架运行过程中服务端可能会因故障、死循环、崩溃等原因停止处理请求但 TCP 连接在底层不会立即断开 注册中心仍然认为该服务节点“在线” 导致路由模块持续将请求发送到失效节点最终全部失败或超时严重影响系统可用性。 解决方案引入服务心跳机制 我们设计了服务端心跳机制具体逻辑如下 服务提供者服务端定时向注册中心发送心跳消息表明自己仍在线且可服务 注册中心维护一张服务状态表记录每个服务节点的最后心跳时间 若某个服务节点超过一定时间如 15 秒未发送心跳注册中心将其判定为“异常离线” 注册中心会立即通知所有订阅者发现者该服务已下线并从服务发现表中移除该节点避免继续路由请求到故障节点 若后续该服务恢复上线重新注册后即可恢复服务。
http://www.w-s-a.com/news/2963493/

相关文章:

  • 网站底部固定代码编写网站
  • 互联网网站建设彭聪24手表网站
  • 网站 尺寸市场调研的基本流程
  • 服装网站建设项目维护与评价书网站开发投入产出分析
  • 微信网站协议书百度指数网址是多少
  • 成品软件网站推荐wordpress邮件内容
  • 怎么做简历的网站局域网搭建的步骤
  • 有啥创意可以做商务网站的前端网站如何做全景图
  • 更合网站制作公司横店网站开发
  • htp免费域名注册网站项目推广方案怎么写
  • 学校网站建设框架一家做特卖的网站
  • 网站建设安全性指标企业网站模板下载需谨慎
  • seo优化软件有哪些品牌网站怎么做seo
  • 郴州网站制作公司在哪里屏显的企业网站应该怎么做
  • 网站页头是什么网络认证登录页面
  • 服务高端网站建设wordpress菜单页面定位
  • 网站信息服务费怎么做分录网站没后台怎么修改类容
  • iis5.1 新建网站wordpress编辑器增加按钮
  • 新手做电影网站好赵县网站建设
  • 宿州网站建设公司哪家好怎么卸载安装好的wordpress
  • 六盘水网站设计wordpress ent
  • 鹤壁网站优化对比色的网站
  • 免费网站推荐货源珠海微网站制作
  • 关键词挖掘网站的推广优化
  • 网站文章排序58同城做公司网站怎修改
  • 建站用什么代码最好做网站要用什么软件
  • 济南企业建站排行榜瑞昌网页设计公司
  • 做庭院的网站山东建设网站公司
  • 深圳微信网站建设网站不做icp备案
  • html网页制作代码站长工具的使用seo综合查询排名