不知不觉之间已经参加工作一年了(雾)。在这一年当中,桃子不止写了几段代码,也玩出了一些蜜汁操作。让我们今天一起回顾一下这猎奇的过往一年吧(内心崩溃)。
TOp 5 团队开发,不管冲突就是干
说出来你肯定不信,我第一个学会的Git命令可不是什么git clone xxx这么安稳的东西,而是git push -f 。因为这个命令解决了我开始写代码的最头疼的事情。我入职后对着作文式的代码看了半个月,然后就画图。画实体图,UML,我相信张秋余看见我的成果肯定会惊讶这小子这么画图软件工程怎么才考60分。(张秋余是大学时期的大佬)。经过半月认真的工作(大型摸鱼现场),我大概熟悉了项目以及我们部门部分大佬的编程习惯(业务层喜欢@Component,而不是@Service之类的奇怪Point),此后我上手我的第一个工作:加字段。加字段这个这个活在写RestAPI的时候可以理解为深层业务的操作(但是我这么菜脚趾头都能得出不会是深层业务),也可以通俗意义上的set。而我所做的事情就是查询一个用户的信息,里面有个标签,通过Rest接口返回。炒鸡基础的查询(甚至连查询都不用写,以前就有),我花了两分钟时间修改完就继续画图去了。可我忘记了这不是单人的开发任务,而是敏捷团队。
那段时间公司的代码仓库刚从SVN跳到Git,我之所以说第一个命令不是Git Clone的原因就是我的代码是从SVN拉的。然后团队只有四个人,但是有二十个人在不同业务维度(分支不同)。众所周知,比较复杂的代码层面,当产品战线较长又有业务并行时,业务上线就是个灾难。不巧,我正好赶上了这次灾难(时隔一年还记忆犹新//加班到十点第一次)。
具体吃瓜现场: - > Eclipse下使用Git
当然,有一说一,那个曾经Revert的胖子现在在京东了,我们回忆起他的时候,就会带出这段往事。我谜一样的操作,覆盖的别人代码带来的后果就是修改两行代码使用这么多次提交(暴露瞎逼操作,是不会使用版本控制工具是多么垃圾)
桃子修改两行代码的耗时
Top 4 容器有很多,各有各的玩法
不过话说回来,因为上次的加字段开发实质上我只在服务端deploy,使用现成的脚本(不对,甚至是别人帮我发的版,我还没有权限)。并未意识到Web容器这个概念。我们的生产环境,分布式Nginx+Zookeeper 最终容器处理还是在Tomcat上。由于之前在大学学习的时候就接触过,觉得还好,但是无奈当时我们交易中心的项目非常庞大,我当时穷人版的3k华硕启动一次项目需要五六分钟,加上Maven打包(在这里吃Maven的瓜)编译。我改完一句话,想看效果基本就等五六分钟。一两次还好,可是到后面我就受不了了.于是采用了轻量级的容器Jetty。的确很好用,嗯,启动1000ms不到,因为我他喵压根连项目都装载不进去。后来发现我为啥要下载插件。当我在Maven库看到这句的时候我都块吐血了。
<dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-webapp</artifactId> <scope>test</scope> </dependency>
?秀 看不起我。在稍微看了下相关类之后我才真正明白一些地方奇怪的配置类。
而这里是简单的开始,容器简直就是个笑话。(疯狂暗示以前200%因为配置问题挂掉的Docker,以及做多任务多镜像(传说中的微服务)的k8s),中间遭遇的什么端口号被占用啊、Zk丢失心跳什么的,甚至出现了容器定时任务的假死。这一波直接尽显我捞比本质。(有篇长文,吃瓜现场还没写完,以后改)
Top 3 Spring事务控制-Mybatis焦作人
这一波以前没有写(偷懒没写完),在这里说几个比较好玩的事情。一说到事务,你们肯定又开始了,什么事务特性传播机制的都来了。。肯定有人嘲讽我,你个辣鸡事务控制不住你说个锤子。并不是而是我和另外一个同事的极限操作让我们互相加班,最终怼到3AM,简直就是个笑话。简述一下大概流程:
数据源只有一个,A将数据update为1,而B在此后将同一条数据Update为2.两人之后都执行Select。只有一个人的读取是正常的。但是很不巧,这个Update是一个1s一次的线程控制,这样的线程有三处。更不巧的是,这三个线程因为操作人的关系,都一直在执行。肯定有人说不就是定时任务杂交嘛,这个事情在发生之后我做了深刻总结和检讨,我意识到对单数据源的操作确保单一控制,隔离分明才是关键。(这里Diss下我们的运维,垃圾连SpringBoot的定时任务都无法解析,NMSL)。
当然,关于标题的Mybatis焦作人这个事情。并未发生在我的身上,但是我觉得这个要引以为戒。说简单一点就是AB在不同时间节点提交了同名的Mapper。这下大家都懂8.
这个话题还能继续。因为我写了个超级搞笑的程序。
我们需要在某段程序异常的时候采集他的异常信息,所以在操作行的基础上加了两列的备注列来存储错误信息。但是这个列的数据变更又被@Transactionl注解控制,所以我启用了嵌套事务,设置了事务的传播机制,配置了Propagation,结果...md 出现了行锁,所以妥妥的SQL Time OUT。无奈做成了这样的:
if ("SUCCESS".equals(resultCode)) { // 虽然发送成功,但用户可能未领取,先记录mchBillno try { whenSendRedPackAlreadySave(activityId, mchno); }catch (Exception e){ log.error("更新mchNo出现异常:",e); } return ; } else { log.error("异常返回报文为:" + xyx); String err_code = TenpayUtil.getDomTextByTag(document, "err_code"); String returnInfo = TenpayUtil.getDomTextByTag(document,"err_code_des"); if(RedpackError.NOTENOUGH.code.equals(err_code)){ log.info("微信账号没钱了,发送红包休息下"); sleep(); } throw new GatewayException(GatewayReturnCodeEnum.ERR_WECHAT_REDPACK,ExpLevel.EXPLOG, xyx+"@"+activityId); }
我通过捕获异常去做更新..虽然这事我好像干过:
不过不管了,功能要紧。然后没想到这块他喵居然有人在用我还不知道!所以然后就成这样子了:
干!这是客服告诉我的问题。我这下就很尴尬。。。。所以我无奈下修改方案,使用Redis发布订阅的方式去做了(微笑司马脸)
当然在经历过这些奇葩之后,我开始了新的奇葩的代码,关于Spring事务传播。原先有个方法,里面调用的部分异常了,我希望不回滚事务。然后使用Try-Catch。结果出现了ReadOnly的事务异常。最终使用了这种模式:
@Transactional public void a(){ try{ serviceB.b(); }catch (Exception e){ serviceC.c(); } } @Transactional(propagation = Propagation.NESTED) public void b(){ }
彩笔本质暴露无疑。
TOP2 搜索引擎 lucence 和Solr
TOP1 分布式锁 Zookeeper、Redis、Mysql对比