swoole

use Swoole\Redis\Server;
//use Swoole\Coroutine\Redis;
$http = new swoole_http_server("0.0.0.0", 9501);
global $redis;
    $redis = new Redis();
	$redis->connect('127.0.0.1', 6379);
	$val = $redis->auth('foobared');
	
$http->set(array(
    'reactor_num' => 2, //reactor thread num
    'worker_num' => 4,    //worker process num
    'backlog' => 128,   //listen backlog
    'max_request' => 50,
    'dispatch_mode' => 1,
    //'daemonize' => 1,
));
$http->on('WorkerStart', function ($serv, $worker_id){
    global $argv;
    
   // var_dump($redis);
    if($worker_id >= $serv->setting['worker_num']) {
        swoole_set_process_name("php {$argv[0]} task worker");
    } else {
        swoole_set_process_name("php {$argv[0]} event worker");
    }
});
$http->on("start", function ($server) {
    echo "Swoole http server is started at http://127.0.0.1:9501\n";
   
});

$http->on("request", function ($request, $response) use ($redis){
    $response->header("Content-Type", "text/plain");
    $response->end(json_encode($request->post)."Hello World\n");
    
    	$a=$redis->get('aa');
    	var_dump($a);
    	posturl("http://182.61.42.187/aa.php",['a','b',$a]);
   
});

$http->start();

function posturl($url,$data){
	
	//$data=json_encode($post);
	$header=array("Content-Type:application/json;charset='utf-8'");
	$curl=curl_init();
	curl_setopt($curl,CURLOPT_URL,$url);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    curl_setopt($curl,CURLOPT_HTTPHEADER,$header);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($curl);
    curl_close($curl);
    echo $output;
    return '';
}


ab -n 1000 -c 100 -w http://182.61.42.187:9501/ >>test.txt

在这里插入图片描述
数据库连接池(Swoole\Coroutine\Channel和Swoole\Coroutine\MySQL)
最佳的方案是进行断线重连 。它的原理是:

(Swoole\Coroutine\Mysql和PDO等其他客户端同理, 此处简单举例)

mysql_query执行后检测返回值
如果mysql_query返回失败,检测错误码发现为2006/2013(这2个错误表示连接失败),再执行一次mysql_connect
执行mysql_connect后,重新执行mysql_query,这时必然会成功,因为已经重新建立了连接
如果mysql_query返回成功,那么连接是有效的,这是一次正常的调用

class MySQLPool {
    const POOL_SIZE = 10;

    protected $pool;
    protected $logger;
    static private $instances;

    var $host = '';
    var $username = '';
    var $password = '';
    var $dbname = '';
    var $port = 3306;
    var $pconnect = FALSE;
    var $db_debug = FALSE;
    var $char_set = 'utf8';
    var $dbcollat = 'utf8_general_ci';

    static public function instance($params) {
        if (!isset(self::$instances[$params])) {

            $params = empty($params) ? 'default' : $params;

            global $util_db_config;

            if (! isset($util_db_config[$params])) {
                throw new RuntimeException("You have specified an invalid database connection group.");
            }

            $config = $util_db_config[$params];

            $pool_size = isset($config['pool_size']) ? intval($config['pool_size']) : MySQLPool::POOL_SIZE;
            $pool_size = $pool_size <= 0 ? MySQLPool::POOL_SIZE : $pool_size;

            self::$instances[$params] = new MySQLPool($config, $pool_size);
        }

        return self::$instances[$params];
    }

    /**
     * MySQLPool constructor.
     * @param int $size 连接池的尺寸
     */
    function __construct($params, $size) {
        $this->logger = new Logger(array('file_name' => 'mysql_log'));

        foreach ($params as $key => $val) {
            $this->$key = $val;
        }

        $this->ycdb = new ycdb(["unix_socket" => ""]);

        $this->pool = new Swoole\Coroutine\Channel($size);

        for ($i = 0; $i < $size; $i++) {
            $mysql = new Swoole\Coroutine\MySQL();

            $ret = $this->connect($mysql);

            if ($ret) {
                $this->pool->push($mysql);
                $this->query("SET NAMES '".$this->char_set."' COLLATE '".$this->dbcollat."'");
            } else {
                throw new RuntimeException("MySQL connect error host={$this->host}, port={$this->port}, user={$this->username}, database={$this->dbname}, errno=[" . $mysql->errno . "], error=[" . $mysql->error . "]");
            }
        }
    }

    function insert($table = '', $data = NULL) {
        if (empty($table) || empty($data) || !is_array($data)) {
            throw new RuntimeException("insert_table_or_data_must_be_set");
        }

        $ret = $this->ycdb->insert_sql($table, $data);
        if (empty($ret) || $ret == -1) {
            throw new RuntimeException("insert_sql error [$table][".json_encode($data)."]");
        }

        $sql = $ret['query'];
        $map = $ret['map'];
        $sql = str_replace(array_keys($map), "?", $sql);
        $ret = $this->query($sql, array_values($map), $mysql);
        if (!empty($ret)) {
            return $mysql->insert_id;
        } else {
            return intval($ret);
        }
    }

    function replace($table = '', $data = NULL) {
        if (empty($table) || empty($data) || !is_array($data)) {
            throw new RuntimeException("replace_table_or_data_must_be_set");
        }

        $ret = $this->ycdb->replace_sql($table, $data);
        if (empty($ret) || $ret == -1) {
            throw new RuntimeException("replace_sql error [$table][".json_encode($data)."]");
        }

        $sql = $ret['query'];
        $map = $ret['map'];
        $sql = str_replace(array_keys($map), "?", $sql);
        $ret = $this->query($sql, array_values($map));
        return $ret;
    }

    function update($table = '', $where = NULL, $data = NULL) {
        if (empty($table) || empty($where) || empty($data) || !is_array($data)) {
            throw new RuntimeException("update_table_or_data_must_be_set");
        }

        $ret = $this->ycdb->update_sql($table, $data, $where);
        if (empty($ret) || $ret == -1) {
            throw new RuntimeException("update_sql error [$table][".json_encode($data)."][".json_encode($where)."]");
        }

        $sql = $ret['query'];
        $map = $ret['map'];
        $sql = str_replace(array_keys($map), "?", $sql);
        $ret = $this->query($sql, array_values($map));
        return $ret;
    }

    function delete($table = '', $where = NULL) {
        if (empty($table) || empty($where)) {
            throw new RuntimeException("delete_table_or_where_must_be_set");
        }

        $ret = $this->ycdb->delete_sql($table, $where);
        if (empty($ret) || $ret == -1) {
            throw new RuntimeException("replace_sql error [$table][".json_encode($where)."]");
        }

        $sql = $ret['query'];
        $map = $ret['map'];
        $sql = str_replace(array_keys($map), "?", $sql);
        $ret = $this->query($sql, array_values($map));
        return $ret;
    }

    function get($table = '', $where = array(), $columns = "*") {
        if (empty($table) || empty($columns)) {
            throw new RuntimeException("select_table_or_columns_must_be_set");
        }

        $ret = $this->ycdb->select_sql($table, $columns, $where);
        if (empty($ret) || $ret == -1) {
            throw new RuntimeException("select_sql error [$table][".json_encode($where)."][".json_encode($columns)."]");
        }

        $sql = $ret['query'];
        $map = $ret['map'];

        $sql = str_replace(array_keys($map), "?", $sql);
        $ret = $this->query($sql, array_values($map));
        return $ret;
    }

    function get_one($table = '', $where = array(), $columns = "*") {
        if (empty($table) || empty($columns)) {
            throw new RuntimeException("select_table_or_columns_must_be_set");
        }

        $where['LIMIT'] = 1;
        $ret = $this->get($table, $where, $columns);
        if (empty($ret) || !is_array($ret)) {
            return array();
        }

        return $ret[0];
    }

    private function connect(& $mysql, $reconn = false) {
        if ($reconn) {
            $mysql->close();
        }

        $options = array();
        $options['host'] = $this->host;
        $options['port'] = intval($this->port) == 0 ? 3306 : intval($this->port);
        $options['user'] = $this->username;
        $options['password'] = $this->password;
        $options['database'] = $this->dbname;
        $ret = $mysql->connect($options);
        return $ret;
    }

    function real_query(& $mysql, & $sql, & $map) {
        if (empty($map)) {
            return $mysql->query($sql);
        } else {
            $stmt = $mysql->prepare($sql);

            if ($stmt == false) {
                return false;
            } else {
                return $stmt->execute($map);
            }
        }
    }

    function query($sql, $map = null, & $mysql = null) {
        if (empty($sql)) {
            throw new RuntimeException("input_empty_query_sql");
        }

        try {
            $mysql = $this->pool->pop();
            $ret = $this->real_query($mysql, $sql, $map);

            if ($ret === false) {
                $this->logger->LogError("MySQL QUERY FAIL [".$mysql->errno."][".$mysql->error."], sql=[{$sql}], map=[".json_encode($map)."]");

                if ($mysql->errno == 2006 || $mysql->errno == 2013) {
                    //重连MySQL
                    $ret = $this->connect($mysql, true);
                    if ($ret) {
                        $ret = $this->real_query($mysql, $sql, $map);
                    } else {
                        throw new RuntimeException("reconnect fail: [" . $mysql->errno . "][" . $mysql->error . "], host={$this->host}, port={$this->port}, user={$this->username}, database={$this->dbname}");
                    }
                }
            }

            if ($ret === false) {
                throw new RuntimeException($mysql->errno . "|" . $mysql->error);
            }

            $this->pool->push($mysql);
            return $ret;
        } catch (Exception $e) {
            $this->pool->push($mysql);
            $this->logger->LogError("MySQL catch exception [".$e->getMessage()."], sql=[{$sql}], map=".json_encode($map));
            throw new RuntimeException("MySQL catch exception [".$e->getMessage()."], sql=[{$sql}], map=".json_encode($map));
        }
    }
}

swoole_process:进程间通过管道传输数据。(write,read)
swoole内存:lock,buffer,table,atomic,mmap,channel,serialize

执行完即释放
$table=new swoole_table(1024);
$table->column('id',$table::TYPE_INT,4);
$table->column('name',$table::TYPE_STRING,64);
$table->create();

$table->set('key1',['id'=>1,'name'=>'test']);

$table->get('key1');
$http=new swoole_http_server('0.0.0.0',9501);
        $http->pool='';
        $http->on('WorkerStart',function($http,$worker_id){
                $http->pool=new Swoole\Coroutine\Channel(10);
                for($i=0;$i<10;++$i){
                        $mysql=new Swoole\Coroutine\MySQL();
                        $ret=$mysql->connect([
						    'host' => '127.0.0.1',
						    'port' => 3306,
						    'user' => 'root',
						    'password' => '81334f478ed48187',
						    'database' => 'laravel',
						]);
                        if($ret){
                                $http->pool->push($mysql);
                        }else{
                                echo "mysql connect error";
                        }
                }
        });
		 $http->on('request',function($rep,$req)use($http){
                echo 'aa';
                $mysql=$http->pool->pop();
                var_dump($mysql);
                $http->pool->push($mysql);
        });
        $http->start();
//开启http server

$http = new swoole_http_server("0.0.0.0", 9501);

$http->set(
    [
        'enable_static_handler' => true,
        'document_root' => "/www/wwwroot/www.test.com/thinkphp5/public/static",
        'worker_num' => 5  //设置worker进程数
    ]
);

$http->on('WorkerStart', function (swoole_server $server, $worker_id){
    //定义应用目录
    define('APP_PATH', __DIR__ . '/../application/');
    // 加载基础文件
    //这里不直接加载start.php的原因是start.php中的代码会直接执行,也就是application\index\controller\Index.php文件(框架的默认首页)
    /*
     * Container::get('app', [defined('APP_PATH') ? APP_PATH : ''])
    ->run()
    ->send();
    */
    require __DIR__ . '/../thinkphp/base.php';
});

$http->on('request', function($request, $response){
    //适配
    /*
     *由于swoole http提供的API和原生php代码是有所不同的,比如原生php中获取get参数为直接从全局数组_GET中获取,而swoole http中是通过$request->get()的方式获取,因此要转换成原生的
     * */

    $_SERVER = [];
    if(isset($request->server)){
        foreach($request->header as $k => $v){
            $_SERVER[strtoupper($k)] = $v;
        }
    }
    $_GET = [];
    if(isset($request->get)){
        foreach($request->get as $k => $v){
            $_GET[$k] = $v;
        }
    }
    $_POST = [];
    if(isset($request->post)){
        foreach($request->post as $k => $v){
            $_POST[$k] = $v;
        }
    }

    //..其余参数用到的继续往后写

    ob_start();
    // 执行应用并响应
    try {
        think\Container::get('app', [APP_PATH])
            ->run()
            ->send();
    }catch (\Exception $e){
        //todo
    }
    $res = ob_get_contents();
    ob_end_clean();
	$response->header('Content-Type', 'image/jpeg', false);
    $response->end($res);
});

$http->start();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值