网站开发中加入cad功能怎么在印度做网站

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

网站开发中加入cad功能,怎么在印度做网站,东莞住建局局长主动投案,做网站建站wmproxy wmproxy是由Rust编写#xff0c;已实现http/https代理#xff0c;socks5代理#xff0c; 反向代理#xff0c;静态文件服务器#xff0c;内网穿透#xff0c;配置热更新等#xff0c; 后续将实现websocket代理等#xff0c;同时会将实现过程分享出来#xff…wmproxy wmproxy是由Rust编写已实现http/https代理socks5代理 反向代理静态文件服务器内网穿透配置热更新等 后续将实现websocket代理等同时会将实现过程分享出来 感兴趣的可以一起造个轮子法 项目地址 gite: https://gitee.com/tickbh/wmproxy github: https://github.com/tickbh/wmproxy 为什么我们需要主动 主动可以让我们掌握好系统的稳定性假设我们有一条连接不可达连接超时的判定是5秒需要检测失败3次才认定为失败那么此时从我们开始检测到判定失败需要耗时15秒。 如果此时我们是个高并发的系统每秒的QPS是1000我们有三个地址判定那么此时我们有1/3的失败概率。那么在15秒内我们会收到15000个请求会造成5000个请求失败如果是重要的数据我们会丢失很多重要数据。 如果此时客户端拥有重试机制那么客户端在失败的时候会发起重试而且系统可能会反复的分配到那台不可达的系统将会造成短时间内请求数激增可能引发系统的雪崩。 所以此时我们主动知道目标端的系统稳定性极其重要。 网络访问示意图 以下是没有主动健康检查 #mermaid-svg-qXykCez19fDbd2rz {font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qXykCez19fDbd2rz .error-icon{fill:#552222;}#mermaid-svg-qXykCez19fDbd2rz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qXykCez19fDbd2rz .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-qXykCez19fDbd2rz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qXykCez19fDbd2rz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qXykCez19fDbd2rz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qXykCez19fDbd2rz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qXykCez19fDbd2rz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qXykCez19fDbd2rz .marker.cross{stroke:#333333;}#mermaid-svg-qXykCez19fDbd2rz svg{font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qXykCez19fDbd2rz .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qXykCez19fDbd2rz text.actortspan{fill:black;stroke:none;}#mermaid-svg-qXykCez19fDbd2rz .actor-line{stroke:grey;}#mermaid-svg-qXykCez19fDbd2rz .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-qXykCez19fDbd2rz .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-qXykCez19fDbd2rz #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-qXykCez19fDbd2rz .sequenceNumber{fill:white;}#mermaid-svg-qXykCez19fDbd2rz #sequencenumber{fill:#333;}#mermaid-svg-qXykCez19fDbd2rz #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-qXykCez19fDbd2rz .messageText{fill:#333;stroke:#333;}#mermaid-svg-qXykCez19fDbd2rz .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qXykCez19fDbd2rz .labelText,#mermaid-svg-qXykCez19fDbd2rz .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-qXykCez19fDbd2rz .loopText,#mermaid-svg-qXykCez19fDbd2rz .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-qXykCez19fDbd2rz .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qXykCez19fDbd2rz .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-qXykCez19fDbd2rz .noteText,#mermaid-svg-qXykCez19fDbd2rz .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-qXykCez19fDbd2rz .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qXykCez19fDbd2rz .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qXykCez19fDbd2rz .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qXykCez19fDbd2rz .actorPopupMenu{position:absolute;}#mermaid-svg-qXykCez19fDbd2rz .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-qXykCez19fDbd2rz .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qXykCez19fDbd2rz .actor-man circle,#mermaid-svg-qXykCez19fDbd2rz line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-qXykCez19fDbd2rz :root{–mermaid-font-family:“trebuchet ms”,verdana,arial,sans-serif;} 客户端 代理服务器 后端1 后端2 请求数据(0.5s) 连接并请求数据(5s)失败 机器宕机不可达 返回失败0.5s总耗时6s 重新请求数据(0.5s) 请求数据成功(0.2s) 返回数据成功(0.2s) 返回数据成功0.5s(总耗时1.4s) 客户端 代理服务器 后端1 后端2 如果出错的时候一个请求的平均时长可能会达到(1.4s 5s) / 2 (3.2s)比正常访问多了(3.2 - 1.4) 1.8s节点的宕机会对系统的稳定性产生较大的影响 以下是主动健康检查它保证了访问后端服务器组均是正常的状态 #mermaid-svg-2V9OHFjtsSFaB74d {font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-2V9OHFjtsSFaB74d .error-icon{fill:#552222;}#mermaid-svg-2V9OHFjtsSFaB74d .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2V9OHFjtsSFaB74d .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-2V9OHFjtsSFaB74d .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2V9OHFjtsSFaB74d .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2V9OHFjtsSFaB74d .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2V9OHFjtsSFaB74d .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2V9OHFjtsSFaB74d .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2V9OHFjtsSFaB74d .marker.cross{stroke:#333333;}#mermaid-svg-2V9OHFjtsSFaB74d svg{font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2V9OHFjtsSFaB74d .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-2V9OHFjtsSFaB74d text.actortspan{fill:black;stroke:none;}#mermaid-svg-2V9OHFjtsSFaB74d .actor-line{stroke:grey;}#mermaid-svg-2V9OHFjtsSFaB74d .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-2V9OHFjtsSFaB74d .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-2V9OHFjtsSFaB74d #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-2V9OHFjtsSFaB74d .sequenceNumber{fill:white;}#mermaid-svg-2V9OHFjtsSFaB74d #sequencenumber{fill:#333;}#mermaid-svg-2V9OHFjtsSFaB74d #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-2V9OHFjtsSFaB74d .messageText{fill:#333;stroke:#333;}#mermaid-svg-2V9OHFjtsSFaB74d .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-2V9OHFjtsSFaB74d .labelText,#mermaid-svg-2V9OHFjtsSFaB74d .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-2V9OHFjtsSFaB74d .loopText,#mermaid-svg-2V9OHFjtsSFaB74d .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-2V9OHFjtsSFaB74d .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-2V9OHFjtsSFaB74d .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-2V9OHFjtsSFaB74d .noteText,#mermaid-svg-2V9OHFjtsSFaB74d .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-2V9OHFjtsSFaB74d .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-2V9OHFjtsSFaB74d .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-2V9OHFjtsSFaB74d .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-2V9OHFjtsSFaB74d .actorPopupMenu{position:absolute;}#mermaid-svg-2V9OHFjtsSFaB74d .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-2V9OHFjtsSFaB74d .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-2V9OHFjtsSFaB74d .actor-man circle,#mermaid-svg-2V9OHFjtsSFaB74d line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-2V9OHFjtsSFaB74d :root{–mermaid-font-family:“trebuchet ms”,verdana,arial,sans-serif;} 客户端 代理服务器 服务器组(只访问1) 请求数据(0.5s) 定时请求保证存活1检查成功2检查失败 loop [健康检查] 处理客户端数据 请求数据(0.2s) 返回数据成功(0.2s) 返回数据成功(0.5s)(总耗时1.4s) 客户端 代理服务器 服务器组(只访问1) 服务器2出错的时候主动检查已经检查出服务器2不可用负载均衡的时候选择已经把服务器2摘除所以系统的平均耗时1.4s系统依然保持稳定 健康检查的种类 在目前的系统中有以下两分类 HTTP 请求特定的方法及路径判断返回是否得到预期的status或者bodyTCP 仅只能测试连通性如果能连接表示正常会出现能连接但无服务的情况 健康检查的准备 我们需要从配置中读出所有的需要健康检查的类型即需要去重把同一个指向的地址过滤掉 配置有可能被重新加载所以我们需要预留发送配置的方式或者后续类似nginx用新开进程的方式则不需要此处做一个预留。 如何去重 像这种简单级别的去重通常用HashSet复杂度为O(1)或者用简单的Vec复杂度为O(n)以SocketAddr的为键值判断是否有重复的数据。 如何保证不影响主线程 把健康请求的方法移到异步函数用tokio::spawn中处理在健康检查的情况下保证不影响其它数据处理 如果同时处理多个地址的健康检查 每一次健康检查都会在一个异步函数中执行在我们调用完请求后我们会对当前该异步进行tokio::time::sleep以让出当前CPU。 如何按指定间隔时间请求 因为每一次健康请求都是在异步函数中我们不确认之前的异步是否完成所以我们在每次请求前都记录last_request我们在请求前调用HealthCheck::check_can_request判断当前是否可以发送请求来保证间隔时间内不多次请求造成服务器的压力。 超时连接判定处理 利用tokio::time::timeout和future做组合等超时的时候直接按错误处理
部分实现源码 主要源码定义在check/active.rs中主要的定义两个类 /// 单项健康检查 #[derive(Debug, Clone)] pub struct OneHealth {/// 主动检查地址pub addr: SocketAddr,/// 主动检查方法, 有http/https/tcp等pub method: String,/// 每次检查间隔pub interval: Duration,/// 最后一次记录时间pub last_record: Instant, } /// 主动式健康检查 pub struct ActiveHealth {/// 所有的健康列表pub healths: VecOneHealth,/// 接收健康列表当配置变更时重新载入pub receiver: ReceiverVecOneHealth, }我们在配置的时候获取所有需要主动检查的数据 /// 获取所有待健康检查的列表 pub fn get_health_check(self) - VecOneHealth {let mut result vec![];let mut already: HashSetSocketAddr HashSet::new();if let Some(proxy) self.proxy {// …}if let Some(http) self.http {// …}result } 主要的检查源码所有的最终信息都落在HealthCheck中的静态变量里 pub async fn do_check(self) - ProxyResult() {// 防止短时间内健康检查的连接过多, 做一定的超时处理, 或者等上一条消息处理完毕if !HealthCheck::check_can_request(self.addr, self.interval) {return Ok(())}if self.method.eq_ignore_ascii_case(http) {match tokio::time::timeout(self.interval Duration::from_secs(1), self.connect_http()).await {Ok® match r {Ok® {if r.status().is_server_error() {log::trace!(主动健康检查:HTTP:{}, 返回失败:{}, self.addr, r.status());HealthCheck::add_fall_down(self.addr);} else {HealthCheck::add_rise_up(self.addr);}}Err(e) {log::trace!(主动健康检查:HTTP:{}, 发生错误:{:?}, self.addr, e);HealthCheck::add_fall_down(self.addr);}},Err(e) {log::trace!(主动健康检查:HTTP:{}, 发生超时:{:?}, self.addr, e);HealthCheck::add_fall_down(self.addr);},}} else {match tokio::time::timeout(Duration::from_secs(3), self.connecthttp()).await {Ok® {match r {Ok() {HealthCheck::add_rise_up(self.addr);}Err(e) {log::trace!(主动健康检查:TCP:{}, 发生错误:{:?}, self.addr, e);HealthCheck::add_fall_down(self.addr);}}}Err(e) {log::trace!(主动健康检查:TCP:{}, 发生超时:{:?}, self.addr, e);HealthCheck::add_fall_down(self.addr);}}}Ok(()) }结语 主动检查可以及时的更早的发现系统中不稳定的因素是系统稳定性的基石也可以通过更早的发现因素来通知运维介入我们的目的是使系统更稳定更健壮处理延时更少。 点击 [关注][在看][点赞] 是对作者最大的支持