GateWay网关

news2024/10/7 12:24:31

GateWay

1. 什么是网关

网关是微服务最边缘的服务,直接暴露给用户,用来做用户和微服务的桥梁

  1. 没有网关:客户端直接访问我们的微服务,会需要在客户端配置很多的ip:port,如果user-service并发比较大,则无法完成负载均衡

  2. 有网关:客户端访问网关,网关来访问微服务,这样只需要使用服务名称即可访问微服务,可以实现负载均衡,可以实现token拦截,权限验证,限流等操作

2. Spring Cloud Gateway简介

SpringCloud Gateway作为Spring Cloud生态的网关,目标是替代Zuul,在SpringCloud2.0以上的版本中,没有对新版本的zuul2.0以上的最新高性能版本进行集成,仍然还是使用的zuul1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于webFlux 框架实现的,而webFlux框架底层则使用了高性能的Reactor模式通信框架的Netty。

3. Spring Cloud Gateway工作流程

在这里插入图片描述

客户端向springcloud Gateway 发出请求,然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。

Handler 再通过指定的过滤器来将请求发送到我们实际的服务的业务逻辑,然后返回。 过滤器之间用虚线分开是因为过滤器可能会在发送爱丽请求之前【pre】或之后【post】执行业务逻辑,对其进行加强或处理。

Filter在 【pre】 类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等

在【post】 类型的过滤器中可以做响应内容、响应头的修改、日志的输出,流量监控等有着非常重要的作用。

总结:Gateway 的核心逻辑也就是 路由转发 + 执行过滤器链

4. Spring Cloud Gateway三大核心概念

4.1 Route(路由)

路由信息的组成:
由一个ID、一个目的URL、一组断言工厂、一组Filter组成。
如果路由断言为真,说明请求URL和配置路由匹配。 

4.2 Predicate(断言)

Java 8中的断言函数。 lambda 四大接口 供给形,消费性,函数型,断言型

Spring Cloud Gateway中的断言函数输入类型是Spring 5.0框架中的ServerWebExchange。Spring Cloud Gateway的断言函数允许开发者去定义匹配来自于Http Request中的任何信息比如请求头和参数。

4.3 Filter(过滤) (重点)

一个标准的Spring WebFilter。 

Spring Cloud Gateway中的Filter分为两种类型的Filter,分别是Gateway Filter和Global Filter。过
Gateway filter是针对某一个路由的filter 对某一个接口做限流
Global Filter个是针对全局的filter,例如token过滤,ip黑名单过滤等

5.Gateway入门

5.1新建项目gateway

注意:项目不要选择spring-web包,导入eureka-client和gateway

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.8</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.powernode</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2021.0.1</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

5.2启动类

@SpringBootApplication
@EnableEurekaClient //网关也是eureka的客户端
public class Gateway80Application {

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

5.3修改配置文件

server:
    port: 80
spring:
    application:
        name: gateway
    cloud:
        gateway:
            enabled: true   #开启网关,默认是开启的
            routes: #设置路由,注意是数组,可以设置多个,按照id做隔离
                -   id: user-service-router    #路由id,没有要求,保持唯一即可
                    uri: http://localhost:8081  #设置真正的服务ip:port
                    predicates: #断言匹配
                        - Path=/info/** #和服务中的路径匹配,是正则匹配的模式
                -   id: provider-service-router
                    uri: http://localhost:8082
                    predicates:
                        - Path=/info/** #如果匹配到第一个路由,则第二个就不会走了,注意这不是负载均衡
#eureka的配置
eureka:
    instance:
        instance-id: ${spring.application.name}:${server.port}
        prefer-ip-address: true
    client:
        service-url:
            defaultZone: http://localhost:8761/eureka/

5.4启动测试

启动eureka,启动gateway,启动user-service, 此时可以通过80端口localhost/info访问用户服务

6.Gateway的路由配置方式

6.1代码注入方式

官网给出的配置类,我们照葫芦画瓢

https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#modifying-the-way-remote-addresses-are-resolved

6.1.1 创建配置类GatewayConfig

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes
                .route("path_rote_guonei", r -> r.path("/guonei").uri("http://news.baidu.com/guonei"))
                .route("path_rote_guoji", r -> r.path("/guoji").uri("http://news.baidu.com/guoji"))
                .route("path_rote_tech", r -> r.path("/tech").uri("http://news.baidu.com/tech"))
                .route("path_rote_lady", r -> r.path("/lady").uri("http://news.baidu.com/lady"))
                .build();
        return routes.build();
    }

6.1.2测试

在这里插入图片描述

开发中最常用的还是在yml中进行配置

7. Gateway微服务名动态路由,负载均衡

7.1 概述

从之前的配置里面我们可以看到我们的URL都是写死的,这不符合我们微服务的要求,我们微服务是只要知道服务的名字,根据名字去找,而直接写死就没有负载均衡的效果了。

默认情况下Gateway会根据注册中心的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能。

需要注意的是uri的协议为lb(load Balance),表示启用Gateway的负载均衡功能。

lb://serviceName是spring cloud gateway在微服务中自动为我们创建的负载均衡uri

协议:就是双方约定的一个接头暗号

7.2 最佳实践

7.2.1 修改gateway配置

server:
    port: 80
spring:
    application:
        name: gateway
    cloud:
        gateway:
            discovery:
                locator:
                    enabled: true   #开启动态路由
                    lower-case-service-id: true #动态路由小驼峰规则
            routes: #设置路由,注意是数组,可以设置多个,按照id做隔离
                -   id: user-service-router    #路由id,没有要求,保持唯一即可
                    uri: lb://provider  #使用lb协议 微服务名称做负均衡
                    predicates: #断言匹配
                        - Path=/info/**  #和服务中的路径匹配,是正则匹配的模式
                -   id: provider-service-router
                    uri: http://localhost:8082
                    predicates:
                        - Path=/info/** #如果匹配到第一个路由,则第二个就不会走了,注意这不是负载均衡
#eureka的配置
eureka:
    instance:
        instance-id: ${spring.application.name}:${server.port}
        prefer-ip-address: true
    client:
        service-url:
            defaultZone: http://localhost:8761/eureka/

7.2.2 启动测试

启动eureka-server,启动两个服务名为provider的服务,和uri里面lb://服务名一致

在provider里面提供两个接口/info

访问测试:http://localhost/info 正常访问

当我们新起一个服务,那么gateway可以实现服务发现功能,我们并没有在routers里面配置路由规则,然而我们访问 新起的provider-order-service,测试访问

http://localhost/provider-order-service/info 可以成功,这就是动态路由和服务发现

8.断言,Gateway里面有哪些断言

通俗的说,断言就是一些布尔表达式,满足条件的返回true,不满足的返回false。

Spring Cloud Gateway将路由作为Spring WebFlux HandlerMapping基础架构的一部分进行匹配。Spring Cloud Gateway包括许多内置的路由断言工厂。所有这些断言都与HTTP请求的不同属性匹配。您可以将多个路由断言可以组合使用

Spring Cloud Gateway创建对象时,使用RoutePredicateFactory创建Predicate对象,Predicate对象可以赋值给Route。

8.1如何使用这些断言

使用断言判断时,我们常用yml配置文件的方式进行配置

server:
    port: 80
spring:
    application:
        name: gateway
    cloud:
        gateway:
            enabled: true   #开启网关,默认是开启的
            routes: #设置路由,注意是数组,可以设置多个,按照id做隔离
                -   id: user-service    #路由id,没有要求,保持唯一即可
                    uri: lb://provider  #使用lb协议 微服务名称做负均衡
                    predicates: #断言匹配
                        - Path=/info/**  #和服务中的路径匹配,是正则匹配的模式
                        - After=2022-07-20T17:42:47.789-07:00[Asia/Shanghai]   #此断言匹配发生在指定日期时间之后的请求,ZonedDateTime dateTime=ZonedDateTime.now()获得
                        - Before=2022-09-18T21:26:26.711+08:00[Asia/Shanghai]   #此断言匹配发生在指定日期时间之前的请求
                        - Between=2022-07-20T21:26:26.711+08:00[Asia/Shanghai],2022-09-20T21:32:26.711+08:00[Asia/Shanghai] #此断言匹配发生在指定日期时间之间的请求
                        - Cookie=name,xiaobai   #Cookie路由断言工厂接受两个参数,Cookie名称和regexp(一个Java正则表达式)。此断言匹配具有给定名称且其值与正则表达式匹配的cookie
                        - Header=token,123456   #头路由断言工厂接受两个参数,头名称和regexp(一个Java正则表达式)。此断言与具有给定名称的头匹配,该头的值与正则表达式匹配。
                        - Host=**.bai*.com:*    #主机路由断言工厂接受一个参数:主机名模式列表。该模式是一个ant样式的模式。作为分隔符。此断言匹配与模式匹配的主机头
                        - Method=GET,POST       #方法路由断言工厂接受一个方法参数,该参数是一个或多个参数:要匹配的HTTP方法
                        - Query=username        #查询路由断言工厂接受两个参数:一个必需的param和一个可选的regexp(一个Java正则表达式)。
                        - RemoteAddr=192.168.1.1/24 #RemoteAddr路由断言工厂接受一个源列表(最小大小1),这些源是cidr符号(IPv4或IPv6)字符串,比如192.168.1.1/24(其中192.168.1.1是IP地址,24是子网掩码)。

8.2 断言总结

Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理

9. Filter过滤器工厂(重点)

9.1 概述

gateway里面的过滤器和Servlet里面的过滤器,功能差不多,路由过滤器可以用于修改进入Http请求和返回Http响应,过滤器只能指定路由进行使用.

9.2 分类

9.2.1 按生命周期分两种

pre 在业务逻辑之前

post 在业务逻辑之后

9.2.2 按种类分也是两种

GatewayFilter 需要配置某个路由,才能过滤。如果需要使用全局路由,需要配置Default Filters。

GlobalFilter 全局过滤器,不需要配置路由,系统初始化作用到所有路由上。

全局过滤器 统计请求次数 限流 token的校验 ip黑名单拦截

9.2.3官网过滤器

官方过滤器中单一过滤器有31个,全局过滤器有9个。

https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gatewayfilter-factories

9.3 自定义网关过滤器(重点)

9.3.1 自定义全局过滤器

全局过滤器的优点的初始化时默认挂到所有路由上,我们可以使用它来完成IP过滤,限流等功能

9.3.2 创建配置类GlobalFilterConfig

@Component
@Slf4j
public class GlobalFilterConfig implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        log.info("进入了我自己的全局过滤器");
        String token=exchange.getRequest().getQueryParams().getFirst("token");
       if(!StringUtils.hasText(token))
       {
           ServerHttpResponse response = exchange.getResponse();
           ObjectMapper mapper=new ObjectMapper();
           String str="没有权限不能访问";
           try {
               byte[] data = mapper.writeValueAsBytes(str);
               DataBuffer buffer = response.bufferFactory().wrap(data);
               response.setStatusCode(HttpStatus.UNAUTHORIZED);
               response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
               return response.writeWith(Mono.just(buffer));              
           }
           catch (Exception ex)
           {
               ex.printStackTrace();
           }
       }

        log.info("验证通过");
        return chain.filter(exchange);
    }
    /**
     * order越小 越先执行
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

9.3.1 访问测试

http://localhost/info

9.4 IP认证拦截实战

9.4.1创建IPGlobalFilter

@Component
@Slf4j
public class IPCheckFilter implements GlobalFilter, Ordered {
    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String ip = exchange.getRequest().getHeaders().getHost().getHostName();
        //这里写死了,只做演示
        if (ip.equals("localhost")) {
            //说明是黑名单里面的ip
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            Map<String, Object> map = new HashMap<>();
            map.put("code", HttpStatus.UNAUTHORIZED);
            map.put("msg", "非法访问");
            response.getHeaders().add("content-Type", "application/json;charset=UTF-8");
            ObjectMapper objectMapper = new ObjectMapper();
            byte[] bytes = objectMapper.writeValueAsBytes(map);
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
            return response.writeWith(Mono.just(buffer));
        }
        return chain.filter(exchange);
    }

    /**
     * 设置此过滤器的执行顺序
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 1;
    }
}

9.4.2 测试访问

localhost/info?token=hello

显示非法访问

10. 限流实战

10.1 什么是限流

网关可以做很多的事情,比如,限流,当我们的系统被频繁的请求的时候,就有可能将系统压垮,所以为了解决这个问题,需要在每一个微服务中做限流操作,但是如果有了网关,那么就可以在网关系统做限流,因为所有的请求都需要先通过网关系统才能路由到微服务中.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ML3L6wJn-1671972536377)(images/32.jpg)]

通俗的说,限流就是限制一段时间内,用户访问资源的次数,减轻服务器压力,限流大致分为两种:

1. IP限流(5s内同一个ip访问超过3次,则限制不让访问,过一段时间才可继续访问)

  1. 请求量限流(只要在一段时间内(窗口期),请求次数达到阀值,就直接拒绝后面来的访问了,过一段时间才可以继续访问)(粒度可以细化到一个api(url),一个服务)

10.2限流的算法–令牌桶

令牌桶算法是比较常见的限流算法之一,大概描述如下:

1)所有的请求在处理之前都需要拿到一个可用的令牌才会被处理;

2)根据限流大小,设置按照一定的速率往桶里添加令牌;

3)桶设置最大的放置令牌限制,当桶满时、新添加的令牌就被丢弃或者拒绝;

4)请求达到后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务逻辑之后,将令牌直接删除;

5)令牌桶有最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WmzYIxDQ-1671972536378)(images/33.jpg)]

10.3 Gateway结合redis实现请求量限流

Spring Cloud Gateway 已经内置了一个RequestRateLimiterGatewayFilterFactory,我们可以直接使用。

目前RequestRateLimiterGatewayFilterFactory的实现依赖于Redis,所以我们还要引入spring-boot-starter-data-redis-reactive。

10.3.1修改Pom

<!--限流要引入Redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

10.3.2定义KeyResolver

KeyResolver用于计算某一个类型的限流的KEY也就是说,可以通过KeyResolver来指定限流的Key。

@Configuration
public class RequestRateLimiterConfig {
    /**
     * IP限流
     * 把用户的IP作为限流的Key
     *
     * @return
     */
    @Bean
    @Primary // 相同类型的bean产生了,使用@Primary表示优先级高
    public KeyResolver hostAddrKeyResolver() {
        KeyResolver keyResolver=new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                String str=exchange.getRequest().getRemoteAddress().getHostName();
                System.out.println(str);
                return Mono.just(str);
            }
        };
        return keyResolver;
    }
    /**
     * 请求接口限流
     * 把请求的路径作为限流key
     *
     * @return
     */
    @Bean
    public KeyResolver apiKeyResolver() {       
       return exchange -> Mono.just(exchange.getRequest().getPath().value());
    }
}

10.3.3修改配置文件

server:
  port: 80
spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        -   id: user-service
            uri: lb://provider
            predicates:
              - Path=/info/**
            filters:
              - name: RequestRateLimiter
                args:
                  key-resolver: '#{@hostAddrKeyResolver}'
                  redis-rate-limiter.replenishRate: 1 #允许用户每秒处理多少个请求
                  redis-rate-limiter.burstCapacity: 3 #令牌桶的容量,允许在一秒钟内完成的最大请求数
  redis:
    host: localhost
    port: 6379
eureka:
  instance:
    instance-id: ${spring.application.name}:${server.port}
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://localhost:9000/eureka/
在上面的配置文件,配置了 redis的信息,并配置了RequestRateLimiter的限流过滤器,该
过滤器需要配置三个参数:
burstCapacity:令牌桶总容量。
replenishRate:令牌桶每秒填充平均速率。
key-resolver:用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。

10.3.4测试

 http://localhost/info?token=hello 快速访问后报429

#令牌桶的容量,允许在一秒钟内完成的最大请求数
redis:
host: localhost
port: 6379
eureka:
instance:
instance-id: s p r i n g . a p p l i c a t i o n . n a m e : {spring.application.name}: spring.application.name:{server.port}
prefer-ip-address: true
client:
service-url:
defaultZone: http://localhost:9000/eureka/


```properties
在上面的配置文件,配置了 redis的信息,并配置了RequestRateLimiter的限流过滤器,该
过滤器需要配置三个参数:
burstCapacity:令牌桶总容量。
replenishRate:令牌桶每秒填充平均速率。
key-resolver:用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。

10.3.4测试

 http://localhost/info?token=hello 快速访问后报429

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

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

相关文章

Unity URP 曲面细分

Unity URP 曲面细分 我终于变得不像我 文章目录Unity URP 曲面细分1 曲面细分与镶嵌1.1 外壳着色器 Hull Shader1.2 镶嵌器阶段 Tessellator1.3 域着色器阶段 Domain Shader2 具体实现2.2 不同的细分策略2.2.1 Flat Tessellation2.2.2 PN Tessellation2.2.3 Phone Tessellation…

Redis分布式锁的实现方式

目录一、分布式锁是什么1、获取锁2、释放锁二、代码实例上面代码存在锁误删问题&#xff1a;三、基于SETNX实现的分布式锁存在下面几个问题1、不可重入2、不可重试3、超时释放4、主从一致性四、Redisson实现分布式锁1、pom2、配置类3、测试类五、探索tryLock源码1、tryLock源码…

微软发布 Entity Framework EF Core 8 或 EF8

Entity Framework 现已被广泛使用&#xff0c;微软首席软件工程经理 Arthur Vickers 日前在一个在线社区会议上的发言。 Entity Framework Core 8.0&#xff08;也称为 EF Core 8 或 EF8&#xff09;的未来规划。EF Core 8 是 EF Core 7 之后的下一个版本&#xff0c;这将是一个…

链表的实现:无头单向非循环链表的实现

笔者在上篇博客书写了一个名为&#xff1a;链式存储之&#xff1a;链表的引出及其简介原文链接为&#xff1a;https://blog.csdn.net/weixin_64308540/article/details/128374876?spm1001.2014.3001.5501对于此篇博客&#xff0c;在一写出来&#xff0c;便引起了巨大反响&…

Golang 【basic_leaming】函数详解

阅读目录1、函数定义2、函数的调用3、函数参数4、函数返回值5、函数变量作用域全局变量局部变量6、函数类型与变量定义函数类型函数类型变量7、高阶函数函数作为参数函数作为返回值8、匿名函数和闭包匿名函数闭包闭包进阶示例1闭包进阶示例2闭包进阶示例39、defer 语句defer 执…

Windows-试用phpthink发现原来可这样快速搭建mysql、redis等环境、xdebug

一、前言 最近在简单学习 php 国人框架 phpthink&#xff0c;不得不说牛&#xff0c;我在 github 上既然搜不到此项目… 但是发现搭建依赖环境不会&#xff0c;于是百度一下&#xff0c;几乎都是各种集成工具什么宝塔、小皮面板等等。有固然是方便&#xff0c;但为什么其它语言…

DAY5 Recommended system cold startup problem

推荐系统的冷启动问题 推荐系统冷启动概念 ⽤户冷启动&#xff1a;如何为新⽤户做个性化推荐物品冷启动&#xff1a;如何将新物品推荐给⽤户&#xff08;协同过滤&#xff09;系统冷启动&#xff1a;⽤户冷启动物品冷启动本质是推荐系统依赖历史数据&#xff0c;没有历史数据⽆…

html+圣诞树

圣诞节 基督教纪念耶稣诞生的重要节日。亦称耶稣圣诞节、主降生节&#xff0c;天主教亦称耶稣圣诞瞻礼。耶稣诞生的日期&#xff0c;《圣经》并无记载。公元336年罗马教会开始在12月25日过此节。12月25日原是罗马帝国规定的太阳神诞辰。有人认为选择这天庆祝圣诞&#xff0c;是…

【学习打卡07】 可解释机器学习笔记之Shape+Lime代码实战

可解释机器学习笔记之ShapeLime代码实战 文章目录可解释机器学习笔记之ShapeLime代码实战基于Shapley值的可解释性分析使用Pytorch对MNIST分类可解释性分析使用shap的Deep Explainer进行可视化使用Pytorch对预训练ImageNet图像分类可解释性分析指定单个预测类别指定多个预测类别…

Elasticsearch 核心技术(一):Elasticsearch 安装、配置、运行(Windows 版)

❤️ 个人主页&#xff1a;水滴技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; &#x1f338; 订阅专栏&#xff1a;大数据核心技术从入门到精通 文章目录一、Elasticsearch 版本的选择二、下载 **Elasticsearch**三、安装 Elasticsear…

Springboot+Netty实现基于天翼物联网平台CTWing(AIOT)终端TCP协议(透传模式)-云服务端(IOT平台)

之前有文章用java实现了设备端和应用订阅端&#xff0c;那么我根据AIOT的协议也可以实现一个demo物联网平台端&#xff0c;这种简易的平台是实现自己搭建物联网平台的基础。 直接用代码 新建Springboot的maven项目&#xff0c;pom.xml文件导入依赖包&#xff08;用到了swagge…

UDP协议在Windows上使用示例

UDP(User Datagram Protocol&#xff0c;用户数据报协议)是无连接的&#xff0c;因此在两个进程通信前没有握手过程。UDP协议提供一种不可靠数据传送服务&#xff0c;也就是说&#xff0c;当进程将一个报文发送进UDP套接字时&#xff0c;UDP协议并不保证该报文将到达接收进程。…

过孔基础常识

过孔&#xff0c;一个绝大多数硬件工程师都听说过&#xff0c;但又并非真正了解的名词。了解的都知道&#xff0c;其在PCB板中其着至关重要的的作用。没有过孔的存在&#xff0c;很难画出一块完美的PCB板。所以呢&#xff0c;小编今日就带大家了解了解什么是过孔。 什么是过孔…

FCN代码及效果展示

1. 代码获取 代码地址: https://github.com/Le0v1n/ml_code/tree/main/Segmentation/FCN 2. 从头开始训练 2.1 测试平台 GPU&#xff1a;NVIDIA RTX 3070CPU: Intel I5-10400FRAM: 16GBOS: Windows 11Dataset: VOC2012Class num: 21(201)Batch size: 4Learning Rate: 0.1Ep…

嘉兴经开区第四届创新创业大赛总决赛成功举办

12月21日至12月22日&#xff0c;嘉兴经济技术开发区第四届创新创业大赛总决赛成功举办&#xff0c;经过激烈角逐最后共有10家企业分别获得大赛初创组和成长组的一二三等奖。 总决赛现场 嘉兴经开区第四届中国创新创业大赛于6月正式启动&#xff0c;陆续在嘉兴、成都、北京、西…

【详细学习SpringBoot源码之内嵌Tomcat启动原理分析编译部署Tomcat源码过程解析-9】

一.知识回顾 【0.SpringBoot专栏的相关文章都在这里哟&#xff0c;后续更多的文章内容可以点击查看】 【1.SpringBoot初识之Spring注解发展流程以及常用的Spring和SpringBoot注解】 【2.SpringBoot自动装配之SPI机制&SPI案例实操学习&SPI机制核心源码学习】 【3.详细学…

12-RabbitMq概述与工作模式深度剖析

MQ概述 MQ全称 Message Queue&#xff08;消息队列&#xff09;&#xff0c;是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信。 MQ 的优势 应用解耦&#xff1a;提高系统容错性和可维护性 异步提速&#xff1a;提升用户体验和系统吞吐量 削峰填谷&#xff1…

unity中使用代码接绘制三维模型

一 模型的构成 在三维世界中&#xff0c;绘制一个模型并不是什么很复杂的问题。只要知道了基本原理一切需求便迎刃而解。 如下图所示&#xff0c;任何模型都是由点线面构成的&#xff0c;而面的最小单位是三角形。 任何一个多边形的面&#xff0c;都是由多个三角形构成的。比…

Web前端105天-day64-HTML5_CORE

HTML5CORE04 目录 前言 一、复习 二、WebSocket 三、服务器搭建 四、聊天室 五、defineProperty 5.1.初识defineProperty 5.2.配置多个属性 5.3.可配置 5.4.赋值监听 5.5.练习 5.6.计算属性 总结 前言 HTML5CORE04学习开始 一、复习 SVG: 利用HTML的 DOM 来绘制图…

PCB贴片机如何送料?

1.常见的贴片机供料器四种形式 http://www.sz-bjzn.com/1547.html 2.模块化设计SMT贴片机送料器的操作方法 3.淘宝 https://item.taobao.com/item.htm?spma230r.1.14.98.33e41823OZ1zzn&id579043582781&ns1&abbucket20#detail 不错&#xff1a;https://item.tao…