论坛首页 Java企业应用论坛

人在江湖:如何用代码保护好自己

浏览 45531 次
该帖已经被评为良好帖
作者 正文
   发表时间:2011-10-14   最后修改:2011-10-14
2个问题解决方法其实都是没有必要的,说白了,你这问题主要责任在于架构师.跟具体实现的程序员自身也有一定关系.
(1):这么重要的充值方法,说白了,就相当于你要输出API.也就是说,确保你的调用者完全正确的调用API也是开发这个包的人要考虑的问题.这种操作调用失败的(不管是业务上的问题,超时...)都应当被包装被合适的Checked Exception让你的调用者必须来处理.
(2):你的这种模式,目的应该只是用来,比如说操作失败时的一种尝试机制.而且还是基于第一个CASE,像OperationTimeout应该是他主动扔出来.如果你连接中发生的问题,那也是RETRY之后包装异常扔到上面统一处理.
0 请登录后投票
   发表时间:2011-10-14  
kidneyball 写道
个人感觉,从纯技术角度上看,楼主的做法其实属于治标不治本,实在是丑陋的架构和管理手法下不得已采用的丑陋做法。

从风险一的应对措施来看,这段代码一次性不管三七二十一把所有Exception都catch起来,加上了一段没有任何业务语义的描述 (An error occured during XXX之类,如果方法名称起得好的话,从异常的调用栈里就能得到同样的信息。如果你觉得这种异常信息有用,有三种可能:1. 你打算让这条异常一直抛到用户界面上去,显示异常信息。或者 2.你所在的团队没有仔细看异常调用栈的习惯。或者 3.你们的代码类名和方法名起得不知所谓。) ,然后包装成另一个Unchecked Exception抛出来。正常来说,只要在架构的高层位置有一个大的try catch统一来干这个事情,这里就根本不用管。

通用的异常处理应该放在高层,通常底层代码是不用管更底层的代码抛出的RuntimeException的,除非:
1. 你有处理这个异常的具体方法(也就是在你的层面看,这个根本不是异常,而是业务的一部分)。
2. 你认为这段代码的调用者有能力处理这个异常,你就应该把这个异常封装成一个Checked Exception再抛出去。
3. 你为这个异常加入更具业务语义的message再抛出去。

从发现错误的角度看,一前一后两个log已经解决所有问题了,这里的异常处理纯属多余。除非,你的上层代码把异常吃掉了(既没日志又没继续往上抛),这纯属是做架构的人胡闹,害人不浅(如果你能拿到他们的代码,把吃异常的地方找出来,追究责任时可以拿来说事)。

不过就算是上层代码不可控,楼主也应该在可控的范围内把这种通用的异常处理往高层放,不用在底层搞那么多层层叠叠的try catch。

第二个风险的应对也不是正路,你开了新线程去调别人的东西,超时了你的线程就异常终止了,另一条线程还在跑呀(就算你强行kill了这条新线程,你也不知道黑箱里有没有再开新线程,或者通过异步方式干其他东西,例如读写数据库之类),它跑的结果怎么样,有没有什么副作用你都不管了。你这个异常终止之后,整个系统就处于一种未知状态了,后面的操作还怎么做,干脆直接Runtime.exit()再重新启动还安全一点。

既然别人的包本来预期是同步使用的,而且你不知道它的运行细节,把它强行改为异步没什么好处。如果你怕别人的包死锁,一般来说也是一前一后两个log就能发现问题了。感觉你在这里有点贪心,除了想发现错误,还想搞点错误恢复,但异步调用不能这么简单处理的。但如果要处理好,成本太高了。

从管理角度看,也很有问题:

1. 自己人的代码还搞什么黑箱。我一般都要求程序员如果调用不是自己写的接口,至少要往下看三层实现代码,包括别人的代码和开源代码。如果要修改代码,需要先往上找出所有调用关系并阅读代码,保证不会修改了一条调用路径上的bug却把另外的调用路径搞死了。如果是黑箱代码(我所在的项目基本没有),除非有完善的技术支持或者口碑非常好,否则一律不用,而且调用黑箱代码的前后必须做好日志。违反者一经发现,口头鄙视。

2. 找人负责也不是不行,但也不能老板越过技术主管直接找程序员的麻烦吧。不懂技术(甚至懂技术,但不了解具体上下文)的人直接批评程序员,往往只找到了表面现象就开骂(例如楼主说的李四),等到找到真正原因,又挂不住面子,反而更不爽你。楼主举的例子,我想象的场景是这样的:老板问张三,你这个语音模块怎么回事,这么卡。张三就说,具体不清楚,不过我调用了李四的包,可能跟这个有关系(典型的推卸责任)。然后老板就问李四,你怎么回事,李四说具体不清楚,能不能告诉我怎样重现错误,我调试一下(典型的认真负责)?老板一个笔记本拍李四脸上:去死吧你,就是你这个害群之马,人头猪脑。。。。(省略一百字)。这种搞法怎么能管好技术团队?

好在楼主说是上一家公司,估计已经脱离苦海了吧,恭喜恭喜。

=======================================
补充一点。。。
我本来想这种方法调用的日志其实最好用debug或trace级别,放在info级别,岂不是逼人在生产环境下关闭info级别的日志(我循环调用一个黑箱方法100次就会看到200条重复的日志,再来50个用户并发访问。。。)。不过后来想想也有道理,这里的日志不是为了查错,而是为了在第一时间撇清责任,等到发现错误再打开日志就太晚了。所以说丑陋的管理导致丑陋的代码。。。

说的很好,在他们这么个破公司里,如果A依赖B的返回值做一些事情,在A处加防护不是很有必要的吗?这样如果B出错了导致A出错了第一时间就会告诉大家B没有返回预期的结果,谁还会去纠结A的问题呢?
0 请登录后投票
   发表时间:2011-10-14  
1. 真正安全的应该是try catch(Throwable ex) 如果只是exception 照样也有一场泄露。
2. 就算要开人,也应该开掉测试而不是开发。
3. 遇见这样的公司,可见是人数不多的公司,极有可能开发和测不分。
4. 这样的软件根本不是什么银行软件,应该各种移动电信广电运营商的小应用拿来收钱的。对应的叫法有BSS,BOSS,支付平台,呼叫中心,银行托收,银行代缴,银行代扣等等。这样的软件不能算是金融软件。
5. 能够随便划掉200万不大可能,银行这种小额支付通常都有限额的。自动取款机上一天才只能取几万块钱,超过十万就需要到银行预约。网上银行和电话银行的转账也没有200万这么高的额度。高额度必须要到柜台办理。
6. 我不懂报文被修改了是什么意思,如果文档上规定是已对方传回的金额为准,那就直接充值呗。从流程上来说,这个充值200万也是充值到某个客户的账本。这笔钱也只是划款到了电信移动运营商,而运营商只是修改了一下客户的账本金额(话费余额)而已。换句话说:银行扣200万给运营商,运营商只是给客户的话费的额度调高了一点。处理办法运营商退200万给银行,并且把客户的余额调整回来就可以了。200万不是损失,损失是一包烟一瓶茅台吧。
8. 我觉得真正的情况应该是客户明明只从银行扣款了200块钱,确被别人把账本金额改成200万,变成客户好像有了200万话费一样。 那这样一条sql把数据改回来就得了


最后一句话,第三方集成商真可怜。
0 请登录后投票
   发表时间:2011-10-17  
java_fei 写道
额,我有点不赞同楼主的说法,首先在做doChange方法那个模块的时候,那个程序员就应该对所有可能发生的异常进行了处理,而不是进行异常的抛出,向楼主所说的,如果讲异常抛出来,这样反复调用,反复抛出是非常耗性能的,而且你try Catch用的多了,你代码后期的维护非常麻烦,所以我想说的是,楼主的方法比较好,但是我觉得异常最好是在方法里面就解决,而不是在方法外面

不同的异常应该应该在不同的层次处理。
在lz提出的例子中,因为你是调用别人的接口,你不清楚别人如何操作的,不属于你的处理范围,如果捕获住反而掩盖了错误,系统可能会陷入莫名其妙的错误境地。
0 请登录后投票
   发表时间:2011-10-31  
向楼主学习,目前多人开发需要注意的问题
0 请登录后投票
   发表时间:2011-11-02   最后修改:2011-11-02
LZ分析的有一定道理,大部分赞同。
但有几点还是有问题的:
1、既然不能保证问程序问题的所在,通过try catch来捕获异常,这样的异常捕获代码将会散落到各处。
2、对于自己模块使用和对外使用的接口从设计上应该有所区别,包括异常机制、包括安全措施。
3、两位同事存在一些问题,但更大的问题是在项目的整个设计上,缺少一种可行的安全机制。单从程序编码不能解决最终的问题。
0 请登录后投票
   发表时间:2011-11-02  
呵呵,对lz的做法相当不认同。

对于风险一,应该是从整体设计上考虑的,所有异常总归是一层一层往上抛的,除非要做compensation,否则一个系统中直接在最上层捕获并处理就足够了,堆栈日志里能看得很清楚源头在哪里。
对于风险二,应该在规范和code review的层次消除掉,凡是和第三方交互的(包括网络、外设、存储等等),都需要就地做异常和超时处理,这样保护了的不止是自己,而是整个公司。即便没有做超时处理,分析javacore也能知道线程卡死在什么地方,根本用不上这种手段。
0 请登录后投票
   发表时间:2011-11-03  
这种方法思路很好,受教了,lz经验多多分享啊!
0 请登录后投票
   发表时间:2011-11-04  
Java新手~学到不少东西,看来写代码平时不注意这些细节,确实容易吃亏~
0 请登录后投票
   发表时间:2012-02-10   最后修改:2012-02-10
如果照你们这样开发系统,各顾各的,谁都怕承担责任而做这些与系统业务无关的工作,
系统早晚会出问题,而且一定会出问题。
软件开发不是你个人有多牛,而是你的团队有没有协作好,管理有没有到位,沟通及不及时。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics