vlambda博客
学习文章列表

相伴Java许多年,我也曾在SSM之时迷茫很久



在我当初接触编程的时候,因为喜欢玩手机游戏,在诺基亚制衡市场的时代,大部分精良的手机游戏都由Java语言进行编写的,那些游戏傻傻的都带着那杯咖啡的图标,我也顺理成章以Java作为编程的母语进行学习。

那时候学习Java从JavaSE开始学起,if判断/for循环/面向对象/多态/多线程/TCP/UDP,虽然多态难为了我很长时间,但不妨碍我沉迷进了编程这个奇妙的世界。学习Java GUI界面编程的时候终于脱离了黑窗口和命令行,终于可以把自己制作的东西交给父母看一看,让他们知道自己儿子在学什么东西,似乎还学的很不错一样!到学习JavaEE的Servlet/JDBC/HTML/CSS/JS/JSP/MySQL至此可以做出来一些小型的网页和博客。那时候特别高兴,感觉终于能够通过自己的技术制作出来一些符合自己想法的东西了,感觉自己就是造物主,自己可以创造一整个世界!

初期工作开始接触使用Hibernate代替JDBC,以Struts2代替Servlet的形式进行编程,逐渐接受各种框架的洗礼,密密麻麻的框架需要学习,排不完的加班和数不清的复杂查询,到现在我仍然想吐槽曾经十几个表联查还觉得理所应当的各个架构师!处理着各种冗余数据与历史代码,每天都掉许多头发,但是当时劝自己,既然刚入行,赚的就是这个钱,我能坚持下去!

后续工作时使用SpringMVC代替Struts2,使用MyBatis代替Hibernate,使用Jedis整合Redis增加缓存,使用POI生成Excel表格,使用dom4j解析XML文件,使用SOAP协议的WebService接口代替HTTP协议进行服务器之间的数据传输,最后使用Spring管理所有的引入框架。让整体项目越来越完善,似乎越来越接近所有人所说的那种企业级开发的程度了。但这段时间的旅程给人的感受并不美好,此时虽然每天晚上我都保持最少2个小时的长久学习状态,但始终没有我在JavaSE与JavaEE时感受到的那种“接受新鲜事物的感觉”。诚然,我的技术不断在完善,我所了解的框架越来越多,我也胜任了市场上要求三年开发经验的面试门槛和工作基础。但于我个人而言,通过JDBC/Hibernate/MyBatis去读取MySQL中的数据有什么区别?Servlet/Struts2/SpringMVC换来换去有什么意义么?只不过换了个框架换了个写法而已,得到的结果并无不同啊。那我此时此刻浪费的时间来干嘛?我很焦虑,在擅长SSM之后,我技术的增长停滞了很长一段时间。那时候可能每天想的最多的就是通过考研来提高自己工资。毕竟单纯从技术上我似乎已经没有什么办法提高工资了。要么考研,要么等待自己的工作年龄生长到一定程度才行。

但后来发现35岁开始,似乎各个公司又不喜欢用你了,这就很尴尬了。我当时已经工作三年左右,二十五六岁了,考研连考试带学习两三年的时间,我还能再干几年?可是不考研的话,等待工龄涨工资我能涨几年?那时候我迷茫的不得了。

后来发现大牛不外乎本公司内自研框架和引擎的高龄程序员们,可是当我与他们一起开发银行管理系统的时候发现他们仍然在用JDK1.4版本,我对整个职业生涯都很绝望,是啊,我们的项目要求的是稳定,哪来那么多潮流技术新技术去给你替换尝试?而且所谓各种大牛研制的引擎或框架来说,始终离不开读取数据库/生成web页面一系列功能,我都不需要回头看就知道其中肯定包括了单点登录/AES对称加密/RSA非对称加密/HTTPS协议/Freemaker生成HTML页面/账号对应权限/审批功能/跑批功能,来来去去做的这些就是我人生的意义么?他们只是工作早了一些,这样的框架换我我也能做啊!我们每天干的都是这些事!等我年纪大了只能和他们一样么?我还年轻我不服啊,我不能只涨年龄不涨技术,但是那时候的Java除了不常用的框架之外的的确确没有什么所谓的“技术”再可以让我学习的了。

但是自那之后虽然Java技术停滞增长了,我便把重心放到了运维工程师的相关技术上,想往我梦想中的“架构”层次再进一步。那时我学会了Nginx + Tomcat + SSM负载均衡的形式,又学会了Keepalived + Nginx + Tomcat + SSM多层负载均衡的形式,学习了WebSocket那种客户端主动推送的协议,学习了Zabbix监控自己的项目,学习了MongoDB这种除了Reids之外的缓存技术,认知了ElasticSearch搜索引擎,认知Git与SVN之间的管理区别。开始不断阅读各种框架的底层源码,例如在Spring代码中设置断点不断的Debug,开始在MyBatis框架中增加代码,定制更适合我自己的MyBatis拦截器(我在原有MyBatis之上增加了拦截器与自定义日志之类的功能)。在这段时间里,对于框架的理解越来越深,对于运维工程师所需的技术了解的越来越多。可是在本职工作中,我仍然感觉,以我当时三四年的工作经验来讲,与那种刚毕业且学习好的学生来说,区别并不大,尤其类似POI/Jedis/MongoDB这一类工具与框架的学习成本很低,快的两天一个,慢的两周也能搞定,学习速度很快,在未来我的优势能在哪里?难道我的优势只能是我能兼职干运维工程师和研发工程师两种工作么去和其他程序员硬卷么?这种优势与我能疯狂加班有什么区别?这并不是我想要的!我并不想只是技术的“量”在增长,技术的“质”仍然处于那个SSM的阶段,我与毕业生写的代码仍然没有任何不同之处!

在我工作五六年的时候,市面上Java研发常用的服务器软件与Java框架已经大部分了解,我开始接了不少私活,其中包括游戏服务器/IM软件后台/OA软件后台/电商后台等等一系列项目,白天上一份班晚上熬夜接着干,得到了不少人的不少赏识,任何一套系统需求分分钟能在脑内形成拓扑图的时候,我极其自大,觉得自己已经无人能及了,对于新出的Spring Boot与Spring Cloud技术不屑一顾,几周内几乎全部学下,其中包括Consul注册中心/Kafka/FastDFS/Spring cloud Ribbon/Spring Data JDBC/缓存与持久化保持一致性/分布式通讯Feign/分布式断路器Hystrix/分布式的任务调度Quartz等等吧。

很多人认为分布式不是新出的概念么?其实早好几年前我在做SOAP的时候就已经使用了这种分布式服务的形式,在我看来分布式微服务和我当初做的分布式服务没任何区别。思想上都是一样的,那时也通过注册中心管理各个SOAP的WebService服务提供者,这种技术只是实现方式在变,可思想以前就有。只是现在实现的更加具体更加成熟了。刚好那时候有一个大项目拆分重做,整套项目大概区分六十多个微服务,那一年多我通过Spring Boot + Spring Cloud的架构独立连续制作了四十几个微服务,听起来数量很多,其实过程十分轻松,并且我还有闲暇时间去看书。那时候我在想,我的技术也就这样了,最多重新学习一下HTML5/CSS3/VUE/Bootstrap/AngularJS回头当个全栈就好了。

再后来有一段时间身体不好在家休养,顺手整理了下自己学习Spring Boot + Spring Cloud的过程,编纂成册出版了《微服务分布式架构基础与实战——基于Spring Boot + Spring Cloud》一书,写书之余学习了Python扩展了下编程语言。

还有在蓝桥杯的云课堂出了一个《Java多线程实战基础》的课程。又重新买了《算法之美》/《算法基础》一系列算法书,从第一页开始仔仔细细的学习,每一道题都回Eclipse中重新编写代码,当然后期陆陆续续的也都忘了。恕我直言,迄今为止我也背诵不出来快排的代码。

那时开始不断审视着我工作之中我遇到厉害的人物,思考他们技术上的优点,当时想着我既然不知道如何去学习了,那就用他们的优点填补自身,起码勉强能够进步。想想那其中包括通过自己手写简易多线程计算机系统的大佬!能够背诵一点点Linux代码的项目经理!自己手写协议的同事!从零到一实现MySQL!从零到一实现Tomcat的各种人才。虽然一个个都很厉害,但是好多学习的内容纯粹都是靠时间堆砌起来的!都没法让我再惊讶起来!因为虽然我没写过,但是我心里都有个大概,有些我学不会也不想学,因为工作上实在用不到!有些我也可以做到!至此我几乎已经放弃了Java方面的学习,再怎么学也不过如此了。

此后来到现任公司被现任领导面试的时候,领导问我:“你当初写的Spring Boot项目最高承载并发(TPS)能达到多少?”

“当时的项目大概六千多吧,主要看数据查询量大小与复不复杂。这也不光是程序的事,重在服务器,硬件性能配置的上跟不上,代码再好也白费。而且当时业务逻辑也比较复杂,需要穿插数个系统,所以这方面不太好直说。”

“让你开发Redis,16核CPU,32G内存的情况下,你单节点并发(TPS)能上6万么?”

“这在太恐怖了,这种机器Redis单节点并发应该也就10万吧?我虽然可以完全实现Redis所有功能包括事务/链表/信息推送,但是确实性能不能和真正Redis进行比较。而且人家还是一个团队在做的东西,一个人肯定完不成!”在我回答之时,别说让我拿自己的产品和Redis进行比较,就算放在一起相提并论我都觉得脸上烧的慌。我一直工作也都是实现业务逻辑而已……

“那你和应届生的区别是什么?这点业务逻辑哪个应届生做不出来?Redis一共才几万行代码,允许你两年制作一个阉割版的Reids,不需要那么多的链表/队列/事务,只是达到最基础的set/get/消息通讯三个功能的情况下,代码肯定更少,那你能不能做到Redis的并发?”

应该……做不到吧?不可能的,不现实的,怎么可能!!!

“你知道么?同样都是Java语言,在不同人手里,完全不一样!青龙偃月刀虽好,但是有些人只能拿它切了自己的脑袋!不是Java厉害,框架厉害,公司厉害,你就厉害!不会性能上的测试与优化!你能仿照的,永远都是只是实现了业务逻辑的残次品!”

为了寻找这个面试官所言的真实性,我来到了当前这家公司,跟着面试我的这名领导优化一套类似Redis的中间件。一开始多少以看笑话且随时走人的心态来的,毕竟在我眼里,这几乎是一件不可能完成的任务。

感谢现任领导,几乎手把手教我各种性能测试的方式,虽然我曾经了解一些,但是在这个项目中始终不够看,改变原有编程观念,不断的优化着接口里每一个小接口,关掉所有的日志输出,尽可能减少循环减少递归次数,几乎全部的线程都为多线程异步使用,一个接口用了十数个队列进行调用,优化其中任何一丝GC可能不会清除掉的垃圾!高并发项目不存在任何Debug行为,线程全在大脑里转。听着似乎很简单吧?但其实一个接口每天需要测几十次,连续测试半年时间去优化里面任何一点细节。

越制作现在手上的这款中间件越觉得自己当初如何可笑,面对曾经不知天高地厚的自己恨不得回去好好抽自己几个嘴巴子。当然,抽的时候一定要把现在学习路线告诉曾经的自己,省的再走太多弯路了。

我是如何做到这样的并发的?很简单,秘密就在我编写的《高性能Java架构:核心原理与案例实战》这本书里。谢谢我的编辑安娜,是她给了我写这本书的机会,也是她不断的帮我修改其中的文字,让这本书更好的呈现给大家。

如今这款中间件诚如当时所说在16核CPU,32G内存的情况下每秒带宽推送至少5个G,可承接6万以上HTTP请求无任何压力,无报错无内存溢出无丢失数据,甚至CPU和内存还有相当多的剩余量,在单机性能达到这个程度时,我又陆续为这个中间件编写集群版本/主从复制版本。

《高性能Java架构:核心原理与案例实战》这本书我在写之前构思过无数次,但开始的时候始终无法达到我所想要讲的那种优化程度。

SQL优化怎么讲?这一条SQL我教你优化之后,下一条你仍然不知道怎么优化!

逻辑优化怎么讲?业务就是那么要求的?难不成教怎么和产品经理打架让他改需求?

架构优化怎么讲?我把我所有架构过的程序交代出来让读者挨个朗读并背诵?

在我不断练习之后,与不少程序员进行沟通,沟通具有实际意义的问题后,我才逐渐形成这本书。

“你知道if判断是否影响性能么?”

“你知道for循环与foreach循环性能是否相同么?”

“你知道JDK的Stream流是否影响性能么?”

“你知道lambda表达式是否影响性能么?”

“你知道工厂模式是否影响性能么?如果影响大概到什么程度?”

“你知道几种缓存形式?哪种性能最好?为什么不能一味的用性能最好的那种缓存形式么?”

“假如让你做一套小说网,那每一个章节那么多字数,你都从缓存中获取数据么?缓存不会崩溃么?Redis承受的住么?”

“你知道一个Java应用程序,什么框架都不引用的情况下,只写入main方法与for循环HelloWord输出,那在8核CPU,16G内存的情况下最多能输出多少次么?”

“你知道MySQL单表达到一亿条数据,在8核CPU,16G内存的情况下,总数据体积达到几个G,使用limit10字段,那需要多长时间获取出来?真如网络上所说的,MySQL单表4000条之后读取速度就降级了么?”

以上问题,在任何搜索引擎上都不可能找到相应答案,但答案就在《高性能Java架构:核心原理与案例实战》这本书里,更重要的是,获取答案的方式方法就在这本书里!

我将我所学的架构思想与测试方式都置入其中,文章简短可能并不齐全,可能在学习此书的过程中您的学习笔记会比这本书写的更加厚重,更厚重几倍,若非如此可能效果不佳。原本我还想补充些内容,但想想无用之文可能几十本都放不下,更重要的是将方式方法告诉大家,将扩展视野的方式告诉大家。日后工作到什么程度,再看个人造化。

此书行文粗糙暂且见谅。愿您在读此书之时可以领略到我在后期成长所体会到的一个个惊喜,愿您读此书之后可以自信的说出前言中的答案,愿您在技术成长的道路上不会像我一直在走弯路。

愿您幸福。

张方兴

行文于2021年4月某夜





高性能Java架构:核心原理与案例实战》购买链接如下所示。

https://item.jd.com/13387600.html

微服务分布式架构基础与实战:基于Spring Boot + Spring Cloud》购买链接如下所示。


https://item.jd.com/12838722.html