Mr.Blog


  • 首页

  • 归档

  • 标签

  • 分类

  • 搜索

服务端及时推送消息给客户端

发表于 2018-04-24 | 分类于 WorkerMan

场景:

  1. 在商户后台, 若有用户下单, 实时通知商户[Ajax 轮询, 并不是实时]
  2. 后台批量导入产品, 每成功导入一个, 就通知前台, 显示导入成功

实现原理:

  1. 服务端 建立一个 Websocket Worker, 用于维护客户端长连接
  2. 服务端 Websocket Worker 启动后, 内部建立一个 Text Worker, 由于 Websocket Worker 与 Text Worker 是同一个进程, 方便共享客户端连接
  3. 某个独立的后台系统, 通过 Text 协议与 Text Worker 通讯
  4. Text Worker 操作 Websocket Worker 完成数据推送

执行流程:

  1. 启动 start.php, 运行命令:php start.php start -d
  2. 浏览器打开 client.html, 支持开启多个, 等于绑定UID, 并接收服务端推送
  3. 运行 send.php, 点击下单, client.html 会收到服务端推送的消息
阅读全文 »

MySQL 自定义函数

发表于 2018-04-24 | 分类于 MySQL

自定义函数获取两点之间距离, Symfony 定义GLength 的DQL

1
2
3
4
#语法
GLength(GeomFromText(CONCAT('LineString(', in_from_x, ' ', in_from_y, ',', in_to_x, ' ', in_to_y, ')'))) / 0.0000092592666666667
#样例
GLength(GeomFromText(CONCAT('LineString(25.44433087228 119.01171736304,', user_latitude, ' ', user_longitude, ')'))) / 0.0000092592666666667

phpmyadmin 导入大文件

发表于 2018-04-24 | 分类于 PHP
  1. 重命名根目录下的 config.simple.inc.php 为 config.inc.php
  2. 根目录新建 import 和 save 文件夹
  3. 将 SQL文件上传到 import 目录下
  4. 进入 phpmyadmin -> 导入 -> 选择 从网站服务器上传文件夹import/中选择
    1
    2
    3
    4
    # config.inc.php
    <?php
    $cfg['UploadDir'] = 'import';
    $cfg['SaveDir'] = 'save';

Symfony 整合 GatewayWorker 碰到的问题

发表于 2018-04-24 | 分类于 Symfony

Error while sending QUERY packet 错误

MySQL 的 max_allowed_packet 太小, 在 [mysqld] 下修改 max_allowed_packet, 然后重启MYSQL

1
2
3
4
5
6
7
8
9
10
[mysqld]
max_allowed_packet=16M

mysql> SHOW VARIABLES LIKE 'max_allowed_packet';
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| max_allowed_packet | 16777216 |
+--------------------+----------+
1 row in set

实际错误可能是 MySQL server has gone away, 设置 MySQL 的 wait_timeout = 10, 并且每次操作后, 主动关闭数据库连接
wait_timeout 配置
Symfony 中的处理方式, 每次获取 Repository 时, 都需验证 MySQL 连接状态, 若无法ping通, 则断开重连

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* Gets a named entity manager.
*
* @param string $name The entity manager name (null for the default one)
* @return \Doctrine\ORM\EntityManager
*/
public static function getEntityManager($name = null)
{
if (!isset(self::$em)) {
self::$em = self::getService('doctrine')->getManager($name);
}

if (!self::$em->isOpen()) {
$doctrine = self::getService('doctrine');
$doctrine->resetManager($name);
self::$em = $doctrine->getManager($name);
}

$conn = self::$em->getConnection();
if ($conn->ping() === false) {
$conn->close();
$conn->connect();
}

return self::$em;
}
阅读全文 »

Symfony3 自定义 Repository Factory

发表于 2018-04-22 | 分类于 Symfony

需求:CommonBundle 存放数据库表的映射/实体/持久类, 现有 AdminBundle 和 ApiBundle 使用同一数据库, 现在需要将两个Bundle的Repository分开, 比如有个表为 User, 则需要两个 Repository, 在 CommonBundle 下新建 Admin/UserRepository.php 和 Api/UserRepository.php, 即将两个Bundle的Repository放在不同的目录下

阅读全文 »

MySQL 解决死锁

发表于 2018-04-02 | 分类于 MySQL

模拟死锁 - 第一步(创建表,并插入数据)

1
2
3
4
5
6
7
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(16) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

INSERT INTO test(title) VALUES('A'),('B');

模拟死锁 - 第二步(会话一:开启事务,更新不提交)

1
2
begin;
UPDATE test SET title = 'C' WHERE id = 1;

模拟死锁 - 第三步(会话二:开启事务,更新同一条数据)

经过一段时间后,提示 Lock wait timeout exceeded; try restarting transaction

1
UPDATE test SET title = 'D' WHERE id = 1;

解决方法

1
2
3
4
#查看未提交的事务,trx_mysql_thread_id 为线程ID,比如查询出来的 trx_mysql_thread_id = 853
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
#执行 kill 线程ID
KILL 853

相关命令

1
2
3
4
5
6
#显示哪些线程正在运行
SHOW PROCESSLIST;
#查看当前锁定的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
#查看当前等待的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

MySQL 下 Sleep 过多解决方法

发表于 2018-03-20 | 分类于 MySQL
配置 wait_timeout 和 interactive_timeout
1
2
3
4
5
6
7
[mysqld]
#默认值:28800秒(8小时),服务器关闭非交互连接之前等待活动的秒数
#在线程启动时,根据全局 wait_timeout 值或全局 interactive_timeout 值初始化会话 wait_timeout 值,取决于客户端类型(由mysql_real_connect()的连接选项CLIENT_INTERACTIVE定义)
wait_timeout=10
#默认值:28800秒(8小时),服务器关闭交互式连接前等待活动的秒数
#交互式客户端定义为在mysql_real_connect()中使用CLIENT_INTERACTIVE选项的客户端,interactive的值如果设置的和wait_timeout不同,在交互模式下(CLIENT_INTERACTIVE),interactive_timeout 会覆盖 wait_timeout
interactive_timeout=10
代码中程序执行完毕,应显式调用 mysql_close
MySQL 相关命令
1
2
3
4
5
6
7
8
9
10
11
12
13
#查看连接数, 每有一个新连接请求, max_connections++, 每中止一个连接 max_connections--
show processlist;
mysql> show processlist;
+----+------+---------------------+-----+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+---------------------+-----+---------+------+-------+------------------+
| 1 | root | 192.168.227.1:53897 | ymd | Query | 0 | init | show processlist |
| 9 | root | 192.168.227.1:55732 | ymd | Sleep | 8720 | | NULL |
+----+------+---------------------+-----+---------+------+-------+------------------+
2 rows in set

# Command 当前连接执行的命令, Time 连接持续时间
# 当 Command = Sleep, 则 Time 持续时间为 wait_timeout 设置的值, wait_timeout 秒后就会关闭连接
1…111213…15
Mr

Mr

懒........

102 日志
21 分类
56 标签
RSS
Links
  • Novnan
  • 挨踢Blog
  • Eagle
  • Timber
  • 谢炳南
© 2020 — 2021 Mr
0%