首页新闻找找看学习计划

webservice返回XML,70个客户端同时调用中心接口,向oracle写数据,怎样提高效率?

0
悬赏园豆:100 [已解决问题] 解决于 2017-12-11 20:33

1 客户端是单线程,一次性传输100条数据,费时1分钟;

2 客户端单线程主要是避免  数据重复传输

3 主要实现从客户端mysql数据库向中心oracle上传数据,中心发布接口服务在tomcat

4 整个流程:部署客户端服务(tomcat),查询是否有需要传输的数据---分页查询100条,改变要传输数据状态---组装成json---调用中心发布的接口服务----中心接受到客户端请求解析数据,保存成功,返回给客户端结果,客户端删除传输成功的数据---客户端提示上传成功

目前最大的问题就是效率低下,中心在收到请求以后到写入oracle成功的这段时间,传输100数据耗时1分钟。一共70个客户端,一个中心

求解:怎样提高传输速度

花开半夏雨的主页 花开半夏雨 | 初学一级 | 园豆:6
提问于:2017-07-13 18:38
< >
分享
最佳答案
0

不要凭感觉,还是找出在那里执行最耗时,在针对性做出优化.

收获园豆:60
秋壶冰月 | 大侠五级 |园豆:5443 | 2017-07-13 20:28

能不能直接从mysql直接入库到oracle数据库

花开半夏雨 | 园豆:6 (初学一级) | 2017-07-15 15:06

@花开半夏雨: MySQL能不能导出Oracle不知道,即使能到,那你的客户端还要吗? 看来你还没找在哪里耗时,还是找出现在系统的瓶颈在哪里,在去优化吧!

秋壶冰月 | 园豆:5443 (大侠五级) | 2017-07-15 15:14

@秋壶冰月: 已经找到了,昨天对数据库优化过了,效果不是很明显,包括数据库大小,并发数量,缓存,建立索引,索引单独分区,。现在想的直接是mysql导出文件,再导入oracle数据库。

花开半夏雨 | 园豆:6 (初学一级) | 2017-07-15 15:17

mysql导入到oracle可以用kettle,速度很快,你数据传输的慢的问题应该是你后台代码的问题,一般过滤查询的时候别用in,用exists 执行速度会很快

零度千里 | 园豆:204 (菜鸟二级) | 2017-08-01 11:48
其他回答(5)
0

感觉没有说太清楚 

100数据有多大?

 你是怎么得出1分钟的,这1分钟包含了处理数据和数据库操作吗?

 传输慢的原因是什么? 是网速慢? 

苍枫露雨 | 园豆:1027 (小虾三级) | 2017-07-13 19:29

100条数据,一条数据  样例   “20001;交通换乘枢纽;三公司;20010000000000000071;渝A60592;酉阳;大高二级;2017-06-05 00:00:00”   得出一分钟是在确认客户端发起请求以后,中心基本同时受到请求,开始计时,中心接受请求处理数据,写入oracle数据库,保存成功,计时结束 ,整个过程都有记录时间,目前怀疑是中心接受请求太多,需要处理的数据多,排队等候,导致写入数据库慢,效率低

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-13 19:35

@花开半夏雨: 

看起来数据不是很大,应该不是网络的问题,

初步认为瓶颈在数据库操作

根据实际情况,可以考虑:

1. 数据库操作采用批量操作 类似 jdbctemplate的batchUpdate, 不要逐条操作,

2. 查看数据库服务器的压力,如果还可以的话,可以增加oracle数据库的最大连接数,同时调整工程的连接池的大小,或者直接把数据库操作改为并发, 增加数据库操作的并发量。

3. 数据库做集群,读写分离,减少读数据库照成的开销

支持(0) 反对(0) 苍枫露雨 | 园豆:1027 (小虾三级) | 2017-07-13 19:46

@苍枫露雨: 是oracle11g的,表空间是users。

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-14 09:34

@苍枫露雨: 最后发现是中心接受数据解析为自定义对象以后。逐条循环根据数据主键判断中心是否存在,无则添加,有则修改。循环完所有数据进行插入或者更新比较耗时。基本100条数据1分钟左右

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-14 09:37

@花开半夏雨: 

那就是了,可以改为批量操作,

比如根据主键判断这个可以直接用  select key from table where key in (k1,k2...,kn)

用返回的keys 比较in中的key,就知道哪些没了,

不知道你们是不是用的spring ,是的话批量插入和更新可以用 jdbctemplate的batchUpdate

支持(0) 反对(0) 苍枫露雨 | 园豆:1027 (小虾三级) | 2017-07-14 10:10

@花开半夏雨: "逐条循环根据数据主键判断中心是否存在"===在多个客户端并发上传时,这个地方可能会有问题。如果有这样的时序:

1. 客户端a 判断 key = 'key_999' 是否存在,结果是不存在

2. 客户端b 判断 key = 'key_999' 是否存在,结果是不存在

3. 客户端a insert,

4. 客户端b insert,

结果会报错。

支持(0) 反对(0) Jacklondon Chen | 园豆:272 (菜鸟二级) | 2017-07-14 11:45

@Jacklondon Chen:两个客户端不会判断同一个主键

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-15 15:03
0

有几个优化办法:

1. 分页查询100条 ==增大到5000. 减少客户端与服务器端的网络交互,是性能优化的基本思想。

2. 100条数据,一条数据  样例... ==== 同一批次的所有数据,统一放在同一个 json 字符串中。不要一个数据,提交一次。同以上思想:减少客户端与服务器端的网络交互。

3. 客户端删除传输成功的数据 ==== 接口数据,按理一般保存若干时间,使用标志位来标明上传成功与否;或者另建一个表,作为上传成功/失败状态及记录。

4. 客户端是单线程...客户端提示上传成功 === 单线程的客户端提示,客户端刷新也需要时间。建议改成:成功只提示状态(开始上传、正在上传、结束上传、空闲等待),失败才提示详细信息;改成多线程是肯定的,单机版程序,主线程只用于显示,后台工作线程用于干活,可以控制启动只启动一个后台工作线程。

5. 增加服务器程序、客户端程序的文件日志。便于调试、调查问题、正式使用后的后续支持。

6. 中心发布接口服务在tomcat === 查 tomcat 文档,改允许的最大并发参数。

7. 数据库做集群 ===这么小的量,用不着。

Jacklondon Chen | 园豆:272 (菜鸟二级) | 2017-07-14 07:56

1  客户端的数据是分类上传,并不是所有的数据都已一种。数据是随时产生的,就算一次上传5000,中心解析为自定义对象以后在,再向数据库插入,这个过程耗时,客户端长时间收不到中心反馈,连接超时()目前时间调整为5分钟)

2 100条数据是一次性写入一个jsonArray里边的

3 客户端有上传任务表,上传状态标识,当其他表有新增或者修改向任务表插入数据,根据主键关联查询上传数据。

4 客户端只有提示上传成功多少条的标识

5 有上传日志表记录,但未记录整体耗时

6 并发数设置的1000

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-14 09:33

@花开半夏雨: 

有上传日志表记录 === 性能调优时,日志应记录在本地文件。可使用 log4j/log4net 之类的组件。日志写详细一点。log4j 的文件日志,每一个都带时间,写详细一点,能看出哪一段用时很多。

数据库日志,本身就会消耗较多的系统资源。如果数据库日志多的话,慢是肯定的。

支持(0) 反对(0) Jacklondon Chen | 园豆:272 (菜鸟二级) | 2017-07-14 09:37

@花开半夏雨: 

客户端的数据是分类上传,并不是所有的数据都已一种 === 那就在 json 中,增加一个字段: 数据种类。争取一次上传所有种类的数据。

首先要通过文件日志来查明,哪一步用时较多,然后进行有针对的优化。

支持(0) 反对(0) Jacklondon Chen | 园豆:272 (菜鸟二级) | 2017-07-14 09:39

@Jacklondon Chen:是用表记录的,并不是日志文件

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-14 09:42

@Jacklondon Chen: 最后发现是中心接受数据解析为自定义对象以后。逐条循环根据数据主键判断中心是否存在,无则添加,有则修改。循环完所有数据进行插入或者更新比较耗时。基本100条数据1分钟左右

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-14 09:43

@花开半夏雨: 服务器端,接口数据的处理方法,应该是先将接收到的接口数据,保存到接口表中,稍作检查,立即返回信息给客户端。

不要同时做很多事情。

做接口程序,数据接收只做“数据落地”,纯 insert ,则性能会好。

其它复杂处理,由单独的后台线程/进程,读接口表,逐个处理。即使慢,客户端也看不到。

估计你们的数据库表索引设计有问题。

支持(0) 反对(0) Jacklondon Chen | 园豆:272 (菜鸟二级) | 2017-07-14 09:50

@Jacklondon Chen:索引有问题?

单个数据表做的索引是客户端ID的传输哪张表的主键 做的非唯一性索引

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-14 10:05

@花开半夏雨: 

如果"数据主键判断中心是否存在,无则添加,有则修改",应该建立唯一性索引。

不知道你们此处,数据主键是一个字段,还是多个字段的组合。

另,也需要判断,数据解析为自定义对象,用时多长时间。

还是那句话,"通过文件日志来查明,哪一步用时较多,然后进行有针对的优化"

支持(0) 反对(0) Jacklondon Chen | 园豆:272 (菜鸟二级) | 2017-07-14 10:09

@Jacklondon Chen: 现在在想,不用封装以后再解析,不通过webservice,直接写一个程序从MySQL数据库直接抽取oracle数据库

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-15 15:05
0

1.或许可以考虑一次性提交吧多条数据整理成一个大集合上传;这样调用接口的次数就会少,如果你后台处理的足够快,很快就能完成;

2.改用异步方式;先提交上传数据,然后放到队列中后台来处理上传的数据,等处理完在通知调用方上传状态 

神牛003 | 园豆:313 (菜鸟二级) | 2017-07-14 09:02

目前是一次性提交多条数据的jsonArray,再解析为自定义对象集合

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-14 09:38

是你说的这个做法,先提交数据,等处理结果

支持(0) 反对(0) 花开半夏雨 | 园豆:6 (初学一级) | 2017-07-14 09:41
0

1.查询的部分:可以考虑SQL语句、表结构、缓存等方面优化

2.提交的部分:增加吞吐量,可以考虑异步执行,让服务器端记录请求数据后立马返回请求结果,执行结果待稍后再请求查询。执行任务放在队列中,交给1个或多个工作单元来完成

收获园豆:40
慧☆星 | 园豆:5384 (大侠五级) | 2017-07-15 09:48
0

客户端服务端都是自己写的吗?可以写个main方法,看看直接调用insert方法快不快。

性能调优从影响性能的主要因素去考虑。

不过一般是数据库引起的,你的数据量有多少?

小彬 | 园豆:947 (小虾三级) | 2017-07-19 09:26
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册