Akawa

ETY001的博客

应用地址:https://oc.mypi.win

之前一直计划接触下 swoole 、redis 、docker。最近时间稍微宽裕些,于是就把这三者揉到一起,
把之前自己用的剪切板重新写了一遍,之前的那个是个nodejs版的。

redis在上一个公司有过接触,但是由于都是封装在底层的,平时用的时候,也只是调用方法,所以认识不够深刻。
这次读了些资料,主要是看了下redis提供的数据结构。现在我对这货的核心功能的认识就是,用C实现了一个安全操作层,
用来对内存进行读取写入操作,并且实现了几种数据结构,用于存储结构化的数据。

开发目标是应用要能允许建立多个剪切板,每个剪切板有个唯一标示,每个剪切板的容量是50条。因此先想到了队列,
于是最后用的是redis的list的数据结构,用户提供剪切板的name和进入剪切板的password,产生唯一标示的方法如下:

1
$hash = md5($password . $name);

然后用$hash作为这个剪切板list的key。

另外一个问题就是如何把websocket的frame_id 和 $hash 关联起来。
frame_id其实就是client_id,即连入到服务器的客户端的唯一标示,$hash和client的关系是,一对多的,
即一个剪切板,可能会有多台终端接入。

最后考虑了下,使用redis的hash数据结构和list数据结构来完成这个对应关系。hash数据结构用来存储
frame_id 到 hash 的关系,即通过该结构,提供 frame_id 即可找到 对应的剪切板list的key,即 $hash 值。

那么list结构是用来做什么的呢?list中存储的是 $hash 做key,每个 list 里面存储着当前连接到该剪切板的
所有终端的 frame_id,这个list的作用就是用来广播的,即同一个剪切板内的某个终端更新剪切板后,通知其他终端更新。

关于制作swoole的docker镜像,可以看这里 https://akawa.ink/2015/06/13/make-swoole-docker.html

代码:https://github.com/ety001/online-clipboard

swoole-docker:https://registry.hub.docker.com/u/ety001/min_swoole/

C-b ? 显示快捷键帮助
C-b C-o 调换窗口位置,类似与vim 里的C-w
C-b 空格键 采用下一个内置布局
C-b ! 把当前窗口变为新窗口
C-b " 模向分隔窗口
C-b % 纵向分隔窗口
C-b q 显示分隔窗口的编号
C-b o 跳到下一个分隔窗口
C-b 上下键 上一个及下一个分隔窗口
C-b C-方向键 调整分隔窗口大小
C-b c 创建新窗口
C-b 0~9 选择几号窗口
C-b c 创建新窗口
C-b n 选择下一个窗口
C-b l 切换到最后使用的窗口
C-b p 选择前一个窗口
C-b w 以菜单方式显示及选择窗口
C-b t 显示时钟
C-b ; 切换到最后一个使用的面板
C-b x 关闭面板
C-b & 关闭窗口
C-b s 以菜单方式显示和选择会话
C-b d 退出tumx,并保存当前会话,这时,tmux仍在后台运行,可以通过tmux attach进入 到指定的会话

1、由于使用的是docker hub 中的 centos:6 ,因此一上来需要先安装开发包,
为了省事,我直接就用下面这条命令了:

yum groupinstall "Development Libraries" "Development Tools"

2、去下载php官网比较新的源码,我下载的是 php-5.6.10

3、安装libxml2-devel

yum install libxml2-devel

4、解压下载后的php源码包,直接 ./configure 然后结束后执行 make && make install

5、编译安装结束后,下载swoole的源码,我下载的是 swoole-1.7.17 ,解压,然后依次执行:
phpize ./configure make && make install

6、编辑php.ini,加入 extension=swoole.so

7、安装完毕,开始瘦身,我主要是删掉 /usr/share /usr/local /usr/src
下面的一些文件,最终初步瘦身从800M到300M。

8、删除完文件后,回到根目录,执行

mkdir /rootfs
mkdir bin etc dev dev/pts lib usr proc sys tmp
mkdir -p usr/lib64 usr/bin usr/local/bin
wget http://busybox.net/downloads/binaries/1.21.1/busybox-x86_64 /sbin/busybox
chmod +x /sbin/busybox
cp /sbin/busybox bin
busybox –install -s bin
cp -r /bin /rootfs/bin
cp -r /etc /rootfs/etc
cp -r /lib /rootfs/lib
cp -r /usr /rootfs/usr
cd /rootfs
tar cf /rootfs.tar .

9、把生成的 rootfs.tar 从 container 中 scp 出来,在放置 rootfs.tar 的目录下,
新建个 Dockerfile 文件,内容如下:

FROM scratch
MAINTAINER ety001 <[email protected]>
ADD rootfs.tar /

10、等待完成后,就可以用 docker images 命令看到新做的这个镜像了。

##WiFi经常掉线问题

相关报错:

1
daemon.info hostapd: wlan0: STA 4c:8d:79:f2:53:9c IEEE 802.11: disconnected due to excessive missing ACKs

在把极壹刷成OpenWRT后,使用了半周多了,稳定性还是不错的,今天用极壹替换掉了家里的总入口的TpLink,
发现接上网线后,wifi在刚开始就连不上,后来连上了,用了2个多小时后,就总是掉线,到最后就连不上了。
不过重启路由后,又好了。看了日志发现好像验证相关的问题,经过搜索,发现大家的解决方案都是把组密钥更新关掉了,
我也先关掉再看下吧,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
#修改/etc/config/wireless
config wifi-iface
option device 'radio0'
option ssid 'yourssid'
option key 'yourpassword'
option mode 'ap'
option encryption 'psk-mixed'
option network 'lan'
option wmm '0'
option wpa_group_rekey '0' #把组密钥更新关掉
option 'wpa_pair_rekey' '0'
option 'wpa_master_rekey' '0'

保存后,重启网络

1
root@ETYOpenWrt:~# /etc/init.d/network restart

####2015-06-12 10:00 update

貌似这是个不简单的bug,https://dev.openwrt.org/ticket/12372

####2015-06-12 14:27 update

找到了个解决方案,https://forum.openwrt.org/viewtopic.php?id=43188
按照6楼的方法,加个 option disassoc_low_ack 0 配置再试试。

####2015-06-12 15:00 update

上一个方案不成功。

####2015-06-12 16:58 update
另外一个方法,再试试 https://www.bungie.net/en/Forum/Post/69319415/0/0/1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@ETYOpenWrt:~# cat /sys/kernel/debug/ieee80211/phy0/ath9k/ani
ANI: ENABLED
ANI RESET: 63
OFDM LEVEL: 0
CCK LEVEL: 0
SPUR UP: 0
SPUR DOWN: 0
OFDM WS-DET ON: 0
OFDM WS-DET OFF: 0
MRC-CCK ON: 0
MRC-CCK OFF: 0
FIR-STEP UP: 12
FIR-STEP DOWN: 14
INV LISTENTIME: 0
OFDM ERRORS: 8792
CCK ERRORS: 11634
root@ETYOpenWrt:~# echo 0 > /sys/kernel/debug/ieee80211/phy0/ath9k/ani
root@ETYOpenWrt:~# cat /sys/kernel/debug/ieee80211/phy0/ath9k/ani
ANI: DISABLED
root@ETYOpenWrt:~#

##Samba配置

先从/etc/passwd中添加一个用户ety001,然后再新加一个samba用户,命令如下:

1
root@ETYOpenWrt:~# smbpasswd -a ety001

把ety001换成你自己的用户名,然后再到luci界面里配置下samba就可以了,也可以直接写下面的配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#文件位置:/etc/config/samba
config samba
option workgroup 'WORKGROUP' #组名
option homes '0' #是否共享家目录
option name 'ety001_hiwifi' #计算机名
option description 'ety001_hiwifi' #计算机描述

config sambashare
option name 'hiwifi' #共享名
option path '/upan' #要共享的目录
option create_mask '0700' #文件权限
option dir_mask '0700' #目录权限
option read_only 'no' #只读
option guest_ok 'no' #是否允许匿名登陆
option users 'ety001' #可允许操作的用户

重启samba即可

##花生壳配置

由于是动态公网IP,所以需要弄个花生壳,要不然多麻烦。需要下载个插件就能搞定了,
地址:http://www.domyself.me/assets/upload/20150612/luci-app-oray.ipk,下载后传到路由器root用户家目录下,执行:

1
opkg install luci-app-oray.ipk

安装好以后,就可以在luci界面看到相关的配置页面了,配置很简单,这里略过。

拉取docker hub上的已有镜像

docker pull base/archlinux

列出本地的镜像

docker images

搜索镜像

docker search image_name

列出容器

# 显示所有的container
docker ps -a

# 显示最新的container
docker ps -l

从一个镜像启动容器并进入terminal

docker run -ti IMAGE /bin/bash
docker run -it --rm IMAGE /bin/bash #运行完删除容器, 建议调试时使用

停止一个容器

# CONTAINER为容器的名字,从 docker ps -a 中可以看到
docker stop CONTAINER

删除容器

# CONTAINER为容器的名字,从 docker ps -a 中可以看到
docker rm CONTAINER

删除本地的镜像

docker rmi IMAGE

提交容器成为新的镜像

docker commit -m "some log" <container_id> <some_name>

进入一个正在运行的容器

docker attach <容器id> #通过容器id进入, 不推荐该方法
docker exec -i -t <容器id> /bin/bash  #通过容器id进入, 推荐该方法

基于Dockerfile编译

docker build -t <镜像名> .

容器自动重启

docker run -it --restart on-failure:10 IMAGE
# no 不自动重启容器 (默认)
# on-failure 容器发生error而退出(容器退出状态为0)重启容器
# unless-stopped 在容器已经stop掉或docker stopped/restarted 的时候才重启容器
# always 在容器已经stop掉或docker stopped / restarted 的时候重启容器

另外附加一篇参考:http://blog.chinaunix.net/uid-10915175-id-4443127.html

按照下面的命令输入即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sudo apt-get install python g++ make checkinstall fakeroot

src=$(mktemp -d) && cd $src

wget -N http://nodejs.org/dist/node-latest.tar.gz

tar xzvf node-latest.tar.gz && cd node-v*

./configure

sudo fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -re's/.+node-v(.+)$/\1/p') make -j$(($(nproc)+1)) install

sudo dpkg -i node_*

转自:http://www.free4net.com/2014/06/installing-nodejs-and-npm-in-kali-linux.html

首先打开终端输入

1
xrandr

得到如下信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ety001@ETYkali:~$ xrandr
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 8192 x 8192
LVDS1 connected (normal left inverted right x axis y axis)
1920x1080 60.0 + 59.9 40.0
1680x1050 60.0 59.9
1600x1024 60.2
1400x1050 60.0
1280x1024 60.0
1440x900 59.9
1280x960 60.0
1360x768 59.8 60.0
1152x864 60.0
1024x768 60.0
800x600 60.3 56.2
640x480 59.9
VGA1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 0mm x 0mm
1024x768 60.0
800x600 60.3 56.2
848x480 60.0
640x480 59.9
HDMI1 disconnected (normal left inverted right x axis y axis)
DP1 disconnected (normal left inverted right x axis y axis)

其中,LVDS1即为笔记本的显示屏幕,VGA1为外接显示器。

输入如下命令,

1
cvt 1920 1080

可以得到相关的分辨率配置信息,如下

1
2
3
ety001@ETYkali:~$ cvt 1920 1080
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline "1920x1080_60.00" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync

新建模式

1
xrandr --newmode "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync

增加模式

1
xrandr --addmode VGA1 "1920x1080_60.00"

接下来就能在显示配置列表中看到1920x1080的选项了。

如果希望下次开机也能自动设置,配置下家目录下面的.profile,加入下面三行即可

1
2
3
cvt 1920 1080
xrandr --newmode "1920x1080_60.00" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync
xrandr --addmode VGA1 "1920x1080_60.00"

参考:http://www.ahlinux.com/ubuntu/6728.html

在终端下翻墙的重要性,当你使用composer之类的东西的时候就体现出来了。
安装proxychains可以实现执行指定的命令的时候,使用代理去访问。

1
2
3
4
5
6
brew install proxychains-ng

vim /usr/local/etc/proxychains.conf

proxychains4 php composer.phar update

安装ROR真费劲。。

  1. 安装ruby
1
sudo yum install ruby
  1. 安装ruby-devel
1
sudo yum install ruby=devel
  1. 安装rails
1
sudo gem install rails

可能需要设置gem的资源服务器为淘宝的。

最好再安装上,mechanize,

1
sudo gem install mechanize

好的吧,终于搞定了aria2c的开机自启动问题。No zuo no die,离开计算所后,好像很久没有这么折腾了,
一个配置的问题引发的一系列的问题。

简单说下我的环境是树莓派 + Archlinux,看着 ArchWiki 上面关于 aria2c 的相关页面
很快就安装配置ok了,不过,重启后,发现 aria2c 根本就没有启动起来。报错信息如下:

1
2
Mar 31 22:31:40 alarmpi aria2c[150]: 03/31 22:31:40 [ERROR] IPv4 RPC: failed to bind TCP port 6800
Mar 31 22:31:40 alarmpi aria2c[150]: Exception: [SocketCore.cc:293] errorCode=1 Failed to bind a socket, cause: Name or service not known

绑定失败?怎么破?

再看下 Wiki 上 /etc/systemd/system/aria2c.service 这个配置文件,貌似没啥问题,然后又手动启动了下,也失败了。
执行 systemctl status aria2c 发现程序成功返回0,systemctl显示也是正在执行,但是ps一下,没有aria2c的进程。

见鬼了!

继续看 wiki ,发现里面说到

1
Ensure your config is set to deamonize (use daemon=true).

我的配置文件没问题,已经加了daemon=true。。。恍惚了好久,在wiki上看到了systemd的页面,看到里面有这么一句话,

1
Type=forking: systemd considers the service started up once the process forks and the parent has exited. For classic daemons use this type unless you know that it is not necessary.

然后我在原来的wiki给出的那个配置的基础上加上了一行 Type=forking(也就是你们现在在wiki中看到的那样,我已经提交修改到wiki了)。

添加好以后,手动启动 systemctl start aria2c 成功!赶紧重启试试。结果还是不行,依旧报错,还是绑定的问题。

后来,就又继续看systemd的配置,尝试添加wants和requires之类的配置,但是都不管用,不过看了这么一段话,在这个页面

1
The most typical case is that the unit A requires the unit B to be running before A is started. In that case add Requires=B and After=B to the [Unit] section of A. If the dependency is optional, add Wants=B and After=B instead. Note that Wants= and Requires= do not imply After=, meaning that if After= is not specified, the two units will be started in parallel.

好吧,wiki给出的那个配置还不是很完善,我又加上了一行,最终配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
file path:
/etc/systemd/system/aria2c.service

file content:
[Unit]
Description=Aria2c download manager
Requires=network.target
After=network.target

[Service]
User=aria2
Type=forking
ExecStart=/usr/bin/aria2c --conf-path=/home/aria2/.aria2/aria2.daemon

[Install]
WantedBy=multi-user.target

再次重启试试,还是不行。。。继续看配置,发现 systemd 还可以配置 timer,我想,既然开机启动不成功,
而开机后手动启动可以,就证明有什么依赖的程序没有启动,系统就启动 aria2c 了,那我延时执行不久可以了么。
于是看文档学习下,写了个针对 aria2c 的 timer,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
file path:
/etc/systemd/system/aria2c.timer

file content:
[Unit]
Description=Run on boot

[Timer]
#10 seconds
OnBootSec=10

[Install]
WantedBy=timers.target

重启成功。这里我忽略了我测试OnBootSec的步骤,其实刚开始是1,结果有时候能启动,有时候启动不起来,才改成10的。

本来以为这就告一段落了,但是突然不知道怎么想的,脑子里闪现静态ip这个词,于是,也就顺带看看systemd的网络配置怎么搞的。
配置好静态ip后,就手贱的把这个 timer 关掉了,然后奇迹发生,aria2c 启动成功!好的吧,原来是这个地方的坑啊。。

收拾下战场,完善下 ArchWiki 的 Start aria2c on system boot 这一节的内容,顺带着去ArchBBS上把一个帖子也回复了
(我放狗搜遍网络,就这一个哥们跟我遇到了同样的问题,却没有被解决)。

就在我快要写完这篇博文的时候,收到了 ArchWiki 管理员的回复,关于daemon=true与Type=forking的这个修改接受了,
不过,对于failed to bind errors则没有接受,可能再接下来的版本会修复这个bug。(PS:庆幸我写的英文,管理员看懂了。)

最后放出我的 aria2 的网页管理界面,终于完工了,下载个Glee 3D Concert测试下:

aria2

0%