之前买的 NodeMCU 做了一些试验之后忙着装修,一直没动它。这两天抽空研究了一下 MQTT 协议,用来实现自己家庭用的 IOT Server,接入多个 NodeMCU 设备。MQTT 协议开销很小,而且 NodeMCU 官方有现成的模块可以使用。

MQTT Server 的选择

决定使用 MQTT 协议后就去网上找各种 Brokers 的实现,因为要部署在 vps 上,而且只有自己一个人使用,不能使用那个占用资源非常多的方案。

项目名 开发语言 官网 备注 采用
emqttd erlang http://www.emqtt.io/ 官方提供一个 docker 镜像,运行后初始占用大约要 100 多 MB 内存 ×
mosquitto c https://mosquitto.org/ 资源占用非常小,初始内存只有几百KB
surgemq go https://github.com/influxdata/surgemq 这是一个库,需要自己写代码调用 ×
mqtt go https://github.com/jeffallen/mqtt 看介绍只支持 QOS 0 ×

目前看来还是使用 mosquitto 更符合我的要求一些,能实现身份验证和各种 QOS 级别的消息传递,而且资源占用非常小。使用 go 语言来开发控制端,连接 mosquitto 服务器,通过订阅和发布消息来控制 nodemcu 设备,然后开放一个 web 界面,这样手机也能方便的远程监控家里的情况。

最近想用 nodemcu 做点小玩意,然后上淘宝买了两只回来,昨晚抽空做了一下实验,成功点亮一颗 LED。

NodeMCU 简介

NodeMCU 是一个可以在嵌入式开发中使用 lua 的开源固件,提供了很多现成的模块,比如:mqtt, cjson, file, websocket, http等。

我买的 NodeMCU 是下面这种,在淘宝上买的,基于 ESP8266 芯片,自带 WIFI 做物联网好用。

NodeMCU

果然很小,如果只买 ESP8266-12F 芯片,然后自己焊接可以做的更小,就是会比较麻烦。

刷固件

首先新买的 NodeMCU 拿到手的时候没有固件,需要先刷入固件。

驱动

我的买的这种便宜一点,USB 转串口的芯片是 CH340G,另外还有一种使用的是 CP2102,据说 CP2102 更好一点,不过我的 CH340G 也一样可以正常使用。

CH340G驱动 For Mac

Read More

前两天看到influxdb这个数据库,觉得拿来存储日志太适合了。数据库带有压缩功能,可以减少存储空间,并且支持一些基本的查询,语法类似SQL(有很多限制,后面会讲到)。配合下列组件可以很方便的查看服务器性能和应用日志分析:

  1. fluentd: 用于日志收集,类似于logstash,使用ruby写的,内存占用比logstash小,不过有gil,多核利用需要用插件多进程。
  2. telegraf: 采集服务器cpu,内存等负载数据,类似于collectd,使用go编写,配合influxdb使用。
  3. grafana: 图形化显示性能分析数据,跟influxdb配合。

influxdb

基本概念

  1. 跟mysql数据一样有数据库,语法也是 create database [dbname],不过多了一个可以设置数据保留规则的东西可以让旧的数据自动清除
  2. 有MEASUREMENTS类似于table,但是没有模式,数据结构可动态增加
  3. 每一个point数据有tag,field, timestamp
  4. tag可以用于group by,field不可以
  5. field可以进行 function aggregate,tag不行
  6. timestamp插入数据的时候可以指定也可以不指定,默认为当前时间
  7. 存储的时间都为utc时区

使用docker部署

用docker来部署比较简单,直接使用 docker run -p 8083:8083 -p 8086:8086 -v influxdb:/var/lib/influxdb influxdb:0.13.0-alpine,我喜欢用alpine版本的镜像,容量比较小。
运行成功后就可以使用浏览器访问8083来控制了, 8083是admin控制台,8086是http api端口。

influxdb管理界面

查询数据

语法类似于 SQL ,不过像group by 之类的语句对 tag 和 field 是有区别的,所以设置 schema 的时候需要注意一下。

SELECT * FROM "bbs" WHERE time > now() - 2h

查询最近两小时的日志数据

弃坑

原本想把整套环境配置起来玩玩,正好碰上迁移服务器,迁移后的服务器内存大小是8G,然后发现个非常严重的问题,这货会把内存吃光光,进程在收集日志的时候就占用1.2G内存,查询的时候更是超过了2G,甚至有上过6G。直接把服务器卡的无法动弹。
目前看来这个方案无法在小内存的服务器上使用,独立到单独的日志处理服务器上也许可行。后来试过0.12.2, 0.13.0, 1.0.0-beta3 都是一样的情况,这样就没办法用了。

首先在 /etc/sysctl.conf 里面加入

kern.maxfiles=1048600
kern.maxfilesperproc=1048500

执行下面的命令

sudo sysctl -w kern.maxfiles=1048600
sudo sysctl -w kern.maxfilesperproc=1048500

limit.maxfiles.plist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>limit.maxfiles</string>
<key>ProgramArguments</key>
<array>
<string>launchctl</string>
<string>limit</string>
<string>maxfiles</string>
<string>1048600</string>
<string>1048600</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>

limit.maxproc.plist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>limit.maxproc</string>
<key>ProgramArguments</key>
<array>
<string>launchctl</string>
<string>limit</string>
<string>maxproc</string>
<string>1048500</string>
<string>1048500</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>

/Library/LaunchDaemons/ 目录中加入这两个 plist 文件

执行下面的命令让其启用

sudo launchctl load /Library/LaunchDaemons/limit.maxfiles.plist
sudo launchctl load /Library/LaunchDaemons/limit.maxproc.plist

再重启计算机就可以了

  • arch-chroot 之前 modprobe dm-mod,否则 grub-install 可能出现找不到 device.map 的错误。
  • arch-chroot 后在 /etc/default/grub 里面的 GRUB_PRELOAD_MODULES 加入 lvm
  • 修改 /etc/mkinitcpio.conf, MODULES 里面加上 dm-thin-poolBINARIES 里面加上 “/usr/bin/thin_check /usr/bin/pdata_tools” , HOOKSfilesystems 之前加上 lvm2。 执行 mkinitcpio -p linux 重新生成。
  • grub-mkconfig -o /boot/grub/grub.cfg 生成 grub 配置。

最近自己拿 j1900 组装了台 nas 期间出了各种问题,原先使用的是 btrfs 文件系统,可是后来因为经常奇怪的死机导致 btrfs 文件系统出错,里面的文件丢失好多,就想着换回 ext4 可又放不下 snapshot 功能,在网上找替代方案,发现 lvm 支持 thin provisioning 可以实现类似的功能,然后就直接重装,上 lvm

省略在 lvm 上面安装 archlinux 的一系列步骤,安装完毕开始调教 lvm

Read More

最近买了一块七彩虹C.Q1900M主板做为 nas 代替以前使用的 cubieboard ,本来想着买过来直接装 debian 系统,然后就可以愉快的使用了。结果昨天到的机子,到今天晚上才把系统给装上,中间出了各种问题。

刚开始是碰到在 3T 的新硬盘上安装 debian 后无法启动的问题,貌似是因为 grub-efi 没安装成功。然后尝试换了 ubuntu server 14.04.3 安装到是一路顺利,就是碰到一个严重的问题,关机的时候会卡死,无法关闭电源,也无法重启机器,只能强制关机,调试了半天的 acpi ,还是没搞定。就在要准备换一个发行版的时候发现原来使用 ubuntu desktop 14.04.2 的 live 模式可以正常关机,顿时觉得有戏啊。然后就一路 happy 的安装完成了。

可是

事情还没有结束,在安装了一堆东西,并升级了内核后,又无法关机了。怀疑是内核的问题,重新使用 14.04.2 自带的 3.16 能正常的关机。重新将系统恢复到 3.16 的内核后,一切又正常了。j1900这破平台,兼容性问题看来挺大了,据说还无法安装 esxi。不过还好,找到问题是内核的就简单了,不升级内核就好,反正3.16也可以使用 docker 。

2016-02-03补充

在换成 archlinux 后高版本内核依然无法正常关机,有时正常,有时又不正常,后来查到将 xhci 控制器关掉改用 echi 就可以正常关机,但这样就无法使用 USB3.0 了,不过平时用 USB3.0 的情况也不多,关系不大。

angularjs 中因为直接制作dom或着其它原因会导致 ngModel 的双向绑定不同步,这时就需要手动处理一下。

直接操作 dom 后使用下面的代码设置 ngModel 的值。

1
2
var inputElem = angular.element(d);
inputElem.data().$ngModelController.$setViewValue(inputElem.val());

其中 d 就是 element,当在 $scope 之外操作的时候还需要使用一下 $scope.$apply();

打开终端输入下面的命令

hdiutil create -srcfolder node_modules node_modules.dmg

其中 node_modules 是文件夹 node_modules.dmg 是打包出来的 dmg 文件。

想要顺带加密的使用下面的命令

echo -n 'password'|hdiutil create -stdinpass -encryption -srcfolder node_modules node.dmg

其中 password 是密码

参数说明

-i

输入文件,可以多个

-vf

滤镜,可以用 -vf “ass=[ass字幕文件]” 来加载

使用FFmpeg给视频增加黑边需要用到 pad 这个滤镜,具体用法如下:

-vf pad=1280:720:0:93:black

按照从左到右的顺序依次为“宽”、“高”、“X坐标”和“Y坐标”,宽和高指的是输入视频尺寸(包含加黑边的尺寸),XY指的是视频所在位置。

比如一个输入视频尺寸是1280x534的源,想要加上黑边变成1280x720,那么用上边的语法可以实现,93是这样得来的,(720-534)/2。

如果视频原始1920x800的话,完整的语法应该是:

-vf ‘scale=1280:534,pad=1280:720:0:93:black’

先将视频缩小到1280x534,然后在加入黑边变成1280x720,将1280x534的视频放置在x=0,y=93的地方,FFmpeg会自动在上下增加93像素的黑边。

注:black可以不写,默认是黑色。

-vf ‘crop=1920:1080:0:0’

这个是用来裁剪视频大小的,比如录像1080i出来成1088像素,底下有8个黑的像素就可以用这命令去掉。

Read More