spring-cloud微服务gateway

news2025/3/16 4:12:22

核心部分:routes(路由), predicates(断言),filters(过滤器)

pom依赖

 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-gateway</artifactId>
 </dependency>
 
 <dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 </dependency>

yml配置网关

server:
  port: 8087
spring:
  application:
    name: gateway-nacos
  cloud:
    gateway:
      routes: #路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
        - id: product_route  #当前路由的标识,要求唯-
          uri: http://localhost:8086 #请求要转发到的地址
          order: 1 #路由的优先级,数字越小级别越高
          predicates: #断言(就是路由转发要满足的条件)
            - Path=/product-service/** #当请求路径满足Path指定的规则时,才进行路由转发
              #http://localhost:8087/product-service/product/9  路由器到⬇
              #http://localhost:8086/product-service/product/9
          filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
            - StripPrefix=1 #转发之前去掉1层路径
              ##http://localhost:8086/product/9

yml注册到nacos配置网关

server:
  port: 8087
spring:
  application:
    name: gateway-nacos
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.11.47:18848
        username: nacos
        password: nacos

    gateway:
      routes: #路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
        - id: product_route  #当前路由的标识,要求唯-
          uri: lb://product_naocs #lb指的是从nacos中按名称获取微服务,并遵循负载均衡策略
          order: 1 #路由的优先级,数字越小级别越高
          predicates: #断言(就是路由转发要满足的条件)
            - Path=/product-service/** #当请求路径满足Path指定的规则时,才进行路由转发
          filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
            - StripPrefix=1 #转发之前去掉1层路径,

yml配置网关(约定大于配置的方式,一般不用这样的配置),例如访问http://localhost:8087/product-service/product/9 ,中的product-service为服务的名字

server:
  port: 8087
spring:
  application:
    name: gateway-nacos
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.11.47:18848
        username: nacos
        password: nacos

    gateway:
      discovery:
        locator:
          enabled: true    #是否启动自动识别nacos服务(约定大于配置)

注意:若要使用自定义配置,则“不能开启注册中心的路由功能”,否则自定义的策略会失,设置中心路由功能为false

server:
 port: 8087
spring:
 application:
   name: gateway-nacos
 cloud:
   nacos:
     discovery:
       server-addr: 192.168.11.47:18848
       username: nacos
       password: nacos
   gateway:
     discovery:
       locator:
         enabled: false  #是否启动自动识别nacos服务(约定大于配置)

查看网关内置断言官网文档,如果用上时间可以设置获取使用方法:ZonedDateTime.now(),获取

内置断言例子,日期2024-01-20T17:42:47都可以访问,超过时间访问返回404

server:
  port: 8087
spring:
  application:
    name: gateway-nacos
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.11.47:18848
        username: nacos
        password: nacos

    gateway:
      routes: #路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
        - id: product_route #当前路由的标识,要求唯-
          uri: http://localhost:8086 #请求要转发到的地址
          order: 1 #路由的优先级,数字越小级别越高
          predicates: #断言(就是路由转发要满足的条件)
            - Path=/product-service/** #当请求路径满足Path指定的规则时,才进行路由转发
            - Before=2024-08-20T17:42:47.789-07:00[America/Denver]
          filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
            - StripPrefix=1 #转发之前去掉1层路径,

        - id: stock-nacos #当前路由的标识,要求唯-
          uri: http://localhost:8085 #请求要转发到的地址
          order: 1 #路由的优先级,数字越小级别越高
          predicates: #断言(就是路由转发要满足的条件)
            - Path=/stock-nacos/** #当请求路径满足Path指定的规则时,才进行路由转发
            - Before=2024-08-20T17:42:47.789-07:00[America/Denver]
          filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
            - StripPrefix=1 #转发之前去掉1层路径,

内部断言的类名是有断言前缀和后缀组成如下

Path+RoutePredicateFactory
RemoteAddr+RoutePredicateFactory
RemoteAddr+RoutePredicateFactory
Header+RoutePredicateFactory

  • 基于远程地址的断言工厂

  • RemoteAddrRoutePredicateFactory:接收一个IP地址段,判断请求主机地址是否在地址段中
- RemoteAddr=192.168.1.1/24
  • 基于Cookie的断言工厂

  • CookieRoutePredicateFactory:接收两个参数,cookie 名字和一个正则表达式。 判断请求cookie是否具有给定名称且值与正则表达式匹配。
- RemoteAddr=chocolate, ch.
  • 基于Header的断言工厂

  • HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式,判断请求Header是否具有给定名称且值与正则表达式匹配。
- Header=X-Request-Id,\d+
  • 基于Host的断言工

  • HostRoutePredicateFactory:接收一个参数,主机名模式。判断请求的Host是否满足匹配规则
- Host=**.testhost.org
基于Method请求方法的
  • 基于Method请求方法的断言工厂

  • MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配
 - Method=GET
  1. 基于Path请求路径的断言工厂

  2. PathRoutePredicateFactory:接收一个参数,判断请求的URI部分是否满足路径规则。
#多个路径使用逗号,隔开
- Path=/foo/{segment}1 , /product/add
  • 基于Query请求参数的断言工厂

  • QueryRoutePredicateFactory:接收两个参数,请求param和正则表达式,判断请求参数是否具有给定名称且值与正则表达式匹配,
- Query=baz, ba.

基于Path请求路径的断言工厂

自定义路由断言工厂

可以查看路径路由的断言工厂,选择AbstractRoutePredicateFactory按Ctrl+H既可以显示出全部的路由断言工厂,可以复制一份修改成自定义的断言工厂

在这里插入图片描述

自定义路由断言工厂需要继承 AbstadRoutepredicatefacdoy类,重写 ap)y方法的透辑,在apy方法中可以通过 excthange.geiequest) 拿到 serneiHpReque 对象,从而可以获取到清求的参数、请求方式、请求头等信息

1. 必须spring组件 bean
2. 类必须加上RoutePredicateFactory作为结尾(底层的处理的约定大于配置自定会读取到的)
3. 必须继承AbstractRoutePredicateFactory
4. 必须声明静态内部类 声明属性来接收 配置文件中对应的断言的信息
5. 需要结合shortcutFieldOrder进行绑定
6. 通过apply进行逻辑判断 true就是匹配成功 false匹配失败

自定义路由断言工厂类

package com.test.gate.config;

import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
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;

/**
 * @Description:
 * @Author: xu
 * @Data: 2024-2024/4/11-21
 * @Version: V1.0
 */
@Component
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {

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

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

    public Predicate<ServerWebExchange> apply(final Config config) {
        return new GatewayPredicate() {
            public boolean test(ServerWebExchange exchange) {
                if (config.getParam().equals("zhangSan")) {
                    return true;
                }
                return false;
            }

            public Object getConfig() {
                return config;
            }

            public String toString() {
                return String.format("Query: param=%s regexp=%s", config.getParam());
            }
        };
    }

    @Validated
    public static class Config {

        private String param;

        public Config() {
        }

        public String getParam() {
            return this.param;
        }

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

    }
}

yml配置(如果一个路由里面有多个断言条件是且的关系,都需要满足才跳转uri)

server:
  port: 8087
spring:
  application:
    name: gateway-nacos
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.11.47:18848
        username: nacos
        password: nacos

    gateway:
#      discovery:
#        locator:
#          enabled: true    #是否启动自动识别nacos服务(约定大于配置)

      routes: #路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
        - id: product_route #当前路由的标识,要求唯-
          uri: http://localhost:8086 #请求要转发到的地址
          order: 1 #路由的优先级,数字越小级别越高
          predicates: #断言(就是路由转发要满足的条件)
            - Path=/product-service/**,/ddd/s #当请求路径满足Path指定的规则时,才进行路由转发
            - Before=2024-08-20T17:42:47.789-07:00[America/Denver]
            - CheckAuth=zhangSan1
          filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
            - StripPrefix=1 #转发之前去掉1层路径,

查看网关各种局部过滤器官网

自定义网关过滤器和自定义断言都全部类似

继承AbstractNameValueGatewavFilterFactory日我们的自定义名称必须要以GatewavFiterFactorv结尾并交给spring管理

package com.test.gate.config;

import com.alibaba.nacos.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * @Description:
 * @Author: xu
 * @Data: 2024-2024/4/12-11
 * @Version: V1.0
 */
@Component

public class CheckAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CheckAuthGatewayFilterFactory.Config> {
    private static Logger log = LoggerFactory.getLogger(CheckAuthGatewayFilterFactory.class);

    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            log.info("调用checkAuthGatewayFilterFactory==="
                    + config.getName());

            String name = exchange.getRequest().getQueryParams().getFirst("name");
            if (StringUtils.isNotBlank(name)) {
                if (config.getName().equals(name)) {
                    chain.filter(exchange);
                } else {
                    //返回404
                    exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
                    exchange.getResponse().setComplete();
                }
                //1 正常请求
                chain.filter(exchange);
            }
            return null;
        };
    }

    public static class Config {
        private String name;

        public Config() {
        }

        public String getName() {
            return this.name;
        }

        public void setName(String prefix) {
            this.name = name;
        }
    }
}
server:
  port: 8087
spring:
  application:
    name: gateway-nacos
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.11.47:18848
        username: nacos
        password: nacos

    gateway:
#      discovery:
#        locator:
#          enabled: true    #是否启动自动识别nacos服务(约定大于配置)

      routes: #路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
        - id: product_route #当前路由的标识,要求唯-
          uri: http://localhost:8086 #请求要转发到的地址
          order: 1 #路由的优先级,数字越小级别越高
          predicates: #断言(就是路由转发要满足的条件)
            - Path=/product-service/**,/ddd/s #当请求路径满足Path指定的规则时,才进行路由转发
            - Before=2024-08-20T17:42:47.789-07:00[America/Denver]
            - CheckAuth=zhangSan1
          filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
            - StripPrefix=1 #转发之前去掉1层路径,
            - CheckAuth=lisi

全局过滤器(Global Filters)配置

在这里插入图片描述

自定义全局过滤器(Global Filters)配置类(一般都是实现认证或者授权,或者做日记记录,不需要在配置文件做任何配置)

package com.test.gate.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @Description:
 * @Author: xu
 * @Data: 2024-2024/4/12-20
 * @Version: V1.0
 */
@Component
public class LogGlobalFilter implements GlobalFilter {
    private static Logger log = LoggerFactory.getLogger(LogGlobalFilter.class);

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

        //做业务处理,授权或者日记记录
        log.info(exchange.getRequest().getPath().value());
        return chain.filter(exchange);
    }
}

要启用 Reactor Netty 访问日志,请设置-Dreactor,netty.http,server.accessLogEnabled=true,它必须是 Java 系统属性,而不是 Spring Boot 属性。如果是jar包启动,就将网关打包成jar包,如下运行

java -jar gateway.jar -Dreactor,netty.http,server.accessLogEnabled=true

idea配置网关日记打印,在vm配置 -Dreactor.netty.http.server.accessLogEnabled=true

在这里插入图片描述

将网关日志记录全部输出到日志文件。以下示例创建一个Logback.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 按天滚动的文件输出 -->
    <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>G:\temptemptemp\gatewaylog\logfile.log</file> <!-- 修改为你想要保存日志文件的路径 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>G:\temptemptemp\gatewaylog\logfile.%d{yyyy-MM-dd}.log
            </fileNamePattern> <!-- 指定按日期滚动的文件名格式 -->
            <maxHistory>30</maxHistory> <!-- 保留最多30天的历史日志文件 -->
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>


    <!-- 异步日志输出 -->
    <appender name="async" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="ROLLING_FILE"/> <!-- 将异步 appender 链接到文件输出 -->
    </appender>

    <!-- 记录器配置 -->
    <logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
        <appender-ref ref="async"/> <!-- 将异步 appender 应用于特定的日志记录器 -->
        <appender-ref ref="STDOUT"/> <!-- 控制台输出 -->
    </logger>

    <!-- 根日志级别设置 -->
    <root level="info">
        <appender-ref ref="STDOUT"/> <!-- 控制台输出 -->
        <appender-ref ref="ROLLING_FILE"/> <!-- 将按天滚动的文件输出器添加到根输出器中 -->
    </root>

</configuration>

Gateway跨域配置(CORS Configuration),网关官网跨域配置

方法一:yml配置文件配置跨域

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':  #运行跨域访问的资源
            allowedOrigins: "https://docs.spring.io"  #跨域允许来源
            allowedMethods:
            - GET
            - POST

方法二:通过配置类设置跨域(注意UrlBasedCorsConfigurationSource 导入的包是import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource)

package com.test.gate.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;

/**
 * @Description:
 * @Author: xu
 * @Data: 2024-2024/4/12-22
 * @Version: V1.0
 */
@Configuration
public class CorsConfig {

    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);

        return new CorsWebFilter(source);
    }
}

网关限流整合sentinel官网

pom.xml添加依赖整合sentinel,和官网配置的有以下不一样是因为spring-cloud-alibaba-sentinel-gateway这个依赖比adapter依赖多了SentinelSCGAutoConfiguration自定注入例如很多需要的bean

<!--sentinel整台gateway  以前版本使用adapter-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!--sentinel的依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

配置文件配置sentinel

#   配置sentinel
    sentinel:
      transport:
        dashboard: 127.0.0.1:8858   #sentiel的dashboard地址

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

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

相关文章

Oauth2.1第三方授权前后端分离实现

前言 Spring Cloud 整合 Spring Security Oauth2 请看我上一篇文章 在当今的数字化时代&#xff0c;随着微服务架构的流行和前后端分离技术的广泛应用&#xff0c;如何实现安全、高效的用户认证与授权成为了开发者们面临的重要挑战。Spring Cloud与Spring Security OAuth2作为J…

小程序商城和微商城的区别

移动互联网电商发展迅速&#xff0c;各种商城系统的类型越来越多&#xff0c;人们选择要从多方面考量再进行评估&#xff0c;选择过程变得困难了很多&#xff0c;比如现在火热的微商城和小程序商城&#xff0c;很多人都不太能分清楚。今天&#xff0c;我们就一起来看看这两种商…

BCLinux8U6系统部署oceanbase分布式数据库社区版之三、分布式数据库部署

本文是在完成步骤一、准备 OBD 中控机&#xff0c;步骤二3台数据库服务器准备后&#xff0c;正式开始oceanbase分布式数据库安装。 前序步骤&#xff1a;BCLinux8U6系统部署oceanbase分布式数据库社区版之一、准备 OBD 中控机 BCLinux8U6系统部署oceanbase分布式数据库社区版…

请求头包含“boundary=----WebKitFormBoundary”的request抓包

对于请求头包含“boundary----WebKitFormBoundary”&#xff0c;不能直接使用request.post请求&#xff0c;这类请求是文件上传请求。 s common_login(name, password) # 获取浏览器对象url archive_url /XXX# 这里先定义一个fields参数&#xff0c;格式为你可能需要一个包…

Linux yum搭建Keepalived,2 台机器都有虚拟 IP 问题

文章目录 Keepalived 搭建一、安装二、keepalived配置1、配置文件详解global_defs模块参数vrrp_instance模块参数vrrp_script模块参数 2、修改配置文件3、启动服务 Tips:1️⃣问题&#xff1a;两台机器上面都有VIP的情况2️⃣完整配置文件 Keepalived 搭建 服务IP服务器Keepal…

微信小程序wx.getLocation 真机调试不出现隐私弹窗

在小程序的开发过程中&#xff0c;首页中包含要获取用户地理位置的功能&#xff0c;所以在这里的onLoad&#xff08;&#xff09;中调用了wx.getLocation()&#xff0c;模拟调试时一切正常&#xff0c;但到了真机环境中就隐私框就不再弹出&#xff0c;并且出现了报错&#xff0…

ubuntu16.04安装Eclipse C/C++

1.安装 JDK 官网源码安装 首先打开JDK官网&#xff0c;JDK1.8的下载网址为&#xff1a;https://www.oracle.com/cn/java/technologies/downloads/#java8-windows&#xff0c;进入到网址如下图所示&#xff1a; 向下滑动到 JDK1.8的下载界面&#xff0c;如下图所示&#xff1a…

【软考】UML中的图之用例图

目录 1. 说明2. 建模2.1 说明2.2 语境建模2.3 需求建模 3. 图示4. 组成部分 1. 说明 1.用例图&#xff08;Use Case Diagram&#xff09;。2.展现了一组用例、参与者&#xff08;Actor&#xff09;以及它们之间的关系。3.用例图通常包括以下的内容&#xff1a;用例、参与者、用…

SpringBoot项目创建及简单使用

目录 一.SpringBoot项目 1.1SpringBoot的介绍 1.2SpringBoot优点 二.SpringBoot项目的创建 三.注意点 一.SpringBoot项目 1.1SpringBoot的介绍 Spring是为了简化Java程序而开发的&#xff0c;那么SpringBoot则是为了简化Spring程序的。 Spring 框架&#xff1a; Spring…

Python高质量函数编写指南

The Ultimate Guide to Writing Functions 1.视频 https://www.youtube.com/watch?vyatgY4NpZXE 2.代码 https://github.com/ArjanCodes/2022-funcguide Python高质量函数编写指南 1. 一次做好一件事 from dataclasses import dataclass from datetime import datetimedatacl…

如何解决selenium无头浏览器访问页面失败问题!!

无头浏览器简介 无头浏览器&#xff08;Headless browser&#xff09;是一种没有图形用户界面&#xff08;GUI&#xff09;的网络浏览器。它可以在后台运行&#xff0c;并通过编程接口进行控制和操作&#xff0c;而不需要显示界面。通常&#xff0c;传统的浏览器如 Chrome、Fi…

生产控制台厂家的技术要求深度解读

随着科技的不断进步和工业的快速发展&#xff0c;生产控制台在现代化生产线中的作用日益凸显。生产控制台作为生产线的“大脑”&#xff0c;要求厂家不仅具备高超的制造技术&#xff0c;还需对技术要求有深入的理解和掌握。本文将对生产控制台厂家的技术要求进行浅析。 生产控制…

vmware安装ubuntu-18.04系统

一、软件下载 百度网盘&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1fK2kygRdSux1Sr1sOKOtJQ 提取码&#xff1a;twsb 二、安装ubuntu系统 1、把ubuntu-18.04的压缩包下载下来&#xff0c;并且解压 2、打开vmware软件&#xff0c;点击文件-打开 3、选择我们刚刚解…

4.15 网络编程

思维导图 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <semaphore.h> #inclu…

白盒测试之分支-条件覆盖

白盒测试之分支-条件覆盖&#xff08;蓝桥课学习笔记&#xff09; 实验介绍 分支&#xff08;判定&#xff09;覆盖是设计一定量的测试用例使程序中的每个判断语句的真假分支都得到覆盖&#xff0c;但是分支覆盖不能保证判断语句中每个条件的真、假分支都得到覆盖。那么&…

Linux的学习之路:5、粘滞位与vim

摘要 这里主要是把上章没说完的权限的粘滞位说一下&#xff0c;然后就是vim的一些操作。 目录 摘要 一、粘滞位 二、权限总结 三、vim的基本概念 四、vim的基本操作 五、vim正常模式命令集 1、插入模式 2、从插入模式切换为命令模式 3、移动光标 4、删除文字 5、复…

详解UART通信协议以及FPGA实现

文章目录 一、UART概述二、UART协议帧格式2.1 波特率2.2 奇校验ODD2.3 偶校验EVEN 三、UART接收器设计3.1 接收时序图3.2 Verilog代码3.3 仿真文件测试3.4 仿真结果3.5 上版测试 四、UART发送器设计4.1 发送时序图4.2 Verilog代码4.3 仿真文件测试4.4 仿真结果4.5 上板测试 五、…

温湿度传感器(DHT11)以及光照强度传感器(BH1750)的使用

前言 对于一些单片机类的环境检测或者智能家居小项目中&#xff0c;温湿度传感器&#xff08;DHT11&#xff09;以及光照强度传感器&#xff08;BH1750&#xff09;往往是必不可少的两个外设&#xff0c;下面我们来剖析这两个外设的原理&#xff0c;以及使用。 1. 温湿度传感…

仿真服务器介绍及应用

仿真服务器是一种高性能的计算设备&#xff0c;专门用于运行复杂的仿真软件和处理大量的计算任务。 仿真服务器通常具备以下特点&#xff1a; 1. 高性能硬件配置&#xff1a;为了满足仿真软件对计算能力的要求&#xff0c;仿真服务器通常配备高性能的CPU、大量的内存以及高速的…

Ollama教程——使用langchain:ollama与langchain的强强联合

相关文章: Ollama教程——入门&#xff1a;开启本地大型语言模型开发之旅 Ollama教程——模型&#xff1a;如何将模型高效导入到ollama框架 Ollama教程——兼容OpenAI API&#xff1a;高效利用兼容OpenAI的API进行AI项目开发 Ollama教程——使用langchain&#xff1a;ollama与…