实用篇-Gateway网关

news2024/11/18 15:42:57

前面学的Nacos是对内负载均衡,现在学的Gateway网关是对外负载均衡和校验,不冲突

一、网关的作用

网关功能:

1、身份认证和权限校验

2、服务路由、负载均衡

3、请求限流

在SpringCloud中有两个组件可以实现网关,分别是gateway、zuul

Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于spriing5中提供的WebFlux,属于响应式编程(非阻塞式)的实现,具备更好的性能

我们都会使用SpringCloudGateway

二、网关的快速入门

网关路由可以配置的内容包括如下

路由id: 路由唯一标识

uri: 路由目的地,支持lb和http两种

predicates: 路由断言,判断请求是否符合要求,符合则转发到路由目的地

filters: 路由过滤器,处理请求或响应

搭建网关服务的步骤如下

第一步: 由于网关是一个服务,所以需要在cloud-demo总项目中新建一个模块,模块名为gateway

第二步: 在gateway微服务项目的pom.xml修改为如下

<?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>cloud-demo</artifactId>
        <groupId>cn.itcast.demo</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gateway</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

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

        <!--网关gateway依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

</project>

第三步: 在gateway微服务项目的src/main/java目录下新建cn.itcast.gateway.GatewayApplication类,写入如下

package cn.itcast.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author 35238
 * @date 2023/5/28 0028 14:06
 */

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

第四步: 在gateway微服务项目的src/main/resources目录下新建File,File名为application.yml,写入如下

server:
  port: 10010 # 服务端口
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 自定义网关路由规则,多个规则就用-
        - id: user-service # 路由标示,必须唯一
          uri: lb://UserService # 路由的目标地址
          predicates:
            - Path=/user/** # 路由断言,判断路径是否以/user开头,如果是则符合
        - id: order-service
          uri: lb://OrderService
          predicates:
            - Path=/order/**

第五步。测试(先确保你的nacos已经启动),先运行GatewayApplication类,然后重启OrderApplication、UserApplication、UserApplication2服务

 

浏览器访问: http://localhost:10010/user/1,注意要http://localhost:10010/user/开头,因为我们在第四步指定了路由断言

可以发现,我们并没有在gateway微服务项目写任何业务代码,但是却能用gateway微服务项目的路径访问到数据,原因就是网关路由,把gateway微服务项目的请求路由到我们指定的其他微服务去了,我们访问这个gateway微服务项目,实际访问的是OrderService和UserService微服务

 

 三、路由断言工厂

路由断言工厂Route Predicate Factory

网关路由可以配置的内容包括如下

路由id: 路由唯一标识

uri: 路由目的地,支持lb和http两种

predicates: 路由断言,判断请求是否符合要求,符合则转发到路由目的地

filters: 路由过滤器,处理请求或响应

接下来,就重点学习predicates的配置

我们在上面快速入门的application.yml配置文件中写的断言规则只是字符串,这些字符串会被断言工厂(Predicate Factory)读取并处理,转变为路由判断的条件

例如 Path=/user/**是按照路径匹配,这个规则是由
org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的

像这样的断言工厂在SpringCloudGateway还有几十个

spring提供了11种基本的Predicate工厂,如下表。为了避免md语法冲突,我在下表写的※其实就是*

名称

说明

示例

After

是某个时间点后的请求

- After=2037-01-20T17:42:47.789-07:00[America/Denver]

Before

是某个时间点之前的请求

- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]

Between

是某两个时间点之前的请求

- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]

Cookie

请求必须包含某些cookie

- Cookie=chocolate, ch.p

Header

请求必须包含某些header

- Header=X-Request-Id, \d+

Host

请求必须是访问某个host (域名)

- Host=**.somehost.org,※※.anotherhost.org

Method

请求方式必须是指定方式

- Method=GET,POST

Path

请求路径必须符合指定规则,多个路径的话逗号隔开,只要符合其中一个就算符合

- Path=/red/{segment},/blue/**

Query

请求参数必须包含指定参数

- Query=name, Jack或者- Query=name

RemoteAddr

请求者的ip必须是指定范围

- RemoteAddr=192.168.1.1/24

Weight

权重处理

不会写也没事,spring官网有提供12种断言工厂的示例

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

演示如下,在刚刚快速入门的gateway微服务项目的application.yml里面添加如下

# 演示After断言工厂,也就是用户必须在亚洲上海时区2037-01-20之后访问,才算符合规则,才会让用户去请求路由到达OrderService服务
- After=2037-01-20T17:42:47.789-07:00[America/Denver] #明显我们现在的时间是不符合要求的,所以等下演示会报404

然后重启GatewayApplication服务,浏览器访问http://localhost:10010/order/102

四、路由过滤工厂

路由的过滤器配置,路由过滤器GatewayFilter

网关路由可以配置的内容包括如下

路由id: 路由唯一标识

uri: 路由目的地,支持lb和http两种

predicates: 路由断言,判断请求是否符合要求,符合则转发到路由目的地

filters: 路由过滤器,处理请求或响应

接下来,就重点学习filters的配置 

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理。不仅可以对请求做处理,还可以对响应做处理,下面是流程图

spring提供了37种不同的路由过滤工厂,如下表 

名称

说明

AddRequestHeader

给当前请求添加一个请求头

RemoveRequestHeader

移除请求中的一个请求头

AddResponseHeader

给响应结果中添加一个响应头

RemoveResponseHeader

从响应结果中移除有一个响应头

RequestRateLimiter

限制请求的流量

......

不会写也没事,spring官网有提供37种过滤器工厂的示例

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

案例:

演示如下

第一步: 在刚刚快速入门的gateway微服务项目的application.yml里面添加如下。

表示给所有进入UserService服务的请求添加一个请求头KEKE:keke is you god

server:
  port: 10010 # 服务端口
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 自定义网关路由规则,多个规则就用-
        - id: user-service # 路由标示,必须唯一
          uri: lb://UserService # 路由的目标地址
          predicates:
            - Path=/user/** # 路由断言,判断路径是否以/user开头,如果是则符合
          filters:
            - AddRequestHeader=KEKE,keke is you god
        - id: order-service
          uri: lb://OrderService
          predicates:
            - Path=/order/**
            - Before=2037-01-20T17:42:47.789-07:00[America/Denver]
          

然后重启GatewayApplication服务 

第二步: 由于请求UserService服务时,网关给路径自动追加了请求头参数,所以我们需要去user-service微服务的src/main/java/cn.itcast.user/web目录的UserController类里面稍微修改一下请求,加一个接收参数的参数

@GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id,@RequestHeader(value = "KEKE",required = false) String keke) {
        System.out.println("获取了请求头" + keke);
        return userService.queryById(id);
    }

然后重启UserService服务 

第三步: 测试。浏览器访问http://localhost:10010/user/1,访问之后回到终端看一下UserService的控制台日志信息,看有没有打印sout那个语句

思考:

我们只是在gateway微服务项目的application.yml配置里面给访问UserService服务(user-service微服务项目)的请求添加了请求头,要是需要给所有请求微服务项目的请求都加上请求头,那岂不是在这个application.yml里面给所以相关微服务都写一遍这个代码,太麻烦了 

解决:

默认过滤器,如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下(和routes同一级)

 #演示默认过滤器,会对所有的路由请求都生效
      default-filters:
        - AddRequestHeader=KEKE,keke is you god #格式: - AddRequestHeader=key,value

测试:

注释掉之前在user-service模块下配置文件中刚才配置的路由过滤器。然后重启GatewayApplication服务,浏览器访问http://localhost:10010/user/2,访问之后回到终端看一下UserService的日志信息,看有没有打印sout那个语句 

server:
  port: 10010 # 服务端口
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 自定义网关路由规则,多个规则就用-
        - id: user-service # 路由标示,必须唯一
          uri: lb://UserService # 路由的目标地址
          predicates:
            - Path=/user/** # 路由断言,判断路径是否以/user开头,如果是则符合
#          filters:
#            - AddRequestHeader=KEKE,keke is you god
        - id: order-service
          uri: lb://OrderService
          predicates:
            - Path=/order/**
            - Before=2037-01-20T17:42:47.789-07:00[America/Denver]
      #演示默认过滤器,会对所有的路由请求都生效
      default-filters:
        - AddRequestHeader=KEKE,keke is you god #格式: - AddRequestHeader=key,value

五、全局过滤器

全局过滤器GlobalFilter的作用是拦截所有进入网关的请求和微服务响应,与GatewayFilter默认过滤器的作用一样

上面刚学的默认过滤器虽然可以作用于所有进入网关的请求和微服务响应,但是默认过滤器是通过配置的方式来定义的,配置的仅仅是参数,过滤器的业务逻辑是无法控制的,由spring写死的,功能有限。但是,如果某些业务比较复杂,例如请求进来后端,但是我想知道是谁发起的,身份是什么,有没有权限访问我,那么这些额外是功能就需要自定义自己来写,而全局过滤器GlobalFilter就能实现这个,特点是可以自定义功能

如何才能使用全局过滤器GlobalFilter,我们只需要实现GlobalFilter接口即可,GlobalFilter接口的方法如下

Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

//exchange: 请求上下文,里面可以获取Request、Response等信息
//chain: 过滤器队列,用来把请求委托给下一个过滤器,也就是放行,交给下一个过滤器
//Mono<Void>: 返回值
//filter: 方法名

案例:

定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件 

条件1: 参数中是否有authorization

条件2: authorization参数值是否为admin

如果同时满足则放行,否则拦截

具体实现如下

第一步: 在gateway微服务项目的src/main/java/cn.itcast.gateway目录新建AuthorizeFilter类,写入如下 

package cn.itcast.gateway;

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

import java.lang.annotation.Annotation;


@Order(-1)//过滤器执行的前后顺序,值越小越先执行,可能你的同事也定义有过滤器,所以这个可以用数字设置自己这个过滤器先执行还是后执行
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //第一步:获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        //第二步:获取参数中的authorization
        String auth = params.getFirst("authorization");
        //判断参数是否等于admin
        if("admin".equals(auth)){
            //是 放行
           return chain.filter(exchange);
        }
        //响应一个未认证的状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        //否 拦截
        return exchange.getResponse().setComplete();
    }


    @Override
    public int getOrder() {
        return -1; //order的值越小,过滤器优先级越高
    }
}

第二步: 重启GatewayApplication服务,分别在浏览器访问http://localhost:10010/user/2,

http://localhost:10010/user/2?authorization=admin

六、过滤器链执行顺序

在上面的 '全局过滤器' 的第一步里面,我们初步使用了@Order注解来指定order值(我上一节通过实现Ordered接口去指定order的值,注解和实现接口两种方式都可以),使得我们写的 'AuthorizeFilter过滤器类' 的优先级最高,不被覆盖(当然也没有谁来覆盖,因为就只定义过这个过滤器)

当请求路由之后,会将 '当前路由过滤器'、'DefaultFilter'、'GlobalFilter',合并到一个过滤器链(集合)中,然后对这些过滤器进行排序,然后依次执行每个过滤器

过滤器执行顺序:

1、每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前

2、'GlobalFilter' 通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定order值大小

3、'路由过滤器'、'defaultFilter' 通过spring来指定order值,默认是按照声明顺序从1递增

从上图中,我们不难发现,'路由过滤器' 和 'defaultFilter过滤器' 的order值是有可能同样的,那这时候这俩order值不就一样了吗,这还怎么判断谁优先,另外由于'GlobalFilter过滤器'是可以通过@Order注解直接指定order值,那么此时三种过滤器的order值可能就一模一样,那靠order还怎么判断谁优先级 

结论:

1、同一种过滤器中,如果order值越小,那么优先级越高

2、不同过滤器中,如果order值越小,那么优先级越高

3、不同过滤器中,如果order值相同,那么优先级为 'defaultFilter过滤器' > '路由过滤器' > 'GlobalFilter过滤器'

七、网关的cors跨域配置

跨域问题处理

在微服务项目中,所有的请求都必须先进入网关,然后由网关路由到某个具体的微服务,也就是跨域请求实际上不需要在每个微服务里面都处理一遍,仅仅在网关处理即可,所以我们需要学习如何在网关,来处理跨域请求

网关是基于Netflix来实现的

跨域也就是域名不一致,主要包括域名不同、域名相同但端口不同。

跨域问题: 浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题

解决方案: CORS(浏览器会不断询问服务器: 你让不让别人跨域访问你)

上图倒数第三行的*表示允许所有请求头跨域

上图的最后一行的360000是有限期,作用是减少性能损耗(损耗来源: 浏览器不断询问服务器),当时间超过这个值,就表名跨域请求的有效期过了,浏览器将不再向服务器发起询问,而是直接放行

上图的'[/**]'表示拦截所有请求,凡是进入网关的请求都会进行跨域处理

演示跨域并解决跨域,如下

第一步: 打开前端页面并向服务器发送请求,模拟跨域请求,8090端口启动它

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<div>
</div>
</body>

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
     axios.get("http://localhost:10010/user/1?authorization=admin").then(function (resp){
         console.log(resp.data);
     }).catch(function (err){
         console.log(err);
     })
</script>

</html>

 

第二步: 在网关微服务那里,写入处理跨域的代码

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

能够正常访问并且拿到数据 

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

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

相关文章

SpringBoot相比于Spring的优点(自动配置和依赖管理)

自动配置 例子见真章 我们先看一下我们Spring整合Druid的过程&#xff0c;以及我们使用SpringBoot整合Druid的过程我们就知道我们SpringBoot的好处了。 Spring方式 Spring方式分为两种&#xff0c;第一种就是我们使用xml进行整合&#xff0c;第二种就是使用我们注解进行简化…

ansble

ansble概述 Ansible是一款自动化运维工具&#xff0c;基于Python开发&#xff0c;具有批量系统配置,批量程序部署, 批量运行命令等功能。 Ansible的很多模块在执行时都会先判断目标节点是否要执行任务&#xff0c;所以&#xff0c;可以放心大胆地让Ansible去执行任务&#xf…

汇编的各种指令(数据搬移、移位、位运算、算数、比较、跳转、特殊功能寄存器、单寄存器、多寄存器、栈指针指令)

1.汇编指令的格式 2.数据搬移指令---mov mvn 3.移位操作指令 4.位运算操作指令 5.算数运算操作指令 6.比较指令---cmp 7.跳转指令 例子&#xff1a; 8.特殊功能寄存器指令 内存操作指令 9.单寄存操作指令 10.多寄存操作指令 11.栈指针操作指令 例子&#xff1a; 保存现场&…

线程池是如何实现线程复用的?

线程池里面采用了生产者消费者的模式&#xff0c;来实现线程复用。生产者消费者模型&#xff0c;其实就是通过一个中间容器来解耦生产者和消费者的任务处理过程。 生产者不断生产任务保存到容器&#xff0c;消费者不断从容器中消费任务。在线程池里面&#xff0c;因为需要保证工…

gRPC初体验

一、gRPC简介 1、RPC是远程过程调用的简称&#xff0c;在分布式系统中&#xff0c;客户端可以像调用本地对象一样调用远程机器上服务端对象&#xff0c;用于系统的垂直拆分&#xff0c;常见的JAVA RPC框架有JAVA自带的RMI、基于Http的Hessian、阿里基于TCP的Dubbo、淘宝基于TC…

二叉树题目:路径总和 III

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;路径总和 III 出处&#xff1a;437. 路径总和 III 难度 5 级 题目描述 要求 给你二叉树的根结点 root \textt…

VS2022 打包WPF安装程序最新教程(图文详解)

文章目录 前言一、安装打包Installer插件1、单独安装2、VS中在线安装二、使用步骤1、创建安装项目2、安装项目主界面3、添加项目输出4、添加快捷方式图标5、添加卸载项目a、新建项目b、添加项目输出c、创建快捷方式6、给快捷方式添加图标a、在Resource文件夹中添加图标文件b、选…

通过内网穿透实现在无公网IP下,Windows远程连接MongoDB数据库

文章目录 前言1. 安装数据库2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射2.3 测试随机公网地址远程连接 3. 配置固定TCP端口地址3.1 保留一个固定的公网TCP端口地址3.2 配置固定公网TCP端口地址3.3 测试固定地址公网远程访问 前言 MongoDB是一个基于分布式文件存储的数…

shopee收货方式有哪些

Shopee 是一家电子商务平台&#xff0c;提供多种不同的收货方式&#xff0c;具体的选项可能会根据您所在的地理位置和商品的类型而有所不同。以下是一些常见的 Shopee 收货方式&#xff1a; 1、快递配送&#xff1a;这是最常见的收货方式&#xff0c;您可以选择让商家使用物流…

开关时的瞬态高电压突变冲击--输入滤波电容可能引起的问题

在开关控制电路中&#xff0c;会出现开关瞬间产生一个高的电压冲击&#xff0c;可能会导致外设的保护机制&#xff0c;甚至损坏。 很多用电装置都由适配器通过一段比较长的电源线供电,在用电装置一端有电源滤波电容。随着产品向小型化,便携化方向发展&#xff0c;陶瓷电容在电源…

服务器安装Pytorch深度学习环境

最近要开始准备毕设啦&#xff0c;决定写一篇关于如何在实验室服务器安装Pytorch深度学习环境的博客&#xff0c;因为我使用的基本是Pytorch所以如果是使用Tensorflow的小伙伴就可以滑走啦~ 服务器统一安装过程 创建文件夹&#xff1a; mkdir miniconda(文件夹名) 转入新建文…

民乐社区关工委举办敬老爱老关爱活动

2023年10月27日&#xff0c;由华润银行支持&#xff0c;民乐社区关工委组织开展的敬老爱老关爱活动走进高乐亦嘉-光明社会福利院和中国文化名人大营救纪念馆&#xff0c;民乐社区关工委主任孙旗开&#xff0c;副主任常满彦、郭娜英、刘昕带领27名中老年人参与了本次活动。 参观…

国家数据局正式揭牌,隐私计算助力数据要素流通共享

2023年10月25日&#xff0c;国家数据局在京正式揭牌。根据中共中央、国务院印发的《党和国家机构改革方案》&#xff0c;国家数据局负责协调推进数据基础制度建设&#xff0c;统筹数据资源整合共享和开发利用&#xff0c;统筹推进数字中国、数字经济、数字社会规划和建设等。 多…

运维监控系统PIGOSS BSM 基础版重磅发布,永久免费

中小企业运维现状 当前多数中小型企业IT运维现状基本分为两部分&#xff1a; 1. 依靠传统的人工运维方式&#xff0c;无有效的监控工具辅助&#xff0c;导致故障发现不及时&#xff0c; 无法实时掌握IT运行状态。 2. 使用开源工具&#xff1a;开源工具因没有专业的售后技术…

如何在 Mac 上切换用户?

如果您想与其他人共享您的 Mac&#xff0c;创建一个独立于您的个人帐户的新用户帐户可能会有所帮助。然而&#xff0c;不利的一面是&#xff0c;时不时地在不同的用户帐户之间切换可能是一件耗时的事情。幸运的是&#xff0c;我创建了本指南&#xff0c;解释如何在 Mac 上快速切…

Android NDK开发详解之将 NDK 与其他构建系统配合使用

Android NDK开发详解之将 NDK 与其他构建系统配合使用 概览Autoconf非 Autoconf make 项目 注意&#xff1a;本页介绍的内容适用于 NDK r19 及更高版本。如果您使用的是旧版 NDK&#xff0c;请考虑进行升级。如果无法升级&#xff0c;请参阅独立工具链指南。 NDK 提供对 ndk-bu…

在安装和配置DVWA渗透测试环境遇到的报错问题

安装环境 前面的安装我参考的这个博主&#xff1a;渗透测试漏洞平台DVWA环境安装搭建及初级SQL注入-CSDN博客 修改bug 1.首先十分感谢提供帮助的博主&#xff0c;搭建DVWA Web渗透测试靶场_dvwa 白屏-CSDN博客&#xff0c;解决了我大多数问题&#xff0c;报错如下&#xff1…

[毕设记录]@开题调研:CAAI资源

发现这里面有些东西还是不错的 https://www.caai.cn/index.php?s/home/article/index/id/53.html其中我主要需要用到大模型技术白皮书

Wi-Fi 6和5G 在应用场景上的区别

在工作领域&#xff0c;我们经常会面临两个选择&#xff0c;场景的解决方案是要用5G还是WiFi 6&#xff0c;其实判断并不困难&#xff0c;但我们仍然还是从理论概念上区分一下。 文章目录 什么是Wi-Fi 6什么是5GWi-Fi 6和5G 的区别区别一&#xff1a;覆盖范围区别二&#xff1…

【Azure】存储服务:Azure 的存储账户

文章目录 一、前提知识&#xff08;建议了解&#xff09;二、介绍 Azure 存储帐户三、使用 Microsoft Azure 门户创建存储帐户 一、前提知识&#xff08;建议了解&#xff09; 在每一个云厂商中&#xff0c;都有自身的云存储&#xff0c;也有根据不同功能进行区分的不同类型的…