部署一個自己的Spring Ai 服務(deepseek/通義千問)

Spring Boot 無縫接入 DeepSeek 和通義千問請求日志記錄及其ip黑白名單
SpringBoot版本 3.2.0 JDK 版本為17 redis 3.2.0 mybatis 3.0.3

依賴引入

關鍵依賴

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>

完整依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.cqie</groupId><artifactId>spring-ai</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-ai</name><description>spring-ai</description><properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>3.2.0</spring-boot.version><spring-ai.version>0.8.1</spring-ai.version></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.0</version><relativePath/> <!-- lookup parent from repository --></parent><dependencies><!-- Spring Boot Web Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Test Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- JUnit (for testing) --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId><version>1.5.21</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.40</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.17</version></dependency><!-- 添加官方Spring AI OpenAI依賴 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><!-- Maven Compiler Plugin --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>${java.version}</source><target>${java.version}</target><encoding>${project.build.sourceEncoding}</encoding></configuration></plugin><!-- Spring Boot Maven Plugin --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>com.cqie.SpringAiApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build><repositories><!-- Spring Milestones Repository --><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><!-- Spring Snapshots Repository --><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories>
</project>

建表(日志+黑名單)

CREATE TABLE `request_log` (`id` varchar(100) NOT NULL COMMENT '主鍵',`date` datetime DEFAULT NULL COMMENT '請求時間',`request_url` varchar(255) DEFAULT NULL COMMENT '請求路徑',`user_agent` varchar(255) DEFAULT NULL COMMENT 'userAgent',`status` int(11) DEFAULT NULL COMMENT '狀態碼',`ip_address` varchar(255) DEFAULT NULL COMMENT 'ip地址',`method` varchar(100) DEFAULT NULL COMMENT '方法',`error_message` varchar(255) DEFAULT NULL COMMENT '錯誤原因',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `black_ips` (`id` varchar(100) NOT NULL COMMENT '主鍵id',`black_ip` varchar(255) DEFAULT NULL COMMENT 'ip地址',`status` tinyint(1) DEFAULT NULL COMMENT '轉態',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

配置文件


# DeepSeek 配置,完全兼容openai配置
# spring:
#   ai:
#     openai:
#       base-url: https://api.deepseek.com  # DeepSeek的OpenAI式端點
#       api-key: sk-xxxxxxxxx
#       chat.options:
#         model: deepseek-chat  # 指定DeepSeek的模型名稱# 通義千問配置
spring:ai:openai:base-url: https://dashscope.aliyuncs.com/compatible-mode  # 通義千問api-key: sk-xxxxxxxxxxxchat.options:model: qwen-plus

配置文件示例

server:port: 8080
spring:application:name: spring-aiai:openai:base-url: https://dashscope.aliyuncs.com/compatible-modeapi-key: sk-***chat.options:model: qwen-plusdatasource:url: jdbc:mysql://ip:3306/springai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: 用戶名password: 密碼driver-class-name: com.mysql.cj.jdbc.Driver# Redis配置data:redis:host: ipport: 6379password: 密碼database: 3lettuce:pool:max-active: 8max-wait: -1msmax-idle: 8min-idle: 0timeout: 10000ms
# 日志配置
logging:level:org.springframework.ai: DEBUG# mybatis配置
mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.cqie.entityconfiguration:map-underscore-to-camel-case: truecall-setters-on-nulls: truejdbc-type-for-null: 'null'

全局異常捕獲

統一返回

package com.cqie.common;import lombok.AllArgsConstructor;
import lombok.Getter;@Getter
@AllArgsConstructor
public class Result {private int code;private String message;private Object data;public Result() {this.code = 0;this.message = "success";this.data = null;}public static Result success(Object data, String message) {Result result = new Result();result.code = 200;result.message = message;result.data = data;return result;}public static Result success(Object data) {Result result = new Result();result.code = 200;result.message = "success";result.data = data;return result;}public static Result error(String errorMsg) {Result result = new Result();result.code = 500;result.message = errorMsg;result.data = null;return result;}}

定義異常

package com.cqie.common;/*** 服務異常*/
public class ServerException extends RuntimeException {public ServerException(String message) {super(message);}public ServerException(String message, Throwable cause) {super(message, cause);}
}

全局捕獲

package com.cqie.config;import com.cqie.common.CommonException;
import com.cqie.common.Result;
import com.cqie.common.ServerException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;/*** 全局異常處理器*/
@RestControllerAdvice
@Slf4j
public class GlobeExceptionHandler {// 處理全局異常@ExceptionHandler(CommonException.class)public Result CommonException(Exception e) {return Result.error(e.getMessage());}@ExceptionHandler(ServerException.class)public Result ServerException(Exception e) {return Result.error(e.getMessage());}}

基于interceptor的日志攔截器

package com.cqie.common;import com.cqie.dao.BlackIpsDao;
import com.cqie.dao.RequestLogDao;
import com.cqie.entity.BlackIps;
import com.cqie.entity.RequestLog;
import com.cqie.utils.RedisUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;/*** 請求檢查,請求日志記錄,黑名單處理*/
@Component
@ConditionalOnBean(RequestLogDao.class)
public class LoggingInterceptor implements HandlerInterceptor {private final RequestLogDao requestLogDao;private final BlackIpsDao blackIpsDao;private final RedisUtils redisUtils;private final String BLACK_IPS_KEY = "black_ips:";public LoggingInterceptor(RequestLogDao requestLogDao, BlackIpsDao blackIpsDao, RedisUtils redisUtils) {this.requestLogDao = requestLogDao;this.blackIpsDao = blackIpsDao;this.redisUtils = redisUtils;}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String ipAddress = getClientIpAddress(request);int status = response.getStatus();String errorMessage = null;// 對黑名單的ip進行處理List<String> blackIps = (List<String>) redisUtils.get(BLACK_IPS_KEY + "spring-ai");if (blackIps == null) {List<String> ipBlackList = blackIpsDao.queryByStatus(0).stream().map(BlackIps::getBlackIp).collect(Collectors.toList());// 一天的過期時間redisUtils.set(BLACK_IPS_KEY + "spring-ai", ipBlackList, 24);}if (blackIps != null && blackIps.contains(ipAddress)) {status = 500;errorMessage = "請求ip已被加入黑名單";saveRequestLog(request, ipAddress, status, errorMessage);throw new ServerException(errorMessage);}// 判斷2s請求最多請求一次,對請求頻率做限制boolean exists = redisUtils.exists(ipAddress);if (exists) {status = 500;errorMessage = "ai服務請求太頻繁";saveRequestLog(request, ipAddress, status, errorMessage);throw new ServerException(errorMessage);}// 記錄調用日志saveRequestLog(request, ipAddress, status, null);// 對請求記錄分析 限制2s請求最多請求一次redisUtils.set(ipAddress, "1", 5);return HandlerInterceptor.super.preHandle(request, response, handler);}private void saveRequestLog(HttpServletRequest request, String ipAddress, int status, String errorMessage) {LocalDateTime now = LocalDateTime.now();String method = request.getMethod();String url = request.getRequestURI();String userAgent = request.getHeader("User-Agent");RequestLog requestLog = new RequestLog();requestLog.setDate(now);requestLog.setRequestUrl(url);requestLog.setStatus(status);requestLog.setUserAgent(userAgent);requestLog.setIpAddress(ipAddress);requestLog.setMethod(method);requestLog.setErrorMessage(errorMessage);requestLogDao.insert(requestLog);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}private String getClientIpAddress(HttpServletRequest request) {String ipAddress = request.getHeader("X-Forwarded-For");if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();}return ipAddress;}
}

注冊攔截器

package com.cqie.config;import com.cqie.common.LoggingInterceptor;
import com.cqie.dao.BlackIpsDao;
import com.cqie.dao.RequestLogDao;
import com.cqie.utils.RedisUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {private final RequestLogDao requestLogDao;private final BlackIpsDao blackIpsDao;private final RedisUtils redisUtils;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//日志攔截器registry.addInterceptor(new LoggingInterceptor(requestLogDao, blackIpsDao,redisUtils)).addPathPatterns("/**").order(0);}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 靜態資源訪問路徑和存放路徑配置registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/", "classpath:/public/");// 新增Camunda webjar資源映射registry.addResourceHandler("/webjars/camunda/**").addResourceLocations("classpath:/META-INF/resources/webjars/camunda-webapp-ui/");// swagger訪問配置registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/", "classpath:/META-INF/resources/webjars/");}}

實現日志和日志表操作

dao server impl 這里只需要dao層就行

redis工具類簡單封裝

package com.cqie.utils;import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Component
public class RedisUtils {@Resourceprivate RedisTemplate<String, Object> redisTemplate;/*** 設置緩存** @param key   鍵* @param value 值*/public void set(String key, Object value) {redisTemplate.opsForValue().set(key, value);}/*** 設置緩存并設置過期時間** @param key     鍵* @param value   值* @param timeout 過期時間(秒)*/public void set(String key, Object value, long timeout) {redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.HOURS);}/*** 獲取緩存** @param key 鍵* @return 值*/public Object get(String key) {return redisTemplate.opsForValue().get(key);}/*** 刪除緩存** @param key 鍵*/public void delete(String key) {redisTemplate.delete(key);}/*** 判斷key是否存在** @param key 鍵* @return true 存在 false不存在*/public boolean hasKey(String key) {return Boolean.TRUE.equals(redisTemplate.hasKey(key));}/*** 設置過期時間** @param key     鍵* @param timeout 過期時間(秒)*/public void expire(String key, long timeout) {redisTemplate.expire(key, timeout, TimeUnit.SECONDS);}/*** 獲取過期時間** @param key 鍵* @return 過期時間(秒)*/public long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);}public boolean exists(String key) {return redisTemplate.hasKey(key);}
} 

接口實現

package com.cqie.controller;import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.StreamingChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.util.ArrayList;
import java.util.List;/*** 基于DeepSeek/通義千問的聊天控制器** @author qingyuqiao*/
@RestController
@RequestMapping("/api")
public class ChatController {/*** 上下文*/private final List<Message> contextHistoryList = new ArrayList<>();private final ChatClient chatClient;private final StreamingChatClient streamingChatClient;/*** ai 初始化信息** @param chatClient* @param streamingChatClient*/public ChatController(ChatClient chatClient, StreamingChatClient streamingChatClient) {this.chatClient = chatClient;this.streamingChatClient = streamingChatClient;// 對用戶輸入進行增強contextHistoryList.add(new SystemMessage("你是一個專業的it技術顧問。"));}/*** 普通對話** @param message 問題* @return 回答結果*/@GetMapping("/chat")public ChatResponse chat(@RequestParam String message) {contextHistoryList.add(new UserMessage(message));Prompt prompt = new Prompt(contextHistoryList);ChatResponse chatResp = chatClient.call(prompt);if (chatResp.getResult() != null) {contextHistoryList.add(chatResp.getResult().getOutput());}return chatResp;}/*** 流式返回** @param message 問題* @return 流式結果*/@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> streamChat(@RequestParam String message) {contextHistoryList.add(new UserMessage(message));Prompt prompt = new Prompt(contextHistoryList);return streamingChatClient.stream(prompt).map(chatResponse -> {if (chatResponse.getResult() != null) {return chatResponse.getResult().getOutput().getContent();}return "";});}
}

成功請求

配合黑名單

接口限制

后續可無縫接入deepseek,只需要修改配置文件的模型和密匙!!!

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

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

相關文章

組裝 (DIY) 一臺顯示器 (4K 屏支持 4 畫面分屏 PBP 1080p x4)

首發日期 2025-04-26, 以下為原文內容: 家里的 PC 主機比較多, 如果同時開機, 顯示器就不夠用了. 因為窮, 窩租住的房間又很小, 放不下很多顯示器. 所以, 窩希望買一臺支持 分屏 功能的顯示器. 最好是 4K 分辨率 (3840x2160) 的屏幕, 然后 4 分屏 (有 4 個 DP 或 HDMI 輸入接口…

[Java入門]抽象類和接口

[Java入門]抽象類和接口 1. 抽象類1.1 抽象類的概念1.2 抽象類語法1.3 抽象類特性1.4 抽象類的作用 2. 接口2.1 接口的概念2.2 語法規則2.3 接口使用2.4 接口特性2.5 實現多個接口2.6 接口間的繼承2.7 抽象類和接口的區別 3. Object類3.1 獲取對象信息3.2 對象比較equals方法 1…

聚焦數字中國|AI賦能與安全守護:Coremail引領郵件辦公智能化轉型

4月28日&#xff0c;第八屆數字中國建設峰會在福州拉開序幕。當天&#xff0c;數字中國新產品新技術發布會開講&#xff0c;Coremail受邀亮相現場&#xff0c;與與會嘉賓分享AI在郵件產品領域的最新應用成果和實踐經驗。 Coremail首席客戶代表劉子建以《AI賦能與安全守護&#…

Qt官方案例知識點總結(拖放操作——Drag And Drop Robot )

-------------------------------------------------------------------------------------------------------------------------------- QPixmap輪廓剪裁 去掉Pixmap的外圍部分&#xff0c;如下&#xff1a; QPixmap pixmap("./img"); //調用createHeuristicMas…

【LLM】MOE混合專家大模型綜述(重要模塊原理)

note 當前的 MoE 架構就是一個用顯存換訓練時長/推理延遲的架構MoE 目前的架構基本集中在于將原先 GPT 每層的 FFN 復制多份作為 n 個 expert&#xff0c;并增加一個 router&#xff0c;用來計算每個 token 對應到哪個 FFN&#xff08;一般采用每個 token 固定指派 n 個 exper…

電子病歷高質量語料庫構建方法與架構項目(臨床情景理解模塊篇)

引言 隨著人工智能技術在醫療健康領域的廣泛應用,電子病歷(Electronic Medical Records,EMR)作為臨床醫療數據的重要載體,已成為醫學研究和臨床決策支持的關鍵資源。電子病歷高質量語料庫的構建為醫療人工智能模型的訓練和應用提供了基礎支撐,其中臨床情境理解模塊是連接…

大連理工大學選修課——機器學習筆記(1):概述

機器學習概述 機器學習的本質 機器學習是為了設計解決問題的算法。 為輸入與輸出建立某種映射&#xff1a; 類似于函數關系&#xff1a; Y f ( X ) Yf(X) Yf(X) 不同的映射方法體現了不同的思想。 相關概念 深度學習是機器學習的一個分支 深度學習是深層次化的神經網…

遠程 Debugger 多用戶環境下的用戶隔離實踐

遠程 Debugger 多用戶環境下的用戶隔離實踐 在現代分布式開發和云原生環境下&#xff0c;遠程 Debugger 的應用愈發普遍。然而&#xff0c;隨著多人協作和多租戶場景的出現&#xff0c;**遠程 Debugger 的“用戶隔離”**變得至關重要。只有實現了良好的用戶隔離&#xff0c;才…

畢業論文 | 基于C#開發的NMEA 0183協議上位機

以下是基于C#開發的NMEA 0183協議上位機完整實現方案,包含串口通信、數據解析與可視化功能: 基于C#開發的NMEA 0183協議上位機 一、項目結構二、核心代碼實現1. 數據模型定義2. 串口通信管理3. NMEA協議解析核心4. 主界面實現(Windows Forms)三、界面設計關鍵元素(需在窗體…

Qt -DFS可視化

博客主頁&#xff1a;【夜泉_ly】 本文專欄&#xff1a;【暫無】 歡迎點贊&#x1f44d;收藏?關注?? 目錄 前言關于如何sleep實現思路Pixmapspixmaps.hpixmaps.cpp MapSquaremapsquare.hmapsquare.cpp dfsthreaddfsthread.hdfsthread.cpprun dfs其他 WidgetUnit其他 Qt -DFS…

RHCSA Linux 系統 文件系統權限

1. 文件的一般權限 &#xff08;1&#xff09;文件權限標識解讀 drwxr - xr - x. 12 root root 144 Feb 17 16:51 usr ?d&#xff1a;文件類型&#xff08;d 表示目錄&#xff09; ?rwx&#xff1a;文件所有者權限&#xff08;讀 r&#xff0c;寫 w&#xff0c;執行 x&am…

華為云IoT平臺與MicroPython實戰:從MQTT協議到物聯網設備開發

目錄 前言 1. 華為云 1.1. 創建實例 1.2. 創建產品 1.3. 編輯服務模型 1.4. 注冊設備 1.4.1. 復制設備連接參數 1.5. 連接參考代碼 2. micropython版-物聯網 2.1. 環境搭建 2.2. 實現步驟 2.3. 示例代碼 結語 前言 物聯網&#xff08;IoT&#xff09;技術的快速發…

2025-04-30 AIGC-如何做短片視頻

摘要: 2025-04-30 AIGC-如何做短片視頻 如何做短片視頻: 一、畫圖修圖 1.保存視頻&#xff08;無水保存&#xff09; 2.文案提取&#xff08;提取文案&#xff09; 3. DeepSeek(提示詞&#xff09; 4.小夢Ai&#xff08;圖片視頻&#xff09; 5.修圖Ai 6.擴圖Ai 7.養生…

硬件工程師面試常見問題(10)

第四十六問&#xff1a;鎖存器&#xff0c;觸發器&#xff0c;寄存器三者的區別 觸發器&#xff1a;能夠存儲一位二值信號的基本單元電路統稱為 "觸發器"。&#xff08;單位&#xff09; 鎖存器&#xff1a;一位觸發器只能傳送或存儲一位數據&#xff0c;而在實際工…

外部訪問 Kubernetes 集群中 MQ 服務的方案

外部訪問 Kubernetes 集群中 MQ 服務的方案 當您在 Kubernetes 集群中部署了消息隊列服務&#xff08;如 RabbitMQ、Kafka、ActiveMQ 等&#xff09;后&#xff0c;以下是外部客戶端訪問這些服務的幾種可靠方法&#xff1a; 一、基礎訪問方案 1. NodePort 方式暴露服務 # M…

論文筆記(八十二)Transformers without Normalization

Transformers without Normalization 文章概括Abstract1 引言2 背景&#xff1a;歸一化層3 歸一化層做什么&#xff1f;4 動態 Tanh &#xff08;Dynamic Tanh (DyT)&#xff09;5 實驗6 分析6.1 DyT \text{DyT} DyT 的效率6.2 tanh \text{tanh} tanh 和 α α α 的消融實驗…

軟考中級-軟件設計師 操作系統(手寫筆記)

第一章&#xff1a;基礎知識 第二章&#xff1a;進程管理 狀態轉換圖 進程同步機制 信號量機制 信號量題 死鎖 第三章&#xff1a;存儲管理 基礎知識 分頁存儲管理 分段存儲管理 段頁式存儲管理 頁面置換算法 第四章&#xff1a;文件管理 基礎知識 索引分配 空閑存儲空間的管…

ubuntu 部署moodle

通過地址https://download.moodle.org/releases/latest/選擇下載&#xff0c;下載兩種壓縮包都特別慢&#xff08;有可能無法下載&#xff09;。 可以使用下面git下載項目 注意圖中php、mysql等版本要求&#xff0c;本次采用Ubuntu22.04下 nginxphp8.2mysql8.4部署 mkdir /var…

python實戰項目67:空氣質量在線檢測平臺js逆向

python實戰項目67:空氣質量在線檢測平臺js逆向 一、需求介紹二、完整代碼一、需求介紹 項目需求是獲取某個城市(以北京市為例)歷年(2013年12月至2025年4月)的空氣質量數據,字段包括日期、AQI、質量等級、PM2.5、PM10、NO2、CO、SO2等。改網站的網址是“https://www.aqis…

【Linux】記錄一個有用PS1

PS1 是用來定義shell提示符的環境變量 下面是一個帶有顏色和豐富信息的 Linux PS1 配置示例&#xff0c;包含用戶名、主機名、路徑、時間、Git 分支和退出狀態提示&#xff1a; # 添加到 ~/.bashrc 文件末尾 PS1\[\e[1;32m\]\u\[\e[m\] # 綠色粗體用戶名 PS…