分类 成长笔记 下的文章

家里的路由器经常在一觉醒来的时候断网,随即小爱音响及其绑定的智能家具全都停止工作。每天早上八点的时候小爱同学会定时帮我加热热水器,而断网后只能去洗冷水。一次两次拔下路由器能解决,但最近越来越冷,洗冷水也觉得越发刺骨,我也实在没有动力从温暖的被窝里起来拔插路由器。

$ vim /etc/network-watch-dog
#!/bin/sh

# 锁文件位置
LOCK_FILE_PATH=/tmp/.network-watch-dog.lock
# 每次发包次数
PING_COUNT=3
# 离上次断网最大等待时间
MAX_WAITING_SECONDS=600

# 这里直接固定 ping ali dns
SUCCESS_COUNT=$(ping 223.5.5.5 -c ${PING_COUNT} 2>&1 | grep '64 bytes' | wc -l)

if [ ${SUCCESS_COUNT} == 0 ]; then
  TIMESTAMP=$(date +%s)

  if [ -f ${LOCK_FILE_PATH} ]; then
    LOCK_TIMESTAMP=$(cat ${LOCK_FILE_PATH})
    # 超过最大等待时间 删除锁文件重启
    if [ $(expr ${TIMESTAMP} - ${LOCK_TIMESTAMP}) -ge ${MAX_WAITING_SECONDS} ]; then
      rm -rf ${LOCK_FILE_PATH}
      reboot
    fi
  else
    # 写入断网时间到锁文件
    echo ${TIMESTAMP} > ${LOCK_FILE_PATH}
  fi
  /etc/init.d/network restart
else
  # 成功联网后判断上次断网遗留的锁文件
  if [ -f ${LOCK_FILE_PATH} ]; then
    rm -rf ${LOCK_FILE_PATH}
  fi
fi

最后给个执行权限,在定时任务中加入这条脚本,我这里每三分钟执行一次。

$ chmod a+x /etc/network-watch-dog
$ crontab -e
*/3 * * * * /etc/network-watch-dog > /dev/null 2>&1

等两天打算搞个断网消息通知。

终端设置代理命令之前文章有写过的,趁今天重装了系统完善一下。

我的 Shell 使用 zsh,在 ~/.zshrc 下追加,如果使用 bash 需要修改 ~/.bashrc,可以使用 echo $SHELL 查看当前正在使用的 Shell。

命令用到了 jq 命令,需要先安装 brew install jq,其他平台替换为 yum 或者 apt-get

# 获取内网 IP
getlocalip() {
  local=$(ifconfig | grep 'inet ' | grep -v 127.0.0.1 | head -n1)
  local_ip=$(echo ${local} | awk '{print $2}')
  local_gateway=$(echo ${local} | awk '{print $6}')
  if [ ! "${local_ip}" ]; then
    echo "Your are offline."
  else
    echo "${local_ip} / ${local_gateway}"
  fi
}

# 获取外网 IP
getpublicip() {
  response=$(curl 'https://api.ip.sb/geoip' -Lsk)
  if [ ! "${response}" ]; then
    echo "You are offline."
  else
    ip=$(echo $response | jq -r '.ip')
    country=$(echo $response | jq -r '.country')
    country_code=$(echo $response | jq -r '.country_code')
    city=$(echo $response | jq -r '.city')
    isp=$(echo $response | jq -r '.isp')
    echo "${ip} at ${city} in ${country}(${country_code}) / ${isp}"
  fi
}

# 获取 内外网 IP
getip() {
  echo "Local IP: $(getlocalip)"
  echo "Public IP: $(getpublicip)"
}

# 定义代理地址
export PROXY_URL=127.0.0.1:7890

# 开启代理
proxyon() {
  export https_proxy=http://${PROXY_URL};
  export http_proxy=http://${PROXY_URL};
  export all_proxy=socks5://${PROXY_URL};
  export no_proxy=localhost,127.0.0.1,*.local,*.vanke.com,*.vankeservice.com
  getip
}

# 关闭代理
proxyoff() {
  unset https_proxy http_proxy all_proxy no_proxy;
  getip
}

然后 source ~/.zshrc,就可以使用命令了。

$ getlocalip
10.39.32.46 / 10.39.32.255
$ getpublicip
120.237.94.* at Shenzhen in China(CN) / China Mobile Guangdong
$ getip
Local IP: 10.39.32.* / 10.39.32.255
Public IP: 58.250.23.228 at Shenzhen in China(CN) / China Unicom Guangdong
$ proxyon
Local IP: 10.39.32.* / 10.39.32.255
Public IP: 52.175.9.* at Central in Hong Kong(HK) / Microsoft Corporation
$ proxyoff
Local IP: 10.39.32.* / 10.39.32.255
Public IP: 183.62.230.* at Guangzhou in China(CN) / China Telecom

最近写需求,同步了上游系统一个接口的数据到表里,大概长这样:

| id | name | role_id |
| 1 | 小王 | 4,5,6 |
| 2 | 小张 | 5,6,7 |
| 3 | 小李 | 50,51,52 |

需求是查询 role_id5 的所有用户,最开始的想法是这样:

select * from T where role_id like '%,5,%';

但是发现 最开始和最末尾的 ID 没有 , 分隔符 ,这就会导致最打头和最末尾的 ID 查不到。然后我又改成了这样:

select * from T where role_id like '%5%';

这个结果显然会将 id3 的结果一起查出来,况且 like 会扫描全表,这并不是我想要的。

后来我又想到了两个方案:

  1. 新建一张表,字段有 idrole_id,将字符串 role_id 列表分隔成一条条关联数据;
  2. 修改 role_id 格式为 |id1|id2|id3|,这样就可以用 like '%|id1|%' 查询。

直到 leader 在群里发了一个 MySQL 函数 FIND_IN_SET,让我立马拍大腿。

FIND_IN_SET(needle,haystack);
needle是要查找的字符串,如果 needle 中包含逗号(,)将无法正常工作。
haystack是要搜索的逗号(,)分隔的字符串列表。

上述的 role_id 字段也不用调整和处理,修改查询语句如下:

select * from T where FIND_IN_SET(5, role_id);

参考:

起因

在项目中不时需要一些开源的工具或者库需要 clone 下来编译或者使用,但是境内访问 Github 的速度实在难堪,导致 clone 的速度经常在 100kb 左右浮动,这仓库要是小忍忍也就过去了,而一些比较大的包那没一下午你还真搞不定。

对比

没有对比没有伤害,我这里使用 laradock/laradock 作为示例,为了排除我本地网络的影响,本次实验在阿里云的服务器上进行,直接上图。

直连 Github clone 仓库:

直连 Github clone 仓库

通过镜像 clone 仓库:

通过镜像 clone 仓库

速度提升非常明显,而速度就是妥妥的生产力啊。

配置

upstream github {
    server 192.30.253.112:443;
    server 192.30.253.113:443;
    keepalive 16;
}

server
{
    listen 80;
    listen 443 ssl http2 reuseport;

    ssl_certificate /etc/nginx/ssl/git.wangmao.me.crt;
    ssl_certificate_key /etc/nginx/ssl/git.wangmao.me.key;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_session_timeout      1d;
    ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers on;

    ssl_session_cache        shared:SSL:50m;

    ssl_session_tickets      on;

    ssl_stapling             on;

    server_name git.wangmao.me;

    if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot")
    {
        return 403;
    }
  
    if ($server_port !~ 443) {
        rewrite ^(/.*)$ https://$host$1 permanent; 
    }

    location / {
        proxy_set_header Accept-Encoding "";
        proxy_set_header Connection "";
        proxy_http_version 1.1;
        proxy_connect_timeout    10s;
        proxy_read_timeout       10s;
        proxy_set_header Host github.com;

        proxy_hide_header Strict-Transport-Security;

        proxy_pass https://github;
    }
}

其他方法

除了使用镜像站 clone 仓库,你还可以使用各类「网络优化」软件,通常他们支持 sock5 或者 http 通过本地或者局域网设置代理。

在终端中命令通常如下:

# 设置终端代理
$ export https_proxy=http://127.0.0.1:1080 http_proxy=http://127.0.0.1:1080 all_proxy=socks5://127.0.0.1:1081
# 取消终端代理
$ unset https_proxy http_proxy all_proxy

我将多个封装为别名,oh-my-zsh 编辑 ~/.zshrc 插入,bash 编辑 ~/.bash_profile

# 设置代理
alias proxy="export http_proxy=$PROXYURL:$PROXYPORT https_proxy=$PROXYURL:$PROXYPORT all_proxy=socks5://127.0.0.1:1081;curl cip.cc"
# 取消代理
alias noproxy="unset http_proxy https_proxy all_proxy;curl cip.cc"

然后 source ./zshrc 就可以使用快捷命令啦。

$ proxy
IP    : 34.97.27.*
地址    : 美国  美国

数据二    : 日本 | 大阪Google云计算数据中心

数据三    : 美国德克萨斯休斯顿

URL    : http://www.cip.cc/34.97.27.*

$ noproxy
IP    : 120.237.94.*
地址    : 中国  广东  深圳
运营商    : 移动

数据二    : 广东省深圳市 | 移动

数据三    : 中国广东深圳 | 移动

URL    : http://www.cip.cc/120.237.94.*

参考

前段时间,上了趟车在闲鱼 ¥90 收了一款 Newwifi3 路由器。到手后立马刷入了 OpenWRT 的衍生系统——PandoraBox,并配置了源以便于开启科学上网。[脸红]

Newwifi3

相比斐讯 K2P 配置相同,只是 5G 信号强度比较弱,不过我一个人住小单间,完全没问题。然而到了第一天晚上就发现一个问题:路由器的四侧有一条缝用于散热,但是我躺床上,那条缝就直接对着我,而缝里边有五颗 LED 灯。[尴尬]

侧边用于散热的缝

你想想,正困的时候,五条灯光直射你的眼睛,你还睡不睡。你说刺眼吧,又不能关,关了我这出租屋里 4G 信号贼差。气不气?[鼓掌]

闪瞎狗眼

无解,便开始寻找解决方案,能不能关掉着破灯:白天亮起,晚上熄灭。

找到了脚本,LED 由 /sys/class/leds 目录下的配置文件控制,写入不同的值来控制 LED 灯的点亮和熄灭,0 值为关闭,3 为开启,写入立即生效。

新建一个脚本用于控制 LED 熄灭,我将他存放在 /etc/off_leds.sh

$ vim /etc/off_leds.sh
#!/bin/bash
for i in `ls /sys/class/leds`
do
  cd /sys/class/leds
  cd $i
  echo 0 > brightness
done

给它个执行权限,然后执行:

$ chmod a+x /etc/off_leds.sh
$ /etc/off_leds.sh

再将它加入定时任务,LED 灯开启可以通过初始化 LED 的脚本实现:

$ crontab -e
# 关闭 LED 灯
0 22 * * * /etc/off_leds.sh
# 开启 LED 灯
0 7 * * * /etc/init.d/led start

到点熄灭了,完美。。。个屁,然而后半夜,它自己又亮了!!![内伤]

不知道为啥会自我唤醒 LED 灯,猜想是断网自动连接或者其他原因,但是我不管,我只想要睡觉![哭泣]

修改定时任务:

$ crontab -e
# 关闭 LED 灯
* 22-6 * * * /etc/off_leds.sh
# 开启 LED 灯
0 7 * * * /etc/init.d/led start

破灯,我还治不了你了。

另外,定时任务有时候写入后会不执行,猜想是 crontab 进程挂掉了,只需要重启下路由器或者直接粗暴的拔插电源就行。