分類
Linux

sar-Linux性能監測

我的CentOS沒有自帶,所以要通過yum install -y sysstat進行安裝。安裝後如果今天是14號,則執行一下sar -o 14,來創建今天的數據文件。

sar -n DEV |egrep 'em1|IFACE' 查看em1網卡網絡流量記錄(eth1)
sar -f /var/log/sa/sa03 -n DEV |egrep 'em1|IFACE' 查看本月3日em1網卡網絡流量記錄(eth1)
sar -u 查看cpu使用記錄
sar -r 查看內存使用記錄
sar -dp | egrep 'DEV|VolGroup-lv_root|VolGroup-lv_home' 查看指定硬盤的使用記錄(sdb)
sar -q 查看平均負載記錄
sar -W 查看頁面交換文件使用記錄
怀疑CPU存在瓶颈,可用 sar -u 和 sar -q 等来查看
怀疑内存存在瓶颈,可用sar -B、sar -r 和 sar -W 等来查看
怀疑I/O存在瓶颈,可用 sar -b、sar -u 和 sar -d 等来查看

df -h 查看磁盤用量
w 查看當前用戶和最近負載

分類
程序

定時發布

接口需要添加一個定時發布的功能,這樣可以提前準備好內容,時間一到,用戶就能看到。這裡用到js和php的日期操作。

大概搜了下html5中用datetime相關的表單,但是由於瀏覽器實現的問題,為了穩定性最終放棄。使用"YYYY-MM-DD HH:mm:ss"這樣的文本來保存設置時間,後台轉換成utc時間戳,最後通過對比時間戳來決定是否發布。時間全部顯示為北京時間。php使用了thinkphp框架。js和php默認返回的時間戳都是UTC時間。

後台的添加新聞模板:

<input type="text" class="" size="100" maxlength="300" name="publishTimeU" id="publishTimeU" value=""/>
<input type="hidden" maxlength="100" name="publishTime" id="publishTime" value=""/>
<script type="text/javascript">
(function($){
	var date = new Date();
	date = date.toISOString().substr(0, 19)+"-08:00";
	var date1 = new Date(date);
	date1 = date1.toISOString().substr(0, 19);
	date1 = date1.replace(/T/, " ");
	$("#publishTimeU").val(date1);
	
	//定時發布失去焦點時,換算時間戳
	$("#publishTimeU").blur(function(){
		var ptString=$("#publishTimeU").val();
		ptString=ptString.replace(/ /, "T")
		var pt=Date.parse(ptString+"+08:00")/1000;
		$("#publishTime").val(pt);
		
	}); 
})(jQuery);
</script>

後台的修改新聞模板:

<input type="text" class="" size="100" maxlength="300" name="publishTimeU" id="publishTimeU" value=""/>
<input type="hidden" maxlength="100" name="publishTime" id="publishTime" value="{$vo.publishTime}"/>
<script type="text/javascript">
(function($){
	var date = new Date($("#publishTime").val()*1000);
	date = date.toISOString().substr(0, 19)+"-08:00";
	var date1 = new Date(date);
	date1 = date1.toISOString().substr(0, 19);
	date1 = date1.replace(/T/, " ");
	$("#publishTimeU").val(date1);
	
	//定時發布失去焦點時,換算時間戳
	$("#publishTimeU").blur(function(){
		var ptString=$("#publishTimeU").val();
		ptString=ptString.replace(/ /, "T")
		var pt=Date.parse(ptString+"+08:00")/1000;
		$("#publishTime").val(pt);
		
	});
})(jQuery);
</script>

php接口:

$now = new DateTime(null, new DateTimeZone('Asia/Hong_Kong'));		
$nowTimestamp = $now->getTimestamp();
//只需在查詢語句的map里添加時間戳對比即可
$map = array (
	'h'		=> array('like','%'.$cid .'%'),
	'publishTime'	=> array('LT',$nowTimestamp),
	'status'	=> 1
);
$count = $model->where ( $map )->cache (false)->count ();
分類
软件

元素之刃

元素之刃-ios

這是Emanon參與製作的一款遊戲,真的耗費了三年多時間,現在終於上線。現在肯花這麼久開發遊戲的真的很少,所以衝著用了這麼久時間打磨也應該差不到哪裡去。蘋果App Store鏈接:元素之刃。我和Emanon都沒有蘋果設備,所以無法寫篇測評什麼的。什麼時候玩過了,再來補充。


接了個iPad2,結果不適配,雖然硬要玩也能玩一下(原始版特效會變黑像素塊,後面關卡會因為看不到血條而打不過;第二版後面關卡會閃退)。所以建議iPad2以下的用戶還是不要嘗試了。有一點提示是,由於這是一個兩三百兆大小的單機遊戲,所以在升級過程中,盡量不要動它,待它升級完成後再開始玩。否則如果自己有誤操作的話,有一定幾率丟失遊戲進度資料。

本文更新於 2016/03/14。

分類
网站

PHP隨機

最近有一個需求是這樣,數據庫有電影幾百條,預告片幾百條。之前是倒序排列返回給客戶端,這樣所有客戶端就能看到最新的片子和預告片,電影和預告片是兩個接口。現在由於考慮服務器壓力,決定隨機展現影片和預告片給客戶端,兩個接口合併成一個,按ABABAB這樣返回。我的做法是以用戶id加今年的天數作為隨機種子對電影和預告片進行隨機排序,然後截取亂序後的數組進行交叉合併並進行分頁,再返回給客戶端。這樣的效果是同一用戶在同一天打開的列表是一樣的,而且影片條目不會重複。而不同用戶打開的列表卻不一樣。公司項目用的ThinkPHP3.1,看下代碼

//接口urlhttp://domin.com:8042/Video/v1.php?qt=Videolist&pi=2&ps=20&uid=972124678
class ApiVideolistAction extends Action{
function getData(){
    //獲取用戶id,單頁條目數量和第幾頁
    $uid = I("get.uid", "0", "intval");
    $pageSize = I("get.ps", "20", "intval");
    $pageNum = I("get.pi", "1", "intval");
    $model1=new Model();

    $film=$model1->query("SELECT video_static.sid FROM video_static, category_video WHERE category_video.cid = 4 AND video_static.status = 1 AND category_video.vid = video_static.sid ");
    $trailer=$model1->query("SELECT video_static.sid FROM video_static, category_video WHERE category_video.cid = 50 AND video_static.status = 1 AND category_video.vid = video_static.sid ");
    $count = count($film) > count($trailer) ? count($film) : count($trailer);
    $allPage = ceil($count / $pageSize);
    if ($pageNum > 0 && $pageNum <= $allPage) {
        $limit_start = ($pageNum - 1) * $pageSize;
    } else {
            $limit_start = 0;
    }
    $dayNum=(int)date('z');
    //设置隨機種子,只要種子一樣,隨機後的數組就一樣
    srand($uid+$dayNum);
    //打亂數組
    shuffle($film);
    shuffle($trailer);
    //分頁切數組
    $vid_listF=array_slice($film,$limit_start,$pageSize);
    $vid_list1F=array_slice($trailer,$limit_start,$pageSize);
    //交叉合併數組
    $arr = array();
    for($i=0;$i < $pageSize; $i++){
        array_push($arr,$vid_listF&#91;$i&#93;); 
        array_push($arr,$vid_list1F&#91;$i&#93;);
    }
    if (empty($arr)) {
            return array(
                "resultStatus" => 1,
                "allCount" => 0,
                "data" => null
            );
    }
    $data = array();
    foreach ($arr as  $every) {
        //這裡用了ThinkPHP的方法根據sid獲取一條數據
        $find = D('VideoStatic')->find($every['sid']);
        //對數據進行處理的示例
        $find['videuri'] = $find['videuri'] ? "http://" . APP_HOST_NAME . ":8042/" . $find['videuri'] : "";        
        if (empty($find)) { continue; }
        $data[] = array_change_key_case($find, CASE_UPPER);
    }
    $result = array(
            "allCount" => $count,
            "pageCount" => $allPage,
            "pageSize" => $pageSize*2,
            "pageIndex" => $pageNum
    );
    return array(
            "resultStatus" => 1,
            "pinfo" => $result,
            "data" => $data
    );
}
}

既然文章名叫PHP隨機,其實PHP隨機最常用的用法是rand(10,13),它會返回最小10,最大13的整數。

分類
网站

php生成圖片與crontab

PHP生成圖片

//@function.php
//先獲取個GET參數等下寫圖片里
if ($_GET["name"]) {
    $name = htmlspecialchars($_GET["name"]);
} else {
    $name = '';
}
//創建圖像
$img=getImgType($img_path);
$img=createImg($img,$wordsPhoto,$left_px,$top_px,25,0,20,'19f','ARIALUNI');
//保存圖像
$img_info=saveImg($img,'png');

//創建圖像函數
function getImgType($img_path) {
	$img = getimagesize ( $img_path );
	switch ($img [2]) {
		case 1 :
			$img = @imagecreatefromgif ( $img_path );
			break;
		case 2 :
			$img = @imagecreatefromjpeg ( $img_path );
			break;
		case 3 :
			$img = @imagecreatefrompng ( $img_path );
			break;
		default :
			$img = @imagecreatefrompng ( $img_path );
	}
	return $img;
}
//修改圖像函數
function createImg($img, $str, $x, $y, $length = 20, $angle = 0, $size = 12, $color = '39f', $font = 'kanghua') {
	switch ($color) {
		case '19f' :
			$color = imagecolorallocate ( $img, 22, 157, 252 );
			break;
		case 'f37' :
			$color = imagecolorallocate ( $img, 255, 51, 119 );
			break;
		case '63a' :
			$color = imagecolorallocate ( $img, 68, 172, 106 );
			break;
		case 'f90' :
			$color = imagecolorallocate ( $img, 255, 158, 3 );
			break;
		case 'a60' :
			$color = imagecolorallocate ( $img, 172, 106, 0 );
			break;
		case '790' :
			$color = imagecolorallocate ( $img, 113, 149, 13 );
			break;
		case 'fff' :
			$color = imagecolorallocate ( $img, 255, 255, 255 );
			break;
		case '000' :
			$color = imagecolorallocate ( $img, 0, 0, 0 );
			break;
		default :
			$color = imagecolorallocate ( $img, 67, 157, 252 );
	}
	switch ($font) {
		case 'ARIALUNI' :
			$font = './../font/ARIALUNI.ttf';
			break;
		case 'CODE2000' :
			$font = './../font/CODE2000.ttf';
			break;
		case 'SarunsManorah' :
			$font = './../font/SarunsManorah.ttf';
			break;
		case 'FreeSerif' :
			$font = './../font/FreeSerif.ttf';
			break;
		case 'kanghua' :
			$font = './../font/kanghua.ttf';
			break;
		case 'shishang' :
			$font = './../font/shishang.ttf';
			break;
		case 'yahei' :
			$font = './../font/yahei.ttf';
			break;
		default :
			$font = './../a_include/font/kanghua.ttf';
	}
	$str = wordwrap_utf8 ( $str, $length );
	imagettftext ( $img, $size, $angle, $x, $y, $color, $font, $str );
	return $img;
}
//文字换行
function wordwrap_utf8($string, $length = 20, $break = "\n", $cut = false) {
	if ($length == 0) {
		return $string;
	}
	preg_match_all ( '/./u', $string, $matches );
	$s = $matches [0];
	$ct = count ( $s );
	for($i = 0; $i < ceil ( $ct / $length ); $i ++) {
		$ns .= implode ( '', array_slice ( $s, $i * $length, $length ) ) . $break;
	}
	return $ns;
}
function saveImg($img, $type = 'png') {
	$img_url = '';
	$img_name = time ().rand(10,99);
        //php5.5以上才支持webp
	if ($type == 'jpg') {
		$img_url = '/a_cache/' . $img_name . '.jpg';
		$img_filename = dirname ( dirname ( dirname ( __FILE__ ) ) ) . '/a_cache/' . $img_name . '.jpg';
		imagejpeg ( $img, $img_filename );
	} else {
		$img_url = '/a_cache/' . $img_name . '.png';
		$img_filename = dirname ( dirname ( dirname ( __FILE__ ) ) ) . '/a_cache/' . $img_name . '.png';
		imagepng ( $img, $img_filename );
	}
	imagedestroy ( $img );
	$img_info ['img_name'] = $img_name;
	$img_info ['img_url'] = '..' . $img_url;
        return $img_info;
}

網頁展示圖片

//@show.php
require_once 'function.php';

<div style="width:100%;text-align:center;background-color: #58C7C2;padding: 0.52em 0.1em 0.52em 0.1em;">
<img id="res_pic" style="display: block;width: 70%;margin-left: 15%;" src="<?php echo $img_info['img_url'];?>" />
</div>

用corntab定期清理緩存圖片

創建可執行文件/www/del_cache,內容如下,意思是刪除兩天前的文件

#!/bin/bash 
find /path/to/your/a_cache/* -mtime +2 -exec rm -f {} \;

把執行文件加入定時任務

crontab -e
#如果有多個編輯器,可能會讓選擇編輯器,但我CentOS中有nano,並沒有提示,我還是得用vi

修改並把下面一行粘貼到最後,意思是每小時的0分執行一次

00 * * * * /path/to/the/script

有時我們需要每30秒執行一次定時任務,但是crontab只能精確到分,可以這麼做:

* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )

這裡還有一個每90秒的例子:

*/3 * * * * /path/to/executable param1 param2
*/3 * * * * ( sleep 90 ; /path/to/executable param1 param2 )

有時我們需要以root用戶來執行crontab中的命令,僅僅切換到root用戶然後使用crontab -e似乎還是不行,後來發現(CentOS下)可以這樣:

nano /etc/crontab
#在這裡編輯需要定時執行的命令,並指定運行命令的用戶
03 * * * * root /path/to/the/script

有時的需求是這樣的,定時任務執行時間不確定,比如有時10分鐘,有時30分鐘,但是我們還不想同時執行兩個任務,這時可以使用flock文件鎖來控制只有一個程序在跑。

#下面的效果就是,每5分鐘檢查一次,如果在ping就跳過此次執行
*/5 * * * * flock -xn /tmp/42ping.lock -c 'ping -c 1000 ft.wupo.info >> ping.log'
#測試發現即使程序異常中斷,lock也會被解除,下次任務仍然得以運行

參考了How to Delete Old Files In A Folder Automatically In LinuxRunning a cron every 30 seconds。對於crontab的寫法,可以到crontab.guru來驗證是否正確。其實我主要是想記錄這一段。

本文更新於 2017/03/07。

分類
网站

Line分享

製作Line分享按鈕請先參考官方文檔用LINE傳送。簡單說是Line分享只能傳一條文本消息和一個url鏈接。http://形式會先跳轉到Line服務器的一個網頁,讓用戶選擇打開Line還是安裝Line。line://形式則直接打開Line進行分享,但是如果用戶沒有安裝Line則按鈕會沒有反應。

使用中發現,Line對Emoji的支持還是很好的,可以放到分享信息中,可以參見Emojiえもじ。同時還發現Line對url的支持有問題,即url中如果出現非英文字符,Line即會將url中剩餘部分丟棄,造成url丟失數據。其實這個解決起來很簡單,用php自帶的base64函數把中文編碼一下再傳遞就好了。只用base64是不行的,因為裡面會有空格等字符會被Line裁掉,所以在加一層urlencode就好了。

//js中定義好Line的分享鏈接,name用base64加密,下面一行php被wordpress保護機制注釋了。
var urlShare="http://www.55mun.com/gameh5/match3/indexv.php?name=<?php echo urlencode(base64_encode($name));?>";
//php中接收並解析出name
$n=htmlspecialchars(base64_decode(urldecode($_GET["name"])));


Line分享網址抓取錯誤

有次分享網址,抓取到的縮略圖和標題都是網站主頁的信息,後來發現是head裏有一條meta信息導致的,這條meta中的url必須是分享的url,否則line就肯定會按照這個meta中的url來抓取:

<meta http-equiv="mobile-agent" content="format=html5;url=http://thePage.you.wishToShare/">

關注Line@

寫法1:

Follow <a href="line://ti/p/@myLineAtAccount">myLineAtAccount</a>

寫法2:

Follow <a href="intent://ti/p/@myLineAtAccount#Intent;scheme=line;action=android.intent.action.VIEW;category=android.intent.category.BROWSABLE;package=jp.naver.line.android;end">myLineAtAccount</a>

本文更新於 2016/07/15。

分類
程序

Emojiえもじ

Emoji即顏文字,現在還挺流行的,像?,完整表可以看Emoji Unicode Tables。其中第一列就是當前設備原生顏文字的表現形式。由於顏文字實際上是字符,所以不同平台有不同的展現形式,就像不同的字體一樣。如果想在網頁中加入顏文字,直接把顏文字當字符複製到網頁中就可以了。

最近用到一個功能,讓Line分享的信息中包含顏文字排列出的圖案,像這種
     ??     ??
???????
???????
???????
     ?????
          ???
               ?
問題主要在於空格和換行,空格無需處理,直接放到待分享信息中即可,換行用\n代替,就可把上面圖案傳至Line分享框了。Line的分享格式我是這樣寫的:

var shareMsg='好搞笑哦\n?';
function shareToLine42(){
	lineUrl="line://msg/text/"+encodeURIComponent(shareMsg)+"%0D%0Ahttps://ft.wupo.info/";
	//如果你有谷歌統計,下面一行可以統計按鈕的點擊次數
	//ga('send', 'event', 'button', 'click', 'share-line-button');
	window.open(lineUrl, 'sharer', 'toolbar=0,status=0,width=626,height=436');
}
注意,shareMsg中顏文字被wordpress做了修改,用來兼容沒有顏文字的平台,實際直接這樣寫"好搞笑哦\n?"就可以。後面代碼中再有顏文字我用"顏文字UTF8"代替。

在wordpress4.4中,顏文字是這樣展現的,把真正的utf8字符放到了alt標籤里。

<img class="emoji" draggable="false" alt="顏文字UTF8" src="https://s.w.org/images/core/emoji/72x72/1f602.png">
去數據庫發現posts表中post_content字段類型為longtext,排序規則為utf8mb4_unicode_ci。其中保存的就是?,而用圖片替換顏文字是發生在文章輸出過程中的。關於排序規則請參考:What's the difference between utf8_general_ci and utf8_unicode_ci,如果沒空細看,那麼結論是直接用utf8mb4_unicode_ci就好。如果你還在用utf8-general-ci,是無法儲存顏文字的。

本文更新於 2016/07/20。