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

rust的axux框架开启负载均衡和重启自身的方法-会议签到的调优

开启负载均衡和重启自身

  • 更换axum后台的意外
  • 解决的尝试
    • 在caddy反代,使用负载均衡,加多一个节点
    • axum主程序 ip映射信息做全局共享
    • axum重启自身刷新全局共享配置

前期刚实现了rust的后台关键业务.结果出现了两类大问题停止服务.在正用着的时候,出现很多意外,真是刺激…

更换axum后台的意外

1, ip2sta的配置没有在原flask服务重启后,没有导入到redis,导致rust后台无法取到,修改原flask初始redis的代码才解决, 停服一天,
2,rust服务,工作进程被我误退出了,结果所有的地点无法访问签到. 停服一天.
3,开启12小时观察到的,新的rust所在主机,没有使用东8区, 只是8点前无法使用业务数据.修改时区,未再造成停服.
下面说下负载均衡和动态监测可以解决这个问题,同时,

解决的尝试

在caddy反代,使用负载均衡,加多一个节点

更新了Caddyfile文件的handle_path改为handle,避免了一次无用的rewrite.

   redir /ck/test  /rk/test/0

    handle  /rk/*   {
   # handle_path /rk/* 
  # rewrite * /rk{path}
    reverse_proxy  {
        	header_up Host {host}
	       	header_up X-Real-IP {remote}
            health_uri /
            health_interval 5s
            health_timeout 1s
            to  10.180.133.35:6055  192.168.11.179:3001
}
    }
   

目测现在有两处提供服务,并且在一处断开后,只使用能用的那个.

axum主程序 ip映射信息做全局共享

上个文章

Android后端签到flask迁移到rust的axum的过程-签到性能和便携 ,ip2sta,加载到axum的启动配置.这样不要每次redis取值.

/**
 * 连接connection_redis
 */
fn connection_redis() -> redis::RedisResult<Connection> {
    let client = redis::Client::open(REDURL)?;
    let con = client.get_connection()?;
    Ok(con)
}
 
fn init_app_config() -> HashMap<String, String> {
    let mut con = connection_redis().ok().unwrap();
    // 测试是否成功连接Reids
    let keys:Vec<String>= con.hkeys("ip2sta" ).ok().unwrap();
     let mut map=HashMap::new(); 
     for i in keys{
        let v:String= con.hget("ip2sta", &i).ok().unwrap();
   
        map.insert(i,v); 
     }
   
   
     map
}
lazy_static! {
    static ref IP2STA: HashMap<String,String> = init_app_config(); }
#[tokio::main]
async fn main() {

在main主任务启动以前加载一次.就可以如下使用

  .route("/rk/test/",get(somehandle))
  .......
async fn somehandle(){
match  IP2STA.get(&cip) {
        Some(sta)=>  pobsta( State(pool.clone()),formatted,sta,person).await ,
        None => Ok(Html(format!("请联系管理员{:?}未设置~!",&cip))),
       
    }

这造成一个问题,ip2sta无法使用最新的数据.
虽然很久不会更新这个底层数据,但是手动重启不是合适的风格.必须要能让后台自动加载新信息…

axum重启自身刷新全局共享配置

https://zhuanlan.zhihu.com/p/649783802
Axum笔记:配置管理
这里提供了很多刷新的方式,其中state的方式已经被pool占有,lazy_static!是本文用的,剩下的我不理解,
下面是我提供的刷新方式,重启自身
在某个handle启动一个新spawn,即调用如下函数.


use tokio::time::{sleep, Duration}; 
use std::{process,env};

async  fn restartme(){
    let delay = Duration::from_millis(50);
 
    // 在延时后启动新进程
    tokio::spawn(async move {
        // 等待延时
        sleep(delay).await;
           // 获取程序自身的路径
      let me = env::current_exe().expect("Failed to get current exe path");
 
      // 重启程序
      let status = process::Command::new(me).spawn();
   
      match status {
          Ok(_child) => {
              // 如果成功,则退出当前实例
              std::process::exit(0);
          }
          Err(e) => {
              // 如果重启失败,打印错误并退出
              println!("Failed to restart: {}", e);
              std::process::exit(1);
          }
      }
    });
}

这样并不容易,因为当前process肯定占有了tcp端口. 所有子线程的成功判断,应该在tcp还未开始时.而且必须在父线程必须释放端口后再打开,可能tokia的axum 使用了,等待重试,和恰好的判断时机,让程序也就是web服务自己完成了配置加载和重启自身.
在这里插入图片描述


http://www.kler.cn/a/440781.html

相关文章:

  • freeipa 主主搭建
  • ASR-LLM-TTS 实时语音对话助手:语音识别、大模型对话、声音生成
  • Fiddler简单使用
  • 【Lua】Lua 基础语法
  • spring cloud contract http实例
  • C和C++的函数指针
  • 游戏引擎学习第52天
  • 【mybatis】mapper.xml文件DOCTYPE含义
  • 【Rust自学】3.4. 函数和注释
  • LLM常见面试题(16-20题)
  • 牛客--字符串加密
  • 常见软件设计模式介绍:三层架构、MVC、SSM、EDD、DDD
  • 通过使用 contenteditable=“true“,我们彻底防止了 iOS 系统键盘的弹出
  • 家具购物小程序+php
  • Pytest-Bdd vs Behave:选择最适合的 Python BDD 框架
  • AIDD-人工智能药物设计-ChemDraw Mac版pojie安装
  • 基于Spring Boot的数码产品抢购系统
  • 常见的数据结构和应用场景
  • Serverless核心组件、最佳实践及性能优化
  • 向量数据库Faiss C++