服务器故障:No space left on device

今天早上小编抱怨图片无法上传,说Wordpress提示没找到临时文件夹。这个错误从来没听过,ssh到后台发现很多操作都提示no space left on device,最后决定重启时,碰到下面的错误:

mktemp: failed to create file via template ‘/tmp/tmp.XXXXXXXXXX’: No space left on device
/etc/init.d/apache2: 91: /etc/init.d/apache2: cannot create : Directory nonexistent

运行了df -h后发现磁盘只有使用70%啊,为什么就满了呢?Google了一下,有人说可能是Inode满了。Inode用来对磁盘上每个文件进行信息索引,从而使操作系统通过Inode查询最快地找到磁盘上的文件。当文件夹里有很多小字节的文件时,在磁盘未满的情况下,Inode可能就先被100%占用了。

我做了一个df -hi的命令查询,发现确实/dev/xvda1 IUse百分比已经达到100%

依照网上的教程,我执行下面的命令找到了Inode占用最多的文件夹

for i in /*; do echo $i; find $i |wc -l; done

结果发现root用户文件夹占用Inode最多,又执行下面的命令

for i in /root/*; do echo $i; find $i |wc -l; done

找到/root/Maildir Inode占用数奇高,而且占用了5.5G的磁盘空间。

Maildir文件夹下共有3个文件夹,new, cur 和 tmp。 new文件夹里面都是未读邮件,cur存放已读邮件,而tmp文件夹则是存放待发送的邮件信息。查询了一下,Maildir文件夹的这5.5G的磁盘占用全部来自new文件夹。依照网上的教程,我执行了find ./new -type f -delete来删除new文件夹下的所有文件(执行这个命令花了10分钟时间)。Inode占用终于降了下来。

光是Inode使用量降下来当然不算解决问题。经过观察,我发现在这个new文件夹每分钟都会有新的文件生成。打开看了下是cron job发送的。于是执行crontab -e,增加MAILTO=”” 禁止cron job发送默认邮件到root。

window.onload和jQuery中的ready函数有什么区别

当页面加载后需要执行一段js时,我一直用jQuery的$(document).ready(),没遇到过任何问题。

前段时间做网页的deeplink,需要在页面加载完成后用js代码跳转至APP打开相应的页面。用了document.ready后发现,如果用户选择不通过APP打开页面,网页上的所有图片都没有显示出来。

一查才发现,自己用的document.ready并非页面加载完成,而是DOM结构载入后完成执行的。这时图片其实还没有加载出来。除了执行顺序外,document.ready和window.onload没什么本质区别。

想要等页面被载入时执行代码,就需要用到window.onload。我将deeplinking的代码放入window.onload后,问题成功解决。

Really?

我们的APP有站内搜索功能,允许用户通过关键词搜索新闻、黄页、分类信息等内容。为了记录最热搜索关键词,我对用户的每次搜索都做了数据库纪录。然后就发现下面这两条(左栏关键词,右栏搜索次数):

Screen Shot 2016-08-26 at 12.06.09 PM

这位可爱的用户把搜索栏当成Google在用么?而且虽然没有任何结果,但还是百折不挠地搜了27次。

你永远无法预料你的用户会做出什么事来。

8385454193_aa204dec75_b

如何利用缓存提高页面加载速度

互联网有一项著名的原则叫“8秒钟原则”,即首页的加载速度超过8秒,有70%的用户就会不耐烦,选择离开。

做网站或APP当然内容是王道,产品提供有价值的内容,才会吸引更多人使用;但如果加载过慢,纵然你的内容再好,也会有相当一部分用户流失。

相对于早期的“静态网页”,现在大家开发网站时都趋向于使用后端语言和数据库通信,为用户实时展现最新文章、最新评论的“动态网页”。这个理念是没错,可当用户访问量增多时,数据库通信将会严重拖慢页面加载速度。假设5秒钟之内有1000名用户访问了你网站的首页,如果你在这5秒没有更新任何内容的话,这1000人访问了1000次数据库,只为了得到一模一样的数据。999次数据库连接通信其实就是在浪费时间和资源。

“动态网页”和数据库的同步其实没必要精确到分和秒。服务器端如果有一个10分钟的缓存机制,将大大减少用户访问时的加载时间。据我的经验,有数据库通信,加载需要3秒钟的页面,使用缓存后可以缩短至600毫秒之内。

php里有一个很轻量、实用的工具叫phpfastcache,用起来简单的不要不要的,只需要$cache->get来获取缓存过的值,如果这个值不存在,那就去数据库里把它抓取出来,用$cache->set把值存入就好了。接下来的10分钟,所有用户访问都在服务器就可以解决,不用连数据库了。当然如果数据不会经常变化的话,缓存有效时间可以设置更久。

$results = $cache->get("identity_keyword");

if($results == null) {
    $results = cURL->get("http://www.youtube.com/api/json/url/keyword/page");
    // Write to Cache Save API Calls next time
    $cache->set("identity_keyword", $results, 60*10);
}

如何按相似标签(类别)的数量来排列相关文章?

如何在Wordpress网站的单页post或是custom post type(CPT) 中显示相关推荐?网上有很多教程教你怎么做。大体都是先得到当前post的类别或标签,然后到数据库里抓有相同标签的post出来。

对于一个小的、文章类型单一的博客,这种方法足够了,但对于结构复杂,同一篇post有多个标签时,我们要在有限的空间(一般不会超过10条)为用户提供最有价值的内容,就涉及优先级和排序的问题。如何判断一篇post和当前post的相关程度呢?

我能想到的最好办法就是按他们相同标签的数量来排序了。下面是我在名为商户(”business”)的CPT中显示相关商户推荐的例子。

首先,用wp_get_object_terms 得到当前商户的所有类别和标签数组,将其implode为string,然后运行query语句得出相关商户,按相同类别和标签数量多少来排序。

SELECT ID, COUNT(*) AS total_count, post_title  FROM `wp_posts` 
LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
LEFT JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
LEFT JOIN wp_terms ON wp_term_taxonomy.term_id = wp_terms.term_id
WHERE wp_posts.ID!=343131 AND wp_posts.post_type='business' AND wp_posts.post_status='publish' AND wp_terms.name IN ('中餐','粤港菜','茶餐厅简餐','奶茶甜点','果汁饮品','咖啡烘焙','早茶点心')
GROUP BY wp_posts.ID
ORDER BY total_count DESC

Mysql并列条件筛选用OR还是IN

假设有一个叫business的table储存了大温地区的全部商户信息,其中有一栏city储存城市信息。我想提取出温哥华、列治文、本那比以及素里的商户,应该如何写query?

之前碰到这样的筛选类型,我一直用的是OR语句,类似这样的形式

WHERE city=’Vancouver’ OR city=’Burnaby’ …

昨天和同事交流,才知道原来还有一种IN语句更简洁高效

WHERE city IN (‘Vancouver’, ‘Burnaby’ …)

stackoverflow 上有人做了实验,IN语句运行速度比OR至少快一倍。

判断一个PHP数组为空时应该用empty还是count==0?

研究了一下,不管是用empty还是用count,运行效率方面没什么差别。如果数组为空,count返回0;但如果数组未定义,会收到php notice。所以要在count前面加isset判断。empty()不会有这个问题。

另外,空数组在PHP中相当于false,所以其实两个方程都不需要用,直接用数组本身做判断也可以。

<?php

    $arr=array();
    
    echo "The array is ", $arr ? 'full' : 'empty', ".\n";
//Output: The array is empty.


    $label = array(0 => 'empty', 1 => 'full');

    echo "The array is ", $label[(bool)$arr], ".\n";
//Output: The array is empty.

Use http_build_query to generate query string

When adding query data to my http requests, I used to url-encode all the parameters and combine them together as a single url-encoded string manually. Today I found a PHP function that just does the job perfectly.


<?php
$data = array('foo'=>'bar',
              'baz'=>'boom',
              'cow'=>'milk',
              'php'=>'hypertext processor');

echo http_build_query($data) . "\n";
//This will output: foo=bar&baz=boom&cow=milk&php=hypertext+processor
echo http_build_query($data, '', '&amp;');
//This will output: foo=bar&amp;baz=boom&amp;cow=milk&amp;php=hypertext+processor

?>

More details can be found here

像windows那样管理你的桌面:Spectacle

Mac OS自身的窗口平铺管理和渣到不行的多显示屏支持一直是我不满意的地方,今天在网上闲逛,看到有人介绍了一款名为Spectacle的应用,可以让Mac像Windows那样对窗口进行各种平铺,于是试用了一下,学会一系列的快捷键后,我已经离不开它了。下面是我从应用Github页上摘录的内容:

Windows can be moved to a number of predefined regions of the screen:

Move to the left half — ⌥⌘←
Move to the right half — ⌥⌘→
Move to the top half — ⌥⌘↑
Move to the bottom half — ⌥⌘↓

Move to the upper left — ⌃⌘←
Move to the lower left — ⌃⇧⌘←
Move to the upper right — ⌃⌘→
Move to the lower right — ⌃⇧⌘→

看起来有点复杂,但用着十分顺手,可以方便地让窗口占满半屏、全屏、三分之一屏和四分之一屏,用好了绝对大大地提升你的工作效率。

Spectacle

官方网站