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

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

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

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

我来说一下Kafka

  这些天正在准备一个技术分享的PPT,在MQ上想找一个RabbitMQ的同行作为对比。目前看来Kafka曝光率很高的,而且之前在技术沙龙的时候有同学说Kafka经常会发生消息消费延迟的问题,本着好学求实的态度(当然最主要乘着老婆孩子都回老家,自己有一些空闲时间了),找了一本Kafka的教材看了一遍,对其大致的结构原理有了一定的认识。
  先说结论吧:如果你要处理的是日志、用户行为记录等非核心数据,而且这些数据流量还挺大,那么用Kafka是比较合适的,毕竟他最初设计出来的初衷就是应对这类场景的;如果你是要处理交易、金融这类核心数据,对数据防丢失、尽量减少重复消费的可能性,那么Kafka真的不适合,要让Kafka实现这类需求也不是不可以,不过要对服务端做很多复杂的配置,而且客户端(包括生产者、消费者)也要做一些额外的编程手段,而这些配置、手段加上之后Kafka的吞吐量肯定会下降很多,那么此时再看Kafka的选择真的是得不偿失了。需要可靠性更强的MQ还是用RabbitMQ吧,他才是金融领域的大神。

一、Kafka原理简介

  Kafka是通过主题(topic)对消息进行分类的,然后主题被分成若干个分区,每一个分区就是一个提交日志,消息以追加的形式写入分区(所以写入的效率是很高的),然后消费者按照先入先出的顺序消费消息。分区是 Kafka最重要的概念,分区可以跨主机存在,通过分区可以实现数据的高性能写入读取、数据冗余和系统的伸缩。
  生产者在生产消息的时候,如果不指定消息键,那么Kafka会通过Round-Robin算法将消息均匀的分布到topic的所有分区上面,这个时候的性能应该是最好的;而如果发布消息的时候提供消息键,则Kafka客户端上的分区器会使用一种不依赖Java和系统升级的散列算法将其映射到一个指定的分区上面去,虽然通过这种方式可以保证消息一定的有序性,但是会大大降低消息的吞吐量,而且如果映射的分区不可用,那么此时发送消息就会出错误。
  消息以追加的形式写入分区后,消息会在设定的保留策略之内(策略是可配置的,比如限制保留时间长度,或者总共消息的大小)一直保存着,消费者通过消息偏移量记录该分区的消息将要消费的位置,消息偏移量是一个不断递增的整数值,在创建的时候Kafka会把它添加到消息里面,并在每个分区中保持唯一。因为消息偏移量标示了将要被消费的消息位置,在消费者崩溃、关闭、重启时都要保留该值的正确性,属于Kafka中重要关键数据,所以是保存在ZooKeeper里面的,而新版本中该偏移保存在Kafka集群自身了。
kafka-cluster
  Kafka的服务器也被称为Broker,其负责接收生产者的消息、为消息设置偏移量、然后提交到磁盘固化保存,同时Broker还能针对消费者的分区请求返回消息体作为响应。多个Broker可以组成集群,其数量可以根据单个Broker的数据容量、单个Broker网络吞吐量、分区的副本数目等因素计算得到。Kafka主题的每个分区可以在不同的Broker产生副本(即分区复制),而借助ZooKeeper所有的分区实例只有一个作为Leader,其余副本作为Fellower存在。

让log4j和rsyslog在一起

  前两天用Java写了一个代付通道代理,因为合作方给的Demo样例就是Java的,所以基本现成的程序调试验证起来也很欢快,而且同主服务用Thrift进行耦合也毫无悬念。写好的代码可以同依赖库全部打包成一个jar文件,在生产上部署也是挺方便的。现在发现在金融领域Java的使用规模要比C++广泛的多,而我们之前处理这类需求,基本都是用C++把别人的样例翻译一遍,其中涉及到的签名加密算法都是用OpenSSL来实现的,有时候这玩意儿和Java有些差异性很难调试,而且OpenSSL本身技术性就强、文档也确实,导致这玩意儿不是一般的难写,更有甚者稍不注意就给你开个core dump或者内存泄漏。
  在Java下面开发,使用log4j基本是日志库事实上的标准了,而且通过配置文件可以自定义日志记录的字段、显示样式、日志文件的保存和管理等操作,可谓是功能强大、使用灵活。如果是本地日志处理基本是够用的,但是我们有也有专用的日志服务器来收集和归档,因此这个异类的服务也必须要能把日志转发到日志服务器才算是需求完整的。之前说过,我们系统重构之后使用了rsyslog,而log4j也对rsyslog提供了对接支持,由此可见选择一个主流的、标准化的组件比自造轮子更科学,特别是在公司研发能力有限、时间精力不足的时候,否则这种插屁股的事情真的是无底洞……
  关于log4j同rsyslog的对接,网上也有很多参考,但初次配置的时候还是有一些折腾的,这里描述一下配置过程和并且给出一个完整的配置,方便后面直接拿来用就可以了。

关于Thrift RPC之C++服务端和客户端的一个封装

  之前也介绍过,Thrift总体架构是分层设计的,用户就可以根据自己的需求对各个层进行个性化选择和定制,但这也带来了弊病:细节多了的话就增加了复杂性,尤其Thrift相关文档严重匮乏已经被诟病许久,这么一来无疑增加了初用者的门槛,就类似于一个工具无论再强大,但是man出来有几十上百个选项参数,估计再有能耐的人也会立马蔫了一半。其实大多数服务端项目的需求都相似,而且一旦固定下来就不会变更了,所以选择常规并符合业务模型的选项组件,将其封装好服务端和客户端调用框架,这样业务开发者就可以方便的用来做业务开发,因而整体说来是一件很有意义的事情。
  Thrift已经在项目中被广泛使用,总体来说性能不俗、稳定可靠,而且很多公司自己开发的RPC框架都主动兼容Thrift协议,说明这货使用还算挺广泛的,虽然之前也说到使用Thrift有些小坑需要注意,比如TSocket Timeout参数,服务端、客户端阻抗匹配等问题。还有就是Thrift是一个纯粹的RPC,功能相对比较单一,不像Zeroc-ICE除了做RPC外还集成了大量的服务治理的功能组件:服务发布和发现、负载均衡、配置更新和同步、服务自动尝试等,但是有时候想想,Do one thing and do it well不正是UNIX的哲学精髓么,ZeroC-ICE不是一时半会儿可以玩溜的,而这些服务治理的功能完全可以用自己熟悉的组件来实现对应功能。
  在之前的开源项目tzmonitor中已经使用Thrift了,基本按照目录结构和封装在其中的添加自己的业务逻辑代码就可以直接使用了,这里主要描述一下新建一个Thrift接口需要的步骤和流程。
apache-thrift

(a) 编写.thrift文件
  在thrifting/source中,可以任意添加.thrift文件,在这个文件中我们会常规的定义数据类型struct和服务接口service,相关的语法请直接参考Thrift相关文档;

关于自己写的两个小项目tzhttpd和tzmonitor

  前面的文章提到了自己开发的tzhttpdtzmonitor,虽然不是什么厉害的东西,但是个人感觉对于后台开发者来说算是比较有用,同时也是自己认真开发和维护的小项目。在这篇文章中,我就将这两个项目实现中的小细节和大家分享一下。

一、tzhttpd - 一个通用的HTTP开发框架


  在程序员界有一个说法:每个后台开发工程师都有一个自己的Web Server。这个说法也非空穴来风,尤其是对于做C++后台开发的,虽然C++程序酷爱造轮子自然是一个原因,但究其根本是C++语言标准本身没有集成一个HTTP框架,甚至C++标准还没有敲定一个标准的网络库,而大家风风火火的造轮子也没有形成一个事实上工业标准的HTTP框架,所以这种尴尬的境地就这么一直持续着。
  自己在做后台开发以来,就使用了boost.asio开发了一个简易的HTTP框架,主要目的是用来做应用程序网关相关的东西,不过那个时候自己的经验和能力有限,而最近工作中越发感觉对一个稳定好用的HTTP框架的需求,在对生产服务端系统的各项要求有了更深入的理解之后,将之前的项目进行了再整理和优化,就得到了上面提到的tzhttpd了。

1.1 特性

  a. 他是基于boost.asio高性能异步框架开发的,所以理论上可以支持很高的并发度支持。因为我的工作环境迫切要求是吞吐量而不是并发度,所以也没有对他做更深入的并发测试和验证,不过框架本身的性能还是不错的;
  b. 虽然只支持HTTP协议的GET/POST方法,但是也可以应对绝大多数应用场景了。HTTP请求的报文、数据都进行了解析和存储,业务层可以很方便的取用;支持Keep-alive长连接;支持VHost虚拟主机。
  c. 支持表达式描述的请求URI匹配,将请求转发到匹配的handler中去。除了将handler写死在项目中之外,还可以通过配置文件和so动态链接库的方式,动态增加URI和对应的handler,这个过程可以方便的部署、更新业务,其他业务不停机不受影响;
  d. 虽然最初是用来做应用程序网关使用的,但是在后期我也增加了VHost、Cache-Control、Content-Type、Redirect的支持,而且还计划支持FastCGI协议,在一定的程度上做一个可用的WebServer;
  e. 附带一个internal_manage的管理界面,方便不停机对服务进行某些更新和维护;

Git工作流的使用

  最近好久都没有更新博客了。
  一方面是自己“三十 而未立”也当爸爸了,在幸福洋溢之余也还有很多的事情需要去做,很多时候下班和周末没有时间开电脑了;另外就是工作上面的事情比较繁琐,而且与此同时挤出零碎的时间完善了一个HTTP服务端框架tzhttp和一个简易的信息收集系统tzmonitor,关于这两个系统的细节我后面会单独描述,此处暂且不表了。不过在写这两个项目的时候,我使用了Git Workflow和Git Submodule特性,感觉确实很方便实用——如果说Git是一个强大的版本控制工具的话,那么Git Workflow就是在现实工作中活用这个工具的“术”了,Git Workflow就像是一个Git在团队实践项目中的工作模式,套用这个模式可以清晰完美解决工作中的版本控制、团队合作、迭代发布的需求,其本质提现的是有效的项目流程管理和各个参与者对于开发维护工作的协同约定。
  说到Git Workflow就不得不谈大名鼎鼎的A successful Git branching model了,这里祭出他的Workflow框图:
git-workflow

人到中年,是该给自己配份保险了

  随着爸妈年纪越来越大、新的生命即将诞生,从来没有感觉自己的责任越来越重,而且“享受”独身子女政策光芒照耀的人,会这种无他可依的孤独感尤为的强烈。太太很久之前就说到保险的事情,现在看来确实是很有必要——倒不是说怕死,而是作为家庭的顶梁柱,已经突破个人的价值,而是全家的依托之所在,虽然中国人从心底里有一种抵触保险的情节(而他的产生感觉毫无根据可言),除了强制的社保、医保、车险之外几乎不会涉及其他的商业保险,身边买其他商业保险的人主要也是身边的朋友是干买保险这一行的,不过在中国这种国情和大环境下,也只有通过保险才是最稳妥的方式手段,借用杠杆提升家庭的抗风险能力。
  年底前也话了不少时间,从一个保险文盲小白,成长为一个对人寿保险略知一二的人,下面就是个人对保险的认识和理解,以及和我相似处境同伴的一些建议,希望能对大家提高保险意识、选择保险产品尽一份绵薄之力。

  言归正传,除了央行、证监会和银监会,中国还有一个相对低调的保监会。因为央行和银监会和大家手里的资金以及社会生活息息相关,所以大家会很熟悉;中国股市跟中国足球一个德行,正所谓恶名传千里,证监会几乎天天被大家问候,曝光率自然很高;中国家庭绝大多数都是保守的储蓄理财,保险除了我们这一代年轻人才有所关注之外,老一代人除非银行渠道推销,受众范围小了自然也显得低调很多。保险按照类型也分为财产保险、养老保险、人身保险,财产保险只有家产万贯的大佬才会考虑,作为一个都快活不下去的穷屌丝自然无须关注;养老保险基本也是钱多的人烧的慌,随着货币不断贬值,感觉还是买房养老更可靠些;人身保险主要以人的健康为目标的保险,每个人都不能保证自己永远健康无疾而终,这个是涉及到人生存本能的需求,也是这篇文章所关注的险种。此外还需要说一句,就像支付公司需要央行的支付业务许可证牌照一样,保险公司也需要保监会的保险牌照才行,不是你有钱就能玩的,而且保险牌照还有地区、险种的限制。

春节长假中的学习小结

  今天没有像往年一样做一个年终总结贴出来,主要是技术方面在之前的文章中都慢慢透露出来了,而且年底也公司也填了各种绩效考评,总结性的东西都写的想吐了,所以也不再流水账了。今年放假没回老家,老爸老妈都来深圳照顾我们了,虽然过年少了些热闹和气氛,但是家人围绕一起的感觉也没显孤单,而且少了拜年胡吃海喝那些形式,倒是七天长假有了些许空闲的事件。
  这几天读了几本书:《Rust 程序设计语言(第一版)》、《Go语言实战》、《RabbitMQ实战指南》、《TCP/IP高效编程:改善网络程序的44个技巧》、《MySQL技术内幕 : SQL编程》,有些想说的,就码成一文吧。
dog-year
  前面两个是编程语言类的图书,读他们倒不是想折腾新开发语言的意思:首先C++已经很复杂了,新标准刷存在感似的层出不穷,足够自己喝几壶慢慢折腾的了,虽然C++使用经验也挺多的了,但自己还不敢冒言“精通”之;而且随着年龄增大,对自己的方向和目标也更显的清晰,集中精力在重要、感兴趣、本质性的领域,不爱折腾这么多现象层面的东西了。了解Rust主要是最近区块链越来越热了,据说绝大多数的区块链框架使用Rust开发,所以这个语言是不是很独特?Go作为含着金汤匙出生的幸运儿,在中国搞的风生水起,各种资料、框架、Repo排山倒海般的袭来,所以也想看看这个语言为啥这么快风靡世界!

Lua脚本语言语法速览

  之前先上了Redis Lua的优化,这里把Lua的基本语法也顺便整理一下,后面回顾查阅会比较方便。
  其实关于Lua这个脚本语言,之前在TP-LINK工作的时候就与之擦肩而过,那时候别的小组在用他做路由器软件(基于openWrt)。后面在逛风云大大的博客时候也时常遇到过他的身影,另外在拜读开涛《亿级流量网站架构核心技术》的时候,书中描述针对大流量网站的开发、运维、管理等很多地方也是用Lua的。虽然此时对Lua的使用场景接触有限,但是看过Lua教程后发现他是一个精炼小巧的语言,现在开发圈子系统语言、脚本语言纷繁丛杂,在他们争来争去不可开交的时候,Lua反而在夹缝中找到了适合自己生存的土壤:他不求接触系统底层获取超凡执行性能;也不求建立丰富的数据结构和程序库,培养封闭自己的生态圈;而他把自己变得极为的小巧精简,用ANSI C实现因此可以运行在几乎所有的架构平台上面,也可以寄存在很多成熟的开发组件当中,当别人觉得蹩脚不方便的时候,我能够见缝插针迎难而上,真是个不错的策略啊。
  Lua程序设计这本书通篇200多页,相比于其他语言的教程可以说是很简短了,其中由易到难描述了Lua语言的方方面面。Lua要是深挖的还是有很多东西可以学的,因为我们只是用他来做插件,当前看来不会做很复杂的大规模的开发,就先看看数据结构、语句、函数这类语言的基本知识吧!

一、Lua概述

  Lua的语句不需要分隔符,所以不用纠结换行、分号等这些东西,可以按照自己的习惯写出工整方便理解的句式。Lua解释器会不断的尝试解析输入的每行内容,如果发现不能够形式一个完整的语句块,就会等到更多的输入内容。在交互式模式下,通过EOF或者os.exit()可以退出交互式Lua shell;如果将执行的语句放入文件中作为脚本,在Lua shell中可以通过dofile(“file.lua”)就可以加载这个脚本;如果只想测试某些Lua语句,可以运行lua -e “print(math.sin(12))”的形式,这样就直接运行语句,而不会启动生成交互式的Lua shell。