Google Cloud Platform 的一点点体验

因为自己想搭个 wireguard 服务器在 HK,去 GCP 启动了一个 VM 实例,结果今天发现似乎不得不把它删掉,总结 GCP 使用感想如下:

  1. 居然连实例重装系统都不支持,只能删掉另起一个
  2. 我使用了一个 CentOS 8 的实例,执行一次 yum update 结果 SSH 都挂了,看了下日志,应该是升级 google 相关软件包导致的
  3. SSH 挂掉后,我想通过串口登陆进系统,串口登陆居然是灰的,默认不让从串口登陆。
  4. 于是我以为是 VM 里面可能没起串口,给 reset 了,结果就起不来
  5. 我只能求助伟大的 Google 搜索,发现,GCP 的串口登陆需要设置 metadata。(这是什么奇葩东西?)
  6. 于是我设置了 metadata,终于可以打开串口了,发现实例没起来是因为 SELinux 不知道为什么被开启了。但我有九成的把握,就是升级 google 相关软件包导致
  7. 我想进 GRUB,改内核启动参数,然而发现,GCP 默认把 GRUB 菜单显示也给关了,美其名曰“快速启动”。就不能给一秒钟时间吗?

想了想,没什么办法可以救得回这台实例了。

虽然上面没有我什么重要的东西,但我总结起来,GCP 的这个使用经验,简直就是在一直打我耳光,也许我属于不配使用它的那一类人吧。可能这是 Google 那群人根据自己在公司内部的使用方式提供出来的最佳实践,估计都已经把 OS 这层给越来越“虚”化,不需要 Google 员工在意 OS 层面的东西。但外界是否也达到了这种地步?恐怕 GCP 是还活在自己的梦里。

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]i ~]# 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 吧