使用【docker】+【shell】腳本半自動化部署微服務項目

一.前言

以下是一個基于 ?Docker + Shell腳本? 的半自動化部署方案,包含鏡像構建、容器管理、網絡配置和日志監控等核心功能,適用于大多數Web應用或微服務項目。

二?.目錄結構

在這里插入圖片描述

三.腳本代碼實現

1.?Shell腳本實現 (deploy.sh)

#!/bin/bash# 設置顏色代碼
E="\033[0m"
R="\033[1;31m"
G="\033[1;32m"
Y="\033[1;33m"
C="\033[1;36m"BASE_DIR=$(pwd)
BASE_NAME=$(basename "${BASE_DIR}")
DOCKER_COMPOSE_BIN=${DOCKER_COMPOSE_BIN:-docker-compose}# 檢查 docker-compose 是否已安裝
if ! command -v $DOCKER_COMPOSE_BIN &> /dev/null; thenecho "docker-compose could not be found, please install it first."exit 1
fi# 顯示幫助信息
show_help() {echo -e "${Y}---------------------------------------------------------------${E}"echo -e "${Y}|---------------------------  HELP ---------------------------|${E}"echo -e "${Y}---------------------------------------------------------------${G}"echo -e "${C}【啟動服務】./deploy.sh start [all|服務名稱]"echo -e "${G} 示例:./deploy.sh start lm-llmtest-dev\n"echo -e "${C}【停止服務】./deploy.sh stop [all|服務名稱]"echo -e "${G} 示例:./deploy.sh stop lm-llmtest-dev\n"echo -e "${C}【重啟服務】./deploy.sh restart [all|服務名稱]"echo -e "${G} 示例:./deploy.sh restart lm-llmtest-dev\n"echo -e "${C}【顯示所有服務容器名稱】./deploy.sh services"echo -e "${G} 示例:./deploy.sh services\n"echo -e "${C}【加載當前服務群組的所有鏡像】"echo -e "${G} 示例:./deploy.sh load \n"echo -e "######### 指定系統部署初始化【全新部署之前須先執行!!】##########"echo -e "${C}【初始化服務數據掛載目錄】./deploy.sh init datadir [數據目錄,/var/llmtest_dev]"echo -e "${G} 示例:./deploy.sh init datadir /var/llmtest_dev \n"echo -e "${C}【初始化數據庫配置信息】./deploy.sh init database [數據目錄] [數據庫啟動模式(host/docker)] [dockers模式時容器名稱]"echo -e "${G} 示例:./deploy.sh init database /var/llmtest_dev host"echo -e "${G} 示例:./deploy.sh init database /var/llmtest_dev docker lm-mariadb-dev"echo -e "${Y}---------------------------------------------------------------${E}"
}# 加載鏡像
load_images() {echo -e "${G}Loading local images! Please wait...${E}"docker_images=('nginx-1.25.1.tar.gz' 'mariadb-10.6.tar.gz' 'nginx-1.26.tar.gz' 'python-3.11.13.tar.gz' 'redis-7.2.4.tar.gz' 'etcd-v3.5.15.tar.gz' 'elasticsearch-8.12.2.tar.gz' 'langchain-v4.tar.gz')for image in "${docker_images[@]}"; doimage_path="${BASE_DIR}/../images/${image}"if [ ! -f "${image_path}" ]; thenecho -e "${R}Error: File ${image} not found!${E}"continuefiif docker load < "${image_path}" &> /dev/null; thenecho -e "${Y}Loading ${image}\t\t\t ${G}Success${E}"elseecho -e "${Y}Loading ${image}\t\t\t ${R}Failure${E}"fidone
}# 初始化函數
initialize() {if [ "$1" = "datadir" ]; then# 初始化服務數據掛載目錄if mkdir -p "$2"/{llmtest,useradmin,redis,mariadb} && mkdir -p "$2/mariadb/datasource" && mkdir -p "$2/logs/"{useradmin,llmtest}; thenecho -e "${G}Initialization Success.${E}"echo -e "${G}Created directories:${E}"# 打印創建的目錄列表for dir in "$2"/llmtest "$2"/useradmin "$2"/redis "$2"/mariadb "$2"/mariadb/datasource "$2/logs/useradmin" "$2/logs/llmtest"; doif [ -d "$dir" ]; thenecho -e "${G}- $dir${E}"elseecho -e "${R}- Failed to create $dir${E}"fidoneelseecho -e "${R}Initialization Failed.${E}"exit 1fielif [ "$1" = "database" ]; then# 初始化數據庫mkdir -p "$2"/{logs,mariadb} && mkdir -p "$2/mariadb/datasource" && cp -a datasource/* "$2/mariadb/datasource" &&if [ "$3" = "docker" ]; thenlocal container_name=$4container_id=$(docker ps -qf "name=$container_name")echo -e "container_name -> $container_name,container_id -> $container_id"if [ -z "$container_id" ]; thenecho -e "${R}Docker container "name=$container_name" not found.${E}"exit 1fidocker exec $container_id bash "/var/llmtest_dev/mariadb/datasource/init_database.sh" "$2" "$3" && echo -e "${G}Database initialization completed.${E}"elif [ "$3" = "host" ]; thenbash "$2/mariadb/datasource/init_database.sh" "$2" "$3" && echo -e "${G}Database initialization completed.${E}"elseecho -e "${R}Unknown mode: $3${E}"exit 1fi || { echo -e "${R}Database initialization failed.${E}"; exit 1; }elseecho -e "${R}Error: Missing required parameters or invalid initialization option.${E}"exit 1fi
}# 開啟服務
start_service() {if [ "$1" = "all" ]; thenif ${DOCKER_COMPOSE_BIN} up -d --build && ${DOCKER_COMPOSE_BIN} ps -a; thenecho -e "${G}All services started successfully.${E}"${DOCKER_COMPOSE_BIN} logs -felseecho -e "${R}Failed to start all services.${E}"exit 1fielseif [ -z "$1" ]; thenecho -e "${R}Error: Service name is required to start a service.${E}"exit 1fiif ${DOCKER_COMPOSE_BIN} up -d --build "$1" && ${DOCKER_COMPOSE_BIN} ps -a; thenecho -e "${G}Service [$1] started successfully.${E}"${DOCKER_COMPOSE_BIN} logs -f $1elseecho -e "${R}Failed to start the service [$1].${E}"exit 1fifi
}# 停止并移除服務及其容器和相關鏡像
stop_and_remove_service() {local service_name=$1if [ -z "$service_name" ]; thenecho -e "${R}Error: Service name is required to stop and remove a service.${E}"exit 1fi# 使用 docker-compose down 來停止并移除服務及其容器if ! ${DOCKER_COMPOSE_BIN} down -v "$service_name"; thenecho -e "${R}Failed to stop and remove the service [$service_name] and its containers.${E}"fi# 獲取服務使用的鏡像名稱image_names=($(${DOCKER_COMPOSE_BIN} images | grep "$service_name" | awk '{print $2}' | sort -u))echo -e "image_names -> $image_names"if [ ${#image_names[@]} -eq 0 ]; thenfor image_name in "${image_names[@]}"; doif [ -n "$image_name" ]; then# 刪除服務鏡像if docker rmi "$image_name"; thenecho -e "${G}Successfully removed image [$image_name] associated with service [$service_name].${E}"elseecho -e "${R}Failed removed image [$image_name] associated with service [$service_name].${E}"fifidoneelse# 停止并移除容器if docker stop "$service_name" && docker rm "$service_name"; thenecho -e "${G}Successfully stopped and removed container [$service_name].${E}"elseecho -e "${R}Failed to stop and remove container [$service_name].${E}"fifi
}# 定義不應被刪除的基礎鏡像列表
declare -a base_images=("mariadb" "mysql" "redis" "nginx" "python") # 添加其他你不想刪除的基礎鏡像# 停止服務并刪除容器和相關鏡像
stop_service() {if [ "$1" = "all" ]; thenecho -e "${Y}#警告!!刪除項目[${BASE_NAME}]下的所有容器及鏡像將不可恢復,不會刪除外部掛載數據.${E}"# 獲取與compose相關的所有鏡像名稱compose_images=($(${DOCKER_COMPOSE_BIN} images | awk 'NR>1{print $2}' | sort -u))# 過濾出不是基礎鏡像的鏡像filtered_images=()for image_ in "${compose_images[@]}"; doskip_image=falsefor base_image in "${base_images[@]}"; doif [[ "$image_" == *"$base_image"* ]]; thenskip_image=truebreakfidoneif ! $skip_image; thenfiltered_images+=("$image_")fidoneecho -e "The following images will be removed: ${filtered_images[@]}"# 使用 docker-compose down 來停止所有服務并移除它們的容器if ! ${DOCKER_COMPOSE_BIN} down -v; thenecho -e "${R}Failed to stop all services and remove containers.${E}"exit 1elseecho -e "${G}All services stopped and containers removed successfully.${E}"fi# 嘗試刪除每個找到的非基礎鏡像for image_ in "${filtered_images[@]}"; doif [ -n "$image_" ]; then  # 確保鏡像名稱非空if docker rmi "$image_" &> /dev/null; thenecho -e "${G}正在移除構建的服務鏡像 ${image_} ...... \t\tsuccess${E}"else# 如果常規刪除失敗,則嘗試強制刪除if docker rmi -f "$image_" &> /dev/null; thenecho -e "${Y}正在強制移除構建的服務鏡像 ${image_} ... \tsuccess (forced)${E}"elseecho -e "${R}無法移除構建的服務鏡像 ${image_}.${E}"fififidone# 最后打印剩余鏡像列表以供確認docker imageselsestop_and_remove_service "$1"fi
}# 重啟服務
restart_service() {if [ "$1" = "all" ]; then# 調用 stop_service 函數來停止所有服務stop_service "all"# 啟動所有服務if ${DOCKER_COMPOSE_BIN} up -d --build && ${DOCKER_COMPOSE_BIN} ps -a; thenecho -e "${G}All services have been restarted successfully.${E}"${DOCKER_COMPOSE_BIN} logs -felseecho -e "${R}Failed to restart all services.${E}"exit 1fielseif [ -z "$1" ]; thenecho -e "${R}Error: Service name is required to restart a service.${E}"exit 1fi# 對于單個服務,調用 stop_service 來停止服務,并重新構建和啟動服務local service_name="$1"stop_service "$service_name"# 重新構建并啟動指定的服務start_service "$service_name"fi
}deploy_service() {echo -e "${DOCKER_COMPOSE_BIN} config --services"services=$(${DOCKER_COMPOSE_BIN} config --services)# 遍歷每個服務并查找其容器名稱和IDecho -e "${G}>>>>>> 容器名稱和ID <<<<<<\n----------------------${E}"for service in $services; do# 查找與服務名匹配的容器信息containers=$(docker ps --filter "name=$service" --format "{{.Names}}({{.ID}})")if [ -z "$containers" ]; thenecho -e "${Y}Service: $service -> No containers found.${E}"elsecontainer_info=""# 拼接所有容器的名稱和IDfor container in $containers; docontainer_info="${container_info}${container}"done# 輸出服務及其對應的容器信息echo -e "${G}Service: $service ${GREEN}-> Container:${container_info}${E}"fidoneecho -e "----------------------${E}"
}case "$1" inhelp)show_help;;load)load_images;;init)shiftinitialize "$@";;start)shiftstart_service "$@";;stop)shiftstop_service "$@";;restart)shiftrestart_service "$@";;services)shiftdeploy_service "$@";;*)echo -e "${R}Usage: $0 {help|load|init|start|stop|restart|services} [args]${E}"exit 1;;
esac

2.docker-compose.yml文件腳本實現

services:# 管理前端lm-backend-dev:container_name: lm-backend-devimage: lm-backend-devbuild:context: ./dockerfile: dockerfiles/dockerfile-backendcliports:- "8001:80"privileged: truevolumes:- "/etc/localtime:/etc/localtime"- "/var/llmtest_dev/html:/usr/share/nginx/html"- "/var/llmtest_dev/logs/cli:/var/log/nginx"
#      - "/data/mulsen/llmtest_dev/cli/nginx/etc:/etc/nginx"#  docker run --privileged -itd --name mariadb-10.11 -v /var/data/data:/home/data -v /var/data/etc:/opt/maria/etc mariadb:10.11  /sbin/init&&/bin/bash# 數據庫服務配置lm-mariadb-dev:container_name: lm-mariadb-devimage: mariadb:latestports:- "3318:3306"privileged: trueenvironment:- TZ=Asia/Shanghai- MYSQL_ROOT_PASSWORD=nwbot#f76m+*- MYSQL_ROOT_HOST:'%'
#      - MYSQL_DATABASES:nwfaq
#      - MYSQL_USER:nwbot
#      - MYSQL_PASSWORD:nwbot#f76m+*volumes:- "/etc/localtime:/etc/localtime"- "/var/llmtest_dev/mariadb/data:/var/lib/mysql"- "/var/llmtest_dev/mariadb/etc:/etc/mysql/conf.d"- "/var/llmtest_dev/mariadb/datasource:/var/llmtest_dev/mariadb/datasource"
#      - "/var/llmtest_dev/mariadb/datasource:/docker-entrypoint-initdb.d"  # 掛載包含初始化腳本和SQL文件的目錄# 配置文件目錄# redis服務配置lm-redis-dev:image: redis:7container_name: lm-redis-devports:- "6889:6379"privileged: trueenvironment:- REDIS_PASSWORD=fF76M+@963volumes:- "/etc/localtime:/etc/localtime"- "/var/llmtest_dev/redis/data:/data"# 用戶管理服務lm-useradmin-dev:container_name: lm-useradmin-devimage: lm-useradmin-devbuild:context: ./dockerfile: dockerfiles/dockerfile-useradminports:- "8002:5000"privileged: trueenvironment:- SERVER_IP=127.0.0.1- SERVER_PORT=57680volumes:- "/etc/localtime:/etc/localtime"- "/var/llmtest_dev/logs/useradmin:/var/app/logs"
#    environment:depends_on:- lm-redis-dev- lm-mariadb-dev# 評測基礎數據服務lm-test-dev:container_name: lm-test-devimage: lm-test-devbuild:context: ./dockerfile: dockerfiles/dockerfile-testports:- "8003:5000"privileged: trueenvironment:- SERVER_IP=127.0.0.1- SERVER_PORT=8003volumes:- "/etc/localtime:/etc/localtime"- "/var/llmtest_dev/logs/test:/var/app/logs"- "/var/llmtest_dev/test/datasets:/var/app/datasets"depends_on:- lm-redis-dev- lm-mariadb-dev# 評測結果分析服務lm-evaluation-dev:container_name: lm-evaluation-devimage: lm-evaluation-devbuild:context: ./dockerfile: dockerfiles/dockerfile-evaluationports:- "8004:5000"privileged: trueenvironment:- SERVER_IP=127.0.0.1- SERVER_PORT=8004volumes:- "/etc/localtime:/etc/localtime"- "/var/llmtest_dev/logs/evaluation:/var/app/logs"- "/var/llmtest_dev/test/datasets:/var/app/datasets"depends_on:- lm-redis-dev- lm-mariadb-dev##############################################################################

3.數據庫初始化腳本init_database.sh

#!/bin/bash
# 設置顏色代碼
E="\033[0m"
R="\033[1;31m"
G="\033[1;32m"
Y="\033[1;33m"
C="\033[1;36m"
# 獲取傳入的路徑參數和運行模式
BASE_DIR=$1
MODE=$2
echo -e "${Y}BASE_DIR -> $BASE_DIR \033[0m"
echo -e "${Y}MODE -> $MODE ${G}"# 數據庫連接信息
if [ "$MODE" = "docker" ]; thenDB_HOST="localhost"  # 在容器內部使用localhostDB_PORT="3306"DB_PASSWORD="nwbot#f76m+*"
elseDB_HOST="192.168.211.75"  # 根據實際情況設置主機IPDB_PORT="3306"DB_PASSWORD="maria"
fiDB_USER="root"
DB_NAME="test"
SQL_FILE="${BASE_DIR}/mariadb/datasource/test.sql"  # 根據傳入路徑設置SQL文件路徑
echo -e "${Y}SQL_FILE -> $SQL_FILE ${G}"# 創建數據庫
mysql --protocol=TCP  -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASSWORD -e "CREATE DATABASE IF NOT EXISTS \`$DB_NAME\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"# 檢查創建數據庫是否成功
if [ $? -ne 0 ]; thenecho -e "\033[0;31m創建數據庫失敗\033[0m"exit 1
fi# 導入數據
mysql --protocol=TCP -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PASSWORD $DB_NAME < $SQL_FILE# 檢查導入數據是否成功
if [ $? -eq 0 ]; thenecho -e "${G}【數據庫和數據導入】初始化完成\033[0m"
elseecho -e "${G}【導入數據】失敗\033[0m"exit 1
fi

三.總結

通過此方案,可實現從開發到生產的平滑遷移,顯著提升部署效率和一致性。
希望對你有所幫助!

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

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

相關文章

每天一道算法題-兩數相加

給你兩個 非空 的鏈表&#xff0c;表示兩個非負的整數。它們每位數字都是按照 逆序 的方式存儲的&#xff0c;并且每個節點只能存儲 一位 數字。 請你將兩個數相加&#xff0c;并以相同形式返回一個表示和的鏈表。 你可以假設除了數字 0 之外&#xff0c;這兩個數都不會以 0 …

win10搭建opengl環境搭建并測試--輸出立方體球體和碗型并在球體上貼圖

參照本文檔可以完成環境搭建和測試&#xff0c;如果想要快速完成環境的搭建可以獲取本人的工程&#xff0c;包括所用到的工具鏈和測試工程源碼獲取&#xff08;非免費介意務下載&#xff09;&#xff1a;鏈接: https://pan.baidu.com/s/1H2ejbT7kLM9ore5MqyomgA 提取碼: 8s1b …

CIR-Net:用于 RGB-D 顯著性目標檢測的跨模態交互與優化(問題)

摘要 問題一&#xff1a;自模態注意力優化單元和跨模態加權優化單元什么意思&#xff1f; 1 優化中間件結構的作用 位置&#xff1a;位于編碼器和解碼器之間 輸入&#xff1a;編碼器提取的RGB特征&#xff0c;深度特征以及RGB-D特征。 輸出&#xff1a;經過優化的RGB&…

LS-NET-004-簡單二層環路解決(華為銳捷思科)

LS-NET-004-簡單二層環路解決&#xff08;華為銳捷思科&#xff09; 以下是為您準備的二層環路示意圖及解決方案&#xff0c;包含四大廠商配置對比&#xff1a; 一、Mermaid 二層環路示意圖 graph TD SW1 -->|Gi0/1| SW2 SW2 -->|Gi0/2| SW3 SW3 -->|Gi0/3| SW1 SW1…

【正點原子K210連載】第七十六章 音頻FFT實驗 摘自【正點原子】DNK210使用指南-CanMV版指南

第七十六章 音頻FFT實驗 本章將介紹CanMV下FFT的應用&#xff0c;通過將時域采集到的音頻數據通過FFT為頻域。通過本章的學習&#xff0c;讀者將學習到CanMV下控制FFT加速器進行FFT的使用。 本章分為如下幾個小節&#xff1a; 32.1 maix.FFT模塊介紹 32.2 硬件設計 32.3 程序設…

火絨終端安全管理系統V2.0——行為管理(軟件禁用+違規外聯)

火絨終端安全管理系統V2.0&#xff1a;行為管理策略分為軟件禁用和違規外聯兩部分&#xff0c;能夠管理終端用戶軟件的使用&#xff0c;以及終端用戶違規連接外部網絡的問題。 l 軟件禁用 軟件禁用策略可以選擇軟件名單的屬性、添加軟件名單以及設置發現終端使用禁用軟件時的…

FastJson:JSON JSONObject JSONArray詳解以及SimplePropertyPreFilter 的介紹

FastJson&#xff1a;JSON JSONObject JSONArray詳解以及SimplePropertyPreFilter 的介紹 FastJson是阿里巴巴開發的一款專門用于Java開發的包&#xff0c;實現Json對象&#xff0c;JavaBean對&#xff0c;Json字符串之間的轉換。 文章目錄 FastJson&#xff1a;JSON JSONObje…

DEFI幣生態重構加速,XBIT去中心化交易所引領DEX安全新范式

2025年3月18日&#xff0c;全球加密市場在監管與技術共振下迎來結構性變革。去中心化金融&#xff08;DeFi&#xff09;代幣DEFI幣因跨鏈流動性協議升級引發社區熱議&#xff0c;而幣應XBIT去中心化交易所&#xff08;以下簡稱XBIT&#xff09;憑借其鏈上透明驗證機制、無需下載…

解析漏洞總結

首先說下為什么要寫著篇文章&#xff0c;之前學習倒是學過&#xff0c;學完就忘啊&#xff0c;tmd iis 5.x/6.0 這個版本有兩種解析姿勢  一.兩種解析漏洞 1.目錄解析 2./xxx.asp/xx.jpg 簡單說一下是什么意思&#xff0c;這里是先在他服務器跟目錄創建一個名為 xxx.…

前端小食堂 | Day18 - 身份認證の八卦陣

&#x1f510; 今日秘術&#xff1a;JWT/OAuth2 攻防奧義 1. JWT 安全の六合陣法 // &#x1f6ab; 危險操作&#xff1a;未驗證簽名 const decodeUnsafe (token) > JSON.parse(atob(token.split(.)[1])); // ? 安全姿勢一&#xff1a;嚴格簽名驗證 import jwt fro…

將bin文件燒錄到STM32

將bin文件燒錄到STM32 CoFlash下載生成hex文件hex2bin使用下載bin到單片機 CoFlash下載 選擇需要安裝的目錄 在Config中可以選擇目標芯片的類型 我演示的是 stm32f103c8t6 最小系統板 Adapter&#xff1a;燒錄器類型 Max Clock&#xff1a;下載速度 Por&#xff1a;接口類型&am…

【Embedded World 2025:邊緣 AI、存儲革新與 1X nm 工藝重塑嵌入式未來】

Embedded World 2025于3月11-13日在德國紐倫堡舉辦&#xff0c;作為全球嵌入式系統領域頂級盛會&#xff0c;匯聚超千家展商與3萬專業觀眾&#xff0c;聚焦嵌入式智能、安全管理及行業解決方案。展會呈現邊緣AI、低功耗MCU、5G RedCap、新型存儲及車規級技術等前沿方向&#xf…

3.19刷題

P6443 [COCI 2010/2011 #1] TIMSKO - 洛谷 #include<bits/stdc.h> using namespace std; int main(){int n,m,k,maxp0;cin>>m>>n>>k;for(int i0;i<n;i){//男生參加人數if(k3*i<mn&&2*i<m) maxpi;}cout<<maxp;return 0; }P645…

Android NDK --- JNI從入門到基礎的全面掌握 (上)

引言 先問 jni是什么&#xff1f; jni和ndk 的關系&#xff1f; 答&#xff1a; java調用 C、C 的代碼。 兩者一個是調用&#xff0c;一個是用c 、c 寫 。 這兩個問題問出來似乎知道又好像不知道。 正文 jni 概述 定義&#xff1a;java Native Interface 即 java本地接口 …

爬蟲 crawler 入門爬取不設防網頁 并實現無限增生

基礎版本 爬取網頁后直接將前端html代碼不加處理的輸出 # pip3 install requests import requests# request the target URL def crawler():response requests.get("https://www.scrapingcourse.com/ecommerce/")response.raise_for_status()print(response.text)…

C++高頻(四)之c++11新特性

C++面試高頻(四)之c++11新特性 1.簡述C++11有什么新特性?? 自動類型推導(Type Inference):引入了 auto 關鍵字,允許編譯器根據初始化表達式的類型自動推導變量的類型。統一的初始化語法(Uniform Initialization Syntax):引入了用花括號 {} 進行初始化的統一語法,可…

HarmonyOs- UIAbility應用上下文

上下文為何物 上下文在計算機科學領域是一個廣泛存在的概念。是現代操作系統核心抽象概念之一。其本質是環境信息的結構化封裝。 有過開發經驗的都知道&#xff0c;當我們在一個系統上進行開發的時候&#xff0c;無論是Android&#xff0c;HarmonyOs&#xff0c;Linux 等等&a…

Redis解決緩存擊穿問題——兩種方法

目錄 引言 解決辦法 互斥鎖&#xff08;強一致&#xff0c;性能差&#xff09; 邏輯過期&#xff08;高可用&#xff0c;性能優&#xff09; 設計邏輯過期時間 引言 緩存擊穿&#xff1a;給某一個key設置了過期時間&#xff0c;當key過期的時候&#xff0c;恰好這個時間點對…

架構思維:軟件建模與架構設計的關鍵要點

文章目錄 1. 軟件建模的核心概念2. 七種常用UML圖及其應用場景類圖時序圖組件圖部署圖用例圖狀態圖活動圖 3. 軟件設計文檔的三階段結構4. 架構設計的關鍵實踐1. 用例圖&#xff1a;核心功能模塊2. 部署圖&#xff1a;架構演進階段3. 技術挑戰與解決方案4. 關鍵架構圖示例5. 架…

numpy學習筆記14:模擬隨機游走過程(一次實驗)

numpy學習筆記14&#xff1a;模擬隨機游走過程(一次實驗) 隨機游走是一個對象在離散時間步中的隨機移動&#xff0c;每次移動的方向和步長由概率決定。在用戶提供的代碼中&#xff0c;步長數組steps的每個元素是-1或1&#xff0c;代表向左或向右移動一步。np.random.choice的作…