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

  专注后台服务端开发也好久了,自我感觉经验增加了很多,接触到的东西确实不少,博文也批量更新了很多。表面看似很多很杂,但个人心中思路计划感觉还是比较明确的,此处做一阶段性整理和总结吧。
  其实不仅仅是后台服务端开发,就整个软件开发的知识构成也是有所层次的。个人毕竟不是正规计算机科班出身,也就是大家所说的半路出道的野程序员,很多时候感觉自己的知识构成还是有所缺陷。长痛不如短痛,晚补不如早补,该学的终究跑不掉!

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

  虽然当下微信公众号席卷自媒体之势如火如荼,但是文章展示个人还是偏向于独立博客的方式,主要是因为个人可以控制的东西比较多。我想,对于我来说,这个时代没有什么比个性和自由更为重要的了吧。
  下面是一些网络知名人士的博客,以及在搜索资料过程中遇到的好站点。除了不感兴趣的前端、移动端外,过于Java/Nodejs等语言化的博客也被KO了,希望平时没事多看看吧!

HTTPS原理简单介绍

  HTTPS在今后的互联网中必将扮演者越来越重要的角色了,国外互联网大佬对https部署也是竭力鼓吹呐喊,HTTP/2协议的推广更是逼着你不上也得上!在HTTPS普及化过程中,必然会损害某些集团的利益,但是这是互联网的趋势,历史的洪流是谁也阻挡不了的!
  这篇文章就是对HTTPS的大概做一个了解,力图宏观上掌握其基本原理和流程,而其中涉及到的具体加密算法的细节之流就留给那些博士title的人研究去吧!
  还是一样,要用Wireshark抓取和分析SSL/TLS的数据包,需要设置电脑的SSLKEYLOGFILE环境变量才可以。在Windows上面搞了好久,发现抓到的数据包还是不能解密,最后在Ubuntu下一次就完成了,看来搞开发的话还要Linux算是神器啊!抓取的数据包和Master-Secret也打包共享给大家了。此外为了简单起见,客户端请求禁用了Diffie Hellman支持,这个算法是为了提高安全性考虑的,好处就是密钥可以独立于服务器的私钥,所以历史数据即使在私钥被窃取的情况下,会话的内容也无法被破解。
https
  上面展现的客户端和服务器整个通信过程尽收眼底:首先三次握手建立TCP连接,然后客户端发起HTTP请求并得到302跳转,客户端进行ACK确认后,转而向443端口进行TCP三次握手连接,接下来就是TLS协商,加密信道建立后采用加密方式进行数据的传输。流程中夹杂着TLS和TCP的数据包,这一点也不奇怪,因为ACK是TCP协议的特性哦!

RPC设计和使用中的一些杂谈

  RPC当前在大公司的开发中越来越流行了,各大厂的开源RPC框架也呈百花开放的状态。在通过前面的文章做了一个对Google出品之gRPC的使用手册,也算是在使用方面有了一个基本的了解。恰巧最近逛别人博客的时候,看到几篇关于RPC原理和设计方面的文章,觉得十分不错,于是这里就将这些文章进行整理,对RPC设计、使用和实现中的那些乱七八糟的问题进行一个归纳总结。

一、RPC的原理和关键点

1.1 RPC的原理

rpc
  RPC的原理可以说是再简单不过了,一张图足以说明问题,总体来说会经历以下的步骤:
  (1). client代码像普通函数调用一样调用client stub函数,这个调用是本地调用,调用参数会和平常函数调用一样进行返回地址和调用参数压栈操作;
  (2). client stub会把调用参数和其它信息(比如调用方法名、调用属性等,可以称为metadata)进行打包封装成message,然后通过系统调用发送该message,这个打包的过程是个序列化的过程;
  (3). client寻求到服务端的地址,然后通过本地操作系统经由某种协议,将上述message发送给server端;
  (4). server端的操作系统接收message后将其传递给server stub;

分布式系统入门笔记(六):基于ZooKeeper的分布式系统的应用场景

  至此,Paxos、Raft、ZAB代表着分布式系统中最常见的一致性协议都有所了解,但是除了PaxSql之外,对于分布式系统一致性原理的实际应用还处于一脸懵逼的状态中。此处于是主要借着《从Paxos到Zookeeper:分布式一致性原理与实践》中的案例,依靠ZooKeeper分布式系统组建,对分布式系统的使用情境做一个简单的了解。毕竟嘛,我又不是做学术的,了解原理后不知道现实有什么用处又有啥意义…
  ZooKeeper扮演者分布式系统的管理和协调框架的作用,通过前面对ZAB和ZooKeeper的了解,ZooKeeper通过ZNode数据模型和序列号、持久和临时节点分类,以及Watcher事件通知机制,可以快速构建分布式应用的核心功能,看看Apache旗下那么多基于ZooKeeper的分布式项目就可晓而知了。ZooKeeper的集群达到3台就可以正常工作了,但是工业上通常认为至少达到5台才是合适的,一方面机器增多集群的可靠性增加了,再次集群工作过程中常常会有机器下线维护的情况,这样在一台机器下线的时候集群还可以容易一台机器宕机而不停止服务。
zookeeper
  再次说明,个人没什么分布式系统的经验,这些都是查阅资料摘抄得来,如果错误尽请指正,被我误导概不负责!

一、数据发布/订阅(配置中心) - Publish/Subscribe
  发布/订阅模式不仅仅会出现在这里,通常消息队列的设计中会更加常用到这种模式。发布/订阅模式功能可以分为这几种模式:
  (1). Push模式是服务器主动将数据更新发送给所有订阅的客户端,优点是实时性好,但是服务端的工作比较繁重,常常需要记录各个客户端的状态信息,甚至要考虑消费者的消费能力实现流量控制工作;
  (2). Pull模式则是由客户端主动发起请求来获取最新数据,通常采用定时机制轮训拉取的方式进行,所以实时性较差,但好处是实现简单;
  (3). 还有就是结合两者进行推拉相结合的方式,客户端向服务端注册自己关心的主题,一旦主题数据有所更新,服务端会向对应订阅的客户端发送事件通知,客户端接收到事件通知后主动向服务器拉取最新的数据。

分布式系统入门笔记(五):ZooKeeper之ZAB一致性协议

  得益于Zookeeper在生产环境的广为使用,ZAB(ZooKeeper Atomic Broadcast,ZooKeeper原子消息广播协议)可算是最广泛应用的分布式一致性协议了,其是对Paxos算法进行了大量的改进后形成的分布式系统数据一致性协议。当之前了解Paxos和Raft算法后,落下ZAB总觉得欠缺了那么点什么。查看资料发现ZooKeeper是2007年开始开发的,而Raft算法2013年才正式发布,所以Raft中的一些设计难免会借鉴ZAB,两者存在了很多相似之处,不过多了解多掌握,想必对于分布式系统原理的融汇贯通还是会大有裨益的!

一、前言

  首先强调一点,无论是ZAB还是Raft,作为生产环境都极度强调了事务严格按照客户端请求的顺序提交,这一点在Zab+vs.+Paxos中解释的很清楚:
  Paxos注重的是一个状态机模型,一致性协议保证所有的状态机副本以相同的顺序执行相同的指令,那么所有状态机可以保证以相同的状态变化进行转移。而为了性能方面的考虑,一致性算法都允许客户端提出多个提议,当客户端并行或者重叠地提出多个决议的情况。在MultiPaxos就有了提交窗口的概念,但是在某个时刻点Leader发生崩溃后,对应的提交窗口中的提案可能有的提案被提交,有提案未被提交,那么新选出来的Leader可以按照任何顺序重新组织这些提案的表决和提交顺序,甚至也有可能会被丢弃掉。所以,Paxos算法没能够保证严格的因果一致性。
  ZAB和Raft注重的是主备(primary-backup)工作模式,各个副本节点会严格按照Leader接收到客户端请求的顺序进行提交,所以可以描述为一种可靠的增量状态更新。客户端可以提出多个决议,这些决议保证会按照FIFO的顺序被提交,即便在Leader崩溃后发生Leader选取的情况下也会有此保证。虽然,Paxos可以不开启提交窗口的功能,任何时候都只允许有一个未提交的决议,那么就可以得到严格序列化的状态转移,但是相比ZAB和Raft这种专门设计优化过的一致性协议,性能会大打折扣;还有就是Paxos算法可以通过将多个提案封包成batch模式,然后整体显露作为一个提案来表决处理(PhxPaxos有这么一个特性)以提高性能,但是按照Paper所述这些改进措施不见得性能会有多大的提高。

Linux服务器的那些性能参数指标

  一个基于Linux操作系统的服务器运行的同时,也会表征出各种各样参数信息。通常来说运维人员、系统管理员会对这些数据会极为敏感,但是这些参数对于开发者来说也十分重要,尤其当你的程序非正常工作的时候,这些蛛丝马迹往往会帮助快速定位跟踪问题。
  这里只是一些简单的工具查看系统的相关参数,当然很多工具也是通过分析加工/proc、/sys下的数据来工作的,而那些更加细致、专业的性能监测和调优,可能还需要更加专业的工具(perf、systemtap等)和技术才能完成哦。毕竟来说,系统性能监控本身就是个大学问。
linux-performance

一、CPU和内存类

1.1 top

  ➜ ~ top
linux-top
  第一行后面的三个值是系统在之前1、5、15的平均负载,也可以看出系统负载是上升、平稳、下降的趋势,当这个值超过CPU可执行单元的数目,则表示CPU的性能已经饱和成为瓶颈了。

  第二行统计了系统的任务状态信息。running很自然不必多说,包括正在CPU上运行的和将要被调度运行的;sleeping通常是等待事件(比如IO操作)完成的任务,细分可以包括interruptible和uninterruptible的类型;stopped是一些被暂停的任务,通常发送SIGSTOP或者对一个前台任务操作Ctrl-Z可以将其暂停;zombie僵尸任务,虽然进程终止资源会被自动回收,但是含有退出任务的task descriptor需要父进程访问后才能释放,这种进程显示为defunct状态,无论是因为父进程提前退出还是未wait调用,出现这种进程都应该格外注意程序是否设计有误。

文本处理利器sed与awk使用总结

   在整理为知笔记的时候,发现很久以前写的awk、sed学习笔记,这不禁然让我回想起自己最开始接触Linux的情形。那时候还在江安校区东五宿舍,一天晚上打开水瞄到了一张海报——“你想了解让微软感到畏惧的操作系统么?”虽然这个讲座最后我也没听成,但也自从那时起Linux就在我心中烙下了深深的印记。上学的时候家里真的很穷,学费也是申请的助学贷款,自认自己从小开始还是比较懂事的,也不知道那时什么勇气让我跟父母开口要四千多块钱买电脑的,但父母还是爽快地支持了我,放假前入手了当时乞丐版ThinkPad R60e,这台电脑用的Celeron处理器(后面手动升级成了Core Solo单核处理器),1024x768的LCD显示器,80G的硬盘居然也装了双系统,虽然烂但是陪我度过了好几个年头,直到我研究生实习后用自己的实习工资换了另外一台联想笔记本(现在还在给我老婆用)它才下岗,当然这已是后话了!
   做的这个笔记,是在放暑假前从图书馆借的那本蓝皮《Unix Shells by Example》,暑假过程中自己折腾的产物,其实当时根本不知道学习这个有什么用。sed、awk当然不会用来单独开发程序,但是在命令行处中理文本,字段切割,分析日志,写一些shell脚本(比如数据库patch)的时候,还有就是在自动化做软件、服务配置文件更新的时候,还是非常好用的。

一、sed - stream editor for filtering and transforming text

   sed的操作格式

➜ ~ sed -opts ‘command’ filename(s)
➜ ~ … | sed -opts ‘command’ # 管道输入

   sed的opts选项

-n 取消默认打印。默认情况下会全文打印,因此会重复打印匹配的记录,而这个选项用来只打印匹配记录
-e 多个command可以用这个连接,比如 sed -n -e ‘cmd1’ -e ‘cmd2’ files
-i 使sed的编辑保存。默认sed操作没有破坏性(不会对原文件修改),但是确实要编辑原文件时候可以加上该参数

   这里实验使用《UNIX shell by example》里面的datafile文件作为数据集。

1
2
3
4
5
6
7
8
9
10
11
➜ ~ cat datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
➜ ~

1.1 删除 d

注意,和通常的法则不一样,下面的行号都是从1开始计数的。
(a) ➜ ~ sed ‘3d’ datafile
删除第3行,其余行打印到屏幕上。再次强调sed默认没有破坏性,原文件datafile没有改变。
(b) ➜ ~ sed ‘3,$d’ datafile
删除第3行到文件的末尾记录,只打印剩余的第1,2两行。$代表文件或者记录的最后一行
(c) ➜ ~ sed ‘$d’ datafile
删除最后一行。
(d) ➜ ~ sed ‘/north/d’ datafile
删除匹配north的行,其余记录都被打印。

MacbookPro上基于ZFS的Gentoo双系统安装

  实在没想到,买了Macbook Pro还是避免不了折腾的命,原本很大程度买Macbook Pro就是不想折腾滴。
  或许上层开发程序员无所谓,但无奈对于对做Linux底层开发者来说,涉及到macOS和Linux操作系统的差异性太大了;即使macOS命令行程序无比丰富,但是BSD风格和Linux那一套相比有时候差异还挺大的;8G内存用虚拟机太吃力了——总之,这种情况唯有双系统可解~
  至于发行版,自从遇到Gentoo之后,就对其他发行版无爱了,而文件系统也一直坚持着ZFS装系统,XFS保存数据。这次是macOS+Gentoo了,原理和步骤差异不大,这里总结一下,给需要的人做个参考吧!
gentoo

  1. EFI启动引导rEFInd
      因为macOS系统使用GPT分区和EFI引导模式,所以要安装的Gentoo也必须使用这种引导模式。rEFInd是一个优秀的EFI引导器,支持Windows/macOS/Linux平台,所以这里需要使用rEFInd来接管,然后用来引导macOS和Gentoo。
      安装rEFInd的方式十分简单,按照教程几步就可以了。从EI Capitan开始,macOS启用了SIP特性,所以必须在恢复模式下安装rEFInd。

分布式系统入门笔记(四):Raft一致性算法

一、前言

  Paxos在分布式系统中地位是不容置疑的,现代分布式系统的实现基本都直接或者间接依赖于Paxos算法。不过Paxos算法有着固有的缺陷:原始的BasicPaxos原理还是比较容易理解的,整个算法无非被分为Prepare和Accept两个阶段,但是要把这种算法工程化实现,各个节点的角色是对等的,系统的效率(可用性)将会非常的低,所以常用的也就是MultiPaxos变体版本以提高性能,这也就隐含的包含了leader的概念了,然后MultiPaxos还允许一个提交窗口,窗口中允许发起多个提案,但是这种情况下考虑到服务器随时可能崩溃的情况,算法将会变得极端复杂。Lamport爷爷就此也是简明说了几句不清不楚的优化,没有具体的实现细节,算是挖了一个巨坑吧。所以说了解BasicPaxos只是一个皮毛,将其推送到工程化可不是件容易的事情。
  Raft算法是斯坦福两位博士生提出的分布式一致性系统,从其论文的题目《In Search of an Understandable Consensus Algorithm》可以看出,作者以Paxos过于复杂为出发点,力求得到一个正常智商的大学生都能看懂,且工程上也容易实现的分布式系统一致性算法为目标。Raft算法借鉴了Paxos的原理,但最大不同是显式强化了Leader这个角色(虽然很多Paxos算法的实现也会产生Leader角色,但这不是Paxos算法本身所必须的),并添加了各种约束条件(比如日志的连续性),让算法更加容易理解和实现。虽然吾等草根屁民尚且不能从理论上审视这个算法的正确性,不过短短时间内美国很多著名大学分布式教学都将Raft算法列入教学课程,且基于Raft协议的项目也越来越多,这些事实已经足以证明一切了。
  学习Raft算法,一篇普通论文和一篇博士学位论文算是不得不读的经典,而前者网上发现了翻译好的中文版本,简单对比了一下原文,发现翻译的质量还是挺高的,很值得参考,但有些原理中文理解困难的话可以对比英文方便理解。作为正规论文,按照论文八股需求难免有些啰嗦拖沓,本文就是按照前面论文阅读摘抄一些重点要点出来,而后面那篇两百多页的博士论文,后面可以慢慢评鉴一下作为补充吧,当然最好的方式还是——一言不合就读代码,毕竟作者说就两千多行!
  还有,论文对状态机的描述比较的好,算是归纳了分布式系统的本质——复制状态机的基础是通过复制日志来实现的:当每个副本的初始状态相同,只要保证各个副本得到的日志都是顺序且一致的,那么按照相同的顺序执行这些日志中的指令,所有副本必然可以进行相同的状态转移得到相同的结果。所以分布式系统解决的根本问题,就是一致性问题,具体就是日志一致性问题,在这个基础上,上层就可以方便实现分布式日志、分布式数据库(bin log)、分布式存储等具体业务了。
raft-stat

二、Raft算法

2.1 Raft算法基础

  Raft算法保证和Paxos算法具有相同的安全性,当集群中绝大多数服务器是正常的,则集群即可以正常工作,比如5个节点的集群,允许2个节点的失效。Raft算共有三种角色、需要处理三个问题,三个角色分别是Leader、Candidate、Follower,三个问题是Leader选举、日志复制和安全性,三个问题将会在后面详细阐述。
  任何服务器只能处于上述三种角色中的一种,正常工作的集群具有一个Leader,剩余的节点都是Fellower,系统保证任何时候至多只有一个Leader,也有可能在选举的过程中尚未产生Leader,而在选举新Leader的时候会产生Candidate这个角色。