需求大概这样:一个单机上运行的系统,有数据库、文件附件;为了适应国内复杂的网络环境,也为了实现负载均衡以及数据备份,在另外一个机房,加 一台备用服务器。附件上传到主服务器,上传过程不用考虑网络问题。两台服务器都做前端机,用dnspod 可以配置动态域名,实现同一域名下的多台前端 机;如果是客户端的接口服务器,那么客户端上可以获取服务器,轮询服务器。
问题是,如何配置两台机器,让他们能够同时进行数据库的读写,以及附件的读操作。并保证两台机器的数据一致性(即数据库、附件都能一致)
说下自己的想法。
- 数据库同步。数据库同步,还是用最经典的主从架构。写主库,读从库,主库到从库做热备份;不过鉴于服务器在不同机房,读操作直接读本地数据库就ok。
- 附件同步。三种方案。a) 利用inotify等触发式文件同步的方式实时同步附件。 b) 做反向代理到主服务器。其实可以理解为一个类似于CDN的方案。Nginx 自带的代理模块,可以做 caching reverse proxy。但是nginx的自带的caching reverse proxy 在HTTP请求带有Range参数时,有个HTTP状态码的小问题。详见 http://www.douban.com/note/91375654/
- 补充1: 原始方案是大概10年9月写的。我自身已经不用了。现在的解决方案是单机房,客户端连不上主机房A,会去尝试另外一个机房B的服务器。B只是A的HTTP反向代理。
- 补充2: 如果需要保证服务质量,并降低单点压力,那么需要考虑 IDC双写+数据同步了。数据的一致性是个难题。详见 @timyang 的 多IDC的数据分布设计(一)
------------------------------------------------------------------------------------------
发现nginx使用反向代理时,返回状态码的BUG
2010-09-17 17:16:11
今天发现的。有空刚才google了一下,似乎有人也遇到类似的问题。http://forum.nginx.org/read.php?2,8958,8958 。Igor Sysoev 回复说,这个问题改不掉。 备用服务器 s.goapk.com 上带缓存的反向代理的配置: server { listen 8003 default; server_name gomarket.goapk.com; access_log /data/logs/gomarket.goapk.com.8003.access.log; error_log /data/logs/gomarket.goapk.com.8003.error.log; location / { proxy_pass http://118.194.24.3:8003; proxy_cache my-cache; proxy_cache_valid 200 302 60m; proxy_cache_valid 404 1m; } } 往主服务器(118.194.24.3) 上上传了一个附件。此时备用服务器还没有缓存。 第一次请求,从HTTP协议上来讲,应该是返回206的,结果返回200: root@scratchbox:/data/www/wwwroot# curl -svo/dev/null -r0-1024 http://s.goapk.com:8003/apkfile/5bc28fef8184e428e69301d0c13156c5.apk * About to connect() to s.goapk.com port 8003 (#0) * Trying 211.162.69.236... connected * Connected to s.goapk.com (211.162.69.236) port 8003 (#0) > GET /apkfile/5bc28fef8184e428e69301d0c13156c5.apk HTTP/1.1 > Range: bytes=0-1024 > User-Agent: curl/7.19.7 (i486-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15 > Host: s.goapk.com:8003 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 17 Sep 2010 09:00:01 GMT < Content-Type: application/octet-stream < Connection: keep-alive < Content-Length: 1171049 < Last-Modified: Fri, 17 Sep 2010 08:58:37 GMT < Accept-Ranges: bytes < { [data not shown] * Connection #0 to host s.goapk.com left intact * Closing connection #0 第二次请求,返回正常: root@scratchbox:/data/www/wwwroot# curl -svo/dev/null -r0-1024 http://s.goapk.com:8003/apkfile/5bc28fef8184e428e69301d0c13156c5.apk * About to connect() to s.goapk.com port 8003 (#0) * Trying 211.162.69.236... connected * Connected to s.goapk.com (211.162.69.236) port 8003 (#0) > GET /apkfile/5bc28fef8184e428e69301d0c13156c5.apk HTTP/1.1 > Range: bytes=0-1024 > User-Agent: curl/7.19.7 (i486-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15 > Host: s.goapk.com:8003 > Accept: */* > < HTTP/1.1 206 Partial Content < Server: nginx < Date: Fri, 17 Sep 2010 09:00:26 GMT < Content-Type: application/octet-stream < Content-Length: 1025 < Connection: keep-alive < Last-Modified: Fri, 17 Sep 2010 08:58:37 GMT < Content-Range: bytes 0-1024/1171049 < { [data not shown] * Connection #0 to host s.goapk.com left intact * Closing connection #0
FROM http://www.douban.com/note/91375654/
No comments:
Post a Comment