【SpringCloud】Eureka的使用

3. Eureka

3.1 Eureka 介紹

Eureka主要分為兩個部分:

EurekaServer:

作為注冊中心Server端,向微服務應用程序提供服務注冊,發現,健康檢查等能力。

EurekaClient:

服務提供者,服務啟動時,會向 EurekaServer 注冊自己的信息 (IP,端口,服務信息
等),Eureka Server 會存儲這些信息。

3.2 搭建 Eureka 服務

Eureka 是一個單獨的服務,所以咱們要手動搭建出 Eureka 服務器。

這里使用父子項目來搭建 Eureka 服務,先創建一個 spring-cloud-demo 的父項目:

在這里插入圖片描述

后續所有的項目創建都在這個父項目中創建子項目。

在這里插入圖片描述

直接復制下面 spring-cloud-demo 的 pom.xml 文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>spring-cloud-demo</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.6</version><relativePath/> <!-- lookup parent from repository --></parent><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><java.version>17</java.version><spring-cloud.version>2022.0.3</spring-cloud.version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>${mybatis.version}</version><scope>test</scope></dependency></dependencies></dependencyManagement>
</project>

pom.xml 關鍵部分解析:

  1. <modules>
    定義子模塊(當前為空),用于多模塊項目管理。所有子模塊需在此聲明,Maven 會按順序構建。
  2. <parent>
    繼承 Spring Boot 的默認配置(如插件、依賴管理),版本為 3.1.6,簡化項目配置。
  3. <properties>
    統一定義變量,便于維護版本:
    • Java 版本:17
    • Spring Cloud:2022.0.3
  4. <dependencies>
    當前僅引入 Lombok(代碼簡化工具),<optional>true</optional> 表示不傳遞依賴給子模塊。
  5. <dependencyManagement>
    統一管理依賴版本,子模塊引用時無需指定版本:
    • 引入 Spring Cloud 全家桶的版本控制
    • 鎖定 MyBatis 和 MySQL 驅動版本
    • 測試用 MyBatis 依賴(僅測試范圍生效)

記得刪除掉父工程的 src 目錄,因為后續不會在父工程中寫代碼。

有了上述操作,咱們的父工程就創建好了,接下來開始創建子工程。

下面開始在父工程底下創建一個子模塊,也就是用這個子模塊去搭建 Eureka 服務:

在這里插入圖片描述

創建子模塊項目名為 eureka-server:
在這里插入圖片描述

此時點擊 Create 后,就會發現 spring-cloud-demo 目錄下出現了 eureka-server 子項目,同時在父項目的 pom.xml 中的 modules 里出現了咱們子模塊的名字

在這里插入圖片描述

在子項目 eureka-server 的 pom.xml <dependencies> </dependencies> 中引入 eureka-server 依賴:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

在子項目 eureka-server 的 pom.xml <project> </project> 加入項目構件插件

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

記得點擊右上角 maven 的刷新,或者打開 maven 面板點擊 Reload ALL Maven Project 按鈕重新加載下依賴。

由于創建的子項目是一個空的項目,所以需要手動創建好對應的包和子模塊的啟動類:

EurekaServerApplication.class 代碼如下:

package com.zlcode.eureka;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class, args);}
}

編寫配置文件,這里需要手動在 resoureces 中創建該項目的配置文件 papplication.yml

# Eureka相關配置
# Eureka 服務
server:port: 10010
spring:application:name: eureka-server
eureka:instance:hostname: localhostclient:# 表示是否從Eureka Server獲取注冊信息,默認為true.因為這是一個單點的Eureka Server,# 不需要同步其他的Eureka Server節點的數據,這里設置為falsefetch-registry: false# 表示是否將自己注冊到Eureka Server,默認為true.由于當前應用就是Eureka Server,故而設置為false.register-with-eureka: falseservice-url:# 設置Eureka Server的地址,查詢服務和注冊服務都需要依賴這個地址defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

有了上述的操作,就能執行 eureka-server 項目中的 main 方法了。

在瀏覽器中輸入 http://127.0.0.01:10010 就能發現此時 eureka-server 已經成功啟動了。

在這里插入圖片描述

3.3 創建cook服務和waiter服務

接下來再來創建兩個子項目,分別是 廚師(cook) 和 服務員(waiter),廚師需要讓服務員上菜。

創建廚師服務和服務員服務跟創建 Eureka 項目一致,創建的流程這里就省略了,也就是在 spring-cloud-demo 目錄下創建廚師子模塊和服務員子模塊。

### 3.3.1 cook-service 模塊配置代碼

cook-service 的 pom.xml 文件如下:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>spring-cloud-demo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cook-service</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

cook-service 的 application.yml 文件如下:

server:port: 8080
spring:application:name: cook-service # 添加服務器名稱
#Eureka Client
eureka:client:service-url:# eureka 地址defaultZone: http://127.0.0.1:10010/eureka/

cook-service 的 啟動類 文件如下:

package com.zlcode.cook;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class CookServiceApplication {public static void main(String[] args) {SpringApplication.run(CookServiceApplication.class, args);}
}

3.3.2 waiter-service 模塊配置代碼

waiter-service 的 pom.xml 文件如下:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>spring-cloud-demo</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>waiter-service</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

waiter-service 的 application.yml 文件如下:

server:port: 9090
spring:application:name: waiter-service # 添加服務器名稱
#Eureka Client
eureka:client:service-url:# eureka 地址defaultZone: http://127.0.0.1:10010/eureka/

waiter-service 的 啟動類 文件如下:

package com.zlcode.waiter;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class WaiterServiceApplication {public static void main(String[] args) {SpringApplication.run(WaiterServiceApplication.class, args);}
}

3.3.3 cook 實體類

將 CookInfo 創建在 cookie-service/*/cook/model/目錄下:

package com.zlcode.cook.model;import lombok.Data;@Data
public class CookInfo {private Integer cookId;private String cookieName;
}

3.3.4 waiter 實體類

將 WaiterInfo 創建在 waiter-service/*/waiter/model/目錄下:

package com.zlcode.waiter.model;import lombok.Data;@Data
public class WaiterInfo {private Integer waiterId;private String waiterName;
}

3.4 服務注冊

啟動咱們的 waiter-service 和 cook-service 項目,就能自動的進行 eureka 的服務注冊了,因為咱們在 .yml 已經配置好了 eureka 的地址。
在這里插入圖片描述

啟動 waiter 和 cook 后,刷新 http://127.0.0.1:10010 就能發現:

在這里插入圖片描述

通過上面可以看到,已經把 cook-service 和 waiter-service 注冊到咱們部搭建的 eureka-server 服務中了。

上述這樣的操作,咱們就稱作為服務注冊。

由于 cook-service 想通過 eureka-server 去發現 waiter-service 所以,也要讓 cook-service 自己在 eureka 中注冊,這樣一來 cook-service 就可以從 eureka-server 中去發現 waiter-service 服務。

3.5 服務發現

前面咱們說,廚師想通過喊服務員名字來讓服務員上菜,但是呢它并不知道當前哪些服務員是能提供服務的,于是便需要向 eureka-server 去獲取可用服務列表,于是廚師就不需要關注服務員叫什么了。

咱們對 cook-service 和 waiter-service 分別創建一個 controller 包,在 cook 的 controller 包中新建 CookController類,在 waiter 的 controller 中新建 WaiterController 類,此處咱們就不新建 Service 層 和 Mapper 層了,這里只是為了學習服務發現,所以使用一層演示就足夠了。

對于 waiter 服務來說,就提供一個接口,這個接口就是執行一個模擬的任務:

package com.zlcode.waiter.controller;import jakarta.websocket.server.PathParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/waiter")
@Slf4j
public class WaiterController {@RequestMapping("/up")public String up(@PathParam("content") String content) {log.info("正在執行: " + content);return "執行: " + content + "成功!";}
}

上述 waiter 就提供了 /waiter/up 這個接口,比如傳遞的 content 為 “給55桌上紅燒肉”,這個請求就會打印一下這個content,然后再模擬返回結果。下面咱們來使用 postman 測試這個接口的可用性:

在這里插入圖片描述

這里可用發現 waiter 服務的 up 接口成功返回了預期的值,同時在 waiter 的控制臺也能看到:

在這里插入圖片描述

調用 waiter 的 up 方法后,成功的模擬執行了上菜操作!

接下來咱們看一下 cook 提供了哪個接口:

package com.zlcode.cook.controller;import jakarta.websocket.server.PathParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/cook")
public class CookController {@Autowiredprivate DiscoveryClient discoveryClient;@RequestMapping("/ok")public String ok(@PathParam("content")String content) {// 通過 discoveryClient 從 eureka-server 獲取服務列表List<ServiceInstance> instances = discoveryClient.getInstances("waiter-service");String uri = instances.get(0).getUri().toString(); // 拿到服務列表的第一個 ip:端口號// ----------------------------------------------------------// 這里咱們拿到了 waiter 的 ip 地址和端口號// 也就是知道了服務員的名字,那么要如何告訴服務員你需要讓他上菜呢?// 當然現實中可用喊一嗓子,但在代碼中呢?// ---------------------------------------------------------return "";}
}

此時這里就可用通過 discoveryClient.getInstances 實例列表,此處是獲取名字為 waiter-service 的服務列表,獲取后,通過 instances.get(0).getUri().toString(); 獲取這個實例的 ip 和 端口號。

為什么這里可能會有多個實例呢?別忘記了,把同一個項目換成不同的端口號,分別運行,這就是兩個服務,同時這兩個服務都進行服務注冊,此時 eureka 上就會有兩個這樣的服務了,只是對應的端口號不同,如果端口號相同,但是ip不同,也就是在不同的主機上,這樣也是 ok 的。

但是這里只啟動了一個 waiter-service 服務,所以咱們取第 0 個就ok了。

ip 和端口號是拿到了,可是如何調用 waiter-service 服務提供的 up 接口呢?

其實也很簡單,既然都拿到ip端口號了,直接使用 ip+端口號/waiter/up?content=“xxx” 這個 url 給 waiter 發一個 http 請求就ok了,但是使用 js 發 http 請求相信都會,但是在 Java 中如何給發送 http 請求呢?

這里可用使用 Spring 提供的 RestTemplate 類,通過這個可用發送一個 http 請求,但是注意了!!!

想認識 RestTemplate 就得知道什么是 Rest。

REST(Representational State Transfer),表現層資源狀態轉移。

簡單來說:REST描述的是在網絡中Client和Server的?種交互形式,REST本身不實用,實用的是如何設計RESTfulAPI(REST風格的網絡接口)接口類似于:

GET/blog/{blogId}:查詢博客
DELETE/blog/{blogId}:刪除博客

而 RestTemplate 是Spring提供,封裝HTTP調?,并強制使用RESTful風格。它會處理HTTP連接和關閉,只需要使用者提供資源的地地和參數即可。

所以要想使用這個 RestTemplate 進行 http 請求,先得把咱們 waiter 服務的 up 接口改成 Rest 風格的接口:

package com.zlcode.waiter.controller;import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/waiter")
@Slf4j
public class WaiterController {@RequestMapping("/up/{content}")public String up(@PathVariable("content") String content) {log.info("正在執行: " + content);return "執行: " + content + "成功!";}
}

接下來在 cook-service 項目中先定義 RestTemplate,把這個對象交給 Spring 容器管理,在 cook 目錄下創建 config 目錄,在這個目錄下創建一個 BeanConfig 類,在這個類中定義好咱們要用的 RestTemplate 就 OK 了。

package com.zlcode.cook.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class BeanConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}

接下來修改 CookConroller 的 ok 接口:

package com.zlcode.cook.controller;import jakarta.websocket.server.PathParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.List;@RestController
@RequestMapping("/cook")
public class CookController {@Autowiredprivate DiscoveryClient discoveryClient;@Autowiredprivate RestTemplate restTemplate;// 咱們的 cook 里面的接口可以不遵循 Rest 規范,// 只要保證使用 restTemplate 調用的接口遵守 Rest 規范就ok了@RequestMapping("/ok")public String ok(@PathParam("content")String content) {// 通過 discoveryClient 從 eureka-server 獲取服務列表List<ServiceInstance> instances = discoveryClient.getInstances("waiter-service");String uri = instances.get(0).getUri().toString(); // 拿到服務列表的第一個 ip:端口號// 通過 restTemplate 給 waiter-service 發送 http 請求String url = uri + "/waiter/up/{content}";// 第一個參數是請求 url, // 第二個參數是這個請求的返回值類型的class對象, // 第三個參數是占位符對應的值String resp = restTemplate.getForObject(url, String.class, content);return "調用成功, 已收到 waiter 的響應: " + resp;}
}

此時咱們此處的代碼,就是 cook 廚師,通過 eureka 注冊中心獲取到服務列表,拿到第一個服務的 ip和端口,通過這個 ip 和 端口 拼接上完整的接口路由,帶上參數,就實現了遠程方法調用了。

此處如果服務員離職了,來了個新的服務員,對于廚師來說,沒有任何影響,廚師只需要關注注冊中心有哪些服務列表就行了。

3.6 服務注冊和發現的注意點

List<ServiceInstance> instances = discoveryClient.getInstances("waiter-service");
String uri = instances.get(0).getUri().toString(); // 拿到服務列表的第一個 ip:端口號
String url = uri + "/waiter/up/{content}";
String resp = restTemplate.getForObject(url, String.class, content);

上面代碼是服務發現和遠程調用的重要代碼。

上面的 discoveryClient.getInstances(“waiter-service”) 這里方法的形參,waiter-service 就像是給這個服務取了一個名字,比如傳菜的都叫做服務員,只要名字叫 waiter-service 的服務,都能獲取到,那么注冊中心是如何知道每個服務的名字呢?

在這里插入圖片描述

觀察 waiter-service 的 spring.application.name 的值是 waiter-server,注冊中心就是通過這個 name 來區分的,所以也就是有可能出現如下的情況:

服務A 的名字:waiter-service 這個服務只提供了 test 接口
服務B 的名字:waiter-service 這個服務只提供了 hello 接口

由于服務 AB 啟動時都會進行服務注冊,那么問題來了,通過discoveryClient.getInstances(“waiter-service”) 會拿到兩個實例,也就是可以獲取兩個服務的 ip 和 端口號,假設 服務C 想調用 test 接口,而服務C 只知道 name 為 waiter-service 的服務提供了 test 接口,但是服務C不知道的是:AB都叫 test-service,但是服務B沒有提供 test 接口。

如果此時 C 通過 instances.get(0).getUri().toString();,拿到的是服務B的ip和端口,此時再通過 restTemplate 進行調用 test 接口,那問題就大了!!

也就是說,如果統稱為服務員,那么必須都得具備傳菜的接口服務。

所以對于這里的 spring.application.name 的值,要保證相同的 name 它所提供的服務(接口)要是一致的!

在這里插入圖片描述

現在咱們就來復現上面這種情況,先創建 B/hello 和 A/test 接口,并且這兩個服務都叫做 waiter-service。

AController:

package com.zlcode.waiter.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class AController {@RequestMapping("test")public String test () {return "成功調用了 服務A 的 test 接口";}
}

BController:

package com.zlcode.waiter.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class BController {@RequestMapping("/hello")public String hello() {return "成功調用了 服務B 的 hello 接口";}
}

啟動這兩個服務A和服務B,服務A的端口為9091,服務B的端口為9092,此時可以發現 服務A 只提供了 test 接口,服務B 只提供了 hello 接口。

在這里插入圖片描述

此時啟動服務A和服務B,都發現已經成功使用 waiter-service 這個名字進行服務注冊了。

然后使用服務C去獲取 waiter-service 對應的服務列表,調用下這兩個服務的 test 接口:

package com.zlcode.cook.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;@Slf4j
@RestController
@RequestMapping("/C")
public class CController {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@RequestMapping("/run")public void run() {List<ServiceInstance> instances = discoveryClient.getInstances("waiter-service");for (ServiceInstance instance : instances) {String uri = instance.getUri().toString();log.info("獲取到服務器地址:" + uri);String url = uri + "/test";try {String resp = restTemplate.getForObject(url, String.class);log.info(uri + " 調用服務器 test 接口成功! resp: " + resp);} catch (Exception e) {e.printStackTrace();log.error("服務器: " + uri + "沒有提供 test 接口.");}}}
}

上述就是服務C,咱們給它運行在 8080 端口上,然后調用 127.0.0.1/C/run 這個接口后,他就會從注冊中心獲取 waiter-service 服務信息,此時能拿到兩個,9091 端口是提供了 test 接口服務的,而 9092 則沒有提供 test 接口服務。

在 postman 調用 127.0.0.1/C/run 觀察項目打印日志:

在這里插入圖片描述

果然不出所料,沒有提供 test 接口的服務B就會報 404 錯誤。所以現在你理解了服務名的重要性了嗎?

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

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

相關文章

前端知識點---window.location.assign() 和 window.location.href 的區別(javascript)

window.location.assign() 和 window.location.href 的主要區別&#xff1a; 讀取和設置 window.location.href&#xff1a;既可以讀取當前 URL&#xff0c;也可以通過賦值更改 URL。 window.location.assign()&#xff1a;只能用于跳轉到新的 URL&#xff0c;不能讀取當前地…

OpenCV圖像拼接(3)圖像拼接類cv::detail::MultiBandBlender

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::detail::MultiBandBlender 是 OpenCV 中用于圖像拼接&#xff08;stitching&#xff09;模塊的一個類&#xff0c;主要用于將多張重疊的圖像…

王者榮耀服務器突然崩了

就在剛剛王者榮耀服務器突然崩了 #王者榮耀崩了#的話題毫無預兆地沖上熱搜&#xff0c;許多玩家發現游戲登錄界面反復彈出異常提示&#xff0c;匹配成功后卡在加載界面&#xff0c;甚至出現對局數據丟失的情況。根據官方公告&#xff0c;目前技術團隊已在全力搶修服務器 #王者…

【JavaScript】JavaScript Promises實踐指南

【JavaScript】JavaScript Promises實踐指南 你了解JavaScript中的Promises嗎&#xff1f;這是一個很多人一開始就放棄的主題&#xff0c;但我會盡量讓它變得盡可能簡單。 1. “Promise”到底是什么&#xff1f; “Promise”是異步編程中的一個基本概念&#xff0c;特別是在J…

計算機視覺總結

以下是針對上述問題的詳細解答,并結合代碼示例進行說明: 1. 改進YOLOv5人臉檢測模塊,復雜光照場景準確率從98.2%提升至99.5% 優化具體過程: 光照補償:在數據預處理階段,采用自適應光照補償算法,對圖像進行實時增強,以減少光照變化對人臉檢測的影響。數據增強:在訓練…

ExpTimerApcRoutine函數分析之作用是ActiveTimerListHead里面移除定時器_etimer

第一部分&#xff1a; VOID ExpTimerApcRoutine ( IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2 ) /* Routine Description: This function is the special …

算法分析與設計 專題三

目錄 一、實驗目的 二、實驗內容 三、問題分析與求解 四、AC源代碼、截圖 五、實驗小結 一、實驗目的 1、了解貪心算法的分析過程&#xff0c;學會用貪心算法解決一些具體的問題。 2、了解廣度優先算法和深度優先算法。 二、實驗內容 1992 當然&#xff0c;我們的收藏中…

1688商品詳情接口:深度解析與應用實踐

在電商領域&#xff0c;1688作為中國領先的B2B平臺&#xff0c;擁有海量的商品信息。對于開發者、商家和數據分析師來說&#xff0c;獲取1688商品的詳細信息是實現數據分析、競品研究、自動化管理和精準營銷的重要手段。本文將詳細介紹1688商品詳情接口的使用方法、技術細節以及…

每日算法-250328

記錄今天學習和解決的LeetCode算法題。 92. 反轉鏈表 II 題目 思路 本題要求反轉鏈表中從 left 到 right 位置的節點。我們可以采用 頭插法 的思路來反轉指定區間的鏈表。 具體來說&#xff0c;我們首先定位到 left 位置節點的前一個節點 prev。然后&#xff0c;從 left 位置…

C語言中的位域:節省內存的標志位管理技術

位域&#xff08;Bit-field&#xff09; 是 C 語言中的一種特性&#xff0c;允許在結構體&#xff08;struct&#xff09;中定義占用特定位數的成員變量。通過位域&#xff0c;可以更精細地控制內存的使用&#xff0c;尤其是在需要存儲多個布爾值或小范圍整數時&#xff0c;可以…

【AI編程學習之Python】第一天:Python的介紹

Python介紹 簡介 Python是一種解釋型、面向對象的語言。由吉多范羅蘇姆(Guido van Rossum)于1989年發明,1991年正式公布。官網:www.python.org Python單詞是"大蟒蛇”的意思。但是龜叔不是喜歡蟒蛇才起這個名字,而是正在追劇:英國電視喜劇片《蒙提派森的飛行馬戲團》(Mo…

【openstack系列】虛擬化技術

OpenStack 是一個開源的云計算管理平臺,它本身并不直接提供虛擬化技術,而是通過集成不同的虛擬化解決方案來管理和編排計算、存儲和網絡資源。OpenStack 的核心優勢在于其靈活性和可擴展性,支持多種虛擬化技術(Hypervisor),使企業可以根據需求選擇合適的底層虛擬化方案。…

保姆級教程:Vue3 + Django + MySQL 前后端聯調(PyCharm+VSCode版)

一、環境準備與驗證 這里為減少篇幅&#xff0c;默認大家都安裝好了這些軟件。不會下載安裝的&#xff0c;教程也很多&#xff0c;這里不再做贅述。話不多說&#xff0c;咱們開始&#xff1a; 1. 安裝驗證 確保已安裝以下軟件并驗證版本&#xff1a; # 驗證Node.js node -v…

Spring Data審計利器:@LastModifiedDate詳解!!!

&#x1f552; Spring Data審計利器&#xff1a;LastModifiedDate詳解&#x1f525; &#x1f31f; 簡介 在數據驅動的應用中&#xff0c;記錄數據的最后修改時間是常見需求。Spring Data的LastModifiedDate注解讓這一過程自動化成為可能&#xff01;本篇帶你掌握它的核心用法…

洛谷題單1-P1001 A+B Problem-python-流程圖重構

題目描述 輸入兩個整數 a,b&#xff0c;輸出它們的和&#xff08;∣a∣,∣b∣≤109&#xff09;。 輸入格式 兩個以空格分開的整數。 輸出格式 一個整數。 輸入輸出樣例 輸入 20 30輸出 50方式-print class Solution:staticmethoddef oi_input():"""從…

CCF CSP 第33次(2024.03)(2_相似度計算_C++)(字符串中字母大小寫轉換+哈希集合)

CCF CSP 第33次&#xff08;2024.03&#xff09;&#xff08;2_相似度計算_C&#xff09; 題目背景&#xff1a;題目描述&#xff1a;輸入格式&#xff1a;輸出格式&#xff1a;樣例1輸入&#xff1a;樣例1輸出&#xff1a;樣例1解釋&#xff1a;樣例2輸入&#xff1a;樣例2輸出…

Windows .gitignore文件不生效的情況排查

概述 今天下班在家里搗騰自己的代碼&#xff0c;在配置.gitignore文件忽略部分文件的時候&#xff0c;發現死活不生效 問題根源 經過一通分析和排查才發現&#xff0c;是.gitignore文件的編碼錯了&#xff0c;剛開始還沒注意到&#xff0c;因為是在Windows下開發&#xff0c…

Uniapp自定義TabBar組件全封裝實踐與疑難問題解決方案

前言 在當前公司小程序項目中&#xff0c;我們遇到了一個具有挑戰性的需求&#xff1a;根據不同用戶身份動態展示差異化的底部導航欄&#xff08;TabBar&#xff09; 。這種多角色場景下的UI適配需求&#xff0c;在提升用戶體驗和實現精細化運營方面具有重要意義。 在技術調研…

四川省汽車加氣站操作工備考題庫及答案分享

1.按壓力容器的設計壓力分為&#xff08; &#xff09;個壓力等級。 A. 三 B. 四 C. 五 D. 六 答案&#xff1a;B。解析&#xff1a;按壓力容器的設計壓力分為低壓、中壓、高壓、超高壓四個壓力等級。 2.緩沖罐的安裝位置在天然氣壓縮機&#xff08; &#xff09;。 A. 出口處 …

2025年- G27-Lc101-542. 01 矩陣--java版

1.題目描述 2.思路 總結&#xff1a;用廣度優先搜索&#xff0c;首先要確定0的位置&#xff0c;不為0的位置&#xff0c;我們要更新的它的值&#xff0c;只能往上下左右尋找跟它最近的0的位置。 解題思路 我們用 BFS&#xff08;廣度優先搜索&#xff09;求解&#xff0c;因為 …