新的一年,生活要过得有仪式感

2017这一年

2017年即将过去,现在回顾发现,这一年不管是年初定的目标,还是年中的想法,都没有完全实现。
过去这一年,面临着许多挑战与混乱。
很多时候,事物的发展,并不像我们预先设想的那样,但我认为一个有效的全年计划,还是非常重要。
写新年计划这个想法,也是受到同学的启发。

设想

以后每年新年来临之际,我都会写一个新年计划,一是看看过去一年的想法实现了多少,二是展望一下未来。算是一个自我总结,改进且不断进步,也是一个对自我优化迭代的一个过程。
我也希望我能回到大学时的状态,保持一定的阅读量。一个勇敢、坚定、有目标且不断奋斗的自己。

2018

  • 看200本书,记录书单及读书笔记
  • 保持背英语单词的习惯
  • 加强锻炼与膳食均衡,BMI指数达标
  • 不断学习(计算机、数学、英语)
  • 早睡早起,不熬夜(11-7)
  • 认识20个优秀的人
  • 找到1个有趣的对象
  • 通过学习取得1个证书
  • 定期淘汰旧东西,执行极简生活理念
  • 做20件新鲜事
  • 看一场演唱会

    家庭生活计划

  • 周四总结日 (回顾本周计划执行情况)
  • 周五美食日 (吃顿大餐)
  • 周六活动日 (执行旅游计划中的短期任务)
  • 周日运动日 (爬山,远足)

    娱乐休闲计划

  • 环球旅游计划探索
  • 日本旅游
  • 深圳游玩
  • 香港游玩
  • 澳门游玩
  • 台湾旅游
  • 探索1~3个未知但意思的景点
  • 短期旅游(城市本地景点活动探索)
  • 学10首外语歌
  • 学20首华语歌

    每日时间表

  • 早起喝一杯白开水
  • 刷牙听歌洗澡洗头
  • 出门上班,希望能直接骑共享单车到地铁站,不要坐公交换乘
  • 地铁上通过Telegram阅读过去一天技术领域的发展与新闻
  • 上班做好每天工作计划
  • 睡前喝杯牛奶,刷牙洗脸洗澡上床

    财富增长计划

  • 提升技术能力,不断学习新技术,并在生产环境中实践
  • 在证券投资方面,继续原有的持股策略,但转变为长期持有,不谋求短期利益
  • 探索能否在美股或港股中操作
  • 控制流动资金的比例,并做好流动资金增长计划

    行为习惯提升计划

  • 不断跳出心理舒适区
  • 多聆听,多接纳多方意见
  • 多赞扬肯定对方
  • 严格要求自己,对他人要多宽容

    体重增长计划

  • 定期执行超市采购计划,保证家里任何时候都有吃的
  • 每天下午增加一个下午茶
  • 要多吃,辅助定期运动

    每周细分计划

  • 学习一个好习惯,记录并执行
  • 看4本书
  • 看2部电影
  • 1次跑步运动
  • 1次爬山或远足
  • 看5集美剧

influxDB的使用与优化

官方配置要求

influxDB是为SSD运行设计的,如果服务器硬盘不是固态硬盘,那么按照官方的说法是不推荐的。
series(维度)是influxDB的一个比较重要的指标,维度越多,所需要的索引也就越大。

备份与还原

使用中发现有时候,influxDB的备份是可以分数据库的,但是还原导入的data会有不认的情况,就是meta中没有读取data中的数据。

还原influxDB

1
influxd restore -database xxxdatabase -datadir /data/influxdb/data ./

这时候在新的influxDB库执行

1
influx_inspect export -database xxxdatabase -datadir /data/influxdb/data/ -waldir /data/influxdb/wal/ -out xxxdatabase

重新将数据导入,并且修改meta元数据

1
influx -import -path=xxxdatabase

这时候就将xxxdatabase,从对应的/data/influxdb/data/与/data/influxdb/wal/输出到文件xxxdatabase中了。

数据维度

统计database的数据维度

1
influx -database 'xxxdatabase' -execute 'show series' -format 'csv'| wc -l

统计具体measurement的数据维度

1
influx -database 'xxxdatabase' -execute 'show series from xxxmeasurement' -format 'csv'| wc -l

openSUSE快照与回滚

前因

作死升级了openSUSE的一个不稳定版本,于是整个系统都挂掉了,无法开机。联想到snapper有个很强大的快照及恢复功能,然后一边摸索一边寻找方法恢复。

首先,要在开机的高级菜单中,选择一个最近的,能打开的快照Read Only快照。
如果不能进入系统,再选择更新的,不断重复。
如果能顺利进入系统,则执行

1
snapper rollback xxx

其中xxx为当前的版本号

再次重启发现能直接进入了,但你可能会发现丢掉了部分数据,这是因为快照内容不全导致的,这时候,执行

1
snapper -v undochange aaa..bbb

其中bbb为当前最新版本,aaa则是你要回滚的版本,这样系统就会恢复到aaa这个状态,把aaa至今的所有变更回滚。

升级变化

ifconfig,arp,netstat,route被移除出net-tools
需额外安装net-tools-deprecated

编译VIM8

编译错误

1
2
3
4
5
6
7
8
9
10
checking --with-tlib argument... empty: automatic terminal library selection
checking for tgetent in -ltinfo... no
checking for tgetent in -lncurses... no
checking for tgetent in -ltermlib... no
checking for tgetent in -ltermcap... no
checking for tgetent in -lcurses... no
no terminal library found
checking for tgetent()... configure: error: NOT FOUND!
You need to install a terminal library; for example ncurses.
Or specify the name of the library with --with-tlib.

安装必要的包

1
zypper in ncurses-devel python-devel

安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
./configure --with-features=huge \
--enable-multibyte \
--enable-rubyinterp=yes \
--enable-pythoninterp=yes \
--with-python-config-dir=/usr/lib64/python2.7/config \
--enable-python3interp=yes \
--with-python3-config-dir=/usr/lib64/python3.4/config \
--enable-perlinterp=yes \
--enable-luainterp=yes \
--enable-gui=gtk3 \
--enable-cscope \
--prefix=/usr

make
make install

Protocol Buffers 一种轻便高效的结构化数据存储格式

介绍

Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 个 .proto 文件。他们用于 RPC 系统和持续数据存储系统。
Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。

安装

安装过程中,参考了Google Protocol Buffer 的使用和原理Protobuf

了解到了下面几点:

  1. 该项目的 php 语言版本,可通过纯 php 包和本地 c 扩展来运行启动;
  2. 纯 php 包是为了提供在 php 平台上更广的可用性,而 c 扩展更注重性能;
  3. 两者的实现,提供了同一套 APIs ,应该是由同一套代码生成的;
  4. 如果用户想在他们两者之间切换,不需要重新修改/生成代码;
  5. 两者都实现了通过生成 php 代码来实现在 php 中的 message 和 enum 类型;
  6. 作者建议通过 php 来生成,支持 .proto 文件;
  7. 这个包的构建过程仅在当前目录安装扩展/包,其次还要安装该协议的编译包去最终完成 php 生成功能。

体会

了解之后,感觉实现起来还是比较麻烦,毕竟很多项目其实已经用了很久了,rpc 接口众多,一下子迁移起来其实是比较困难的。如果是新建的项目倒是可以尝试,但是每次都需要预先定义这些数据结构,其实也是带来一定的难度,因为数据结构可能会不断的变化。理论上 google 的这个协议是让不同的语言不必去例会数据结构,而只需要关注具体的数据。但是代码毕竟还是人来写的,其实用起来反而不如 json 这些标准化跨平台包含数据结构的格式。

感觉暂时还不适合在大项目中使用,毕竟开发不仅仅是一个人,而是一个团队。

如何反爬虫及恶意采集

前言

恶意采集、攻击及非搜索引擎爬虫,影响了服务器的网络,同时也有可能暴露一些存在风险/SQL注入的网站。

我们虽然是识别出了,但是他们的抓取还是没有停止,有时候一天就是上百万次,严重影响了服务器网络状况,只有千日做贼,没有千日防贼的道理。

因此,从社会工程学的角度,不仅仅要防范,还要主动出击,增加难度。

主要策略

  1. 加入延时,让他采集难度增加,效率下降,如每天100万采集,把响应时间从0.1s延长到5s,那么就可以减少98%的访问,同样的时间内,恶意爬虫一天仅能采集2万;
  2. 适当返回正确状态的假数据、垃圾内容、扰乱他们正常采集,让他们花大量时间在正确内容的甄别上;
  3. 通过跳转的形式,把爬虫的攻击引回他自己的服务器、竞争对手的网站;
  4. 通过跳转的形式,让爬虫去下载大容量 iso 文件(国内各大镜像),搞挂他的内存、数据库;
  5. 返回一些包含恶意js、非标准的html内容,搞坏他们的爬虫分析,及时中止对方程序;
  6. 必要时,可以使用杀手锏,跳转到当地公安局、境外安全组织、黑客组织。

TLS 1.3:改进延迟,部分握手加密

制定进展

IETF正在制定TLS协议的最新版本1.3,截至目前还没有正式发布,新的 TLS 1.3 基于 TLS 1.2,将移除对部分弱加密算法如 MD5 和 SHA-22 的支持。

TLSv1.3 新特性

  • 将不再支持静态RSA密钥交换,握手将默认使用前向安全(Perfect Forward Secrecy),一个安全性足够强的 Diffie-Hellman 参数。
  • 将移除 ChangeCipherSpec协议。
  • 将大幅改进握手,注重隐私,在握手尽可能早的阶段加密信息,ServerHello 之后的所有消息都是加密的,客户端只需要一次往返就能与服务器建立安全和验证的连接。
  • 客户端将在 ClientHello 阶段将提高 key_share(共用密钥)。
  • Sessions 将在握手完成之后,才会被建立。
  • Renegotiation攻击不可能发生。
  • 绝大部分的握手将处于加密状态。
  • 很多类型的信息现在也有了扩展(如 Certificate Transparency)
    改进后的握手流程

支持程度

  • nginx
    在 nginx 的最新 mainline 版本 1.13.0 中,可以看到有一条这样的介绍
    1
    Feature: the "TLSv1.3" parameter of the "ssl_protocols" directive.

也就是nginx在最新的版本已经加入这个配置选项,并且支持1.3版本的 TLS 了。

  • Firefox
    Firefox 52 已正式支持 TLS 1.3。
  • Chrome Dev
    Google Chrome 浏览器已经在测试版本中开始支持TLS 1.3了。

速度提升

在升级 HTTPS 的过程中,很多大型网站会有所顾虑,因为相比传统 HTTP 协议,TLS 的握手会耗费更多的延时,进而会影响网站的打开时间,并且使用TLS还是有可能在第一次连接的时候受到中间人攻击。
在 TLS 1.2 时代,我们可以通过完美前向加密、HTTP/2、HSTS、HSTS preload list、CHACHA20_POLY1305 协议等方式,提升网站的安全性,加快网站的访问速度,这方面也确实起到了很好的效果。

降低延时

访问安全加密网站时,首先要建立共用密钥,这一过程叫做一次握手。有专门的加密消息往来于浏览器和网站之间,每一次连接,TLS握手就随之发生。
通过移动网络访问时,由于 4G 网络的延时,加载时间可能会增加上百ms不等,也会影响到用户体验。

两代协议握手对比
对于 TLS 1.2,每次请求需要2次消息往来,才能完成握手。
对于 TLS 1.3,首次握手只需要1次消息往来,可以节约几十到上百ms不等。

TLS 1.3 改进增加了“不额外增加网络延时”模式(0-RTT)。对于近期访问过的站点,可以直接发送有用的数据,而不需要经过握手。
针对0-RTT及其他相关的扩展性,早在2016年5月之前,微信就基于TLS1.3草案标准,设计实现了一套安全通信协议mmtls。基于TLS1.3的微信安全通信协议mmtls介绍

因此,加上 HTTP/2 对多资源加载的优化,通过 HTTPS + HTTP/2 完全有希望使得速度比传统 HTTP 协议更快更安全。

Chrome 开启TLSv1.3

在地址栏输入chrome://flags/

  • 找到Maximum TLS version enabled.并选择TLS 1.3
  • 重启浏览器

OpenSSL支持

近期OpenSSL也发布了一篇新文章Using TLS1.3 With OpenSSL
该文章介绍了新版本的开发进展及一些需要注意事项。
OpenSSL 1.1.1 版本即将发布,该版本将支持 TLSv1.3,将完全兼容于原有1.1.0,理论上,只要应用支持 1.1.0,那么可以直接升级到 1.1.1。将自动支持 TLSv1.3,而不需要做任何其他操作。
编译的时候,需增加选项enable-tls1_3

新增加密套件

  • TLS13-AES-256-GCM-SHA384
  • TLS13-CHACHA20-POLY1305-SHA256
  • TLS13-AES-128-GCM-SHA256
  • TLS13-AES-128-CCM-8-SHA256
  • TLS13-AES-128-CCM-SHA256

nginx推荐配置

nginx 配置

这本来是个很简单的配置,但是还是有很多开发者没留意、没注意、对 TLS 加密等等不了解,会有一些错误的配置。
而网上的配置也参差不齐,经常有很多错误的安全套件顺序,在网上排名特别高,这里还是推荐一下Mozilla的配置,有3个档次,大家可以按自己的用户分布情况,选择对应合适的配置。
Mozilla 的推荐配置

推荐配置

这个配置能够最低兼容到 Firefox 1, Chrome 1, IE 7, Opera 5 以及 Safari 1。

  • Ciphersuites: ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
  • Versions: TLSv1.2, TLSv1.1, TLSv1
  • TLS curves: prime256v1, secp384r1, secp521r1
  • Certificate type: RSA
  • Certificate curve: 'None
  • Certificate signature: sha256WithRSAEncryption
  • RSA key size: 2048
  • DH Parameter size: 2048
  • ECDH Parameter size: 256
  • HSTS: max-age=15768000
  • Certificate switching: None

Linux文件系统修复

前因

当前的操作系统是openSUSE,系统目录使用的是btrfs文件系统,用户目录使用的是xfs文件系统。由于公司突然间断电,导致系统完全崩溃,开机后直接进入grub修复界面。初步判断是因为,计算机使用的固态硬盘,加上断电时,计算机还在做关键操作,操作完成之后,写文件的校验值checksum和文件不一致。最终导致系统目录无法读取。

处理过程

用户目录挂载盘符为/dev/sdb4
恢复时仅需一行代码:

1
xfs_repair /dev/sdb4 -L

系统目录挂载盘符为/dev/sdb3
恢复时我并没有恢复成功,直接放弃了,反正我也用不到。
但通过查看帮助似乎有下面这种方法:

1
btrfsck --repair --init-csum-tree --init-extent-tree  <device>

但我执行后不成功,于是我直接保留用户目录,然后重新安装了。

缓存的伪随机及定期清理

缓存的伪随机策略

有时候在业务逻辑上,我们需要返回一些随机的数据,越随机越好,这时候缓存较短的时间、不缓存等方式均不理想。缓存一定的时间会导致用户会以为页面没刷新,没取到数据,体验不好。
而若不缓存,大量的请求可能会造成数据库、中间件的巨大压力。
可以通过设置特定的键值+随机数的方式,来人为造成一定数量随机出来的缓存,完美解决随机问题。

1
2
3
4
5
6
7
8
$key = 'key:sample:'.rand(1, 500);
$value = $redis->get($key);
if (!$value) {
$value = self::getData('...');
if ($key) {
$redis->setex($key, rand(600, 1200), $value);
}
}

缓存时间随机+key键值随机,可以产生500种(甚至更多)组合,满足线上的需求。

长期缓存,定期清理

当我们做了缓存之后,有时候缓存的时间不能设置太长,因为总会有一些数据在变更。变更后,如果很长的时间内,缓存一直有效,那么修改的操作等于没有成功。
缓存的时间短,也导致了缓存命中率不高,内存利用率较小,反而增加了多余的两次缓存读写(缓存取不到数据,从数据库/中间件获取,再次写入缓存),性能提升不够明显。
其实对比热数据而言,99%的在库数据,是长时间不会变化的,可以通过检测数据库插入/变更/删除时间,通过特定的调度脚本,及时从缓存种移除。
如果做了这些工作,那么缓存的设置就可以大胆的设置为长期缓存,半年,整月等策略,缓存的命中率能提升一个大台阶。

缓存置换策略的选择

在redis中,当缓存的内存占用量达到峰值maxmemory的时候,这时候就需要用到置换策略了,这个策略不设置或设置错误,都会导致浪费,甚至影响系统正常运行,抛出错误,502网关错误等等。redis一共支持6种策略。

  • noeviction: 不进行置换,表示即使内存达到上限也不进行置换,所有能引起内存增加的命令都会返回error
  • allkeys-lru: 优先删除掉最近最不经常使用的key,用以保存新数据
  • volatile-lru: 只从设置失效(expire set)的key中选择最近最不经常使用的key进行删除,用以保存新数据
  • allkeys-random: 随机从all-keys中选择一些key进行删除,用以保存新数据
  • volatile-random: 只从设置失效(expire set)的key中,选择一些key进行删除,用以保存新数据
  • volatile-ttl: 只从设置失效(expire set)的key中,选出存活时间(TTL)最短的key进行删除,用以保存新数据

缓存与基础业务系统分离

如果基础业务系统与缓存放在同一redis库,那么设置了volatile-lru,就会导致正常用户可能被迫下线。设置了volatile-ttl就会导致一些缓存时间较短的缓存,没有起到作用,频繁被擦除,影响命中率,缓存效果也不理想。
若缓存与基础业务系统分离,既可以优化缓存的命中率等考核条件。同时也可以保证用户正常的使用不受影响,如session、用户登录状态、邮箱/手机验证码等数据。

session

在使用session时,应选择按照volatile-ttl策略,并发量高时,删除长期不在线的用户。

缓存

在缓存方面,通过volatile-lru,近期最少使用算法,讲命中率低的缓存及时删除,把空间让给更需要的缓存。