PlayStation 4 Pro

最近买了个美版 PS4 pro 。其实本来打算是买回给老家的一台新买的 4K + HDR 电视机配的,要不然按照国内的内容源缺乏程度, 4K + HDR 就是个摆设而已。

当然先是寄到了自己广州这边,然而玩了几天 The Last Of Us 之后,我有点喜欢这个游戏机了(挖鼻孔)。于是这几天不跑步,不运动,晚上和周末花了一点时间把它通关了。然而看着已经买了的好多个其它正在下载的游戏,更加觉得自己可以重新开始宅了。。。

以前不太理解有些人为什么会话这么多钱买游戏玩,(PC 游戏盗版一大堆在那里呢),然而有了个游戏机后才发现,它的优点——省心(不用为系统配置操心)确实是最大的卖点。作为一个玩具,它能让人纯粹的从中找到乐趣,不用再关心其它事情,这就是最好的了。

如何正确的引导用户设置好的密码

  1. 可以强迫用户输入密码的长度最小为 N 位。
  2. 不要强迫用户必须输入数字、字母、特殊符号的组合。因为过于复杂的密码用户自己都记不住几个,只能重复的使用常用的几个密码组合,或者是写下来在某个地方,结果是被别人偷看、盗走。
  3. 支付密码,只用数字就可以了,不要强迫用户必须输入其它字母或者符号。用户也许不会天天都用你的 app 进行支付,同样,再说一遍,过于复杂的密码很容易忘记。因为这个密码本身已经有登陆密码的保护了,可以做的一个限制是输错 N 次之后,暂时冻结支付或者要求进入恢复支付密码的步骤。
  4. 让你的登录表单对密码管理器友好。有些登录表格会蓄意不让浏览器记住密码,然而实际上,让浏览器自动保存和填写密码是更好的办法,这样用户可以随机生成密码填进去就完事了。而当密码管理器无法记住密码的时候,用户同样也只能从自己脑海里面的常用密码选一个出来使用,最终的结果是导致用户在不同网站用了相同的密码。
  5. 如果用户选择了记住登录状态,就不要动不动隔了一两天没登陆就把用户登录状态取消了。这点在很多 app 上面非常常见,然而,在使用了随机密码的情况下,输入密码其实是个痛苦的过程。同时,这也是个高风险的过程,因为容易被偷看和监听,尤其是国内这么多网站都还没有部署 HTTPS 的情况下。

CentOS 的默认最大 pid

最近发现新上架的几个服务器(CentOS 6)上面跑的进程的 pid 有些不一样,它们要比原来一些旧的环境上面的 pid 要大很多。看了下系统最大允许的 pid 值:

[[email protected] ~]# cat /proc/sys/kernel/pid_max
196608

这比旧系统上面的 32768 要大很多。

查了一下原因,是这样的:

The kernel begins with a default pid_max value of 32768, and then will adjust it upward based on the number of possible CPUs the system could have. It will use a value of 1024 * num_possible_cpus if that value is larger than the default. The value the kernel will use for pid_max is capped at approximately 4 million.

https://access.redhat.com/solutions/874023

也就是说,在一个系统上面,pid_max 是根据可能的 CPU 个数来确定的(不是实际存在的个数)。具体规则就是可能 CPU 个数乘以 1024。不过为了防止可能 CPU 个数较小的环境上面 pid 很快被用尽,最小的 pid_max 都是从 32768 开始的。

看了一下新服务器的可能 CPU 个数是 192,乘以 1024,刚好就是 196608 了。

Windows 的退化

Windows 本来是优秀应用软件的集中地,尤其是以微软自己的应用程序为代表,这些软件基本很少崩溃,响应迅速,性能非常好。

然而到了 modern apps/UWP 时代之后,这一切都在退化。

已经说不清是多少次被 Windows 10 上面的 UWP 应用的闪退、崩溃给弄到吐血了(其中很多都是微软自己的应用)。并且, UWP 的问题不仅仅是闪退,它的性能也远远不如传统的 Windows 应用,比如:它的启动实在太慢。

我完全不知道 UWP 是否是个好的应用平台,不知道是否是开发者的低能导致的问题。然而这些都不重要。Windows 需要的成功,靠这么烂的软件(平台)质量是只能走向死路的。

ZSH 也不完美

以前有段时间在命令行上折腾过不少时间,接触过 ZSH, Fish 等不同的 Shell,但是后来不玩了,因为 bash-completion 通常来说已经够用了。但是最近发现已经有人弄了个 Oh My Zsh 这样的项目,一些主题还是很不错的,于是重新设置了默认 shell 为 zsh 了。

但是 zsh 也不完美。

➜  ~ rsync -e ssh -avzP 198.1x.x.x:/home/luo/*.deb .
zsh: no matches found: 198.1x.x.x:/home/luo/*.deb

只能切换回去 bash 执行。

使用 Kapacitor 对 InfluxDB 数据进行统计处理

InfluxDB + Telegraf + Grafana 算是一套不错的数据收集、视觉化工具,相比于更为常见的 ELK 架构,它有着自己的特点。查询功能总得来说虽不如 ES 强大,但是优点是——已经够用了,而且它的性能不错,存储的数据占用空间也相比 ES 小。

简单介绍这三个工具:

  • InfluxDB InfluxData 的一款时序数据库,它是这套工具的核心;
  • Telegraf 则是 InfluxData 自己开发的一个数据收集工具,相比于 Logstash 或者 Mozilla 的 Heka,它有了更多的内置实用 input 插件,例如 sysstat, Mongodb, MySQL, 日志文件 grok 和跟踪 … 使用 Telegraf 可以非常容易的监控起系统和各种常见服务的各种参数,基本无需再安装其它专用工具。
  • Grafana 则是一个数据视觉化工具(“画图”的),支持多种数据后端,包括 InfluxDB,Elasticsearch,Zabbix 等。

实际上,InfluxData 是有一个自己的 TICK 架构的(Telegraf + InfluxDB + Chronograf + Kapacitor),其中 Chronograf  是用来画图的,但是看起来似乎还不成熟,不如使用 Grafana 好。Kapacitor 则是一个专门处理 InfluxDB 里面的数据的工具,用它可以对收集到的数据进行统计、触发报警等。。。

好了,说了这么多,其实是想借一个实例说下怎样用 InfluxData 的 Kapacitor 来对 InfluxDB 的数据进行加工处理。

假设:已经搭建好了 InfluxDB + Telegraf + Grafana 这套工具,web 日志收集存储在了 InfluxDB,我们想查看一些统计数值,比如每日独立访问 IP 这样的有价值的数据,我们现在该怎么做?

一般来说,有以下几个选项:

  1. 在 Grafana 里面,我们新建一个图表,每次查看时实时统计出所有的每日独立 IP。但是这个方法实在不妥,web 日志量很大,如果每次一查看那个图表就把 InfluxDB 里面的数据全部过一遍,还要计算、分组,实在太低效,性能太糟糕。对于每日独立 IP 这种数据来说,我们其实并不需要它是实时的,只要每天统计一次即可。
  2. 我们写个 Shell 或者强大一点,Python 脚本去从 InfluxDB 查询出独立 IP 数,再把结果存回 InfluxDB,再把它放到 crontab 里面每天运行,然后 Grafana 建立的图表可以直接查这个新的 measurement。这种方法远比第一种要好很多,但是仍然是需要写脚本的。
  3. 我们可以利用专门的工具——Kapacitor 来做这件事。下面就详细说下如何取每日独立 IP 数。

按照官方的简介,Kapacitor 是一款“Time-Series Data Processing, Alerting and Anomaly Detection”,也就是说——数据处理、报警、异常探测它都能做。

Kapacitor 的安装、配置都很简单,推荐从官网下载 rpm/deb 包安装,然后修改 /etc/kapacitor/kapacitor.conf 文件,在 InfluxDB 连接配置里面设置好账号、密码,就可以启动 kapacitor 服务了。

Kapacitor 有一个后台服务,用户需要做的事就是编写 TICKscript 脚本,然后把这个脚本加载。

来看这个计算每日独立 IP 的脚本,ip.tick:

batch
    |query('''
        SELECT count(distinct(clientip)) AS uip
        FROM "telegraf"."retentionPolicy"."log_measurement"
    ''')
        .period(1d)
        .cron('0 0 * * *')
    |influxDBOut()
        .database('logstats')
        .measurement('site_uip')
        .tag('kapacitor', 'true')

其中,batch 指令表示这是一个对数据进行一次批量处理的任务; |query() 表示这是数据查询的处理节点,我们在 query() 里面直接写入 InfluxDB 的类SQL 查询语句即可,但并没有加入 WHERE 条件对查询时间进行限定,这是为何?因为后面的 .period() 指定了查询范围为一天;然后再利用 .cron() 这个属性,我们可以告诉 Kapacitor 每天零点都执行一次这个查询。|influxDBOut() 则是将查询出来的数据存入 InfluxDB,它的几个属性也比较好理解,不再详说。

保存文件后,执行以下命令:

$ kapacitor define log_uip -tick ip.tick -type batch \
   -dbrp telegraf.retentionPolicy
$ kapacitor enable log_uip

就定义和启用了这个 Kapacitor 任务。接下来还可以用 kapacitor show log_uip 或者 kapacitor list tasks 等命令查看任务状态。看到了吧,这样比脚本加 crontab 还是要简单不少的。(kapacitor 命令的参数含义可以用 help 子命令或者这个文档链接查看。)

在它运行过后,我们就可以在 Grafana 里面取 logstats 数据库里面 site_uip 的 uip 出来进行画图了。

总结:这篇文章只是用一实例展示了 Kapacitor 的功能之一,实际上 Kapacitor 的功能远不止这些,(报警等功能,因为我的环境早有这种功能,没有使用过。)tick 脚本的语法也比上面展示出来的部分强大很多,其数据处理节点也很丰富。总得来说,InfluxData 的这套 TICK 架构似乎还在快速发展的起步阶段(尤其是除 InfluxDB 外的那三部分),但是其实用性已经有一定吸引力了。

No blinking

我一直都喜欢在用的 OS 上面禁用掉光标闪烁,因为一个不停闪烁的光标实在是让我觉得焦躁。有个专门的网页教你怎么在各个平台禁用光标闪烁(http://www.jurta.org/en/prog/noblink)。

但是在 Windows 10 上面,禁用光标闪烁后会有一个后果——任务栏活动窗口的高亮闪烁不会消退。

具体说来就是图中这样,橙色的高亮即使在鼠标点击之后仍然会保留。

相比于光标闪烁,这个除了关闭程序否则永不消退的高亮更是让人难受,于是只能启用光标闪烁。

这次写的真是个无比闲得慌的事情。。。

当你的程序依赖于 MySQL 查询缓存…

前两天升级和迁移了一个 MySQL 环境,因为:

  1. 某天我发现原来的环境居然是个 RAID 0,尽管已经有个 Slave 环境了,但是把数据放在毫无冗余的磁盘上面实在是有太大风险。
  2. 系统需要扩展了,接手这个项目时候,程序和数据库都在一个机器,从性能、安全各个方面来说都不是很好的方案。
  3. MySQL 5.6 相比 5.5 在查询优化上面有很大的提升。
  4. 事实上刚好还有个 mongodb 需要升级版本,可以一起下线后升级。

OK,于是就找了个凌晨,下线、升级了,初看起来一切正常。

但是到了第二天,问题出现了。开发说从 MySQL 同步数据到 mongodb 非常慢,只有原来的 1/36!

于是都开始怀疑是 mongodb 的问题,难道是程序逻辑有问题?写新版本的 mongodb 没有对参数什么的?但是得到否定的答复。

。。。。。。

折腾了好一会儿,看了 mongodb 的各种文档之后,看了一下一直在跑着的 mongostat 输出,发现是有出现过高并发的写入(但不是出现问题的同步造成的),至少,这说明了——mongodb 升级后的写入功能本身是没有问题,事实上,观察到的结果是有提升。排除了 mongodb 的问题,心想是否可能 MySQL 的数据库问题,看了一眼慢日志,结果确实发现有大量的同一个超过 1s 的查询,时间点和同步一致。

问了一下开发,他们说这个查询应该会被缓存住,第一下很慢,但是后面就很快了!好吧,我看了一眼 MySQL 的查询缓存:

mysql> show status like 'Qcache%';

哈!全部是0,查询缓存被关闭了!

再查了一下 MySQL 的参考文档

query_cache_type
...
This variable defaults to OFF as of MySQL 5.6.8, ON before that.

MySQL 在 5.6 之前的版本是默认开启查询缓存的,而 5.6 开始却默认关闭了它!

于是,设置 query_cache_type=1 之后,重启 MySQL,同步一切正常了。

总结:MySQL 做了这个改动,但是却没有在它们的升级文档中给出说明;开发把程序一个重要的功能依赖于这个数据库缓存,也没有说明。谢谢你们一起给我出了难题!当然,更重要的一个事情是——升级之前没有彻底的测试过!!!所有人都想当然了,这是流程规范的问题。

Chrome vs. Backspace

Hacker News 上面出现了一个讨论(https://news.ycombinator.com/item?id=11729287),是关于 Google Chrome 去除了将 Backspace 键作为回退到上一个页面的快捷键功能。
我很惊讶很多人在回帖里面对 Chrome 开发者的这一决定表示支持,因为:

  1. 我自己是个 backspace 键的重度用户。我尽量都是在用键盘快捷键在导航,除了 backspace,还有 Ctrl+w,f5,f6 。。。没兴趣从以前的 backspace 切换为两只手才能操作的 Ctrl+左方向键。
  2. backspace 并不是很多人说的那么小众的导航键。相反,把它作为回退上页的功能来用的例子非常多,比如在 Windows 平台,File Explorer 里面也是可以用它回退到上一页面的。
  3. Google Chrome 得了 Apple 的病。一直以来我都觉得 Chrome 其实更像是个 Apple 弄出来的浏览器,标榜着自己比用户更懂一切。而我不想被当作傻瓜。

我觉得我还是继续用 Firefox 吧

php-fpm chroot 迁移至 CentOS 7.2 版本的 segfault 问题

一直是在用 php-fpm 内置的 chroot 功能在跑手头的几个 php 论坛站点。
但是最近将整个 chroot 环境迁移至新的地方之后,出现问题了:
有一个论坛一直是返回 502 状态码。看了下,发现 dmesg 输出有一些信息:

...
[444346.942769] php-fpm[13096]: segfault at 1fae98fc ip 00007f53655429df sp 00007f5347847d80 error 6 in libresolv-2.17.so[7f5365537000+16000]
[444500.294150] php-fpm[13149]: segfault at 1fae98fc ip 00007f53655429df sp 00007f5347847d80 error 6 in libresolv-2.17.so[7f5365537000+16000]
[444500.407066] php-fpm[13151]: segfault at 1fae98fc ip 00007f53655429df sp 00007f5347c07d80 error 6 in libresolv-2.17.so[7f5365537000+16000]
...

chroot 里面的根目录结构是以前从 CentOS 7.1 拷贝创建的,看来和 7.2 不兼容。libresolv 里面发生了 segfault,说明问题应该是和 DNS 解析有关。
试了几次之后,把 7.2 的 libnss 相关 so 文件拷贝到 chroot 里面后,问题解决了。以防万一,接下来干脆把 chroot 里面的所有 so 更新了一次。