0%

2020

前几天的早上一个技术群里大家又热闹起来,惯例讨论起了最近的形势,瞎扯一气,什么工作压力,消灭贫困,996的正确性,加班等等。

每逢这种讨论,我是没多大兴趣的。直到看到他们说着说着,一位大神前辈(大龄可优化对象/狗头)说道:

我见过不少人,没有反思过自己的状况,明明处于这种危墙下,还糊里糊涂地生了俩(孩子)。

我顿时来了精神。大神紧接着指出:

结果就是,工作的巨大压力虽能保证一个一般的所谓高薪收入,但是实际上,离破产只差一层窗户纸。

听罢此言,忽觉后背发凉,再回想自身处境,犹如一脚踏在悬崖边上,往上看似开阔平地,往下则是万丈深渊。

未完待续…

https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=3535369360,3418153328&fm=173&app=49&f=JPEG?w=255&h=227&s=6BA2C44D0C82D37452B830B70300C040

腾乃密召新闻哥入曰:“吾欲问汝借一物,以压众心,汝必勿吝。”
新闻哥曰:“老板欲用何物?”
腾曰:“欲借汝头以示众耳。”
新闻哥大惊曰:“某实无罪!”
腾曰:“吾亦知汝无罪,但不杀汝,会员必变矣。汝走后,汝年终奖吾自花之,汝勿虑也。”
新闻哥再欲言时,腾早呼保安hr推出门外,一刀斩讫,悬头高竿,出榜晓示曰:“新闻哥妖言惑众,非我兄弟,谨按贰伍壹法。”
于是众怨始解。

每次下班打卡都要经历以下步骤:

  1. 我打卡了。
  2. 我打卡了吗?我确认我打卡了。
  3. 我打卡了吗?我确认我确认过打卡了。

打卡完毕,下班。

cover

  1. 每增加国民平均受教育年限一年,国家GDP可提升30%以上。(再穷不能穷教育!)
  2. 平均来讲多读一年书比少读一年书,工资多8%。(活到老学到老!)
  3. 买保险,可以避免贫困陷阱。(敲黑板!!!富人必备。)
  4. 富裕可以增加人的耐心,贫穷会使人丧失耐心。(多存钱,少剁手,争取早日摆脱贫困陷阱)

coverimg

2019 年 5 月的热点,除了中美姨妈般互撕,和华为被蹂躏之外,就是《权力的游戏》大结局了,从 2011 年至 2019 年跨度九年,除了 2018 年停更外其他都是每年一季。多余的废话就不多说了,只说每年 4 月 17 号是苦逼的一年少有的盼头。

关于第八季后面再吐槽,今天只说说《权力的游戏》印象最深刻的印象。既不是原以为的主角奈德史塔克被突然砍头(居然没有刀下留人),也不是血色婚礼上萝卜的尸体被插上狼头,不是琼恩被光之王复活,更不是夜王一枪擒龙,甚至不是第八季夜王被艾丽娅一剑反杀,而是非常普通的一幕,这一幕可能大多数人都已经忘记了。

没有主角、没有战斗、没有暴力、没有美女,只有一群糟老头子、酸腐的知识分子在末日来临之前,坐在旧镇闲聊。知道异鬼在长城外蠢蠢欲动的山姆来到旧镇就是为了找寻对抗异鬼之道,他看到这帮学士和文化人一副迂腐的样子,想必内心是绝望的。山姆质问他们为何不急(这些都是印象中的剧情,如有差错敬请指正,能提供在哪一集另有重谢),学士们一番话令我印象深刻,大概是指异鬼来了又怎么样,百姓们该生则生该死则死,不会比之前铁王座的那些人们坏到哪里去。兴,百姓苦;亡,百姓苦。老百姓才不会在意铁王座上坐的是人是鬼呢。

好家伙,渲染了几季的异鬼来临恐怖氛围,口口声声说了几季的 Winter is coming,到这里我都释然了。什么异鬼,什么凛冬,都是历史中的一部曲罢了。

coverimg

前言

随着公司业务的爆炸式的增长,需求规模和用户规模也迅速地膨胀起来,这样给系统的三高(高性能、高并发、高可用)以及扩展性、可维护性都带来了考验。而旧系统因为早期设计的各种局限性(如早期参与人员的水平、架构设计的前瞻性、老板的急性子等等),逐渐满足不了现状和未来的新需求,暴露出各种问题。开发人员们像是拖着老破车上高速,苦不堪言。(说人话:老系统代码的坑太深了,开发们填不住了,要么被坑埋了,要么弃坑逃跑了…)

那么这个时候,通常要面临一个问题:是继续填坑还是跑路走人 选择重构。填坑是不可能的,这辈子都不可能的。而选择重构是需要壮士断腕的勇气,因为重构是一项老大难、一件耗时耗力的事情,且多少会对现有业务开发造成影响,甚至是停滞。因此大多时候得不到产品经理和老板的支持,他们关心的只有一个:下个需求什么时候能上!至于其他的,都是你们研发该操心的。

自己选择的重构路,跪着也要走完。如何来一次就干就干的重构呢?根据互联网常见项目重构流程,以及我的亲身参与的重构项目经历,梳理大中小型系统的常见重构流程如下:

零:说服业务方

重构不单是研发团队的事情,更是整个项目团队的事情。重构可以提升系统的三高,也可以优化改善业务流程,满足新的业务诉求等等。重构需要投入大量资源,必须要得到业务方的支持。通常这个时候需要对他们晓之以理,动之以情,阐述清楚重构的利弊,以及不重构的要害。在得到他们的支持后,重构的工作便正式开展。

参与人员:技术 Leader

一:树立重构目标,有的放矢

重构是一项工程,是一场持久战,它不是一两个迭代、甚至一两个月能做好的事情,需要投入大量的人力、物力、时间精力等。那么在这场旷日持久的战斗中,我们的目标是什么?是通过更优秀更合理的架构来满足系统三高的需求,还是想通过重构来提高代码质量,或者引入新的技术和框架来升级整个系统,抑或通过重构来优化业务流程,实现原来实现不了的需求。有了目标后,才能做到有的放矢。

参与人员:技术 Leader,架构师

二:确定重构的范围,并对重构作出预测

重构通常有以下几个级别的重构

  • 平台级别重构。针对整体平台的重构,如阿里早期是 LAMP 架构,后来整体迁移到了 Java 平台。
  • 系统级别重构。针对业务系统的重构,如通过引入微服务架构或者 SOA 架构,分解单体应用。
  • 架构级别重构。如通过架构的调整和重新设计,改善原有架构的不合理之处。如通过分层使业务解耦,引入优德88金殿设计提升系统高并发等。
  • 业务级别重构。常见为某些业务需求因为系统设计的不合理性导致无法满足或有缺陷满足,需要通过业务系统的重构调整或数据库的重构来解决。
  • 模块/代码级别重构。这是最常见的重构。通常指使用设计模式、封装继承、优化拆解代码,使得代码的结构更良好,运行效率更高。
  • 确定这次重构是属于什么级别,确定重构的整体范围的大小,确定重构的技术选型,进而对重构工作进行科学的评测和预估。比如需要投入哪些成本,需要投入的人力和时间是多少,在重构的过程中能否支撑正常业务需求等等。在有了这些预测后,也对业务方有个交代,尤其是当他们追在后面问什么时候能上新需求。

    参与人员:技术 Leader,架构师,研发人员

    三:旧系统的熟悉和业务梳理

    重构不是和旧系统说散就散,而是要不断和旧系统战斗的过程。知己知彼,百战不殆。重构不仅需要清楚新系统的目标和未来,更需要对旧系统非常熟悉(尤其是坑)。此时需要参与重构的人员(尤其是参与旧系统的人员)来对旧系统业务和系统进行梳理,对原有资料信息进行收益和整理的工作,对旧系统的关键代码和数据库设计进行 Review等等。

    以下是重构旧系统前需要准备的常见工作:

  • 旧系统资料和信息的收集,包含且不限于系统相关的设计文档和技术文档等文档资料,架构图、UML 图,数据库设计 ER 图等图形化资料
  • 业务线和业务流程的梳理,整理业务线上的各大项目、业务流程,并输出为文档
  • 旧系统关键代码的 Review
  • 有相关疑难点及时与相关与业务线上的人员沟通,将问题解决在”襁褓”中。

    参与人员:技术 Leader,架构师,研发人员

    四:数据库重构

    如果在重构中需要涉及数据库的重构,数据库的重构一般是最先开始的一步。系统需要重构的直接原因,也大多和数据库有关。在数据库重构时,我们清楚旧系统中数据库的各种设计缺陷和使用障碍,那么就可以对症下药,如通过三大范式或反范式来设计表,是否需要分库分表等等。

    参与人员:DBA,架构师

    五:后台系统重构

    后台系统重构前,必须需要依照前文所述的一些设计和技术文档。这些文档输出后并经讨论成型后,架构师进行系统架构设计,后台开发人员进行具体编码工作。通常这个过程是耗时最长的,也是非常重要的一环。后台的架构设计水平,决定着系统重构的水平,业务代码的质量,决定着系统重构的质量。

    因为这个过程比较漫长,且成果无法立竿见影。所以通常采用敏捷开发的模式,通过迭代的方式来进行后台系统重构。迭代的方式有几个好处:

    1. 需要将整个重构过程进行有效规划和量化,做到胸有成竹
    2. 每个阶段能有可见的成果,确保团队在长时间的重构过程中不陷于泥潭
    3. 对已重构好的部分可以及时进行联调测试或观察,不断在迭代中总结、在总结中迭代

    另外在后台系统重构时,也需要有明确量化的目标和标准,比如各系统和业务模块支持多少 QPS,接口响应时间多长时间等,这样团队才能在重构的过程中不至于为了重构而重构。

    在重构过程中,定期进行 Code Review,及时发现重构的问题和质量的问题,避免出现破窗效应,引入拙劣的设计或垃圾代码,进而破坏整个系统。

    参与人员:技术 Leader,架构师,研发人员

    六:数据迁移与检查

    如果涉及数据库重构时,在新的数据库设计好后,就会有面临数据迁移的问题。一般分为全量迁移和增量迁移,全量迁移是将旧系统的数据一次性迁移到新的数据库中,增量迁移是在实行全量迁移后旧系统新产生的数据迁移到新系统上来,增量迁移一直到旧系统下线不再产生新数据后。通常迁移都是通过编写脚本或程序来实现,拒绝人工操作。

    迁移后自然需要对比新旧系统的数据,同样可以通过脚本或程序来进行对比,查缺补漏,定位分析。

    参与人员:DBA,研发人员

    七:系统检查、联调与测试

    在后台系统重构到一定程度时,同样也需要编写脚本和程序来对新旧系统的业务接口进行检查,及时发现重构中的问题,必要时候进行架构调整和数据库调整。当然,在重构时,开发人员能提高单元测试覆盖率当然是更好不过。当各系统和模块的依赖解决的差不多时,可以开始联调工作。

    当然最后还需要系统性的测试,如功能性测试、稳定性测试、性能测试,本地测试、模拟线上环境测试等。测试中发现的问题经验证修复后,达到上线的标准,即可灰度上线。

    参与人员:架构师,研发人员,测试人员

    八:灰度发布与观察

    万里长征已经走到最后,也到了最紧要的关头。灰度发布时,只接入一小部分流量,并及时跟踪和分析线上的 log 与监控告警,一有问题及时解决。当新系统趋于稳定时,可以逐渐加大灰度发布的范围和接入的流量,同时继续跟踪线上 log 与监控告警。

    参与人员:运维人员,测试人员,研发人员

    九:系统切换

    在系统切换时,需要提前制订系统切换方案,包含相应的规划与流程,甚至是应急预案与回滚方案,避免走一步看一步。

    参与人员:运维人员,测试人员

    结语

    通过上述几个步骤后,我们成功对系统进行重构。

    重构是一项大工程,但经历重构后的系统也并非完美无缺。重构不是终点,更像是起点。

    2019 年 3 月 17 日,经过周五和周六的两天忙碌后,周日准备先放松一下。在拒掉了朋友一起遛娃的邀约后,带着老婆女儿来到位于西乡的基督教宝安堂。

    在和气的保安大叔指引下,我们来到二楼的主堂。此时11点多,距离下午的主日崇拜还有几个小时,堂内只有零零散散几个人,有相貌普通且发型有些凌乱的年轻女人,也有怀抱着婴儿的少妇和衣着光鲜的老妇人。整个屋子是一排排的暗红色长椅,每一把长椅的后面摆放了几本一样深色的书,一本圣经,一本赞美诗,另有一小册赞美诗短篇。这些专用来给信徒们直接使用,而不需要自带经文和赞美诗。

    在长椅上坐了一会后,我往大堂的最前方讲台走去。遥看着讲台上下摆放着几排绿植。米黄色的背景墙上一个深色的十字架,上面“以马内利”四个大字。我注视着十字架一步步走过去,内心感到无比平静。走到讲台前方,看到十字架下面有一方台子,上面两行字,上一行“A Ω”,下一行“为的是纪念主”。

    在主堂呆了一会后,我们三人沿着楼梯去三楼看看。走在楼梯间仿佛听到奏乐声,走进三楼的副堂发现是几位年轻人在摆弄乐器,有钢琴,有吉他,他们不紧不缓地弹着《江南》。这是我最爱的歌曲,但伴奏音乐倒是第一次听,听来煞是有感觉。我们就这样听着音乐,往大堂后方走去,但见堂内有穿着校服充电看电视的学生,有双手紧握、闭着眼睛激情祷告的一对母女,还有说着笑着弹着音乐的年轻人。

    走到后方的窗台边上,我转头一看,但见墙上画着一副巨大的油画,耶稣身披白衣手执长杖在牧羊,一只只白色的绵羊在兀自地吃草。放眼望去,外面阳光灿烂无比,屋内也亮亮堂堂。

    这一刻,沐浴在主的光辉下,如沐春风。

    后记,回去后,查了一下“A Ω”的意思,A 是 Alpha,起始之意,Ω 是 Omega,终了的意思。“A Ω”就是从始至终。

    jstat 用于监视 Java 虚拟机(JVM)的统计数据。这个命令是实验性的,不受支持。

    简介

    jstat <一般选项 | 输出选项> <vmid> <时间间隔> <count>

    jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

    一般选项

    ​ 一个通用命令行选项,-help 或者 -options。详见 一般选项

    输出选项

    ​ 包含单个 statOption的一个或多个输出选项,以及 -t,-h 和 -J 选项。详见输出选项

    vmid

    ​ 虚拟机标识符,是指示目标 JVM 的一个字符串。一般格式如下:

    [protocol:][//]lvmid[@hostname[:port]/servername]

    vmid 的语法对应 URI 的语法。vmid 字符串可以是从表示本地 JVM 的一个整数,到指定通信协议、端口和其他特定实现值的更复杂的结构。详见虚拟机标识符

    间隔时间

    ​ 以指定单位秒(s)或毫秒(ms)的采样间隔。默认是秒,必须为正整数。当指定时,jstat 命令会在每个间隔时间进行输出。

    数量

    ​ 要显示的样本数。默认无穷大,这样 jstat 命令会一直输出的统计信息,直到 JVM 终止或者 jstat 命令终止。必须为正整数。

    描述

    jstat 命令显示被监测的 Java HotSpot VM的性能统计数据。用虚拟机标识符或者vmid选项标识目标 JVM。

    虚拟机标识

    vmid 的语法对应于 URI 的语法:

    [protocol:][//]lvmid[@hostname[:port]/servername]

    protocol

    ​ 通信协议,如果省略协议且没有指定主机名,默认协议是特定于平台的优化本地协议。如果省略了协议并指定主机名,那么默认协议是 RMI

    lvmid

    ​ 目标 JVM 的本地虚拟机标识。lvmid 是一个特定于平台的值,它唯一地标识系统上的 JVM。lvmid 是虚拟机标识符唯一需要的组件。lvmid 通常是(但不一定是)目标 JVM 进程的操作系统的标识符。你可以使用 jps 命令来确定 lvmid,此外也可以在 Solaris、Linux、OS X平台上使用 ps命令来确定 lvmid,在 Windows上可以使用 Windows 任务管理器来操作。

    hostname

    ​ 目标主机的主机名或 IP 地址。如果省略了 hostname,默认是本地主机。

    port

    ​ 与远程服务器通信的端口。如果省略主机名或协议指指定优化的本地协议,则忽略端口值。否则,端口参数的处理是特定于实现的。对于默认的 rmi 协议,端口值指示远程主机上 rmiregistry 的端口号。如果省略端口值且协议值指示 rmi,则使用默认 rmiregistry 的端口。

    servername

    ​ servername 参数的矗立取决于实现。对于优化的本地协议,这个字段被忽略。对于 rmi 协议,它表示远程主机上 RMI 远程对象的名称。

    选项

    jstat 命令支持两种选项类型:一般选项和输出选项。一般选项用来显示简单的用法和版本信息。输出选项决定统计输出的内容和格式。

    所有选项及其功能都可能在未来的版本中更改或移除。

    一般选项

    如果你指定了一个一般选项,则不能再指定任何其他选项或参数。

    -help

    ​ 显示帮助信息

    -options

    ​ 显示一个统计选项列表,详见输出选项