• 分布式Nginx缓存清理(PHP的socket编程)


    最近,公司要使用康乐的几台自建CDN换成Nginx,在缓存配置上不会有很多的问题,纠结的问题是:Nginx的如何批量进行缓存清理

    我们都知道Nginx提供了一个第三方的模块"nginx ngx_cache_purge",作为缓存清理的一个接口,进行Nginx缓存清理,但是这个接口只能基于url进行清理,这几乎是一个致命的缺点。

    因为线上web应用:

        1. url很多

        2. 完全url我们几乎是不可能知道

        3. 如果需要整站清理,那如果一个url,一个url清理,几乎是不可能完成的任务

    为了有效清理Nginx缓存,我整理出了一个思路:

        1. 在每台CDN上面跑一个清理缓存的daemon(这里我是使用php的socket编写的),原理就是删除缓存目录下的所有文件。

        2. 使用一台控制机,这台控制机通过web的php页面,发送指令给CDN上的daemon,由daemon把CDN上面的所有缓存文件删除。

    php_daemon.php

    <?php
    set_time_limit(0);


    $ip = '192.168.182.128';
    $port = 10000;

    if(($sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) < 0) {
    echo "socket_create() 失败的原因是:".socket_strerror($sock)." ";
    }

    if(($ret = socket_bind($sock,$ip,$port)) < 0) {
    echo "socket_bind() 失败的原因是:".socket_strerror($ret)." ";
    }

    if(($ret = socket_listen($sock,4)) < 0) {
    echo "socket_listen() 失败的原因是:".socket_strerror($ret)." ";
    }

    include('cache_all.php');
    do {
    if (($msgsock = socket_accept($sock)) < 0) {
    echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . " ";
    break;
    } else {
    $msg="测试成功! ";
    socket_write($msgsock, $msg, strlen($msg));

    $buf = socket_read($msgsock,8192);
    if ($buf == 'clear'){
    delete_all('/home/cache');
    }


    }

    socket_close($msgsock);

    }while (true);
    ?>

     cache_all.php

    function delete_all($dir)
    {
    $files=array();
    $result=array();
    if(is_dir($dir))
    {
    if($handle=opendir($dir))
    {
    while(($file=readdir($handle))!==false)
    {
    if($file!="." && $file!="..")
    {
    if(is_dir($dir."/".$file))
    {
    $files[$file]=delete_all($dir."/".$file);
    }
    else
    {
    $files[]=$dir."/".$file;

    unlink($dir."/".$file);
    }
    }
    }
    closedir($handle);
    }
    }
    }

    使用php命令行,后台执行php_daemon.php: nohup /usr/local/webserver/php/bin/php php_daemon.php &

    查看监听是否成功:netstat -nl |grep 10000

    tcp 0 0 192.168.182.128:10000 0.0.0.0:* LISTEN                       #监听成功

    web客户端代码:test.php

    <?php
    header("Content-Type:text/html;charset=utf-8");
    error_reporting(E_ALL);
    set_time_limit(0);
    echo "<h2>TCP/IP Connection</h2> ";

    $port = 10000;
    $ip = "192.168.182.128";

    /*
    +-------------------------------
    * @socket连接整个过程
    +-------------------------------
    * @socket_create
    * @socket_connect
    * @socket_write
    * @socket_read
    * @socket_close
    +--------------------------------
    */

    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    if ($socket < 0) {
    echo "socket_create() failed: reason: " . socket_strerror($socket) . " ";
    }else {
    echo "OK. ";
    }

    echo "试图连接 '$ip' 端口 '$port'... ";
    $result = socket_connect($socket, $ip, $port);
    if ($result < 0) {
    echo "socket_connect() failed. Reason: ($result) " . socket_strerror($result) . " ";
    }else {
    echo "连接OK ";
    }

    $in="clear";

    if(!socket_write($socket, $in, strlen($in))) {
    echo "socket_write() failed: reason: " . socket_strerror($socket) . " ";
    }else {
    echo "发送指令成功";
    }

    while($out = socket_read($socket, 8192)) {
    echo "接收服务器回传信息成功! ";
    echo "接受的内容为:",$out;
    }


    echo "关闭SOCKET... ";
    socket_close($socket);
    echo "关闭OK ";
    ?>

     通过浏览器访问test.php:

    连接成功,查看缓存目录,确定缓存是否清理完成...................

  • 相关阅读:
    【贪心+DFS】D. Field expansion
    【贪心+博弈】C. Naming Company
    【dp】E. Selling Souvenirs
    【multimap的应用】D. Array Division
    内存变量边界对齐
    3.8 高级检索方式(二)
    3.7 高级检索方式(一)
    openGL加载obj文件+绘制大脑表层+高亮染色
    3.6 Lucene基本检索+关键词高亮+分页
    3.5 实例讲解Lucene索引的结构设计
  • 原文地址:https://www.cnblogs.com/zhaojonjon/p/5691089.html
Copyright © 2020-2023  润新知