Docker + Nacos + Spring Cloud Gateway 实现简单的动态路由配置修改和动态路由发现

news2024/11/26 12:45:09

1.环境准备

1.1 拉取Nacos Docker镜像

从Docker Hub拉取Nacos镜像:

docker pull nacos/nacos-server:v2.4.0

在这里插入图片描述

1.2 生成密钥

你可以使用命令行工具生成一个不少于32位的密钥。以下是使用 OpenSSL 生成 32 字节密钥的示例:

openssl rand -base64 32

在这里插入图片描述

1.3 启动Nacos容器

使用以下命令启动一个Nacos容器:

docker run -d --name nacos-server \
  -e MODE=standalone \
  -e NACOS_AUTH_ENABLE=true \
  -e NACOS_AUTH_TOKEN=jXd7Gp8MYxJVwK/Qj3d6h5XPwTRrqJL/vope5yHd8DA= \
  -e NACOS_AUTH_IDENTITY_KEY=your-identity-key \
  -e NACOS_AUTH_IDENTITY_VALUE=your-identity-value \
  -e NACOS_AUTH_ENABLE_USERAGENT_AUTHWHITE=true \
  -p 8848:8848 \
  -p 9848:9848 \
  nacos/nacos-server:v2.4.0

NACOS_AUTH_ENABLE=true 启用Nacos的身份验证。

NACOS_AUTH_TOKEN的值为正确的 Base64 编码字符串,长度不少于 32 字节。

NACOS_AUTH_IDENTITY_KEY=your-identity-key 设置身份验证的key。

NACOS_AUTH_IDENTITY_VALUE=your-identity-value 设置身份验证的value。

NACOS_AUTH_ENABLE_USERAGENT_AUTHWHITE=true 启用User Agent白名单,绕过一些安全检查。

在这里插入图片描述

1.4 访问Nacos控制台

在Nacos容器启动后,可以通过浏览器访问Nacos控制台,URL如下:
在这里插入图片描述
说明:初始化密码。

1.5 创建命名空间

在这里插入图片描述

操作:点击命名空间,新建命名空间。
在这里插入图片描述
说明:自己随便定义命名空间,随便描述。

在这里插入图片描述
说明:创建结果。

1.6 创建配置

1.7 创建gateway.yaml

hello: abc

在这里插入图片描述

说明:用来测试是否读取到配置信息,点击发布即创建。

1.8 创建gateway-dynamic-routes.yaml

spring:
  cloud:
    gateway:
      routes:
        - id: service-route
          uri: lb://producer-service-1
          predicates:
            - Path=/service/**
          filters:
            - StripPrefix=1

说明:

请求匹配:当客户端发送一个HTTP请求时,Spring Cloud Gateway会根据定义的路由进行匹配。它会首先检查请求路径是否匹配Path=/service/**这个谓词。

前缀移除:如果请求路径匹配,StripPrefix=1过滤器会移除路径的第一个部分。例如,客户端请求/service/produce会被转换为/produce`。

请求转发:经过前缀移除后,Gateway会根据uri配置将请求转发到producer-service-1服务。由于lb://前缀的存在,Gateway会通过服务注册中心(如Eureka或Consul)找到producer-service-1服务的一个实例,并将请求转发给该实例。

在这里插入图片描述

说明:测试动态路由配置,点击发布即创建。

1.9 创建结果

在这里插入图片描述

说明:自定义的命名空间下创建两个配置文件。

2.项目结构

在这里插入图片描述

说明:使用两个服务,代表不同的路由,模拟在没有重启网关服务的条件下实现,通过Nacos修改配置文件实现网关路由的配置更新与发现。

2.1 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 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>3.3.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.example</groupId>
    <artifactId>spring_nacos_gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>producer_service_1</module>
        <module>producer_service_2</module>
    </modules>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

说明:两个提供者的父类配置文件,网关模块不需要父类。

2.2 gateway模块

在这里插入图片描述

2.2.1 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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>22</java.version>
        <spring-boot.version>3.3.2</spring-boot.version>
        <spring-cloud.version>2023.0.1</spring-cloud.version>
        <spring-cloud-alibaba.version>2023.0.1.2</spring-cloud-alibaba.version>
    </properties>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <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>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>2.4.0-BETA</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.5.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba.nacos/logback-adapter -->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>logback-adapter</artifactId>
            <version>1.1.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.1.0-alpha1</version>
        </dependency>

        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</artifactId>
            <version>1.57.2</version>
        </dependency>
    </dependencies>
</project>

2.2.2 nacos-logback14.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="LOG_DIR" value="logs"/>
    <property name="APP_NAME" value="gateway-service"/>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_DIR}/${APP_NAME}.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_DIR}/${APP_NAME}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="FILE"/>
    </root>
</configuration>

2.2.3 bootstrap.yml

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.186.77:8848
        username: nacos
        password: 123456
      config:
        server-addr: 192.168.186.77:8848
        file-extension: yaml
        group: DEFAULT_GROUP
        namespace: 94507d25-b8c3-4e5c-a8ef-b02b8ce4c0fb #命名空间的ID
        encode: UTF-8
        username: nacos
        password: 123456
    gateway:
      discovery:
        locator:
          enabled: true # 启用动态路由发现功能。
          lower-case-service-id: true #将服务ID转换为小写
  config:
    import:
      - nacos:gateway.yaml #配置文件1
      - nacos:gateway-dynamic-routes.yaml #配置文件2
server:
  port: 8003

说明:通过以上配置,Spring Cloud Gateway将会自动根据Nacos中的注册服务动态生成路由。例如,如果有一个服务 order-service 注册到Nacos,Gateway将自动为这个服务生成一个路由规则,将所有以 /order-service/** 开头的请求转发到该服务。

2.2.4 GatewayApplication.java

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

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

    @Bean
    @LoadBalanced //启动请求的负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

2.2.5 ConfigController.java

package org.example.gateway;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
    @Value("${hello:false}")
    private String Hello;

    @RequestMapping("/get")
    public String get() {
        return Hello;
    }
}

2.3 producer_service_1模块

在这里插入图片描述

2.3.1 pom.xml

<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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>spring_nacos_gateway</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>producer_service_1</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2023.0.1.2</version>
        </dependency>
    </dependencies>
</project>

2.3.2 application.yml

server:
  port: 8001
spring:
  application:
    name: producer-service-1
  cloud:
    nacos:
      discovery:
        server-addr: http://192.168.186.77:8848
        username: nacos
        password: 123456

2.3.3 ProducerApplication01.java

package org.example.producer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

2.3.4 ProducerController.java

package org.example.producer.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProducerController {
    @GetMapping("/produce")
    public String produce() {
        return "服务提供者1号";
    }
}

2.4 producer_service_2模块

在这里插入图片描述

说明:实际上,该部分跟producer_service_1结构完全一样,只是改了一下启动类名还有端口配置。

2.4.1 pom.xml

<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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>spring_nacos_gateway</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>producer_service_2</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2023.0.1.2</version>
        </dependency>
    </dependencies>
</project>

2.4.2 application.yml

server:
  port: 8002
spring:
  application:
    name: producer-service-2
  cloud:
    nacos:
      discovery:
        server-addr: http://192.168.186.77:8848
        username: nacos
        password: 123456

说明:端口跟服务名同producer_service_1模块不一样。

2.4.3 ProducerApplication02.java

package org.example.producer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

2.4.4 ProducerController.java

package org.example.producer.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProducerController {
    @GetMapping("/produce")
    public String produce() {
        return "服务提供者2号";
    }
}

说明:启动类同producer_service_1模块不一样,方便区分。

3.测试验证

3.1 测试读取配置文件(gateway.yaml)

在这里插入图片描述

3.2 动态路由发现测试

在这里插入图片描述
解释:Spring Cloud Gateway将会自动根据Nacos中的注册服务动态生成路由。例如,如果有一个服务 order-service 注册到Nacos,Gateway将自动为这个服务生成一个路由规则,将所有以 /order-service/** 开头的请求转发到该服务,本案例的服务是producer-service-2,自行类比·。

3.2 手动修改配置重新发布(gateway-dynamic-routes.yaml)

未修改前:

在这里插入图片描述

访问:

在这里插入图片描述

修改:

在这里插入图片描述

访问:

在这里插入图片描述

4.总结

静态路由:是在配置文件或配置中心中手动定义并且不会自动改变的路由。管理员需要手动添加或更新路由配置。

动态路由:是指路由条目根据实时的网络状态或服务注册信息自动更新。使用服务发现机制,路由器能够自动感知到服务的变化,并调整路由表。

静态路由 vs 动态路由

特点静态路由动态路由
配置方式手动配置自动配置
维护复杂度
适应网络变化
使用场景小型、固定网络大型、动态变化网络
依赖性低(不依赖服务注册中心)高(依赖服务注册中心)

​ 在Nacos中,静态路由适用于固定的、手动管理的路由配置,而动态路由适用于自动化、高效管理的动态变化的服务路由配置。根据实际需求选择合适的路由方式可以提升系统的灵活性和可维护性。

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

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

相关文章

免费插件集-illustrator插件-Ai插件-选择路径等分

文章目录 1.介绍2.安装3.通过窗口>扩展>知了插件4.功能解释5.总结 1.介绍 本文介绍一款免费插件&#xff0c;加强illustrator使用人员工作效率&#xff0c;路径处理功能&#xff0c;功能是选择路径等分。首先从下载网址下载这款插件 https://download.csdn.net/download…

本地Gitlab-runner自动编译BES项目

0 Preface/Foreword 1 Gitlab-runner配置情况 具体情况如下&#xff1a; Gitlab-ruuner运行在wsl 1中的Ubuntu 18.04 distro上专门为GitLab-runner分配了一个用户&#xff0c;名为gitlab-runner 2 自动编译 2.1 找不到编译工具链 根据错误提示&#xff0c;交叉编译工具链未找…

Springboot利用大模型实现即时通信

gitee地址&#xff1a;https://gitee.com/myha/Springboot-langchain-chat 版本及工具说明 本项目版本&#xff1a;springboot3.2.8 jdk17 mybatis-plus3.5.7 安装python&#xff0c;可以参考&#xff1a;https://docs.python.org/zh-cn/3/using/windows.html#the-full-in…

zsh 配置 docker 自动补全

zsh 配置 docker 自动补全 在终端中使用 docker 的命令的时候必须要全部手敲&#xff0c;没有提示&#xff0c;于是就在找是否有自动补全的脚本&#xff0c;搜索了一圈踩了一些坑总结了一下具体的步骤。 首先执行如下命令&#xff1a; mkdir -p ~/.zsh/completion curl -L h…

Visual Studio创建 OpenCV项目

1、cmake 编译 opencv 参考链接&#xff1a;CMake编译OpenCV3.4.1心得_cmake 3.4.1-CSDN博客 1&#xff09;opencv文件名最好不要有空格 2&#xff09;没有下载opencv_contrib&#xff0c;不用配置OPENCV_EXTRA_MODULES_PATH 1、Visual Studio创建 OpenCV项目 参考链接&am…

esp32通过smartconfig连接wifi

esp32通过smartconfig连接wifi整体设计流程 1.流程图 2.代码实现 #include <WiFi.h> #include <SPIFFS.h>// 定义存储文件的文件名 const char* wifi_config_file "/wifi_config.txt";// 定义变量存储 WiFi 信息 // 1&#xff09;不填写为空时通过sma…

LangGraph Studio

文章目录 一、关于 LangGraph Studio下载 二、设置三、打开一个项目三、调用图开始新的运行配置图运行 四、创建和编辑线程1、创建一个线程2、选择一个线程3、编辑线程状态 五、如何向图表添加中断1、将中断添加到节点列表2、向特定节点添加中断 六、Human-in-the-loop七、编辑…

多模态大模型intern-vl 1.5 论文解读:How Far Are We to GPT-4V?

论文&#xff1a;https://arxiv.org/pdf/2404.16821 目录 1 介绍 3.1 整体架构 3.2 强大的视觉编码器 InternViT-6B-448px-V1.2 InternViT-6B-448px-V1.5 3.3 动态高分辨率 动态宽高比匹配 图像分割与缩略图 InternVL 1.5&#xff0c;这是一款开源的多模态大语言模型&…

Onenet服务器创建产品和设备

Onenet服务器创建产品和设备 (1)浏览器搜索 Onenet, 或者打开这个网址 OneNET - 中国移动物联网开放平台 (10086.cn) (2)登录注册, 密码特殊符号是 (3)进入此网址, 设备管理页面 设备列表 - OneNET物联网平台 (10086.cn) (4)点击产品开发,创建产品 (5)其他行业 (6)设备接…

功能管理之语录管理功能开发(八)

云风网 云风笔记 云风知识库 这里话不多说&#xff0c;直接上效果图,开发逻辑和专栏上篇用户管理大致相同

【JVM基础12】——垃圾回收-说一下JVM有哪些垃圾回收器?

目录 1- 引言&#xff1a;垃圾回收器2- ⭐核心&#xff1a;垃圾回收器详解2-1 串行垃圾回收器2-2 并行垃圾回收器2-3 CMS&#xff08;并发垃圾回收&#xff09;——主要作用在老年代 3- 小结3-1 说一下JVM有哪些垃圾回收器&#xff1f; 1- 引言&#xff1a;垃圾回收器 在 JVM …

人在职场,一半清醒,一半糊涂

职场如战场&#xff0c;同事之间&#xff0c;除了利益竞争&#xff0c;鲜有情谊。 想要扎根立足&#xff0c;学会清醒做事&#xff0c;糊涂做人&#xff0c;才有可能避免“踩坑”&#xff0c;行稳致远。 01 人在职场&#xff0c;清醒做事&#xff0c;才不会被排挤出局。 职…

Fluent Mybatis

官方文档&#xff1a;https://gitee.com/fluent-mybatis/fluent-mybatis/wikis 新的ORM框架&#xff0c;整个设计理念非常符合工程师思维。 Fluent Mybatis 介绍 何为 Fluent Mybatis&#xff1f; Fluent Mybatis, 是一款 Mybatis 语法增强框架, 综合了 Mybatis Plus, Dynam…

codetop标签双指针题目大全解析(C++解法),双指针刷穿地心!!!!!

写在前面&#xff1a;此篇博客是以[双指针总结]博客为基础的针对性训练&#xff0c;题源是codetop标签双指针近一年&#xff0c;频率由高到低 1.无重复字符的最长子串2.三数之和3.环形链表4.合并两个有序数组5.接雨水6.环形链表II7.删除链表的倒数第N个节点8.训练计划II9.最小覆…

python爬虫代理ip多线程配置的详细教程

在网络爬虫的世界里&#xff0c;代理IP和多线程配置是两个非常重要的技巧。它们不仅能帮助我们提高爬虫的效率&#xff0c;还能有效地避免被目标网站封禁。今天&#xff0c;我就带大家一起探讨如何在Python中配置代理IP和多线程&#xff0c;实现高效的网络爬取。 代理IP的基本…

【vue3|第19期】vue3一般组件与路由组件的探讨

日期&#xff1a;2024年8月2日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

stm32cubemx生成驱动程序里面的变量,如何被main函数调用

用stm32cubemx生成了一个串口中断程序&#xff0c;功能实现了对不定长输入字符的统计和输出打印&#xff0c;在主函数写了回调函数void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 想重新排版&#xff0c;把回调函数放到UART.c里面&#xff0c; 考虑到main.c和uart…

使用Adobe Photoshop CS5给图片加水印

使用Adobe Photoshop CS5给图片加水印 前言1.我这里使用的是Adobe Photoshop CS52.新建空白画布3.写入水印内容4.按 Ctrl T 将其倾斜5.右键图层选择“混合选项”6.选择描边&#xff0c;颜色选择灰色7.效果如下8.填充选择0&#xff0c;不透明度选择75%9.打开编辑&#xff0c;选…

上海冷链配送新篇章 华鼎冷链科技以卓越服务餐饮品牌

在快速发展的上海餐饮连锁行业中&#xff0c;冷链运输作为保障食品安全与品质的关键环节&#xff0c;正迎来前所未有的发展机遇与挑战。华鼎冷链科技作为该领域的佼佼者&#xff0c;正引领着上海乃至全国冷链运输行业的新风尚。 华鼎冷链科技的成功并非一蹴而就。首先&#xff…

1990-2023年上市公司常用变量数据(1400+指标)

1990-2023年上市公司常用变量数据&#xff08;1400指标&#xff09; 1、时间&#xff1a;1990-2023年 2、范围&#xff1a;上市公司 3、格式&#xff1a;dta 4、来源&#xff1a;上市公司年报 5、指标&#xff1a;包括上市公司基本信息&#xff08;性质、行业、地址&#…