博客链接保持不变的重要性和实现方法

  1. 方便多年后外链自己的文章链接依然可用;
  2. 积累 SEO 权重,减少被浏览器标为 404 的概率;
  3. 方便外界盗图后图片依然可以访问;
  4. 方便收藏者有需要时可以找回原文和最新评论;

实现手段

  1. 注册一个自己的域名;
  2. 每次更换博客依然绑定原来的域名,并保持旧文章访问地址不变。
  3. 将 “www.你的域名/路径” 和 “你的域名/路径” 的其中一种设置 302 跳转到另外那种。

后记

此文是对我至今不转换成 Ghost 博客的借口——固定链接无法保持。

[翻译]修复 Nginx 和 PHP-FPM 之间的超时问题

本文是 《Fixing timeout between Nginx and PHP-FPM》 的译文。

=======译文开始========

若你使用 Nginx 作为 PHP-FPM 的反向代理,且你的 PHP 脚本很复杂或者很慢,需要运行很久,很可能就会看到 504 gateway time-out 错误。这是个很常见的错误,但是大多数情况下人们会找错解决问题的地方,他们不知道怎么找到哪个超时 directive 是正确的、符合他们的情景的。

原文配图:花五小时修复超时程序,不如用一个 directive 立即解决
原文配图:花五小时修复超时程序,不如用一个 directive 立即解决

我看见很多人拼命的试验 proxy_read_timeout, send_timeout, 甚至 client_header_timeout 和client_body_timeout 的 directive,但如果他们瞥一眼 Nginx 的 error_log,会看到一条类似这样的错误:

2013/01/19 11:36:59 [error] 14564#0: *1215 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 123.456.789.123, server: example.com, request: "POST /path/to/some/script.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "example.com", referrer: "http://example.com/"

这条错误清楚的陈述了 Nginx 和 upstream 服务之间的连接超时这件事。在此这个 upstream 服务是 PHP-FPM,但也可以是任何 FastCGI 服务在读响应头时出错。若你据此稍加分析,就不会没找到 fastcgi_read_timeout 这个 directive。浏览文档,看看它是做什么:

设置 upstream 等待 FastCGI 进程发送数据的时长的 directive 。若你有长时间运行、若非结束不输出结果的 FastCGI 进程,修改这个 directive。若你在错误日志中看到 upstream 超时错误,那么增加这个参数到某个更合适的值。

所以,在 http, server 或者 location 的 { 和 } 之间加上这个 directive 并赋予足够高的数值是明智之举,例如:

location ~* .php$ {
include fastcgi_params;
fastcgi_index index.php;
fastcgi_read_timeout 120;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

=======译文结束=======

看到这篇文章是因为 www.yymwz.com 国庆期间莫名其妙 504 gateway time-out 了四天,还顺带连累了同一个服务器上的本站一起 504 了。重启服务什么的都不行。搜索了下,叫我用什么 directive 的都有,而且都号称能解决问题,当然总不见效。最后还是按照这篇文章得到解决。修改了 fastcgi_read_timeout 的 directive 以后,mysql 被拖垮了一次,重启后就正常了,昨天那么久只挂了两次,已经好多了。

不过为什么 PHP 脚本会突然超时,博主我依然是百思不得其解的说。待后续吧。

阿里云使用心得

起因

从网易离职,回家休年假时,老妈逮住我抱怨 www.yymwz.com 很不稳定的情况。当时 www.yymwz.com 挂在 BAE 上,每次刷新都时好时坏。而且随着地域的不同,有的能访问,有的不能(不确定BAE是否用了 CDN)。后端内功太浅,无法和 BAE 再磨合下去的博主最终决定购买 VPS。

初体验

2014-04-22 14:49:27 开始试用阿里云主机,配置如下:

  • 带宽:1Mbps
  • CPU:1核
  • 操作系统:Ubuntu 12.04 64位
  • 内存:512MB
  • 云盾:是

阿里云官方有个一键安装包,可以直接装好 LAMP 或 LNNP 环境。不过当时找号称价值 300 元的限时免费数据迁移服务,重新装了一个 WordPress 并把 BAE 上的数据库内容全部导入了。 他们很快就搞好了,可惜有个缺点,装的是 WDlinux.cn 的全套系统,还提供一个网页版的后台。对于会用 Linux 的人感觉怪怪的,也不知道有没有被开后门。最后自己重装了 LAMP 环境。

阿里云的备案服务非常好,按流程一步步走,12天就搞定了,还得到了免费的 12 天补偿续费。 新网站也很好,全国各省都很快,WordPress 也跑得很健康,再也不莫名其妙死掉了。

挫折

之所以选择 LAMP 环境,主要是因为 Apache 对 WordPress 的支持最好。然而毫无运维经验肯定要踩坑,第一遇到的就是内存问题。 内存问题的症状是:

  1. Apache 常年占用 400M 内存;
  2. 升级配置加到 1G 内存以后,ab 测试结果还是 10 个并发不到就挂了;
  3. 访问人数一多(这里的“多”只是几个人外加几个爬虫),内存吃紧,MySQL 数据库进程就被杀死;
  4. 加了 WP Super Cache 缓存以后,大约同时有十几个连接,Apache 就无法创建新进程,旧的进程也会退出,有时 Apache 还自动重启了,访客得到“服务器连接被重置”的结果;
  5. 加了缓存以后无法缓解 WordPress 有人登录的情况,有时候两个人同时 IO 操作,MySQL 也挂了。

搜索了以后才发现大家都说 Apache 和 WordPress 非常吃内存。而且发现阿里云的云盾会占用一定的内存,不到 100M。还发现阿里云默认的 swap 交换区是 0,可能和阿里云服务器的 IO 不怎么好有关系。

NodeJS 确实是个好东西。阿里云上安装 Ghost 博客并 ab 压力测试之,可以轻松撑住几十个并发。然而在迁移大量数据的过程中,Ghost 对 WordPress 的固定链接、导航、页面和媒体(包括页面已经插入的媒体文件)都支持的不太好,宣告失败。

[截图]决心优化Apahce的孩子
[点击看大图]2011年决心优化Apahce的孩子

[截图]当年决心优化Apache内存问题的孩子在用nginx
[点击看大图]2013年,当年决心优化Apache内存问题的孩子在用nginx

后来,终于让我放弃优化 Apache 的是 这篇博文的评论,如上图(红框内的日期和对应的评论内容)。

解决

博主尝试了很多方法。什么“小内存主机终极优化方案”、“Apache 吃内存的解决办法”之类均告失败,最后用 Nginx 替换了 Apache 。目前大约可以撑住 50 个并发了。最后的配置如下:

  • 带宽:1Mbps
  • CPU:1核
  • 操作系统:Ubuntu 12.04 64位
  • 内存:1GB
  • 云盾:是
  • 环境:LNMP
  • 网站:两个 WordPress 均加了 PHP 缓存,一个 NodeJS 写的 Ghost 博客

后记

自从 PHP7 出来以后,升级到了 PHP7 ,大大降低了 php-fpm 对内存的占用。现在服务器内存压力一点也不大。

又有人留言说带宽可以更高一些,就又用优惠券加到了 2M 带宽。

后来看到这篇 实例分析阿里云服务器带宽如何选择? ,发现其实不用升级带宽也行。本站服务器最高的带宽占用只有 712 Kbps(非 https 的图片资源走七牛云存储),所以完全够用。


参考

拓展阅读

碰巧看到 zengrong.net 这个 WordPress 博客,用阿里云一年多,从 Apache 换成了 Lighttpd ,并于2014年2月将内存加到了 1G ,这是它的优化心得:

PHP的cURL扩展安装(开启)方法

网上找了很多资料都说要编译或者重新编译 PHP,其实以下几行命令就够了:


$ sudo apt-get update
$ sudo apt-get install php5-curl
$ sudo /etc/init.d/apache2 restart

参考资料

安装/配置cURL其他服务_函数参考_PHP手册

NodeJs批量下载“百度云存储(BCS)”的所有文件

导语

NodeJs 是一个使用 V8 JS 引擎的服务器端编程语言。百度云存储的英文缩写是 BCS ,是百度开发者中心提供的云存储服务。

本文阐述利用官方提供的 RESTful API 将 BCS 上的文件批量按源路径下载并保存下来的一种方法。需要安装了 NodeJs

获取签名

首先通过官方的 URL 签名界面取得签名,在 BAE 3.0 的“管理开发者服务”界面中,点击左侧的“云存储”,再选择一个 Bucket ,再点击“URL签名”,如下图所示。

百度云存储(BCS)官方生成签名界面截图
百度云存储(BCS)官方生成签名界面截图

点击“签名”按钮,即可得到一个像 http://bcs.duapp.com/bucket?sign=xxx 的地址。其中 bucket 是你的 bucket 名, xxx 就是签名字符串。

依赖的 NodeJs 模块

本文使用到 NodeJs 内置的文件系统模块和 GitHub 上的 request 模块。request 是 NodeJs 实现的 curl ,先安装 request。
npm install request

NodeJs 代码

1.引入依赖的模块

var fs = require('fs');
request = require('request');

2.声明签名字符串,会多次用到

var sign = '你的签名字符串';

3.自动创建不存在的目录

由于 fs 创建文件时无法自动创建目录,需要手动检查目录是否存在,若不存在就创建,所以需要自己编写一个。

var MKDirIfNotExist = function(filePN){
var dirArr = filePN.split('/'), cPath = '';
for(var i = 0, len = dirArr.length; i < len; i ++){
if(dirArr[i]) {
cPath += dirArr[i];
var exists = fs.existsSync(cPath);
if(!exists){
fs.mkdirSync(cPath);
}
cPath += '/';
}
}
}

函数的作用是传入代表目录地址的字符串,若脚本运行目录下不存在该字符串表示的路径,则创建。

4.读取 RESTful API 的文件列表和内容并保存本地

这里终于切入了正题。生成签名那里生成的 RESTful API 地址直接可以列出最多 200 个 Bucket 上的文件及其路径,可以直接读取并下载它们。

request('http://bcs.duapp.com/你的bucket名?sign=你的签名字符串', function (error, response, body) {
if (!error && response.statusCode == 200) {
var bodyJSON = JSON.parse(body);
for(var i = 0, len = bodyJSON.object_total; i < len; i ++){
if(bodyJSON.object_list[i].is_dir == '0'){
MKDirIfNotExist(bodyJSON.object_list[i].parent_dir);
fs.openSync('./' + bodyJSON.object_list[i].object, "w");
request('http://bcs.duapp.com/你的bucket名'+ bodyJSON.object_list[i].object + '?sign=' + sign).pipe(fs.createWriteStream('./' + bodyJSON.object_list[i].object));
}}
}
});

注意因为是顺序执行,所以这里用的都是 Sync 版的 fs 函数。
由于本人的 BCS 里总文件个数不到 200 个,所以没有给 RESTful API 传更多的参数,要求分页传回更多的文件信息。

5.完成

将本节所有代码按顺序复制粘贴另存为后缀是 .js 的文本文件,修改成你自己的信息后,直接运行
node 你的文件名
运行完就会看到所有文件都在那了。

参考文档

BAE 迁移 SAE 步骤

1、创建 SAE 应用;
2、下载 WordPress 3.8 For SAE v1217 并安装;
3、从 BAE 导出 sql 数据文件,在 SAE 中导入;
4、修改域名指向,至此 SAE 新网站可以正常访问;
5、通过 SVN 将原主题目录上传到 SAE 代码库中。

待完成:将 BAE bucket 用 API 打包下载后通过 SAE storage 客户端上传到 SAE storage 中,以保证媒体库不会裂图。

BAE 2.0 上 wordpress 3.5.2 原版发邮件的方法

注意!!由于 BAE 2.0 已经全面下线,本文内容不再有用!!

本站用的就是最新的原版的 wordpress 3.5.2 。玻璃泉上的 《BAE上原版wordpress发邮件教程》 文章已经说得很清楚了。以下五个步骤是根据此文针对最新 SDK 作出的修改后亲测有效的方法。

1、下载“Bcms.class.php”文件和“lib”文件夹的压缩包,也就是官方的 SDK(来自消息队列的官方文档)。后将它们放入wp-includes目录下。“sample”文件夹不用放进去。

2、接下来,在 wordpress 根目录下的 wp-config.php 文件中加入如下几行(如果已有则不用重复添加):

/* 消息队列 */
define('BCMS_QUEUE','您的消息队列名那一串');
$bcms_host = 'bcms.api.duapp.com';
/* accessKey 和 secretKey 消息队列要用 */
$accessKey = getenv('HTTP_BAE_ENV_AK');
$secretKey = getenv('HTTP_BAE_ENV_SK');

3、然后打开 wp-includes 下的 pluggable.php 文件,查找

if ( !function_exists( 'wp_mail' ) ) :

在它的上一行添加如下代码:

/**
* BAE Send Mail
* BCMS
*/
if ( !function_exists( 'wp_mail' ) ) :
function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {
require_once ABSPATH . WPINC . '/Bcms.class.php';
$bcms = new Bcms ( $accessKey, $secretKey, $bcms_host) ;
$ret = $bcms->mail ( BCMS_QUEUE, $message, array($to), array( Bcms::MAIL_SUBJECT => $subject)) ;
if ( false === $ret ) {
return false;
} else {
return true;
}
}
endif;

4、这样就行了,可以正常发出来自 BCMS 的电子邮件了。发出的邮件不出意料的落在的垃圾邮件文件夹里:

用 BAE BCMS 发出的 wordpress 重设密码邮件用 BAE BCMS 发出的 wordpress 重设密码邮件

5、Bcms 的 class 不能重复定义。BAE 环境中已经内置了一些定义,所以把报重定义 Fatal Error 的 PHP 文件内的内容全部注释掉即可。

最后,距离前文提到的《BAE上原版wordpress发邮件教程》 撰文的 2012-11-15 已经过去了一年半多,可以看到现在本文代码中调用 BCMS 的方法和那时的已经略有不同,需要 $accessKey 和 $secretKey 和指定 $bcms_host。

BCMS 的 SDK 也许将来还会再作修改,到时应该以官方的 SDK 里的 sample.php 的方法为准。

6、BAE 2.0 的 BCMS 服务有配额,配额里发邮件次数用完了就不能再发邮件了。据 BAE 客服回复,BAE 3.0 可以直接发邮件,不需要 mail 服务。有条件的可以往 BAE 3.0 (收费) 迁移,就省去这个麻烦了。

测试 BAE 下 wordpress 插入图片是否正常

公司一角的一束红玫瑰
工位的玫瑰

以上是用 wordpress 的媒体库功能直接传到 /wp-content/uploads/ 下的测试。不考虑浏览器缓存的情况下,这个图片文件只能当天保持,之后就消失了。

 

天使的翅膀
天使的翅膀

以上是直接传到 bucket 下的测试

 

用 BAE 的 搭建的 wordpress 是否能够正常插入图片? 这是用 BAE 搭建的 wordpress 添加图片媒体的测试。

可见,"工位的玫瑰"图片自动上传后的地址是 https://www.bokeyy.com/wp-content/uploads/2013/07/YqDZ7.jpg  ,依然是在 wp-content 的 upload 目录下。

结果可见, https://www.bokeyy.com/wp-content/uploads/2013/07/YqDZ7.jpg   这个文件只是临时存在,明天就会被清除,而 buckets 才是可以一直存在的。

http://mawenjian.net/p/1018.html 下载了个 百度云附件(BCS Support) v1.1 的 wordpress 插件,再用同样的方法传了张图"天使的翅膀"到 https://www.bokeyy.com/wp-content/uploads/2013/07/IMG_1879.jpg ,是正解的使用 BAE 上的 wordpress 传文件的方法。

附赠批量替换所有旧的媒体库文件地址为新的 BAE 文件地址的 SQL 语句:
update wp_posts set post_content=replace(post_content ,’http://www.yymwz.com/wp-content/uploads/’,’http://bcs.duapp.com/yuanyuanmwz/’)

Github上搭建自己的个人博客

1、前提

你需要注册一个github的帐号,并登陆到github.com。这样就到达了你的个人首页。

2、开始创建自己的blog

  1. 然后点New repository创建一个新的repository,命名为:yss.github.com(这里的yss为你在github上的用户名,下面涉及到的用户名也以yss为例)
  2. 进入这个仓库:yss.github.com,点击偏右上角的Admin,进入Admin页面
  3. 找到下面的灰色按钮,名为:Automatic Page Generator
  4. 进入到上面这个页面后,点右下角的continue to Layouts。则进入了模板选择页面。
  5. 然后选择一个模板,点public按钮即可(偏右上角的位置)。
  6. 这样就可以访问你的github博客了~

3、后话

github博客还有很多扩展性的东西,有待后续去了解,去学习。

当然这是最最基本的搭建自己个人的github博客。

后期基于jekyll搭建了自己的博客:yansong.me。算是做了回所谓的用黑客的方式写博客~~

4、扩展性阅读及参考

http://pages.github.com/

https://help.github.com/categories/20/articles