详解springcloud gateway工作原理、断言、filter、uri、id、全局跨域、globalfilter等以及关键源码实现

news2025/4/24 11:06:00
1.gateway概念
  1. 网关就是当前微服务项目的"统一入口"
  2. 程序中的网关就是当前微服务项目对外界开放的统一入口
  3. 所有外界的请求都需要先经过网关才能访问到我们的程序
  4. 提供了统一入口之后,方便对所有请求进行统一的检查和管理
2. 网关的主要功能
  • 将所有请求统一经过网关
  • 网关可以对这些请求进行检查
  • 网关方便记录所有请求的日志
  • 网关可以统一将所有请求路由到正确的模块\服务上

“路由"的近义词就是"分配”
在这里插入图片描述

3. 工作原理

在这里插入图片描述
在这里插入图片描述
Spring Gateway的工作原理基于路由、断言(Predicates)和过滤器(Filters)三大核心概念:

  • ‌路由(Route):定义了请求的转发规则,包括目标URL和匹配条件。
  • 断言(Predicates):用于匹配HTTP请求的各种条件,如路径、头信息、参数等。只有匹配成功的请求才会被路由处理。
  • 过滤器(Filters):在请求处理前后执行特定的逻辑,例如权限校验、日志记录
4. 配置和使用示例
spring:
  cloud:
    gateway:
      routes:
        - id: myroute
          uri: http://example.com
          predicates:
            - Path=/api/**
          filters:
            - AddRequestHeader=X-Request-ID, \${requestId}

这个配置定义了一个路由,所有路径以/api/开头的请求都会被转发到http://example.com,并且在请求头中添加一个X-Request-ID字段‌

springcloud gateway中配置uri有3种方式:

  • ws(websocket)方式: uri: ws://localhost:9000
  • http方式: uri: http://localhost:8130/
  • lb(注册中心中服务名字)方式: uri: lb://brilliance-consumer

springcloud gatetway命名规范

能被gateway的lb方式识别到的命名规则为:

   "[a-zA-Z]([a-zA-Z]|\\d|\\+|\\.|-)*:.*"

如果名字中有非*“a-zA-Z:.”*规则字符或者使用“_”,则会报错

5.网关gateway routes的组成

1. id:必须唯一

2. predicates(断言)
在这里插入图片描述
关键类源码分析:

package org.springframework.cloud.gateway.handler.predicate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.style.ToStringCreator;
import org.springframework.http.server.PathContainer;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPattern.PathMatchInfo;
import org.springframework.web.util.pattern.PathPatternParser;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_MATCHED_PATH_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_MATCHED_PATH_ROUTE_ID_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_PATH_CONTAINER_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.putUriTemplateVariables;
import static org.springframework.http.server.PathContainer.parsePath;

/**
 * @author Spencer Gibb
 * @author Dhawal Kapil
 */
public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<PathRoutePredicateFactory.Config> {

    private static final Log log = LogFactory.getLog(PathRoutePredicateFactory.class);

    private static final String MATCH_TRAILING_SLASH = "matchTrailingSlash";

    private PathPatternParser pathPatternParser = new PathPatternParser();

    public PathRoutePredicateFactory() {
       super(Config.class);
    }

    private static void traceMatch(String prefix, Object desired, Object actual, boolean match) {
       if (log.isTraceEnabled()) {
          String message = String.format("%s \"%s\" %s against value \"%s\"", prefix, desired,
                match ? "matches" : "does not match", actual);
          log.trace(message);
       }
    }

    public void setPathPatternParser(PathPatternParser pathPatternParser) {
       this.pathPatternParser = pathPatternParser;
    }

    @Override
    public List<String> shortcutFieldOrder() {
       return Arrays.asList("patterns", MATCH_TRAILING_SLASH);
    }

    @Override
    public ShortcutType shortcutType() {
       return ShortcutType.GATHER_LIST_TAIL_FLAG;
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
       final ArrayList<PathPattern> pathPatterns = new ArrayList<>();
       synchronized (this.pathPatternParser) {
          pathPatternParser.setMatchOptionalTrailingSeparator(config.isMatchTrailingSlash());
          config.getPatterns().forEach(pattern -> {
             PathPattern pathPattern = this.pathPatternParser.parse(pattern);
             pathPatterns.add(pathPattern);
          });
       }
       return new GatewayPredicate() {
          @Override
          public boolean test(ServerWebExchange exchange) {
             PathContainer path = (PathContainer) exchange.getAttributes().computeIfAbsent(
                   GATEWAY_PREDICATE_PATH_CONTAINER_ATTR,
                   s -> parsePath(exchange.getRequest().getURI().getRawPath()));

             PathPattern match = null;
             for (int i = 0; i < pathPatterns.size(); i++) {
                PathPattern pathPattern = pathPatterns.get(i);
                if (pathPattern.matches(path)) {
                   match = pathPattern;
                   break;
                }
             }

             if (match != null) {
                traceMatch("Pattern", match.getPatternString(), path, true);
                PathMatchInfo pathMatchInfo = match.matchAndExtract(path);
                putUriTemplateVariables(exchange, pathMatchInfo.getUriVariables());
                exchange.getAttributes().put(GATEWAY_PREDICATE_MATCHED_PATH_ATTR, match.getPatternString());
                String routeId = (String) exchange.getAttributes().get(GATEWAY_PREDICATE_ROUTE_ATTR);
                if (routeId != null) {
                   // populated in RoutePredicateHandlerMapping
                   exchange.getAttributes().put(GATEWAY_PREDICATE_MATCHED_PATH_ROUTE_ID_ATTR, routeId);
                }
                return true;
             }
             else {
                traceMatch("Pattern", config.getPatterns(), path, false);
                return false;
             }
          }

          @Override
          public Object getConfig() {
             return config;
          }

          @Override
          public String toString() {
             return String.format("Paths: %s, match trailing slash: %b", config.getPatterns(),
                   config.isMatchTrailingSlash());
          }
       };
    }

    @Validated
    public static class Config {

       private List<String> patterns = new ArrayList<>();

       private boolean matchTrailingSlash = true;

       public List<String> getPatterns() {
          return patterns;
       }

       public Config setPatterns(List<String> patterns) {
          this.patterns = patterns;
          return this;
       }

       /**
        * @deprecated use {@link #isMatchTrailingSlash()}
        */
       @Deprecated
       public boolean isMatchOptionalTrailingSeparator() {
          return isMatchTrailingSlash();
       }

       /**
        * @deprecated use {@link #setMatchTrailingSlash(boolean)}
        */
       @Deprecated
       public Config setMatchOptionalTrailingSeparator(boolean matchOptionalTrailingSeparator) {
          setMatchTrailingSlash(matchOptionalTrailingSeparator);
          return this;
       }

       public boolean isMatchTrailingSlash() {
          return matchTrailingSlash;
       }

       public Config setMatchTrailingSlash(boolean matchTrailingSlash) {
          this.matchTrailingSlash = matchTrailingSlash;
          return this;
       }

       @Override
       public String toString() {
          return new ToStringCreator(this).append("patterns", patterns)
                .append(MATCH_TRAILING_SLASH, matchTrailingSlash).toString();
       }

    }

}
package org.springframework.cloud.gateway.handler.predicate;

import java.util.function.Consumer;
import java.util.function.Predicate;
import org.springframework.cloud.gateway.handler.AsyncPredicate;
import org.springframework.cloud.gateway.support.Configurable;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.cloud.gateway.support.ShortcutConfigurable;
import org.springframework.web.server.ServerWebExchange;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.toAsyncPredicate;

/**
 * @author Spencer Gibb
 */
@FunctionalInterface
public interface RoutePredicateFactory<C> extends ShortcutConfigurable, Configurable<C> {

    /**
     * Pattern key.
     */
    String PATTERN_KEY = "pattern";

    // useful for javadsl
    default Predicate<ServerWebExchange> apply(Consumer<C> consumer) {
       C config = newConfig();
       consumer.accept(config);
       beforeApply(config);
       return apply(config);
    }

    default AsyncPredicate<ServerWebExchange> applyAsync(Consumer<C> consumer) {
       C config = newConfig();
       consumer.accept(config);
       beforeApply(config);
       return applyAsync(config);
    }

    default Class<C> getConfigClass() {
       throw new UnsupportedOperationException("getConfigClass() not implemented");
    }

    @Override
    default C newConfig() {
       throw new UnsupportedOperationException("newConfig() not implemented");
    }

    default void beforeApply(C config) {
    }

    Predicate<ServerWebExchange> apply(C config);

    default AsyncPredicate<ServerWebExchange> applyAsync(C config) {
       return toAsyncPredicate(apply(config));
    }

    default String name() {
       return NameUtils.normalizeRoutePredicateName(getClass());
    }

}

自定义Vip路由断言工厂实现

package com.wemedia.gateway.config;

import jakarta.validation.constraints.NotEmpty;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.CookieRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * 自定义Vip路由断言工厂
 */
@Component
public class VipRoutePredicateFactory extends AbstractRoutePredicateFactory<VipRoutePredicateFactory.Config> {

    public VipRoutePredicateFactory(){
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("param","value");
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                //localhost/search?q=hhh&user=jackma
                ServerHttpRequest request = serverWebExchange.getRequest();
                String first = request.getQueryParams().getFirst(config.param);
                return StringUtils.hasText(first)&&first.equals(config.value);
            }
        };
    }


    @Validated
    public static class Config {
        @NotEmpty
        private String value;
        @NotEmpty
        private String param;

        public String getParam() {
            return param;
        }

        public void setParam(String param) {
            this.param = param;
        }


        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }

    }
}

在这里插入代码片

配置Vip断言
在这里插入图片描述
3. Filter(过滤器)
在这里插入图片描述
3.1 rewritePath(路径重写)
在这里插入图片描述
在这里插入图片描述

  • 添加RewritePath过滤器,重写原先路径/readDb,在访问路径前面追加/api/order/readDb,不然网关无法直接访问/readDb;
  • 添加AddReponseHeader过滤器,给响应头增加参数X-Response-ABC,值为123

3.2 默认过滤器filter:
在这里插入图片描述
增加默认过滤器default-filters, 参数Add-ReponseHeader=X-Reponse-Abc ,值为123 给所有服务的相应头中

3.3 全局过滤器GlobalFilter

package com.wemedia.gateway.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 实现响应时间全局过滤器
 */
@Component
@Slf4j
public class RTGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        String uri = request.getURI().toString();
        long start=System.currentTimeMillis();
        log.info("请求【{}】开始时间:{}",uri,start );
        //================以上是前置逻辑==============

        Mono<Void> filter = chain.filter(exchange).doFinally((result) -> {
            //================后置逻辑
            long end = System.currentTimeMillis();
            log.info("请求【{}】结束时间:{},耗时:{}ms", uri, end, end - start);
        });
        return filter;
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

过滤器filter 列表:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.4 自定义过滤器工厂

关键源码分析

package org.springframework.cloud.gateway.filter.factory;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.web.server.ServerWebExchange;

import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator;

/**
 * @author Spencer Gibb
 */
public class AddResponseHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {

    @Override
    public GatewayFilter apply(NameValueConfig config) {
       return new GatewayFilter() {
          @Override
          public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
             return chain.filter(exchange).then(Mono.fromRunnable(() -> addHeader(exchange, config)));
          }

          @Override
          public String toString() {
             return filterToStringCreator(AddResponseHeaderGatewayFilterFactory.this)
                   .append(config.getName(), config.getValue()).toString();
          }
       };
    }

    void addHeader(ServerWebExchange exchange, NameValueConfig config) {
       final String value = ServerWebExchangeUtils.expand(exchange, config.getValue());
       HttpHeaders headers = exchange.getResponse().getHeaders();
       // if response has been commited, no more response headers will bee added.
       if (!exchange.getResponse().isCommitted()) {
          headers.add(config.getName(), value);
       }
    }

}

1.实现一次性token自定义过滤器工厂

package com.wemedia.gateway.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.UUID;

/**
 * 实现一次性令牌的自定义过滤器工场
 */
@Component
@Slf4j
public class OnceTokenGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                //每次响应之前,添加一个一次性令牌,支持uuid,jwt等格式

                return chain.filter(exchange).then(Mono.fromRunnable(()->{
                    ServerHttpResponse response = exchange.getResponse();
                    HttpHeaders headers = response.getHeaders();
                    String value = config.getValue();
                    if("uuid".equalsIgnoreCase(value)){
                        value = UUID.randomUUID().toString();
                    }

                    if("jwt".equalsIgnoreCase(value)){
                        value="";
                    }


                    headers.add(config.getName(),value);
                }));
            }
        };
    }
}

2.配置一次性token过滤器
在这里插入图片描述
3.访问api响应结果如下:
在这里插入图片描述
3.5 实现全局跨域
在这里插入图片描述

  • 解决单机跨域方法:直接在每个controller上增加注解@CrossOrigin

在这里插入图片描述

  • 在分布式系统上解决跨域问题,在gateway上统一处理跨域问题
    配置全局跨域:
    在这里插入图片描述
    运行结果如下,增加了跨域处理:
    在这里插入图片描述

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

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

相关文章

C++面向对象特性之继承篇

C语音是面向过程的语言&#xff0c;而C在其之上多了面向对象的特性&#xff0c;面向对象三大特性:封装性、继承性、多态性。今天主包来讲讲自己学到的关于C继承特性的知识。 一、继承是什么 继承是提高代码复用的一种重要手段。正如C的模版、泛型编程等等都是为了实现代码复用…

【AI News | 20250423】每日AI进展

AI Repos 1、suna Suna是一款完全开源的AI助手&#xff0c;旨在通过自然对话帮助用户轻松完成现实世界的任务。它作为您的数字伙伴&#xff0c;提供研究、数据分析和日常问题解决等功能&#xff0c;并结合强大的能力与直观的界面&#xff0c;理解您的需求并交付成果。Suna的工…

【学习准备】算法和开发知识大纲

1 缘起 今年&#xff08;2025年&#xff09;的职业升级结果&#xff1a;不通过。没办法升职加薪了。 需要开始完善学习&#xff0c;以应对不同的发展趋势&#xff0c;为了督促自己学习&#xff0c;梳理出相关学习大纲。 分为算法和开发两部分。 算法&#xff0c;包括基础算法和…

第七篇:linux之基本权限、进程管理、系统服务

第七篇&#xff1a;linux之基本权限、进程管理、系统服务 文章目录 第七篇&#xff1a;linux之基本权限、进程管理、系统服务一、基本权限1、什么是权限&#xff1f;2、为什么要有权限&#xff1f;3、权限与用户之间的关系&#xff1f;4、权限对应的数字含义5、使用chmod设定权…

爬虫案例-爬取某企数据

文章目录 1、准备要爬取企业名称数据表2、爬取代码3、查看效果 1、准备要爬取企业名称数据表 企业名称绍兴市袍江王新国家庭农场绍兴市郑杜粮油专业合作社绍兴市越城区兴华家庭农场绍兴市越城区锐意家庭农场绍兴市越城区青甸畈家庭农场绍兴市袍江王新国家庭农场绍兴市袍江月明…

学习笔记—C++—string(一)

目录 string 为什么学习string的类 string类的常用接口 string类对象的常见构造 string类对象的访问及遍历操作 operator[] 迭代器 范围for auto 迭代器&#xff08;二&#xff09; string类对象的容量操作 size,length,max_size,capacity,clear基本用法 reserve 提…

GPLT-2025年第十届团体程序设计天梯赛总决赛题解(共计266分)

今天偶然发现天梯赛的代码还保存着&#xff0c;于是决定写下这篇题解&#xff0c;也算是复盘一下了 L1本来是打算写的稳妥点&#xff0c;最后在L1-6又想省时间&#xff0c;又忘记了insert&#xff0c;replace这些方法怎么用&#xff0c;也不想花时间写一个文件测试&#xff0c…

MySQL数据库精研之旅第十期:打造高效联合查询的实战宝典(一)

专栏&#xff1a;MySQL数据库成长记 个人主页&#xff1a;手握风云 目录 一、简介 1.1. 为什么要使用联合查询 1.2. 多表联合查询时的计算 1.3. 示例 二、内连接 2.1. 语法 2.2. 示例 三、外连接 4.1. 语法 4.2. 示例 一、简介 1.1. 为什么要使用联合查询 一次查询需…

15.FineReport动态展示需要的列

1.首先连接自带的sqlite数据库&#xff0c;具体方法参考下面的链接 点击查看连接sqlite数据库 2.文件 – 新建普通报表 3.新建数据库查询 4.查询自带的销售明细表 5.把数据添加到格子中&#xff0c;并设置边框颜色等格式 6.查询新的数据集&#xff1a;column 7.点笔 8.全部添…

Windows云主机远程连接提示“出现了内部错误”

今天有人反馈说有个服务器突然连不上了&#xff0c;让我看下什么问题&#xff0c;我根据他给的账号密码试了下发现提示“出现了内部错误”&#xff0c;然后就是一通排查 先是查看安全组&#xff0c;没发现特别的问题&#xff0c;因为也没有调过这块的配置 然后通过控制台登录进…

最新扣子(Coze)案例教程:Excel数据生成统计图表,自动清洗数据+转换可视化图表+零代码,完全免费教程

大家好&#xff0c;我是斜杠君。 知识星球群有同学和我说每天的工作涉及很多数据表的重复操作&#xff0c;想学习Excel数据表通过大模型自动转数据图片的功能。 今天斜杠君就带大家一起搭建一个智能体&#xff0c;以一个销售行业数据为例&#xff0c;可以快速实现自动清洗Exc…

如何安装Visio(win10)

首先下载下面这些文件 HomeStudent2021Retail.img officedeploymenttool_17531-20046.exe office中文语言包.exe 确保这些文件都在一个文件夹内&#xff08;我已经上传这些资源&#xff0c;这些资源都是官网下载的&#xff09; 官网资源下载教程 1.下载Office镜像&#xff0…

建筑安全员 A 证与 C 证:差异决定职业方向

在建筑行业的职业发展道路上&#xff0c;安全员 A 证和 C 证就像两条不同的岔路&#xff0c;它们之间的差异&#xff0c;在很大程度上决定了从业者的职业方向。 从证书性质和用途来看&#xff0c;A 证是从业资格证书&#xff0c;更像是一把开启安全管理高层岗位的 “金钥匙”。…

(19)VTK C++开发示例 --- 分隔文本读取器

文章目录 1. 概述2. CMake链接VTK3. main.cpp文件4. 演示效果 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;VTK开发 &#x1f448; 1. 概述 本例采用坐标和法线&#xff08;x y z nx ny nz&#xff09;的纯文本文件&#xff0c;并将它们读入vtkPolyData并显示…

Redis从入门到实战先导篇

前言&#xff1a;本节内容包括虚拟机VMware的安装&#xff0c;Linux系统的配置&#xff0c;FinalShell的下载与配置&#xff0c;Redis与其桌面客户端的安装指导,便于后续黑马Redis从入门到实战的课程学习 目录 主要内容 0.相关资源 1.VMware安装 2.Linux与CentOS安装 3.Fi…

JavaScript 防抖和节流

方法一&#xff1a;使用lodash库的debounce方法 方法二&#xff1a;手写防抖函数 function debounce(fn,t){// 1.声明一个定时器变量 因为需要多次赋值 使用let声明let timer // 返回一个匿名函数return function(){if(timer){// 如果定时器存在清除之前的定时器 clearTimeout(…

Spring Boot 启动时 `converting PropertySource ... to ...` 日志详解

Spring Boot 启动时 converting PropertySource ... to ... 日志详解 1. 日志背景 在 Spring Boot 应用启动过程中&#xff0c;会加载并处理多种 配置源&#xff08;如 application.properties、系统环境变量、命令行参数等&#xff09;。这些配置源会被封装为 PropertySource…

分割数据集中.json格式标签转化成伪彩图图像

一、前言 图像分割任务中&#xff0c;分割数据集的转换和表示方式对于模型训练至关重要。目前主要有两种常见的分割结果表示方法&#xff1a; 1. 转化为TXT文件 这种方式通常使用一系列的点&#xff08;坐标&#xff09;来表示图像中每个像素的类别标签。每个点通常包含像素…

Linux之彻底掌握防火墙-----安全管理详解

—— 小 峰 编 程 目录&#xff1a; 一、防火墙作用 二、防火墙分类 1、逻辑上划分&#xff1a;大体分为 主机防火墙 和 网络防火墙 2、物理上划分&#xff1a; 硬件防火墙 和 软件防火墙 三、硬件防火墙 四、软件防火墙 五、iptables 1、iptables的介绍 2、netfilter/…

# 构建和训练一个简单的CBOW词嵌入模型

构建和训练一个简单的CBOW词嵌入模型 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;词嵌入是一种将词汇映射到连续向量空间的技术&#xff0c;这些向量能够捕捉词汇之间的语义关系。在这篇文章中&#xff0c;我们将构建和训练一个简单的Continuous Bag of Words…