俗可耐

俗的耐人寻味


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

  • 搜索

解决CentOS7上执行Curl特别慢的问题

发表于 2017-12-02

概述

之前项目新部署的服务器刚换为CentOS7时,发现项目延时增高不少,后来发现是由于请求第三方接口时curl过慢导致的,问题CentOS版本为7.1.1503,需要通过升级libcurl类库来解决。

查找问题

查找问题时通过执行以下命令来测试curl各过程的速度:

1
curl -o /dev/null -s -w %{time_namelookup}::%{time_connect}::%{time_starttransfer}::%{time_total}::%{speed_download}"\n" 'http://www.baidu.com'

得到输出:

1
0.156::0.159::0.163::0.163::14565.000

各项数据的含义为:

字段 含义
time_namelookup DNS 解析域名的时间
time_connect client和server端建立TCP连接的时间
time_starttransfer 从client发出请求,到web的server响应第一个字节的时间
time_total client发出请求,到web的server发送会所有的相应数据的时间
speed_download 下载速度,单位byte/s

从上面的数据可以看到在域名解析这一步就耗费了大量的时间,所以导致整个curl的请求变慢。

解决方案

最后通过Google找到一篇文章里的解决方法,就是升级libcurl。

升级libcurl

1
mkdir /tmp/libcurl && cd /tmp/libcurl && wget http://dl.fedoraproject.org/pub/archive/fedora/linux/updates/19/x86_64/curl-7.29.0-27.fc19.x86_64.rpm && wget http://dl.fedoraproject.org/pub/archive/fedora/linux/updates/19/x86_64/libcurl-7.29.0-27.fc19.x86_64.rpm && wget http://dl.fedoraproject.org/pub/archive/fedora/linux/updates/19/x86_64/libcurl-devel-7.29.0-27.fc19.x86_64.rpm && yum -y install *.fc19.x86_64.rpm

重启php-fpm

如果是PHP项目的话,升级libcurl之后要重启fpm。重启命令为:

1
kill -USR2 `cat /opt/php-*.*.*/var/run/php-fpm.pid`

注: pid文件的位置根据服务器情况进行修改,也可以直接查出php-fpm的master进程id后,kill -USR2 pid。

PHP Ctype函数

发表于 2017-11-27

概述

ctype扩展在PHP4.2.0版本后就默认开启了,此扩展提供了一系列检测字符、字符串是否符合某种规则的函数,在一些场景写使用特别方便。

常用函数列表

ctype_alnum

检测参数是否仅包含字母或数字

1
bool ctype_alnum ( string $text )

可以用在检测用户名的地方,如果需要允许使用下划线_和短横线-等字符,可先用str_replace进行替换后再检测:

1
2
3
if(!ctype_alnum(str_replace(['_', '-'], '', $username))) { 
echo 'invalid.';
}

ctype_alpha

检测参数是否仅包含字母,在标准的locale下,字母指[a-zA-Z]。

1
bool ctype_alpha ( string $text )

ctype_digit

检测参数是否仅包含数字(10进制)字符[0-9]

1
bool ctype_digit ( string $text )

ctype_lower、ctype_upper

分别检测参数中是否仅包含小写字母或者大写字母

1
2
bool ctype_lower ( string $text )
bool ctype_upper ( string $text )

ctype_xdigit

检测参数是否仅包含十六进制字符[0-9a-fA-F]

1
bool ctype_xdigit ( string $text )

PHP合并数组

发表于 2017-11-27

概述

php合并数组一般有三个方法

  1. 使用array_merge函数
  2. 使用array_merge_recursive函数
  3. 使用操作符+
阅读全文 »

PHP遍历文件目录

发表于 2017-11-26

虽然目前大部分公司使用PHP的场景不会去读取目录,但在一些笔试题中还是会出现这样的题目,算是考基本功的一些体现吧。

知识点:

  1. scandir
  2. opendir
  3. DirectoryIterator

最方便的方法是使用语言自带的scandir函数:

1
2
$files = scandir('/usr/local/etc/nginx');
print_r($files);

阅读全文 »

B-树

发表于 2017-11-16

描述

B树(英语:B-tree)是一种自平衡的树,能够保持数据有序。这种数据结构能够让查找数据、顺序访问、插入数据及删除的动作,都在对数时间内完成。B树,概括来说是一个一般化的二叉查找树(binary search tree),可以拥有多于2个子节点。与自平衡二叉查找树不同,B树为系统大块数据的读写操作做了优化。B树减少定位记录时所经历的中间过程,从而加快存取速度。B树这种数据结构可以用来描述外部存储。这种数据结构常被应用在数据库和文件系统的实现上。 –摘自维基百科

B树的阶

B树每个节点最多包含k个孩子,k被成为B树的阶。k的大小取决于磁盘页的大小。

阅读全文 »

sql_mode之only_full_group_by

发表于 2017-09-17

起因

最近将一个项目的MySQL升级到5.7,出现类似下面的错误:

ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘yourdb.yourtable.yourfield’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

说明

这个是由于MySQL在5.7版本中添加了一个sql_mode: ONLY_FULL_GROUP_BY,当配置了此sql_mode后,select语句中要查询的字段必须严格是group by语句中的字段或者是聚合函数。

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.20 |
+-----------+
# 创建数据库
mysql> create database sql_test charset utf8mb4;
# 创建user表
mysql> create table user (id int(11) unsigned auto_increment primary key, account varchar(50));
# 创建order表
mysql> create table user_order (id int(11) unsigned auto_increment primary key, user_id int(11) unsigned, product_id int(11), order_money float);
# 插入测试数据
mysql> insert into user (account) values ('zhangsan'), ('lisi'), ('wangwu'), ('zhaoliu');
mysql> insert into user_order(user_id, product_id, order_money) values (1, 1, 1), (1, 1, 2), (2, 2, 5);
# 测试查询
mysql> select b.user_id, a.account, sum(b.order_money) as total_money from user_order b left join user a on b.user_id = a.id group by a.id;
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'sql_test.b.user_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

解决

修改sql

将需要查询的列加入到group by语句中。

1
2
3
4
5
6
7
mysql> select b.user_id, a.account, sum(b.order_money) as total_money from user_order b left join user a on b.user_id = a.id group by b.user_id, a.account;
+---------+----------+-------------+
| user_id | account | total_money |
+---------+----------+-------------+
| 1 | zhangsan | 3 |
| 2 | lisi | 5 |
+---------+----------+-------------+

去除sql_mode中的ONLY_FULL_GROUP_BY

首先查询当前的sql_mode,分为全局的和当前session的。

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> select @@global.sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@global.sql_mode |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+

mysql> select @@session.sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@session.sql_mode |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+

然后对sql_mode进行修改

1
2
mysql> set global sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
mysql> set session sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

再执行初始的查询sql语句:

1
2
3
4
5
6
7
mysql> select b.user_id, a.account, sum(b.order_money) as total_money from user_order b left join user a on b.user_id = a.id group by a.id, a.account;
+---------+----------+-------------+
| user_id | account | total_money |
+---------+----------+-------------+
| 1 | zhangsan | 3 |
| 2 | lisi | 5 |
+---------+----------+-------------+

参考文章:

  • http://www.ywnds.com/?p=8184
  • stackoverflow
  • webkj
  • stackoverflow

PHP使用Composer安装第三方包库

发表于 2016-10-15 | 分类于 composer

配置文件composer.json

Composer的配置文件为项目根目录下的composer.json文件,对第三方库的依赖就配置在此文件中:在require或者require-dev中填入相应的库的名称以及版本需求。

1
2
3
4
5
6
7
8
9
{                             
"require" : {
"php": ">5.3.0",
"curl/curl": ">=1.4.0"
},
"require-dev": {
"phpunit/phpunit": "*"
}
}

安装依赖库到本地

composer install

在composer.json文件所在目录执行composer install, composer.json里填写的依赖包就会被下载到本地。

阅读全文 »

使用 Satis 创建 Composer 私有库

发表于 2016-09-03 | 分类于 composer

本文中使用satis搭建内部的composer仓库

创建Composer包

首先要先创建一个Composer包,可参考:创建你的第一个composer包

创建好之后,可以托管到任意的VCS仓库里,如:GIT、SVN等,也可以放在本地以Path的方式指定路径,更多可参考:点击这里

安装satis

1
2
3
$ composer create-project composer/satis --stability=dev --keep-vcs
$ mv satis private_composer_repo
$ cd private_composer_repo
阅读全文 »

创建你的第一个composer包

发表于 2016-09-02 | 分类于 composer

[参考文章:http://blog.jgrossi.com/2013/creating-your-first-composer-packagist-package/]

Composer是PHP的包管理器,我们可以很方便地使用别人共享的包,当然我们也可以创建自己的包以分享给其他人使用。本文就是教你如何创建自己的第一个composer包。

文件结构

首先创建如下目录结构及文件,talking_robot为项目的根目录:

1
2
3
4
5
6
7
0 talking_robot $ tree
.
└── src
└── TalkingRobot
└── Talk.php

2 directories, 1 file

编辑Talk.php文件

1
2
3
4
5
6
7
8
9
10
<?php
namespace TalkingRobot;

class Talk
{
public static function sayHello()
{
return 'Hello Composer';
}
}

开始 Composer

composer init

现在要在项目的根目录里创建一个composer.json的文件,我们可以手动创建,也可以在根目录里通过composer init命令来根据提示创建:

阅读全文 »

PHP Header跳转传递Post数据

发表于 2016-06-21 | 分类于 PHP

注: 说是Header方式跳转,其实不然。

我们有时需要在PHP中进行一些链接的跳转,经常使用如下方式:

1
header("Location: $url");

可是,此种方式无法满足跳转时,向目标链接中post数据,一种解决方法就是输出一段含有表单HTML网页,在页面里通过JS提交表单的方式模拟Post跳转。

1
2
3
4
5
6
7
8
9
10
<?php
echo <<<EOT
<form name='fr' action='{$url}' method='POST'>
<input type='hidden' name='field1' value='{$field1}'>
<input type='hidden' name='field2' value='{$field2}'>
</form>
<script type='text/javascript'>
document.fr.submit();
</script>
EOT;
12

greatcl

13 日志
2 分类
16 标签
GitHub
友情链接
  • VlugarNote
  • MacTalk
  • Picksomething
  • fookwood
© 2016 — 2020 greatcl
备案号 沪ICP备16037985号-1