VPS 内存不足导致 nginx 频繁 502
因为后端的 php5-fpm 新进程没有足够的内存可以申请,所以 nginx 就直接秒返回 502。
因为 vps 是 openvz 系统,也无法自行设置 swap 分区,无解了。郁闷。
因为后端的 php5-fpm 新进程没有足够的内存可以申请,所以 nginx 就直接秒返回 502。
因为 vps 是 openvz 系统,也无法自行设置 swap 分区,无解了。郁闷。
人生被各种灰暗与不顺心笼罩。
这么多年第一次如此深刻的认识到自己没钱。
也是再一次想改变自己,准确的说,想改变现状。
参考文章树莓派二代 dnsmasq ipset iptables shadowsocks 网关代理、将gfwlist转换成带ipset的dnsmasq规则,适用于OpenWrt智能上网和使用ipset让openwrt上的shadowsocks更智能的重定向流量的补充终于折腾好了。
先简单说下原理。一般来说,正常的上网是通过路由器拨号上网并充当网关进行 NAT 转发,实现本地局域网内多台设备同时上网。而问题在于,路由器一般功能有限无法提供更加智能的网关业务处理。除非路由器支持第三方固件升级,如 OpenWrt 或 DDWrt 等。实际上,除开路由器网关,可以使用其他电脑(比如树莓派)充当二级网关,来解决此问题。
原有的网络拓扑是路由器 IP 为 192.168.1.1,通过路由器上的 DHCP 指定网关为 192.168.1.1,主 DNS 服务器为 119.29.29.29 备选 DNS 服务器为 114.114.114.114。
修改后的网络拓扑是路由器 IP 为 192.168.1.1,树莓派 IP 为 192.168.1.2,通过路由器上的 DHCP 指定网关为 192.168.1.2,主 DNS 服务器为 192.168.1.2 备选 DNS 服务器为 119.29.29.29。树莓派的网关为 192.168.1.1,手工指定主 DNS 服务器为 119.29.29.29 备选 DNS 服务器为 114.114.114.114。
所以第一步需要将树莓派设置为 iface eth0 inet static
,执行 sudo nano /etc/network/interfaces
,修改内容如下:
auto lo iface lo inet loopback auto eth0 #iface eth0 inet dhcp iface eth0 inet static address 192.168.1.2 netmask 255.255.255.0 network 192.168.1.0 gateway 192.168.1.1
然后,执行 sudo nano /etc/resolv.conf
,修改内容如下:
nameserver 119.29.29.29 nameserver 114.114.114.114
下一步是打开 NAT 网关,执行 sudo nano /etc/sysctl.conf
,修改指定行为:
net.ipv4.ip_forward=1
检查 sudo nano /etc/iptables.up.rules
,如果有 8080 转发,请禁止
:POSTROUTING ACCEPT [0:0] #-A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8081 #-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080 COMMIT
NAT 需要重启才能生效。这样,树莓派可以充当一个普通的网关代理,但没有 DNS 服务。此时可以将客户端网关修改为 192.168.1.2,DNS 服务器指定为 119.29.29.29 检查是否可以上网。
我们知道,通过域名访问任何一项网络服务,都先必须解析域名。现在要做的就是,树莓派使用 dnsmasq 提供局域网的 DNS 服务,使用特殊的规则解析指定的域名,并将解析到的 IP 加入 ipset 规则组,然后 iptables nat 使用 ipset 指定的规则组自动走 shadowsocks 的代理线路进行访问。从而达到我们的目的。
需要安装的包有:sudo apt-get install ipset dnsmasq shadowsocks-libev
我们并不需要 shadowsocks-libev 自带的 server 服务,执行 sudo update-rc.d shadowsocks-libev remove
禁止自动启动服务。
替代的是使用 ss-redir 连接 shadowsocks 代理服务器(通常会使用的是 ss-local 来开启 socks 代理,但 redir 会减少 socks 代理开销)。
手工建立 shadowsocks-redir 服务,执行:
sudo cp /etc/init.d/shadowsocks-libev /etc/init.d/shadowsocks-redir sudo cp /etc/default/shadowsocks-libev /etc/default/shadowsocks-redir sudo cp /etc/shadowsocks-libev/config.json.dpkg-old /etc/shadowsocks-libev/redir.json
需要 sudo nano /etc/init.d/shadowsocks-redir
将相关 shadowsocks-libev
改为 shadowsocks-redir
,以及 ss-server
改为 ss-redir
# Provides: shadowsocks-redir DESC=shadowsocks-redir # Introduce a short description here NAME=shadowsocks-redir # Introduce the short server's name here DAEMON=/usr/bin/ss-redir # Introduce the server's location here
sudo nano /etc/default/shadowsocks-redir
修改 CONFFILE
CONFFILE="/etc/shadowsocks-libev/redir.json"
sudo nano /etc/shadowsocks-libev/redir.json
配置 local_address 和端口,需要绑定 0.0.0.0 和 1080 端口(建议)
{ "server":"example.com", "server_port":10307, "local_address":"0.0.0.0", "local_port":1080, "password":"password" }
开启服务,并设置自动启动服务
sudo service shadowsocks-redir start sudo update-rc.d shadowsocks-redir defaults
可以使用 sudo netstat -nlp | grep redir
查看服务端口是否正常。
使用 sudo ipset -N ss iphash
创建新的 ipset 规则组,因为系统重启后 ipset 数据会丢失,建议将 ipset -N ss iphash
加入到 /etc/init.d/networking
中 start>
中,如
case "$1" in start) if init_is_upstart; then exit 1 fi ipset -N ss iphash process_options check_ifstate
否则,修改 iptables 默认规则后,会导致 ss 规则找不到,从而无法启动网络。
修改 iptables nat 规则,sudo iptables -t nat -A PREROUTING -p tcp -m set --match-set ss dst -j REDIRECT --to-port 1080
因为 iptables 重启后规则失效,需要修改 sudo nano /etc/iptables.up.rules
:POSTROUTING ACCEPT [0:0] -A PREROUTING -p tcp -m set --match-set ss dst -j REDIRECT --to-port 1080 COMMIT
下一步就是配置 dnsmasq,首先打开 sudo nano /etc/dnsmasq.conf
,修改
# Include another lot of configuration options. #conf-file=/etc/dnsmasq.more.conf conf-dir=/etc/dnsmasq.d
然后创建一个 google 的规则 sudo nano /etc/dnsmasq.d/google.conf
内容为
server=/.googleapis.com/208.67.222.222#5353 ipset=/.googleapis.com/ss server=/.google.com/208.67.222.222#5353 ipset=/.google.com/ss
使用 sudo service dnsmasq restart
重启服务,并将客户端的网关和 DNS 服务器都改为 192.168.1.2 即可以直接访问 google。
最后一步就是每天自动更新 gfwlist 规则为 dnsmasq 配置了。执行 sudo nano /etc/cron.daily/dnsmasq-gfwlist.py
,内容为 https://gist.github.com/larryli/bf0671b41ede5d77c52862f57fff6159
所有测试没问题后,请将路由器 DHCP 服务器,将网关设置为 192.168.1.2,DNS 服务器为 192.168.1.2 即完成所有配置。
其实很早就想着做一个静态内容同步,只是一直懒着不想动。
略微折腾了一下,直接提交到 https://larryli.github.io/
raspbian 下很简单,直接安装 motion 即可:
sudo apt-get install motion
不过需要手工打开服务配置:
sudo nano /etc/default/motion
将 start_motion_daemon=no
修改为:
start_motion_daemon=yes
处理一个小的权限问题:
sudo chmod 777 /var/lib/motion
再 sudo service motion start
启动服务。
默认会使用 /dev/video0
这个设备,请确定 USB 摄像头插上去,能否 lsusb
列出,并且设备映射成功。
在路由器开放外网端口之前可以修改 /etc/motion/motion.conf
文件中以下配置:
width 640 height 480 # 视频大小 text_right Larry Li(Shenzhen)n%Y-%m-%d %T-%q # 右下角文字 text_left CAMERA rpi1 # 左下角文字 target_dir /var/lib/motion # 文件存放位置,需要 chmod 777 picture_filename %Y%m%d/%H%M%S-%v-%q # 也可以按 %Y/%m/%d/%H%M%S-%v-%q 年月日一层一层建目录存放 movie_filename %Y%m%d/%H%M%S-%v # 其他几个 filename 配置也相同处理 stream_port 8081 # 指定实时 http 监控端口 stream_localhost off # 需要将 on 修改为 off 取消仅 localhost 访问限制 stream_limit 2 # 最好设置一个访问数限制 stream_auth_method 1 # 1 是标准的 basic auth stream_authentication username:password # 用户名和密码 webcontrol_port 0 # 关闭控制端口,或者也设置 basic auth 的用户名和密码
然后使用 btsync 把 /var/lib/motion
共享给手机和远程电脑,我直接使用了 rw 读写模式,手工在远程删除旧文件。
sudo add-apt-repository ppa:ondrej/php-7.0 sudo apt-get update udo apt-get install php7.0-cli php7.0-fpm php7.0-gd php7.0-json php7.0-mcrypt php7.0-mysql php7.0-readline php7.0-sqlite php-apcu
有一个坑需要注意的是,sock 文件是从 /var/run/php5-fpm.sock
变成了 /var/run/php/php7.0-fpm.sock
因为 VPS 性能所限,整体提升并不是很给力,只是一两倍而已。
主站切换到 Let’s Encrypt 自动颁发的免费证书。
目前公测期间,证书只有 90 天有效期,但可以使用 crontab 脚本自动在服务器上定时 renew。
不过,颁发证书本身有 IP 和域名的限制。
就是 git tag release 功能。
不是还没有类似 GitHub 那种发布列表的页面。
而且标签页面功能也有待加强,也许会增加二进制文件发布的功能吧。
当然,这个功能首当其冲的会影响到 gitlab.com 自身。
一般来说使用 git commit -S
就调用 gpg 工具自动搜索 user.name<user.email>
对应的私钥来签名提交。
git 2.0 以上版本提供了 commit.gpgsign
设置可以自动打开 gpg 签名选项。
然后配合 user.signingkey
就可以设置默认的 key 来自动签名了。
git config --global user.name "Larry Li" git config --global user.email larryli@qq.com git config --global user.signingkey 2D8B022C git config --global commit.gpgsign true
密钥 2D8B022C
可以通过 gpg -K
查看可用的私钥。
WebSocket 从 2010 年出现到现在已经五六年了,目前来说主流浏览器已经对其普遍支持,但实际运行却非常之少。
一般来说,WebSocket 都是双向全双工通信的。所以很容易设计一个异步协议 WAMP,提供异步的 RPC 远程调用和 Publish & Subscribe 模式实现。
但是,这种设计完全无视了 WebSocket 是基于 HTTP 协议的。也就是说,HTTP 使用 url 来路由,WebSocket 也同样可以用 url 来路由。
就拿 Pub/Sub 模式来说,WebSocket 天生就可以使用不用的路由来表示不同的 Pub。
而浏览器作为 Client 去 Call 服务器不正是 RESTful API 该做的事情么?
那么,除非是服务器要去 Call 浏览器端,WAMP 的大部分设计都是不需要的。
WebSocket 真的只需要简单的使用,就如它一开始被赋予的使命一样,作为一个 Push 及时的把服务端最新的消息推送到客户端。甚至消息都不需要包含实体,而只是一个通知即可。