SpringCloud微服务详细笔记(一):微服务介绍--微服务拆分--RestTemplate远程调用--Nacos注册中心

news2024/12/28 21:30:06

目录

1.认识微服务

1.1单体架构

1.2微服务

1.3SpringCloud

2.微服务拆分

2.1服务拆分原则

2.1.1什么时候拆?

2.1.2怎么拆?

2.2微服务项目结构:

2.3服务拆分示例:

2.4远程调用

2.4.1RestTemplate

2.4.2远程调用示例

2.5总结

3.服务治理

3.1注册中心原理

3.2Nacos注册中心

3.3服务注册

3.3.1.添加依赖

3.3.2.配置Nacos

3.3.3.启动服务实例

3.4服务发现

3.4.1引入依赖

3.4.2.配置Nacos地址

3.4.3.发现并调用服务


1.认识微服务

1.1单体架构

将业务的所有功能集中在一个项目中开发,打成一个包部署。

当项目规模较小时,这种模式上手快,部署、运维也都很方便,因此早期很多小型项目都采用这种模式。


单体架构的优缺点:
优点:
架构简单
部署成本低

缺点:
团队协作成本高:你们团队数十个人同时协作开发同一个项目,由于所有模块都在一个项目中,不同模块的代码之间物理边界越来越模糊。最终要把功能合并到一个分支,你绝对会陷入到解决冲突的泥潭之中。
系统发布效率低:任何模块变更都需要发布整个系统,而系统发布过程中需要多个模块之间制约较多,需要对比各种文件,任何一处出现问题都会导致发布失败,往往一次发布需要数十分钟甚至数小时。
系统可用性差:单体架构各个功能模块是作为一个服务部署,相互之间会互相影响,一些热点功能会耗尽系统资源,导致其它服务低可用。

1.2微服务

微服务架构:首先是服务化,就是将单体架构中的功能模块从单体应用中拆分出来,独立部署为多个服务。同时要满足下面的一些特点:
-单一职责:一个微服务负责一部分业务功能,并且其核心数据不依赖于其它模块。
-团队自治:每个微服务都有自己独立的开发、测试、发布、运维人员,团队人员规模不超过10人
-服务自治:每个微服务都独立打包部署,访问自己独立的数据库。并且要做好服务隔离,避免对其它服务产生影响

于是,单体架构存在的问题就得到了解决。
- 团队协作成本高:
  - 由于服务拆分,每个服务代码量大大减少,参与开发的后台人员在1~3名,协作成本大大降低
- 系统发布效率低:
  - 每个服务都是独立部署,当有某个服务有代码变更时,只需要打包部署该服务即可
- 系统可用性差:
  - 每个服务独立部署,并且做好服务隔离,使用自己的服务器资源,不会影响到其它服务。

微服务架构解决了单体架构存在的问题,特别适合大型互联网项目的开发,因此被各大互联网公司普遍采用。大家以前可能听说过分布式架构,分布式就是服务拆分的过程,其实微服务架构正式分布式架构的一种最佳实践的方案。

1.3SpringCloud

SpringCloud是目前国内使用最广泛的微服务框架,其官网地址:https://spring.io/projects/spring-cloud。

SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验。

其中常见的组件包括:

另外,SpringCloud底层是依赖于SpringBoot的,并且有版本的兼容关系,如下:

2.微服务拆分

2.1服务拆分原则

服务拆分要考虑的两个问题:什么时候拆?怎么拆?

2.1.1什么时候拆?

创业型项目:一般是先采用单体架构,随着用户规模扩大、业务复杂后再逐渐拆分为微服务架构。这样初期成本会比较低,可以快速试错。但是,这么做的问题就在于后期做服务拆分时,可能会遇到很多代码耦合带来的问题,拆分比较困难(前易后难)。
确定的大型项目:资金充足,目标明确,可以直接选择微服务架构,避免后续拆分的麻烦。(前难后易)

2.1.2怎么拆?

拆分项目要做到:
- 高内聚:
每个微服务的职责要尽量单一,包含的业务相互关联度高、完整度高。
- 低耦合:每个微服务的功能要相对独立,尽量减少对其它微服务的依赖,或者依赖接口的稳定性要强。

高内聚首先是单一职责,但不能说一个微服务就一个接口,而是要保证微服务内部业务的完整性为前提。目标是当我们要修改某个业务时,最好就只修改当前微服务,这样变更的成本更低。

一旦微服务做到了高内聚,那么服务之间的耦合度自然就降低了。

当然,微服务之间不可避免的会有或多或少的业务交互,比如下单时需要查询商品数据。这个时候我们不能在订单服务直接查询商品数据库,否则就导致了数据耦合。而应该由商品服务对应暴露接口,并且一定要保证微服务对外接口的稳定性(即:尽量保证接口外观不变)。虽然出现了服务间调用,但此时无论你如何在商品服务做内部修改,都不会影响到订单微服务,服务间的耦合度就降低了。

  • 不同微服务,不要重复开发相同业务
  • 微服务数据独立,不要访问其它微服务的数据库
  • 微服务可以将自己的业务暴露为接口,供其它微服务调用

拆分方式一般有两种:
纵向拆分:按照业务模块来拆分。例如一个项目中,可能有用户管理功能、订单管理功能、购物车功能、商品管理功能、支付功能等。那么按照功能模块将他们拆分为一个个服务,就属于纵向拆分。这种拆分模式可以尽可能提高服务的内聚性。
横向拆分:抽取公共服务,提高复用性。例如用户登录是需要发送消息通知,记录风控数据,下单时也要发送短信,记录风控数据。因此消息发送、风控数据记录就是通用的业务功能,因此可以将他们分别抽取为公共服务:消息中心服务、风控管理服务。这样可以提高业务的复用性,避免重复开发。同时通用业务一般接口稳定性较强,也不会使服务之间过分耦合。

2.2微服务项目结构:

一般微服务项目有两种不同的工程结构
- 独立Project:每一个微服务都创建为一个独立的工程,甚至可以使用不同的开发语言来开发,项目完全解耦。
  - 优点:服务之间耦合度低
  - 缺点:每个项目都有自己的独立仓库,管理起来比较麻烦

- Maven聚合:整个项目为一个Project,然后每个微服务是其中的一个Module
  - 优点:项目代码集中,管理和运维方便(授课也方便)
  - 缺点:服务之间耦合,编译时间较长

2.3服务拆分示例:

下面这个是一个示例项目,项目结构如下。

我们的要求是拆分商品服务功能。
1、在hamll中新建Module功能

2、填写信息---模块名称---选择Maven项目---选择JDK版本---点击Create完成创建

3、引入依赖:可以直接复制hm-service的依赖,然后删除一些不需要的依赖就可以了。

<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.heima</groupId>
        <artifactId>hmall</artifactId>
        <version>1.0.0</version>
    </parent>

    <artifactId>item-services</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!--common-->
        <dependency>
            <groupId>com.heima</groupId>
            <artifactId>hm-common</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <!--数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>

        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

4、编写包和启动类---新建com.hmall.item包---在包下新建启动类(可以直接复制hm-service的启动类,然后改启动类的名称就好了)

package com.hmall.item;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@MapperScan("com.hmall.item.mapper")
@SpringBootApplication
public class ItemApplication {
    public static void main(String[] args) {
        SpringApplication.run(ItemApplication.class, args);
    }
}

5、 创建以后会用到的各种包--controller--domain--mapper--service等

6、配置文件:可以直接从hm-service中拷贝。

7、然后更改application.yaml的信息,其他两个不用改。

server:
  port: 8081  #端口需要改,不然会和hm-service的冲突
spring:
  application:
    name: item-services    #微服务名称也需要改
  profiles:
    active: local
    #数据库连接需要改:微服务的数据库需要独立,不能访问其他微服务的数据库,所以我们需要在docker中重新创建一个独立的mysql,但这里我们就只是为了模拟,
    #所以就在当前数据库新建一个database。把hamll数据库换了就行,这里换成了hm-item。
  datasource:
    url: jdbc:mysql://${hm.db.host}:3307/hm-item?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: ${hm.db.pw}
mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
  global-config:
    db-config:
      update-strategy: not_null
      id-type: auto
logging:
  level:
    com.hmall: debug
  pattern:
    dateformat: HH:mm:ss:SSS
  file:
    path: "logs/${spring.application.name}"
knife4j:
  enable: true
  openapi:
    title: 黑马商城商品管理接口文档     #修改文档名称为模块对应的功能。
    description: "黑马商城商品管理接口文档"
    email: zhanghuyi@itcast.cn
    concat: 虎哥
    url: https://www.itcast.cn
    version: v1.0.0
    group:
      default:
        group-name: default
        api-rule: package
        api-rule-resources:
          - com.hmall.item.controller #改为item-services下的包

 8、从hm-service拷贝与商品管理有关的代码到item-service
导入顺序:domain---mapper---service---controller。因为是依赖关系。
 因为引入的import需要更改,可以设置自动导入import,避免一直需要按Alt+Enter
File->Settings->Editor->General->Auto Import->勾选右边两个有关import的选项


9、这里有一个地方的代码需要改动,就是ItemServiceImpl中的deductStock方法:

这也是因为ItemMapper的所在包发生了变化,因此这里代码必须修改包路径。

最后,还要导入数据库表。默认的数据库连接的是虚拟机,在你docker数据库执行课前资料提供的SQL文件:

最终,会在数据库创建一个名为hm-item的database,将来的每一个微服务都会有自己的一个database:

11、配置完所有东西后,启动item-services,然后访问商品微服务的swagger接口文档:
http://localhost:8081/doc.html

然后测试其中的根据id批量查询商品这个接口:

测试参数:100002672302,100002624500,100002533430,结果如下:

说明商品微服务抽取成功了。

2.4远程调用

在业务拆分的过程中,有时候我们会遇到比如这样的问题:购物车业务需要查询商品信息,但是商品信息查询的功能已经拆分开了,两者的数据库又不是同一个,导致我们无法查询商品信息。

虽然代码不是连通的,但是网络是连通的。

要想解决这样的问题,我们要使用跨微服务的远程调用的方法。

我们前端向服务端查询数据,其实就是从浏览器远程查询服务端数据。比如通过Swagger测试商品查询接口,就是向http://localhost:8081/items这个接口发起的请求:
而这种查询就是通过http请求的方式来完成的,不仅仅可以实现远程查询,还可以实现新增、删除等各种远程请求。

于是我们也可以通过Java代码发送http请求来实现远程调用

2.4.1RestTemplate

Spring给我们提供了一个RestTemplate工具,可以方便的实现Http请求的发送。使用步骤如下;
(1)注入RestTemplate到Spring容器

(2)发起远程调用

RestTemplate给我们提供了很多的方法,方便发送Http请求

2.4.2远程调用示例

先将RestTemplate注册为一个Bean:

注入RestTemplate

修改相应代码,发送http请求到另一个模块

然后开始接口调试----记住两个业务功能都要启动,item-services和cart-service都要启动。

查询成功

2.5总结

什么时候需要拆分微服务?
- 如果是创业型公司,最好先用单体架构快速迭代开发,验证市场运作模型,快速试错。当业务跑通以后,随着业务规模扩大、人员规模增加,再考虑拆分微服务。
- 如果是大型企业,有充足的资源,可以在项目开始之初就搭建微服务架构。

如何拆分?
- 首先要做到高内聚、低耦合
- 从拆分方式来说,有横向拆分和纵向拆分两种。纵向就是按照业务功能模块,横向则是拆分通用性业务,提高复用性

服务拆分之后,不可避免的会出现跨微服务的业务,此时微服务之间就需要进行远程调用。微服务之间的远程调用被称为RPC,即远程过程调用。RPC的实现方式有很多,比如:
- 基于Http协议
- 基于Dubbo协议
我们课堂中使用的是Http方式,这种方式不关心服务提供者的具体技术实现,只要对外暴露Http接口即可,更符合微服务的需要。

Java发送http请求可以使用Spring提供的RestTemplate,使用的基本步骤如下:
- 注册RestTemplate到Spring容器
- 调用RestTemplate的API发送请求,常见方法有:
  - getForObject:发送Get请求并返回指定类型对象
  - PostForObject:发送Post请求并返回指定类型对象
  - put:发送PUT请求
  - delete:发送Delete请求
  - exchange:发送任意类型请求,返回ResponseEntity

3.服务治理

前面我们实现了微服务拆分,并且通过Http请求实现了跨微服务的远程调用。不过这种手动发送Http请求的方式存在一些问题。

试想一下,假如商品微服务被调用较多,为了应对更高的并发,我们进行了多实例部署,如图:

此时,每个item-service的实例其IP或端口不同,问题来了:
item-service这么多实例,cart-service如何知道每一个实例的地址?
http请求要写url地址,cart-service服务到底该调用哪个实例呢?
如果在运行过程中,某一个item-service实例宕机,cart-service依然在调用该怎么办?
如果并发太高,item-service临时多部署了N台实例,cart-service如何知道新实例的地址?

为了解决上述问题,就必须引入注册中心的概念了,接下来我们就一起来分析下注册中心的原理。

3.1注册中心原理

在微服务远程调用的过程中,包括两个角色:

  • 服务提供者:提供接口供其它微服务访问,比如item-service

  • 服务消费者:调用其它微服务提供的接口,比如cart-service

在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务就引入了注册中心的概念。注册中心、服务提供者、服务消费者三者间关系如下:

流程如下:

  • 服务启动时就会注册自己的服务信息(服务名、IP、端口)到注册中心

  • 调用者可以从注册中心订阅想要的服务,获取服务对应的实例列表(1个服务可能多实例部署)

  • 调用者自己对实例列表负载均衡,挑选一个实例

  • 调用者向该实例发起远程调用

当服务提供者的实例宕机或者启动新实例时,调用者如何得知呢?

  • 服务提供者会定期向注册中心发送请求,报告自己的健康状态(心跳请求)

  • 当注册中心长时间收不到提供者的心跳时,会认为该实例宕机,将其从服务的实例列表中剔除

  • 当服务有新实例启动时,会发送注册服务请求,其信息会被记录在注册中心的服务实例列表

  • 当注册中心服务列表变更时,会主动通知微服务,更新本地服务列表

3.2Nacos注册中心

目前开源的注册框架有很多,我们用Nacos来实现。
我们基于Docker来部署Nacos的注册中心,首先我们要准备MySQL数据库表,用来存储Nacos的数据。由于是Docker部署,所以大家需要将资料中的SQL文件导入到你Docker中的MySQL容器中:

最终表结构如下:

然后,找到课前资料下的nacos文件夹:

其中的nacos/custom.env文件中,有一个MYSQL_SERVICE_HOST也就是mysql地址,需要修改为你自己的虚拟机IP地址,还有端口,密码等:

然后,将课前资料中的nacos目录上传至虚拟机的/root目录。
进入root目录,然后执行下面的docker命令:

docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim

容器部署完成后可以通过下面命令来查看Nacos的运行日志

docker logs -f nacos

启动完成后,访问下面地址:http://192.168.52.135:8848/nacos,注意将192.168.52.135替换为你自己的虚拟机IP地址。

首次访问会跳转到登录页,账号密码都是nacos

3.3服务注册

比如将item-service注册到Nacos中,有以下步骤:

3.3.1.添加依赖

item-servicepom.xml中添加依赖:

<!--nacos 服务注册发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

3.3.2.配置Nacos

item-serviceapplication.yml中添加nacos地址配置:

spring:
  application:
    name: item-service # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.52.135:8848 # nacos地址

3.3.3.启动服务实例

为了测试一个服务多个实例的情况,我们再配置一个item-service的部署实例:

右击Modify options

添加VM options

设置不同的启动类名称和端口号。然后点击Apply--Ok

启动Item-services的多个启动类。

访问nacos控制台,可以发现服务注册成功:

点击详情,可以查看到item-service服务的两个实例信息:

3.4服务发现

服务的消费者要去nacos订阅服务,这个过程就是服务发现,步骤如下:

  • 引入依赖

  • 配置Nacos地址

  • 发现并调用服务

3.4.1引入依赖

服务发现除了要引入nacos依赖以外,由于还需要负载均衡,因此要引入SpringCloud提供的LoadBalancer依赖。
我们在cart-service中的pom.xml中添加下面的依赖:

<!--nacos 服务注册发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

可以发现,这里Nacos的依赖于服务注册时一致,这个依赖中同时包含了服务注册和发现的功能。因为任何一个微服务都可以调用别人,也可以被别人调用,即可以是调用者,也可以是提供者。
因此,等一会儿cart-service启动,同样会注册到Nacos。

3.4.2.配置Nacos地址

cart-serviceapplication.yml中添加nacos地址配置:

spring:
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848  #nacos地址

3.4.3.发现并调用服务

服务调用者cart-service就可以去订阅item-service服务了。不过item-service有多个实例,而真正发起调用时只需要知道一个实例的地址。

因此,服务调用者必须利用负载均衡的算法,从多个实例中挑选一个去访问。常见的负载均衡算法有:
服务发现需要用到一个工具,DiscoveryClient,SpringCloud已经帮我们自动装配,我们可以直接注入使用:

接下来,我们就可以对原来的远程调用做修改了,之前调用时我们需要写死服务提供者的IP和端口:

但现在不需要了,我们通过DiscoveryClient发现服务实例列表,然后通过负载均衡算法,选择一个实例去调用:


然后通过Swagger调试,成功。

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

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

相关文章

Qt篇——Qt使用C++获取Windows电脑上所有外接设备的名称、物理端口位置等信息

我之前有发过一篇文章《Qt篇——获取Windows系统上插入的串口设备的物理序号》&#xff0c;文章中主要获取的是插入的USB串口设备的物理序号&#xff1b;而本篇文章则进行拓展&#xff0c;可以获取所有外接设备的相关信息&#xff08;比如USB摄像头、USB蓝牙、USB网卡、其它一些…

前端转鸿蒙好做吗

在科技不断发展的当下&#xff0c;许多前端开发者可能会思考一个问题&#xff1a;前端转鸿蒙好做吗? 一、前端与鸿蒙开发的差异 1. 技术栈的变化 前端开发主要涉及 HTML、CSS、JavaScript 等技术&#xff0c;而鸿蒙开发则需要掌握 Java、Kotlin、JavaScript 等语言&#xff0c…

远程存储 RDMA

什么是 RDMA RDMA&#xff08;Remote Direct Memory Access&#xff09;指的是远程直接内存访问&#xff0c;这是一种通过网络在两个应用程序之间搬运缓冲区里的数据的方法。 Remote&#xff1a;数据通过网络与远程机器间进行数据传输。 Direct&#xff1a;没有内核的参与&am…

计算机毕业设计 | 基于SpringBoot的健身房管理系统(附源码)

1&#xff0c;项目背景 随着人们生活水平的提高和健康意识的增强&#xff0c;越来越多的人开始关注自己的身体健康并加入到健身行列中。然而&#xff0c;传统的健身房管理方式往往存在诸多问题&#xff0c;如会员信息管理混乱、课程安排不合理、教练资源分配不均等&#xff0c…

MaxCompute基础概论

1. 简介与背景 随着大数据技术的发展&#xff0c;企业和组织面临着处理海量数据的挑战。传统的数据存储和处理工具难以应对高并发、复杂计算以及海量数据的快速增长需求。为了解决这些问题&#xff0c;阿里云推出了 MaxCompute&#xff08;原名 ODPS&#xff09;&#xff0c;这…

超声波雪深监测站

超声波雪深监测站是一种用于测量和监测雪深的设备。它的功能和作用主要包括以下几个方面&#xff1a; 雪深测量&#xff1a;超声波雪深监测站能够通过发射超声波并接收回波的方式&#xff0c;测量雪地表面到地面之间的距离&#xff0c;从而得到雪深的数据。通过分析和处理这些数…

图像去噪的艺术:自适应中值滤波器的应用与实践

在数字图像处理的众多挑战中&#xff0c;噪声的去除是一个永恒的话题。特别是椒盐噪声&#xff0c;因其随机将像素点变为极黑或极白&#xff0c;对图像的视觉质量破坏极大。本文将通过MATLAB实现的自适应中值滤波器&#xff08;AMF&#xff09;&#xff0c;探讨其在图像去噪中的…

--- 数据结构 二叉树 --- java

树形结构 数使一个非线性结构&#xff0c;他是由n个结点组成的具有一定层次关系的集合&#xff0c;叫做树是因为他像是一颗倒挂的树&#xff0c;根在上&#xff0c;叶子在下&#xff0c;具有一些性质 1&#xff0c;有一个特殊节点叫做根节点&#xff0c;他没有钱去节点&#x…

017_Python爬虫系列_防盗链代理

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈 PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈 Oracle数…

限流,流量整形算法

写在前面 本文看下流量整形相关算法。 目前流量整形算法主要有三种&#xff0c;计数器&#xff0c;漏桶&#xff0c;令牌桶。分别看下咯&#xff01; 1&#xff1a;计数器 1.1&#xff1a;描述 单位时间内只允许指定数量的请求&#xff0c;如果是时间区间内超过指定数量&a…

用Python实现时间序列模型实战——Day 17: 时间序列模型的评估方法

一、学习内容 1. 预测误差的评估指标 在时间序列预测中&#xff0c;常用的评估指标包括 MAE (Mean Absolute Error), MSE (Mean Squared Error) 和 RMSE (Root Mean Squared Error)。这些指标用于衡量模型的预测误差。 MAE (Mean Absolute Error)&#xff1a; MAE 衡量预测值…

mysql学习教程,从入门到精通,MySQL WHERE 子句(10)

1、SQL WHERE 子句 在本教程中&#xff0c;您将学习如何使用SQL从表中选择特定记录。 根据条件选择记录 在上一章中&#xff0c;我们学习了如何从表或表列中获取所有记录。但是&#xff0c;在现实世界中&#xff0c;我们通常只需要选择&#xff0c;更新或删除满足某些条件的那…

HarmonyOS---应用测试概述

一、应用质量要求 应用质量要求分为应用体验质量建议和应用内容合规要求两大部分。 1、应用体验质量建议 功能数据完备、基础体验要求、HarmonyOS特征增强体验要求。 &#xff08;1&#xff09;功能数据完备 &#xff08;2&#xff09;基础体验要求 &#xff08;3&#xff09;增…

盘古信息IMS 驱动智能工厂建设,助力制造企业降本增效

随着全球化的加剧和市场竞争的日益激烈&#xff0c;制造业面临着提高生产效率、降低成本、提升产品质量以及实现绿色可持续发展等多重压力。智能工厂是利用人工智能、大数据、物联网、云计算等新技术&#xff0c;实现工厂的智能化、自动化、可持续化发展的新型制造业模式&#…

《深度学习》OpenCV 高阶 图像直方图、掩码图像 参数解析及案例实现

目录 一、图像直方图 1、什么是图像直方图 2、作用 1&#xff09;分析图像的亮度分布 2&#xff09;判断图像的对比度 3&#xff09;检测图像的亮度和色彩偏移 4&#xff09;图像增强和调整 5&#xff09;阈值分割 3、举例 二、直方图用法 1、函数用法 2、参数解析…

芋道快速开发平台的使用心得

1.前端版本 项目的管理后台有 4 个版本&#xff1a; yudao-ui-admin-vue3 (opens new window)&#xff1a;基于 Vue3 element-plus yudao-ui-admin-vben (opens new window)&#xff1a;基于 Vue3 vben(ant-design-vue) yudao-ui-admin-vue2 (opens new window)&#xff…

LaTeX中制作表格【表格数据自动换行】(附latex源码)

一、latex软件推荐 在使用LaTeX进行文档编写时&#xff0c;有几款非常受欢迎且功能强大的软件和在线编辑器可供选择。以下是一些推荐的LaTeX软件&#xff1a; 1. Overleaf(强烈推荐) Your Projects - Overleaf, Online LaTeX Editorhttps://www.overleaf.com/project 2.Tex…

图新说【消防】(一步步的做好态势标绘)

0.序 越来越多的消防战士使用图新说来做消防预案&#xff0c;态势标绘比武等。 图新说即可应用于具体的消防救援任务&#xff0c;制作具体的作战方案&#xff0c;让战士的配合更加紧密。 也可以做大型的消防预案&#xff0c;针对辖区内的重点建筑、危化存储区提前做应急救援方…

最新版MYMPay码支付开源版系统源码_个人免签支付_聚合支付系统

最新版MYMPay码支付开源版系统源码_个人免签支付_聚合支付系统 安装环境&#xff1a; PHP&#xff1a;7.0-8.2 (推荐使用7.4) 需要安装Xload 扩展 MySQL&#xff1a;5.6版本 访问 http://你的域名/install 进行安装 后台地址&#xff1a;http://你的域名/Admin/ 账号&am…

C++笔记之map的实用操作

C++笔记之map的实用操作 文章目录 C++笔记之map的实用操作1.初始化1.1.使用列表初始化1.2.使用 `insert` 方法1.3.使用 `emplace` 方法1.4.复制构造1.5.移动构造2.赋值2.1.列表赋值2.2.插入元素2.3.批量插入3.取值3.1.使用 `[]` 操作符3.2.使用 `at()` 方法3.3.检查键是否存在3…