点击蓝字 关注我们
一
前言
首先郑重申明:本文并不是想教唆你怎么把SAP服务器搞死.
虽然你确实可以从本文中学到搞死SAP服务器的技巧,但是如果因为你对公司的抱怨而导致你无意中使用了本文中的方式无意中搞死了贵公司的SAP服务器.
请不要甩锅给本文作者. 罪过在于你无意的报复之心及贵公司无意让你拥有了报复之心.
鉴于本文可能让部分心有芥蒂的程序员有更强的破坏力.
在文末会给出相应的解决方案
本文主要介绍怎么无意中让PO系统宕机
二
技能储备
干坏事之前先储备一些技能,关键时候才能发挥出重要的作用. 比如:节假日中让系统挂掉(这对开发或系统维护人员无疑是最大的噩耗,美美的假期泡汤,还不一定有加班工资).
使用本文的方式之前需要先储备如下的知识
使用PO的JDBC通道从中间表读取数据,生成消息传递到目标系统.
可能你无意中查询到了SAP的这个帮助. 如图一
在JDBC通道中按图一中方式配置了发出通道的读取语句和更新语句,如图二
https://help.sap.com/doc/saphelp_nw73/7.3.16/en-US/7e/5df96381ec72468a00815dd80f8b63/content.htm?no_cache=true
select * from table where processed = 0
update table set processed = 1 where processed = 0
图一
图二
三
天时地利人和
中国传统文化讲究天时地利人和,三者合一方成大事. 因此要干票大的,也得考虑考虑这些因素.
01
天时
你夜观天象,发现最近七星不亮,似有不吉之兆. 因此暂停了JDBC SENDER通道一段时间,恰逢元旦假期,为了安度假期,又重新打开了JDBC SENDER通道(把期间累计的几百万条记录处理掉,数据量大是很重要的因素).
关于通道的暂停的方法
暂停通道的两种方式
通道配置中设置状态inactive(图三)
通道监控器停止通道(图四)
自动启动停止通道
详见链接无峰,公众号:ABAP 技巧与实战PO系列之 通道的可用性计划
图三
图四
02
地利
这个存粹凑数的, 想不到啥地利的因素. 如果要硬凑, 那么你恰好出现在银河系猎户座旋臂-太阳系-地球-亚洲-中国-某地. 是为地利
03
人和
开发和系统维护人员在假期中休假的休假,结婚的结婚,离异的离异. 总之各顾各的去了. 人都不在是为人和.
四
案发
然后PO系统就挂了. 在岗的的业务人员及时的发现了问题: 怎么仓库收不到收货单据, 供应商货都拉到了仓库,在等着按单收货呢.
事件持续发酵几个小时. 估计中国移动的营收又增加了0.00000000165890个百分点.(这个梗来自拼多多)
BASIS紧急介入. 祭出重启大法. 重启了PO系统, 重启后几分钟,系统又不响应了. 靠,重启都没法解决的问题,那基本无解了.
休假结婚离异的开发人员被紧急召回:没改任何代码呀, 咱可是严格遵照中国程序员编程规范,节假日前不发布新版本.
维护人员也很冤枉: 我只是重新开启了一个接口. 这不是正常操作么?
五
解决办法
找到之前使用JDBC SENDER 通道访问的表, 把处理标记 都设置为已处理 processed = 9. 然后再重启PO系统. BINGO,问题成功解决. 有没有觉得这个问题的发生和解决都有点不可思议?
六
总结
PO JDBC SENDER 通道中的SELECT 语句用于获取数据产生一个消息. 如果读取数据库的SELECT 语句读取了大量数据,PO尝试把所有这些数据构造成一个巨大的XML时,出现系统宕机, 重启后, 通道重新激活,再次读取,再次构造,再次宕机. (感觉PO好脆弱).
不太建议PO中使用JDBC SENDER 通道. 因为很难解决PO读取数据, 外部系统同时写入数据的场景(序列化读取是系统推荐的一种方式,需要读写双方都设置序列化操作).
如果一定需要使用JDBC SENDER通道, 可以尝试通过rownum<= N 限定一下消息的大小(ORACLE数据库有效, 其它数据库类型不确定)
SELECT ROWnum ,exord,flag FROM DANIANG.Zttemp
WHERE (flag IS NULL OR FLAG = '') AND rownum <= 100;
UPDATE DANIANG.Zttemp SET FLAG = 'X'
WHERE (flag IS NULL OR FLAG = '') AND rownum <= 100;
通过rownum 获取的数据和更新的数据是否严格一致, 这一点有些存疑. 在JDBC SENDER 通道中怎么限定每次读取的数据包大小? 这个问题期望读者能给出更好的答案.
(验证ORACLE的rownum 的获取,select 的字段顺序不一样, 会导致一条记录的rownum不一致. update 中使用的rownum 可能是基于select * 获取的. 这就要求SELECT 语句一定不能修改字段原本顺序,否则可能导致更新的数据和读取的数据不一致)
THE
END