JAVA接入OPC DA2.0引发的问题

news2025/1/22 15:45:25

背景:

JAVA接入OPC DA后,在生产环境跑了一段时间后就会出现异常,给折腾的够呛,起初的报错还能通过重启OPC连接解决,后来强制重新连接也不行,最终一套测试下来,除非重启OPC服务器,别无他法!简单说下几个错误及导致的原因,以及给出解决方案!

错误一:An internal error occurred. [0x8001FFFF]

查询了很多资料无果,只有一些有年代的提问:An internal error occurred. [0x8001FFFF]
后来发现可以通过重启解决,于是有了直接判断异常,相同则重启OPC,解决燃眉之急。

        if ("An internal error occurred. [0x8001FFFF]".equals(e.getMessage())) {
            OpcUtils.forceReconnect();
        }

但目前并未查到原因!

错误二:org.jinterop.dcom.common.JIException: Message not found for errorCode: 0x800700A4

后来跑了一段时间后发现一直报异常0x800700A4,而且重连再也无法建立链接,但是可以打印OPC服务器的服务,只是无法建立连接!此时的我已经要炸了!由于测试环境无法达成与生产环境完全一致,无法进行测试,只能搜索问题,更头大的是使用OPC客户端软件也无法建立连接,此刻已经无解了。

查了很多,有的说是COM无法创建更多线程,也有说是windows系统bug,内存泄露需要更新补丁!但是依旧无有效解决方案。由于客户端也连接不上只能认为是OPC服务软件的问题了,每次重启都会恢复,运行一段时间就不行,但是OPC服务本身无任何问题。于是猜想DCOM有问题,我又写了一个基于COM的中转程序,想着本地连接肯定没问题了吧,很自信!

结果开心的时刻来了,跑去生产环境去部署发现COM方式也连接不上,脸打的生疼!最终还是完整部署了一份和生产环境一致的测试环境,经过我不懈的压测,最终OPC服务软件报了个错!(擦 生产环境为何没有),就因为这个错误提示,才引起我对一段代码的怀疑,之前觉得有疑惑但是没管它。

JAVA通过COM方式(jeasyopc)接入OPC DA

定位到问题

仅仅一个服务端OPC软件的异常 “AddGroup”,让我想起一段代码:

        //TODO 同步读取数据
        try {
            Group group = server.addGroup();
            Map<String, Item> itemMap = group.addItems(itemIds.toArray(new String[0]));
            List<DataItem> result = new ArrayList<>();
            for (Map.Entry<String, Item> entry : itemMap.entrySet()) {
                Item item = entry.getValue();
                ItemState itemState = item.read(true);
                DataItem dataItem = JiVariantUtil.parseValue(item.getId(), itemState);
                result.add(dataItem);
            }
//            group.clear();
//            server.removeGroup(group,false);
            return result;
        } catch (Exception e) {
            log.error("同步读取失败!", e);
            return null;
        }

这段查询代码来源于网络,当时很纳闷为何注释了两行,因为也浅显的了解了下OPC知识,知道关于group分组是在客户端定义,当时脑里的思路还在想正常定义分组应该初始化定义好同步给OPC服务器,后面直接拿分组名称用就是了,这里等于每次都会新增分组,注释的是清除,现在想想也真是大意了,狠狠的吃了把偷懒的亏!

结论显而易见,由于不断的addGroup,导致OPC服务器崩溃了。

优化代码

方法一

最简单的优化方式,每次新增,并且每次移除,只需要把注释的代码修改为:

server.removeGroup(group,true);

本人已压测过千万次查询写入,没有问题,效率会低点。

方法二

当前最优解应该是项目启动的时候初始化分组,addGroup后记录分组的名称,并在后续的交互中使用Group名称进行交互!写的过程中才发现,原来自带了很多方法就是为了这么用的,没文档,只能看代码了。大致列下实现:

   public static List<Item> getOrCreateOpcItem(Collection<String> itemIds) {
      Server server = getServer();
       if (Objects.isNull(server)) {
           log.error("OPC 获取OPC item时,服务为空!获取ItemIds:{}", itemIds);
           return null;
       }
       String key = String.join(",", itemIds);
       List<Item> result = new ArrayList<>();
       try {
           try {
               Group group = server.findGroup(key);
               List<Integer> integers = OpcUtils.itemClientHandleMap.get(key);
               for (Integer integer : integers) {
                   result.add(group.findItemByClientHandle(integer));
               }
           } catch (UnknownGroupException e) {
               Group group = server.addGroup(key);
               Map<String, Item> itemMap = group.addItems(itemIds.toArray(new String[0]));
               result = new ArrayList<>(itemMap.values());
               OpcUtils.itemClientHandleMap.put(key, result.stream().map(Item::getClientHandle).collect(Collectors.toList()));
           }
       } catch (Exception e) {
           log.error("OPC 查询/创建OPC Group及Item异常,ItemIds:{}", itemIds, e);
           return null;
       }
       return result;
   }
   
  public static void writeSync(String itemId, Boolean value) {
      try {
           List<Item> orCreateOpcItems = getOrCreateOpcItem(List.of(itemId));
           if (Objects.isNull(orCreateOpcItems)) {
               log.error("OPC-Sync write failed! 获取item失败,ItemId: {}, Value: {}", itemId, value);
               return;
           }
           Item item = orCreateOpcItems.get(0);
           JIVariant jiVariant = new JIVariant(value);
           item.write(jiVariant);
       } catch (Exception e) {
           log.error("OPC-Sync write failed! ItemId: {}, Value: {}", itemId, value, e);
       }
   }
    
   public static List<DataItem> readSync(Collection<String> itemIds) {
       try {
           List<Item> orCreateOpcItems = getOrCreateOpcItem(itemIds);
           if (Objects.isNull(orCreateOpcItems)) {
               log.error("OPC-Sync read failed! 获取item失败,ItemId: {}", itemIds);
               return null;
           }
           List<DataItem> result = new ArrayList<>();
           for (Item item : orCreateOpcItems) {
               ItemState itemState = item.read(true);
               DataItem dataItem = JiVariantUtil.parseValue(item.getId(), itemState);
               result.add(dataItem);
           }
           return result;
       } catch (Exception e) {
           log.error("同步读取失败!itemIds:[{}]", itemIds, e);
           return null;
       }
   }

OPC DA客户端工具(从KEPServerEX 6精简):

链接: https://pan.baidu.com/s/1kAZJHdIDxOxjIXhdfnLJ_Q?pwd=his3

提取码: his3

总结

  1. 测试环境一定要与生产环境完全一致!
  2. 一定测试!长时间压测!
  3. 补足基础知识,查看源码,正确使用方式其义自见

参考:

microsoft security essentials errorcode 0x800700a4
.Net: I got the following exception InteropServices.COMException: "No more threads can be created in the system.

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

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

相关文章

生产制造企业数字化转型:流程制造ERP

ERP的含义是企业资源计划&#xff0c;含义是对企业所拥有各种资源进行综合规划和优化管理&#xff0c;用以降低成本&#xff0c;提高效率&#xff0c;增加利润。ERP最初是在90年代初提出的&#xff0c;那时的ERP概念&#xff0c;还只是根据计算机技术的发展和供需链管理,推论各…

[附源码]java毕业设计校园闲置物品租赁系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

深度学习——动物数据集大合集(附下载地址)

说明&#xff1a;部分数据收费&#xff0c;付费后数据请关注私信内容&#xff0c;会给出下载链接&#xff0c;亲测数据质量不错&#xff0c;如下图所示&#xff1a; ​ 1、30种常见鱼类数据集 数据集介绍&#xff1a;30种常见鱼类数据集&#xff08;每类鱼30-100张图片不等&am…

丰田+比亚迪「围攻」大众,明年或将「让出」榜首之位

大众&#xff0c;正在经历最艰难的时刻。 高工智能汽车研究院监测数据显示&#xff0c;今年1-10月&#xff0c;大众集团旗下大众品牌乘用车在中国市场的交付上险同比下滑11.5%&#xff0c;而作为老对手&#xff0c;排名第二的丰田&#xff0c;则是同比增长13.72%。 豪华品牌部…

Oracle快速入门 | 黑马

简介 概述 Oracle目前使用最广的大型数据库管理系统&#xff0c;作为分布式数据库实现分布式处理功能。 广泛用于金融行业&#xff0c;大量数据而且需要很安全 特点 支持多用户&#xff0c;大事务量的事务处理数据安全性和完整性控制&#xff08;主要卖售后的&#xff0c…

信息安全工程实践笔记--Day1 信息收集漏洞扫描

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录实验目标&#xff08;一&#xff09;信息收集一、搜索引擎二、域名1.whois 查询2.子域名查询3.真实ip(1)什么是cdn&#xff1f;(2) 如何验证目标服务器是否挂载cdn&a…

吴恩达-机器学习-k-means聚类算法

目录 吴恩达-机器学习2022版 k-means聚类算法实现整理 1.核心函数四个&#xff1a; 1.find_closest_centroids &#xff1a;寻找最近的质心 2.compute_centroids &#xff1a;迭代重新计算质心 3.kMeans_init_centroids &#xff1a;随机初始化质心 4.run_kMean…

Centos安装Rclone,操作Minio基本命令

简介 Rclone 是一个用于和同步云平台同步文件和目录命令行工具。它允许在文件系统和云存储服务之间或在多个云存储服务之间访问和同步文件&#xff0c;它具有单向同步功能&#xff0c;使目录完全相同&#xff0c;它具有加密、缓存和联合后端&#xff0c;支持 Fuse 安装&#…

MindSpore是一种适用于端边云场景的新型开源深度学习训练/推理框架

MindSpore是一种适用于端边云场景的新型开源深度学习训练/推理框架。 MindSpore提供了友好的设计和高效的执行&#xff0c;旨在提升数据科学家和算法工程师的开发体验&#xff0c;并为Ascend AI处理器提供原生支持&#xff0c;以及软硬件协同优化。 同时&#xff0c;MindSpore…

【计算机网络】

1、应用层 web应用——http协议 请求消息格式&#xff1a;请求行&#xff0c;头部行&#xff0c;消息体 请求方法get&#xff0c;post&#xff0c;delete&#xff0c;put上传文件 Email应用——SMTP&#xff0c;POP3/IMAP DNS应用——DNS协议 P2P应用&#xff1a;文件分发等…

实战项目【7】MEMS惯性传感器的精度参数和单位换算

1 前言 有不少朋友在做项目的时候经常涉及到加速度计和陀螺仪的原始数据转换为其他的单位的问题&#xff0c;这篇文章梳理和推导一下。 1&#xff09;加速度计的原始数据 在应用时常见的转换单位有: g、m/s^2 、角度 2&#xff09;陀螺仪的原始数据 在应用时常见的转换单位有&a…

〖全域运营实战白宝书 - 运营角色认知篇⑤〗- “运营“ 是否有前途?

大家好&#xff0c;我是 哈士奇 &#xff0c;一位工作了十年的"技术混子"&#xff0c; 致力于为开发者赋能的UP主, 目前正在运营着 TFS_CLUB社区。 &#x1f4ac; 人生格言&#xff1a;优于别人,并不高贵,真正的高贵应该是优于过去的自己。&#x1f4ac; &#x1f4e…

UE4 回合游戏项目 23- 进入战斗

在上一篇&#xff08;UE4 回合游戏项目 22- 控制新角色&#xff09;基础上继续增加两个角色进入战斗的逻辑 效果&#xff1a; 步骤&#xff1a; 1. 打开“gameMode1”&#xff0c;新增一个变量命名为“正在控制的所有玩家”&#xff0c;变量类型为“roleCategory”的数组 2.打…

Jitamin 安装与配置

Jitamin Jitamin (读作/ˈdʒɪtəmɪn/) 是一款免费、开源&#xff0c;使用PHP语言开发的项目管理系统。Jitamin灵感来自于Vitamin&#xff0c;并结合了Just In Time(准时)和敏的拼音min&#xff0c;意指效率与敏捷是项目管理的维他命。 功能特性 简洁、美观的界面支持多主题…

Celix是什么?能做什么?

半路突然看到了OSGI,又学习了一下&#xff0c;大概了解了架构的一些基础知识。 像MVC&#xff0c;MVP等其实就是分层架构&#xff0c;这类是最容易想到的。 然后其实我就没有接触&#xff0c;如微服务架构&#xff0c;微内核架构。 是什么&#xff1f; 而Celix就是属于微内…

[附源码]java毕业设计校园网学生成绩查询系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Redis源码篇(6)——主从复制

主从复制 从服务器执行 SLAVEOF IP PORT 命令即可实现对主服务器的复制。 复制又分为完整同步和部分同步&#xff08;2.8之后&#xff09; 完整同步&#xff1a;与混合持久化过程类似&#xff0c;先以rdb的方式保存rdb文件然后发送给从服务器。再将期间的命令保存到复制缓存区…

[论文评析]基于人体姿态识别的立定跳远 动作智能评估系统

基于人体姿态识别的立定跳远 动作智能评估系统论文信息背景方法系统总体设计立定跳远动作智能评估系统标准动作库子系统动作采集子系统人体姿态动作评估子系统人体姿态评估模型立定跳远关键帧匹配姿态评估及对比总结论文信息 题目&#xff1a;基于人体姿态识别的立定跳远 动作…

AMBA:AXI/AHB/APB学习笔记

AMBA、AXI、AHB、APB学习笔记AMBA总线&#xff1a;各模块之间的连接AHB特性&#xff1a;组成部分&#xff1a;AXIAPBAMBA总线&#xff1a;各模块之间的连接 advanced microcontroller bus architecture高级微控制器总线架构 AHB Advanced High-performance Bus 高级高性能总…

微信小程序|搭建一个博客小程序

文章目录一、文章前言二、创建小程序三、功能开发&#xff08;1&#xff09;首页&#xff08;2&#xff09;领域页&#xff08;3&#xff09;博客详情页&#xff08;4&#xff09;个人中心页一、文章前言 此文主要通过小程序搭建一个博客系统&#xff0c;实现博客的一些基础功能…