最优化使用阿里OSS云存储

  上一篇文章讲到了为何要迁移到阿里OSS,经过几天时间的实际验证,发现还是踩了不少的坑,这里记录下,供参考。

  首先有几个先决条件如下:

  1. 全站所有请求必须HTTPS
  2. 全站仅允许出现自有二级域名
  3. 上行和下行流量均不经过ECS服务器

  (代码洁癖 8)

  阿里OSS我们可以简单的认为分两个部分:

一是存储有关的,提供了两个访问域名:一个是公网,一个内网

<bucket>.oss-cn-shenzhen.aliyuncs.com (A域名)
<bucket>.oss-cn-shenzhen-internal.aliyuncs.com (B域名)

二是为图像处理(缩图,转码)有关的,也提供了一个访问域名:

<bucket>.img-cn-shenzhen.aliyuncs.com (C域名)

我们在这个图像处理的功能上面绑定了一个自有的二级域名:

image.snapast.com (D域名)

默认分配并指向了下面的CDN加速节点域名:

image.snapast.com.w.kunlunca.com (E域名)

  暂且称为A~E域名,注意其中细微差别。其中A和B域名本身是支持HTTPS的,但C不行,在绑定了D之后,可以上传SSL证书开启。A域名也可以绑定自有域名,但不支持HTTPS。图像处理设置了禁止原图访问,也就是C,D域名仅允许通过“样式”访问到缩略图。但A,B不受限制,本来就不同的系统。

于是第一个方案是这样的:

用户上传:HTTPS POST A域名
用户访问:HTTPS GET D域名

  初看没啥问题,除了引入一个第三方域名,不符合预定规范,但也运行良好,但有个很严重的问题,会泄漏原图,将D域名的路径拼接到A上面就能拿到原图。故pass掉,和客服聊了后给了个鸡贼的方案:

方案二:

用户上传:HTTPS POST upload.snapast.com -> proxy_pass -> B域名
用户访问:HTTPS GET D域名

  在nginx上将用户上行的POST请求转发到B域名,这样可以在nginx层面拦截原图访问,并可以支持自有域名HTTPS。虽然又点不符合规范了,虽然ECS下行带宽还是蛮大的,proxy_pass也是内网地址,似乎也无大碍。

方案三:
将bucket设置为私有,这样POST不变,GET需要增加signature,想想就复杂,搞的URL又长又丑,没再尝试。

  后来想想,能不能直接POST到D域名试试,居然成功了。Object 管理中证实了文件是传成功的,但感觉怪怪的,原来CDN还能upload。官方文档似乎也没有说这样用合不合理,暂且先如此把。

使用阿里云OSS WEB直传

  最近在忙着将snapast.com的图片迁移到阿里OSS服务器上,并采用WEB直传方案,以加快客户端上传速度。并使用CDN访问方式来提高图片加载速度。目前所有的图片都是存储在ECS云服务器上,用的是FastDFS存储,纯Java的图片缩放处理,速度比较慢。并且单线程就将CPU消耗完了,2M的带宽也经不起并发访问,于是决定将图片迁移到OSS上。

  WEB直传的架构设计还是很优秀的,客户端直接POST请求到OSS服务器,无需经过ECS服务器,ECS只是计算一个Policy,并接收OSS回调,整个图片上传流程就完成了。OSS具有阿里的海量CDN支持,各种网络下都能很好的优化。

这里主要记录下一些细节:

  1. OSS要设置Cors规则,以便跨域请求
  2. 2. Bucket区域要和ECS区域一致,方便内网拉取数据
  3. 使用uploadifive上传组件且auto设置为true时,在onAddQueueItem方法中获取Policy,已换plupload,在BeforeUpload中获取Policy。
  4. 由于OSS会忽略请求中文件域以后的字段,因此在封装参数的时候,将文件域(Content-Disposition: form-data; name=”file”; filename=”xxx.jpg”)置于最后,这货貌似完全照搬Amazon S3,否则会找不到key

  Upload差不多就这样了,先写到这。

迁移到阿里云一些笔记

  现在看到的博客已经跑在阿里云上了,随之迁移的还有找歌词后台和花图相册(链接就在屏幕左侧)。由于之前用的linkcloud云主机业务与阿里云合并,商务那边通知到期后只能迁移到阿里云上,正好他们家的内核版本过低,无法满足docker需要,于是尽早开始了迁移计划。

  首先是转移备案,阿里的备案系统还是蛮方便的,后台填完资料,寄送幕布,都很快,最后审核了一周多点也就过了。收到邮件后立刻新开了主机,配置环境。这里还有个小插曲,备案前其实就买了一个,后来觉得配置太高了,于是又退了。事实证明,阿里的单核顶linkcloud双核。

  迁移并不复杂,无非是安装新环境,打包,传输,解压,运行,验证。这里简单做下笔记,以备不时之需。

1. 磁盘挂载
  买了新主机,自然是先挂载好数据盘,阿里的帮助中心已经写的很清楚了。我选配了100g的普通云盘,挂在点位于/dev/xvdb,将用ext4格式化。fdisk -l可以看到一个xvdb磁盘未包含任何分区信息,用fdisk /dev/xvdb对磁盘进行分区,再次使用fdisk -l可以看到/dev/xvdb1出现,用mkfs.ext4 /dev/xvdb1进行格式化。

配置到fstab以便开机自动挂载

echo '/dev/xvdb1 /mnt/vdb1 ext4 defaults 0 0' >> /etc/fstab

此时可以重启下验证是否成功df -h

/dev/xvdb1       99G   60M   94G   1% /mnt

2. nginx
  使用apt-get安装,同步旧服务器的conf.d/*配置文件,Jenkins密码文件,SSL证书。删除默认站点sites-available和sites-enabled目录下的default。nginx推荐做法是将站点配置(Virtual Host)文件放在sites-available下,在sites-enabled下建立到available的连接,可以方便的启用和禁用。我这里简单处理全放在了conf.d下。

关闭nginx版本显示和post大小限制:

vim /etc/nginx/nginx.conf
server_tokens off;
client_max_body_size 20M;

配置完重启nginx进程,检测是否有误

3. mysql
  使用apt-get安装,同步旧服务器conf,授权远程登录,修改root密码:

GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY "newpassword";
GRANT ALL PRIVILEGES ON *.* TO root@“127.0.0.1" IDENTIFIED BY "newpassword";
GRANT ALL PRIVILEGES ON *.* TO root@"localhost" IDENTIFIED BY "newpassword";
flush privileges;

导出旧服务器上的db,p参数表示待输入密码

mysqldump -p db_name > db_name.sql

复制到新机器上登录mysql后用以下命令导入

source /root/db_name.sql;

若数据量不大,可以用GUI工具转移,例如Navicat的数据传输功能

4. redis
  下载源代码&编译安装

wget http://download.redis.io/releases/redis-3.0.6.tar.gz
tar xf redis-3.0.6.tar.gz
cd redis-3.0.6/
make
make install

安装为服务,自启动

cd utils
./install_server.sh

为了安全起见,redis仅监听来自本机的请求,设置bind 127.0.0.1,并设置密码requirepass。再修改启动脚本,增加密码(若设置了密码,必须要如下操作,否则无法正常重启redis)

vim /etc/init.d/redis_6379
定义变量:
PASS="pass"
在stop方法中增加-a参数
$CLIEXEC -p $REDISPORT -a $PASS shutdown

迁移redis数据,在旧机器上登录redis-cli,使用save指令将内存数据保存到/var/lib/redis/dump.rdb中,再scp到新机器对应的目录上,重启即可。

5. java,maven,jenkins,tomcat
  官方JDK最新已经是8u65了,直接用最新的,不得不说Oracle也是个坑货,下载个jdk还要验证一下,导致直接wget链接会失败的。这里加一个cookie就好了:

wget --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie;" http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jdk-8u66-linux-x64.tar.gz

下载放在/usr/java 目录中
tar xf 解压到/usr/java/jdk1.8.0_66

设置环境变量:

# set maven home
export MAVEN_HOME=/usr/local/apache-maven-3.3.3
export PATH=$MAVEN_HOME/bin:$PATH

# set java home
export JAVA_HOME=/usr/java/jdk1.8.0_66
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH

# set jenkins home
export JENKINS_HOME=/mnt/vdb1/.jenkins

将旧机器的相关目录打包scp过来即可

6. fastdfs
  Fastdfs安装可以参考我之前的文章,这里简单带过。先安装libfastcommon和做好链接,同步旧服务器配置文件和照片数据目录,设置为服务自动启动:

update-rc.d fdfs_trackerd defaults 90
update-rc.d fdfs_storaged defaults 95

7. php和wordpress
  apt-get安装php5-fpm和php5-mysql,复制wordpress目录。新版本的fpm默认没有监听9000端口,而是采用unix sock来连接,因此nginx站点配置中修改下

fastcgi_pass unix:/var/run/php5-fpm.sock;

  最后再检查各个项目是否正常,接口是否能调用成功,再到dnspod中将各域名A纪录指向阿里云的新IP,保证平滑迁移,至此就算完成了。

云主机 & VPS

  云计算,概念上已经炒得比较火了,就IaaS层面而言,也有很多公司陆续开放了服务。逐一体验了一把,算是小结一点。

  Amazon EC2
  一提到云计算,自然会考虑到鼎鼎有名的亚马逊,它的EC2早在去年就注册过,那还是Ubuntu 10.10发布之时提供一个小时的使用机会,详情可以在这里看到。
  验证过电话和信用卡后注册了一台micro配置的主机,E5645@2.40GHz,600m的内存,8GB的磁盘,用UnixBench跑了一下,才21~27的得分。老问题依旧,连接速度慢,vim操作都不怎么流畅。用sftp传个项目kb级的速度,还断流。唯一快的是更新系统,当然他们有自己的源。最大的好处是静态IP是不需要额外付费的,只要不浪费,并注意流量不超标就可以了。
  EC2控制台内容丰富,专业,功能齐全,主机状态一览无余。

  盛大云C2
  盛大云比较看好,是因为价格低廉,配置也还凑活,最低配置有512M内存,8GB磁盘,一个月才34.7元。UnixBench得分在70左右。不过网络可不便宜,电信2M独享90一个月。好玩的是选择不要外网IP的情况下,也能联网,相当于内网一台可以上网的主机,只是无法从外网访问,跑一些本地应用还是不错的。
  C2的控制台就简单多了,基本也够用了,没有外网IP的时候也能通过控制台进行远程控制。

  阿里云
  只能看月或年缴费,最低一款一个月99,单核2.26G,512M内存,60G硬盘,外网带宽1M,不支持带宽升级。阿里巴巴不愧电商老大,这样的套餐都出的来,和联通3G样的,高不高,低不低,想升级,换套餐。没有按小时计费,所以没有继续注册了,估计性能和盛大差不多,价格也很接近。

  LinkCloud
  这家的产品似乎不怎么出名,产品首页很简陋,但性价比还算不错。最低配置有2.4G CPU,1G内存,100G硬盘。带宽1M情况下一个月163。UnixBench表现很不错,得分228.7。磁盘读取都在240M以上,性能算是不错了。网络很快,测试时选择了峰值10M带宽或40M带宽,下载都能很稳定占满。但若不选择外网IP,根本无法远程控制,联系客服后得到一个可笑的答复,再开通一个有外网IP的主机,远程后再用内网IP连接这台机器。且内网机器无法访问互联网,成了彻底与世隔绝的机器。
  这家的后台管理极其简陋,漏洞一大堆,很难想象能把项目放心的托付。

  试用后可以发现云主机和传统VPS之间最大的差别在于更细粒度的资源使用与费用支出。可以按使用小时来计费、按独享的带宽来计费,或流量来计费。云主机可以细分到存储、分发、数据库、负载均衡等等,这样极大提高了稳定性,降低了中小项目的前期投入。最贵的一部分投入还是在带宽上,万恶的电信。想作web服务,域名也都是要备案的。