云原生 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.rhkb.cn/news/93242.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安科瑞变电所运维平台在电力系统中应用分析

摘要&#xff1a;现代居民生活、工作对电力资源的需求量相对较多&#xff0c;给我国的电力产业带来了良好的发展机遇与挑战。探索电力系统基本构成&#xff0c; 将变电运维安全管理以及相应的设备维护工作系统性开展&#xff0c;能够根据项目实践工作要求&#xff0c;将满足要求…

hbase 报错 Master passed us a different hostname to use; was=

原因 wsl2的 /etc/hosts 配置的不兼容,我这里是ubuntu22 命令行输入hostname 看输出什么,比如输出 aaa 那么替换/etc/hosts 127.0.0.1 aaa

Mysql之explain详解

1. explain作用 使用explain可以展示出sql语句的执行计划&#xff0c;再根据sql的执行计划去判断这条sql有哪些点可以进行优化&#xff0c;从而让sql的效率达到最大化。 2. 执行计划各列含义 &#xff08;1&#xff09;id&#xff1a;id列是select的序列号&#xff0c;这个…

【BASH】回顾与知识点梳理(三十二)

【BASH】回顾与知识点梳理 三十二 三十二. SELinux 初探32.1 什么是 SELinux当初设计的目标&#xff1a;避免资源的误用传统的文件权限与账号关系&#xff1a;自主式访问控制, DAC以政策规则订定特定进程读取特定文件&#xff1a;委任式访问控制, MAC 32.2 SELinux 的运作模式安…

nvm管理node版本

nvm是什么&#xff1f; NVM全名叫做 nodejs version manage,即Node的版本管理工具。 使用NVM&#xff0c;可以通过命令很方便地在多个NodeJS版本之间进行切换。 nvm的下载与安装 下载地址&#xff1a;Releases coreybutler/nvm-windows (github.com) windows系统下载nvm-setup…

【自动化测试】接口自动化01

文章目录 一、熟悉若requests库以及底层方法的调用逻辑二、接口自动化以及正则和Jsonpath提取器的应用6. 高频面试题&#xff1a;9. 示例&#xff1a;接口关联13. 文件上传示例14. cookie关联的接口 努力经营当下 直至未来明朗 一、熟悉若requests库以及底层方法的调用逻辑 接…

RTT(RT-Thread)ADC设备(RTT保姆级介绍)

目录 ADC设备 前言 ADC相关参数说明 访问ADC设备 配置ADC设备 ADC实例 硬件设计 软件设计 ADC设备 前言 ADC(Analog-to-Digital Converter) 指模数转换器。是指将连续变化的模拟信号转换为离散的数字信号的器件。 对于ADC的详细介绍和在STM32中的裸机应用可参考以下…

在CentOS 7上使用kubeadm部署Kubernetes集群

如有错误&#xff0c;敬请谅解&#xff01; 此文章仅为本人学习笔记&#xff0c;仅供参考&#xff0c;如有冒犯&#xff0c;请联系作者删除&#xff01;&#xff01; 前言&#xff1a; Kubernetes是一个开源的容器编排平台&#xff0c;用于管理和自动化部署容器化的应用程序。…

软文发布问题解答:高效宣传与推广指南

以下是一秒推小编针对软文发布的20个常见问题及回答&#xff1a; 1. 什么是软文&#xff1f; 答&#xff1a;软文是指用文学手法、写作技巧撰写的宣传文章&#xff0c;以实现对特定受众的陈述、说明和推销。 2. 发布软文的目的是什么&#xff1f; 答&#xff1a;发布软文的目…

出现ffmpeg.dll丢失的修复方法分享,教你快速修复ffmpeg.dll文件

当你使用或尝试运行与FFmpeg相关的应用程序时&#xff0c;可能会遇到一个常见的问题&#xff0c;ffmpeg.dll文件丢失。这个动态链接库文件对于正常运行FFmpeg应用程序至关重要。在本文中&#xff0c;我们将详细探讨为什么会出现ffmpeg.dll丢失的情况&#xff0c;并提供一些修复…

奥威BI数据可视化工具:360度呈现数据,告别枯燥表格

随着企业数据量的不断增加&#xff0c;如何有效地进行数据分析与决策变得越来越重要。奥威BI数据可视化工具作为一款强大的数据分析工具&#xff0c;在帮助企业深入挖掘数据价值方面具有显著优势。 奥威BI数据可视化工具是一款基于数据仓库技术的数据分析工具&#xff0c;具有…

海外应用ASO优化的小技巧3

编写准确的应用程序描述&#xff0c;有4000个字符限制。用户可以访问应用程序的主要功能和信息&#xff0c;要说服并推动用户去下载我们的应用&#xff0c;需要使用自然流利的语言。 1、填写应用描述的方案。 我们需要知道该应用有什么用&#xff0c;能够解决什么问题&#xf…

在医疗行业数字孪生能做些什么?

数字孪生技术随着发展正在多行业遍地开花&#xff0c;在之前的文章中也为大家介绍过数字孪生的行业应用&#xff0c;今天带大家一起探讨一下数字孪生在医疗行业的表现。其实数字孪生在医疗行业已有很多应用案例&#xff0c;从医疗诊断到手术模拟&#xff0c;再到药物研发&#…

基于Redis实现点赞及排行榜功能

微信公众号访问地址&#xff1a;基于Redis实现点赞及排行榜功能 推荐文章&#xff1a; 1、SpringBoot整合多数据源&#xff0c;并支持动态新增与切换&#xff08;详细教程&#xff09; 2、​​​​​​Redis中使用lua脚本 3、SpringBoot统一标准响应格式及异常处理 4、Spr…

linux两台服务器互相备份文件(sshpass + crontab)

crontab crontab是linux系统自带的定时调度软件&#xff0c;可用于设置周期性被执行的指令&#xff0c;一般用在每天的非高峰负荷时间段运行作业&#xff0c;可在无需人工干预的情况下运行作业。支持在一周或一月中的不同时段运行。 crontab命令允许用户提交、编辑或删除相应的…

MongoDB:数据库初步应用

一.连接MongoDB 1.MongoDBCompass连接数据库 连接路径:mongodb://用户名:密码localhost:27017/ 2.创建数据库(集合) MongoDB中数据库被称为集合. MongoDBCompass连接后,点击红色框加号创建集合,点击蓝色框加号创建文档(数据表) 文档中的数据结构(相当于表中的列)设计不用管…

安装chromedriver 115,对应chrome版本115(经检验,116也可以使用)

目录 1. 查看Chrome浏览器的版本2. 找到对应的chromedriver3. 安装ChromeDriver 1. 查看Chrome浏览器的版本 点进这个网站查看&#xff1a;chrome://settings/help &#xff08;真是的&#xff0c;上一秒还是115版本&#xff0c;更新后就是116版本了&#xff0c;好在chromedi…

java版本企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发

java版本企业电子招标采购系统源码Spring Cloud Spring Boot 二次开发 一、立项管理 1、招标立项申请 功能点&#xff1a;招标类项目立项申请入口&#xff0c;用户可以保存为草稿&#xff0c;提交。 2、非招标立项申请 功能点&#xff1a;非招标立项申请入口、用户可以保存为草…

【JVM】JVM 调优的参数都有哪些?

文章目录 1. 设置堆空间大小2. 虚拟机栈的设置3. 年轻代中Eden区和两个Survivor区的大小比例4. 年轻代晋升老年代阈值5. 设置垃圾回收收集器 1. 设置堆空间大小 设置堆的初始大小和最大大小&#xff0c;为了防止垃圾收集器在初始大小、最大大小之间收缩堆而产生额外的时间&…

JVM——HotSpot的算法细节实现

一、根节点枚举 固定可作为GC Roots的节点主要在全局性的引用&#xff08;如常量或类静态属性&#xff09;与执行上下文&#xff08;如栈帧中的本地变量表&#xff09;中&#xff0c;尽管目标明确&#xff0c;但查找要做到高效很难。现在java应用越来越庞大&#xff0c;光方法区…