RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Tokio 模塊的優(yōu)雅停機(jī)機(jī)制

科技綠洲 ? 來(lái)源:TinyZ ? 作者:TinyZ ? 2023-09-19 15:26 ? 次閱讀

在進(jìn)行高并發(fā)、網(wǎng)絡(luò)編程時(shí),優(yōu)雅停機(jī)是一個(gè)非常重要的問(wèn)題。在 Rust 語(yǔ)言中,Tokio 是一個(gè)非常流行的異步編程框架,它提供了一些優(yōu)雅停機(jī)的機(jī)制,本文將圍繞 Tokio 模塊的優(yōu)雅停機(jī)進(jìn)行詳細(xì)的講解。

Tokio 模塊簡(jiǎn)介

Tokio 是 Rust 語(yǔ)言中的異步編程框架,它提供了一些基礎(chǔ)的異步編程工具,如異步 IO、任務(wù)調(diào)度等。Tokio 的異步編程模型基于 Future 和 Task,其中 Future 代表異步計(jì)算的結(jié)果,而 Task 則代表異步計(jì)算的執(zhí)行上下文。Tokio 的任務(wù)調(diào)度器會(huì)負(fù)責(zé)管理所有的 Task,并在 Future 完成時(shí)將其推入相應(yīng)的 Task 中執(zhí)行。

優(yōu)雅停機(jī)的意義

在進(jìn)行網(wǎng)絡(luò)編程時(shí),服務(wù)器需要處理大量的請(qǐng)求,而在某些情況下,服務(wù)器需要停止服務(wù)。如果直接關(guān)閉服務(wù)器,會(huì)導(dǎo)致正在處理的請(qǐng)求被中斷,可能會(huì)導(dǎo)致數(shù)據(jù)丟失或者服務(wù)不可用。因此,在關(guān)閉服務(wù)器時(shí),需要進(jìn)行優(yōu)雅停機(jī),即在關(guān)閉服務(wù)器之前,需要等待所有請(qǐng)求處理完畢,并且不再接受新的請(qǐng)求。

Tokio 模塊的優(yōu)雅停機(jī)

在 Tokio 模塊中,提供了一些優(yōu)雅停機(jī)的機(jī)制,包括:

    1. 優(yōu)雅停機(jī)信號(hào)
    1. 優(yōu)雅停機(jī)超時(shí)
    1. 優(yōu)雅停機(jī)任務(wù)

下面將詳細(xì)介紹這些機(jī)制。

優(yōu)雅停機(jī)信號(hào)

優(yōu)雅停機(jī)信號(hào)是一種通知服務(wù)器進(jìn)行優(yōu)雅停機(jī)的機(jī)制。在 Unix 系統(tǒng)中,常用的優(yōu)雅停機(jī)信號(hào)是 SIGTERM 和 SIGINT。當(dāng)收到這些信號(hào)時(shí),服務(wù)器應(yīng)該停止接受新的請(qǐng)求,并等待正在處理的請(qǐng)求完成。

在 Tokio 模塊中,可以使用 tokio_signal 模塊來(lái)監(jiān)聽(tīng)優(yōu)雅停機(jī)信號(hào)。下面是一個(gè)示例代碼:

use tokio::signal::unix::{Signal, SIGTERM, SIGINT};

#[tokio::main]
async fn main() - > Result< (), Box< dyn std::error::Error >> {
    // 創(chuàng)建信號(hào)監(jiān)聽(tīng)器
    let mut sigterm = Signal::new(SIGTERM)?;
    let mut sigint = Signal::new(SIGINT)?;

    // 等待信號(hào)
    tokio::select! {
        _ = sigterm.recv() = > {
            println!("Received SIGTERM, shutting down gracefully...");
        }
        _ = sigint.recv() = > {
            println!("Received SIGINT, shutting down gracefully...");
        }
    }

    Ok(())
}

在上面的代碼中,我們使用 Signal::new 函數(shù)創(chuàng)建了兩個(gè)信號(hào)監(jiān)聽(tīng)器,分別監(jiān)聽(tīng) SIGTERM 和 SIGINT 信號(hào)。然后使用 tokio::select!宏來(lái)等待信號(hào)的到來(lái),如果收到信號(hào),則輸出相應(yīng)的日志信息。

優(yōu)雅停機(jī)超時(shí)

在等待正在處理的請(qǐng)求完成時(shí),可能會(huì)出現(xiàn)請(qǐng)求處理時(shí)間過(guò)長(zhǎng)的情況。為了避免服務(wù)停機(jī)時(shí)間過(guò)長(zhǎng),需要設(shè)置一個(gè)優(yōu)雅停機(jī)的超時(shí)時(shí)間。如果在超時(shí)時(shí)間內(nèi),請(qǐng)求還沒(méi)有處理完成,則直接關(guān)閉服務(wù)器。

在 Tokio 模塊中,可以使用 tokio::time 模塊來(lái)設(shè)置超時(shí)時(shí)間。下面是一個(gè)示例代碼:

use tokio::signal::unix::{Signal, SIGTERM, SIGINT};
use tokio::time::{sleep, Duration};

const GRACEFUL_SHUTDOWN_TIMEOUT: u64 = 30;

#[tokio::main]
async fn main() - > Result< (), Box< dyn std::error::Error >> {
    // 創(chuàng)建信號(hào)監(jiān)聽(tīng)器
    let mut sigterm = Signal::new(SIGTERM)?;
    let mut sigint = Signal::new(SIGINT)?;

    // 等待信號(hào)
    tokio::select! {
        _ = sigterm.recv() = > {
            println!("Received SIGTERM, shutting down gracefully...");
        }
        _ = sigint.recv() = > {
            println!("Received SIGINT, shutting down gracefully...");
        }
    }

    // 等待請(qǐng)求處理完成
    let start_time = std::time::Instant::now();
    while start_time.elapsed().as_secs() < GRACEFUL_SHUTDOWN_TIMEOUT {
        if is_all_request_completed() {
            break;
        }
        sleep(Duration::from_secs(1)).await;
    }

    // 如果請(qǐng)求還沒(méi)有處理完成,則直接關(guān)閉服務(wù)器
    if !is_all_request_completed() {
        println!("Graceful shutdown timeout, closing server...");
    }

    Ok(())
}

fn is_all_request_completed() - > bool {
    // 判斷是否所有請(qǐng)求都已經(jīng)處理完成
    true
}

在上面的代碼中,我們使用 tokio::time::sleep 函數(shù)來(lái)等待請(qǐng)求處理完成,并設(shè)置了一個(gè)超時(shí)時(shí)間。如果在超時(shí)時(shí)間內(nèi),請(qǐng)求還沒(méi)有處理完成,則直接關(guān)閉服務(wù)器。

優(yōu)雅停機(jī)任務(wù)

在等待正在處理的請(qǐng)求完成時(shí),可能需要執(zhí)行一些清理操作,如關(guān)閉數(shù)據(jù)庫(kù)連接、釋放資源等。為了避免這些清理操作被中斷,需要將它們封裝成一個(gè)優(yōu)雅停機(jī)任務(wù),在服務(wù)器關(guān)閉之前執(zhí)行。

在 Tokio 模塊中,可以使用 tokio::task::spawn_blocking 函數(shù)來(lái)創(chuàng)建一個(gè)優(yōu)雅停機(jī)任務(wù)。下面是一個(gè)示例代碼:

use tokio::signal::unix::{Signal, SIGTERM, SIGINT};
use tokio::time::{sleep, Duration};
use tokio::task::spawn_blocking;

const GRACEFUL_SHUTDOWN_TIMEOUT: u64 = 30;

#[tokio::main]
async fn main() - > Result< (), Box< dyn std::error::Error >> {
    // 創(chuàng)建信號(hào)監(jiān)聽(tīng)器
    let mut sigterm = Signal::new(SIGTERM)?;
    let mut sigint = Signal::new(SIGINT)?;

    // 等待信號(hào)
    tokio::select! {
        _ = sigterm.recv() = > {
            println!("Received SIGTERM, shutting down gracefully...");
        }
        _ = sigint.recv() = > {
            println!("Received SIGINT, shutting down gracefully...");
        }
    }

    // 執(zhí)行優(yōu)雅停機(jī)任務(wù)
    let graceful_shutdown_task = spawn_blocking(|| {
        // 執(zhí)行清理操作
        cleanup();
    });

    // 等待請(qǐng)求處理完成
    let start_time = std::time::Instant::now();
    while start_time.elapsed().as_secs() < GRACEFUL_SHUTDOWN_TIMEOUT {
        if is_all_request_completed() {
            break;
        }
        sleep(Duration::from_secs(1)).await;
    }

    // 等待優(yōu)雅停機(jī)任務(wù)完成
    graceful_shutdown_task.await.unwrap();

    // 如果請(qǐng)求還沒(méi)有處理完成,則直接關(guān)閉服務(wù)器
    if !is_all_request_completed() {
        println!("Graceful shutdown timeout, closing server...");
    }

    Ok(())
}

fn is_all_request_completed() - > bool {
    // 判斷是否所有請(qǐng)求都已經(jīng)處理完成
    true
}

fn cleanup() {
    // 執(zhí)行清理操作
}

在上面的代碼中,我們使用 tokio::task::spawn_blocking 函數(shù)創(chuàng)建了一個(gè)優(yōu)雅停機(jī)任務(wù),用于執(zhí)行清理操作。在等待請(qǐng)求處理完成時(shí),我們等待這個(gè)任務(wù)完成,并在關(guān)閉服務(wù)器之前執(zhí)行清理操作。

總結(jié)

在本文中,我們介紹了 Tokio 模塊的優(yōu)雅停機(jī)機(jī)制,包括優(yōu)雅停機(jī)信號(hào)、優(yōu)雅停機(jī)超時(shí)和優(yōu)雅停機(jī)任務(wù)。這些機(jī)制可以幫助我們?cè)诜?wù)器關(guān)閉時(shí),避免數(shù)據(jù)丟失和服務(wù)不可用的問(wèn)題。在實(shí)際應(yīng)用中,我們應(yīng)該根據(jù)具體情況選擇合適的優(yōu)雅停機(jī)機(jī)制,并且在優(yōu)雅停機(jī)任務(wù)中執(zhí)行必要的清理操作。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 模塊
    +關(guān)注

    關(guān)注

    7

    文章

    2695

    瀏覽量

    47431
  • 網(wǎng)絡(luò)編程
    +關(guān)注

    關(guān)注

    0

    文章

    71

    瀏覽量

    10074
  • rust語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    57

    瀏覽量

    3009
  • Tokio
    +關(guān)注

    關(guān)注

    0

    文章

    12

    瀏覽量

    57
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    什么是Tokio模塊 Channel?

    模塊 Channel? Tokio 模塊中的 channel 是一種用于在異步任務(wù)之間傳遞數(shù)據(jù)的機(jī)制。它類似于操作系
    的頭像 發(fā)表于 09-19 15:57 ?955次閱讀

    AsyncRead和AsyncWrite 模塊進(jìn)階用法示例

    Rust 語(yǔ)言是一門高性能、安全、并發(fā)的編程語(yǔ)言,越來(lái)越受到開(kāi)發(fā)者的關(guān)注和喜愛(ài)。而 Tokio 是 Rust 語(yǔ)言中一個(gè)非常流行的異步運(yùn)行時(shí),它提供了一系列的異步 I/O 操作,其中包括
    的頭像 發(fā)表于 09-20 11:41 ?869次閱讀

    第31章 FreeRTOS低功耗之停機(jī)模式

    了外設(shè)的時(shí)鐘控制機(jī)制,在停機(jī)模式下電壓調(diào)節(jié)器可運(yùn)行在正?;虻凸哪J?。此時(shí)在1.8V供電區(qū)域的的所有時(shí)鐘都被停止, PLL、 HSI和HSE RC振蕩器的功能被禁止, SRAM和寄存器內(nèi)容被保留
    發(fā)表于 09-13 20:17

    第22章 RTX低功耗之停機(jī)模式

    轉(zhuǎn)rtx操作系統(tǒng)低功耗是MCU的一項(xiàng)非常重要的指標(biāo),本章節(jié)為大家講解STM32F103和STM32F407的低功耗方式之停機(jī)模式在RTX操作系統(tǒng)上面的實(shí)現(xiàn)方法(RTX本身支持的tickless低功耗
    發(fā)表于 10-09 08:18

    stm32停機(jī)

    大家好,請(qǐng)教一個(gè)問(wèn)題:我用stm32f103c8作為主控通過(guò)功率驅(qū)動(dòng)電路來(lái)控制一個(gè)有刷直流電機(jī),當(dāng)電機(jī)速度增大(增大PWM占空比)到一定程度時(shí),stm32就停機(jī)了,PWM停止沒(méi)有輸出,其他功能也停止
    發(fā)表于 12-19 08:49

    使用tokio實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Client和Server通訊模型

    本系列是關(guān)于用Rust構(gòu)建一個(gè)KV Server的系列文章,內(nèi)容包括用tokio做底層異步網(wǎng)絡(luò)通訊、使用toml文件做配置、protobuf做傳輸協(xié)議、內(nèi)存/RockDB做數(shù)據(jù)存儲(chǔ)、事件通知、優(yōu)雅關(guān)機(jī)、并發(fā)連接限制及測(cè)量監(jiān)控等。
    的頭像 發(fā)表于 09-09 09:45 ?2294次閱讀

    WasmEdge增加了Tokio支持

    看:https://wasmer.io/posts/wasmer-takes-webassembly-libraries-manistream-with-wai WasmEdge增加了Tokio 支持
    的頭像 發(fā)表于 12-05 11:55 ?840次閱讀

    Tokio中hang死所有worker的方法

    原因是 tokio 里的待執(zhí)行 task 不是簡(jiǎn)單的放到一個(gè) queue 里,除了 runtime 內(nèi)共享的,可被每個(gè) worker 消費(fèi)的run_queue[2],每個(gè) worker 還有一個(gè)自己的 lifo_slot[3],只存儲(chǔ)一個(gè)最后被放入的 task (目的是減小調(diào)度延遲)。
    的頭像 發(fā)表于 02-03 16:26 ?975次閱讀

    DC電源模塊短路保護(hù)的機(jī)制

    BOSHIDA DC電源模塊短路保護(hù)的機(jī)制 DC電源模塊短路保護(hù)是指在輸出端短路時(shí),電源自動(dòng)保護(hù)以避免損壞。該保護(hù)機(jī)制通常包括以下幾個(gè)方面: 1. 過(guò)流保護(hù) 當(dāng)輸出端短路時(shí),電源輸出電
    的頭像 發(fā)表于 07-11 11:26 ?1839次閱讀
    DC電源<b class='flag-5'>模塊</b>短路保護(hù)的<b class='flag-5'>機(jī)制</b>

    如何使用Tokio 和 Tracing模塊構(gòu)建異步的網(wǎng)絡(luò)應(yīng)用程序

    ,并在調(diào)試和故障排除時(shí)提供有用的信息。 在本教程中,我們將介紹如何使用 Tokio 和 Tracing 模塊來(lái)構(gòu)建一個(gè)異步的網(wǎng)絡(luò)應(yīng)用程序,并使用 Tracing 來(lái)記錄應(yīng)用程序的行為和性能。我們將從安裝和配置開(kāi)始,然后介紹如何使用 To
    的頭像 發(fā)表于 09-19 15:29 ?682次閱讀

    如何使用 Tokio 模塊的Channel

    Channel 是一種在多線程環(huán)境下進(jìn)行通信的機(jī)制,可以讓線程之間互相發(fā)送消息和共享數(shù)據(jù)。Rust 語(yǔ)言中的 Tokio 模塊提供了一種異步的 Channel 實(shí)現(xiàn),使得我們可以在異步程序中方
    的頭像 發(fā)表于 09-19 15:38 ?667次閱讀

    tokio模塊channel中的使用場(chǎng)景和優(yōu)缺點(diǎn)

    Rust 語(yǔ)言的 tokio 模塊提供了一種高效的異步編程方式,其中的 channel 模塊是其核心組件之一。本教程將介紹 tokio 模塊
    的頭像 發(fā)表于 09-19 15:54 ?785次閱讀

    Tokio 的基本用法

    Tokio 是一個(gè)異步 I/O 框架,它提供了一種高效的方式來(lái)編寫(xiě)異步代碼。它使用 Rust 語(yǔ)言的 Futures 庫(kù)來(lái)管理異步任務(wù),并使用 Reactor 模式來(lái)處理 I/O 事件。 本系
    的頭像 發(fā)表于 09-19 16:05 ?816次閱讀

    Channel模塊的使用方法示例

    是一種用于在異步任務(wù)之間傳遞數(shù)據(jù)的機(jī)制。它類似于操作系統(tǒng)中的管道,可以在不同的異步任務(wù)之間傳遞數(shù)據(jù)。Tokio 模塊
    的頭像 發(fā)表于 09-20 11:47 ?1048次閱讀

    優(yōu)雅停機(jī)是什么?SpringBoot+Nacos+k8s實(shí)現(xiàn)優(yōu)雅停機(jī)

    優(yōu)雅停機(jī)是什么?網(wǎng)上說(shuō)的優(yōu)雅下線、無(wú)損下線,都是一個(gè)意思。
    的頭像 發(fā)表于 02-20 10:00 ?2027次閱讀
    <b class='flag-5'>優(yōu)雅</b><b class='flag-5'>停機(jī)</b>是什么?SpringBoot+Nacos+k8s實(shí)現(xiàn)<b class='flag-5'>優(yōu)雅</b><b class='flag-5'>停機(jī)</b>
    RM新时代网站-首页