[Java]微服务配置管理
介绍
代码拆分为微服务后, 每个服务都有自己的配置文件, 而这些配置文件中有很多重复的配置, 并且配置变化后需要重启服务, 才能生效, 这样就会影响开发体验和效率
配置管理服务可以帮助我们集中管理公共的配置, 并且nacos就可以实现配置管理服务
配置共享
我们可以把微服务共享的配置抽取到Nacos中统一管理,这样就不需要每个微服务都重复配置了。
分为两步:
- 在Nacos中添加共享配置
- 微服务拉取配置
- 在Nacos中添加共享配置
- 以cart-service为例,我们看看有哪些配置是重复的,可以抽取的:
- 首先是jdbc相关配置:
- 然后是日志配置:
- 然后是swagger以及OpenFeign的配置:
- 在nacos控制台分别添加这些配置。
2-1 首先是jdbc相关配置,在配置管理
->配置列表
中点击+
新建一个配置:
- http://192.168.1.97:8848/nacos/
- 在弹出的表单中填写信息:
- 其中详细的配置如下
spring:datasource:url: jdbc:mysql://${hm.db.host:192.168.150.101}:${hm.db.port:3306}/${hm.db.database}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: ${hm.db.un:root}password: ${hm.db.pw:123}
mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandlerglobal-config:db-config:update-strategy: not_nullid-type: auto
- 这里的jdbc的相关参数不能写死,例如:
数据库ip
: 通过${hm.db.host:192.168.150.101}
配置了默认值为192.168.150.101
,同时允许通过${hm.db.host}
来覆盖默认值数据库端口
: 通过${hm.db.port:3306}
配置了默认值为3306
,同时允许通过${hm.db.port}
来覆盖默认值数据库database
:可以通过${hm.db.database}
来设定,无默认值
2-2 然后是统一的日志配置,命名为shared-log.
yaml
,配置内容如下:
logging:level:com.hmall: debugpattern:dateformat: HH:mm:ss:SSSfile:path: "logs/${spring.application.name}"
3-3 然后是统一的swagger配置,命名为shared-swagger.yaml
,配置内容如下:
knife4j:enable: trueopenapi:title: ${hm.swagger.title:黑马商城接口文档}description: ${hm.swagger.description:黑马商城接口文档}email: ${hm.swagger.email:zhanghuyi@itcast.cn}concat: ${hm.swagger.concat:虎哥}url: https://www.itcast.cnversion: v1.0.0group:default:group-name: defaultapi-rule: packageapi-rule-resources:- ${hm.swagger.package}
- 微服务拉取配置
2-1 了解基于NacosConfig拉取共享配置代替微服务的本地配置的流程
- 项目启动后, SpringCloud在初始化上下文的时候会先读取一个名为
bootstrap.yaml
(或者bootstrap.properties
)的文件,我们将nacos地址配置到bootstrap.yaml
中,SpringCloud就可以读取nacos中的配置了。 - nacos的配置文件拉取完成后, SpringCloud上下文(
ApplicationContext
)才会初始化SpringBoot上下文,去读取application.yaml
。 - 将拉取到的共享配置与本地的
application.yaml
配置合并,完成项目上下文的初始化。
因此,微服务整合Nacos配置管理的步骤如下:
2-2 在cart-service模块引入依赖:
<!--nacos配置管理--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--读取bootstrap文件--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency>
2-3 新建bootstrap.yaml文件:
spring:application:name: cart-service #每个微服务对应一个名称profiles:active: dev #读取dev的配置cloud:nacos:server-addr: 192.168.1.97:8848 #nacos地址config:file-extension: yaml # 文件后缀名shared-configs: # 配置共享- dataId: shared-jdbc.yaml # 共享mybatis配置- dataId: shared-log.yaml # 共享日志配置- dataId: shared-swagger.yaml # 共享swagger配置
2-4 修改application.yaml
由于一些配置挪到了bootstrap.yaml,因此application.yaml需要修改为:
server:port: 8082
feign:okhttp:enabled: true # 开启OKHttp连接池支持
hm:swagger:title: "购物车服务接口文档"package: com.hmall.cart.controllerdb:database: hm-cart
2-5 重启购物车模块, 查看配置是否生效, 测试功能是否正常
配置热更新
当修改配置文件中的配置时,微服务无需重启即可使配置生效。
- 配置共享只能简化各个微服务中配置文件, 实现公共配置的共享
- 很多的业务中的参数,将来可能会根据实际情况临时调整。例如购物车业务,购物车数量有一个上限
- 我们应该将其配置在配置文件中,方便后期修改。
- 但现在的问题是,即便写在配置文件中,修改了配置还是需要重新打包、重启服务才能生效。
- 这就要用到Nacos的配置热更新能力了,修改配置文件后, 无需重启立即生效
- 在Nacos中添加配置
- 这里我们直接使用
cart-service.yaml
这个名称,则不管是dev还是local环境都可以共享该配置。 - 如果是
cart-service-application.dev.yaml
这个名称,则dev环境才可以使用该配置。
1-1 nacos中要有一个与微服务名有关的配置文件
- 注意文件的dataId格式:要符合规定的规则
[服务名]-[spring.active.profile].[后缀名]
文件名称由三部分组成:
服务名
:我们是购物车服务,所以是cart-service
spring.active.profile
:就是spring boot中的spring.active.profile
,可以省略,则所有profile共享该配置后缀名
:例如yaml
- 在微服务读取配置
2-1 微服务中要以特定方式读取需要热更新的配置属性, 推荐使用方式1
2-2 在cart-service
中新建一个配置属性读取类:
@Data
@Component
@ConfigurationProperties(prefix = "hm.cart")
public class CartProperties {private Integer maxItems;
}
2-3 接着,在业务中使用该属性加载类:
2-4 测试一下: 向购物车中添加多个商品, 然后修改nacos中的配置, 再次添加商品
动态路由
网关的路由配置全部是在项目启动时由org.springframework.cloud.gateway.route.CompositeRouteDefinitionLocator
在项目启动的时候加载,并且一经加载就会缓存到内存中的路由表内(一个Map),不会改变。也不会监听路由变更,所以,我们无法利用上节课学习的配置热更新来实现路由更新。
因此,我们必须监听Nacos的配置变更,然后手动把最新的路由更新到路由表中。这里有两个难点:
- 如何监听Nacos配置变更?
- 如何把路由信息更新到路由表?
1. 监听Nacos配置变更
在Nacos官网中给出了手动监听Nacos配置变更的SDK:
https://nacos.io/zh-cn/docs/sdk.html
如果希望 Nacos 推送配置变更,可以使用 Nacos 动态监听配置接口来实现。
public void addListener(String dataId, String group, Listener listener)
请求参数说明:
示例代码:
String serverAddr = "{serverAddr}";
String dataId = "{dataId}";
String group = "{group}";
// 1.创建ConfigService,连接Nacos
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
ConfigService configService = NacosFactory.createConfigService(properties);
// 2.读取配置
String content = configService.getConfig(dataId, group, 5000);
// 3.添加配置监听器
configService.addListener(dataId, group, new Listener() {@Overridepublic void receiveConfigInfo(String configInfo) {// 配置变更的通知处理System.out.println("recieve1:" + configInfo);}@Overridepublic Executor getExecutor() {return null;}
});
这里核心的步骤有2步:
- 创建ConfigService,目的是连接到Nacos
- 添加配置监听器,编写配置变更的通知处理逻辑
第一步: 创建ConfigService
由于我们采用了spring-cloud-starter-alibaba-nacos-config
自动装配,因此ConfigService
已经在com.alibaba.cloud.nacos.NacosConfigAutoConfiguration
中自动创建好了:
NacosConfigManager中是负责管理Nacos的ConfigService的,具体代码如下:
因此,只要我们拿到NacosConfigManager
就等于拿到了ConfigService
,第一步就实现了。
第二步,编写监听器。
虽然官方提供的SDK是ConfigService中的addListener,不过项目第一次启动时不仅仅需要添加监听器,也需要读取配置,因此建议使用的API是这个:
String getConfigAndSignListener(String dataId, // 配置文件idString group, // 配置组,走默认long timeoutMs, // 读取配置的超时时间Listener listener // 监听器
) throws NacosException;
既可以配置监听器,并且会根据dataId和group读取配置并返回。我们就可以在项目启动时先更新一次路由,后续随着配置变更通知到监听器,完成路由更新。
2. 更新路由
更新路由要用到org.springframework.cloud.gateway.route.RouteDefinitionWriter
这个接口:
package org.springframework.cloud.gateway.route;import reactor.core.publisher.Mono;/*** @author Spencer Gibb*/
public interface RouteDefinitionWriter {/*** 更新路由到路由表,如果路由id重复,则会覆盖旧的路由*/Mono<Void> save(Mono<RouteDefinition> route);/*** 根据路由id删除某个路由*/Mono<Void> delete(Mono<String> routeId);}
这里更新的路由,也就是RouteDefinition,之前我们见过,包含下列常见字段:
- id:路由id
- predicates:路由匹配规则
- filters:路由过滤器
- uri:路由目的地
将来我们保存到Nacos的配置也要符合这个对象结构,将来我们以JSON来保存,格式如下:
{"id": "item","predicates": [{"name": "Path","args": {"_genkey_0":"/items/**", "_genkey_1":"/search/**"}}],"filters": [],"uri": "lb://item-service"
}
以上JSON配置就等同于:
spring:cloud:gateway:routes:- id: itemuri: lb://item-servicepredicates:- Path=/items/**,/search/**
OK,我们所需要用到的SDK已经齐全了。
3. 实现动态路由
首先, 我们在网关gateway引入依赖:
<!--统一配置管理-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--加载bootstrap-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
然后在网关gateway
的resources
目录创建bootstrap.yaml
文件,内容如下:
spring:application:name: gatewaycloud:nacos:server-addr: 192.168.1.97:8848config:file-extension: yamlshared-configs:- dataId: shared-log.yaml # 共享日志配置
接着,修改gateway
的resources
目录下的application.yml
,把之前的路由移除,最终内容如下:
server:port: 8080
hm:jwt:location: classpath:hmall.jksalias: hmallpassword: hmall123tokenTTL: 30mauth:excludePaths:- /search/**- /users/login- /items/**- /hi
然后,在gateway
中定义配置监听器:
package com.hmall.gateway.route;import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.hmall.common.utils.CollUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;@Slf4j
@Component
@RequiredArgsConstructor
public class DynamicRouteLoader {private final RouteDefinitionWriter writer;private final NacosConfigManager nacosConfigManager;// 路由配置文件的id和分组private final String dataId = "gateway-routes.json";private final String group = "DEFAULT_GROUP";// 保存更新过的路由idprivate final Set<String> routeIds = new HashSet<>();@PostConstructpublic void initRouteConfigListener() throws NacosException {// 1.注册监听器并首次拉取配置String configInfo = nacosConfigManager.getConfigService().getConfigAndSignListener(dataId, group, 5000, new Listener() {@Overridepublic Executor getExecutor() {return null;}@Overridepublic void receiveConfigInfo(String configInfo) {updateConfigInfo(configInfo);}});// 2.首次启动时,更新一次配置updateConfigInfo(configInfo);}private void updateConfigInfo(String configInfo) {log.debug("监听到路由配置变更,{}", configInfo);// 1.反序列化List<RouteDefinition> routeDefinitions = JSONUtil.toList(configInfo, RouteDefinition.class);// 2.更新前先清空旧路由// 2.1.清除旧路由for (String routeId : routeIds) {writer.delete(Mono.just(routeId)).subscribe();}routeIds.clear();// 2.2.判断是否有新的路由要更新if (CollUtils.isEmpty(routeDefinitions)) {// 无新路由配置,直接结束return;}// 3.更新路由routeDefinitions.forEach(routeDefinition -> {// 3.1.更新路由writer.save(Mono.just(routeDefinition)).subscribe();// 3.2.记录路由id,方便将来删除routeIds.add(routeDefinition.getId());});}
}
重启网关,任意访问一个接口,比如 http://localhost:8080/search/list?pageNo=1&pageSize=1:
发现是404,无法访问。因为网关的路由现在是没有的
接下来,我们直接在Nacos控制台添加路由,路由文件名为gateway-routes.json
,类型为json
:
配置内容如下:
[{"id": "item","predicates": [{"name": "Path","args": {"_genkey_0":"/items/**", "_genkey_1":"/search/**"}}],"filters": [],"uri": "lb://item-service"},{"id": "cart","predicates": [{"name": "Path","args": {"_genkey_0":"/carts/**"}}],"filters": [],"uri": "lb://cart-service"},{"id": "user","predicates": [{"name": "Path","args": {"_genkey_0":"/users/**", "_genkey_1":"/addresses/**"}}],"filters": [],"uri": "lb://user-service"},{"id": "trade","predicates": [{"name": "Path","args": {"_genkey_0":"/orders/**"}}],"filters": [],"uri": "lb://trade-service"},{"id": "pay","predicates": [{"name": "Path","args": {"_genkey_0":"/pay-orders/**"}}],"filters": [],"uri": "lb://pay-service"}
]
无需重启网关,稍等几秒钟后,再次访问刚才的地址:
网关路由成功了!
相关文章:
[Java]微服务配置管理
介绍 代码拆分为微服务后, 每个服务都有自己的配置文件, 而这些配置文件中有很多重复的配置, 并且配置变化后需要重启服务, 才能生效, 这样就会影响开发体验和效率 配置管理服务可以帮助我们集中管理公共的配置, 并且nacos就可以实现配置管理服务 配置共享 我们可以把微服务共…...
c/c++ 用easyx图形库写一个射击游戏
#include <graphics.h> #include <conio.h> #include <stdlib.h> #include <time.h>// 定义游戏窗口的大小 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600// 定义玩家和目标的尺寸 #define PLAYER_SIZE 50 #define TARGET_SIZE 20// 玩家的结构…...
Rust eyre 错误处理实战教程
在《Rust 错误处理库: thiserror 和 anyhow》中我们介绍了Rust简化处理错误策略,本文解释eyre错误处理库,并通过多个实际示例进行说明,最后于anyhow库进行对比,让你更好理解其应用场景。 eyre是一个用于 Rust 的错误处理库&#x…...
面试小札:JVM虚拟机
1. 定义与基本概念 - JVM(Java Virtual Machine)即Java虚拟机,是Java程序的运行核心。它是一个虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来运行Java字节码。字节码是一种中间格式,它使得Java程序能…...
Docker扩容操作(docker总是空间不足)
Docker扩容操作(docker总是空间不足) 1、df二连,一共也就70g,总是占满93%以上。所以需要移动到其他目录上 查看docker镜像和容器存储目录的空间大小 du -sh /var/lib/docker/2、停止docker服务 systemctl stop docker3、首先创建目录并迁移 # 首先创…...
数字图像处理(4):FPGA中的定点数、浮点数
(1)定点数:小数点固定在数据的某一位置的数,可以分为定点整数和定点小数和普通定点数。定点数广泛应用于数字图像处理(图像滤波、图像缩放)和数字信号处理(如FFT、定点卷积)中。 定…...
毕昇入门学习
schemas.py 概述 这段代码主要定义了一系列基于 Pydantic 的数据模型(BaseModel),用于数据验证和序列化,通常用于构建 API(如使用 FastAPI)。这些模型涵盖了用户认证、聊天消息、知识库管理、模型配置等多…...
2411C++,学习C++提示4
结构绑定 auto [first, ...ts] std::tuple{1, 2 ,3};assert(1 first);浮点作为非类型模板参数 template<double Value> constexpr auto value Value;int main() {std::cout << value<4.2>; // prints 4.2 }template<double... Vl1s, double... Vl2s&g…...
STM32-- 看门狗--介绍、使用场景、失效场景
STM32 中的看门狗(Watchdog Timer,简称 WDG)有两种主要类型:独立看门狗(IWDG) 和 窗口看门狗(WWDG)。它们的喂狗机制各有特点,主要区别如下: 1. 独立看门狗&a…...
【赵渝强老师】PostgreSQL的数据库
PostgreSQL的逻辑存储结构主要是指数据库中的各种数据库对象,包括:数据库集群、数据库、表、索引、视图等等。所有数据库对象都有各自的对象标识符oid(object identifiers),它是一个无符号的四字节整数,相关对象的oid都…...
linux安全管理-会话安全
文章目录 1 设置命令行界面超时退出2 配置终端登录失败策略3 配置 SSH 登录失败策略 1 设置命令行界面超时退出 1、检查内容 检查操作系统是否设置命令行界面超时退出。 2、配置要求 操作系统设置命令行界面超时退出。 3、配置方法 配置命令行界面超时时间,编辑/et…...
Ubuntu监视显卡占用情况
在终端中运行 watch -n 0.5 nvidia-smi【以下内容由大模型生成】 watch -n 0.5 nvidia-smi 是一个组合命令,用于在 Linux 终端中定期执行 nvidia-smi 命令并显示其输出。让我们分解一下这个命令的各个部分: watch: watch 是一个用于定期执行其他命令并显…...
学成在线day06
上传视屏 断点续传 通常视频文件都比较大,所以对于媒资系统上传文件的需求要满足大文件的上传要求。http协议本身对上传文件大小没有限制,但是客户的网络环境质量、电脑硬件环境等参差不齐,如果一个大文件快上传完了网断了没有上传完成&…...
Mac安装及合规无限使用Beyond Compare
文章目录 Beyond CompareBeyond Compare简介Beyond Compare安装Beyond Compare到期后继续免费使用 Beyond Compare Beyond Compare简介 Beyond Compare 是一款由 Scooter Software 开发的文件和文件夹比较工具。它主要用于对比两个文件或文件夹之间的差异,并支持文…...
【青牛科技】2K02 电动工具专用调速电路芯片描述
概述: 2K02 是电动工具专用调速电路。内置稳压电路,温度系数好,可以调节输出频率以及占空比的振荡输出,广泛的应用于小型电钻,割草机等工具。 主要特点: ● 电源电压范围宽 ● 占空比可调 ● 温度系数好 …...
基于SpringBoot实现的民宿管理系统(代码+论文)
🎉博主介绍:Java领域优质创作者,阿里云博客专家,计算机毕设实战导师。专注Java项目实战、毕设定制/协助 📢主要服务内容:选题定题、开题报告、任务书、程序开发、项目定制、论文辅导 💖精彩专栏…...
安装QT6.8(MSVC MinGW)+QT webengine+QT5.15.2
本篇主要针对只使用过QT5的qmake,没有用过MSVC,VS的老同学。 建议一部分一部分安装,全部勾选安装遇到问题会中断,前功尽弃。 我自己需要的是QT5,编出的软件用在公司设备上。 QT6:建议也安装学习…...
MinIO常见操作及Python实现对象的增删改查
MinIO常见操作 MinIO是一个高性能的开源对象存储服务,它兼容Amazon S3云存储服务API。在MinIO中,常见的操作包括: 存储桶操作: 创建、列出、获取信息、删除存储桶。 对象操作: 上传、下载、列出、删除对象。 权限管理&…...
网络编程中的字节序函数htonl()、htons()、ntohl()和ntohs()
目录 1,网络字节序和主机字节序 2. 函数的具体作用 2.1,htonl(Host to Network Long) 2.2,htons(Host to Network Short) 2.3,ntohl(Network to Host Long) 2.4,ntohs(Network to Host Sho…...
【dvwa靶场:File Upload系列】File Upload低-中-高级别,通关啦
目录 一、low级别,直接上传木马文件 1.1、准备一个木马文件 1.2、直接上传木马文件 1.3、访问木马链接 1.4、连接蚁剑 二、medium级别:抓包文件缀名 2.1、准备一个木马文件,修改后缀名为图片的后缀名 2.2、上传文件,打开burpSuite&…...
RHCE NFS
RHCE NFS 1.11. 2 NFS 主机名格式1.3 NFS 服务器配置1.3.1 /etc/exports 配置文件1.3.1.1 导出条目1.3.1.2 默认选项1.3.1.3 默认和覆盖选项 1.4 启动 NFS 服务器1.5 练习1.5.1 配置 NFS 服务器和客户端挂载1.5.2 配置autofs自动挂载(需要时才挂载) 1.6 …...
【数据结构】ArrayList与顺序表
ArrayList与顺序表 1.线性表2.顺序表2.1 接口的实现 3. ArrayList简介4. ArrayList使用4.2 ArrayList常见操作4.3 ArrayList的遍历4.4 ArrayList的扩容机制 5. ArrayList的具体使用5.1 杨辉三角5.2 简单的洗牌算法 6. ArrayList的问题及思考 【本节目标】 线性表顺序表ArrayLis…...
互联网基础
TCP/IP协议(协议组) 分层名称TCP/IP协议应用层HTTP,FTP,mDNS,WebSocket,OSC...传输层TCP,UDP网络层IP链路层(网络接口层)Ethernet,Wi-Fi... 链路层(网络接口层) 链路层的主要作用…...
ffmpeg.js视频播放(转换)
chrome 临时设置SharedArrayBuffer "C:\Program Files\Google\Chrome\Application\chrome.exe" --enable-featuresSharedArrayBuffer 引用的js及相关文件 ffmpeg.min.js ffmpeg.min.js.map ffmpeg-core.js ffmpeg-core.wasm ffmpeg-core.worker.js 以上几个现…...
后端 Java发送邮件 JavaMail 模版 20241128测试可用
配置授权码 依赖 <dependency><groupId>javax.mail</groupId><artifactId>javax.mail-api</artifactId><version>1.5.5</version> </dependency> <dependency><groupId>com.sun.mail</groupId><artifa…...
电脑中的vcruntime140_1.dll文件有问题要怎么解决?一键修复vcruntime140_1.dll
遇到“vcruntime140_1.dll无法继续执行代码”的错误通常表明电脑中的vcruntime140_1.dll文件有问题。这个文件属于Visual C Redistributable,对很多程序的运行至关重要。本文将提供几个步骤,帮助你迅速修复这一错误,使电脑恢复正常工作状态。…...
探索 Vue 3.0中Treeshaking特性?
Vue 3.0 中的 Tree Shaking 特性 Tree Shaking 是一种优化技术,旨在通过静态分析代码,去除未使用的模块或函数,从而减小最终的打包文件大小。在 Vue 3.0 中,由于其模块化设计和代码按需引入的特性,Vue 的 Tree Shaking 特性得到了增强,能够有效地去除那些在生产环境中未…...
Paddle Inference部署推理(十)
十:Paddle Inference推理 (python)API详解 9. 启用内存优化 API定义如下: # 开启内存 / 显存复用,具体降低内存效果取决于模型结构 # 参数:None # 返回:None paddle.inference.Config.enable…...
万能门店小程序管理系统 doPageGetFormList SQL注入漏洞复现
0x01 产品简介 万能门店小程序管理系统是一款功能强大的工具,旨在为各行业商家提供线上线下融合的全方位解决方案。是一个集成了会员管理和会员营销两大核心功能的综合性平台。它支持多行业使用,通过后台一键切换版本,满足不同行业商家的个性化需求。该系统采用轻量后台,搭…...
全面+彻底解决VMware安装后没有VMnet1和VMnet8的问题
目录 1、摘要 (1)问题 (2)所用工具 ① Everything软件 ② CCleaner软件 2、问题的检查与确认 3、解决过程 (1)卸载已经安装的VMware (2)设置services.mcs:服务自…...
青岛注册公司费用/seo网站优化推荐
xargs:通过缓冲方式并以前面命令行的输出作为参数,随后的命令调用该参数 若忽略 xargs 的 options 来看的话,cm1 | xargs cm2可以单纯看成: cm2 cm1因此, find .... | xargs rm 也可作 rm find ... 来处理.然而, 若 find 的结果太多, 可能会超过rm 可能接…...
wordpress 改 名字/app推广代理
WechatIMG122.jpeg环境 查看 windows 系统信息 D204EDD0-0843-4DB4-B885-17CF111A4A9D.png按照流程控制面板->系统和安全->系统查看 windows 系统信息,如上图所示。 查看 windows 版本号 2020-09-11_5f5ad11f3c54b.pngcmd下执行winver查看 windows 版本号。wi…...
高校网站推广方案/微博推广技巧
面向对象编程思维 1.职责 在一起 属性:方法计算所需要的属性 方法:拥有数据之后必须体现出的方法 面向对象过程中职责的分配 类与对象:抽象与具体 视角的变化: 行为视角:结构化方法数据视角:数据为中心方…...
广东网站建设公司排名/使用 ahrefs 进行 seo 分析
1 日程规划软件:Wunderlist 将项目进行安排的井井有条,是每个科研人员的基本素质。但是人的精力毕竟有限,这时就需要借助一些工具软件来打理日常生活事务。在此强烈推荐的是奇妙清单(Wunderlist)软件。Wunderlist是一款…...
html5营销网站建设/2023年7月疫情还会严重吗
文章目录1. 网址2. 加密参数3. 解密逻辑1. 网址 http://zhaopin.baidu.com/ 2. 加密参数 刷新页面,在ajax请求里有一个token参数 3. 解密逻辑 全局搜索token 在出现的js文件中依次查看 因为我已经测试过了,目标参数就在箭头所指的js文件中 点击进入…...
上海购物网站建设/哪个软件可以自动排名
1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id603672744434 2)全套实验源码手册视频下载地址:http://www.openedv.com/thread-300792-1-1.html 3)…...