iOS 申请证书与发布流程

http://www.cnblogs.com/sk-fengzi/p/5670087.html

发表在 工作日志 | 留下评论

Centos 下PHP编译安装fileinfo扩展

1.检查当前环境

php -i|grep fileinfo 若出现 fileinfo fileinfo support => enabled 则代表fileinfo扩展可用,否则不可用。

2.安装

2-1:下载

wget -O php-5.6.9.tar.gz http://cn2.php.net/get/php-5.6.9.tar.gz/from/this/mirror

2-2:解压

tar -zxvf php-5.6.9.tar.gz

2-3:进入对应php版本扩展目录(我这是5.6.9版本)

cd /var/php5.6.9/php-5.6.9/ext/fileinfo

2-4:编译&&安装

/usr/local/php/bin/phpize
./configure -with-php-config=/usr/local/php/bin/php-config
make && make install
vim /usr/local/php/etc/php.ini

2-5:修改php.ini

加入:extension=fileinfo.so

发表在 linux | 留下评论

GIT提交代码报error: RPC failed; result=22, HTTP code = 413解决办法

参照http://blog.csdn.net/passion_wu128/article/details/8216086中搭建的gitlab服务器提交的时候总是出现如下错误:

error: RPC failed; result=22, HTTP code = 413

fatal: The remote end hung up unexpectedly

fatal: The remote end hung up unexpectedly

 

这跟git的postBuffer变量值没有关系。

(如果code = 411,则是由postBuffer引起的,可以在客户端执行

git config –global http.postBuffer 52428800,改为最大50M)

参照这篇帖子里面的办法解决了此问题:

http://stackoverflow.com/questions/7489813/github-push-error-rpc-failed-result-22-http-code-413

其实就是将http 协议改为ssh认证就可以了

git remote set-url origin git@github.com:GitRepoName.git

github.com是你的服务器域名,我的是192.168.1.120

GitRepoName.git是git仓库名

当然还要通过ssh认证

客户端执行命令:

ssh-keygen -t rsa -C “username@163.com”

然后三次回车或者指定密钥路径和密码,默认产生的密钥和公钥在登录用户的.ssh文件夹下.

(密码必须放在用户的.ssh文件夹下)

然后使用username@163.com登录gitlab管理界面,在用户的profile中add public key

保存就可以了,此公钥的内容会自动追加到服务器中的/home/git/.ssh/authorized_keys文件中。

(不要直接将此公钥拷贝到authorized_keys文件中)

重启gitlab服务

sudo /etc/init.d/gitlab restart

认证成功后push 和 pull的时候就不需要再输入用户名和密码了,而且刚才的错误也没有了。

今天(2013/01/09)发现最好的解决办法是修改nginx.conf,我的路径是/etc/nginx/nginx.conf

在http中加入 client_max_body_size 50m, 这个值默认是1M.(以前对nginx不熟悉,根本不知道这个配置,找了好久终于解决这个问题了)

重启gitlab服务

sudo /etc/init.d/gitlab restart

Ok了,小于50M的东西都可以使用http协议提交了。

发表在 php | 留下评论

PHP-FPM进程CPU 100%的原因及解决方案

最近有服务器不时出现的CPU使用率超高,内存几乎被吃光,系统甚至自动kill掉一些进程,如sshd,vsftpd等。用top查看,PHP-CGI进程高挂不下,如下是解决方案:
一、进程跟踪
# top //找出CPU使用率高的进程PID
# strace -p PID //跟踪进程
# ll /proc/PID/fd //查看该进程在处理哪些文件
将有可疑的PHP代码修改之,如:file_get_contents没有设置超时时间。
二、内存分配
如果进程跟踪无法找到问题所在,再从系统方面找原因,会不会有可能内存不够用?据说一个较为干净的PHP-CGI打开大概20M-30M左右的内存,决定于PHP模块开启多少。
通过pmap指令查看PHP-CGI进程的内存使用情况
# pmap $(pgrep php-cgi |head -1)
按输出的结果,结合系统的内存大小,配置PHP-CGI的进程数(max_children)。
三、监控
最后,还可以通过监控与自动恢复的脚本保证服务的正常运转。下面是我用到的一些脚本:
只要一个php-cgi进程占用的内存超过 %1 就把它kill掉
#!/bin/sh
PIDS=`ps aux|grep php-cgi|grep -v grep|awk’{if($4>=1)print $2}’`
for PID in $PIDS
do
echo `date +%F….%T`>>/data/logs/phpkill.log
echo $PID >> /data/logs/phpkill.log
kill -9 $PID
done

检测php-fpm进程
#!/bin/bash
netstat -tnlp | grep “php-cgi” >> /dev/null #2&> /data/logs/php_fasle.log
if [ “$?” -eq “1” ];then #&& [ `netstat -tnlp | grep 9000 | awk ‘{ print $4}’ | awk -F “:” ‘{print $2}’` -eq “1” ];then
/usr/local/webserver/php/sbin/php-fpm start
echo `date +%F….%T` “System memory OOM.Kill php-cgi. php-fpm service start. ” >> /data/logs/php_monitor.log
fi
通过http检测php执行
#!/bin/bash
status=`curl -s –head “http://127.0.0.1:8080/chk.php” | awk ‘/HTTP/ {print $2}’`
if [ $status != “200” -a $status != “304” ]; then
/usr/local/webserver/php/sbin/php-fpm restart
echo `date +%F….%T` “php-fpm service restart” >> /data/logs/php_monitor.log
fi

发表在 linux | 留下评论

MySQL查询优化-explain

在分析查询性能时,考虑EXPLAIN关键字同样很管用。EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL如何执行查询操作、以及MySQL成功返回结果集需要执行的行数。explain 可以帮助我们分析 select 语句,让我们知道查询效率低下的原因,从而改进我们查询,让查询优化器能够更好的工作。

 

       一、MySQL 查询优化器是如何工作的

        MySQL 查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行。最终目标是提交 SELECT 语句查找数据行,而不是排除数据行。优化器试图排除数据行的原因在于它排除数据行的速度越快,那么找到与条件匹配的数据行也就越快。如果能够首先进行最严格的测试,查询就可以执行地更快。

EXPLAIN 的每个输出行提供一个表的相关信息,并且每个行包括下面的列:

说明
id         MySQL Query Optimizer 选定的执行计划中查询的序列号。表示查询中执行 select 子句或操作表的顺序,id值越大优先级越高,越先被执行。id 相同,执行顺序由上至下。

 

 

select_type 查询类型 说明
SIMPLE 简单的 select 查询,不使用 union 及子查询
PRIMARY 最外层的 select 查询
UNION UNION 中的第二个或随后的 select 查询,不 依赖于外部查询的结果集
DEPENDENT UNION UNION 中的第二个或随后的 select 查询,依 赖于外部查询的结果集
SUBQUERY 子查询中的第一个 select 查询,不依赖于外 部查询的结果集
DEPENDENT SUBQUERY 子查询中的第一个 select 查询,依赖于外部 查询的结果集
DERIVED 用于 from 子句里有子查询的情况。 MySQL 会 递归执行这些子查询, 把结果放在临时表里。
UNCACHEABLE SUBQUERY 结果集不能被缓存的子查询,必须重新为外 层查询的每一行进行评估。
UNCACHEABLE UNION UNION 中的第二个或随后的 select 查询,属 于不可缓存的子查询

 

 

 

 

 

 

说明
table 输出行所引用的表

 

 

type 重要的项,显示连接使用的类型,按最 优到最差的类型排序 说明
system 表仅有一行(=系统表)。这是 const 连接类型的一个特例。
const const 用于用常数值比较 PRIMARY KEY 时。当 查询的表仅有一行时,使用 System。
eq_ref const 用于用常数值比较 PRIMARY KEY 时。当 查询的表仅有一行时,使用 System。
ref 连接不能基于关键字选择单个行,可能查找 到多个符合条件的行。 叫做 ref 是因为索引要 跟某个参考值相比较。这个参考值或者是一 个常数,或者是来自一个表里的多表查询的 结果值
ref_or_null 如同 ref, 但是 MySQL 必须在初次查找的结果 里找出 null 条目,然后进行二次查找。
index_merge 说明索引合并优化被使用了。
unique_subquery 在某些 IN 查询中使用此种类型,而不是常规的 ref:value IN (SELECT primary_key FROM single_table WHERE some_expr)
index_subquery 在 某 些 IN 查 询 中 使 用 此 种 类 型 , 与 unique_subquery 类似,但是查询的是非唯一 性索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
range 只检索给定范围的行,使用一个索引来选择 行。key 列显示使用了哪个索引。当使用=、 <>、>、>=、<、<=、IS NULL、<=>、BETWEEN 或者 IN 操作符,用常量比较关键字列时,可 以使用 range。
index 全表扫描,只是扫描表的时候按照索引次序 进行而不是行。主要优点就是避免了排序, 但是开销仍然非常大。
all 最坏的情况,从头到尾全表扫描。

 

 

 

说明
possible_keys 指出 MySQL 能在该表中使用哪些索引有助于 查询。如果为空,说明没有可用的索引。

 

 

说明
key MySQL 实际从 possible_key 选择使用的索引。 如果为 NULL,则没有使用索引。很少的情况 下,MYSQL 会选择优化不足的索引。这种情 况下,可以在 SELECT 语句中使用 USE INDEX (indexname)来强制使用一个索引或者用 IGNORE INDEX(indexname)来强制 MYSQL 忽略索引

 

 

说明
key_len 使用的索引的长度。在不损失精确性的情况 下,长度越短越好。

 

 

说明
ref 显示索引的哪一列被使用了

 

 

说明
rows MYSQL 认为必须检查的用来返回请求数据的行数

 

 

说明
rows MYSQL 认为必须检查的用来返回请求数据的行数

 

 

 

 

 

extra 中出现以下 2 项意味着 MYSQL 根本不能使用索引,效率会受到重大影响。应尽可能对此进行优化。

 

extra 项 说明
Using filesort 表示 MySQL 会对结果使用一个外部索引排序,而不是从表里按索引次序读到相关内容。可能在内存或者磁盘上进行排序。MySQL 中无法利用索引完成的排序操作称为“文件排序”
Using temporary 表示 MySQL 在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by。

 

 

 

 

 

 

 

 

下面来举一个例子来说明下 explain 的用法。

先来一张表:

CREATE TABLE IF NOT EXISTS `article` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`author_id` int(10) unsigned NOT NULL,
`category_id` int(10) unsigned NOT NULL,
`views` int(10) unsigned NOT NULL,
`comments` int(10) unsigned NOT NULL,
`title` varbinary(255) NOT NULL,
`content` text NOT NULL,
PRIMARY KEY (`id`)
);

再插几条数据:

INSERT INTO `article`
(`author_id`, `category_id`, `views`, `comments`, `title`, `content`) VALUES
(1, 1, 1, 1, '1', '1'),
(2, 2, 2, 2, '2', '2'),
(1, 1, 3, 3, '3', '3');

需求:
查询 category_id 为 1 且 comments 大于 1 的情况下,views 最多的 article_id。
先查查试试看:

EXPLAIN
SELECT author_id
FROM `article`
WHERE category_id = 1 AND comments > 1
ORDER BY views DESC
LIMIT 1\G

看看部分输出结果:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: article
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
        Extra: Using where; Using filesort
1 row in set (0.00 sec)

很显然,type 是 ALL,即最坏的情况。Extra 里还出现了 Using filesort,也是最坏的情况。优化是必须的。

嗯,那么最简单的解决方案就是加索引了。好,我们来试一试。查询的条件里即 where 之后共使用了 category_id,comments,views 三个字段。那么来一个联合索引是最简单的了。

ALTER TABLE `article` ADD INDEX x ( `category_id` , `comments`, `views` );

结果有了一定好转,但仍然很糟糕:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: article
         type: range
possible_keys: x
          key: x
      key_len: 8
          ref: NULL
         rows: 1
        Extra: Using where; Using filesort
1 row in set (0.00 sec)

type 变成了 range,这是可以忍受的。但是 extra 里使用 Using filesort 仍是无法接受的。但是我们已经建立了索引,为啥没用呢?这是因为按照 BTree 索引的工作原理,先排序 category_id,如果遇到相同的 category_id 则再排序 comments,如果遇到相同的 comments 则再排序 views。当 comments 字段在联合索引里处于中间位置时,因comments > 1 条件是一个范围值(所谓 range),MySQL 无法利用索引再对后面的 views 部分进行检索,即 range 类型查询字段后面的索引无效。
那么我们需要抛弃 comments,删除旧索引:

 DROP INDEX x ON article;

然后建立新索引:

ALTER TABLE `article` ADD INDEX y ( `category_id` , `views` ) ;

接着再运行查询:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: article
         type: ref
possible_keys: y
          key: y
      key_len: 4
          ref: const
         rows: 1
        Extra: Using where
1 row in set (0.00 sec)

可以看到,type 变为了 ref,Extra 中的 Using filesort 也消失了,结果非常理想。

再来看一个多表查询的例子。

首先定义 3个表 class 和 room。

CREATE TABLE IF NOT EXISTS `class` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`card` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `book` (
`bookid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`card` int(10) unsigned NOT NULL,
PRIMARY KEY (`bookid`)
);
CREATE TABLE IF NOT EXISTS `phone` (
`phoneid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`card` int(10) unsigned NOT NULL,
PRIMARY KEY (`phoneid`)
) engine = innodb;

然后再分别插入大量数据。插入数据的php脚本:

<?php
$link = mysql_connect("localhost","root","870516");
mysql_select_db("test",$link);
for($i=0;$i<10000;$i++)
{
    $j   = rand(1,20);
    $sql = " insert into class(card) values({$j})";
    mysql_query($sql);
}
for($i=0;$i<10000;$i++)
{
    $j   = rand(1,20);
    $sql = " insert into book(card) values({$j})";
    mysql_query($sql);
}
for($i=0;$i<10000;$i++)
{
    $j   = rand(1,20);
    $sql = " insert into phone(card) values({$j})";
    mysql_query($sql);
}
mysql_query("COMMIT");
?>

然后来看一个左连接查询:

explain select * from class left join book on class.card = book.card\G

分析结果是:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: class
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: book
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
2 rows in set (0.00 sec)

显然第二个 ALL 是需要我们进行优化的。
建立个索引试试看:

ALTER TABLE `book` ADD INDEX y ( `card`);
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: class
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: book
         type: ref
possible_keys: y
          key: y
      key_len: 4
          ref: test.class.card
         rows: 1000
        Extra: 
2 rows in set (0.00 sec)

可以看到第二行的 type 变为了 ref,rows 也变成了 1741*18,优化比较明显。这是由左连接特性决定的。LEFT JOIN 条件用于确定如何从右表搜索行,左边一定都有,所以右边是我们的关键点,一定需要建立索引。
删除旧索引:

DROP INDEX y ON book;

建立新索引。

ALTER TABLE `class` ADD INDEX x ( `card`);

结果

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: class
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: book
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
2 rows in set (0.00 sec)

基本无变化。
然后来看一个右连接查询:

explain select * from class right join book on class.card = book.card;

分析结果是:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: book
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: class
         type: ref
possible_keys: x
          key: x
      key_len: 4
          ref: test.book.card
         rows: 1000
        Extra: 
2 rows in set (0.00 sec)

优化较明显。这是因为 RIGHT JOIN 条件用于确定如何从左表搜索行,右边一定都有,所以左边是我们的关键点,一定需要建立索引。

删除旧索引:

DROP INDEX x ON class;

建立新索引。

ALTER TABLE `book` ADD INDEX y ( `card`);

结果

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: class
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: book
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
2 rows in set (0.00 sec)

基本无变化。      最后来看看 inner join 的情况:

explain select * from class inner join book on class.card = book.card;

结果:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: book
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: class
         type: ref
possible_keys: x
          key: x
      key_len: 4
          ref: test.book.card
         rows: 1000
        Extra: 
2 rows in set (0.00 sec)

删除旧索引:

DROP INDEX y ON book;

结果

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: class
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: book
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
2 rows in set (0.00 sec)

建立新索引。

ALTER TABLE `class` ADD INDEX x ( `card`);

结果

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: class
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: book
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
2 rows in set (0.00 sec)

综上所述,inner join 和 left join 差不多,都需要优化右表而 right join 需要优化左表

我们再来看看三表查询的例子

添加一个新索引:

1
ALTER TABLE `phone` ADD INDEX z ( `card`);
ALTER TABLE `book` ADD INDEX y ( `card`);
explain select * from class left join book on class.card=book.card left join phone on book.card = phone.card;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: class
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 20000
        Extra: 
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: book
         type: ref
possible_keys: y
          key: y
      key_len: 4
          ref: test.class.card
         rows: 1000
        Extra: 
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: phone
         type: ref
possible_keys: z
          key: z
      key_len: 4
          ref: test.book.card
         rows: 260
        Extra: Using index
3 rows in set (0.00 sec)

后 2 行的 type 都是 ref 且总 rows 优化很好,效果不错。
MySql 中的 explain 语法可以帮助我们改写查询,优化表的结构和索引的设置,从而最大地提高查询效率。当然,在大规模数据量时,索引的建立和维护的代价也是很高的,往往需要较长的时间和较大的空间,如果在不同的列组合上建立索引,空间的开销会更大。因此索引最好设置在需要经常查询的字段中

发表在 MYSQL | 留下评论

HTML5获取媒体文件的播放时间

video元素有一个duration属性,它表示的是视频时长的秒数,在页面上为了能更友好的显示时间,我们还需要对这些秒数进行格式化,需要使用到parseInt 和余数操作 (%):

 

<html>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<head><title>测试文件上传</title></head>
<body>
<input type=”file” id=”fileinput” onchange=”getduration()” />
<video id=”media” src=”” controls width=”400px” heigt=”400px”></video>
<script type=”text/javascript”>
function getduration(){
var file = document.getElementById(‘fileinput’).files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e){
var media=document.getElementById(“media”);
media.src=this.result;
//media.play(); //播放
//alert(parseFloat(media.duration));
//writeObj(file);
var i = setInterval(function() {
if(media.readyState > 0) {
var minutes = parseInt(media.duration / 60, 10);
var seconds = parseInt(media.duration % 60);
alert(minutes+’分’+seconds+’秒’);
clearInterval(i);
}
}, 200);
}
}

function writeObj(obj){
var description = “”;
for(var i in obj){
var property=obj[i];
description+=i+” = “+property+”\n”;
}
alert(description);
}
</script>
</body>
</html>

需要说明的一点是,我们需要使用setInterval来检查视频的readyState是否有效,如果视频还没有加载成功,我们就去获取这个值,得到的数值就会有问题。parseInt是用来获取分钟数,余数操作时用来获取秒数。

 

发表在 HTML5 | 留下评论

html5 中创建manifest缓存以及更新方法

今天学习了一下manifest的相关知识,整理记录如下,以备将来查阅。

一、manifest

  • MIME TYPE:text/cache-manifest
  • 需要由你创建的:NAME.manifest
  • 作用:主要是配置需要缓存的文件
二、实现
  1. 在服务器上添加MIME TYPE支:比如 Apache 中可在 .htaccess 中添加:
    AddType text/cache-manifest manifest
  2. 创建 NAME.manifest:其中第一行的 CACHE MANIFEST 标识是一定要有的(测试时发现火狐不加也能缓存成功,但不知是否有其他影响);

    CACHE / NETWORK / FACKBACK 三个关键字用于不同功能,CACHE 缓存;NETWORK 指不想缓存的页面;FALLBACK 是指当没有响应时的替代方案,比如我想请求某个页面,但这个页面的服务器挂了,那么,我可以显示另外一个指定的页面;

    文件编码最好使用utf-8;

    行开头“#”是注释;

     

    [plain] view plain copy

    1. CACHE MANIFEST  
    2. # VERSION  
    3.   
    4. # 直接缓存的文件d  
    5. CACHE:  
    6. m.js  
    7. m1.js  
    8.   
    9. # 需要在时间在线的文件  
    10. NETWORK:  
    11. cache.html   
    12.   
    13. # 替代方案  
    14. FALLBACK:  
    15. #/ajax/ ajax.html  

     

     

3. html文件改造

         给 <html> 标签加 manifest 属性

[plain] view plain copy

  1. <html manifest=”m.manifest”>  
  2. <head>  
  3.     <meta http-equiv=”Content-Type” content=”text/html;charset=utf-8″>  
  4.     <script type=”text/javascript” src=”m.js”></script>  
  5. </head>  
  6. <body>  
  7. ver:5<p>  
  8. <input type=”button” value=”shwo_ver” onclick=”show_ver();” /><p>  
  9. <input type=”button” value=”load_js” onclick=”load_js();” /><p>  
  10. <input type=”button” value=”is_online” onclick=”is_online();” /><p>  
  11. </body>  
  12. </html>  


三、测试

       chrome的开发者工具 》Console  会显示创建缓存的情况

[plain] view plain copy

  1. Document was loaded from Application Cache with manifest http://127.0.0.1/work/html5/manifest/m.manifest  
  2. Application Cache Checking event  
  3. Application Cache Downloading event  
  4. Application Cache Progress event (0 of 4) http://127.0.0.1/work/html5/manifest/m.js  
  5. Application Cache Progress event (1 of 4) http://127.0.0.1/work/html5/manifest/m1.js  
  6. Application Cache Progress event (2 of 4) http://127.0.0.1/work/html5/manifest/cache.html  
  7. Application Cache Progress event (3 of 4) http://127.0.0.1/work/html5/manifest/cache1.html  
  8. Application Cache Progress event (4 of 4)   
  9. Application Cache UpdateReady event  


四、关于更新

    1.自动更新:浏览器除了在第一次访问 Web 应用时缓存资源外,只会在 cache manifest 文件本身发生变化(即使是注释变化)时更新缓存。而 cache manifest 中的资源文件发生变化并不会触发更新。
2.手动更新:开发者也可以使用 window.applicationCache 的接口更新缓存。方法是检测 window.applicationCache.status 的值,如果是 UPDATEREADY,那么可以调用 window.applicationCache.update() 更新缓存。示范代码如下。

[javascript] view plain copy

  1. if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {  
  2.         window.applicationCache.update();   
  3. }  


五、在线状态检测和监视

  1.检测:navigator.onLine 属性表示当前是否在线。如果为 true, 表示在线;如果为 false, 表示离线

  2.监视:当在线 / 离线状态切换时会触发online/offline 事件,这两个事件触发在 body 元素上,并且沿着 document.body、document 和 window 的顺序冒泡。

参考:

使用 HTML5 开发离线应用   http://www.189works.com/article-68089-1.html

HTML5离线篇收藏— cache manifest  http://www.cnblogs.com/brainmao/archive/2011/09/27/2193495.html

发表在 HTML5 | 留下评论

【转】PHP性能分析之xhprof

xdebug讲到了使用xdebug对php程序进行性能分析,这里再介绍另外一个工具:xhprof,facebook出品。xhprof是一个函数级别的分层性能报告工具,包括调用次数,阻塞时间,CPU时间和内存使用情况。
首先,下载并安装xhprof扩展

1
2
3
4
5
6
7
8
9
10
11
12
tar -zxvf xhprof-0.9.4.tgz
cd xhprof-0.9.4
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
make install
#拷贝扩展
cp /usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/xhprof.so /usr/local/php/lib/php/extensions/
mkdir -p /tmp/xhprof
chmod 755 /tmp/xhprof
chown www:www /tmp/xhprof

xhprof自带的界面工具比较简单,这里推荐使用另外一个UI:XHProf.io。下载解压到web目录下面,重命名/xhprof/includes/目录下的config.inc.sample.php为/xhprof/includes/config.inc.php,并更改文件:

1
2
3
4
5
return array(
    'url_base' => 'http://192.168.84.2:8502/', //本地的XHProf.io站点
    'url_static' => null, // When undefined, it defaults to $config['url_base'] . 'public/'. This should be absolute URL.
    'pdo' => new PDO('mysql:dbname=test;host=192.168.84.3;charset=utf8', 'root', 'root') //本地的数据库配置,只支持PDO
);

在test数据库上运行/xhprof/setup/database.sql,创建性能检测相关的表结构。
由于XHProf会去github上检测版本,国内访问较慢,建议不要检测。更改/xhprof/includes/bootstrap.inc.php如下:

1
2
3
4
5
curl_setopt_array($ch, array(
    CURLOPT_URL => 'http://192.168.84.2:8502/version.json', //本地的XHProf.io站点下面
    CURLOPT_HEADER => FALSE,
    CURLOPT_RETURNTRANSFER => TRUE
));

然后更改php.ini配置,在最后加上以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
;xhprof
[xhprof]
extension=xhprof.so;
xhprof.output_dir=/tmp/xhprof
; Automatically add files before PHP document.
; XHProf.io站点下的prepend.php
auto_prepend_file = /usr/local/nginx/xhprof/inc/prepend.php
; Automatically add files after PHP document.
; XHProf.io站点下的append.php
auto_append_file = /usr/local/nginx/xhprof/inc/append.php

auto_prepend_file为每次php脚本运行前,自动加载并运行的文件;auto_append_file为每次php脚本运行后,自动加载并运行的文件。这样可以省去每次在需要检测的php文件里面写xhprof_enable/xhprof_disable等调用代码,不必更改原有代码(无侵入)。
注意:如果你访问了php页面却收集不到情况,可能是你的代码里面写了exit/die终止了程序执行,导致auto_append_file未加载执行,去掉exit/die就可以了。另外,如果提示:Unexpected system behaviour,可能是数据库连接不上,PDO、mbstring扩展未安装,响应数据里面带有错误信息的等等。

重启php-fpm:

1
2
#重启php-fpm
kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`

xhprof1

访问该服务器上php页面,即可以在http://192.168.84.2:8502/看到检测情况。
xhprof5
xhprof4
xhprof6

参数说明
Inclusive Time 包括子函数所有执行时间。
Exclusive Time/Self Time 函数执行本身花费的时间,不包括子树执行时间。
Wall Time 花去了的时间或挂钟时间。
CPU Time 用户耗的时间+内核耗的时间
Inclusive CPU 包括子函数一起所占用的CPU
Exclusive CPU 函数自身所占用的CPU

参考链接:
给CentOS6.3 + PHP5.3 安装PHP性能测试工具 XHProf-0.9.2 
xhprof.io/INSTALL.md
php auto_append_file

发表在 php | 留下评论

Windows环境下生成Apple证书教程,包含P12以及mobileprovision文件

准备OpenSSL

访问:http://slproweb.com/products/Win32OpenSSL.html 。并下载Win32 OpenSSL v1.0.1c Light版本(注意:版本可能会升级),如果您运行OpenSSL有问题,还需要下载Visual C++ 2008 Redistributables安装。

IOS SIGN STEP 1.png

安装OpenSSL完毕后,默认在C盘的OpenSSL-Win32。

IOS SIGN STEP 3.png

生成CSR请求文件

进入Windows的命令行(WIN+R,进入运行)。开始输入各个命令.

cd C:\OpenSSL-Win32\bin\

set RANDFILE=.rnd

set OPENSSL_CONF=C:\OpenSSL-Win32\bin\openssl.cfg

openssl genrsa -out my.key 2048

openssl req -new -key my.key -out my.certSigningRequest -subj "/emailAddress=myemail@sample.com,CN=Common Name,C=CN"

如图: IOS SIGN STEP 4.png

获取CER证书

将生成的certSigningRequest文件上传到Apple的开发者相关页面(例如开发者证书、推送证书等)https://developer.apple.com/ios/manage/certificates/team/distribute.action

AppStoreNew 8.png

将最后生成的cer文件改个名字后放到C:\OpenSSL-Win32\bin\目录中,和之前生成的文件放在一起。

IOS SIGN STEP 6.png

导出p12文件

P12文件包含了证书的密钥和公钥,可以方便迁移到其他电脑上。 最后在刚才的环境中运行命令行(如果之前命令行窗口被关了,还是要重新执行一遍开始的几条set环境配置命令):

openssl x509 -in my.cer -inform DER -out my.pem -outform PEM

openssl pkcs12 -export -inkey my.key -in my.pem -out my.p12 -password pass:111111

如图:

IOS SIGN STEP 7.png

这样就生成了密码为111111,文件名为my.p12的密钥文件。您可以将这个文件导入MAC电脑,也可以上传到追信魔盒的IOS代签名区。

批处理工具

为了方便生成,我们提供了写好的BAT批处理文件。

OpenSSL生成证书批处理文件:文件:MyCerRequest.zip

解压缩到OpenSSL的bin目录下,生成my.certSigningRequest时运行MyRequest.bat;在下载并放置好my.cer文件后,运行MyP12.bat即可生成my.p12文件。

如何生成mobileprovision文件?

申请发布(Distribution)描述文件

在“Certificates, Identifiers & Profiles”页面“Provisioning Profiles”下选择“Distribution”,可查看到已申请的所有发布(Distribution)描述文件,点击右上角的加号可创建新描述文件:

打开“Add iOS Provisioning Profile”页面,在“Development”栏下选中“iOS App Development”:

点击“Continue”按钮,打开“App ID”选择页面,选择要使用的“App ID”(如之前创建的“io.dcloud.HBuildApp”),点击“Continue”:

打开“Select certificates”页面,选择前面创建的发布证书:

点击“Continue”,输入描述文件的名称(如“HBuilderProfileDistribution”):

点击“Generage”,生成描述文件成功:

点击“Download”下载保存开发描述文件(如HBuilderProfileDistribution.mobileprovision)。

发表在 IOS&OS | 留下评论

安装svn服务器过程,以及出现svn “cannot set LC_CTYPE locale”的解决

yum install -y subversion

mkdir /opt/svn

svnadmin create /opt/svn/davesvn

pwd /opt/svn/davesvn/conf

#创建版本库后,在这个目录下会生成3个配置文件:

#(1)svnserve.conf: svn服务配置文件下。

#(2)passwd: 用户名口令文件。

#(3)authz: 权限配置文件。

 

vi svnserve.conf

anon-access=none

auth-access=write

password-db=passwd

 

vi passwd

[users]

#<用户1> = <密码1>

#<用户2> = <密码2>

#运行svn

svnserve -d -r /opt/svn

#-d表示后台运行

#-r 指定根目录是 /opt/svn

出现以下警告提示的解决办法:

$ svn
svn: warning: cannot set LC_CTYPE locale
svn: warning: environment variable LANG is en_US.UTF-8
svn: warning: please check that your locale name is correct
Type svn help for usage.

    
    解决方法很简单,修改/etc/profile:

sudo vi /etc/profile
加入一行:
export LC_ALL=C
source /etc/profile
发表在 linux | 留下评论