当前位置: 首页 > news >正文

springcloud微服务架构搭建过程

项目地址:源代码

仅作为学习用例使用,是我开发过程中的总结、实际的一部分使用方式
开发环境:
jdk11
springboot2.7.6
springcloud2021.0.5
alibabacloud 2021.0.4.0
redis6.0
mysql8.0

一、项目搭建

1. 创建

wdz-api:存放远程服务调用相关接口
wdz-auth:认证业务
wdz-gateway:网关
wdz-modules:业务模块微服务
wdz-common:存放公用中间件、数据库等服务

pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><modules><module>wdz-common</module><module>wdz-gateway</module><module>wdz-api</module><module>wdz-auth</module><module>wdz-modules</module></modules><groupId>com.wdz</groupId><artifactId>wdz-ruzhou</artifactId><version>1.0.0</version><name>wdz-ruzhou</name><description>微服务架构</description><properties><java.version>11</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.7.6</spring-boot.version><spring-cloud.version>2021.0.5</spring-cloud.version><spring-cloud.alibaba>2021.0.4.0</spring-cloud.alibaba><fastjson2.version>2.0.14</fastjson2.version><lombok.version>1.18.24</lombok.version></properties><dependencyManagement><dependencies><!--springcloud 微服务依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!--springboot 依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!--alibaba 微服务依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud.alibaba}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>${fastjson2.version}</version></dependency></dependencies></dependencyManagement><!--配置打包环境数据--><profiles><profile><id>dev</id><properties><profiles.active>dev</profiles.active><nacos.username>nacos</nacos.username><nacos.password>nacos</nacos.password><nacos.server>127.0.0.1:8848</nacos.server><nacos.discovery.namespace>5efed786-91f6-44c4-8e14-049df72b2a48</nacos.discovery.namespace><nacos.config.namespace>5efed786-91f6-44c4-8e14-049df72b2a48</nacos.config.namespace></properties><activation><activeByDefault>true</activeByDefault></activation></profile><profile><id>test</id><properties><profiles.active>test</profiles.active><nacos.username>nacos</nacos.username><nacos.password>nacos</nacos.password><nacos.server>127.0.0.1:8848</nacos.server><nacos.discovery.namespace>f02ccd30-e3d5-4235-9282-d0a613bd322b</nacos.discovery.namespace><nacos.config.namespace>f02ccd30-e3d5-4235-9282-d0a613bd322b</nacos.config.namespace></properties></profile><profile><id>prod</id><properties><profiles.active>prod</profiles.active><nacos.username>nacos</nacos.username><nacos.password>nacos</nacos.password><nacos.server>127.0.0.1:8848</nacos.server><nacos.discovery.namespace>747829ca-6d8a-4417-a46a-bd31a6f5e442</nacos.discovery.namespace><nacos.config.namespace>747829ca-6d8a-4417-a46a-bd31a6f5e442</nacos.config.namespace></properties></profile></profiles><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>3.0.0</version></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>${java.version}</source><target>${java.version}</target><encoding>${project.build.sourceEncoding}</encoding></configuration></plugin></plugins><!--用于yml配置中变量替换如: @nacos.name@--><resources><resource><directory>src/main/resources</directory><!-- 引入所有 匹配文件进行过滤 --><includes><include>application*</include><include>bootstrap*</include><include>logback*</include></includes><!-- 启用过滤 即该资源中的变量将会被过滤器中的值替换 --><filtering>true</filtering></resource></resources></build>
</project>

nacos(2.2.0.1)

我为什么选择nacos作为注册中心?
1、独立的可视化管理后台
2、持久化,配置数据直接存储在数据库中
3、动态配置,修改配置可实时生效,不用重启
4、活跃度高,资料文件丰富
5、功能全面
6、是经过阿里巴巴考验的
戳==>官网

安装nacos

点击选择版本下载
windows建议下载zip
linux 建议下载tar.gz
下载完成解压即可

配置数据库

打开conf下的application.properties文件:
修改数据库配置,将注释打开,并配置数据源
在这里插入图片描述

创建数据库目前只支持mysql,版本要求:5.6.5+

需要IPV6支持使用:derby-schema.sql 否则使用:mysql-schema.sql 配置完成后

单机启动nacos:

Linux/Unix/Mac使用命令:sh startup.sh -m standalone
windows使用命令:./startup.cmd -m standalone
standalone:表示单机模式运行,非集群模式
官方文档
启动过程中如果出现jwt认证问题启动失败,请参考:戳详情

错误示例
在这里插入图片描述
修改文件:

nacos.core.auth.plugin.nacos.token.secret.key
使用base64 处理数据长度大于等于32即可

在这里插入图片描述
在这里插入图片描述

访问:http://localhost:8848/nacos,默认用户名密码:nacos

集群启动 官方文档

如果是在一台电脑上/服务器上模拟集群:
将nacos解压之后的文件nacos复制多份,
在这里插入图片描述

并修改对应conf文件夹下的application.properties文件端口配置
在这里插入图片描述
再将conf下的cluster.conf.example 复制一份并修改后缀为conf
在这里插入图片描述
将其他nacos地址配置在cluster.conf中
在这里插入图片描述
依次启动服务:
windows命令:./startup.cmd
linux命令: sh ./startup.sh
访问对应nacos
在这里插入图片描述
在这里插入图片描述

nacos 服务配置config与发现 discovery

创建测试注册服务网关服务,nacos作为注册中心有多种方式,本文用javaSDK的方式
在这里插入图片描述

pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>wdz-ruzhou</artifactId><groupId>com.wdz</groupId><version>1.0.0</version></parent><modelVersion>4.0.0</modelVersion><groupId>com.wdz</groupId><artifactId>wdz-gateway</artifactId><packaging>jar</packaging><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
yml配置:
server:port: 8080servlet:context-path: /spring:application:name: wdz-gatewayprofiles:active: @profiles.active@
---
# 使用导入的方式读取所有需要的nacos中的配置文件
spring:config:import:- optional:nacos:application-common.yml- optional:nacos:${spring.application.name}.ymlcloud:nacos:username: @nacos.username@password: @nacos.password@server-addr: @nacos.server@# 服务发现discovery:namespace: @nacos.discovery.namespace@# 配置config:namespace: @nacos.config.namespace@

集群nacos负载配置:

通过nginx配置服务访问的nacos

upstream nacos-cluster{server 127.0.0.1:8247;server 127.0.0.1:8549;server 127.0.0.1:8848;
}
server{listen 801;server_name localhost;location /nacos{proxy_pass http://nacos-cluster;}
}
结果

在这里插入图片描述

在这里插入图片描述

负载均衡Ribbon
内置负载均衡规则类规则描述
RoundRobinRule简单轮询服务列表选择服务器,它是Ribbon默认的负载均衡规则
AvailabilityFilteringRule忽略规则:1、链接3次失败,会标记为短路状态,将持续30秒,如果还是失败则持续短路,时间增长,2、并发数过高的服务链接,并发数达到上限则会被忽略
WeightedResponseTimeRule权重策略,每个服务器配置一个权重值,权重值越小,选择这个服务器的比重就会越小
ZoneAvooidanceRule以区域可用的服务器为基础进行服务器的选择,使用Zone对服务器进行分类,Zone相当于一个机房,一个区域,然后再对Zone内的多个服务做轮询
BestAvailableRule忽略哪些短路服务器,并选择并发数较低的服务器
RandomRule随机选择一个可用服务器
RetryRule重试机制的选择逻辑

自定义策略方式:

代码方式:作用的是所有服务
@Bean
public  IRule diyRule(){return new RandomRule();
}
yml方式:作用的是所配置的服务
servicename: # 服务名称如:userserviceribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule 

ribbon默认是懒加载,第一次访问的时候响应时间会比较长,初次加载之后响应就会变短。
开启ribbon饥饿加载有效提高第一次访问响应时间

ribbon:eager-load:enabled: true  # 开启饥饿加载clients: # 指定加载的服务名称- userservice- orderservice- systemservice- XXXservice
nacos服务分级存储模型

一级是服务:如:userservice、orderservice
二级是集群:配置了同一个discovery.cluster-name:
三级是实例:如杭州机房的某台部署了要访问的服务器
设置实例的集群属性:名称一样的在同一个集群内
spring.cloud.nacos.discovery.cluster-name:

NacosRule负载均衡策略:
1、优先选择同集群的服务
2、本地集群找不到提供者,才去其他集群找,并且会报警告
3、确定了可用实例列表后,再采用随机负载均衡挑选实例

NacosRule配置:

servicename: # 服务名称如:userserviceribbon:NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule 

环境隔离:namespace

spring:cloud:nacos:discovery:namespace: @nacos.discovery.namespace@ 
# 不同名称空间之间的服务不能互通,如user使用的prod order使用的dev,这两个服务不能互通

nacos特点

1、支持服务端主动监测提供者状态,临时实例采用心跳模式,非临时实例采用主动监测模式
2、林实施例心跳不正常会被剔除nacos的服务列表,非临时实例不会被剔除
3、服务列表变更消息推送模式,服务列表更新及时
4、nacos集群默认采用AP方式,集群中存在非临时实例时,采用CP模式
CAP:C(一致性),A(可用性),P(分区容错)原文
在这里插入图片描述

Feign 源码

feign是声明式的http客户端

使用方式

pom引入依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
java代码
@FeignClient("applicationName")
public interface ApplicationName{@GetMapping("/get")Object queryById(Long id);
}

自定义feign配置

类型作用说明
feign.Logger.Level修改日志级别包含四种不同的级别:none、basic、headers、full
feign.codec.Decoder响应结果解析器http远程调用的结果做解析,例如解析json字符串为java对象
feign.codec.Encoder请求参数编码将请求参数编码,便于通过http请求发送
feign.Contract支持注解格式默认是SpringMvc的注解
feign.Retryer失败重试机制请求失败的重试机制,默认没有,会使用Ribbon的重试

none: 不记录日志
basic:只记录请求方法和URL以及响应状态代码和执行时间
headers:记录基本信息以及请求和响应标头
full:记录请求和响应的头部、主体和元数据

yml日志配置

feign:client:config:default: # DETAULT 是全局配置,如果换成application.name 则是指定服务有效loggerLevel: FULL
feign:client:config:userservice: # 针对userservice有效loggerLevel: FULL

代码方式:

public class FeignClientConfig{@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.BASIC;}
}
然后将该配置添加到:
全局配置方式启动类上
EnableFeignClients(defaultConfiguration=FeignClentConfig.class)
局部配置方式
@FeignClient(value="applicationname",configuration=FeignClientConfig)

feign性能优化

URLConnection:默认实现,不支持连接池
Apache HttpClient:支持链接池
OKHttp:支持连接池
因为http链接时要三次握手,断开时要4次挥手,导致的性能浪费
优化的性能主要包括:
1、使用连接池代替默认的URLConnection
2、日志级别,最好用basic或none,日志也会浪费性能

连接池配置:

引入依赖

<!--优化feignURLConnection-->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId>
</dependency>

配置yml

feign:httpclient:enabled: true # 开启feign对httpClient的支持max-connections: 200 # 最大链接数  可根据测试结果最优配置max-connections-per-route: 50 # 每个路径最大链接数 可根据测试结果最优配置

实践:
在这里插入图片描述
system项目引用
EnableFeignClients.clients 指定feignClient接口,及默认配置
在这里插入图片描述

如果发现RemoteUserService 加载不到提示,spring-cloud-starter-loadbalancer依赖缺失
在api中添加依赖:负载均衡依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

测试接口
在这里插入图片描述
目标服务接口
在这里插入图片描述

测试结果:
在这里插入图片描述

SpringAMQP

springboot封装的消息队列,使用的是rabbitmq

生产端

引入依赖

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

配置

spring:rabbitmq:host: 127.0.0.1 # 主机port: 5672   # 端口virtual-host: /  # 虚拟主机username: rabbitmq # 用户名password: 123456  # 密码

消费端

引入依赖

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

配置

spring:rabbitmq:host: 127.0.0.1 # 主机port: 5672   # 端口virtual-host: /  # 虚拟主机username: rabbitmq # 用户名password: 123456  # 密码

监听java代码:

@Component
public class RabbitMqListener {@RabbitListener(queues = "mq-user")public void listenerQueueMsg(String msg){System.out.println(msg);}
}

如果提示异常:队列不存在,且启动失败

添加配置:

@Configuration
public class RabbitMqConfig {@Beanpublic Queue initQueue(){return new Queue("mq-user");}
}

由于rabbitmq的消费预取机制,会导致处理能力弱的消费端处理速度变慢,所以限制预取信息条数

spring:rabbitmq:listener:simple:prefetch: 1 # 每次只能获取一条消息,处理完成之后才能获取下一个

监听端信息:

@Slf4j
@Component
public class RabbitMqListener {@RabbitListener(queues = "mq-user")public void listenerQueueMsg(String msg) {log.info("[listenerQueueMsg]=========:{}",msg);}@RabbitListener(queues = "mq-user")public void listenerQueueMsg2(String msg) {log.info("[listenerQueueMsg2]=========:{}",msg);}
}

消息发布/订阅

发布订阅模式允许将同一消息发送给多个消费者,实现方式是加入exchange(交换机):
fanout:广播
direct:路由
topic:话题
交换机只处理转发,会造成消息丢失

FanoutExchange 方式

发送消息用户服务:

@GetMapping("/send")public LoginUser send(String username) {String queueName = "demo.fanout";String message = username;rabbitTemplate.convertAndSend(queueName,"", message);return new LoginUser(1L, username, "123456");}@GetMapping("/to")public LoginUser to(String username) {String queueName = "demo.fanout";String message = username;rabbitTemplate.convertAndSend(queueName,"", message);return new LoginUser(1L, username, "123456");}

接收消息 system服务:

监听代码@RabbitListener(queues = "demo.fanout2")public void listenerFanoutMsg2(String msg) {log.info("[demo.fanout2]=========:{}", msg);}
@Configuration
public class FanoutExchangeConfig {/*** 一个消息多个消费者监* fanout 广播模式* 定义交换机*/@Beanpublic FanoutExchange fanoutExchange() {return new FanoutExchange("demo.fanout");}@Beanpublic Queue fanoutQueue() {return new Queue("demo.fanout");}/*** 绑定交换机与队列关系** @param fanoutExchange* @param fanoutQueue* @return*/@Beanpublic Binding fanoutBinding(FanoutExchange fanoutExchange,Queue fanoutQueue) {return BindingBuilder.bind(fanoutQueue).to(fanoutExchange);}
}

接收消息 order服务:

监听
@Slf4j
@Component
public class RabbitMqListener {@RabbitListener(queues = "demo.fanout")public void listenerFanoutMsg(String msg) {log.info("[demo.fanout]=========:{}", msg);}
}

fanout 配置

@Configuration
public class FanoutExchangeConfig {/*** 一个消息多个消费者监* fanout 广播模式* 定义交换机*/@Beanpublic FanoutExchange fanoutExchange() {return new FanoutExchange("demo.fanout");}@Beanpublic Queue fanoutQueue() {return new Queue("demo.fanout2");}/*** 绑定交换机与队列关系** @param fanoutExchange* @param fanoutQueue* @return*/@Beanpublic Binding fanoutBinding(FanoutExchange fanoutExchange,Queue fanoutQueue) {return BindingBuilder.bind(fanoutQueue).to(fanoutExchange);}
}

均可接收到消息

DirectExchange 方式

direct exchange 会将接收到的消息根据规则路由到指定的queue
每个queue都与exchange设置一个bindingkey
发布者发送消息时指定消息的RoutingKey
exchange将消息路由到BingingKey与消息RoutingKey一致的队列

order/system中的监听

// 注解方式处理监听信息
// bindings 代码实现的Binding
// @QueueBinding 绑定信息
// value = @Queue(name = "direct.queue")绑定消息队列
//  exchange = @Exchange(name = "demo.direct",type = ExchangeTypes.DIRECT)
// 绑定交换机,名称是demo.direct 类型是direct
// key 是direct模式的主要配置,可同时监听多个key
@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue"),exchange = @Exchange(name = "demo.direct",type = ExchangeTypes.DIRECT),key = {"system","direct"}))public void listenerMessage(String msg) {log.info("[system.direct]=========:{}", msg);}

消息发送者:

/***@param exchange  交换机名称*@param message     消息内容*@param routingKey  direct 路由key*@return*/@GetMapping("/direct")public void direct(String exchange,String message,String routingKey) {rabbitTemplate.convertAndSend(exchange,routingKey, message);}

发送信息:
http://localhost/user/direct?exchange=demo.direct&message=发送的消息内容&routingKey=system

Topic 方式

topic方式与direct方式类似,只是key由精准匹配转换为模糊匹配

 // 监听@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue"),exchange = @Exchange(name = "topic-wdz",type = ExchangeTypes.TOPIC),key = "#.order"))public void listenerTopicMessage(String msg) {log.info("[listenerTopicMessage]=========:{}", msg);}

发送

@GetMapping("/direct")
public void direct(String exchange,String message,String routingKey) {rabbitTemplate.convertAndSend(exchange,routingKey, message);
}

优化

由于springamqp默认使用的是jdk默认的序列化(ObjectOutputStream)方式,性能问题有待提升。
更换为JSON方式序列化。

生产者/消费者引入依赖
  <dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformats-binary</artifactId><version>2.13.4</version></dependency>

初始化bean即可

@Bean
publicMessageConverter messageConverter(){return new Jackson2JsonMessageConverter();
}

Sentinel

分布式事务seata

事务(transaction):遵守ACID原则

原子性(Atomicity):事务中的所有操作,要么全部成功,要么全部失败
一致性(consistency):要保证数据库内部完整性的约束、声明性约束
隔离性(isolation):对同一自愿操作的事务不能同时发生
持久性(durability):对数据库的一切修改将永久保存,不管是否出现故障

演示案例:

下单流程:
订单服务创建订单–>账户服务扣减余额–>商品服务扣减库存
1、访问订单服务创建订单
2、通过feign调用user扣减余额
3、通过feign调用goods扣减库存

在这里插入图片描述

feign接口

@FeignClient(value = "wdz-goods")
public interface RemoteGoodsService {@GetMapping("/goods/subtractStock")void subtractStock(@PathVariable("username") String username);}
@FeignClient(value = "wdz-user")
public interface RemoteUserService {@GetMapping("/user/subtractBalance")void subtractBalance();
}

控制器代码

订单服务控制器

@RestController
@RequestMapping("order")
public class OrderController {@Autowiredprivate RemoteGoodsService remoteGoodsService;@Autowiredprivate RemoteUserService remoteUserService;@GetMapping("create")public void create(){System.out.println("订单服务:创建了订单");remoteGoodsService.subtractStock();remoteUserService.subtractBalance();}
}

用户服务控制器代码

@RestController
@RequestMapping("user")
public class UserController {@GetMapping("subtractBalance")public void subtractBalance(){System.out.println("用戶服务:减余额");}
}

商品控制器代码

@RestController
@RequestMapping("goods")
public class GoodsController {@GetMapping("subtractStock")public void subtractStock(){System.out.println("商品服务:减少了库存");}
}
依次启动nacos-->gateway-->user-->goods-->order
访问:http://localhost:8080/order/order/create
订单服务:创建了订单
用戶服务:减余额
商品服务:减少了库存

相关文章:

springcloud微服务架构搭建过程

项目地址&#xff1a;源代码 仅作为学习用例使用&#xff0c;是我开发过程中的总结、实际的一部分使用方式 开发环境&#xff1a; jdk11 springboot2.7.6 springcloud2021.0.5 alibabacloud 2021.0.4.0 redis6.0 mysql8.0 一、项目搭建 wdz-api&#xff1a;存放远程服务调用相关…...

LeetCode:215. 数组中的第K个最大元素

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340;算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 一、&#x1f331;215. 数组中的第K个最大元素 题目描述&#xff1a;给定整数数组nums和整…...

vue面试题(day06)

文章目录前言请谈谈WXML与标准的html的异同&#xff1f;请谈谈WXSS和CSS的异同&#xff1f;请谈谈微信小程序主要目录和文件的作用&#xff1f;请谈谈小程序的双向绑定和vue的异同&#xff1f;简单描述下微信小程序的相关文件类型&#xff1f;微信小程序有哪些传值(传递数据)方…...

22 k8s常用命令

一、k8s网络 service网络 pod网络 节点网络 》 svc、pod网络都是虚拟机网络&#xff0c;真实网络是节点网络 二、内核升级 因为coentos系统3.10存在一些bug&#xff0c;docker、kubernetes不稳定&#xff0c;建议升级到4.4版本以上 三、集群资源分类 名称空间级别&#xff1…...

基于ESP32做低功耗墨水屏时钟

基于ESP32做低功耗墨水屏时钟电子墨水屏概述ESP32实验低功耗电子时钟功能描述接线开发实验结果电子墨水屏 概述 电子墨水是一种革新信息显示的新方法和技术。和传统纸差异是电子墨水在通电时改变颜色&#xff0c;并且可以显示变化的图象&#xff0c;像计算器或手机那样的显示。…...

常见路由器开源系统(固件)简介

前段时间在折腾如何通过 SD-WAN 组网方式打通办公室和家里的异地局域网。需要用到路由器的静态路由表功能&#xff0c;但是遍历整个家用路由器市场几乎没有支持这个功能的路由器&#xff08;只有华硕 RT-AX57 有这个功能&#xff0c;但是成本超出了我的预算&#xff09;。所有就…...

HCIE-Cloud Computing LAB备考第二步:逐题攻破--第二题:FusionAccess-搭建FA实验环境之安装基础组件和初始化ITA组件

HCIE-Cloud Computing LAB备考第二步:逐题攻破–第二题:FusionAccess-思维导图+题目=建立逻辑 专业术语 名词描述备注FusionAccess华为推出的桌面云产品,是一种虚拟桌面应用,它主要通过在硬件上部署FusionAccess配套的软件基础上,虚拟化出相互隔离的桌面,用户通过瘦客户端…...

Android APP检查设备是否为平板

正文 Android APP判断设备是否为平板的三种方法&#xff1a; 通过屏幕尺寸判断。一般来说&#xff0c;平板电脑的屏幕尺寸比手机大很多&#xff0c;可以根据屏幕的长宽比和尺寸等信息来区分设备类型。通过屏幕像素密度判断。一般来说&#xff0c;平板电脑的屏幕像素密度比手机…...

MP:使用步骤、分页、queryWrapper

Mybatis-Plus 官网&#xff1a; MyBatis-Plus (baomidou.com) 1. 意义 mybatis-plus是一个插件&#xff0c;它不能单独使用&#xff0c;必须配合mybatis使用&#xff0c;作用是简化mybatis操作&#xff0c;通过使用MP提供的方法&#xff0c;自动生成SQL语句进行CRUD 2. 使用步骤…...

C++ string类

C string类讲解 1、为什么学习string类&#xff1f; C语言中的字符串 在C语言中&#xff0c;字符串是以’\0’结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符…...

虚拟机断电centos无法启动

虚拟机断电后centos7无法正常启动 XFS(sda3) 首先需要查找日志 在界面中查找日志是 journalctl 1.由于我的电脑死机&#xff0c;虚拟机没有正常关闭导致重启后 node1节点&#xff1a;可以登陆但是出现XFS(sda3)&#xff1a;Corruption of in-memoru data detectednode2节点&…...

python学习之基于Python的人脸识别技术学习

摘要&#xff1a; 面部识别技术的应用越来越广泛&#xff0c;它广泛应用于安全系统、人机交互、社交媒体、医疗保健等领域。本文介绍了基于Python的人脸识别技术&#xff0c;包括人脸检测、人脸特征提取和人脸识别三个部分。我们使用OpenCV和Dlib库来实现这些功能&#xff0c;…...

[Qt][Android] Qt for Android 环境搭建

建议使用 Linux 环境开发 Qt for Android&#xff0c;Windows 环境不好弄&#xff0c;问题多。 直接按照官方文档给的流程进行一步步做就行了&#xff1a; Getting Started with Qt for Android | Qt 6.4https://doc.qt.io/qt-6/android-getting-started.html建议使用 ubuntu…...

maven setting 配置

<?xml version"1.0" encoding"UTF-8"?><settings xmlns"http://maven.apache.org/SETTINGS/1.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/SETTINGS/1.0.0…...

【0基础学爬虫】爬虫基础之网络请求库的使用

大数据时代&#xff0c;各行各业对数据采集的需求日益增多&#xff0c;网络爬虫的运用也更为广泛&#xff0c;越来越多的人开始学习网络爬虫这项技术&#xff0c;K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章&#xff0c;为实现从易到难全方位覆盖&#xff0c;特设【0基础学…...

超级实用,解密云原生监控技术,使用prometheus轻松搞定redis监控

前言 大家好&#xff0c;我是沐风晓月&#xff0c;本文收录于《 prometheus监控系列》 &#xff0c;截止目前prometheus专栏已经更新到第8篇文章。 本文中的是prometheus已经安装好&#xff0c;如果你还未安装&#xff0c;可以参考 prometheus安装及使用入门 若你想监控其他…...

音视频开发—MediaCodec 解码H264/H265码流视频

使用MediaCodec目的 MediaCodec是Android底层多媒体框架的一部分&#xff0c;通常与MediaExtractor、MediaMuxer、AudioTrack结合使用&#xff0c;可以编码H264、H265、AAC、3gp等常见的音视频格式 MediaCodec工作原理是处理输入数据以产生输出数据 MediaCodec工作流程 Med…...

CVPR 2023|淘宝视频质量评价算法被顶会收录

近日&#xff0c;阿里巴巴大淘宝技术题为《MD-VQA: Multi-Dimensional Quality Assessment for UGC Live Videos》—— 适用于无参考视频质量评价的最新研究成果被计算机视觉领域顶级会议IEEE/CVF Computer Vision and Pattern Recognition Conference 2023&#xff08;CVPR 20…...

【C++学习】继承

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《C学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; C是面向对象的编程语言&#xff0c;它有很多的特性&#xff0c;但是最重要的就是封装&#xff0c;继承…...

【03173】2020年8月高等教育自学考试-软件开发工具

一、单项选择题&#xff1a;1. 区别于一般软件&#xff0c;对软件开发工具而言&#xff0c;下列各项最重要的性能是 A. 效率 B. 响应速度C. 资源消耗 D. 使用方便2. 在软件开发过程的信息需求中&#xff0c;属于跨开发周期的信息是A. 有关系统环境的需求信息 B. 有关软件设计的…...

Java中的String类

String类1.String类1.1 特性1.2 面试题1.3 常用方法1.4 String与其他类型之间的转换2. StringBuilder类、StringBuffer类&#xff1a;可变字符序列1.String类 1.1 特性 String类为final类&#xff0c;不可被继承&#xff0c;代表不可变的字符序列&#xff1b; 实现了Serializ…...

【java】笔试强训Day3【在字符串中找出连续最长的数字串与数组中出现次数超过一半的数字】

目录 ⛳选择题 1.以下代码运行输出的是 2.以下程序的输出结果为 3.下面关于构造方法的说法不正确的是 ( ) 4.在异常处理中&#xff0c;以下描述不正确的有&#xff08; &#xff09; 5.下列描述中&#xff0c;错误的是&#xff08; &#xff09; 6.…...

一文7个步骤从0到1教你搭建Selenium 自动化测试环境

【导语】Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。本文详细介绍了搭建自动化测试环境所需的工具&#xff0c;让你学习自动化测试不…...

Oracle目录应急清理

Oracle目录应急清理清理错误位置的归档日志清理30天前的监听告警日志清理监听日志清理30天以前的trace文件清理30天以前的审计日志清理错误位置的归档日志 检查$ORACLE_HOME/dbs下是否有归档文件&#xff1a; ls $ORACLE_HOME/dbs/arch* | wc -l检查和修改归档位置&#xff1…...

使用 OBS 进行区域录制

1. OBS 与区域录屏 实际上 OBS 的使用场景可谓是与区域录屏格格不入的。 虽然我们依旧有一些办法在 OBS 中达到区域录屏的目的&#xff0c;但其操作实在过于繁琐&#xff0c;还不如直接使用 QQ 或者 Windows 最新的自带截屏录屏来进行区域录屏来的方便实在。 但若非常强烈的…...

aws eks 配置授权额外的用户和角色访问集群

参考资料 https://github.com/kubernetes-sigs/aws-iam-authenticator#full-configuration-formathttps://docs.amazonaws.cn/zh_cn/eks/latest/userguide/add-user-role.html 众所周知&#xff0c;aws eks使用 Authenticator 或者 aws 命令来进行账户级别的用户和角色的授权…...

MagicalCoder可视化开发平台:轻松搭建业务系统,为企业创造更多价值

让软件应用开发变得轻松起来&#xff0c;一起探索MagicalCoder可视化开发工具的魔力&#xff01;你是否为编程世界的各种挑战感到头痛&#xff1f;想要以更高效、简单的方式开发出专业级的项目&#xff1f;MagicalCoder低代码工具正是你苦心寻找的产品&#xff01;它是一款专为…...

8个不能错过的程序员必备网站,惊艳到我了!!!

程序员是一个需要不断学习的职业&#xff0c;不少朋友每天来逛CSDN、掘金等网站&#xff0c;但一直都抱着“收藏从未停止&#xff0c;学习从未开始”的态度&#xff0c;别骗自己了兄弟。在编程体系中&#xff0c;有很多不错的小工具&#xff0c;可以极大得提升我们的开发效率。…...

Mybatis(二):实现“增删改查”

Mybatis&#xff08;二&#xff09;&#xff1a;实现“增删改查”前言一、MyBatis的增删改查1、添加2、修改3、删除4、查询4.1 查询一个实体4.1 查询集合二、MyBatis获取参数值的两种方式&#xff08;重点&#xff09;1、单个字面量类型的参数2、多个字面量类型的参数3、map集合…...

Faster RCNN 对血液细胞目标检测

目录 1. 介绍 2. 工具函数介绍 utils 2.1 xml 文件的读取 get_label_from_xml 2.2 绘制边界框 draw_bounding_box...