Spring Cloud Gateway 监控、多网关实例路由共享 | Spring Cloud 18

news2024/11/22 14:11:36

一、监控

ActuatorSpring Boot提供的用来对应用系统进行监控的功能模块,借助于Actuator开发者可以很方便地对应用系统某些监控指标进行查看、统计等。

Actuator的核心是端点Endpoint

Endpoint可以让我们监视应用程序并与其交互。Spring Boot包含许多内置端点,并允许您添加自己的端点。

我们可以启用或禁用每个端点,启用或禁用端点控制是否创建端点并且其bean存在于应用程序上下文中。 要进行远程访问,还必须通过JMXHTTP公开端点。大多数端点HTTP访问默认是关闭的。

二、开启Gateway的Actuator

2.1 引入Actuator依赖

gateway/pom.xml 新增以下内容:

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

2.2 启动监控端点

gateway/src/main/resources/bootstrap.yml中新增以下内容:

management.endpoint.gateway.enabled: true # default value
management.endpoints.web.exposure.include: gateway

开启监控端点,访问/actuator/gateway/*Spring Cloud Gateway 应用程序进行交互。

2.3 详细访问格式

Spring Cloud Gateway监控端点(注意每个端点都有/actuator/gateway基本路径):

ID方法描述
globalfiltersGET获取网关中定义(应用于所有路由)的全局过滤器列表。
routefiltersGET获取网关中定义(应用于路由)的GatewayFilterFactory列表。
refreshPOST清除路由缓存。
routesGET获取网关中定义的路由列表。
routes/{id}GET获取指定路由的信息。
routes/{id}POST向网关添加新的路由。
routes/{id}DELETE从网关中删除指定路由。

2.3.1 获取路由明细

通过/actuator/gateway/routes获取网关中定义的路由列表:

[{
	"predicate": "Paths: [/provider/**], match trailing slash: true",
	"route_id": "54c58c6b-de67-4381-a9de-5f39690a35c3",
	"filters": ["[[StripPrefix parts = 1], order = 0]"],
	"uri": "http://localhost:4000",
	"order": 0
}, {
	"predicate": "Paths: [/lb/**], match trailing slash: true",
	"route_id": "36e46476-f309-473c-87c3-5f6a41f9b9a0",
	"filters": ["[[StripPrefix parts = 1], order = 0]"],
	"uri": "lb://nacos-discovery-http-provider",
	"order": 0
}, {
	"predicate": "Paths: [/csdn/**], match trailing slash: true",
	"route_id": "ce24523b-50e8-468d-b581-cfbb063ab64b",
	"filters": ["[[RewritePath /csdn/(?<remaining>.*) = '/${remaining}'], order = 0]"],
	"uri": "https://blog.csdn.net:443",
	"order": 0
}, {
	"predicate": "Paths: [/provider/**], match trailing slash: true",
	"route_id": "http-provider-route",
	"filters": ["[[StripPrefix parts = 1], order = 1]"],
	"uri": "http://localhost:4000",
	"order": 0
}, {
	"predicate": "(Paths: [/lb/**], match trailing slash: true && com.gm.demo.gateway.component.CustomRoutePredicateFactory$1@41a0a5ba)",
	"route_id": "nacos-discovery-http-provider-route",
	"filters": ["[[StripPrefix parts = 1], order = 1]"],
	"uri": "lb://nacos-discovery-http-provider",
	"order": 0
}, {
	"predicate": "(XForwardedRemoteAddrRoutePredicateFactory$$Lambda$1155/0x000000080141f938 && Paths: [/proxy/**], match trailing slash: true)",
	"route_id": "xforwarded_remoteaddr_route",
	"filters": ["[[StripPrefix parts = 1], order = 1]", "[[RedirectTo 302 = http://baidu.com], order = 2]"],
	"uri": "http://127.0.0.1:9999/",
	"order": 0
}, {
	"predicate": "Paths: [/rate/**], match trailing slash: true",
	"route_id": "requestratelimiter_route",
	"filters": ["[[StripPrefix parts = 1], order = 1]", "[com.gm.demo.gateway.filter.CustomRequestRateLimiterGatewayFilterFactory$$Lambda$1181/0x0000000801432860@6ee76969, order = 2]"],
	"uri": "lb://nacos-discovery-http-provider",
	"order": 0
}, {
	"predicate": "Paths: [/day/**], match trailing slash: true",
	"route_id": "day_requestratelimiter_route",
	"filters": ["[[StripPrefix parts = 1], order = 1]", "[com.gm.demo.gateway.filter.DayRequestRateLimitGatewayFilterFactory$$Lambda$1182/0x0000000801432ac0@5c25c28d, order = 2]"],
	"uri": "lb://nacos-discovery-http-provider",
	"order": 0
}, {
	"predicate": "Paths: [/delay/**], match trailing slash: true",
	"metadata": {
		"connect-timeout": 200,
		"response-timeout": 200
	},
	"route_id": "per_route_timeouts",
	"filters": ["[[StripPrefix parts = 1], order = 1]"],
	"uri": "https://example.org:443",
	"order": 0
}]

响应包含网关中定义的所有路由的详细信息。下表描述了响应的每个元素(每个都是一个路由)的结构:

名称类型描述
route_idString路由标识
predicateObject路由断言
filtersArray应用于路由的GatewayFilterFactory集合
orderNumber路由顺序

默认情况下启用此功能。要禁用它,请设置以下属性:

spring.cloud.gateway.actuator.verbose.enabled: false

2.3.2 检索全局过滤器

通过/actuator/gateway/globalfilters获取网关中定义(应用于所有路由)的全局过滤器列表:

{
	"org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@684a802a": -1,
	"org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@3a589eed": -2147482648,
	"org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@69d902f9": 10000,
	"org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@10a064bd": 10150,
	"org.springframework.cloud.gateway.filter.ForwardPathFilter@3ca3eba2": 0,
	"org.springframework.cloud.gateway.filter.NettyRoutingFilter@2ff8d39b": 2147483647,
	"org.springframework.cloud.gateway.filter.RemoveCachedBodyFilter@7b5c9412": -2147483648,
	"org.springframework.cloud.gateway.filter.ForwardRoutingFilter@547052": 2147483647,
	"org.springframework.cloud.gateway.filter.LoadBalancerServiceInstanceCookieFilter@2de7fe0e": 10151,
	"org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c00420": 2147483646,
	"com.gm.demo.gateway.filter.ApiLoggingFilter@352e4b6d": 2147483647,
	"org.springframework.cloud.gateway.filter.GatewayMetricsFilter@22f046b": 0
}

响应包含现有全局过滤器的详细信息。对于每个全局过滤器,都有过滤器对象的字符串表示和过滤器链中的相应顺序。

2.3.4 路由过滤器

通过/actuator/gateway/routefilters获取网关中定义(应用于路由)的GatewayFilterFactory列表:

{
	"[DedupeResponseHeaderGatewayFilterFactory@336070ab configClass = DedupeResponseHeaderGatewayFilterFactory.Config]": null,
	"[RequestRateLimiterGatewayFilterFactory@433b546f configClass = RequestRateLimiterGatewayFilterFactory.Config]": null,
	"[RedirectToGatewayFilterFactory@3dec769 configClass = RedirectToGatewayFilterFactory.Config]": null,
	"[RetryGatewayFilterFactory@3d405fe5 configClass = RetryGatewayFilterFactory.RetryConfig]": null,
	"[PrefixPathGatewayFilterFactory@20a4cba7 configClass = PrefixPathGatewayFilterFactory.Config]": null,
	"[RewriteResponseHeaderGatewayFilterFactory@19d9ba89 configClass = RewriteResponseHeaderGatewayFilterFactory.Config]": null,
	"[AddRequestHeaderGatewayFilterFactory@2419a5db configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
	"[RewritePathGatewayFilterFactory@9de1b85 configClass = RewritePathGatewayFilterFactory.Config]": null,
	"[StripPrefixGatewayFilterFactory@3436d3d7 configClass = StripPrefixGatewayFilterFactory.Config]": null,
	"[SetRequestHostHeaderGatewayFilterFactory@dbca149 configClass = SetRequestHostHeaderGatewayFilterFactory.Config]": null,
	"[DayRequestRateLimitGatewayFilterFactory@7dc92a06 configClass = DayRequestRateLimitGatewayFilterFactory.Config]": null,
	"[RewriteLocationResponseHeaderGatewayFilterFactory@484876a1 configClass = RewriteLocationResponseHeaderGatewayFilterFactory.Config]": null,
	"[RequestSizeGatewayFilterFactory@2e47a71e configClass = RequestSizeGatewayFilterFactory.RequestSizeConfig]": null,
	"[CacheRequestBodyGatewayFilterFactory@6be80629 configClass = CacheRequestBodyGatewayFilterFactory.Config]": null,
	"[ModifyRequestBodyGatewayFilterFactory@383e6734 configClass = ModifyRequestBodyGatewayFilterFactory.Config]": null,
	"[CustomRequestRateLimiterGatewayFilterFactory@2a73a64f configClass = RequestRateLimiterGatewayFilterFactory.Config]": null,
	"[AddResponseHeaderGatewayFilterFactory@516037be configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
	"[SetRequestHeaderGatewayFilterFactory@323c6f9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
	"[SaveSessionGatewayFilterFactory@60ef30b1 configClass = Object]": null,
	"[RemoveRequestHeaderGatewayFilterFactory@282c5075 configClass = AbstractGatewayFilterFactory.NameConfig]": null,
	"[RemoveRequestParameterGatewayFilterFactory@2ed35f24 configClass = AbstractGatewayFilterFactory.NameConfig]": null,
	"[ModifyResponseBodyGatewayFilterFactory@3be50b2c configClass = ModifyResponseBodyGatewayFilterFactory.Config]": null,
	"[SecureHeadersGatewayFilterFactory@4b475742 configClass = SecureHeadersGatewayFilterFactory.Config]": null,
	"[RequestHeaderToRequestUriGatewayFilterFactory@3f40568e configClass = AbstractGatewayFilterFactory.NameConfig]": null,
	"[PreserveHostHeaderGatewayFilterFactory@10f10230 configClass = Object]": null,
	"[SetStatusGatewayFilterFactory@20163008 configClass = SetStatusGatewayFilterFactory.Config]": null,
	"[RemoveResponseHeaderGatewayFilterFactory@362b384c configClass = AbstractGatewayFilterFactory.NameConfig]": null,
	"[SetResponseHeaderGatewayFilterFactory@68550d86 configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
	"[MapRequestHeaderGatewayFilterFactory@52bb3dcd configClass = MapRequestHeaderGatewayFilterFactory.Config]": null,
	"[SetPathGatewayFilterFactory@52c6e959 configClass = SetPathGatewayFilterFactory.Config]": null,
	"[RequestHeaderSizeGatewayFilterFactory@37b470df configClass = RequestHeaderSizeGatewayFilterFactory.Config]": null,
	"[AddRequestParameterGatewayFilterFactory@654db80b configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null
}

2.3.5 刷新路由缓存

要清除路由缓存,发出请求/actuator/gateway/refresh。该请求返回 200,但没有响应正文。

2.3.6 获取网关中定义的路由

通过/actuator/gateway/routes获取网关中定义的路由列表:

[{
	"predicate": "Paths: [/provider/**], match trailing slash: true",
	"route_id": "54c58c6b-de67-4381-a9de-5f39690a35c3",
	"filters": ["[[StripPrefix parts = 1], order = 0]"],
	"uri": "http://localhost:4000",
	"order": 0
}, {
	"predicate": "Paths: [/lb/**], match trailing slash: true",
	"route_id": "36e46476-f309-473c-87c3-5f6a41f9b9a0",
	"filters": ["[[StripPrefix parts = 1], order = 0]"],
	"uri": "lb://nacos-discovery-http-provider",
	"order": 0
}, {
	"predicate": "Paths: [/csdn/**], match trailing slash: true",
	"route_id": "ce24523b-50e8-468d-b581-cfbb063ab64b",
	"filters": ["[[RewritePath /csdn/(?<remaining>.*) = '/${remaining}'], order = 0]"],
	"uri": "https://blog.csdn.net:443",
	"order": 0
}, {
	"predicate": "Paths: [/provider/**], match trailing slash: true",
	"route_id": "http-provider-route",
	"filters": ["[[StripPrefix parts = 1], order = 1]"],
	"uri": "http://localhost:4000",
	"order": 0
}, {
	"predicate": "(Paths: [/lb/**], match trailing slash: true && com.gm.demo.gateway.component.CustomRoutePredicateFactory$1@3715ba94)",
	"route_id": "nacos-discovery-http-provider-route",
	"filters": ["[[StripPrefix parts = 1], order = 1]"],
	"uri": "lb://nacos-discovery-http-provider",
	"order": 0
}, {
	"predicate": "(XForwardedRemoteAddrRoutePredicateFactory$$Lambda$1155/0x000000080141f938 && Paths: [/proxy/**], match trailing slash: true)",
	"route_id": "xforwarded_remoteaddr_route",
	"filters": ["[[StripPrefix parts = 1], order = 1]", "[[RedirectTo 302 = http://baidu.com], order = 2]"],
	"uri": "http://127.0.0.1:9999/",
	"order": 0
}, {
	"predicate": "Paths: [/rate/**], match trailing slash: true",
	"route_id": "requestratelimiter_route",
	"filters": ["[[StripPrefix parts = 1], order = 1]", "[com.gm.demo.gateway.filter.CustomRequestRateLimiterGatewayFilterFactory$$Lambda$1181/0x0000000801432860@711c23ed, order = 2]"],
	"uri": "lb://nacos-discovery-http-provider",
	"order": 0
}, {
	"predicate": "Paths: [/day/**], match trailing slash: true",
	"route_id": "day_requestratelimiter_route",
	"filters": ["[[StripPrefix parts = 1], order = 1]", "[com.gm.demo.gateway.filter.DayRequestRateLimitGatewayFilterFactory$$Lambda$1182/0x0000000801432ac0@58145bb, order = 2]"],
	"uri": "lb://nacos-discovery-http-provider",
	"order": 0
}, {
	"predicate": "Paths: [/delay/**], match trailing slash: true",
	"metadata": {
		"connect-timeout": 200,
		"response-timeout": 200
	},
	"route_id": "per_route_timeouts",
	"filters": ["[[StripPrefix parts = 1], order = 1]"],
	"uri": "https://example.org:443",
	"order": 0
}]

2.3.6 获取指定路由信息

通过/gateway/routes/{id}获取指定路由的信息:

{
	"predicate": "Paths: [/provider/**], match trailing slash: true",
	"route_id": "54c58c6b-de67-4381-a9de-5f39690a35c3",
	"filters": ["[[StripPrefix parts = 1], order = 0]"],
	"uri": "http://localhost:4000",
	"order": 0
}

下表描述了响应结构:

名称类型描述
route_idString路由标识
predicateObject路由断言
filtersArray应用于路由的GatewayFilterFactory集合
orderNumber路由顺序

2.3.7 创建路由

要创建路由需指定路由字段的 JSON 正文发出POST请求,/gateway/routes/{id_route_to_create}

其中 JSON 正文内容请见2.3.6获取指定路由信息

2.3.8 删除路由

通过/gateway/routes/{id_route_to_delete}DELETE请求删除路由。

三、多网关实例路由共享

Spring Cloud Gateway 提供了两种RouteDefinitionRepository实现。

第一个是 InMemoryRouteDefinitionRepository仅存在于一个网关实例的内存中的。这种类型的存储库不适合跨多个网关实例路由共享。

为了在 Spring Cloud Gateway 实例集群之间共享路由,需要启动RedisRouteDefinitionRepository存储库。

3.1 引入redis-reactive依赖

gateway/pom.xml 新增以下内容:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

3.2 启用存储库

gateway/src/main/resources/bootstrap.yml中新增以下内容启用Redis存储库:

spring.cloud.gateway.redis-route-definition-repository.enabled: true

通过配置文件配置的静态路由和 redis 动态路由同时存在时取并集。

需与监控端点配置使用。在下文具体描述。

3.3 测试步骤及效果

3.3.1 移除静态路由

删除配置文件中的静态路由配置

此步骤可省略

3.3.2 添加路由

通过监控端点添加路由,通过Postman进行:
在这里插入图片描述
示例JSON请求体:

{
	"id": "baidu_route",
	"predicates": [{
		"name": "Path",
		"args": {
			"_genkey_0": "/baidu/**"
		}
	}],
	"filters": [{
		"name": "StripPrefix",
		"args": {
			"path": 1
		}
	}],
	"uri": "https://www.baidu.com",
	"order": 0
}

JSON请求体格式最好是参照PredicateFactoryConfig属性和GatewayFilterFactoryConfig属性进行配置

请求成功后,新添加的路由并没有马上生效,需要等待路由刷新后才正式生效

3.3.3 查看redis

发现新添加的路由在存储在Redis中,key的命名规则是routedefinition_*
在这里插入图片描述

3.3.4 重启网关服务

重新进行访问,原持久化至Redis被再次生效:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/404327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

rapidcsv 写csv文件实例

csv实质是一个文本文件&#xff0c;可以使用rapidcsv写文件操作&#xff0c;如下实例&#xff1a; 第一行实质是从-1行开始&#xff0c;列是从0开始 #include "rapidcsv.h" #include <string> using namespace std; void CMFCApplication1Dlg::OnBnClickedBu…

【flask】URL和视图映射

目录 首页 传参 URL数据类型 get传参 首页 url与视图函数的映射是通过app.route()装饰器实现的。 只有一个斜杠代表的是根目录——首页。 传参 URL传参是通过<参数名称>的形式进行传递。URL中有几个参数&#xff0c;在视图函数中也要指定几个参数 from flask im…

WattOS:一个稳又快的轻量级 Linux 发行版

导读Linux 领域里的每个人不是听说过就是使用过某个轻量级的 Linux 发行版。大家都知道我们不断追求的是&#xff1a;占用内存少&#xff0c;配置资源要求低&#xff0c;包含一个轻量级的桌面环境&#xff08;或者窗口管理器&#xff09;&#xff0c;并且提供和其他发行版相似的…

从官网下载/处理 MNIST 数据集,并构造CNN网络训练

这里写自定义目录标题MNIST 网络 测试用1. 导入所需要的模块2. 下载 MNIST 数据集3. 读取 MNIST 数据集MNIST 网络 测试用 1. 导入所需要的模块 import sys sys.path.append(../../) from zfdplearn import fdutils, fdtorch_net, fddata import os import os.path as path i…

# 数据完整性算法在shell及python中的实践

数据完整性算法在shell及python中的实践 文章目录数据完整性算法在shell及python中的实践1 预备知识1.1 摘要算法1.2 报文&#xff08;数据&#xff09;完整性校验1.3 python byte类型字符串与普通字符串区别2 传统方法&#xff08;散列函数&#xff09;2.1 在shell中实践2.2 在…

python调试模块ipdb

1. 调试python ipdb是用来python中用以交互式debug的模块&#xff0c;可以直接利用pip安装; 其功能类似于pycharm中 python控制台&#xff0c; 而使用ipdb 的优点&#xff0c;便是直接在代码中调试&#xff0c; 避免了在python控制台&#xff0c;或者重新设置一些简单变量。…

Web前端开发--自用

第一章 1.1 时间&#xff1a;1980 人物&#xff1a;Tim Berners-Lee 地点&#xff1a;欧洲核子研究组织中最大的欧洲核子物理实验室 事件&#xff1a;与Robert Cailliau建立ENQUIRE系统 1984年&#xff0c;世界上第一个客户端浏览器&#xff08;World Wide Web&#xff09;和第…

软考高项——配置管理

配置管理配置管理配置管理6个主要活动配置项配置基线配置项的状态配置库配置库权限管理配置审计配置管理 配置管理的总线索包括&#xff1a; 1&#xff09;配置管理6个主要活动 2&#xff09;配置项 3&#xff09;配置基线 4&#xff09;配置项的状态 5&#xff09;配置库 6&a…

SAP SQVI快速报表的使用

SQVI快速报表 一、说明 对数据表进行查询通常使用SE16&#xff0c;但只限于单张表&#xff0c;对于多表联动的查询&#xff0c;则需要通过创建Query的方式&#xff0c;方法有多种&#xff0c;而SQVI是一种简洁快速的工具。SQVI全称是Quick Viewer&#xff0c;可以快速生成多表…

动态规划回文子串

647. 回文子串方法&#xff1a;双指针回文子串有长度为奇数和偶数两种&#xff0c;extend(s, i, i, n); extend(s, i, i 1, n);就分别对应长度为奇数和偶数的情况class Solution { private:int extend(const string& s, int i, int j, int n) {int res 0;while (i > 0…

前端——8.超链接标签

这篇文章&#xff0c;我们来讲一下超链接标签 目录 1.超链接标签介绍 1.1链接的分类 2.具体案例讲解 2.1外部链接 2.2 内部标签 2.3 空链接 2.4下载连接 2.5网页元素链接 2.6锚点标签 3.小结 1.超链接标签介绍 超链接标签是HTML中一个十分重要的标签&#xff0c;下…

案例18-面向对象之开门小例子

目录 一&#xff1a;背景介绍 二&#xff1a;思路&方案 1.面向过程 2.面向对象 3.面向对象(反射) 三&#xff1a;过程 1.面向过程&#xff1a;原本何老师的作用交给我了米老师来完成。 2.面向对象&#xff1a;把开门的方法完全交个何老师&#xff0c;米老师不需要有…

k8s 部署 skywalking 并持久化到es

1、k8s中安装部署 skywalking skywalking集群情况下需要保证用同一数据源&#xff0c;这里我们存储方式改为es 1.1 部署elasticsearch docker run -it -d -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS"-Xms256m -Xmx256m" -e "discovery.typesingle-node"…

DSRC技术

DSRC(Dedicated Short Range Communication)专用短程通信 定位 是V2X领域存在的两大通信技术之一&#xff08;另一个为LTE-V2X&#xff09;。 所属技术路线 与这两大技术相对应&#xff0c;是V2X无线通信技术的两大技术路线&#xff1a; IEEE 802.11p 本是04年指定的一个通…

一文入门HTML+CSS+JS(样例后续更新)

一文入门HTMLCSSJS&#xff08;样例后续更新&#xff09;前言HTML&#xff0c;CSS和JS的关系HTMLhead元素titlelinkmetabody元素设置网页正文颜色与背景颜色添加网页背景图片设置网页链接文字颜色设置网页边框文字与段落标记普通文字的输入对文字字体的设置 font使用文字的修饰…

代码随想录刷题-数组总结篇

文章目录数组二分查找原理习题题目1思路和代码题目-2移除元素习题我的想法暴力解法双指针有序数组的平方习题暴力排序双指针长度最小的子数组习题暴力解法滑动窗口螺旋矩阵 II习题我的解法别人的解法总结数组 二分查找 本节对应代码随想录中&#xff1a;代码随想录-二分查找 …

java教程--函数式接口--lambda表达式--方法引用

函数式接口 介绍 jdk8新特性&#xff0c;只有一个抽象方法的接口我们称之为函数接口。 FunctionalInterface ​ JDK的函数式接口都加上了FunctionalInterface 注解进行标识。但是无论是否加上该注解只要接口中只有一个抽象方法&#xff0c;都是函数式接口。 如在Comparato…

Makefile的概述

什么是makemake 是个命令&#xff0c;是个可执行程序&#xff0c;用来解析Makefile文件的命令&#xff0c;这个命令存放在 /usr/binmake概述1.GUN make是一种代码维护工具2.make 工具会根据makefile文件定义的规则和步骤&#xff0c;完成整个软件项目的代码维护工作。3.一般用来…

解决Win10图片/文件右键单击自动退出并刷新桌面问题

问题描述 这两天开始不知道怎么回事儿&#xff0c;右键选择图片时候&#xff0c;电脑黑屏且资源管理器自动重启。然后我就开始找很多方法去解决。 我试了很多种复杂的简单的方法&#xff0c;但是只有一种解决了我的问题。 解决方案【解决我的问题】 这个方法如下&#xff1…

VirtualBox的克隆与复制

快照太多&#xff0c;想整合成1个文件怎么办&#xff1f; 最近&#xff0c;我就遇到一个问题。快照太多了。比较占用空间怎么办&#xff1f; 错误做法 一开始&#xff0c;我是这么操作的&#xff0c;选中某个快照&#xff0c;然后选择删除…然后我登录虚拟机后&#xff0c;发…