关于微信支付

微信支付的官方文档:
https://pay.weixin.qq.com/wiki/doc/api/index.html
php的sdk下载地址:
https://pay.weixin.qq.com/wiki/doc/api/download/WxpayAPI_php_v3.zip

这里文档和sdk都比较详细,基本上换掉sdk的证书文件夹和配置文件就可以使用,但是还是有不少坑

首先要在公众平台上设置测试授权目录,还有测试白名单,这个就不细说了

重点说下实际中可能会遇到的问题

第一个是错误码60

是因为https证书校验失败

解决方法
WxPay.Api.php537行

1
2
3
4
5
6
7
8
9
10
11
12
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验

//改为
if (stripos($url, "https://") !== FALSE) {
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
} else {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);//严格校验
}

第二个是错误码28

Read More

Redis-消息队列和异步处理

之前公司有个app的项目,里面有即时聊天,需要一个存放聊天记录的接口

每一条聊天记录都直接存放mysql,来一条insert一条,量不大还好说,基本都能应付。但是如果量特别大,一天几百万条,上千万条,这个insert操作就会执行几百万次,会不会响应不过来?用户体验会不会降低?

类似的案例还有

一个帖子,用户每访问一次就要set visitor = visitor+1,每天访问上百万次,就要update上百万次,,这个聊天记录表又是访问请求最高的,会不会锁死?

其实这些都可以优化

Redis读的速度是110000次/s,写的速度是81000次/s 。

第一个案例里面可以用Redis做消息中转站,用一个list存放我们的聊天记录。

利用Redis的性能,我们可以把这些请求都写到缓存。然后后台启用一个crontab定时任务,每分钟执行,把队列里的数据拿出来,存到MySQL,甚至可以每10秒,5秒做一次操作

这里给大家一个简单的demo

Read More

Redis用法和总结

什么是Redis

MySQL:关系型数据库

NoSQL:非关系型的数据库,数据之间无关系,无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式,有非常高的读写性能,尤其在大数据量下,表现非常优秀。

  • 键值(Key-Value)存储数据库(Redis)
  • 列存储数据库
  • 文档型数据库(MongoDb)
  • 图形(Graph)数据库

Redis 就是一个 Key-Value 存储系统。支持的数据类型包括string(字符串)、hash(哈希)、list(链表)、set(集合)和zset(有序集合)等等。

Redis的性能

官方的bench-mark数据:
测试完成了50个并发执行100000个请求。
设置和获取的值是一个256字节字符串。
结果:读的速度是110000次/s,写的速度是81000次/s 。

Redis的持久化

Redis运行在内存中但是可以持久化到磁盘

Redis提供了多种不同级别的持久化方式:一种是RDB,另一种是AOF.

RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照。当redis需要做持久化时,redis会fork一个子进程;子进程读出数据并将数据写到磁盘上一个临时RDB文件中;当子进程完成写临时文件后,将原来的RDB替换掉,这样的好处就是可以copy-on-write,缺点就是在redis异常死掉时, 最近的数据会丢失

AOF redis每执行一个修改数据的命令,都会把它添加到aof文件中,当redis重启时,将会读取AOF文件进行“重放”以恢复到redis关闭前的最后时刻。

Redis 可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整

Redis为什么这么快

1)绝大部分请求是纯粹的内存操作(非常快速)
2)采用单线程,避免了不必要的线程切换开销
3)非阻塞IO

Read More

mysql行级锁处理小规模并发实现抢购秒杀

MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁;InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。

1表级锁:直接锁定整张表,在你锁定期间,其它进程无法对该表进行写操作。如果你是写锁,则其它进程则读也不允许
2行级锁:仅对指定的记录进行加锁,这样其它进程还是可以对同一个表中的其它记录进行操作。
3页面锁:表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。

Read More

PHP 递归函数的应用(三) 层级结构数据的树状输出

还是以应用一的数组为例

1
2
3
4
5
6
7
8
9
10
11
12
$data = array(
0 => array('id' => '1', 'pid' => 0, 'name' => '一级栏目一'),
1 => array('id' => '2', 'pid' => 1, 'name' => '二级栏目一'),
2 => array('id' => '3', 'pid' => 1, 'name' => '二级栏目二'),
3 => array('id' => '4', 'pid' => 2, 'name' => '三级栏目一'),
4 => array('id' => '5', 'pid' => 2, 'name' => '三级栏目二'),
5 => array('id' => '6', 'pid' => 3, 'name' => '三级栏目三'),
6 => array('id' => '7', 'pid' => 3, 'name' => '三级栏目四'),
7 => array('id' => '8', 'pid' => 0, 'name' => '一级栏目二'),
8 => array('id' => '9', 'pid' => 8, 'name' => '二级栏目三'),
9 => array('id' => '10', 'pid' => 7, 'name' => '四级栏目一'),
);

输出结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
一级栏目一

├─ 二级栏目一

│ ├─ 三级栏目一

│ └─ 三级栏目二

└─ 二级栏目二

├─ 三级栏目三

└─ 三级栏目四

└─ 四级栏目一

一级栏目二

└─ 二级栏目三

还能以select形式展现

Read More