【筆記】Spring Cloud Gateway 實現 gRPC 代理

Spring Cloud Gateway 在 3.1.x 版本中增加了針對 gRPC 的網關代理功能支持,本片文章描述一下如何實現相關支持.本文主要基于 Spring Cloud Gateway 的 官方文檔 進行一個實踐練習。有興趣的可以翻看官方文檔。

在這里插入圖片描述
由于 Grpc 是基于 HTTP2 協議進行傳輸的,因此 Srping Cloud Gateway 在支持了 HTTP2 的基礎上天然支持對 Grpc 服務器的代理,只需要在現有代理基礎上針對 grpc 協議進行一些處理即可。

以下為實現步驟,這里提供了示例代碼,可以按需取用.

生成服務器證書

由于 Grpc 協議使用了 Http2 作為通信協議, Http2 在正常情況下是基于 TLS 層上進行通信的,這就要求我們需要配置服務器證書,這里為了測試,使用腳本生成了一套 CA 證書:

#!/bin/bash
# 指定生成證書的目錄
dir=$(dirname "$0")/../resources/x509
[ -d "$dir" ] && find "$dir" -type f -exec rm -rf {} \;
mkdir -p "$dir"
pushd "$dir" || exit
# 生成.key  私鑰文件 和 csr 證書簽名請求文件
openssl req -new -nodes -sha256 -newkey rsa:2048 -keyout ca.key -out ca.csr \
-subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Ghimi Technology/OU=Ghimi Cloud/CN=ghimi.top"
# 生成自簽名 .crt 證書文件
openssl x509 -req -in ca.csr -key ca.key -out ca.crt -days 3650
# 生成服務器私鑰文件 和 csr 證書請求文件(私鑰簽名文件)
openssl req -new -nodes -sha256 -newkey rsa:2048 -keyout server.key -out server.csr \
-subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Ghimi Technology/OU=Ghimi Blog/CN=blog.ghimi.top"
# 3. 生成 server 證書,由 ca證書頒發
openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -extensions SAN \
-extfile <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:dns.ghimi.top,IP:127.0.0.1,IP:::1"))
# 將 crt 證書轉換為 pkcs12 格式,生成 server.p12 文件,密碼 123456
openssl pkcs12 -export -in server.crt -inkey server.key -CAfile ca.crt \
-password pass:123456 -name server -out server.p12
# 導出服務器證書和證書私鑰為 java keystore 格式 server.jks 為最終的導出結果 密碼 123456
keytool -importkeystore -srckeystore server.p12 -destkeystore server.jks \
-srcstoretype pkcs12 -deststoretype jks -srcalias server -destalias server \
-deststorepass 123456 -srcstorepass 123456
# 將 ca 證書導入到 server.jks 中
keytool -importcert -keystore server.jks -file ca.crt -alias ca -storepass 123456 -noprompt
popd || exit

構建 Grpc 服務

首先我們需要創建一個 Maven 工程,并編寫 gRPC 相關的服務器代碼:

添加 gRPC 所需要的相關依賴:

<!-- grpc 關鍵依賴-->
io.grpc:grpc-netty-shaded:jar:1.64.0:runtime -- module io.grpc.netty.shaded [auto]
io.grpc:grpc-protobuf:jar:1.64.0:compile -- module io.grpc.protobuf [auto]
io.grpc:grpc-stub:jar:1.64.0:compile -- module io.grpc.stub [auto]
io.grpc:grpc-netty:jar:1.64.0:compile -- module io.grpc.netty [auto]

用 protobuf 生成一個 Java gRPC模板:

syntax = "proto3";
option java_multiple_files = true;
option java_package = "service";message HelloReq {string name = 1;
}
message HelloResp {string greeting = 1;
}
service HelloService {rpc hello(HelloReq) returns (HelloResp);
}

然后在 pom.xml 添加 prptobuf 生成插件:

<!-- project.build.plugins -->
<plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.6.1</version><configuration><protocArtifact>com.google.protobuf:protoc:3.25.1:exe:${os.detected.classifier}</protocArtifact><pluginId>grpc-java</pluginId><pluginArtifact>io.grpc:protoc-gen-grpc-java:1.64.0:exe:${os.detected.classifier}</pluginArtifact><!--設置grpc生成代碼到指定路徑--><!--<outputDirectory>${project.build.sourceDirectory}</outputDirectory>--><!--生成代碼前是否清空目錄--><clearOutputDirectory>true</clearOutputDirectory></configuration><executions><execution><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions>
</plugin>

注意在指定 protoc 的版本時要和上面 grpc 依賴的 protobuf 版本保持一致,否則可能會出現類找不到的報錯。
在這里插入圖片描述
然后執行執行 Maven 命令生成 Protobuf 對應的 Java 代碼:

mvn protobuf:compile protobuf:compile-custom

之后就可以基于生成的 Protobuf Java 代碼編寫一個 gRPC Server 了 :

public static void main(String[] args) throws IOException, InterruptedException {TlsServerCredentials.Builder tlsBuilder = TlsServerCredentials.newBuilder();File serverCert = new ClassPathResource("/x509/server.crt").getFile();File serverKey = new ClassPathResource("/x509/server.key").getFile();File caCert = new ClassPathResource("/x509/ca.crt").getFile();ServerCredentials credentials  = tlsBuilder.trustManager(caCert).keyManager(serverCert, serverKey).build();// ServerCredentials credentials = InsecureServerCredentials.create(); // 不建議使用,非常坑Server server = Grpc.newServerBuilderForPort(443, credentials).addService(new HelloImpl()).build();server.start().awaitTermination();
}static class HelloImpl extends HelloServiceGrpc.HelloServiceImplBase {@Overridepublic void hello(HelloReq request, StreamObserver<HelloResp> responseObserver) {String msg = "hello " + request.getName() + " from server";System.out.println("server received a req,reply: " + msg);HelloResp res = HelloResp.newBuilder().setGreeting(msg).build();responseObserver.onNext(res);responseObserver.onCompleted();}
}

嘗試啟動 GrpcServer ,檢查端口是否已被監聽,當前端口綁定在 443 上,這里 GrpcServer 的服務器證書一定要配置.

編寫 GrpcClient 代碼:

public static void main(String[] args) throws InterruptedException, IOException {// 當服務器配置了證書時需要指定 ca 證書TlsChannelCredentials.Builder tlsBuilder = TlsChannelCredentials.newBuilder();File caCert = new ClassPathResource("/x509/ca.crt").getFile();ChannelCredentials credentials = tlsBuilder.trustManager(caCert).build();// 不做服務器證書驗證時使用這個// ChannelCredentials credentials = InsecureChannelCredentials.create();ManagedChannelBuilder<?> builder = Grpc.newChannelBuilder("127.0.0.1:7443", credentials);ManagedChannel channel = builder.build();HelloServiceGrpc.HelloServiceBlockingStub stub = HelloServiceGrpc.newBlockingStub(channel);service.HelloReq.Builder reqBuilder = service.HelloReq.newBuilder();HelloResp resp = stub.hello(reqBuilder.setName("ghimi").build());System.out.printf("success greeting from server: %s", resp.getGreeting());channel.shutdown().awaitTermination(5, TimeUnit.MINUTES);
}

執行 GrpcClient,調用 443 端口的 GrpcServer 查看執行效果:
在這里插入圖片描述
現在我們就可以開發 Spring Cloud Gateway 了,首先添加依賴,我這里添加了 spring-cloud-starter-gateway:3.1.9 版本(為了適配 Java8,已經升級 Java11 的可以提升至更高版本)。

org.springframework.cloud:spring-cloud-starter-gateway:3.1.9

編寫 GrpcGateway 啟動類:

@SpringBootApplication
public class GrpcGateway {public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(GrpcGateway.class, args);}
}

先不做配置嘗試運行一下,看下是否能夠正常運行:
在這里插入圖片描述
可以看到成功監聽到了 8080 端口,這是 Spring Cloud Gateway 的默認監聽端口,現在我們在 /src/main/resources/ 目錄下添加 application.yml 配置,配置代理 grpc 端口:

server:port: 7443 #端口號http2:enabled: truessl:enabled: truekey-store: classpath:x509/server.p12key-store-password: 123456key-store-type: pkcs12key-alias: server
spring:application:name: scg_grpccloud:gateway: #網關路由配置httpclient:ssl:use-insecure-trust-manager: true
#          trustedX509Certificates:
#            - classpath:x509/ca.crtroutes:- id: user-grpc #路由 id,沒有固定規則,但唯一,建議與服務名對應uri: https://[::1]:443 #匹配后提供服務的路由地址predicates:#以下是斷言條件,必選全部符合條件- Path=/**               #斷言,路徑匹配 注意:Path 中 P 為大寫- Header=Content-Type,application/grpcfilters:- AddResponseHeader=X-Request-header, header-value

添加 application.yml 后,重啟 Spring Cloud Gateway 嘗試用 GrpcClient 調用 7443 代理端口,可以看到請求成功:
在這里插入圖片描述

報錯分析

GrpcServer 和 GrpcClient 如果都配置了 InsecureServerCredentials 的情況下, GrpcClient 可以直接調用 GrpcServer 成功:

GrpcServer

TlsServerCredentials.Builder tlsBuilder = TlsServerCredentials.newBuilder();
ServerCredentials credentials = InsecureServerCredentials.create(); // 配置通過 h2c(http2 clear text) 協議訪問
Server server = Grpc.newServerBuilderForPort(443, credentials).addService(new HelloImpl()).build();
server.start().awaitTermination();

GrpcClient

ChannelCredentials credentials = InsecureChannelCredentials.create(); // 通過 h2c 協議訪問 GrpcServer
tlsBuilder.requireFakeFeature();
ManagedChannelBuilder<?> builder = Grpc.newChannelBuilder("127.0.0.1:443", credentials);
ManagedChannel channel = builder.build();
HelloServiceGrpc.HelloServiceBlockingStub stub = HelloServiceGrpc.newBlockingStub(channel);
service.HelloReq.Builder reqBuilder = service.HelloReq.newBuilder();
HelloResp resp = stub.hello(reqBuilder.setName("ghimi").build());
System.out.printf("success greeting from server: %s\n", resp.getGreeting());
channel.shutdown().awaitTermination(5, TimeUnit.MINUTES);

此時使用 GrpcClient 調用 GrpcServer ,可以調用成功:
在這里插入圖片描述

但是,如果中間添加了 Spring Cloud Gateway 的話, Grpc Server 和 Grpc Client 就都不能使用 InsecureCredentials 了, Spring Cloud Gateway 在這種場景下無論與 client 還是和 server 通信都會由于不識別的協議格式而報錯:
在這里插入圖片描述

如果 GrpcServer 沒有配置服務器證書而是使用了 InsecureServerCredentials.create() ,GrpcClient 雖然不使用證書訪問能夠直接驗證成功,但是如果中間通過 GrpcGateway 的話這種機制就有可能出現問題,因為 GrpcGateway 與 GrpcServer 之間的通信是基于 Http2 的,而非 Grpc 特定的協議,在 GrpcServer 沒有配置服務器證書的情況下處理的包可能會導致 GrpcGateway 無法識別,但是如果 GrpcServer 配置了證書后 GrpcGateway 就能夠正常驗證了。

GrpcServer 在沒有配置證書的情況下通過 Srping Cloud Gateway 的方式進行代理,并且 Spring Cloud Gateway 的 spring.cloud.gateway.http-client.ssl.use-insecure-trust-manager=true 的場景下 GrpcClient 訪問 Spring Cloud Gateway 會報錯:

GrpcClient 報錯信息:

Exception in thread "main" io.grpc.StatusRuntimeException: UNKNOWN: HTTP status code 500
invalid content-type: application/json
headers: Metadata(:status=500,x-request-header=header-value,content-type=application/json,content-length=146)
DATA-----------------------------
{"timestamp":"2024-06-28T13:18:03.455+00:00","path":"/HelloService/hello","status":500,"error":"Internal Server Error","requestId":"31f8f577/1-8"}at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:268)at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:249)at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:167)at service.HelloServiceGrpc$HelloServiceBlockingStub.hello(HelloServiceGrpc.java:160)at com.example.GrpcClient.main(GrpcClient.java:30)

報錯信息解析,GrpcClient 報錯結果來自于 Spring Cloud Gateway ,返回結果為不識別的返回內容 invalid content-type: application/json 這是由于 Spring Cloud Gateway 返回了的報錯信息是 application/json 格式的,但是 GrpcClient 通過 grpc 協議通信,因此會將錯誤格式錯誤直接返回而非正確解析錯誤信息.

GrpcGateway 報錯信息:

io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 00001204000000000000037fffffff000400100000000600002000000004080000000000000f0001at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1313) ~[netty-handler-4.1.100.Final.jar:4.1.100.Final]Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):*__checkpoint ? org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]*__checkpoint ? HTTP POST "/HelloService/hello" [ExceptionHandlingWebHandler]
Original Stack Trace:at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1313) ~[netty-handler-4.1.100.Final.jar:4.1.100.Final]at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1383) ~[netty-handler-4.1.100.Final.jar:4.1.100.Final]

這里就是的報錯信息是 GrpcGateway 無法正確解析來自 GrpcServer 的 http2 的包信息而產生的報錯.這是由于 GrpcGateway 與 GrpcServer 在 h2c(Http2 Clean Text) 協議上的通信格式存在差異,從而引發報錯.

最后是來自 GrpcServer 的報錯:

628, 2024 9:18:03 下午 io.grpc.netty.shaded.io.grpc.netty.NettyServerTransport notifyTerminated
信息: Transport failed
io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2Exception: HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 16030302650100026103036f6977c824c322105c600bd1dbat io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2Exception.connectionError(Http2Exception.java:109)at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.readClientPrefaceString(Http2ConnectionHandler.java:321)at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.decode(Http2ConnectionHandler.java:247)at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:453)

這里就是 GrpcServer 與 GrpcGateway 通信過程由于協議包無法識別導致通信終止,從而引發報錯.

報錯場景2

在 Spring Cloud Gateway 的 application.yml 中同時配置了 use-insecure-trust-manager: truetrustedX509Certificates 導致的報錯:

spring:cloud:gateway: #網關路由配置httpclient:ssl:use-insecure-trust-manager: truetrustedX509Certificates:- classpath:x509/ca.crt

use-insecure-trust-manager: true 表示在于 GrpcServer 通信的過程中不會驗證服務器證書,這樣如果證書存在什么問題的情況下就不會引發報錯了,但是在同時配置了 use-insecure-trust-manager: truetrustedX509Certificates 的情況下 use-insecure-trust-manager: true 選項是不生效的,Spring Cloud Gateway 會還是嘗試通過配置的 ca 證書去驗證服務器證書,從而引發報錯,因此不要同時配置 use-insecure-trust-manager: truetrustedX509Certificates這兩個選項。

# 同時配置了 `use-insecure-trust-manager: true` 和 `trustedX509Certificates` 后服務證書校驗失敗報錯
javax.net.ssl.SSLHandshakeException: No subject alternative names matching IP address 0:0:0:0:0:0:0:1 foundat java.base/sun.security.ssl.Alert.createSSLException(Alert.java:130) ~[na:na]Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):*__checkpoint ? org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]*__checkpoint ? HTTP POST "/HelloService/hello" [ExceptionHandlingWebHandler]
Original Stack Trace:

客戶端通常情況下只需要配置 ca 證書,用于驗證服務器證書,但是驗證服務器證書這一步是可以跳過的,在一些場景下服務器證書的校驗比較嚴格的時候容易出問題,此時可以選擇不進行服務器證書校驗,在 Spring Cloud Gateway 代理訪問 GrpcServer 時,可以為 Spring Cloud Gateway 配置 use-insecure-trust-manager: true 來取消對 GrpcServer 的強驗證。

No subject alternative names matching IP address 0:0:0:0:0:0:0:1 found

這個問題就是在校驗服務器證書時,由于服務器證書校驗失敗導致的報錯了,通常情況下, client 會校驗服務器的FQDN域名信息是否與請求的連接一致:

# 請求服務器證書
openssl req -new -nodes -sha256 -newkey rsa:2048 -keyout server.key -out server.csr \
-subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Ghimi Technology/OU=Ghimi Blog/CN=blog.ghimi.top"

上面是在使用命令生成服務器證書時配置的信息,其中 CN=blog.ghimi.top 就是我配置的域名信息,這就要求我的 GrpcServer 的 ip 地址綁定了這個域名,然后 GrpcClient 通過這個域名訪問:

ManagedChannelBuilder<?> builder = Grpc.newChannelBuilder("blog.ghimi.top:7443", credentials);

在這種情況下 GrpcClient 會拿服務器返回的證書與當前連接信息進行比較,如果一致則服務器驗證成功,否則驗證失敗并拋出異常.

在 GrpcServer 只有 ip 地址沒有域名的情況下,基于域名的驗證就不生效了,此時去做證書驗證就一定會報錯:

# 同時配置了 `use-insecure-trust-manager: true` 和 `trustedX509Certificates` 后服務證書校驗失敗報錯
javax.net.ssl.SSLHandshakeException: No subject alternative names matching IP address 0:0:0:0:0:0:0:1 foundat java.base/sun.security.ssl.Alert.createSSLException(Alert.java:130) ~[na:na]Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):*__checkpoint ? org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]*__checkpoint ? HTTP POST "/HelloService/hello" [ExceptionHandlingWebHandler]
Original Stack Trace:

報錯信息中提到的 subject alternative names 就是在域名失效后的另外一種驗證手段,他要求ca在簽發服務器證書時向服務器證書中添加一段附加信息,這個信息中可以添加證書的可信 ip 地址:

# 通過 ca 證書頒發服務器證書
openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -extensions SAN \
-extfile <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:dns.ghimi.top,IP:127.0.0.1"))

上面腳本中的 IP:127.0.0.1 就是添加的可信地址,我們可以同時添加多個服務器地址,以上面的報錯為例,我們只需要在生成服務器證書的時候添加 ::1 的本地 ipv6 地址即可修復該錯誤:

openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -extensions SAN \
-extfile <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:dns.ghimi.top,IP:127.0.0.1,IP:::1"))

報錯場景4 使用 pkcs12 配置了多張自簽名 ca 證書識別失效問題

解決方案,改為使用 Java Keystore 格式的證書即可修復.

參考資料

  • Spring Cloud Gateway and gRPC
  • spring-cloud-gateway-grpc
  • gRPC-Spring-Boot-Starter 文檔
  • rx-java
  • Working with Certificates and SSL
  • 介紹一下 X.509 數字證書中的擴展項 subjectAltName

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

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

相關文章

深度學習之Transformer模型的Vision Transformer(ViT)和Swin Transformer

Transformer 模型最初由 Vaswani 等人在 2017 年提出,是一種基于自注意力機制的深度學習模型。它在自然語言處理(NLP)領域取得了巨大成功,并且也逐漸被應用到計算機視覺任務中。以下是兩種在計算機視覺領域中非常重要的 Transformer 模型:Vision Transformer(ViT)和 Swi…

git 個人常見錯誤備注

問題1&#xff1a;all conflict fixed but you are still merging。。。。。 如果你已經解決了所有沖突&#xff0c;但 Git 仍然提示你正在進行合并&#xff0c;可能是因為你還沒有完成合并過程。以下是詳細步驟&#xff0c;確保你正確完成合并并提交更改&#xff1a; 確認所…

Tongsuo(銅鎖)項目介紹 - 實現國密SSL協議

文章介紹 銅鎖(Tongsuo)是一個提供現代密碼學算法和安全通信協議的開源基礎密碼庫,為存儲、網絡、密鑰管理、隱私計算、區塊鏈等諸多業務場景提供底層的密碼學基礎能力,實現數據在傳輸、使用、存儲等過程中的私密性、完整性和可認證性,為數據生命周期中的隱私和安全提供保…

鴻蒙 如何 url decode

在 TypeScript 和 JavaScript 中進行 URL 編碼的最簡單方式是使用內置的 global 函數 encodeURIComponent()。以下是一個示例&#xff1a; let url "https://example.com/?name測試&job開發者"; let encodedURL encodeURIComponent(url); console.log(encode…

【RAG】FoRAG:面向網絡增強型長形式問答的事實性優化RAG

一、解決問題 在基于網絡的長形式問答&#xff08;Web-enhanced Long-form Question Answering, LFQA&#xff09;任務中&#xff0c;現有RAG在生成答案時存在的問題&#xff1a; 事實性不足&#xff1a;研究表明&#xff0c;現有系統生成的答案中只有大約一半的陳述能夠完全得…

Qt開發筆記:Qt3D三維開發筆記(一):Qt3D三維開發基礎概念介紹

若該文為原創文章&#xff0c;轉載請注明原文出處 本文章博客地址&#xff1a;https://blog.csdn.net/qq21497936/article/details/140059315 長沙紅胖子Qt&#xff08;長沙創微智科&#xff09;博文大全&#xff1a;開發技術集合&#xff08;包含Qt實用技術、樹莓派、三維、O…

匯編語言基礎教程

匯編語言基礎教程 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將深入探討匯編語言的基礎知識和應用&#xff0c;幫助大家理解匯編語言在計算機編程中…

來自Claude官方的提示詞庫,支持中文!建議收藏!

大家好,我是木易,一個持續關注AI領域的互聯網技術產品經理,國內Top2本科,美國Top10 CS研究生,MBA。我堅信AI是普通人變強的“外掛”,所以創建了“AI信息Gap”這個公眾號,專注于分享AI全維度知識,包括但不限于AI科普,AI工具測評,AI效率提升,AI行業洞察。關注我,AI之…

多元時間序列分析——VAR(向量自回歸模型)

VAR模型主要是考察多個變量之間的動態互動關系&#xff0c;從而解釋各種經濟沖擊對經濟變量形成的動態影響。這種動態關系可通過格蘭杰因果關系、脈沖響應以及方差分解來進一步明確和可視化。VAR模型主要研究內生變量之間的關系&#xff0c;內生變量就是參與模型并由模型體系內…

通天星CMSV6車載監控平臺CompanyList信息泄露漏洞

1 漏洞描述 通天星CMSV6車載視頻監控平臺是東莞市通天星軟件科技有限公司研發的監控平臺,通天星CMSV6產品覆蓋車載錄像機、單兵錄像機、網絡監控攝像機、行駛記錄儀等產品的視頻綜合平臺。通天星科技應用于公交車車載、校車車載、大巴車車載、物流車載、油品運輸車載、警車車…

推薦一款程序員的搞錢神器

你是不是經常為開發環境的搭建而頭疼&#xff1f;有沒有遇到過因為接口開發而焦頭爛額的情況&#xff1f;作為一名程序員&#xff0c;特別是獨立開發者&#xff0c;這些問題是不是常常讓你覺得心力交瘁&#xff1f;別擔心&#xff0c;現在有一個神器&#xff0c;能讓你擺脫這些…

五、golang基礎之slice和map

文章目錄 一、slice&#xff08;一&#xff09;含義&#xff08;二&#xff09;定義切片&#xff08;三&#xff09;切片初始化&#xff08;四&#xff09;len() 和 cap() 函數&#xff08;五&#xff09;空(nil)切片&#xff08;六&#xff09;切片截取&#xff08;七&#xf…

2024HVV最新POC/EXP,目前有8000+個POC/EXP

點擊"仙網攻城獅”關注我們哦~ 不當想研發的滲透人不是好運維 讓我們每天進步一點點 簡介 都是網上收集的POC和EXP&#xff0c;最新收集時間是2024年五月&#xff0c;需要的自取。 表里沒有的可以翻翻之前的文章&#xff0c;資源比較零散沒有整合起來。 文件鏈接&#xff…

hexo博客搭建

系列文章目錄 文章目錄 系列文章目錄前言1. 環境配置2. 打包并發布到github倉庫3. 生成ssh秘鑰4.vscode配置本地與遠端相對路徑不一致問題總結 前言 本文主要介紹了hexo博客怎么搭建 1. 環境配置 安裝git、nodejs、npm創建博客文件夾blogcmd輸入命令npm install -g hexo初始化…

10波形震蕩原因及采集設備安裝視頻

10波形震蕩原因及采集設備安裝視頻 排查過程算法軟件后臺解碼計算嵌入式采集設備準備視頻 結語其他以下是廢話 之前說過&#xff1a;“解決不了的真的就不是我這邊能解決的了”&#xff0c;這是因為我們充分排查了自身&#xff0c;那么問題出在哪里呢&#xff1f; 不愿溝通、不…

Spring Boot 全面解析:從入門到實踐案例

引言&#xff1a; Spring Boot 是由 Pivotal 團隊提供的全新框架&#xff0c;旨在簡化 Spring 應用的初始搭建以及開發過程。它基于 Spring 平臺&#xff0c;通過“約定優于配置”的原則&#xff0c;盡可能自動化配置&#xff0c;減少XML配置&#xff0c;使得開發者能夠快速啟…

矢量數據庫:概念、歷史、現狀與展望?

矢量數據庫&#xff1a;概念、歷史、現狀與展望&#xff1f; 李升偉 概念&#xff1a;矢量數據庫是一種專門用于存儲、檢索和搜索矢量的數據庫。在數據科學和機器學習中&#xff0c;矢量是表示數據的有序列表或數字序列&#xff0c;可以表示各種類型的數據&#xff0c;如文本…

阿里云智能編程助手的安裝使用

https://help.aliyun.com/document_detail/2590613.html 通義靈碼&#xff0c;是阿里云出品的一款基于通義大模型的智能編碼輔助工具&#xff0c;提供行級/函數級實時續寫、自然語言生成代碼、單元測試生成、代碼優化、注釋生成、代碼解釋、研發智能問答、異常報錯排查等能力&a…

前后端防重復提交

數據重復提交是一個大忌&#xff0c;會帶來無效數據&#xff0c;應該在前端和后端都建議檢測防范。 前端一般是按鈕按下觸發數據提交&#xff0c;如果用戶鼠標操作習慣不好&#xff0c;或者鼠標或系統設置問題會導致鼠標連擊&#xff0c;如果前端不做相關處理&#xff0c;可能會…

洞察數據資產的奧秘:深入剖析數據資產在企業運營中的核心作用,提出一套全面、系統的數據資產解決方案,幫助企業實現數據資產的最大化利用和增值

一、引言 在數字化浪潮洶涌的今天&#xff0c;數據已成為企業最寶貴的資產之一。數據資產不僅記錄了企業的歷史運營軌跡&#xff0c;更蘊含著指導未來決策的智慧。然而&#xff0c;如何有效管理、利用這些數據資產&#xff0c;使其轉化為企業的競爭優勢和利潤增長點&#xff0…