云原生 envoy xDS 動態配置 java控制平面開發 支持restful grpc實現 EDS 動態endpoint配置

envoy xDS 動態配置 java控制平面開發 支持restful grpc 動態endpoint配置

大綱

  • 基礎概念
  • Envoy 動態配置API
  • 配置方式
  • 動靜結合的配置方式
  • 純動態配置方式
  • 實戰

基礎概念

Envoy 的強大功能之一是支持動態配置,當使用動態配置時,我們不需要重新啟動 Envoy 進程就可以生效。Envoy 通過從磁盤文件或網絡接口讀取配置,動態地重新加載配置。動態配置使用所謂的發現服務 API,指向配置的特定部分。這些 API 也被統稱為xDS 即 (xxx discovery service)

注意:
Envoy的發現API開發模式是,按照Envoy指定的接口名稱,請求參數,響應值,自己開發,即需要滿足Envoy的規范

Envoy動態配置支持文件方式,grpc接口和, restful接口,其中 grpc接口/REST接口 的配置提供者(自己開發的項目)也被稱為控制平面

實現方式:

  • 文件方式: 監聽文件的變化動態修改
  • grpc接口: 使用的tcp長連接
  • REST接口: 使用的http輪詢的方式實現

Envoy 動態配置API

API類型

Envoy 內部有多個發現服務 API (xDS):

  • 監聽器發現服務(LDS listener discovery service) 使用 LDS,Envoy 可以在運行時發現監聽器,包括所有的過濾器棧、HTTP 過濾器和對 RDS 的引用。(即動態配置 listener 類似nginx配置虛擬主機)
  • 擴展配置發現服務(ECDS) 使用 ECDS,Envoy 可以獨立于監聽器獲取擴展配置(例如,HTTP 過濾器配置)。
  • 路由發現服務(RDS route discovery service) 使用 RDS,Envoy 可以在運行時發現 HTTP 連接管理器過濾器的整個路由配置。與 EDS 和 CDS 相結合,我們可以實現復雜的路由拓撲結構。(即動態配置路由)
  • 虛擬主機發現服務(VHDS) 使用 VHDS 允許 Envoy 從路由配置中單獨請求虛擬主機。當路由配置中有大量的虛擬主機時,就可以使用這個功能。
  • 寬泛路由發現服務(SRDS) 使用 SRDS,可以把路由表分解成多個部分。當有大的路由表時,就可以使用這個 API。
  • 集群發現服務(CDS cluster discovery service ) 使用 CDS,Envoy 可以發現上游集群。Envoy 將通過排空和重新連接所有現有的連接池來優雅地添加、更新或刪除集群。Envoy 在初始化時不必知道所有的集群,因為我們可以在以后使用 CDS 配置它們。(即動態配置集群)
  • 端點發現服務(EDS endpoint discovery service) 使用 EDS,Envoy 可以發現上游集群的成員。 (即動態配置后端服務類似nginx upstream)
  • 秘密發現服務(SDS) 使用 SDS,Envoy 可以為其監聽器發現秘密(證書和私鑰,TLS 會話密鑰),并為對等的證書驗證邏輯進行配置。
  • 運行時發現服務(RTDS) 使用 RTDS,Envoy 可以動態地發現運行時層。

API 版本

Envoy 的 API 有 v2 v3 目前主流版本是 v3

官方文檔 https://www.envoyproxy.io/docs/envoy/latest/configuration/overview/xds_api

xDS API 可以使用restful接口和grpc接口開發,只要滿足指定的接口名稱和DiscoveryRequest,DiscoveryResponse參數和響應對象即可

例如以下就是一個EDS的接口
/v3/discovery:endpoints (即自己寫的controller的mapping是/v3/discovery:endpoints)
@RequestMapping("/v3/discovery:endpoints")

配置方式

動靜結合的配置方式

靜態配置與動態配置結合

例如

static_resources:listeners:- name: my_listeneraddress:socket_address: protocol: TCPaddress: 0.0.0.0port_value: 15200filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerstat_prefix: my-http-filterhttp_filters:- name: envoy.filters.http.routerstat_prefix: my_listener_httpcodec_type: AUTOroute_config:name: local_routevirtual_hosts:- name: local_servicedomains: ["*"]routes:- match:  prefix: "/" route:  cluster: user-service clusters:- name: user-servicetype: EDS #這里就是使用動態配置的方式實現endpoint的動態發現connect_timeout: 0.5seds_cluster_config: eds_config:resource_api_version: V3api_config_source:api_type: RESTtransport_api_version: V3cluster_names: [edscluster]refresh_delay: 10s - name: edsclustertype: STATICconnect_timeout: 0.5shosts:  - socket_address: address: 192.168.0.218port_value: 7590 

純動態配置方式

使用dynamic_resources 配置動態內容

例如

dynamic_resources:ads_config:api_type: GRPCtransport_api_version: V3grpc_services:- envoy_grpc:cluster_name: xds_clustercds_config:resource_api_version: V3api_config_source:api_type: GRPCtransport_api_version: V3grpc_services:- envoy_grpc:cluster_name: xds_clusterlds_config:resource_api_version: V3api_config_source:api_type: GRPCtransport_api_version: V3grpc_services:- envoy_grpc:cluster_name: xds_cluster

當envoy沒有讀取到配置時會一直使用默認的配置,所以如果控制平面宕機后還是會保持配置

每個 xDS API 都有給定的資源類型:

v2版本

LDS :  envoy.api.v2.Listener
RDS : envoy.api.v2.RouteConfiguration
CDS : envoy.api.v2.Cluster
EDS :envoy.api.v2.ClusterLoadAssignment (EDS就是配置 endpoint)

v3版本

envoy.config.listener.v3.Listener
envoy.config.route.v3.RouteConfiguration,
envoy.config.route.v3.ScopedRouteConfiguration,
envoy.config.route.v3.VirtualHost
envoy.config.cluster.v3.Cluster
envoy.config.endpoint.v3.ClusterLoadAssignment  (EDS endpoint 返回的resources 對象類型)
envoy.extensions.transport_sockets.tls.v3.Secret
envoy.service.runtime.v3.Runtime

即接口返回DiscoveryResponse 內部的resources 是以上類型

實戰

本次測試 envoy的版本為v1.16.0 使用docker鏡像部署

在這里插入圖片描述

基于envoy xDS api v3版本 java restful實現

step1 配置 envoy.yaml

配置文件如下

node:cluster: myclusterid: test-id# 這是一段靜態配置
static_resources:listeners:- name: my_listeneraddress:socket_address: protocol: TCPaddress: 0.0.0.0port_value: 15200 #配置一個靜態的listener 監聽來自任意IP的請求15200端口的http請求filter_chains:- filters:- name: envoy.filters.network.http_connection_manager #注意指定filterstyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerstat_prefix: my-http-filterhttp_filters:- name: envoy.filters.http.routerstat_prefix: my_listener_httpcodec_type: AUTOroute_config:name: local_routevirtual_hosts:- name: local_servicedomains: ["*"]  #任意域名的請求routes:- match:  prefix: "/"   # 任意url的請求route:  cluster: user-service  # 路由到user-service 集群# 配置集群    clusters:- name: user-servicetype: EDS  #模式指定為EDS  connect_timeout: 0.5s # 配置連接超時時間eds_cluster_config: eds_config:resource_api_version: V3 #指定使用V3版本接口api_config_source:api_type: REST  #使用restful的方式transport_api_version: V3   #指定使用V3版本接口cluster_names: [edscluster]refresh_delay: 10s  # 配置刷新頻率# 這里配置的是envoy EDS接口的提供服務即控制平面       - name: edsclustertype: STATICconnect_timeout: 0.5s # 配置連接超時時間# envoy會去請求 192.168.0.218:7590/v3/discovery:endpoints 這個接口 獲取endpoint配置信息# 代碼見 my-docker-demo-envoy-plane/DataPlaneEndpointControllerV3.javahosts:  - socket_address: address: 192.168.0.218port_value: 7590  

啟動 envoy 鏡像

docker run  -p 5201:5201 -p 15200:15200  -v /ops/envoy:/etc/envoy  envoyproxy/envoy:v1.16.0 

envoy 啟動后可以看到開始調用 EDS接口,由于還沒啟動服務此時會報錯

在這里插入圖片描述

step2 java 程序開發

EDS接口使用java springboot 開發

注意點如下:

  • 1 接口必須是 /v3/discovery:endpoints
  • 2 動態配置需要是一個json 字符串 并且滿足endpoint需要的格式
  • 3 返回值必須是一個DiscoveryResponse service.discovery.v3.DiscoveryResponse

DiscoveryResponse 格式如下

{"version_info": ...,"resources": [],"type_url": ...,"nonce": ...,"control_plane": {...}
}

整體的返回值json字符串如下

{"versionInfo": "1.0.0","resources": [{"@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment","clusterName": "user-service","endpoints": [{"lbEndpoints": [ {"endpoint": {"address": {"socketAddress": {"address": "10.244.1.203","portValue": 5588}}}}]}]}]
}

如果自己拼接json字符串感覺比較麻煩,可以使用envoy-api包

<dependency><groupId>io.envoyproxy.controlplane</groupId><artifactId>api</artifactId><version>1.0.39</version></dependency>

這個包,里面有xDS中的各種資源對象 以及grpc接口

也可以使用官方提供的 java控制面板項目 打包編譯后得到api包,里面也有xDS中的各種資源對象

在這里插入圖片描述

java 代碼如下

  @RequestMapping(value="/v3/discovery:endpoints" , produces = {"application/json;charset=UTF-8"})public String discovery(HttpServletRequest req) throws Exception {			//json 字符串拼接//String json = staticJson();/*** 構建返回EDS 配置json 字符串*/String json = useBean();return json;}/*** @return*/private String useBean() throws Exception {/*** 以下資源類出自* * <dependency><groupId>io.envoyproxy.controlplane</groupId><artifactId>api</artifactId><version>1.0.39</version></dependency>* *///配置上游服務(類似nginx upstream)SocketAddress sa1 = SocketAddress.newBuilder().setAddress("10.244.0.190").setPortValue(5588).build();SocketAddress sa2 = SocketAddress.newBuilder().setAddress("10.244.1.203").setPortValue(5588).build();Address address1 = Address.newBuilder().setSocketAddress(sa1).build();Address address2 = Address.newBuilder().setSocketAddress(sa2).build();Endpoint end1 = Endpoint.newBuilder().setAddress(address1).build();Endpoint end2 = Endpoint.newBuilder().setAddress(address2).build();LbEndpoint lb1 = LbEndpoint.newBuilder().setEndpoint(end1).build();LbEndpoint lb2 = LbEndpoint.newBuilder().setEndpoint(end2).build();LocalityLbEndpoints llb = LocalityLbEndpoints.newBuilder().addLbEndpoints(lb1).addLbEndpoints(lb2).build();ClusterLoadAssignment cla = ClusterLoadAssignment.newBuilder().setClusterName("user-service").addEndpoints(llb).build();DiscoveryResponse dr = DiscoveryResponse.newBuilder().setVersionInfo("1.0.0").addResources(Any.pack(cla)).build();JsonFormat.TypeRegistry typeRegistry = JsonFormat.TypeRegistry.newBuilder().add(ClusterLoadAssignment.getDescriptor()).build();JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(typeRegistry);return printer.print(dr);
}

基于 envoy xDS api v3版本 java grpc實現

grpc的關鍵

  • 1 使用envoy api包 實現對應的grpc 服務
  • 2 返回值需要指定typeUrl
  • 3 配置文件需要加入 http2_protocol_options 指定使用http2

沒使用http2_protocol_options 配置會出現如下異常

io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2Exception: Unexpected HTTP/1.x request: POST /envoy.service.endpoint.v3.EndpointDiscoveryService/StreamEndpoints at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2Exception.connectionError(Http2Exception.java:109) ~[grpc-netty-shaded-1.48.1.jar:1.48.1]at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.readClientPrefaceString(Http2ConnectionHandler.java:302) ~[grpc-netty-shaded-1.48.1.jar:1.48.1]at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.decode(Http2ConnectionHandler.java:239) ~[grpc-netty-shaded-1.48.1.jar:1.48.1]at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:438) [grpc-netty-shaded-1.48.1.jar:1.48.1]

在這里插入圖片描述

返回值未指定typeUrl

023-08-16 06:14:49.608][8][warning][config] [source/common/config/grpc_mux_impl.cc:155] Ignoring the message for type URL  as it has no current subscribers.

在這里插入圖片描述

關鍵配置 envoy.yaml 如下

# 指定集群名稱
# 動態配置需要指定節點集群名稱        
node:cluster: myclusterid: test-id# 這是一段靜態配置
static_resources:listeners:- name: my_listeneraddress:socket_address: protocol: TCPaddress: 0.0.0.0port_value: 15200 #配置一個靜態的listener 監聽來自任意IP的請求15200端口的http請求filter_chains:- filters:- name: envoy.filters.network.http_connection_manager #注意指定filterstyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerstat_prefix: my-http-filterhttp_filters:- name: envoy.filters.http.routerstat_prefix: my_listener_httpcodec_type: AUTOroute_config:name: local_routevirtual_hosts:- name: local_servicedomains: ["*"]  #任意域名的請求routes:- match:  prefix: "/"   # 任意url的請求route:  cluster: user-service  # 路由到user-service 集群# 配置集群    clusters:- name: user-servicetype: EDS  #模式指定為EDS  connect_timeout: 0.5s # 配置連接超時時間eds_cluster_config: eds_config:resource_api_version: V3 #指定使用V3版本接口api_config_source:api_type: GRPC  #使用grpc的方式transport_api_version: V3   #指定使用V3版本接口# 指定grpc_services 對應的集群# 這里將使用下面定義的集群grpc_services: - envoy_grpc: cluster_name: edscluster# 這里配置的是envoy EDS接口的提供服務即控制平面       - name: edsclustertype: STATICconnect_timeout: 0.5s # 配置連接超時時間# 這里是一個關鍵,必須指定http2_protocol_options 即使用http2http2_protocol_options: {}hosts:  - socket_address: address: 192.168.0.218port_value: 7899  

關鍵java代碼

public class EndpointDiscoveryServiceGrpcImpl extends EndpointDiscoveryServiceGrpc.EndpointDiscoveryServiceImplBase {/*** 這個接口是客戶端模式* */@Overridepublic io.grpc.stub.StreamObserver<io.envoyproxy.envoy.service.discovery.v3.DiscoveryRequest> streamEndpoints(io.grpc.stub.StreamObserver<io.envoyproxy.envoy.service.discovery.v3.DiscoveryResponse> responseObserver) {System.out.println("run grpc ...");/*** 創建StreamObserver<DiscoveryRequest>對象*/StreamObserver<DiscoveryRequest> so = new StreamObserver<DiscoveryRequest>() {@Overridepublic void onNext(DiscoveryRequest request) {//接收客戶端每一次發送的數據,返回給客戶端//showRequest(request);SocketAddress sa1 = SocketAddress.newBuilder().setAddress("10.244.0.214").setPortValue(5588).build();SocketAddress sa2 = SocketAddress.newBuilder().setAddress("10.244.0.201").setPortValue(5588).build();Address address1 = Address.newBuilder().setSocketAddress(sa1).build();Address address2 = Address.newBuilder().setSocketAddress(sa2).build();Endpoint end1 = Endpoint.newBuilder().setAddress(address1).build();Endpoint end2 = Endpoint.newBuilder().setAddress(address2).build();LbEndpoint lb1 = LbEndpoint.newBuilder().setEndpoint(end1).build();LbEndpoint lb2 = LbEndpoint.newBuilder().setEndpoint(end2).build();LocalityLbEndpoints llb = LocalityLbEndpoints.newBuilder().addLbEndpoints(lb1).addLbEndpoints(lb2).build();ClusterLoadAssignment cla = ClusterLoadAssignment.newBuilder()/*** 這里配置的ClusterName 應該是路由對應的cluster name 而不是 node中的cluster* route: { cluster: user-service }*/.setClusterName("user-service") .addEndpoints(llb).build();final DiscoveryResponse dr = DiscoveryResponse.newBuilder().setVersionInfo("1.0.0")							.setTypeUrl("type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment").addResources(Any.pack(cla)).build();/*** 客戶端模式這里不會去關閉StreamObserver* 即不會調用 responseObserver.onCompleted();方法*/responseObserver.onNext(dr);System.out.println("send DiscoveryResponse ");}@Overridepublic void onError(Throwable t) {System.out.println("onError");t.printStackTrace();}@Overridepublic void onCompleted() {//當客戶端數據發送完畢后調用此方法,返回客戶端SocketAddress sa1 = SocketAddress.newBuilder().setAddress("10.244.0.214").setPortValue(5588).build();SocketAddress sa2 = SocketAddress.newBuilder().setAddress("10.244.0.201").setPortValue(5588).build();Address address1 = Address.newBuilder().setSocketAddress(sa1).build();Address address2 = Address.newBuilder().setSocketAddress(sa2).build();Endpoint end1 = Endpoint.newBuilder().setAddress(address1).build();Endpoint end2 = Endpoint.newBuilder().setAddress(address2).build();LbEndpoint lb1 = LbEndpoint.newBuilder().setEndpoint(end1).build();LbEndpoint lb2 = LbEndpoint.newBuilder().setEndpoint(end2).build();LocalityLbEndpoints llb = LocalityLbEndpoints.newBuilder().addLbEndpoints(lb1).addLbEndpoints(lb2).build();ClusterLoadAssignment cla = ClusterLoadAssignment.newBuilder().setClusterName("user-service").addEndpoints(llb).build();final DiscoveryResponse dr = DiscoveryResponse.newBuilder().setVersionInfo("1.0.0").addResources(Any.pack(cla)).build();System.out.println("onCompleted");responseObserver.onNext(dr);responseObserver.onCompleted();}};return so;

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

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

相關文章

spring boot 整合mongodb

1、安裝依賴 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>2、配置數據庫連接 spring:data:mongodb:host: localhostport: 27017username: xxxxxxp…

2682. 找出轉圈游戲輸家

題目描述&#xff1a; n 個朋友在玩游戲。這些朋友坐成一個圈&#xff0c;按 順時針方向 從 1 到 n 編號。從第 i 個朋友的位置開始順時針移動 1 步會到達第 (i 1) 個朋友的位置&#xff08;1 < i < n&#xff09;&#xff0c;而從第 n 個朋友的位置開始順時針移動 1 步…

“華為杯”研究生數學建模競賽2018年-【華為杯】F題:中轉航班調度:從 MILP 模型到啟發式算法

目錄 摘 要 1 問題描述 2 模型假設 3 符號定義及數據預處理 3.1 符號定義

【廣州華銳視點】帆船航行VR模擬實操系統

帆船航行VR模擬實操系統由廣州華銳視點開發&#xff0c;是一種創新的教學工具&#xff0c;它利用虛擬現實技術&#xff0c;為學生提供了一個沉浸式的學習環境。通過這種系統&#xff0c;學生可以在虛擬的環境中進行帆船航行的實訓&#xff0c;從而更好地理解和掌握帆船航行的技…

Maven(四)常用命令大全

目錄 一、mvn 命令參數二、mvn 插件命令1.介紹2.查看插件的使用文檔3.常用的插件命令 官網地址&#xff1a; https://maven.apache.org/官方插件清單&#xff1a; https://maven.apache.org/plugins/index.html Maven 是一個強大的構建工具&#xff0c;它提供了許多命令來進行項…

使用Python統計字符內容的占比

說明&#xff1a;如果有自己動手做過字符動畫&#xff0c;會知道字符動畫的“靈動性”核心在于使用的字符集。 簡單來說&#xff0c;動畫轉為字符動畫&#xff0c;原理是將動畫轉為灰階圖&#xff0c;灰度范圍是0~255&#xff0c;然后將對應灰度的像素點轉為對應比值的字符。這…

linux github 倉庫管理常用操作

linux 的常用操作 linux 本地 ssh驗證連接github賬號本地倉庫連接遠程私有倉庫push/pull操作 Connecting to Github with ssh git local configuration If you are using git for the first time, configure the user name and email in the device. git config --global u…

R語言ggplot2 | R語言繪制物種組成面積圖(三)

&#x1f4cb;文章目錄 面積圖簡介準備數據集加載數據集數據處理數據可視化 利用R語言繪制物種組成圖。本文以堆疊面積圖的方式與大家分享。 面積圖簡介 面積圖又叫區域圖。它是在折線圖的基礎之上形成的, 它將折線圖中折線與自變量坐標軸之間的區域使用顏色或者紋理填充&…

設計模式之單例設計模式

單例設計模式 2.1 孤獨的太陽盤古開天&#xff0c;造日月星辰。2.2 餓漢造日2.3 懶漢的隊伍2.4 大道至簡 讀《秒懂設計模式總結》 單例模式(Singleton)是一種非常簡單且容易理解的設計模式。顧名思義&#xff0c;單例即單一的實例&#xff0c;確切地講就是指在某個系統中只存在…

【算法題】螺旋矩陣III (求解n階蛇形矩陣)

一、問題的提出 n階蛇形矩陣的特點是按照圖1所示的方式排列元素。n階蛇形矩陣是指矩陣的大小為nn&#xff0c;其中n為正整數。 題目背景 一個 n 行 n 列的螺旋矩陣可由如圖1所示的方法生成&#xff0c;觀察圖片&#xff0c;找出填數規律。填數規則為從 1 開始填到 nn。 圖1 …

【配置環境】Linux下安裝MySQL

目錄 一&#xff0c;環境 二&#xff0c;安裝步驟 1.使用包管理器安裝MySQL 2.配置MySQL的安全選項 3.設置root用戶使用密碼進行身份驗證&#xff08;可選&#xff09; 三&#xff0c;拓展知識 1.如何修改MySQL的密碼策略&#xff1f; 2.實現連接MySQL數據庫的測試代碼…

TiDB基礎介紹、應用場景及架構

1. 什么是newsql NewSQL 是對各種新的可擴展/高性能數據庫的簡稱&#xff0c;這類數據庫不僅具有NoSQL對海量數據的存儲管理能力&#xff0c;還保持了傳統數據庫支持ACID和SQL等特性。 NewSQL是指這樣一類新式的關系型數據庫管理系統&#xff0c;針對OLTP&#xff08;讀-寫&…

經驗分享:企業數據倉庫建設方案總結!

導讀 在企業的數字化轉型浪潮中&#xff0c;數據被譽為“新時代的石油”&#xff0c;而數據倉庫作為數據管理與分析的核心基礎設施&#xff0c;在企業的信息化建設中扮演著重要的角色。本文將深入探討企業數據倉庫建設過程中所遇到的問題以及解決經驗&#xff0c;為正在籌備或…

進程/線程上下文切換會用掉你多少CPU?

進程是操作系統的偉大發明之一&#xff0c;對應用程序屏蔽了CPU調度、內存管理等硬件細節&#xff0c;而抽象出一個進程的概念&#xff0c;讓應用程序專心于實現自己的業務邏輯既可&#xff0c;而且在有限的CPU上可以“同時”進行許多個任務。但是它為用戶帶來方便的同時&#…

嵌入式Linux Qt5 (C++)開發欄目概述

本欄目開始介紹Linux系統下的Qt C程序開發&#xff0c;資源是以嵌入式為切入點&#xff08;現在Linux系統下的Qt C程序開發好像就是應用于嵌入式&#xff09;&#xff0c;那就跟著一起學習Linux系統下的Qt C程序開發知識&#xff0c;再擴展一下嵌入式的知識吧。我這里默認已經熟…

php初解

php是什么&#xff1f; PHP&#xff0c;全稱 Hypertext Preprocessor &#xff0c;中文翻譯“超文本預處理器”。 PHP是一種被廣泛應用的開源通用腳本語言&#xff0c;尤其適用于 Web 開發。 擁有快速&#xff0c;靈活&#xff0c;實用的特點&#xff0c;PHP能做任何事&#xf…

ORACLE中UNION、UNION ALL、MINUS、INTERSECT學習

1、UNION和UNION ALL的使用與區別 如果我們需要將兩個select語句的結果作為一個整體顯示出來&#xff0c;我們就需要用到union或者union all關鍵字。union的作用是將多個結果合并在一起顯示出來。 union和union all的區別是union會自動壓縮多個結果集合中的重復結果&#xff…

高速下載VisualGLM模型文件的解決方案

大家好,我是愛編程的喵喵。雙985碩士畢業,現擔任全棧工程師一職,熱衷于將數據思維應用到工作與生活中。從事機器學習以及相關的前后端開發工作。曾在阿里云、科大訊飛、CCF等比賽獲得多次Top名次。現為CSDN博客專家、人工智能領域優質創作者。喜歡通過博客創作的方式對所學的…

GO語言自底向上優化

Go Ballast(通過嘗試降低 GC 頻率以提高整體性能&#xff0c;針對所有 Go應用都適用) 首先我們明白GO語言GC觸發條件是由比例來觸發的。例如&#xff0c;當前存活內存10GB&#xff0c;觸發比例是100%&#xff0c;因此下次觸發GC的時候是當內存達到20GB的時候觸發GC。這種機制在…

碎片筆記|圖數據與圖神經網絡基礎介紹

前言&#xff1a;前段時間了解了一下圖神經網絡&#xff0c;本篇博客記錄一下相關知識&#xff0c;以備不時之需。 強烈推薦這篇博客&#xff08;作者來自 Google Research&#xff09;&#xff0c;個人認為是圖神經網絡基礎入門的不二選擇&#xff01; 目錄 一、圖數據1.1 定義…