微服务项目【服务调用分布式session共享】

news2025/1/8 5:02:59

nginx动静分离

第1步:通过SwitchHosts新增二级域名:images.zmall.com

第2步:将本次项目的所有静态资源js/css/images复制到nginx中的html目录下

第3步:在nginx的核心配置文件nginx.conf中新增二级域名images.zmall.com访问映射,用于实现nginx动静分离

注意:修改成功之后,重启nginx服务使其配置生效!!!

server{
    listen 80;
    server_name images.zmall.com;
    location / {
        root html;
        index index.html;
    }
}

第4步:删除zmall-product商品服务和zmall-gateway网关服务下的static静态资源,改用nginx中配置的静态资源

第5步:修改zmall-product商品服务中的templates/common/head.html

<#assign ctx>
    <#--域名,动态请求时需加入该前缀-->
    http://zmall.com/product-serv
</#assign>
<#--采用H5方式的base标签,在整个页面的url地址前加入,用于访问nginx中的静态资源-->
<base href="http://images.zmall.com/"/>

第6步:分别重启zmall-product、zmall-gateway以及nginx后输入请求地址:zmall.com/product-serv/index.html访问商品服务首页,如下所示:

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

服务调用

创建配置zmall-cart购物车模块

第1步:基于Spring initializr创建zmall-cart购物车模块

第2步:将zmall-order订单模块配置到主模块中

<modules>
    ...
    <module>zmall-cart</module>
    ...
</modules>

第3步:修改pom.xml

<parent>
    <groupId>com.xujie.zmall</groupId>
    <artifactId>zmall</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>
<artifactId>zmall-cart</artifactId>

<dependencies>
    <dependency>
        <groupId>com.xujie.zmall</groupId>
        <artifactId>zmall-common</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

第4步:配置application.yml(端口:8030)

server:
  port: 8030
spring:
  application:
    name: zmall-cart
  datasource:
    #type连接池类型 DBCP,C3P0,Hikari,Druid,默认为Hikari
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/zmall?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
    username: root
    password: 1234
  freemarker:
    suffix: .html
    template-loader-path: classpath:/templates/
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
#mybatis-plus配置
mybatis-plus:
  #所对应的 XML 文件位置
  mapper-locations: classpath*:/mapper/*Mapper.xml
  #别名包扫描路径
  type-aliases-package: com.xujie.zmall.model
  configuration:
    #驼峰命名规则
    map-underscore-to-camel-case: true
#日志配置
logging:
  level:
    com.xujie.zmall.mapper: debug

第5步:在启动类上加入@EnableDiscoveryClient

第6步:分别将商品模块中的common/head.html导入到templates目录,并修改head.html中的ctx局部变量

<#assign ctx>
    <#--一级域名,动态请求时需加入该前缀-->
    http://zmall.com/cart-serv
</#assign>
<#--采用H5方式的base标签,在整个页面的url地址前加入,用于访问nginx中的静态资源-->
<base href="http://images.zmall.com/"/>

第7步:在zmall-gateway网关服务中配置购物车的路由转发规则(重启gateway网关服务)

spring:
  application:
    name: zmall-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:
        ...
        - id: cart_route
          uri: lb://zmall-cart # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
          predicates:
            - Path=/cart-serv/**
          filters:
            - StripPrefix=1
            #此过滤器设置路由过滤器检查的请求属性,以确定是否应发送原始主机头,而不是由 HTTP 客户端确定的主机头
            - PreserveHostHeader

注意:这里要配置过滤器PreserveHostHeader,用于处理重定向时依然已原始主机头发送请求。

第8步:创建CartController并定义请求方法

@Controller
public class CartController {

    @RequestMapping("/cart.html")
    public String toCart(){
        return "buyCar";
    }

    @RequestMapping("/addCart")
    public String addCart(Integer pid,Integer num){
        return "redirect:/cart.html";
    }
}

注意:这里使用redirect重定向方式跳转页面,在SpringCloud gateway路由转发过程中会导致域名跳转变成了http请求方式,所以必须在Gateway网关服务中进行相关的配置。具体请参考第8步的gateway网关路由配置。

第9步:在zmall-product模块中修改加入购物车的请求方法,定向到购物车

<td><a href="http://zmall.com/cart-serv/addCart?pid=${(product.id)!}&num=3" class="b_sure">去购物车结算</a><a href="#" class="b_buy">继续购物</a></td>

创建配置zmall-order订单模块

第1步:基于Spring initializr创建zmall-order订单模块

第2步:将zmall-order订单模块配置到主模块中

<modules>
    ...
    <module>zmall-order</module>
    ...
</modules>

第3步:修改pom.xml

<parent>
    <groupId>com.xujie.zmall</groupId>
    <artifactId>zmall</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>
<artifactId>zmall-order</artifactId>

<dependencies>
    <dependency>
        <groupId>com.xujie.zmall</groupId>
        <artifactId>zmall-common</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>

第4步:配置application.yml(端口:8040)

server:
  port: 8040
spring:
  application:
    name: zmall-order
  datasource:
    #type连接池类型 DBCP,C3P0,Hikari,Druid,默认为Hikari
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/zmall?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
    username: root
    password: 1234
  freemarker:
    suffix: .html
    template-loader-path: classpath:/templates/
  cloud:
    nacos:
      config:
        server-addr: localhost:8848
#mybatis-plus配置
mybatis-plus:
  #所对应的 XML 文件位置
  mapper-locations: classpath*:/mapper/*Mapper.xml
  #别名包扫描路径
  type-aliases-package: com.xujie.zmall.model
  configuration:
    #驼峰命名规则
    map-underscore-to-camel-case: true
#日志配置
logging:
  level:
    com.xujie.zmall.mapper: debug

第5步:在启动类上加入@EnableDiscoveryClient@MapperScan({"com.xujie.zmall.mapper"})

第6步:定义订单接口,可从公共模块zmall-common中直接复制过来

第7步:创建OrderController并定义请求接口

@Controller
public class OrderController {
    @Autowired
    private IOrderService orderService;

    @RequestMapping("/orderUserList")
    @ResponseBody
    public List<Order> orderUserList(){
        return orderService.list(new QueryWrapper<Order>()
                .eq("userId",18));
    }
}

第8步:在zmall-gateway网关服务中配置购物车的路由转发规则(重启gateway网关服务)

spring:
  application:
    name: zmall-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:
        ...
        - id: order_route
          uri: lb://zmall-order # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
          predicates:
            - Path=/order-serv/**
          filters:
            - StripPrefix=1
            - PreserveHostHeader

服务调用

在zmall-user中通过openfeign方式访问order服务接口

  • 定义openfeign接口
@FeignClient("zmall-order")
public interface IOrderFeignService {

    @RequestMapping("/orderUserList")
    List<Order> orderUserList();
}

  • 启动类上设置@EnableDiscoveryClient@EnableFeignClients
  • 调用接口并测试接口
@Controller
public class UserController {

    @Autowired
    private IOrderFeignService orderFeignService;

    @RequestMapping("/login.html")
    public String toLogin(){
        return "login";
    }

    @RequestMapping("/order.html")
    @ResponseBody
    public List<Order> orderUserList(){
        return orderFeignService.orderUserList();
    }
}

spring session实战

什么是Spring Session

SpringBoot整合Spring-Session的自动配置可谓是开箱即用,极其简洁和方便。这篇文章即介绍SpringBoot整合Spring-Session,这里只介绍基于RedisSession的实战。

Spring Session 是Spring家族中的一个子项目,Spring Session提供了用于管理用户会话信息的API和实现。它把servlet容器实现的httpSession替换为spring-session,专注于解决 session管理问题,默认Session信息存储在Redis中,可简单快速且无缝的集成到我们的应用中

spring session官网地址:https://spring.io/projects/spring-session

Spring Session的特性:

  • 提供用户session管理的API和实现
  • 提供HttpSession,以中立的方式取代web容器的session,比如tomcat中的session
  • 支持集群的session处理,不必绑定到具体的web容器去解决集群下的session共享问题

为什么要使用Spring Session

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T6YqkIpX-1676079804219)(spring-session\session会话流程.png)]

SpringCloud微服务将一个完整的单体应用拆解成了一个个独立的子服务,而每一个独立的微服务子模块都将部署到不同的服务器中,而服务与服务之间是独立隔离的,这个时候使用要实现服务与服务之间的session会话共享,则需要借助于spring-session框架来解决分布式session管理与共享问题。

错误案例展示

在用户服务zmall-user中编写登录控制器,登录时创建session,并将当前登录用户存储sesion中。

@Controller
public class UserController {
	
    @RequestMapping("/login.html")
    public String toLogin(HttpSession session){
        session.setAttribute("username","admin");
        return "login";
    }
}

在Gateway网关服务中添加用户服务的路由转发规则

spring:
  application:
    name: zmall-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:
        ...
        - id: user_route
          uri: lb://zmall-user # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
          predicates:
            - Path=/user-serv/**
          filters:
            - StripPrefix=1
            - PreserveHostHeader

在商品服务zmall-product中编写查询控制器,在登录创建session后,使用将sessionId置于cookie中访问。如果没有session将返回错误。

@Controller
public class ProductController {

    @RequestMapping("/index.html")
    public String index(Model model, HttpSession session){
        Object username = session.getAttribute("username");
        System.out.println("**********"+username);
        return "index";
    }
}

配置spring-session

在公共模块zmall-common中引入spring-session的pom配置,由于spring-boot包含spring-session的starter模块,所以pom中依赖:
注意:公共模块作为所有微服务子模块的依赖支持,如果不在各服务模块中配置redis支持,会导致启动其他微服务时出现报错情况。

<!--redis-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring session-->
<dependency>
	<groupId>org.springframework.session</groupId>
	<artifactId>spring-session-data-redis</artifactId>
</dependency>
<!--commons-pool2-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

分别在商品服务zmall-product和用户服务zmall-user中配置application.yml

spring:
  session:
    redis:
      flush-mode: on_save
      namespace: session.zmall
      cleanup-cron: 0 * * * * *
    store-type: redis
    timeout: 1800
  redis:
    host: localhost
    port: 6379
    password: 123456
    jedis:
      pool:
        max-active: 100
        max-wait: 10
        max-idle: 10
        min-idle: 10
    database: 0

重新启动zmall-user和zmall-product服务,先访问:http://zmall.com/user-serv/login.html,然后在访问:http://zmall.com/product-serv/index.html;回到zmall-product模块控制台查看session获取情况。

用户登录

第1步:在zmall-common公共模块中创建全局异常处理、响应封装类

第2步:在zmall-user模块中定义IUserService及UserServiceImpl

IUserService

public interface IUserService extends IService<User> {
    JsonResponseBody<?> userLogin(UserVo user, HttpServletRequest req, HttpServletResponse resp);
}

UserServiceImpl

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Override
    public JsonResponseBody<?> userLogin(UserVo user,
                                         HttpServletRequest req,
                                         HttpServletResponse resp) {
        //1.判断用户账号和密码是否为空
        if(StringUtils.isEmpty(user.getLoginName())||
                StringUtils.isEmpty(user.getPassword()))
            return new JsonResponseBody<>(JsonResponseStatus.USERNAME_OR_PWD_EMPTY);
        //2.根据用户名查询数据对应的用户信息
        User us = this.getOne(new QueryWrapper<User>()
                .eq("loginName", user.getLoginName()));
        //3.判断us用户对象是否为空
        if(null==us)
            return new JsonResponseBody<>(JsonResponseStatus.USERNAME_ERROR);
        try {
            //MD5加密转换处理
            String pwd=MD5Utils.md5Hex(user.getPassword().getBytes());
            //4.判断输入密码与数据库表存储密码是否一致
            if(!us.getPassword().equals(pwd)){
                return new JsonResponseBody<>(JsonResponseStatus.PASSWORD_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResponseBody<>(JsonResponseStatus.ERROR);
        }
        //5.通过UUID生成token令牌并保存到cookie中
        String token= UUID.randomUUID().toString().replace("-","");
        //将随机生成的Token令牌保存到Cookie中,并设置1800秒超时时间
        //CookieUtils.setCookie(req,resp,"token",token,7200);
        //6.将token令牌与spring session进行绑定并存入redis中
        HttpSession session = req.getSession();
        session.setAttribute(token,us);
        return new JsonResponseBody<>();
    }
}

第3步:创建UserVo类

@Data
public class UserVo {
    private String loginName;
    private String password;
}

第4步:在UserController中定义用户登录方法

/**
* 用户登陆功能实现
* @return
*/
@RequestMapping("/userLogin")
@ResponseBody
public JsonResponseBody<?> userLogin(UserVo user,
    HttpServletRequest req,
    HttpServletResponse resp){
    return userService.userLogin(user,req,resp);
}

第5步:在前端login.html页面中定义登录js方法

<script>
    $(function(){
        $('.log_btn').click(function(){
            let loginName=$('.l_user').val();
            let password=$('.l_pwd').val();

            if(''===loginName){
                alert('请输入用户名!');
                return false;
            }
            if(''===password){
                alert('请输入密码!');
                return false;
            }
            console.log({
                loginName:loginName,
                password:password
            });
            $.post('http://zmall.com/user-serv/userLogin',{
                loginName:loginName,
                password:password
            },function(rs){
                console.log(rs);
                if(rs.code===200){
                    location.href='http://zmall.com/product-serv/index.html';
                }else{
                    alert(rs.msg);
                }
            },'json');
        });
    });
</script>

登录成功后,跳转到商品首页

二级域名问题

测试在用户模块中保存用户信息,然后在产品模块中读取,但是使用二级域名方式访问读取失败

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bXdoXGVi-1676079804242)(spring-session\image-20220316211941783.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AX1oOv5W-1676079804269)(spring-session\image-20220316212342140.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WlrZ6S9q-1676079804279)(spring-session\image-20220316213018825.png)]

请分别在用户服务和商品服务中该配置类,解决二级域名访问session无效问题。

@Configuration
public class SessionConfig {
    @Bean
    public CookieSerializer cookieSerializer(){
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        cookieSerializer.setDomainName("zmall.com");
        cookieSerializer.setCookieName("ZMALLSESSION");
        return cookieSerializer;
    }
    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer(){
        return new GenericJackson2JsonRedisSerializer();
    }
}

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

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

相关文章

h2database源码解析-表和索引

目录表索引MVPrimaryIndexMVDelegateIndexMVSecondaryIndex索引更新表 h2使用类MVTable表示数据库表&#xff0c;h2的表数据是基于主键排列的&#xff0c;这种表也叫做主键索引表。这也就意味着表必须有主键&#xff0c;如果没有主键&#xff0c;h2会自动生成一个主键_ROWID_&…

在Linux和Windows上编译datax-web-ui源码

记录&#xff1a;375场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;使用apache-maven-3.8.7安装编译datax-web-ui源码。在Windows上操作系统上&#xff0c;使用apache-maven-3.8.7编译datax-web-ui源码。版本&#xff1a;JDK 1.8 node-v14.17.3 npm-6.14.13datax-web-ui开…

江苏五年制专转本应该复习几轮?

五年制专转本应该复习几轮&#xff1f; 据调查统计&#xff1a;2022年专转本17%的考生复习三轮及以上&#xff0c;23%的考生复习了两轮。这两类的考生录取率高至85%。可见复习轮数多&#xff0c;专转本上岸的概率也大。综合多方因素&#xff0c;建议同学们专转本复习四轮&#…

pointpillars Paper学习总结

Pointpillar Paper PointPillars提出了一种新的点云编码方式和3D转2D的方法&#xff0c;用2D卷积的方式实现目标检测而没有采用耗时的3D卷积&#xff0c;在速度和精度上达到了很好的平衡&#xff0c;其速度快、精度高、易于部署的特点使得其在工业界得到了广泛的应用。 处理思…

JavaWeb--JDBC

JDBC1 JDBC概述1.1 JDBC概念1.2 JDBC本质1.3 JDBC好处2 JDBC快速入门2.1 编写代码步骤2.2 具体操作3 JDBC API详解3.1 DriverManager3.2 Connection3.2.1 获取执行对象3.2.2 事务管理3.3 Statement3.3.1 概述3.3.2 代码实现3.4 ResultSet3.4.1 概述3.4.2 代码实现3.5 案例3.6 P…

2.Java基础【Java面试第三季】

2.Java基础【Java面试第三季】前言推荐2.Java基础01_字符串常量Java内部加载-上58同城的java字符串常量池面试code讲解intern()方法---源码解释02_字符串常量Java内部加载-下whyOpenJDK8底层源码说明递推步骤总结考查点03_闲聊力扣算法第一题字节跳动两数求和题目说明面试题解法…

rt-thread 移植调试记录

rt-thread 移植调试记录 记录rt-thread移植的过程。这里移植仅仅是利用rt-thread源码目录已经移植好的文件&#xff0c;组建自己的工程&#xff0c;不需要自己编写汇编完成底层移植。 1. 搭建基础工程 这里使用的是正点原子的潘多拉开发板&#xff0c;MCU为stm32l475。需要先…

【c++】类和对象:让你明白“面向一个对象有多重要”:构造函数,析构函数,拷贝构造函数的深入学习

文章目录 什么是面向对象&#xff1f;一&#xff1a;类是什么&#xff1f; 1.类的访问限定符 2.封装 3.类的实例化 4.this指针二&#xff1a;类的6个默认成员函数 1.构造函数 2.析构函数 3.拷贝构造函数什么是面向对象&#xff1f; c语言是面向…

window系统中安装Jupyter Notebook方法记录

1.初步感受Jupyter Notebook Jupyter Notebook 官网地址&#xff1a;Jupyter Notebook Jupyter Notebook&#xff08;此前被称为 IPython notebook&#xff09;是一个交互式笔记本&#xff0c;支持运行 40 多种编程语言。 Jupyter Notebook 的本质是一个 Web 应用程序&#xf…

Java体系最强干货分享—挑战40天准备Java面试,最快拿到offer!

如何准备java面试&#xff0c;顺利上岸大厂java岗位&#xff1f; 主攻Java的人越来越多&#xff0c;导致行业越来越卷&#xff0c;最开始敲个“hello world”都能进大厂&#xff0c;现在&#xff0c;八股、全家桶、算法等等面试题横行&#xff0c;卷到极致&#xff01;就拿今年…

聊聊什么是架构,你理解对了吗?

什么是架构?软件有架构?建筑也有架构?它们有什么相同点和不同点? 下面咱们就介绍一下,容易混淆的几个概念 一、系统与子系统 系统 泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体。它的意思是 “总体”、“整体”或“联盟” 子系…

Java基础常见面试题(二)

面向对象基础 面向对象和面向过程的区别 面向过程 优点&#xff1a; 性能比面向对象高&#xff0c;因为类调用时需要实例化&#xff0c;开销比较大&#xff0c;比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发&#xff0c;性能是最重要的因素。 缺点…

如何做迭代规划

敏捷开发中的迭代规划如同使用需求漏斗&#xff0c;对各方需求定期进行优先级排序并层层拆解或合并&#xff0c;最终把高优先级且细粒度的需求从漏斗进入到研发团队&#xff0c;确保研发团队做对的事&#xff08;Do Right Things&#xff09;&#xff0c;避免团队跑偏方向或进度…

Netty之EventLoopGroup详解

目录 目标 Netty版本 Netty官方API NioEventLoopGroup和DefaultEventLoop的区别 EventLoopGroup实现对内部EventLoop的轮询 EventLoop对普通任务和定时任务的实现 执行普通任务 执行定时任务 划分EventLoopGroup职责 简言 实现 指定EventLoopGroup操作ChannelHandl…

手机上怎么在线生成gif?1分钟教你手机图片合成gif

怎样通过手机实现在线制作GIF图片的操作呢&#xff1f;接下来&#xff0c;给大家分享两招gif制作&#xff08;https://www.gif.cn/&#xff09;小窍门-【GIF中文网】不需要下载任何软件&#xff0c;小白也能轻松上手。支持原画质导出&#xff0c;图片无损处理。一起来看看具体步…

前端教学视频分享(视频内容与市场时刻保持紧密相连,火热更新中。。。)

⚠️获取公众号 本次要想大家推荐一下本人的公众号&#xff0c;在微信中搜索公众号 李帅豪在对话框中输入前端视频四个字即可立即获取所有视频&#xff0c;不收费无广告&#xff01;&#xff01;&#xff01; 本公众号收集了近两年来前端最新最优秀的学习视频&#xff0c;涵盖…

大数据技术架构(组件)30——Spark:Optimize--->Submit

2.1.9、Optimize--->Submit调优工作主要从CPU、内存、网络开销和IO四方面入手2.1.9.0、Spark On Yarn2.1.9.0.1、Jar包管理及本地性调优spark.yarn.jars :将jar包放到hdfs上&#xff0c;避免每次driver启动的时候都要进行jar包的分发。yarn.nodemanager.localizer.cache.cle…

ChatGPT告诉你智能制造

ChatGPT自上线以来&#xff0c;几乎得到了外界的一致好评&#xff0c;上线两个月&#xff0c;获得1亿月活跃用户&#xff0c;成为增长最快的面向消费者的应用。 面对ChatGPT拟人一般的问答能力&#xff0c;很多人认为它代表着AlphaGo之后&#xff0c;人工智能应用的第二次浪潮…

电子技术——MOS差分输入对

电子技术——MOS差分输入对 差分输入系统因其极高的共模抑制能力&#xff0c;差分输入几乎是是构建所有通用模拟IC的基本前级输入&#xff0c;也是现代信号传输理论的基础。本节我们讲解MOS差分输入对。 MOS差分输入对 下图展示了MOS差分输入对的基本原理图&#xff1a; 一个…

数据采集协同架构,集成马扎克、西门子、海德汉、广数、凯恩帝、三菱、海德汉、兄弟、哈斯、宝元、新代、发那科、华中各类数控以及各类PLC数据采集软件

文章目录 前言一、采集协同架构是什么&#xff1f;可以做什么&#xff08;数控、PLC配置采集&#xff09;&#xff1f;二、使用步骤 1.打开软件&#xff0c;配置MQTT或者数据库&#xff08;支持sqlserver、mysql等&#xff09;存储转发消息规则2.配置数控系统所采集的参数、转…