- 浏览: 703446 次
- 性别:
- 来自: 北京
-
文章分类
- 全部博客 (239)
- 系统架构设计 (16)
- java collection framework (2)
- java分布式 (4)
- java多线程 (0)
- 故障处理及调优 (16)
- 软件开发过程及管理 (28)
- OS (5)
- 常用算法 (3)
- design pattern (8)
- transaction (7)
- java apps (48)
- corejava (7)
- java and DB (10)
- cache (0)
- webservice (14)
- web前端 (25)
- 报表 (4)
- 日志系统设计 (3)
- Oracle (4)
- mysql (11)
- xml (11)
- 数据源配置管理 (3)
- 企业数据存储 (4)
- php (2)
- 测试 (1)
最新评论
-
orangebook:
对于初学者来说,这样编写可能会误导,理解更烦锁。
观察者模式(发布-订阅) -
liudajiang:
呵呵 startThreads(rand ...
实践缩小Java synchronized 粒度 -
zengwenbo5566:
谢谢博主,学习了
解决getOutputStream() has already been called for this response -
u011335423:
大神厉害啊 可以了
解决getOutputStream() has already been called for this response -
xiang37:
...
解决getOutputStream() has already been called for this response
最近遇到的一个关于socket.close的问题,在某个应用服务器出现的状况(执行netstat -np | grep tcp):
tcp 0 0 10.224.122.16:50158 10.224.112.58:8788 CLOSE_WAIT
tcp 0 0 10.224.122.16:37655 10.224.112.58:8788 CLOSE_WAIT
tcp 1 0 127.0.0.1:32713 127.0.0.1:8080 CLOSE_WAIT
tcp 38 0 10.224.122.16:34538 10.224.125.42:443 CLOSE_WAIT
tcp 38 0 10.224.122.16:33394 10.224.125.42:443 CLOSE_WAIT
tcp 1 0 10.224.122.16:18882 10.224.125.10:80 CLOSE_WAIT
tcp 1 0 10.224.122.16:18637 10.224.125.10:80 CLOSE_WAIT
tcp 1 0 10.224.122.16:19655 10.224.125.12:80 CLOSE_WAIT
........................................
总共出现了200个CLOSE_WAIT的socket.而且这些socket长时间得不到释放.下面我们来看看为什么会出现这种大量socket的CLOSE_WAIT情况。
首先我们要搞清楚的是,这个socket是谁发起的,我们可以看到122.16这台机器开了很多端口,而且端口号都很大,125.12 或者125.10上的端口都是很常见服务器端口,所以122.16上这么多CLOSE_WAIT的socket是由122.16开启的,换句话说这台机器是传统的客户端,它会主动的请求其他机器的服务端口.要搞清楚为什么会出现CLOSE_WAIT,那么首先我们必须要清楚CLOSE_WAIT的机制和原理.
假设我们有一个client, 一个server.
当client主动发起一个socket.close()这个时候对应TCP来说,会发生什么事情呢?如下图所示.
client首先发送一个FIN信号给server, 这个时候client变成了FIN_WAIT_1的状态, server端收到FIN之后,返回ACK,然后server端的状态变成了CLOSE_WAIT.接着server端需要发送一个FIN给client,然后server端的状态变成了LAST_ACK,接着client返回一个ACK,然后server端的socket就被成功的关闭了.
从这里可以看到,如果由客户端主动关闭一链接,那么客户端是不会出现CLOSE_WAIT状态的.客户端主动关闭链接,那么Server端有可能会出现CLOSE_WAIT的状态.而我们的服务器上,是客户端socket出现了CLOSE_WAIT,由此可见这个是由于server主动关闭了server上的socket.那么当server主动发起一个socket.close(),这个时候又发生了一些什么事情呢.
从图中我们可以看到,如果是server主动关闭链接,那么Client则有可能进入CLOSE_WAIT,如果Client不发送FIN包,那么client就一直会处在CLOSE_WAIT状态(后面我们可以看到有参数可以调整这个时间).
那么现在我们要搞清楚的是,在第二中场景中,为什么Client不发送FIN包给server.要搞清楚这个问题,我们首先要搞清楚server是怎么发FIN包给client的,其实server就是调用了socket.close方法而已,也就是说如果要client发送FIN包,那么client就必须调用socket.close,否则就client就一直会处在CLOSE_WAIT(但事实上不同操作系统这点的实现还不一样).
下面我们来做几个实验
实验一:
环境:
服务器端:win7+tomcat,tomcat的keep-alive的时间为默认的15s.
客户端:mac os
实验步骤:服务器启动后,客户端向服务器发送一个get请求,然后客户端阻塞,等待服务器端的socket超时.通过netstat -np tcp可以看到的情况是发送get请求时,服务器和客户端链接是ESTABLISHED, 15s之后,客户端变成了CLOSE_WAIT,而服务器端变成了FIN_WAIT_2.这一点也在我们的预料之中,而这个时候由于客户端线程阻塞,客户 端socket空置在那里,不做任何操作,2分钟过后,这个链接不管是在win7上,还是在mac os都看不到了.可见,FIN_WAIT_2或者CLOSE_WAIT有一个timeout.在后面的实验,可以证明,在这个例子中,其实是 FIN_WAIT_2有一个超时,一旦过了2分钟,那么win7会发一个RST给mac os要求关闭双方的socket.
实验二
服务器端:ubuntu9.10+tomcat,tomcat的keep-alive的时间为默认的15s.
客户端:mac os
实验步骤:服务器启动后,客户端向服务器发送一个get请求,然后客户端阻塞,等待服务器端的socket超时.通过netstat -np tcp(ubuntu使用netstat -np|grep tcp)可以看到的情况是发送get请求时,服务器和客户端链接是ESTABLISHED, 15s之后,客户端变成了CLOSE_WAIT,而服务器端变成了FIN_WAIT_2.这一点也也在我们的预料之中,而这个时候由于客户端线程阻塞,客 户端socket空置在那里,不做任何操作,1分钟过后,ubuntu上的那个socket不见了,但是mac os上的socket还在,而且还是CLOSE_WAIT,这说明,FIN_WAIT_2确实有一个超时时间,win7上的超时操作可以关闭mac os上的socket,而ubuntu上的FIN_WAIT_2超时操作却不能关闭mac os上的socket(其状一直是CLOSE_WAIT).
实验三
服务器端:mac os+tomcat,tomcat的keep-alive的时间为默认的15s.
客户端:mac os
实验步骤:服务器启动后,客户端向服务器发送一个get请求,然后客户端阻塞,等待服务器端的socket超时.通过netstat -np tcp可以看到的情况是发送get请求时,服务器和客户端链接是ESTABLISHED, 15s之后,客户端变成了CLOSE_WAIT,而服务器端变成了FIN_WAIT_2.这一点也在我们的预料之中,而这个时候由于客户端线程阻塞,客户 端socket空置在那里,不做任何操作,4分钟过后,mac os服务器端上的那个socket不见了,但是mac os客户端上的socket还在,而且还是CLOSE_WAIT,这说明,FIN_WAIT_2确实有一个超时时间,win7上的超时操作可以关闭mac os上的socket,而ubuntu和mac os上的FIN_WAIT_2超时操作却不能关闭mac os上的socket.
总结, 当服务器的内核不一样上FIN_WAIT_2的超时时间和操作是不一样的.
经查:控制FIN_WAIT_2的参数为:
/proc/sys/net/ipv4/tcp_fin_timeout
如 果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60秒。2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。参见tcp_max_orphans。
实验四
服务器端:ubuntu9.10+tomcat,tomcat的keep-alive的时间为默认的15s.
客户端:mac os
实验步骤:服务器启动后,客户端向服务器发送一个get请求,然后关闭客户端关闭socket.通过netstat -np tcp可以看到的情况是发送get请求时,服务器和客户端链接是ESTABLISHED, 客户端拿到数据之后,客户端变成了TIME_WAIT,而服务器端变成了已经看不到这个socket了.这一点也也在我们的预料之中,谁主动关闭链接,那 么谁就需要进入TIME_WAIT状态(除非他的FIN_WAIT_2超时了),大约1分钟之后这个socket在客户端也消失了.
实验证明TIME_WAIT的状态会存在一段时间,而且在这个时间端里,这个FD是不能被回收的.但是我们的问题是客户端有很多CLOSE_WAIT,而且我们的服务器不是windows,而是linux,所以CLOSE_WAIT有没有超时时间呢,肯定有,而且默认情况下这个超时时间应该是比较大的.否则不会一下子看到两百个CLOSE_WAIT的状态.
客户端解决方案:
1.由于socket.close()会导致FIN信号,而client的socket CLOSE_WAIT就是因为该socket该关的时候,我们没有关,所以我们需要一个线程池来检查空闲连接中哪些进入了超时状态(idleTIME),但进入超时的socket未必是CLOSE_WAIT的状态的.不过如果我们把空闲超时的socket关闭,那么CLOSE_WAIT的状态就会消失.(问 题:像HttpClient这样的工具包中,如果要检查链接池,那么则需要锁定整个池,而这个时候,用户请求获取connection的操作只能等待,在 高并发的时候会造成程序响应速度下降,具体参考IdleConnectionTimeoutThread.java(HttpClient3.1))
2.经查,其实有参数可以调整CLOSE_WAIT的持续时间,如果我们改变这个时间,那么可以让CLOSE_WAIT只保持很短的时间(当然这个参数不只作用在CLOSE_WAIT上,缩短这个时间可能会带来其他的影响).在客户端机器上修改如下:
sysctl -w net.ipv4.tcp_keepalive_time=60(缺省是2小时,现在改成了60秒)
sysctl -w net.ipv4.tcp_keepalive_probes=2
sysctl -w net.ipv4.tcp_keepalive_intvl=2
我们将CLOSE_WAIT的检查时间设置为30s,这样一个CLOSE_WAIT只会存在30S.
3. 当然,最重要的是我们要检查客户端链接的空闲时间,空闲时间可以由客户端自行定义,比如idleTimeout,也可由服务器来决定,服务器只需要每次在 response.header中加入一个头信息,比如说名字叫做timeout头,当然一般情况下我们会用keep-alive这个头字段, 如果服务器设置了该字段,那么客户端拿到这个属性之后,就知道自己的connection最大的空闲时间,这样不会由于服务器关闭socket,而导致客 户端socket一直close_wait在那里.
服务器端解决方案
4.前面讲到客户端出现CLOSE_WAIT是由于服务器端Socket的读超时,也是TOMCAT中的keep-alive参数.那么如果我们把这个超时时间设置的长点,会有什么影响?
如果我们的tomcat既服务于浏览器,又服务于其他的 APP,而且我们把connection的keep-alive时间设置为10分钟,那么带来的后果是浏览器打开一个页面,然后这个页面一直不关闭,那么 服务器上的socket也不能关闭,它所占用的FD也不能服务于其他请求.如果并发一高,很快服务器的资源将会被耗尽.新的请求再也进不来. 那么如果把keep-alive的时间设置的短一点呢,比如15s? 那么其他的APP来访问这个服务器的时候,一旦这个socket, 15s之内没有新的请求,那么客户端APP的socket将出现大量的CLOSE_WAIT状态.
所以如果出现这种情况,建议将你的server分开部署,服务于browser的部署到单独的JVM实例上,保持keep-alive为15s,而服务于架构中其他应用的功能部署到另外的JVM实例中,并且将keep-alive的时间设置的更长,比如说1个小时.这样客户端APP建立的connection,如果在一个小时之内都没有重用这条connection,那么客户端的 socket才会进入CLOSE_WAIT的状态.针对不同的应用场景来设置不同的keep-alive时间,可以帮助我们提高程序的性能.
5.如果我们的应用既服务于浏览器,又服务于其他的APP,那么我们还有一个终极解决方案.那就是配置多个connector, 如下:
<!-- for browser --> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- for other APP --> <Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" keepAliveTimeout="330000" />
访问的时候,浏览器使用8080端口,其他的APP使用8081端口.这样可以保证浏览器请求的socket在15s之内如果没有再次使用,那么 tomcat会主动关闭该socket,而其他APP请求的socket在330s之内没有使用,才关闭该socket,这样做可以大大减少其他APP上 出现CLOSE_WAIT的几率.
你一定会问,如果我不设置keepAliveTimeout又怎么样呢,反正客户端有idleTimeout,客户端的close_wait不会持 续太长时间,请注意看上图中标红的地方,一个是close_wait,还有一个是time_wait状态,也就是说谁主动发起请求,那么它将会最终进入 time_wait状态,据说windows上这个time_wait将持续4分钟,我在linux上的测试表明,linux上它大概是60s左右,也就 是说高并发下,也就是服务器也需要过60s左右才能真正的释放这个FD.所以我们如果提供http服务给其他APP,那么我们最好让客户端优先关闭 socket,也就是将客户端的idleTimeout设置的比server的keepalivetimeout小一点.这样保证time_wait出现 在客户端. 而不是资源较为紧张的服务器端.
总结:
本文中ahuaxuan给大家揭示了TCP层client和server端socket关闭的一般流程,并且指出异常情况下client和server端 各自会发生的情况,包含了在不同平台上出现了的不同情况, 同时说明了在应用层上我们可以做什么样的逻辑来保证socket关闭时对server端带来最小的影响.
其他资料:
/proc/sys/net/ipv4/tcp_keepalive_time
当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时。
/proc/sys/net/ipv4/tcp_keepalive_intvl
当探测没有确认时,重新发送探测的频度。缺省是75秒。
/proc
/sys/net/ipv4/tcp_keepalive_probes
在认定连接失效之前,发送多少个TCP的keepalive探测包。缺省值是
9。这个值乘以tcp_keepalive_intvl之后决定了,一个连接发送了keepalive之后可以有多少时间没有回应。
/proc/sys/net/ipv4/tcp_max_orphans
系
统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单
的DoS攻击,你绝对不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。
This limit exists only
to prevent simple DoS attacks, you _must_ not rely on this or lower the
limit artificially, but rather increase it (probably, after increasing
installed memory), if network conditions require more than default
value, and tune network services to linger and kill such states more
aggressively. 让我再次提醒你:每个孤儿套接字最多能够吃掉你64K不可交换的内存。
/proc/sys/net/ipv4/tcp_orphan_retries
本端试图关闭TCP连接之前重试多少次。缺省值是7,相当于50秒~16分钟(取决于RTO)。如果你的机器是一个重载的WEB服务器,你应该考虑减低这个值,因为这样的套接字会消耗很多重要的资源。参见tcp_max_orphans。
/proc/sys/net/ipv4/tcp_max_syn_backlog
记
录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128。如果服务器不堪重负,试
试提高这个值。注意!如果你设置这个值大于1024,最好同时调整include/net/tcp.h中的TCP_SYNQ_HSIZE,以保证
TCP_SYNQ_HSIZE*16 ≤tcp_max_syn_backlo,然后重新编译内核。
/proc/sys/net/ipv4/tcp_max_tw_buckets
系
统同时保持timewait套接字的最大数量。如果超过这个数字,time-wait套接字将立刻被清除并打印警告信息。这个限制仅仅是为了防止简单的
DoS攻击,你绝对不能过分依靠它或者人为地减小这个值,如果网络实际需要大于缺省值,更应该增加这个值(如果增加了内存之后)。
发表评论
-
java服务,cpu高,内存高,telnet不通排查及分析
2013-12-22 12:29 3112记录上周五的一个java服务的异常排查及分析过程,以备将来 ... -
QPS、PV和需要部署机器数量计算公式
2013-07-31 16:39 1732QPS = req/sec = 请求数/秒 【QPS ... -
java自带监视工具使用_jmap_jhat
2013-07-06 17:50 892jmap命令(Java Memory Map)1.介绍打 ... -
java自带监视工具使用_jps_jstack
2013-07-06 17:32 1884jps命令(Java Virtual Machin ... -
处理OutOfMemoryError: PermGen space
2013-07-06 12:15 1438前两天后台系统内存溢出错误,查看tomcat日志,看到如下 ... -
Heap OOM故障实例2_websphere应用部署
2013-03-20 18:21 2063根据用户需求,将公司 ... -
Heap OOM故障实例1
2013-02-25 15:43 1391故障描述: 线上系统运行过程中出现OOM异常,导致jvm ... -
visualVM远程监视安装
2012-08-10 14:44 11081. 通过jstatd启动RMI服务 ... -
tomcat内存配置及项目实践
2010-04-29 16:07 1713最近在做一个数据请求 ... -
利用JProfiler对应用服务器内存泄漏问题诊断一例-2
2009-09-10 17:22 3198实施情况 采用的方案:某某软件商采用了新的会话登录信息 ... -
利用JProfiler对应用服务器内存泄漏问题诊断一例-1
2009-09-10 17:16 1588在中间件应用服务器 ... -
jconsole+tomcat配置说明-3-基于jdk1.5
2009-09-07 16:33 4522Figure 15: List of All Logger N ... -
jconsole+tomcat配置说明-2-基于jdk1.5
2009-09-07 16:18 1749Figure 9: Threads Tab. ... -
jconsole+tomcat配置说明-1-基于jdk1.5
2009-09-07 16:08 2751JConsole是JDK自带的东西,功能虽然没有一些商业软件那 ... -
监控和剖析数据库操作 -- P6Spy、SQL Profiler、IronTrack SQL 使用简
2008-12-31 16:37 1878俞 黎敏 (mailto:YuLimin@163. ...
相关推荐
《Unix高级技术内幕》是深入理解Unix操作系统精髓的一本经典教程。它涵盖了Unix系统的17个关键主题,旨在帮助读者全面掌握Unix系统的核心技术和高级应用。以下是对这17个章节主要内容的详细解读: 1. **Unix历史与...
《Unix技术内幕》是一本深度探讨Unix操作系统的经典著作,主要面向那些希望深入理解Unix系统原理、进行系统级编程和管理的开发者与技术人员。pdg格式可能是扫描版电子书的常见格式,通常用于存储图像文档,便于在线...
省级-R&D研发资本流动数据(2001-2022年).zip
DeepSeek相关源码适合感兴趣的人学习使用
## 数据内容 上市公司招聘明细数据(企业名称、关联股票代码、与上市公司关系、发布年份、结束年份、岗位、工作城市、工作区域、最低月薪、最高月薪、岗位职责、学历要求、工作经验、招聘人数、类别、公司地点、工作地点、发布日期、结束日期、数据来源) ## 时间跨度 2014-2023
【PHP】基于THINKPHP6开发后台管理框架,前后端分离、RBAC权限管理等_pgj
"晶体光学仿真技术:中波红外激光的差频信号产生与转换效率求解",晶体光学仿真,如转效率求解 用于产生中波红外激光,利用晶体,产生差频信号,进行产生中波红外光,这里考虑了相位匹配条件,以及准相位匹配 ,晶体光学仿真; 转换效率求解; 中波红外激光产生; 晶体产生差频信号; 相位匹配条件; 准相位匹配。,"晶体差频信号仿真:中波红外激光产生与转换效率求解"
D746CCC6_20250204134411941IC.dump
TensorFlow 编程_fashion_MNIst_代码
内容概要:本文档提供了针对深度求索公司(DeepSeek)从初学者到专家的详细指导。主要内容涵盖对DeepSeek产品的理解和使用方法,包括其开源模型、API服务和行业解决方案等基础功能介绍,快速上手指南,以及进一步深入掌握的技巧,比如模型微调、部署与性能优化策略。对于希望深入探究的企业和个人开发者还给出了参与社区和技术研讨的具体方向,鼓励他们在实践中成长。 适合人群:想要深入了解DeepSeek平台特点及其应用场景的数据科学家、软件工程师和其他IT专业人员,尤其是那些对人工智能感兴趣并对深度学习有一定认知的人士。 使用场景及目标:帮助使用者熟悉DeepSeek的各项功能和服务;学会构建、训练并优化自己的AI项目;最终达到独立进行AI系统的创新和技术研发水平。 其他说明:除了详细的步骤解释外,本文档还包括许多实际案例来辅助理解概念,如怎样使用提供的API接口创建聊天机器人或完成代码生成功能,同时也提及了一些科研成果以供感兴趣的读者查阅。
基于西门子博途PLC编程的立体仓库控制系统:WINCC组态仿真与图纸报告综合解决方案,基于plc的立体仓库控制系统,采用西门子博途PLC编程,WINCC组态仿真,包括图纸,报告等 ,基于plc的立体仓库控制; 西门子博途PLC编程; WINCC组态仿真; 图纸; 报告,基于PLC的立体仓库控制系统:博途编程与WINCC仿真方案
"博途1200PLC与HMI全自动洗衣机控制系统仿真升级版:深入理解结构与工作原理的实践教程",基于博途1200PLC+HMI全自动洗衣机控制系统仿真-升级版 程序: 1、任务:了解全自动洗衣机的结构、工作过程、分析其控制原理 2、系统说明: 系统设有自动控制区,中、高水位选择区,标准模式、速洗模式、排水模式、脱水模式等功能选择。 及多种功能模拟与仿真 自动洗衣机博途仿真工程配套有博途PLC程序+IO点表+PLC接线图+主电路图+控制流程图 附赠:设计参考文档(与程序不是配套,仅供参考)。 博途V16+HMI 可直接模拟运行 程序简洁、精炼,注释详细 ,关键词:博途1200PLC;HMI全自动洗衣机控制系统;仿真;升级版;任务;工作过程;控制原理;自动控制区;水位选择区;模式选择;功能模拟与仿真;IO点表;PLC接线图;主电路图;控制流程图;博途V16;HMI;模拟运行;程序简洁精炼;注释详细。 以上关键词用分号分隔为: 博途1200PLC; HMI全自动洗衣机控制系统; 仿真; 升级版; 任务; 工作过程; 控制原理; 自动控制区; 水位选择区; 模式选择; 功能模
【JavaScript】通过Feishu开放平台和Chatopera机器人平台上线智能对话机器人服务,聊天机器人,飞书,lark
内容概要:本文档详细介绍了如何从官方网站或网盘下载并安装VMware Workstation软件及其开源版本VMware Player,接着引导用户获取Ubuntu操作系统的ISO镜像文件,最后一步步地指导创建新的Ubuntu虚拟机。对于每个步骤都提供了详尽的指示,例如选择正确的产品版本、接受许可证协议时注意的选项以及在创建虚拟机过程中所需设定的关键参数,比如选择合适的镜像文件、配置磁盘容量等具体操作方法。 适合人群:面向刚开始接触Linux发行版的新手用户和技术爱好者。 使用场景及目标:使用户能够在PC上顺利部署与体验基于不同内核的多操作系统环境;帮助初学者理解并熟悉使用虚拟化工具来模拟实际物理服务器的过程和应用场景;为希望尝试搭建个人学习或实验平台的读者提供实用的指引。 阅读建议:由于文中提到的一些链接可能有有效期,建议尽早按照指引操作并保存必要的资源;同时可以配合在线社区论坛或其他教程资料进行补充学习以获得更加全面的认识。
北航并行课程作业: 在GPU 实现一个矩阵并行乘法程序,要求矩阵大小不小于8000*8000,且元素为双精度浮点数(double)类型;比较并行程序与串行程序的加速比,同时注意排除数据准备时间作程序运行时间。
详细介绍及样例数据:https://blog.csdn.net/T0620514/article/details/145538280
西门子1200系列电梯仿真系统:全能群控与故障报警的智慧化解决方案,电梯程序.基于西门子1200系列两部十层电梯全网最牛逼仿真,博图V15及以上版本,自己编写的,带群控,有超载、故障检修、紧急报警功能,一组外呼按钮,清单有plc组态画面,点表,原理图电气图,该程序仅需一台电脑就可以仿真,不用下载到实物,只要安装了博图加仿真就可以用了,喜欢的可以买去参考。 清单:plc程序 HMI组态画面wincc编写 电气接线图 硬件框架图 io表 注意:带报告 ,核心关键词:电梯程序; 西门子1200系列; 仿真; 博图V15; 群控; 超载; 故障检修; 紧急报警; 清单; plc组态画面; 电气图; HMI组态画面wincc编写; 硬件框架图; io表; 报告。,西门子1200系列电梯仿真程序:群控超载故障检修一体解决方案
上市公司-重污染企业数据(1991年-2023年)
【Java】一款微服务系统,采用前后端分离模式,后台采用SpringcloudAlibaba作为微服务框
python网络爬虫_pgc