SpringCloud微服务(简略笔记一)

news2025/9/21 2:05:01

目录

介绍

​编辑

认识微服务

单体架构

分布式架构

微服务分析:

分布式架构(SpringCloud微服务)

服务拆分与服务远程调用:

提供者与消费者

微服务治理

Eureka注册中心

操作步骤

 Ribbon负载均衡

负载均衡流程

自定义负载均衡策略

饥饿加载

总结

nacos

启动

注册中心前的准备

服务跨集群调用问题

NacosRole负载均衡

Nacos——服务实例的权重设置

Nacos环境隔离

Nacos与eureka的共同点

nacos配置管理

Nacos配置管理-配置热更新

Nacos配置管理

Fegin远程调用

自定义Feign配置

Http客户端Feign

抽取FeignClient

统一网关Gateway

搭建网关步骤步骤:

 路由断言工厂Route Predicate Factory

路由过滤器GatewayFilter

全局过滤器GlobalFilter

过滤器执行顺序

跨域问题处理

Docker

项目部署的问题


介绍

微服务是一种软件架构风格,它是以专注于单一职责的很多小型项目为基础,组合出复杂的大型应用。

认识微服务

单体架构

单体架构:讲业务的所有功能集中在一个项目中开发,打成一个包部署

分布式架构

分布式架构:根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务。

微服务分析:

单体架构:我们一开始接触的项目,是MVC架构,分模块开发,一个项目的数据放到一个数据库中,一次打包,启动项目。

分布式架构:一个业务抽离成一个业务,此业务的数据抽离成一个数据库,也就是说,多个业务,多个数据库,多个服务。

分布式架构(SpringCloud微服务)

服务拆分与服务远程调用:

举个例子:

我们有两个表,订单表和用户表,两个表要做关联查询,订单表有userId,要在订单表中展示出User的数据。

@Data
public class Order {
    private Long id;
    private Long price;
    private String name;
    private Integer num;
    private Long userId;
    private User user;
}

  由于用户和订单抽离成了两个服务,也就是有两个数据库的数据,

1.有了userId,我直接id查询是行不通的,因为order数据库没有user数据。

2.既然user用户表成了一个服务,那么可以用类似浏览器前端发送ajax的形式,获取服务数据。

package cn.itcast.order;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}
package cn.itcast.order.service;

import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2. 利用RestTemplate 发起http请求,查询用户
        // 2.1 url路径
        String url = "http://localhost:8081/user/" + order.getUserId();
        // 2.2 发起http请求,实现远程调用
        User user = restTemplate.getForObject(url, User.class);

        // 3. 封装user到Order
        order.setUser(user);
        // 4.返回
        return order;
    }
}

提供者与消费者

* 服务提供者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)

* 服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)

一个服务既可以是提供者又可以是消费者。

微服务治理

Eureka注册中心

eureka的作用

* 消费者该如何获取服务提供者具体信息?

    * 服务提供者启动时向eureka注册自己的信息

    * 消费者根据服务名称向eureka拉去提供者信息

    *eureka保存这些信息

* 如果有多个服务提供者,消费者该如何选择?

    * 服务消费者利用负载均衡算法,从服务列表中挑选一个

* 消费者如何感知服务提供者建康状态?

    * 服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态

    *eureka会更新记录服务列表信息,心跳不正常会被剔除

    * 消费者就可以拉渠道最新的信息

操作步骤

1. 搭建注册中心

搭建EurekaServer

步骤一:依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

步骤二:启动类注解

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

步骤三:yml配置

server:
  port: 10086
spring:
  application:
    name: eureka-server   # eureka的服务名称
eureka:
  client:
    service-url:  # eureka的地址信息
      defaultZone: http://127.0.0.1:10086/eureka

2. 服务注册

      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
server:
  port: 8080
spring:
  application:
    name: orderservice
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
eureka:
  client:
    service-url:  # eureka的地址信息
      defaultZone: http://127.0.0.1:10086/eureka

3. 服务发现

        String url = "http://userservice/user/" + order.getUserId();
        // 2.2 发起http请求,实现远程调用
        User user = restTemplate.getForObject(url, User.class);

负载均衡

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

 Ribbon负载均衡

负载均衡流程

自定义负载均衡策略

userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则 

饥饿加载

Ribbon默认是采用懒加载,即第一次访问时才回去创建LoadBalanceClient,请求时间会很长。

而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

ribbon:
  eager-load:
    enabled: true
    clients: userservice

总结

1. Ribbon负载均衡规则

         * 规则接口是IRule

         * 默认实现是ZoneAvoidanceRule,根据zone

           选择服务列表,然后轮询

2.   负载均衡自定义方式

      * 代码方式:配置灵活,但修改时需要重新打包

         发布

       * 配置方式:直观,方便,无需重新打包发布,

          但是无法做全局配置

3. 饥饿加载

       * 开启饥饿加载

       * 指定饥饿加载的微服务名称。

nacos

GitHub的Release下载页:https://github.com/alibaba/nacos/releases

启动

windos下,进入加压后的bin目录,命令:startup.cmd -m standalone

网址:http://127.0.0.1:8848/nacos

账号密码都是:nacos

注册中心前的准备

父工程依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.5.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

客户端依赖

<!-- nacos客户端依赖包 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

 yml配置

server:
  port: 8080
spring:
  application:
    name: orderservice
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
#eureka:
#  client:
#    service-url:  # eureka的地址信息
#      defaultZone: http://127.0.0.1:10086/eureka

服务跨集群调用问题

服务调用尽可能选择本地集群的服务,跨集群调用延迟较高,本地集群不可访问时,再去访问其它集群。

yml配置

server:
  port: 8081
spring:
  application:
    name: userservice
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        cluster-name: SH # 集群名称  代替杭州

mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
#eureka:
#  client:
#    service-url:  # eureka的地址信息
#      defaultZone: http://127.0.0.1:10086/eureka

NacosRole负载均衡

server:
  port: 8080
spring:
  application:
    name: orderservice
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        cluster-name: HZ # 集群名称  代替杭州
userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
#eureka:
#  client:
#    service-url:  # eureka的地址信息
#      defaultZone: http://127.0.0.1:10086/eureka

Nacos——服务实例的权重设置

实例的权重控制

1. Nacos控制台可以设置实例的权重值,0~1之间

2. 同集群内的多个实例,权重越高被访问的频率越高

3. 权重设置为0则完全不会被访问

Nacos环境隔离

1. namespace用来做环境隔离

2. 每个namespace都有唯一id

3. 不同namespace下的业务不可见

server:
  port: 8080
spring:
  application:
    name: orderservice
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        cluster-name: HZ # 集群名称  代替杭州
        namespace: eebd708a-506e-47e1-97b0-05e491a1982a # dev环境
userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
#eureka:
#  client:
#    service-url:  # eureka的地址信息
#      defaultZone: http://127.0.0.1:10086/eureka

Nacos与eureka的共同点

共同点

1. 都支持服务注册和服务拉取

2. 都支持服务提供者心跳方式做健康测试

区别

1. nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式

2. 临时实例心跳不正常会被剔除,非临时实例则不会被剔除

3. nacos支持服务列表变更的消息推送模式,服务列表更新更及时

4. nacos集群采用AP方式,当集群中存在菲临时实例时,采用CP模式,Eureka采用AP方式

nacos配置管理

配置的步骤

nacos的配置管理依赖

<!--nacos配置管理依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

然后,在user-service中添加一个bootstrap.yaml文件,内容如下:

spring:
  application:
    name: userservice # 服务名称
  profiles:
    active: dev #开发环境,这里是dev 
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
      config:
        file-extension: yaml # 文件后缀名

 测试一下

   @Value("${pattern.dateformat}")
    private String dateformat;

    @GetMapping("/now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }

Nacos配置管理-配置热更新

在用的类上添加热更新注解


@Slf4j
@RestController
@RequestMapping("/user")
@RefreshScope
public class UserController {

    @Autowired
    private UserService userService;

   @Value("${pattern.dateformat}")
    private String dateformat;

    @GetMapping("/now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }

第二种方式:使用@ConfigurationPoperties注解

package cn.itcast.user.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @author Mtz
 * @version 1.0
 * @2023/10/619:21
 * @function
 * @comment
 */
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
    private String dateformat;
}
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

//   @Value("${pattern.dateformat}")
//    private String dateformat;

    @Autowired
    private PatternProperties patternProperties;

    @GetMapping("/now")
    public String now() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(patternProperties.getDateformat()));
    }

Nacos配置管理

多环境配置共享

微服务启动时会从nacos读取多个配置文件:

多种配置的优先级:

* 服务名-profile.yaml > 服务名称.yaml > 本地配置

Fegin远程调用

在消费者服务引入依赖

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

启动类添加注解

package cn.itcast.order.service;

import cn.itcast.order.client.UserClient;
import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserClient userClient;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);

        // 2.
        User user = userClient.findById(order.getUserId());

        order.setUser(user);


        // 4.返回
        return order;
    }
}

自定义Feign配置

基于配置文件修改feign的日志级别可以针对单个服务:

feign:  
  client:
    config: 
      userservice: # 针对某个微服务的配置
        loggerLevel: FULL #  日志级别 

也可以针对所有服务:

feign:  
  client:
    config: 
      default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
        loggerLevel: FULL #  日志级别 

而日志的级别分为四种:

  • NONE:不记录任何日志信息,这是默认值。

  • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间

  • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息

  • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。

Http客户端Feign

Feign的性能优化

Feign底层的客户端实现:

* URLConnection:默认实现,不支持连接池

* Apache HttpClient:支持连接池

* OKHTTP :支持连接池

在消费者引入依赖

<!--httpClient的依赖 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

配置连接池

feign:
  client:
    config:
      default: # default全局的配置
        loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
  httpclient:
    enabled: true # 开启feign对HttpClient的支持
    max-connections: 200 # 最大的连接数
    max-connections-per-route: 50 # 每个路径的最大连接数

抽取FeignClient

步骤:

1. 创建一个module,命名为feign-api,引入feign的srarter依赖

2.将order-servivce中编写的UserClient , User ,DefaultFeignConfiguration都复制到feign-api项目中

3. 将order-service中引入feign-api的依赖

4.修改order-service的所有与上述三个组件有关的import部分,改成导入feign-api中的包

5. 重启测试

依赖


        <!--引入HttpClient依赖-->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
        </dependency>

由于在不同的包下,扫描时注意UserClient的位置

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients(clients = UserClient.class)
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

}

统一网关Gateway

为什么需要网关?

权限控制:网关作为微服务入口,需要校验用户是是否有请求资格,如果没有则进行拦截。

路由和负载均衡:一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路由。当然路由的目标服务有多个时,还需要做负载均衡。

限流:当请求流量过高时,在网关中按照下流的微服务能够接受的速度来放行请求,避免服务压力过大。

搭建网关步骤步骤:

模块服务所需的依赖


        <!--网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--nacos服务发现依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

yml配置

server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求

路由配置包括:

1.路由id:路由的唯一标识

2. 路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡

3.路由断言(predicates):判断路由的规则。

 路由断言工厂Route Predicate Factory

* 我们在配置文件中写的断言规则只是字符串,这些字符串会被PrdicateFactory读取并处理,转变为路由判断的条件

网址参考:Spring Cloud Gateway

路由过滤器GatewayFilter

SpringCloud网址参考:Spring Cloud Gateway

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:

yml配置

server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
          filters: # 过滤器
            - AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头
        - id: order-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://orderservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/order/** # 这个是按照路径匹配,只要以/user/开头就符合要求
            - After=2025-01-20T17:42:47.789-07:00[America/Denver]

默认配置

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/**
      default-filters: # 默认过滤项
      - AddRequestHeader=Truth, Itcast is freaking awesome! 

全局过滤器GlobalFilter

GlobalFilter的逻辑需要自己写代码实现,定义方式是接口GlobalFilter接口。

package cn.itcast.gateway;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        // 2.获取authorization参数
        String auth = params.getFirst("authorization");
        // 3.校验
        if ("admin".equals(auth)) {
            // 放行
            return chain.filter(exchange);
        }
        // 4.拦截
        // 4.1.禁止访问,设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        // 4.2.结束处理
        return exchange.getResponse().setComplete();
    }
}

过滤器执行顺序

请求进入网关会碰到三类过滤器:当前路由的过滤器,DefaultFilter,GlobalFIlter

请求路由后,会将当前路由过滤器和DefaultFilter,GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器。

跨域问题处理

spring:
  cloud:
    gateway:
      # 。。。
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求 
              - "http://localhost:8090"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

Docker

项目部署的问题

大型项目组件较多,运行环境较为复杂,部署时会碰到一些问题:

*  依赖关系复杂,容易出现兼容问题

*  开发,测试,生产环境有差异

Docker如何解决依赖的兼容问题?

* 就应用的libs(函数库),Deps(依赖),配置与应用一起打包。

* 将每个应用放到一个隔离容器去运行,避免互相打扰

Docke如何解决不同系统环境的问题?

* Docker将用户程序与所需调用的系统(比如Ubuntu)函数库一起打包

*Docker运行到不同操作系统时,借助于操作系统的linux内核来运行

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

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

相关文章

手把手改进yolo训练自己的数据(坑洼路面识别)

结果展示 在Pothole Detection数据集上对YOLOv7进行微调的步骤如下&#xff1a; 0 环境配置 if not os.path.exists(yolov7): !git clone https://github.com/WongKinYiu/yolov7.git %cd yolov7 !pip install -r requirements.txt数据集准备&#xff1a; 收集一个专门用于po…

栈的运行算法

一&#xff0c;顺序栈的静态分配 二&#xff0c;顺序栈的动态分配 #include<stdio.h> #include<stdlib.h> #define initsize 5 #define incresize 5typedef struct Sqstack{int *base;int *top;int stacksize; }Sqstack;void InitStack(Sqstack *s){(*s).base(int…

数字孪生技术:新零售的未来之路

随着科技的不断进步&#xff0c;新零售产业正经历着巨大的变革。数字孪生作为一种新兴技术正在加速这一变革的进程。它不仅为新零售企业带来了更高效的运营方式&#xff0c;还为消费者提供了更个性化、便捷的购物体验。那么&#xff0c;数字孪生技术究竟如何在新零售产业中发挥…

选择同步云盘工具?这些值得一试的优秀选择!

对于云盘用户而言&#xff0c;同步功能是影响产品选择的重要因素。在日常办公过程中&#xff0c;我们难免会遇到需要查看文件&#xff0c;但是存储文件的原设备不在身边的情况。这个时候同步云盘的重要性就显现出来了. 同步云盘的优势 文件同步&#xff1a;同步云盘可以将文件…

L05_SpringBoot入门

SpringBoot入门 浅谈Restful风格代码实现(并且通过Apifox进行接口测试[以传入json格式数据为例])首先创建一个SpringBoot项目,pom文件包引入如下下面在新建src创建com.ndky.controller包,然后再在包内创建一个HelloController类编写(一个简易的restful风格的代码)编写GET请求代…

正则表达式基础语法

https://tool.oschina.net/regex 正则表达式&#xff1a;检查、匹配字符串的表达式 单个字符匹配&#xff1a; 有特殊含义的匹配&#xff1a; 多次重复匹配&#xff1a; 限定开头结尾的匹配&#xff1a; 贪婪模式&#xff1a;在满足条件的情况下&#xff0c;尽可能多匹配…

Python算法练习 10.12

leetcode 649 Dota2参议院 Dota2 的世界里有两个阵营&#xff1a;Radiant&#xff08;天辉&#xff09;和 Dire&#xff08;夜魇&#xff09; Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每…

MNIST字符识别(C++)

构建网络 采用官方示例的的lenet网络 训练 相关文件都已编译好&#xff0c;下载后执行命令即可 .\caffe-bin.exe train --solver .\lenet_solver.prototxt 识别 #include <caffe/caffe.hpp>#include <opencv2/core/core.hpp> #include <opencv2/highgui/hi…

炒现货白银的最佳时间

天时地利人和是我们进行现货白银投资最关键的因素。天时是指我们因时而动&#xff0c;在适合的时机出击。地利&#xff0c;就是我们对市场的定位&#xff0c;对自己入场的定位有清晰的了解&#xff0c;并且这些位置对我们有利。人和就是指投资者的状态很好&#xff0c;对如何进…

STM32MP157按键中断实验

按键配置 #include "key_it.h" #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_gic.h" #include "stm32mp1xx_exti.h" #include "stm32mp1xx_rcc.h"void key_it_config() {/* RCC使能GPIOF时钟 */RCC->MP_AHB4ENSE…

九章云极DataCanvas公司入选《AIGC产业链北京专精特新企业图谱》

近日&#xff0c;北京市经济和信息化局成功举办AIGC&#xff08;生成式人工智能&#xff09;产业链专精特新企业融通路演活动&#xff0c;并正式发布《AIGC产业链北京市专精特新企业图谱》&#xff08;下称《图谱》&#xff09;。九章云极DataCanvas公司凭借DataCanvas Alaya九…

Python- socket编程

Python中的socket模块为网络通信提供了基础API&#xff0c;使我们能够在应用程序中实现低级的网络交互。使用socket编程&#xff0c;可以创建TCP、UDP和RAW sockets来进行数据通信。 以下是Python socket 编程的简要概述&#xff1a; 1. 核心概念 Socket: 通信的端点&#x…

PTrade获取当日n个季度前的日期所处季度的最后一天——时间相关函数4

本文介绍的函数用于获取当日n个季度前的日期所处季度的最后一天&#xff08;有点绕&#xff0c;看后面例子就好理解了&#xff09;。 源码 def last_day_of_quarter_before_n_quarters(n):"""获取当日n个季度前的日期所处季度的最后一天:return: 当日n个季度前…

leetcode 打家劫舍篇

198. 打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个…

【嵌入式】STM32F031K4U6、STM32F031K6U6、STM32F031K6T6主流ARM Cortex-M0基本型系列MCU规格参数

一、电路原理图 【嵌入式】STM32F031K4U6、STM32F031K6U6、STM32F031K6T6主流ARM Cortex-M0基本型系列MCU —— 明佳达 二、规格参数 1、STM32F031K4U6&#xff08;16KB&#xff09;闪存 32UFQFPN 核心处理器&#xff1a;ARM Cortex-M0 内核规格&#xff1a;32 位单核 速度&a…

喜报!冲量在线中标中国电信北京公司2023年基于通用GPU的可信执行环境技术的研究项目

近日&#xff0c;冲量在线中标中国电信北京公司2023年基于通用GPU的可信执行环境的研究项目&#xff01;基于通用GPU的可信执行环境技术&#xff0c;完成业界领先的基于国产可信芯片的AI算力平台建设。 通过平台TEEGPU的隐私计算能力&#xff0c;给现有的AI智算平台在可信计算方…

必知必会的22种设计模式(GO语言)

日常工作中免不了使用设计模式&#xff0c;那么你使用了哪些设计模式呢&#xff1f; 设计模式是什么&#xff1f; 设计模式是一种在软件设计中对常见问题的通用解决方案。 它们是经过验证的、可重用的设计思想&#xff0c;可以帮助解决开发过程中遇到的各种问题。 设计模式…

碰撞检测算法——分离轴算法在Unity中实现(二)

一、介绍 分离轴算法&#xff08;简称SAT&#xff09;通常用于检查两个简单多边形&#xff08;凸边形&#xff09;之间或多边形与圆之间的碰撞。本质上&#xff0c;如果您能够绘制一条线来分隔两个多边形&#xff0c;则它们不会发生碰撞&#xff0c;如果找不到一条线来分割两个…

卷积神经网络CNN基础知识

目录 1 前言2 卷积神经网络CNN2.1 LeNet-5相关介绍2.2 CNN基本结构2.2.1 卷积层2.2.2 池化层&#xff08;下采样层&#xff09;2.2.3 全连接层2.2.3.1激励层&#xff08;非线性激活&#xff09;2.2.3.2 线性层2.2.3.3 Dropout层2.2.3.4 总结 2.3 图像的上采样和下采样2.3.1 上采…

vue2 .sync 修饰符

vue2 .sync 修饰符 **创建 工程&#xff1a; H:\java_work\java_springboot\vue_study ctrl按住不放 右键 悬着 powershell H:\java_work\java_springboot\js_study\Vue2_3入门到实战-配套资料\01-随堂代码素材\day04\准备代码\13-sync修饰符 vue --version vue create v-sy…