Rust網絡編程實戰:全面掌握reqwest庫的高級用法

一、開篇導引

1.1 對比Python Requests解釋為何reqwest是Rust生態的標桿HTTP客戶端

在Python生態中,Requests 庫以其簡潔易用的API成為了HTTP客戶端的首選。它使得開發者能夠輕松地發送各種HTTP請求,處理響應,而無需過多關注底層細節。然而,Python作為一種解釋型語言,在性能和并發處理方面存在一定的局限性。

Rust的 reqwest 庫則在性能、安全性和并發處理上展現出了強大的優勢。reqwest 是基于Rust的異步運行時構建的,它充分利用了Rust的所有權系統和類型系統,能夠高效地處理大量并發請求,同時保證內存安全。與Python的 Requests 相比,reqwest 在處理高并發場景時,性能提升顯著。例如,在處理大量的API請求時,reqwest 能夠在更短的時間內完成更多的請求,并且占用更少的系統資源。

1.2 適用場景分析:何時選擇reqwest而非hyper/ureq等其他庫

庫名適用場景原因
reqwest高并發的Web服務、API客戶端、爬蟲開發提供了簡潔的API,同時支持異步和同步模式,易于使用和擴展。
hyper底層HTTP服務開發、自定義HTTP協議實現是一個底層的HTTP庫,提供了更細粒度的控制,但API相對復雜。
ureq簡單的HTTP請求、腳本化的網絡操作輕量級的HTTP庫,API簡單,但功能相對較少。

適用場景:在需要處理大量并發請求的場景下,如Web服務的API調用、爬蟲開發等,reqwest 是更好的選擇。而對于需要自定義HTTP協議或進行底層HTTP服務開發的場景,hyper 更合適。如果只是進行簡單的HTTP請求,ureq 則可以滿足需求。

二、核心功能詳解

2.1 基礎篇

2.1.1 同步/異步雙模式配置

reqwest 支持同步和異步兩種模式,開發者可以根據具體需求選擇合適的模式。

// 同步模式(blocking模式)
use reqwest::blocking::get;fn main() -> Result<(), reqwest::Error> {let response = get("<https://httpbin.org/json>")?;println!("Status: {}", response.status());println!("Body: {}", response.text()?);Ok(())
}// 異步模式
use reqwest;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let response = reqwest::get("<https://httpbin.org/json>").await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:同步模式下,程序會阻塞直到請求完成,適合簡單的腳本或對并發要求不高的場景。異步模式下,請求會在后臺執行,程序可以繼續執行其他任務,適合高并發場景。

適用場景:腳本化的網絡操作可以使用同步模式,而高并發的Web服務或爬蟲開發則應使用異步模式。

2.1.2 請求構建器模式(Builder Pattern)

請求構建器模式允許開發者通過鏈式調用的方式構建復雜的請求。

use reqwest;
use std::time::Duration;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let client = reqwest::Client::new();let url = "<https://httpbin.org/post>";let response = client.post(url).header("X-Custom-Header", "value").timeout(Duration::from_secs(30)).basic_auth("user", Some("pass")).send().await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:reqwest::Client::new() 創建一個客戶端實例,通過鏈式調用 post()header()timeout() 等方法可以設置請求的各種參數,最后調用 send() 方法發送請求。

適用場景:需要設置多個請求參數的場景,如發送帶有自定義頭部、認證信息和超時設置的請求。

2.2 進階篇

2.2.1 連接池調優(keep-alive配置)

連接池可以復用已經建立的連接,減少連接建立和關閉的開銷,提高性能。

use reqwest;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let client = reqwest::Client::builder().pool_idle_timeout(std::time::Duration::from_secs(30)) // ?? 空閑連接的超時時間.pool_max_idle_per_host(5) // ?? 每個主機的最大空閑連接數.build()?;let response = client.get("<https://httpbin.org/json>").await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:reqwest::Client::builder() 用于創建一個可配置的客戶端實例,通過 pool_idle_timeout()pool_max_idle_per_host() 方法可以設置連接池的參數。

適用場景:需要頻繁發送請求的場景,如API客戶端或爬蟲開發。

2.2.2 自動重試與超時策略

可以通過自定義重試邏輯和超時設置來處理請求失敗的情況。

use reqwest;
use std::time::Duration;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let client = reqwest::Client::builder().timeout(Duration::from_secs(5)) // ?? 請求超時時間.build()?;let mut retry_count = 0;let max_retries = 3;loop {match client.get("<https://httpbin.org/json>").await {Ok(response) => {println!("Status: {}", response.status());println!("Body: {}", response.text().await?);break;}Err(err) => {if retry_count >= max_retries {return Err(err);}retry_count += 1;println!("Request failed, retrying ({}/{})...", retry_count, max_retries);}}}Ok(())
}

操作原理說明:通過 timeout() 方法設置請求超時時間,使用循環和計數器實現自動重試邏輯。

適用場景:網絡不穩定的環境下,如移動網絡或跨地域的請求。

2.2.3 多部分文件上傳(multipart/form-data)

可以使用 reqwest 進行多部分文件上傳。

use reqwest;
use std::fs::File;
use std::io::BufReader;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let client = reqwest::Client::new();let file = File::open("example.txt")?;let reader = BufReader::new(file);let form = reqwest::multipart::Form::new().text("field1", "value1").part("file", reqwest::multipart::Part::reader(reader).file_name("example.txt"));let response = client.post("<https://httpbin.org/post>").multipart(form).send().await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:使用 reqwest::multipart::Form::new() 創建一個表單實例,通過 text()part() 方法添加表單字段和文件,最后使用 multipart() 方法將表單添加到請求中。

適用場景:需要上傳文件的場景,如圖片上傳、文件備份等。

2.2.4 代理服務器與TOR網絡集成

可以通過設置代理服務器來隱藏請求的真實來源,也可以集成TOR網絡實現匿名請求。

use reqwest;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let proxy = reqwest::Proxy::http("<http://proxy.example.com:8080>")?;let client = reqwest::Client::builder().proxy(proxy).build()?;let response = client.get("<https://httpbin.org/json>").await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:使用 reqwest::Proxy::http() 創建一個代理實例,通過 proxy() 方法將代理添加到客戶端中。

適用場景:需要隱藏請求來源或突破網絡限制的場景,如爬蟲開發、網絡測試等。

2.2.5 Cookie持久化實戰

可以將Cookie存儲到文件中,實現Cookie的持久化。

use reqwest;
use std::fs::File;
use std::io::{Read, Write};
use serde_json;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let client = reqwest::Client::new();let response = client.get("<https://httpbin.org/cookies/set?name=value>").await?;let cookies = response.cookies().cloned().collect::<Vec<_>>();let cookies_json = serde_json::to_string(&cookies)?;let mut file = File::create("cookies.json")?;file.write_all(cookies_json.as_bytes())?;println!("Cookies saved to cookies.json");Ok(())
}

操作原理說明:通過 response.cookies() 方法獲取響應中的Cookie,使用 serde_json 將Cookie序列化為JSON字符串,最后將JSON字符串寫入文件。

適用場景:需要保持會話狀態的場景,如登錄后的后續請求。

2.3 企業級特性

2.3.1 自定義TLS后端(rustls vs native-tls)

reqwest 支持使用 rustlsnative-tls 作為TLS后端。

use reqwest;
use reqwest::ClientBuilder;
use rustls::ClientConfig;
use rustls::RootCertStore;
use webpki_roots::TLS_SERVER_ROOTS;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let mut root_store = RootCertStore::empty();root_store.add_server_trust_anchors(TLS_SERVER_ROOTS.0.iter().map(|ta| {rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(ta.subject,ta.spki,ta.name_constraints,)}));let tls_config = ClientConfig::builder().with_safe_defaults().with_root_certificates(root_store).with_no_client_auth();let client = ClientBuilder::new().use_rustls_tls().tls_config(tls_config).build()?;let response = client.get("<https://httpbin.org/json>").await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:通過 ClientBuilder::new() 創建一個可配置的客戶端實例,使用 use_rustls_tls() 方法指定使用 rustls 作為TLS后端,通過 tls_config() 方法設置TLS配置。

適用場景:對TLS安全性有較高要求的場景,如金融交易、敏感數據傳輸等。

2.3.2 請求/響應攔截器(類似Axios的interceptor)

可以通過自定義中間件實現請求/響應攔截器。

use reqwest;
use reqwest::ClientBuilder;
use reqwest_middleware::{ClientBuilder as MiddlewareClientBuilder, RequestBuilder, Result};
use reqwest_tracing::TracingMiddleware;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let client = ClientBuilder::new().build()?;let middleware_client = MiddlewareClientBuilder::new(client).with(TracingMiddleware::default()).build();let request = middleware_client.get("<https://httpbin.org/json>");let response = request.send().await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:使用 reqwest_middleware 庫創建一個帶有中間件的客戶端,通過 with() 方法添加中間件,中間件可以在請求發送前和響應返回后進行攔截和處理。

適用場景:需要對請求和響應進行統一處理的場景,如日志記錄、錯誤處理等。

2.3.3 分布式追蹤集成(OpenTelemetry)

可以將 reqwestOpenTelemetry 集成,實現分布式追蹤。

use reqwest;
use opentelemetry::global;
use opentelemetry::sdk::trace as sdktrace;
use opentelemetry::trace::Tracer;
use reqwest_middleware::ClientBuilder;
use reqwest_tracing::TracingMiddleware;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let tracer = init_tracer();let client = reqwest::Client::new();let middleware_client = ClientBuilder::new(client).with(TracingMiddleware::default()).build();let span = tracer.start("http_request");let _guard = span.enter();let response = middleware_client.get("<https://httpbin.org/json>").send().await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);span.end();global::shutdown_tracer_provider();Ok(())
}fn init_tracer() -> impl Tracer {let tracer = sdktrace::TracerProvider::builder().with_simple_exporter(sdktrace::stdout::new_exporter()).build();global::set_tracer_provider(tracer);global::tracer("reqwest_example")
}

操作原理說明:使用 opentelemetry 庫創建一個追蹤器,通過 reqwest_middlewarereqwest_tracing 庫將追蹤器集成到 reqwest 客戶端中,在請求發送時記錄追蹤信息。

適用場景:分布式系統中,需要對請求進行追蹤和性能分析的場景。

2.3.4 壓力測試與性能調優指標

可以使用 wrk 等工具對 reqwest 應用進行壓力測試,通過調整連接池大小、超時時間等參數進行性能調優。

配置參數吞吐量(請求/秒)響應時間(毫秒)
默認配置100050
連接池大小=100150040
超時時間=10秒120060

適用場景:需要對應用的性能進行評估和優化的場景,如生產環境的性能調優。

三、實戰項目演示

3.1 構建帶有緩存層的REST API客戶端

可以使用 reqwest 構建一個帶有緩存層的REST API客戶端,減少重復請求。

use reqwest;
use std::collections::HashMap;
use std::time::Duration;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let mut cache: HashMap<String, String> = HashMap::new();let client = reqwest::Client::new();let url = "<https://httpbin.org/json>";if let Some(cached_response) = cache.get(url) {println!("Using cached response: {}", cached_response);} else {let response = client.get(url).timeout(Duration::from_secs(5)).send().await?;let body = response.text().await?;cache.insert(url.to_string(), body.clone());println!("New response: {}", body);}Ok(())
}

操作原理說明:使用 HashMap 作為緩存,在發送請求前先檢查緩存中是否存在該請求的響應,如果存在則直接使用緩存,否則發送請求并將響應存入緩存。

適用場景:需要頻繁訪問相同API的場景,如數據查詢、配置獲取等。

3.2 實現自動切換代理的爬蟲框架

可以使用 reqwest 實現一個自動切換代理的爬蟲框架,提高爬蟲的穩定性。

use reqwest;
use std::time::Duration;
use rand::seq::SliceRandom;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let proxies = vec!["<http://proxy1.example.com:8080>","<http://proxy2.example.com:8080>","<http://proxy3.example.com:8080>",];let mut rng = rand::thread_rng();let client = reqwest::Client::builder().timeout(Duration::from_secs(10)).build()?;let url = "<https://httpbin.org/json>";let mut retry_count = 0;let max_retries = 3;loop {let proxy = proxies.choose(&mut rng).unwrap();let proxy_obj = reqwest::Proxy::http(proxy)?;let proxy_client = client.clone().proxy(proxy_obj);match proxy_client.get(url).send().await {Ok(response) => {println!("Status: {}", response.status());println!("Body: {}", response.text().await?);break;}Err(err) => {if retry_count >= max_retries {return Err(err);}retry_count += 1;println!("Request failed with proxy {}, retrying ({}/{})...", proxy, retry_count, max_retries);}}}Ok(())
}

操作原理說明:首先定義一個代理列表,使用 rand 庫隨機選擇一個代理。創建一個 reqwest 客戶端,并通過 proxy() 方法設置代理。發送請求,如果請求失敗則重試,最多重試 max_retries 次,每次重試時重新選擇代理。

適用場景:Web 爬蟲開發,尤其是在需要突破網站反爬機制或應對網絡限制的情況下,自動切換代理可以提高爬蟲的穩定性和成功率。

3.3 與 Serde 深度集成的類型安全 HTTP 交互

可以結合 reqwestserde 實現類型安全的 HTTP 交互,將響應數據自動反序列化為 Rust 結構體。

use reqwest;
use serde::Deserialize;#[derive(Debug, Deserialize)]
struct ExampleResponse {origin: String,headers: serde_json::Value,
}#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let client = reqwest::Client::new();let url = "<https://httpbin.org/json>";let response = client.get(url).send().await?;let data: ExampleResponse = response.json().await?;println!("Origin: {}", data.origin);println!("Headers: {:?}", data.headers);Ok(())
}

操作原理說明:定義一個 Rust 結構體 ExampleResponse,并使用 serdeDeserialize 特性進行標注。發送 HTTP 請求后,使用 response.json().await? 方法將響應數據自動反序列化為 ExampleResponse 結構體。

適用場景:與 API 進行交互時,需要將響應數據進行結構化處理的場景,如解析 JSON 數據、處理 XML 數據等,類型安全的交互可以避免手動解析數據時可能出現的錯誤。

四、調試技巧

4.1 使用 reqwest - middleware 增強日志

reqwest - middleware 可以幫助我們記錄請求和響應的詳細信息,方便調試。

use reqwest;
use reqwest_middleware::{ClientBuilder, Result};
use reqwest_tracing::TracingMiddleware;
use tracing_subscriber::FmtSubscriber;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let subscriber = FmtSubscriber::builder().with_max_level(tracing::Level::DEBUG).finish();tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");let client = reqwest::Client::new();let middleware_client = ClientBuilder::new(client).with(TracingMiddleware::default()).build();let response = middleware_client.get("<https://httpbin.org/json>").send().await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:使用 tracing_subscriber 配置日志級別為 DEBUG,通過 reqwest_middlewarereqwest_tracing 庫將日志功能集成到 reqwest 客戶端中。在請求發送和響應返回時,會記錄詳細的日志信息。

適用場景:開發和調試階段,需要詳細了解請求和響應信息的場景。

4.2 通過 mitmproxy 抓包分析

mitmproxy 是一個強大的抓包工具,可以攔截和分析 HTTP 請求和響應。

  1. 啟動 mitmproxy:在終端中運行 mitmproxy 命令。
  2. 配置 reqwest 客戶端使用 mitmproxy 代理:
use reqwest;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let proxy = reqwest::Proxy::http("<http://127.0.0.1:8080>")?;let client = reqwest::Client::builder().proxy(proxy).build()?;let response = client.get("<https://httpbin.org/json>").send().await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:啟動 mitmproxy 后,它會在本地監聽 8080 端口。配置 reqwest 客戶端使用該代理,所有的請求和響應都會經過 mitmproxy,可以在 mitmproxy 的界面中查看詳細信息。

適用場景:需要分析請求和響應的具體內容,排查網絡問題的場景。

4.3 常見錯誤代碼速查表

錯誤代碼含義解決方法
CE3023連接池耗盡增加連接池大小,檢查是否有大量未釋放的連接
E0433找不到類型或模塊檢查依賴是否正確安裝,模塊路徑是否正確
E0308類型不匹配檢查變量類型,確保數據類型一致

適用場景:在開發和調試過程中,遇到錯誤代碼時可以快速查找原因和解決方法。

五、擴展閱讀

5.1 與 tower 生態的集成路徑

tower 是一個用于構建異步服務的模塊化框架,reqwest 可以與 tower 生態集成,實現更復雜的中間件和服務組合。

use reqwest;
use tower::ServiceBuilder;
use tower_http::trace::TraceLayer;#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let client = reqwest::Client::builder().build()?;let service = ServiceBuilder::new().layer(TraceLayer::new_for_http()).service(client);let request = reqwest::Request::builder().method(reqwest::Method::GET).uri("<https://httpbin.org/json>").body(None).unwrap();let response = service.call(request).await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:使用 ServiceBuilder 構建一個服務,通過 layer() 方法添加 TraceLayer 中間件,將 reqwest 客戶端作為服務的底層實現。

適用場景:需要構建復雜的異步服務,對請求進行更精細處理的場景。

5.2 基于 reqwest 構建 SDK 的設計模式

可以基于 reqwest 構建 SDK,常見的設計模式有工廠模式、單例模式等。

use reqwest;pub struct MySdk {client: reqwest::Client,
}impl MySdk {pub fn new() -> Self {let client = reqwest::Client::new();MySdk { client }}pub async fn get_data(&self, url: &str) -> Result<reqwest::Response, reqwest::Error> {self.client.get(url).send().await}
}#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let sdk = MySdk::new();let response = sdk.get_data("<https://httpbin.org/json>").await?;println!("Status: {}", response.status());println!("Body: {}", response.text().await?);Ok(())
}

操作原理說明:定義一個 MySdk 結構體,在 new() 方法中創建 reqwest 客戶端。通過 get_data() 方法封裝請求邏輯,提供統一的接口供外部調用。

適用場景:開發面向第三方的 SDK,需要對 reqwest 進行封裝和抽象的場景。

5.3 WASM 環境下的特殊限制

在 WebAssembly(WASM)環境下使用 reqwest 有一些特殊限制,如不支持同步請求,需要使用異步請求。

use wasm_bindgen_futures::spawn_local;
use reqwest;#[wasm_bindgen(start)]
pub async fn main() -> Result<(), reqwest::Error> {let response = reqwest::get("<https://httpbin.org/json>").await?;let text = response.text().await?;console_log!("Response: {}", text);Ok(())
}

操作原理說明:在 WASM 環境下,使用 wasm_bindgen_futures::spawn_local 來執行異步任務,使用 reqwest::get() 方法發送異步請求。

適用場景:開發基于 WebAssembly 的前端應用,需要進行網絡請求的場景。

流程圖和時序圖

自動切換代理的爬蟲框架流程圖

開始
選擇代理
發送請求
請求成功?
處理響應
重試次數達到上限?
結束并報錯
結束

帶有緩存層的 REST API 客戶端流程圖

開始
緩存中是否存在數據?
使用緩存數據
發送請求
處理響應
將響應存入緩存
結束

與 Serde 集成的類型安全 HTTP 交互時序圖

Client Server 發送 HTTP 請求 返回 HTTP 響應 使用 Serde 反序列化響應數據 處理反序列化后的數據 Client Server

Cargo.toml 依賴模板

[dependencies]
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rand = "0.8"
tracing = "0.1"
tracing-subscriber = "0.3"
reqwest-middleware = "0.10"
reqwest-tracing = "0.6"
tower = "0.4"
tower-http = "0.4"
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"

各功能的 MSRV(最低支持 Rust 版本)

功能MSRV
基礎功能1.46.0
異步模式1.46.0
連接池調優1.46.0
自動重試與超時策略1.46.0
多部分文件上傳1.46.0
代理服務器與 TOR 網絡集成1.46.0
Cookie 持久化1.46.0
自定義 TLS 后端1.46.0
請求/響應攔截器1.46.0
分布式追蹤集成1.46.0
與 Serde 集成1.46.0
與 tower 生態集成1.46.0
WASM 環境支持1.46.0

通過以上內容,你可以全面深入地掌握 reqwest 庫的高級用法,無論是在開發生產級的 HTTP 客戶端,還是構建復雜的網絡應用,都能游刃有余。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/79584.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/79584.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/79584.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

k8s中sidecar死循環

序言 怎么發現我的同事們很上進呢&#xff0c;估計做了下賤的事兒吧。 傷不到我&#xff0c;不代表不疼&#xff01; sidecar產生的問題 1 背景 在k8s的環境中&#xff0c;pod的使用越來越多了&#xff0c;也就產生了sidecar容器&#xff0c;在現在的環境中&#xff0c;一個pod…

Day53 二叉樹的層序遍歷

給你二叉樹的根節點 root &#xff0c;返回其節點值的 層序遍歷 。 &#xff08;即逐層地&#xff0c;從左到右訪問所有節點&#xff09;。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* T…

C盤清理技巧分享

一、系統級深度清理 1. 存儲感知自動化 路徑:設置 → 系統 → 存儲 → 開啟「存儲感知」配置策略: 臨時文件:每 1-2 周自動清理回收站:超過 30 天自動清空應用緩存:按需求設置清理頻率進階操作:在「高級存儲設置」中關閉「傳遞優化」(減少更新緩存占用)2. 磁盤清理工具…

面試題--隨機(一)

MySQL事務中的ACID特性&#xff1f; A 原子性 事務是一組SQL語句&#xff0c;不可分割 C 一致性 事務中的SQL語句要么同時執行&#xff0c;即全部執行成功&#xff0c;要么全部不執行&#xff0c;即執行失敗 I 隔離性 MySQL中的各個事務通過不同的事務隔離等級&#xff0c;產生…

Spring Boot資源耗盡問題排查與優化

Spring Boot服務運行一段時間后新請求無法處理的問題。服務沒有掛掉&#xff0c;也沒有異常日志。思考可能是一些資源耗盡或阻塞的問題。 思考分析 首先&#xff0c;資源耗盡可能涉及線程池、數據庫連接、內存、文件句柄或網絡連接等。常見的如線程池配置不當&#xff0c;導致…

Map和Set相關練習

目錄 1、只出現一次的數字 2、寶石與石頭 3、壞鍵盤打字 4、復制帶隨機指針的鏈表 5、大量數據去重 6、大量數據重復次數 7、前K個高頻單詞 1、只出現一次的數字 oj&#xff1a;136. 只出現一次的數字 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 1. 使用…

day45——非遞減數列(LeetCode-665)

題目描述 給你一個長度為 n 的整數數組 nums &#xff0c;請你判斷在 最多 改變 1 個元素的情況下&#xff0c;該數組能否變成一個非遞減數列。 我們是這樣定義一個非遞減數列的&#xff1a; 對于數組中任意的 i (0 < i < n-2)&#xff0c;總滿足 nums[i] < nums[i …

OOM 未觸發 JVM 崩潰的可能原因

1. OOM 未觸發 JVM 崩潰的可能原因? (1) 未配置 JVM 參數強制崩潰? 關鍵參數缺失?&#xff1a; 若未添加 -XX:CrashOnOutOfMemoryError&#xff0c;JVM 在 OOM 時可能僅拋出異常并正常退出&#xff0c;而非崩潰&#xff0c;因此不會生成 hs_err_pid.log。 # 正確配置示例&…

Axios 介紹及使用指南

本文將基于 Axios 原理&#xff0c;安裝及封裝方面展開描述&#xff0c;話不多說&#xff0c;現在發車&#xff01; 一、原理 Axios 中文文檔&#xff1a;起步 | Axios中文文檔 | Axios中文網 賽前科普&#xff1a; 下文將涉及到三個關鍵詞&#xff1a;Axios&#xff0c;Ajax…

C#插件與可擴展性

外接程序為主機應用程序提供了擴展功能或服務。.net framework提供了一個編程模型,開發人員可以使用該模型來開發加載項并在其主機應用程序中激活它們。該模型通過在主機和外接程序之間構建通信管道來實現此目的。該模型是使用: System.AddIn, System.AddIn.Hosting, System.…

Melos 發布pub.dev

確保登錄 置登錄狀態 按照提示操作&#xff0c;先運行&#xff1a; bash dart pub logout 這會清除當前的&#xff08;損壞的&#xff09;登錄信息。 然后再重新登錄&#xff1a; bash dart pub login 這一次它應該會在瀏覽器中打開 Google 登錄頁面&#xff0c;完成登…

4.黑馬學習筆記-SpringMVC(P43-P47)

1.SpringMVC簡介 SpringMVC技術&#xff08;更少的代碼&#xff0c;簡便&#xff09;與servlet技術功能相同&#xff0c;屬于web層開發技術。 SpringMVC是一種基于java實現MVC模型的輕量級web框架。 輕量級指的是&#xff08;內存占用比較低&#xff0c;運行效率高&#xff09;…

【特殊場景應對1】視覺設計:信息密度與美學的博弈——讓簡歷在HR視網膜上蹦迪的科學指南

寫在最前 作為一個中古程序猿,我有很多自己想做的事情,比如埋頭苦干手搓一個低代碼數據庫設計平臺(目前只針對寫java的朋友),比如很喜歡幫身邊的朋友看看簡歷,講講面試技巧,畢竟工作這么多年,也做到過高管,有很多面人經歷,意見還算有用,大家基本都能拿到想要的offe…

CentOS 7 linux系統從無到有部署項目

環境部署操作手冊 一、Maven安裝與配置 1. 下載與解壓 下載地址&#xff1a;https://maven.apache.org/download.cgi?spm5238cd80.38b417da.0.0.d54c32cbnOpQh2&filedownload.cgi上傳并解壓解壓命令&#xff1a; tar -zxvf apache-maven-3.9.9-bin.tar.gz -C /usr/loc…

Odoo:免費開源的軋制品行業管理軟件

Odoo免費開源的軋制品行業管理軟件能夠幫助建材、電線電纜、金屬、造紙包裝以及紡織品行業提高韌性和盈利能力&#xff0c;構筑美好未來。 文 &#xff5c; 開源智造&#xff08;OSCG&#xff09;Odoo金牌服務 提高供應鏈韌性&#xff0c;賦能可持續發展 如今&#xff0c;金屬…

51單片機實驗二:數碼管靜態顯示

目錄 一、實驗環境與實驗器材 二、實驗內容及實驗步驟 1.單個數碼管顯示 2.六個數碼管依次從0~F變換顯示 3.proteus仿真 一、實驗環境與實驗器材 環境&#xff1a;Keli&#xff0c;STC-ISP燒寫軟件,Proteus. 器材&#xff1a;TX-1C單片機&#xff08;STC89C52RC…

學術AI工具推薦

一、基礎信息對比 維度知網研學AI&#xff08;研學智得AI&#xff09;秘塔AIWOS AI開發公司同方知網&#xff08;CNKI&#xff09;上海秘塔網絡科技Clarivate Analytics是否接入DeepSeek? 深度集成&#xff08;全功能接入DeepSeek-R1推理服務&#xff09;? 通過API接入DeepS…

冰川流域提取分析——ArcGIS pro

一、河網提取和流域提取視頻詳細GIS小熊 || 6分鐘學會水文分析—河網提取&#xff08;以宜賓市為例&#xff09;_嗶哩嗶哩_bilibili 首先你要生成研究區域DEM&#xff0c;然后依次是填洼→流向→流量→柵格計算器→河網分級→柵格河網矢量化&#xff08;得到河網.shp&#xff…

【物聯網-RS-485】

物聯網-RS-485 ■ RS-485 連接方式■ RS-485 半雙工通訊■ RS-485 的特點 ■ RS-485 連接方式 ■ RS-485 半雙工通訊 一線定義為A 一線定義為B RS-485傳輸方式&#xff1a;半雙工通信、&#xff08;邏輯1&#xff1a;2V ~ 6V 邏輯0&#xff1a;-6V ~ -2V&#xff09;這里的電平…

解析檢驗平板:設備還是非設備?深入了解其功能與應用(北重鑄鐵平臺廠家)

檢驗平板通常被歸類為設備&#xff0c;因為它們具有特定的功能&#xff0c;并且被用于測試和評估其他設備或產品的性能和質量。檢驗平板通常具有平坦的表面&#xff0c;用于放置要進行測試或檢驗的物品。它們可以用于測量尺寸、形狀、平整度、表面光潔度等參數。 檢驗平板的應…