一周技术小结 1

title: 一周技术小结 1
date: 2017-9-4 21:22:21

tcp 保存连接 auth 信息

在我的 服务器开发系列 1 遇到了一个问题: tcp client 在连接后, 需要先发送一个 auth msg 进行认证, 认证不通过会直接断掉, 所以需要保存当前连接的状态.

当时提供了 2 种办法:

  • 用 redis 来存储
  • 使用 swoole 的共享内存解决方案: swoole table

但是, 真的是自己知道的「太少」, swoole wiki 上面就有解决方案: swoole_server中内存管理机制

$serv = new swoole_server("0.0.0.0", 9999);
$serv->authFlag = []; // 认证成功后存储

$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) {
    // auth 判断
    if (!isset($serv->authFlag[$fd])) {
        // 需要 auth 认证
    }
}

分表

有 2 张表数据增长很快, 数据量已经百万级了, 而 mysql 表的容量在千万级, 可能就满足不了服务器对性能的要求了,「分库分表」势在必行了, 先做分表方案:

$table = 'game_'. ($uid % 100); // 按照用户 id 取模, 将表分成 100 份

在分表的同时, 也会有一张表, 来存储所有数据, 方便「后台管理」等系统获取数据, 不过这张表会定期清理:

CREATE TABLE game_tmp LIKE game;
RENAME TABLE game game_201709;
RENAME TABLE game_tmp game;

并发「上机游戏」的简单实现

要解决并发导致的资源争抢问题, 很容易想到各种锁: 读写锁 / 排它锁 / 自旋锁. 但是, 其实只要保证「原子性」操作, 就可以自己来不加锁实现, 下面提供 2 种基于 redis 的方案:

public static function incr($key)
{
    $res = static::getEngine()->incr($key); // redis incr command
    if ($res == 1) { // 返回 1 表示此进程竞争到了此资源
        return true;
    }
    return false; // 返回大于 1 说明没有竞争到
}

同理, 还有 redis setnx command

pr: pull request

玩 github 就会对这个词比较熟悉了, 这周遇到了 2 件事和这有关.

  • 工作开发中使用 pr: 首先 fork 一份原项目, 在 fork 出来的项目上就可以「随意」了; 提交代码后就可以提 pr 了, 在 pr 里面可以指定 code review 的各位大大

  • 贡献开源: 最近 swoole 用的比较多, 使用到了eaglewu/swoole-ide-helper 项目, 遇到改进的地方, 就使用 pr 来贡献一点自己的力量

mysql 问题简单排查

遇到 mysql 出问题了, 可以简单使用下面方法排查试试看:

-- mysql 上当前连接的进程
SHOW PROCESSLIST 
 -- information_schema 非常有用
SELECT * FROM information_schema.`PROCESSLIST`

-- 通过上面查询出来的 id 杀掉进程
kill id 

用这个方法找到了外包写的问题代码.

mysql 处理 json 数据

很早就知道 mysql5.7 支持 json, 不过一直没机会使用, 这次刚好碰上了: 原来的服务器用 nodejs 写的, 在 mysql 中用了很多 json 字段, 这就造成使用时需要 json encode / json decode, 作为服务器怎么能忍, 所以需要进行「数据迁移」.

在没有 mysql json 支持之前:

  • 原表添加新字段来保存 json decode 后的数据
  • 新建临时表, 用来保存 json decode 后的数据
  • 跑脚本, 读取数据, json decode, 写入临时表
  • 临时表和原表 join 来更新新字段
-- 临时表, 用来迁移数据
DROP TABLE IF EXISTS db_tmp;
CREATE TABLE `db_tmp` (
`id`  BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
intv1 BIGINT NOT NULL DEFAULT 0,
intv2 BIGINT NOT NULL DEFAULT 0,
intv3 BIGINT NOT NULL DEFAULT 0,
string1 VARCHAR(255) NOT NULL DEFAULT '',
string2 VARCHAR(255) NOT NULL DEFAULT '',
string3 VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
public function gameSession()
{
    $begin = microtime();

    $dbTmp = 'db_tmp';
    DbClient::execute("TRUNCATE $dbTmp");
    $table = 'game';
    $count = DbClient::findColumn("SELECT COUNT(*) FROM $table");
    $id = 0;
    $limit = 2000; // 一定要注意分页
    while ($count>0) {
        $rows = DbClient::findAll("SELECT id,record_text FROM $table WHERE id>$id LIMIT $limit");

        $data = [];
        foreach ($rows as $v) {
            $arr = json_decode($v['record_text'], true);
            $videoUrl = $arr['video_url'] ?? '';
            $data[] = [$v['id'], $videoUrl];
        }
        $id = $v['id'];

        $options = ['column_names' => ['id', 'string1']];
        DbClient::insertAll($dbTmp, $data, $options);
        echo "table:$table id:$id limit:$limit\n";

        $count -= $limit;
    }

    echo "time take: " . (microtime() - $begin) . "\n";
}

但是, 我们有了 json 函数支持后:

-- mysql json function
UPDATE game SET video_url=trim(BOTH '"' FROM json_extract(record_text, '$.video_url')) WHERE record_text is NOT NULL;

而且, 实测下来, 使用 2000 来分页, 脚本需要 2 分钟, 而 json 函数不到 5s

计算机基础真差

  1. 说一下 top k 算法(大量数中求最大 k 个数)
  2. mysql 的索引是什么数据结构? 说一下 B+ Tree . explain 各字段什么意思, explain 后的语句能直接线上用么(强制指定索引)? where a=xxx and b>xxx order by c 如何建索引?
  3. 说一下 epoll
  4. 说一下 swoole 的进程模型? 网络数据如何流转的? 进程间如何通信的? 使用 unix socket 通信其实是起的 udp server, 会有什么问题?
  5. https 协议看过没? 说一下 https 协议以及网络数据如何交互的

再说一下以前遇到的:

  1. 说一下快排
  2. 说一下 mysql 服务器的架构, mysql 查询优化是什么?
  3. 说一下 select poll epoll
  4. 服务器大量 502 怎么办
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容