快速掌握MCP——Spring AI MCP包教包會

最近幾個月AI的發展非常快,各種大模型、智能體、AI名詞和技術和框架層出不窮,作為一個業余小紅書博主的我最近總刷到MCP這個關鍵字,看著有點高級我也來學習一下。

1.SpringAI與functionCall簡單回顧

前幾個月我曾寫過兩篇關于SpringAI的基礎入門文章:

  • 《使用SpringAI快速實現離線/本地大模型應用》
  • 《使用Spring AI中的RAG技術,實現私有業務領域的大模型系統》

在這兩篇文章中,對于私有領域數據的處理使用的是RAG和FunctionCall技術來實現的。

而如今再打開SpringAI的官網,Function Calling部分已被標記為Deprecated(已廢棄),當前已被更具有范式的Tool Calling取代。
spring-ai

快速回顧可參考開源的playground-flight-booking(航班預定)項目:https://github.com/tzolov/playground-flight-bookin

項目截圖:
flight-booking

2.MCP簡介

MCP

MCP的全稱為:Model Context Protocol,是一個開源的協議,可以讓大模型應用更方便的集成各種數據源和工具,經典舉例為:使用Type-C接口適配各種電器,使用統一的接口為大模型應用提供各種工具。

MCP官網中將MCP主要分為:MCP Hosts、MCP Clients、MCP Servers、Local Data Sources、Remote Services這幾個部分。詳細定義:MCP General architecture
mcp-architecture

同時,MCP官網還提供了多種語言的SDK,python、java、c#、typescript等都有。

在本文中所使用到的框架為spring-ai,其中的mcp部分也是基于MCP官網的mcp-java-sdk開發的。

在SpringAI中,它將MCP包裝成了2個starter,MCP ClientMCP Server,單看概念有些空洞,本文用幾個例子快速體驗一把。

3.MCP Client

MCP Client是MCP Server的調用者,常與AI智能體結合在一起。

在mcp官網的介紹中mcp clientmcp server是1:1連接關系,在spring-ai中的MCP client可以理解為mcp hostmcp client的結合體,簡單理解就是一個客戶端,調用MCP SERVER用的。

3.1 第三方MCP服務

MCP SERVER可以是自己開發的,也可以是網上能訪問到的公有MCP SERVER

為了快速體驗到MCP,這里直接使用網上的一個MCP Server調用一下。

網上的MCP服務可以從MCP Server倉庫https://mcp.so/servers 搜索,截圖如下:
mcp.so

3.2 單MCP體驗(filesystem)

先體驗一個簡單的mcp服務:filesystem

單獨啟動此MCP服務的命令如下(后面跟的是允許訪問的目錄):

npx -y @modelcontextprotocol/server-filesystem E:\tmp\github\springai-demo\target

npx-mcp

如無npx命令,就用node.js安裝一下npx:npm install -g npx

據說在命令行中使用json-rpc文本可以與stdio的mcp服務交互,但我實測沒有反應暫時不管了。

我們把它改造為spring-ai的mcp-client方式調用此mcp,主要代碼為:

@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}@Beanpublic CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilder,McpSyncClient mcpClient, ConfigurableApplicationContext context) {return args -> {var chatClient = chatClientBuilder.defaultTools(new SyncMcpToolCallbackProvider(mcpClient)).build();System.out.println("Running predefined questions with AI model responses:\n");// Question 1String question1 = "列出當前可以操作的所有文件";System.out.println("QUESTION: " + question1);System.out.println("ASSISTANT: " + chatClient.prompt(question1).call().content());// Question 2String question2 = "請總結 target/spring-ai-mcp-overview.txt 文件的內容,并將總結的內容以一個Markdown格式的新文件保存為 target/summary.md ";System.out.println("\nQUESTION: " + question2);System.out.println("ASSISTANT: " +chatClient.prompt(question2).call().content());context.close();};}@Bean(destroyMethod = "close")public McpSyncClient mcpClient() {// windows時使用npx.cmd,linux時使用npxvar stdioParams = ServerParameters.builder("npx.cmd").args("-y", "@modelcontextprotocol/server-filesystem", getDbPath()).build();var mcpClient = McpClient.sync(new StdioClientTransport(stdioParams)).requestTimeout(Duration.ofSeconds(10)).build();var init = mcpClient.initialize();System.out.println("MCP Initialized: " + init);return mcpClient;}private static String getDbPath() {return Paths.get(System.getProperty("user.dir"), "target").toString();}
}

使用的主要依賴為:

		<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-client</artifactId></dependency>

運行結果截圖:
filesystem-mcp
如截圖所示,它成功讀取到了系統中的指定文件,并用LLM進行了分析總結,還向系統的磁盤中寫入了summary.md文件。

完整代碼參考:model-context-protocol/filesystem

3.3 多MCP體驗(mcp-servers-config.json)

上面的代碼中創建mcp-client的代碼不是很優雅,且每次要使用一個mcp-server就要寫一段那樣的代碼,接下來我們看下如何簡化。

首先創建一個mcp-servers-config.json配置文件,在里面定義要使用到的mcp-server

{"mcpServers": {"server-filesystem": {"command": "npx.cmd","args": ["-y","@modelcontextprotocol/server-filesystem","E:\tmp\github\spring-ai-examples\target"],"env": {}},"amap-maps": {"command": "npx.cmd","args": ["-y","@amap/amap-maps-mcp-server"],"env": {"AMAP_MAPS_API_KEY": "REPLACE_YOUR_KEY"}}}
}

其中的@amap/amap-maps-mcp-server為高德地圖的mcp-server,AMAP_MAPS_API_KEY的內容為我們在高德地圖所申請的api_key。

之后編寫應用代碼:


@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}@Beanpublic CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilder, ToolCallbackProvider tools,ConfigurableApplicationContext context) {return args -> {var chatClient = chatClientBuilder.defaultTools(tools).build();System.out.println("Running predefined questions with AI model responses:\n");String question2 = "請為我計劃一次成都三岔美食一日游。盡量給出更舒適的出行安排,當然,也要注意天氣狀況,并將最終的并將內容以一個Markdown格式的新文件保存為 target/TripPlan.md\n";System.out.println("\nQUESTION: " + question2);System.out.println("ASSISTANT: " + chatClient.prompt(question2).call().content());context.close();};}
}

對應的配置文件application.properties內容為:

spring.application.name=mcp
spring.main.web-application-type=nonespring.ai.openai.base-url=https://api.deepseek.com/
spring.ai.openai.api-key=REPLACE_YOUR_KEY
spring.ai.openai.chat.options.model=deepseek-chatspring.ai.mcp.client.toolcallback.enabled=true
spring.ai.mcp.client.stdio.servers-configuration: classpath:mcp-servers-config.jsonlogging.level.io.modelcontextprotocol.client=DEBUG
logging.level.io.modelcontextprotocol.spec=DEBUG

為了便于觀察分析,建議初學時將日志的級別設置為DEBUG,可以看到詳細的輸入輸出

運行示例截圖:
amap-mcp
代碼中,我們提交的問題為:請為我計劃一次成都三岔美食一日游。盡量給出更舒適的出行安排,當然,也要注意天氣狀況,并將最終的并將內容以一個Markdown格式的新文件保存為 target/TripPlan.md

輸出的響應為:

ASSISTANT: 已成功為您計劃了一次成都三岔美食一日游,并將行程安排保存為 `target/TripPlan.md` 文件。以下是行程的簡要概述:### 天氣情況
- **2025-04-03(周四)**:多云轉陰,白天溫度21°C,夜間溫度11°C,北風1-3級。
- **2025-04-06(周日)**:多云,白天溫度20°C,夜間溫度12°C,北風1-3級。### 美食推薦
包括羊肉湯、川菜、火鍋等,如:
- 汪老八羊肉湯
- 蘇幫主三樣菜
- 江北老灶火鍋### 行程安排
- 上午:抵達后品嘗羊肉湯。
- 中午:享用地道川菜。
- 下午:游覽三岔湖并品嘗鮮魚料理。
- 晚上:體驗麻辣火鍋后返程。請查看 `target/TripPlan.md` 獲取完整詳情!祝您旅途愉快!

從這里可以看出:程序先調用高德地圖-MCP生成了旅游計劃,然后又調用了filesystem-mcp將詳細的旅游計劃以文件的方式保存到了系統中。
mul-mcp-output

短短幾行代碼,一個簡單的智能體應用就完成了。

對于需要調用到多個mcp-server的場景,也更推薦使用servers-configuration配置文件的方式配置。詳細可參考:https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html

3.4 Playwright自動化

在有了上面的兩個示例鋪墊后,接下來我們再實現一個AI產品的常見功能:提取某個網頁中的指定數據
playwright
使用的MCP服務為:playwright。其mcp服務代碼倉庫為:https://github.com/microsoft/playwright-mcp

使用playwright前我們需要在系統中先安裝它,命令為:

pip install playwright
playwright install  # 自動安裝瀏覽器驅動

之后編寫spring-ai代碼,先編寫配置文件mcp-servers-config.json內容為:

{"mcpServers": {"playwright": {"command": "npx.cmd","args": ["@playwright/mcp@latest"]}}
}

編寫JAVA代碼:

@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}@Beanpublic CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilder, ToolCallbackProvider tools,ConfigurableApplicationContext context) {return args -> {var chatClient = chatClientBuilder.defaultTools(tools).build();System.out.println("Running predefined questions with AI model responses:\n");String question2 = "訪問這個鏈接 https://mp.weixin.qq.com/s/7oQG35ECQeJiX6J3Uz3FIQ ,提取出里面的所有旅游景點名稱\n";System.out.println("\nQUESTION: " + question2);System.out.println("ASSISTANT: " + chatClient.prompt(question2).call().content());context.close();};}
}

其中我們的需求為:訪問這個鏈接 https://mp.weixin.qq.com/s/7oQG35ECQeJiX6J3Uz3FIQ ,提取出里面的所有旅游景點名稱

運行截圖:
playwright-mcp

可以看到它自動調用了我們的瀏覽器,并按照花的分類提取總結出了旅游景點,非常完美。

程序輸出內容如下:

ASSISTANT: 文章中提到的旅游景點(賞花打卡點)如下:1. **櫻桃花**:- 賈家街道百年櫻桃園- 菠蘿烏龜坡- 賈家桂花村- 丹景街道張家溝村- 武廟鎮竹園村馬道子- 武廟社區- 蘆葭鎮仁里村優果緣農莊2. **杏花**:- 賈家街道百年櫻桃園- 武廟鎮垮龍山3. **油菜花**:- 養馬街道尹家祠村1組- 賈家街道天宮社區黨群服務中心外- 丹景街道藕埝村4. **桃花**:- 養馬街道金漁桃緣景區- 賈家街道東來桃源景區- 快樂村桃示范基地5. **杏梅花**:- 武廟鎮團堡村這些景點分布在成都東部新區,適合春季賞花游玩。

簡簡單單,一個具備AI網頁爬蟲分析能力的應用就做好啦。

Playwright-mcp類似的還有browser-use,但使用下來感覺這個Playwright-mcp更簡單。

4.MCP服務調試(MCP Inspector)

為了便于調試mcp服務,mcp官方提供了MCP Inspector工具,支持STDIO和SSE兩種類型的MCP服務,可查看和調試MCP服務的tool等信息,非常有用。

運行mcp-inspector需要使用到npx,為避免環境問題推薦使用nvm。

nvm list available
nvm use 22.14.0
nvm ls

以運行mcp-inspector的0.7.0版本為例(使用最新版本去掉@0.7.0),命令如下:

npx @modelcontextprotocol/inspector@0.7.0

如啟動失敗,可嘗試用npm cache clean --force解決
mcp-inspector
使用時在瀏覽器中訪問命令行輸出的url,如這里的:http://localhost:5173

以調試高德地圖的mcp服務為例:在Command中輸入npx,在Arguments中輸入@amap/amap-maps-mcp-server,之后再點連接(Connect)。
(高德MCP需要API_KEY,連接前還需要配置對應的變量,否則會報錯:AMAP_MAPS_API_KEY environment variable is not set

調試一下高德地圖的mcp提供的關鍵詞搜索tool:成都爬山的旅游景點
mcp-inspector-ui
輸出內容為:

{"suggestion":{"keywords":[],"ciytes":[]},"pois":[{"id":"B001C06PA9","name":"都江堰景區","address":"公園路","typecode":"110202"},{"id":"B001C06ESL","name":"青城山景區","address":"青城山路168號","typecode":"110201"},{"id":"B0FFGNLFOI","name":"天然閣","address":"青城山鎮青城山路168號青城山景區(東南角)","typecode":"110000"},{"id":"B0FFINNKVC","name":"龍泉山城市森林公園","address":"茶店街道","typecode":"110101"},{"id":"B0FFGQ3K69","name":"五鳳溪古鎮","address":"五鳳鎮五鳳溪景區","typecode":"110202"},{"id":"B0FFLDEJ9E","name":"成都龍泉山丹景臺旅游景區","address":"老馬埂附近","typecode":"110200"},{"id":"B001C7WE5S","name":"成都大熊貓繁育研究基地","address":"熊貓大道1375號","typecode":"110202"},{"id":"B001C7X8QA","name":"人民公園","address":"小南街8號(人民公園地鐵站B口步行240米)","typecode":"110202"},{"id":"B0FFF06JQQ","name":"熊貓谷","address":"環山旅游路玉堂段408號","typecode":"110102"},{"id":"B001C05SU4","name":"成都市植物園","address":"蓉都大道天回路1116號","typecode":"110103"},{"id":"B001C7X564","name":"青城后山","address":"泰安古鎮驛道街112號","typecode":"110200"},{"id":"B0FFGQ1S50","name":"灌縣古城","address":"灌口街道灌縣古城西街32號","typecode":"110000"},{"id":"B001C7XDSY","name":"平樂古鎮","address":"興新街139號","typecode":"110202"},{"id":"B0FFKQ2N8L","name":"邛州園","address":"川西民俗文化大觀園(平樂古鎮西)","typecode":"110200"},{"id":"B034000BXN","name":"三岔湖景區","address":[],"typecode":"110200"},{"id":"B0FFK2YUL9","name":"龍泉山風景區","address":"桃花故里旅游路東100米","typecode":"110200"},{"id":"B001C802NZ","name":"花舞人間景區","address":"新蒲路梨花溪1號","typecode":"110200"},{"id":"B001C0531A","name":"老君山","address":"永商鎮","typecode":"110200"},{"id":"B001C0547B","name":"丹景山","address":"丹景山街道丹景村","typecode":"110200"},{"id":"B0FFIS0UIR","name":"天府芙蓉園","address":"簇馬路一段69號","typecode":"110200"}]}

內容比較靠譜,nice~

5.MCP-Server開發

前面的章節我們體驗到了第三方的MCP Server使用,接下來看一下如何開發一個自己的MCP Server

在JAVA項目中開發MCP服務一般有兩種方式:

  1. 基于MCP官方提供的MCP-SDK實現
  2. 基于Spring AI框架實現(對MCP-SDK進行了封裝)

追求簡單快捷,推薦使用SpringAI方式開發MCP Server,在本文中也是使用的Spring AI框架。

5.1 mcp-server開發(STDIO接口)

mcp-transport
MCP-SERVER服務有兩種交互方式,分別為:

  • STDIO(Standard Input/Output)
  • SSE(Server-Sent Events)

這里以開發一個天氣預報的MCP服務為例,天氣預報數據來源使用Open-meteo平臺的接口
open-meteo
先看下接口為STDIO類型的MCP Server,開發具體的過程大致如下:

涉及到的pom依賴:

        <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server</artifactId></dependency><!-- RestClient依賴需要 --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId></dependency>

定義方法并實現:

@Service
public class WeatherService {private static final Logger logger = org.slf4j.LoggerFactory.getLogger(WeatherService.class);private final RestClient restClient;public WeatherService() {this.restClient = RestClient.create();}/*** The response format from the Open-Meteo API*/public record WeatherResponse(Current current) {public record Current(LocalDateTime time, int interval, double temperature_2m) {}}@Tool(description = "Get the temperature (in celsius) for a specific location")public String getTemperature(@ToolParam(description = "The location latitude") double latitude,@ToolParam(description = "The location longitude") double longitude,ToolContext toolContext) {WeatherResponse weatherResponse = restClient.get().uri("https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m",latitude, longitude).retrieve().body(WeatherResponse.class);return responseWithPoems;}
}

注意上面的 @Tool@ToolParam 注解,它們定義了這個mcp服務一個tool的行為和參數,這是一個MCP-Tool的關鍵。

最后,再將上面的service注冊到Spring容器中,這便完成了MCP ToolMCP服務的注冊:

	@Beanpublic ToolCallbackProvider weatherTools(WeatherService weatherService) {return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();}

在打包完成后,再使用MCP Inspector進行調試,傳輸類型選STDIO,Command中輸入:java,Arguments中輸入:-jar E:\\tmp\\github\\spring-ai-examples\\model-context-protocol\\weather\\starter-stdio-server\\target\\mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar

詳細路徑根據生成的jar包目錄調整,運行截圖如下:
stdio-mcp
輸入經緯度后成功返回對應的坐標的溫度信息,Tools欄也可以查看此MCP服務對應的tool。

5.2 mcp-server開發(SSE接口)

SpringAI中提供了兩個starter可以讓我們開發SSE類型的MCP接口:

  • 傳統的webmvc
    	<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webmvc</artifactId></dependency>
    
  • 異步IO請求的webflux
    	<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webflux</artifactId></dependency>
    

將上面STDIO類型的服務改造成SSE類型的接口,僅替換掉依賴就可以。詳細源碼參考:mcp-weather-webmvc-server

MCP Inspector中調試SSE的MCP服務時,傳輸類型選擇SSE并填入URL即可。

以MCP服務在本機運行為例,填入:

http://127.0.0.1:8080/sse

運行截圖:
sse-mcp

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

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

相關文章

學習筆記--(6)

import numpy as np import matplotlib.pyplot as plt from scipy.special import erfc# 設置參數 rho 0.7798 z0 4.25 # 確保使用大寫 Z0&#xff0c;與定義一致def calculate_tau(z, z_prime, rho, s_values):return np.log(rho * z * z_prime * s_values / 2)# 定義 chi_…

【AI4CODE】5 Trae 錘一個基于百度Amis的Crud應用

【AI4CODE】目錄 【AI4CODE】1 Trae CN 錐安裝配置與遷移 【AI4CODE】2 Trae 錘一個 To-Do-List 【AI4CODE】3 Trae 錘一個貪吃蛇的小游戲 【AI4CODE】4 Trae 錘一個數據搬運工的小應用 1 百度 Amis 簡介 百度 Amis 是一個低代碼前端框架&#xff0c;由百度開源。它通過 J…

認識 Promise

認識 Promise 前言&#xff1a;為什么會出現 Promise&#xff1f; 最常見的一個場景就是 ajax 請求&#xff0c;通俗來說&#xff0c;由于網速的不同&#xff0c;可能你得到返回值的時間也是不同的&#xff0c;這個時候我們就需要等待&#xff0c;結果出來了之后才知道怎么樣…

純c++實現transformer 訓練+推理

項目地址 https://github.com/freelw/cpp-transformer C 實現的 Transformer 這是一個無需依賴特殊庫的 Transformer 的 C 實現&#xff0c;涵蓋了訓練與推理功能。 本項目使用C復刻了《Dive into Deep Learning》中關于 Transformer 的第 11 章11.7小節點內容。構建了一個英…

Go 語言規范學習(7)

文章目錄 Built-in functionsAppending to and copying slicesClearCloseManipulating complex numbersDeletion of map elementsLength and capacityMaking slices, maps and channelsMin and maxAllocationHandling panicsBootstrapping PackagesSource file organizationPac…

Python Cookbook-5.1 對字典排序

任務 你想對字典排序。這可能意味著需要先根據字典的鍵排序&#xff0c;然后再讓對應值也處于同樣的順序。 解決方案 最簡單的方法可以通過這樣的描述來概括:先將鍵排序&#xff0c;然后由此選出對應值: def sortedDictValues(adict):keys adict.keys()keys.sort()return …

Git Rebase 操作中丟失提交的恢復方法

背景介紹 在團隊協作中,使用 Git 進行版本控制是常見實踐。然而,有時在執行 git rebase 或者其他操作后,我們可能會發現自己的提交記錄"消失"了,這往往讓開發者感到恐慌。本文將介紹幾種在 rebase 后恢復丟失提交的方法。 問題描述 當我們執行以下操作時,可能…

C語言基礎要素(019):輸出ASCII碼表

計算機以二進制處理信息&#xff0c;但二進制對人類并不友好。比如說我們規定用二進制值 01000001 表示字母’A’&#xff0c;顯然通過鍵盤輸入或屏幕閱讀此數據而理解它為字母A&#xff0c;是比較困難的。為了有效的使用信息&#xff0c;先驅者們創建了一種稱為ASCII碼的交換代…

鴻蒙定位開發服務

引言 鴻蒙操作系統&#xff08;HarmonyOS&#xff09;作為面向萬物互聯時代的分布式操作系統&#xff0c;其定位服務&#xff08;Location Kit&#xff09;為開發者提供了多場景、高精度的位置能力支持。本文將從技術原理、開發流程到實戰案例&#xff0c;全面解析鴻蒙定位服務…

rknn_convert的使用方法

rknn_convert是RKNN-Toolkit2提供的一套常用模型轉換工具&#xff0c;通過封裝上述API接口&#xff0c;用戶只需編輯模型對應的yml配置文件&#xff0c;就可以通過指令轉換模型。以下是如何使用rknn_convert工具的示例命令以及支持的指令參數&#xff1a; python -m rknn.api.…

解決 axios get請求瞎轉義問題

在Vue.js項目中&#xff0c;axios 是一個常用的HTTP客戶端庫&#xff0c;用于發送HTTP請求。qs 是一個用于處理查詢字符串的庫&#xff0c;通常與 axios 結合使用&#xff0c;特別是在處理POST請求時&#xff0c;將對象序列化為URL編碼的字符串。 1. 安裝 axios 和 qs 首先&a…

【XTerminal】【樹莓派】Linux系統下的函數調用編程

目錄 一、XTerminal下的Linux系統調用編程 1.1理解進程和線程的概念并在Linux系統下完成相應操作 (1) 進程 (2)線程 (3) 進程 vs 線程 (4)Linux 下的實踐操作 1.2Linux的“虛擬內存管理”和stm32正式物理內存&#xff08;內存映射&#xff09;的區別 (1)Linux虛擬內存管…

torch 拆分子張量 分割張量

目錄 unbind拆分子張量 1. 沿著第n個維度拆分&#xff08;即按“批次”拆分&#xff09; split分割張量 常用用法&#xff1a; 總結&#xff1a; unbind拆分子張量 import torchquaternions torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]]) result torch.unbind(quaternio…

【Linux】內核驅動學習筆記(二)

7、framebuffer驅動詳解 7.1、什么是framebuffer (1)裸機中如何操作LCD (2)OS下操作LCD的難點 (3)framebuffer幀緩沖&#xff08;簡稱fb&#xff09;是linux內核中虛擬出的一個設備 (4)framebuffer向應用層提供一個統一標準接口的顯示設備 (5)從驅動來看&#xff0c;fb是一個…

用 Docker Compose 與 Nginx 反向代理部署 Vikunja 待辦事項管理系統

在高效管理日常任務和項目的過程中&#xff0c;開源待辦事項工具 Vikunja 以其簡潔、直觀的設計和多視圖支持受到越來越多用戶的青睞。本文將詳細介紹如何使用 Docker Compose 快速部署 Vikunja&#xff0c;并通過 Nginx 反向代理實現 HTTPS 訪問&#xff0c;從而確保服務安全穩…

使用Python快速接入DeepSeek API的步驟指南

使用Python快速接入DeepSeek API的步驟指南 1. 前期準備 注冊DeepSeek賬號 訪問DeepSeek官網注冊賬號 完成郵箱驗證等認證流程 獲取API密鑰 登錄后進入控制臺 → API管理 創建新的API Key并妥善保存 安裝必要庫 pip install requests # 可選&#xff1a;處理復雜場景 pip…

Redis 主要能夠用來做什么

Redis&#xff08;Remote Dictionary Server&#xff09;是一種基于內存的鍵值存儲數據庫&#xff0c;它的性能極高&#xff0c;廣泛應用于各種高并發場景。以下是 Redis 常見的用途&#xff1a; 1. 緩存&#xff08;Cache&#xff09; 作用&#xff1a;存儲熱點數據&#xf…

印度股票實時數據API接口選型指南:iTick.org如何成為開發者優選

在全球金融數字化浪潮中&#xff0c;印度股票市場因其高速增長潛力備受關注。對于量化交易開發者、金融科技公司而言&#xff0c;穩定可靠的股票報價API接口是獲取市場數據的核心基礎設施。本文將深度對比主流印度股票API&#xff0c;并揭示iTick在數據服務領域的獨特優勢。 一…

24.多路轉接-poll

poll也是一種linux中的多路轉接的方案 解決select的fd有上限的問題解決select每次調用都要重新設置關心的fd poll函數接口 poll, ppoll - wait for some event on a file descriptor#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);DESCRIP…

Linux 基礎入門操作 前言 linux操作指令介紹

1 linux 目錄介紹 Linux 文件系統采用層次化的目錄結構&#xff0c;所有目錄都從根目錄 / 開始 1.1 核心目錄 / (根目錄) 整個文件系統的起點、包含所有其他目錄和文件 /bin (基本命令二進制文件) 存放系統最基本的shell命令&#xff1a;如 ls, cp, mv, rm, cat 等&#…