我的Raspberry Pi工作了大约半年之后,文件系统开始出现莫名其妙的问题,各种文件都出现乱码,以至于某系统命令一执行就segment fault。到重新“安装”系统的时候了。
之前主要跑的服务是我的博客,nginx + wordpress搭的,在RPi上因为CPU的问题(php-fpm执行时几乎占满cpu),响应比较慢。既然重新弄了,考虑把某些请求交给家里的其它机器来处理。
家里还有一台跑Ubuntu的笔记本,希望满足如下要求:
1) 如果笔记本开机着,http请求(几乎)都交给笔记本处理;
2) 如果笔记本关机,http请求都由RPi来处理;
这些应该是完全自动实现的。
在Stackoverflow上问了这个问题,有人提示说可以通过nginx的load-balance功能来实现我的需求。于是开始google一番,找到了解决方案。
基本的思想是,把nginx配置成反向代理,笔记本和RPi都作为upstream来处理http请求;通过nfs共享同一个wordpress目录;配置mysql让wordpress访问同一个数据库。
一步一步来配置这些。
其中Raspberry Pi的地址固定为192.168.1.100,笔记本的地址固定为192.168.1.101,数据库名为minewpdb,数据库用户名为minedb
1. 配置Mysql
mysql仍然放在RPi上,让mysql接受网络的请求,这样不同的机器可以用同一个mysql数据库。
1 2 3 4 5 6 7 8 9 10 11 12 | sudo vim /etc/mysql/my .cnf ==> 把 bind-address 改成RPi的ip地址 bind-address = 192.168.1.100 mysql -u root -p #登录mysql控制台 mysql> grant all on minewpdb.* to 'mineblog' @ '192.168.1.100' identified by 'xxx' ; # 本地RPi的wordpress访问 mysql> grant all on minewpdb.* to 'mineblog' @ '192.168.1.101' identified by 'xxx' ; # 笔记本的wordpress访问 mysql> quit; sudo service mysql restart # 重启mysql服务 # 在RPi和笔记本上分别测试一下 mysql -u mineblog -h 192.168.1.100 -p # 如果能登录成功,就ok了 |
2. 配置wordpress
Wordpress仍然在RPi上,只要修改wordpress的config文件,把数据库的host,用户名和密码都设对就行了。
1 2 3 4 5 6 | sudo vim /path/to/wordpress/wp-config .php ==> 修改DB_HOST等参数 define( 'DB_NAME' , 'minewpdb' ); define( 'DB_USER' , 'mineblog' ); define( 'DB_PASSWORD' , 'xxx' ); define( 'DB_HOST' , '192.168.1.100' ); |
3. 配置nfs
在RPi上设置nfs export,让笔记本mount它,这样可以保证跑的wordpress是同一份。
1 2 3 4 5 6 | sudo vim /etc/exports ==> 添加wordpress目录到exports /path/to/wordpress 192.168.1.101(rw,no_root_squash,insecure, sync ,no_subtree_check) sudo service rpcbind start # RPi的nfs依赖于rpcbind sudo update-rc.d rpcbind enable # 设置rpcbind自动启动 sudo service nfs-kernel-server start # 重启nfs |
在笔记本上,mount这个目录:
1 | sudo mount -t nfs 192.168.1.100: /path/to/wordpress /path/to/wordpress |
4. 配置nginx
在RPi上要把nginx配置成反向代理,upstream是RPi和笔记本,端口号都是8000,真正的wordpress运行在8000端口上。
添加新的配置文件 /etc/nginx/sites-available/wordpress-load-balance,注意我把http的访问全部重定向到https,以防GFW
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | # Upstream to abstract backend connection(s) for php upstream php { server unix: /var/run/php5-fpm .sock; } upstream mineservers { # 设置两个upstream, 其中笔记本优先,同时设置5s的fail_timout # 因为局域网很稳定,所以max_fails设成1就行了, # 如果fail就说明笔记本关机中,让RPi自己来处理 server 192.168.1.101:8000 weight=999 fail_timeout=5s max_fails=1; server 192.168.1.100:8000; } server { listen 80; server_name mine260309.me; rewrite ^ https: // $server_name$request_uri? permanent; } server { listen 443 ssl; server_name mine260309.me; ssl_certificate /path/to/cert/mine260309 .me.2014.chain.crt; ssl_certificate_key /path/to/cert/mine260309 .me.2014.key; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; access_log /path/to/wordpress/logs/proxy .log; error_log /path/to/wordpress/logs/proxy_error .log; location / { # 代理到upstream proxy_pass http: //mineservers ; ### force timeouts if one of backend is died ## proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; ### Set headers #### proxy_set_header Accept-Encoding "" ; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ### Most PHP, Python, Rails, Java App can use this header ### #proxy_set_header X-Forwarded-Proto https;## #This is better## proxy_set_header X-Forwarded-Proto $scheme; add_header Front-End-Https on; ### By default we don't want to redirect it #### proxy_redirect off; } } server { root /path/to/wordpress ; # 在8000端口监听 listen 8000; server_name mine260309.me; ... # normal wordpress configurations } |
在笔记本上用同样的配置就可以了。
这样,任何一个请求到RPi,它会让nginx优先反向代理到笔记本的nginx的8000端口,由笔记本来处理;
如果笔记本关机,在5秒钟之后它会fail,于是再由RPi自己的8000端口处理。
Q.E.D.