【置顶】个人阶段性学习和规划总结(技能树)

  本人专注后台服务端开发一晃已经好久了,自我感觉上不仅经验增加了很多,同时接触到的东西确实不少,在增加见识的同时博文也批量更新了很多。大多人看来内容很多很杂,此处做一阶段性整理和总结吧,给自己也梳理梳理一下。
  其实不仅仅是后台服务端开发这个方向,就整个软件开发来说,其知识构成也是有所层次的。个人毕竟不是正规计算机科班出身,也就是大家所说的半路出道、自学成才的野程序员,优点就是不会被那些所谓正规计算机教育的所束缚禁锢住,但是很多时候感觉自己的知识构成还是有所缺陷。既然励志要靠撸代码吃饭养家,那么长痛不如短痛,晚补不如早补,该学的终究跑不掉!

【置顶】博客资源收录大全

  虽然当下微信公众号席卷自媒体市场之势如火如荼,但是针对文章展示的话个人还是偏向于独立博客的形式,主要是因为个人可控制化的东西比较多。我想,在被条条框框束缚的无以喘息的情况下,这个时代没有什么比个性和自由更为重要的了吧。
  下面是一些网络知名人士的博客,以及平时在搜索资料过程中遇到的好站点,都被一一记录下来了,真心喜欢的话可以用RSS订阅这些站点,其中很多都是全文输出的。因为个人的兴趣取向问题,除了将不感兴趣的前端、移动端外,过于偏向于Java/Nodejs等语言化的博客也被KO了(即使编程思想是独立于语言而存在的),希望平时没事多看看吧!
  以下罗列之排名不分先后。

【置顶】架构师成长之路

  上个月公司组织我和另外一个同事有幸参加了每年一度的全球架构师峰会,姑且算是架构师们的一场盛宴吧,不过确实感觉这个峰会挺水的,和自己当初的期望相差甚远。虽然近一百多个场次中零星夹杂着一些产品、质量方面的主题,但是绝大多数会场都是架构师在秀技术,当然这也折射出来:在国内,架构师常常被狭隘成技术能力强的那一拨人群。
  虽然不知道国外的架构师是否真如书本上说的那样,是一个偏向技术族的高端(几近全能)管理型人才,但是理想总需要有的,而且我觉得能做到那种标准的人肯定是企业稀缺的人才。这就整理收集了一些所谓架构师的职责和所需技能,就置顶当做自己努力的目标吧,希望能早日实现梦想!

1. 系统架构师是技术领导
  这意味着架构师除了需要有技术能力,同时还必须有领导能力。在项目中架构师具有做出技术方面决策的权力,相比而言项目经理则更加注重于在资源、排期、成本方面的规划和跟踪。
  架构师还需要参与到架构团队的组织管理,除了在较高层次设计系统架构外还,需要对各种工作和活动做出策划,因为架构实现最终会被落实分解成一个个的任务去执行。团队的质量对整个架构的成败有至关重要的影响,所以架构师还最好参与到团队员工的培养和新员工的面试选拔上去。
  架构师的领导力还体现在和团队成员的沟通交互上面,给员工的工作方向做出指引,给予他们充分明确的信息,并在需要的时候能够做出样例师范。成功的架构师都是以人为本的,每个架构师都会作为导师、教练的角色来带领团队的成员,成员的成长进步会推动项目的顺利进行,同时也让员工自身、整个团队、整个项目大大获益;同时架构师还需要发掘团队中各个成员的长处优势,鼓励大家相互分享相互学习。
  架构师在技术角度上要是整个项目推动的驱动力,架构师必须能够适时做出决策,并且保证这些决策能够被充分的讨论和论证,内容明确,最终落实实现下来。
  架构师需要和不同领域的人协同工作,需要对商务环境、需求的变更做出快速的响应,所以架构师的压力回是比较大的,需要寻求方式来释放消极情绪,努力使自身和团队成员积极向上的工作态度。

一个简单的基于Protobuf的RPC框架

  在喜迎新年时刻大家都忙着划水摸鱼,而且这段时间系统变更都封版冻结了,也算是可以正当地清闲的一段时间了。在阅读logcabin项目代码的时候受作者之启发,于是便沿着原作者的思路做了一个简单的C++专用RPC开发框架tzrpc,目前该项目的基本功能已经完成,其代码也开源共享了。


  可能让大家觉得RPC开发框架名字咋一听起来比较唬人,但是正如自己在之前的文章中所提到的:RPC框架的核心就是统一规范化数据编解码和网络传输方面的细节,方便业务端可以快速实现网络程序开发而已,如果究其本质内容的话,这个过程和普通的互联网开发相比没有什么差异的,所以自然不足为奇。之所以自己要做这个东西,一方面是因为目前工作中所用到的基于socket网络开发库的确是不怎么的好,在生产上用起来问题很多,比如在封装上就以一个简单的两字节长度做为头部,然后就直接追加流式消息体了,如果将一个非法的请求错误地打向这个端口,那么这个服务就会卡死甚至崩溃掉,还有一些客户端调用设置了超时,如果服务端负载很重导致客户端超时返回,下一次复用连接的客户端请求和响应会和上一个请求的响应串话,这在生产上已经暴露出问题了,当然和这个框架的健壮性不佳已经使用者不规范使用都有关系;另一方面Thrift和grpc很好很强大,但是如果想要做一些个性化的定制和功能增加,就会觉得难以下手,而我想这个原因估计也是很多互联网公司为了满足自己业务需求,另起炉灶开发内部RPC框架的最主要原因了。而我写这个工具的初衷,也就是想整理出一套自己摸得透、掌控得了、可以按需求随意定制的网络开发库,增加后续网络服务的开发效率,增加在网络服务开发中的积累。

分布式数据系统之分区

  数据分区在互联网行业中使用的非常普遍,因为在信息爆炸式增长情况下,互联网行业使用单机单库来解决庞大数据量的方法效率越来越低了,而数据分区可以很好地提高系统可扩展性。使用数据分区的情形下,要么选用成熟的中间件,这样业务层可以通过这个代理曾无感知式地访问数据;也或者业务层感知分片逻辑,通过这种侵入式的方式解决;再或者采用那些强大的分布式数据库,它们解决了数据分区、扩容、分布式事务的所有细节,业务层对此毫无感知。
  当然现代分布式系统基础组件都偏向于一站式解决数据分片、扩容、数据迁移和再均衡、请求路由等各项功能,比如Spanner采用的location proxy,以及TiKV的Placement Driver都是用来实现上述功能,这些完美解决方案的出现将使得上层应用可以更加集中关注与业务级别的开发,因为脏活累活基本由这些基础组件的开发者全揽承包了。

一、Key-Value的数据分区

  分区的主要目的是要将数据存储和访问负载尽量均匀地分布在所有节点上,这样理论上系统的吞吐量可以成倍地增长,否则负载的严重不均衡的分区就会成为系统的热点,成为整个系统的性能瓶颈之所在。

1.1 基于关键字区间分区

  基于关键字分区就是为每个分区分配一段连续的关键字或者以最小值和最大值界定的关键字区间范围,实现上关键字的区间段不一定非要均匀分布,因为数据本身相对于关键字可能就不是均匀分布的,分区边间应该适配数据本身的分布特征,设定合理的分区范围让数据均匀地分布在各个节点上。在区间内部,数据可以按照关键字排序进行保存,这样就可以轻松支持关键字区间查询的功能了。
  但是基于关键字区间分区的缺点是某些访问模式可能会导致热点,比如按照时间戳作为关键字来分区,则总会导致某个节点成为写入负载高的访问热点,而其他节点则几乎是写入空闲的,这种情况可以增加其他字段(比如实体名)作为前缀来分区,再连接时间进行排序存储,那么多个实体的数据分布在各个节点上,而对于某一个实体也可以实现时间范围的查询功能。

分布式数据系统之复制

  前段时间向大家推荐的堪称2018年必读神书《Designing Data-Intensive Applications》,现在已经发型简体中文版了,书名被翻译为《数据密集型应用系统设计》。自己看完英文版后觉得很不错,总体行文偏向于学术风格,虽然不想很多技术书籍那么实用——可以立马用于提高生产率,但是在有过一定的开发和架构经验后,在实践中那些看似那么显而易见的解决方案,或者那些看似极为高端的分布式系统,在书中作者对相关知识点和面都进行了相应的总结和剖析,总会让人有一种拨开云雾见青天的感觉。
  总体感觉书中对于分布式系统数据这一部门写的不错,所以后面几篇文章主要是这一部分相关知识点的学习总结了。
  数据复制是在多台机器上保存多个相同的数据副本,主要是用于实现以下几个目的:让数据更接近访问的用户,降低访问延迟(低延迟);提供冗余挺高可用性,当部分组件出现故障的时候任然可以提供服务(容忍节点故障);扩展多台机器同时提供数据访问能力,提高总体吞吐量(可扩展性)。

一、主从复制

  主从复制是当前最流行的复制模式,其工作流程为:在多个副本中指定一个副本为主副本,当客户需要修改数据库的时候,必须将写请求发送给主副本,主副本首先将数据写入本地存储;接着主副本把数据更改作为复制的日志发送给所有的从副本,每个从副本获得数据更改日志之后将其应用到本地,且严格保证和主副本相同的写入顺序;只读请求可以在主副本或者从副本上执行查询。

1.1 同步复制和异步复制

  同步复制和异步复制是复制机制中一个十分重要的设计选项。同步复制需要主节点等待从节点确认写入完成后才向客户端报告写入操作完成,其好处是能保证一旦客户端收到响应,则所有同步复制的副本都具有最新数据版本,而主节点故障后从节点可以立即替换故障节点,但是缺点是客户响应延时较大,而且一旦同步发生问题,则写入就会被视为失败,而且会阻塞其后主节点的所有请求。
  异步复制的好处就是主节点的吞吐量能够达到最大,但是主节点故障后异步复制系统可能会导致数据丢失,这是一个严重的问题。通常的解决方案还包括半同步复制,即选择一个从节点和主节点进行同步复制,所有其他的节点采用异步复制的方案。此外,有时候我们验证新业务的时候还会采用双写的方案,即一份数据同步的在两个库中写两遍,等后续验证无误后再改回单写操作。

1.2 配置新的从节点

  针对增加新节点或者替换失败节点的时候,新的副本将是一片空白。这个时候通常的做法是将主节点在某个时刻建立一个一致性快照(MySQL通过某些工具可以,而LevelDB直接支持一致性快照访问迭代器),然后将快照数据传递到新节点上进行恢复,随后新节点从快照开始的位置再向主节点请求所有的数据变更,这个操作称之为catch。

1.3 处理节点失效

  对于复制中从节点失效(比如从节点崩溃,网络闪断等),因为从节点会记录自己最后成功应用的日志,所以从节点恢复后只需要从故障点开始再向主节点进行catch就可以了,处理起来相对容易。
  针对主节点失效,处理起来就比较麻烦了,包括的步骤有:确认主节点失效,选择某个从节点将其提升为主节点,客户端的请求目标要定位到新主节点上,其他从节点要从这个新的主节点进行赋值。其实这几个步骤中任何一个都充满了变数,所以这种切换操作通常都是进行人工确认和执行的,当然这也是“分布式一致性协议”大放光彩的地方。

WAL实现数据库的可靠性

  之前描述到InnoDB事务部分的内容,一直感觉通过搜集各方面资料整理起来的内容都比较的散乱,说句实话很多东西现在自己也都串不起来。最近在看其他文章的时候也涉及到了Write Ahead Log方面相关的知识,感觉又些许有了眉目,实际上WAL是实现事务可靠性的一种常见的手段,而不仅仅在MySQL上才有的哦。
  学习过数据库的人肯定对ACID(Atomicity,Consistency,Isolation,Durability)特性十分的熟悉,但在数据库实现中,如果在有数据更新的时候直接覆盖原始数据,那么在使用异常时候是很难保证A、D特性的。比如常见的持久化设备硬盘都是逻辑上按照512字节分扇区来组织管理的,数据库底层的数据页也是这个大小,假如当一个事务需要更新很多数据页的时候,这个更新过程是无法保证多个扇区的写满足原子性特性的,也就是说在写多个扇区的过程中服务或者系统挂掉的话,数据库就会处于不一致的状态,所以实现上在修改数据的时候我们肯定不能直接操作数据库中的原始文件。
  针对上述问题,传统上使用rollback journal的机制可以解决,其原理是:当需要对数据文件进行修改的时候,先将原始数据的内容拷贝到一个独立的rollback journal file当中,然后直接对原始数据文件进行更新操作;当更新过程中出现crash或需要ROLLBACK的时候,rollback journal file中的原始数据将会被用来进行数据还原;而如果事务最终执行了COMMIT,那么更新操作成功之后rollback journal file中的备份将会被删除掉。
  除此之外,WAL是另外一种广泛使用的保证数据安全更新的机制。在这种机制下,当需要执行更新操作的时候,原始的数据被还是被存在于原始的数据库文件中,执行修改的只是原始数据在内存中对应的缓存页buffer pool,同时所有的更新操作将会被记录在一个独立于数据文件的日志文件中,写完日志该事务就可以返回了,而且日志通常是使用顺序追加的方式记录,所以日志落盘操作相比于数据落盘操作会快很多,事务执行响应速度会很快。但事务返回后,对应相应数据库原始文件还没有执行更新,这种更改看似是临时性的,不过数据库能够保证再次请求相同数据的时候,在满足事务隔离性要求的前提下能够返回满足条件的结果,而且只要日志被持久化了,即使后面发生崩溃也能够使用日志进行数据重建。

公司年度旅游之郴州莽山行

  公司每年都有一次年度旅行的福利,本年度通过行政整理后再经过大家投票预先,最后公平民主地选出了澳门、郴州和韶关三个选项。郴州游的周五中午开始到周日晚上历时两天半的日程,景点只有郴州莽山地质公园,一年到头忙于公司-家庭之间奔波的我们,这次终于可以出去透一口气了,那个兴奋劲甭提了。
  虽然这次旅行大家总体评价不错,不过还是同个人事先预期有所差异,也许是去年个人因为陪伴怀孕老婆的原因没有参加当时桂林游的缘故吧,所以对公司组织的年度旅游也没啥概念。本次莽山游和往常一样,报的是直接一百多个人规模的旅行团,所有吃喝拉撒全部打包给了旅行团,行政部的同事自然可以不用动脑筋进行旅程的安排策划了,不过游玩的体验自然也会有所折扣。整个旅游日程规划了两天半,而两天半的时间悠哉于一个景区,时间可以说是相当的充裕了,整个行程不用冲冲忙忙的,可以说是这次游玩最大的一个优点吧。
  因为这次旅行是报团的,考虑到缩减成本的原因,所以感觉伙食上吃的不太好。虽然很久之前我个人报团游长城的时候,还吃过带苍蝇的饭菜,对于旅游餐甚是反感。这次大家还都觉得也说的过去,但这几天天天连续地吃流水席的形式真的是要把人吃吐了,很多肉菜为了图快和流水化就都是直接放调料蒸熟的。本来在出发之前大家还一个劲头地讨论,担心去了湖南会不会吃不惯,毕竟那儿可是以辛辣全国出名的,但实际上我们所吃的菜大多数都没放辣椒,难道就是特别为我们粤港澳的游客?更诡异的是所有流水席的菜谱和上菜顺序都基本一致:海带汤、竹笋腊肉、烧豆腐、小炒黄牛肉、蒸鸡块、蒸肉、蒸鱼、水煮大白菜、蒲公英——你没看错,他们那儿把蒲公英当野菜吃,而且是每顿必上的收尾菜,实际上我们尝试后没人吃的下那东西,同时他们还把蒲公英炒来当茶喝。
  虽然莽山被评为国家级4A风景区,但从一个在成都待过几年光阴的人看来,同为4A的雅安碧峰峡要比莽山好看好玩的多了。在整个两日行程中,游览时最长的登山路线基本也就绕着一块石头(望夫石)和一条瀑布转了一圈,只花了一个多小时就走完了,其实相比较看来我觉得还不如深圳马峦山好看;一些为数目而“拼凑”的景点简直让人大跌眼镜,一个两层楼高都不到的石墩称为万寿塔,所谓的参观博物馆就是看三条比蚯蚓大一点的烙铁头幼蛇,而猴舎也就是两只分别被围困在两只铁笼子里面的猴子,里面有一个办公柜大小的舎;在过去的车程上导游还给我们大摆瑶族风俗和段子,但整个旅程连一个穿少数民族服装的都没见到,更别提少数民族的风俗人情了;整个风景区的外围只有零星的几家酒店、两个炒农家菜的小馆子、一个杂货超市,其余就前不着村后不着店了,所以整个景区的旅游经济几乎算是没怎么开发。不过也有可能旅游团做的不好,没能充分尽享莽山的魅力,但是总体感觉真的很一般啊。
  不过我的眼中的世界也不全是灰暗面,这一次旅游也非不无是处。对于长时间浪迹在大城市中,全天时间几乎都耗费在家和办公室的人来说,这次能连续两天泡在天然氧吧中着实让人幸福感满满,清凉、新鲜、湿润的空气感觉都让我们这满是甲醛、苯、汽车尾气的肺顿时苏醒过来了,而且远离城市的喧嚣和工作的搅扰,心中也感觉无比的宁静。在这份恬静中思考一下工作生活中的难题,或者品味一下《人生的意义》,或多或少地总会有那么一种收获和顿悟感。

构建自己的CA

  最近的项目在做通过银联接入牛逼哄哄的人行之CNAPS2系统,不过他们强制要求通信报文采用国家标准SM2进行硬件签名,所以公司折腾了两家硬件签名机设备来玩,这边就做了相关的机器评测,看看相关的指标是否虚标了。不过CNAPS2系统的业务算是相当的复杂的,而其性能、并发性到底怎么样也就不得而知了,毕竟互联网交易的压力都被银联、网联这样的清算组织挡下来了。
  因为SM2实在是太非主流了,而且密码学相关的东西本来就复杂的要死,所以这边就先用RSA进行签名和验签测试。同时因为硬件签名机其证书所用的私钥是通过硬件产生并保存在机器当中(而且通常都导不出来),然后通过硬件产生证书请求文件来让CA核发证书的,所以这边为了折腾方便就自己建了一个CA,然后可以按照各种姿势核发证书了!

一、构建CA步骤

1.1 openssl相关配置

  对于几乎所有的Linux系统都会默认已经安装好了openssl工具了,而其相关配置文件和工作路径在系统的/etc/pki/目录下面。
  openssl默认情况下就可以使用,不过通过修改/etc/pki/tls/openssl.conf配置文件的一些配置信息,比如证书的有效期、默认国家地区等参数,以及对新证书请求的规则检查策略配置好,后面在签发新证书会比较方便,很多参数直接使用默认值变可以一路回车了。

1
2
3
4
5
6
7
8
default_days = 1095 # how long to certify for, 3 years
dir = /etc/pki/CA # Where everything is kept

countryName_default = CN
stateOrProvinceName_default = Guangdong
localityName_default = Shenzhen
0.organizationName_default = cpplus.cc Co.LTD
organizationalUnitName_default = R&D

  从上面的配置可知,/etc/pki/CA是整个CA的工作路径,然后我们切换到该目录下,执行如下操作:

1
2
[[email protected] CA] touch index.txt serial
[[email protected] CA] echo 0001 > serial

  上面的index.txt文件会罗列出后面新签发证书的序列号和DN信息,而serial是一个全局递增的索引记录文件,每签发一个证书该文件中的序列号就会执行递增操作。

人人都是管理者

  前几天公司高管做了一个针对基层管理者的培训,培训中讲到自己是如何放弃当时相对安稳的生活工作环境,来到公司后制定具有战略性、挑战性的年度目标,然后在实施过程中自己是如何面对和克服种种困难和不利,并最终超额三倍地完成预定计划的。当然这个计划如此漂亮地完成有一定外部环境因素的促成,因为支付行业属于国家强监管环境的行业,但是所罗列的项目启动之初从零开始所面对的各种困难和挑战是客观存在且比较常见的,所以相对于那些只会引经据典、套用IBM、GE这些跟我们遥不可及的案例来剖析佐证的刻板式灌输相比,这场培训的案例就发生在我们的身边,当然也更触动、更具说服力。
  在结尾向我们推荐了管理学教父德鲁克的《卓有成效的管理者》,这本被誉为管理学的“圣经”的读物,其实早就已经买了,只不过一直拖拉着没有看完,这两天晚上乘着哄娃睡觉的时间看完了。之前对管理总给人一种错觉,那就是管理学是尽量让组织和员工提高效率、增加产出的目的,就是公司用来更加剥削和压迫的工具,再或者这类书都是给领导准备的,对技术族基层员工没有太大的作用。但当系统地看完这本书之后就会发现管理不仅仅局限于狭义上的领导,被管理的对象也不局限于基层员工,在当今知识类工作越来越多,与传统体力、机械性的劳动性质不同,现在的知识工作内容都是差异性很强的,而且在组织中工作者之间的关联性更强更复杂,除了领导在宏观层面上要对人事、工作等内容进行管理之外,每一个知识工作者个体也需要有管理自己、管理身边同事、甚至是管理自己领导的意识和能力,只有这样工作的效率才会提高、个人的价值才会得到实现、同事之间的合作才会有效和愉快,整个组织才能向着好的、积极的方向发展。

一、有效的管理

  现代社会知识劳动形的职位越来越多,这种类型的工作者不像传统体力劳动行业一样容易被严密的督导,知识类型的工作没有办法使用数量、成本来衡量,只能通过结果、产出来衡量,所以很大程度上需要工作者本人对自我管理、自我监督和自我提高效率。德鲁克在书中将管理者的角色进行了扩充,管理者的特点是能够做出决策,并且承担做出贡献的责任,所以管理者不仅仅是领导干部,对于知识工作者、专业技术人员都可以被称为管理人员,而且由于知识类工作者职位的特殊性,这类人员在工作中的决策不仅仅影响到自身,还影响到整个集体的绩效和成果输出。