swoole 连接池
proxy_pool.php
<?php
class ProxyServer
{
protected $frontends;
protected $backends;
/**
* @var swoole_server
*/
protected $serv;
protected $index = 0;
protected $mode = SWOOLE_BASE;
protected $backendServer;
function run($backendServer = array('host' => '127.0.0.1', 'port' => '80'), $port = 9501, $host = '0.0.0.0')
{
$this->backendServer = $backendServer;
$serv = new swoole_server($host, $port, $this->mode);
$serv->set(array(
'worker_num' => 8, //worker process num
//'backlog' => 128, //listen backlog
//'open_tcp_keepalive' => 1,
//'log_file' => '/tmp/swoole.log', //swoole error log
));
$serv->on('WorkerStart', array($this, 'onStart'));
$serv->on('Receive', array($this, 'onReceive'));
$serv->on('Close', array($this, 'onClose'));
$serv->on('WorkerStop', array($this, 'onShutdown'));
$serv->start();
}
function onStart($serv)
{
$this->serv = $serv;
//echo "Server: start.Swoole version is [" . SWOOLE_VERSION . "]\n";
}
function onShutdown($serv)
{
echo "Server: onShutdown\n";
}
function onClose($serv, $fd, $from_id)
{
//清理掉后端连接
if (isset($this->frontends[$fd])) {
$backend_socket = $this->frontends[$fd];
$backend_socket->closing = true;
$backend_socket->close();
unset($this->backends[$backend_socket->sock]);
unset($this->frontends[$fd]);
}
echo "onClose: frontend[$fd]\n";
}
function onReceive($serv, $fd, $from_id, $data)
{
//尚未建立连接
if (!isset($this->frontends[$fd])) {
//连接到后台服务器
$socket = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
$socket->closing = false;
$socket->on('connect', function (swoole_client $socket) use ($data) {
$socket->send($data);
});
$socket->on('error', function (swoole_client $socket) use ($fd) {
echo "ERROR: connect to backend server failed\n";
$this->serv->send($fd, "backend server not connected. please try reconnect.");
$this->serv->close($fd);
});
$socket->on('close', function (swoole_client $socket) use ($fd) {
echo "onClose: backend[{$socket->sock}]\n";
unset($this->backends[$socket->sock]);
unset($this->frontends[$fd]);
if (!$socket->closing) {
$this->serv->close($fd);
}
});
$socket->on('receive', function (swoole_client $socket, $_data) use ($fd) {
$this->serv->send($fd, $_data);
});
if ($socket->connect($this->backendServer['host'], $this->backendServer['port'])) {
$this->backends[$socket->sock] = $fd;
$this->frontends[$fd] = $socket;
} else {
echo "ERROR: cannot connect to backend server.\n";
$this->serv->send($fd, "backend server not connected. please try reconnect.");
$this->serv->close($fd);
}
} //已经有连接,可以直接发送数据
else {
/**
* @var $socket swoole_client
*/
$socket = $this->frontends[$fd];
$socket->send($data);
}
}
}
// config
$backendServerList = [
[
'host' => 'api.eelly.com', 'port' => 443, 'proxy_port' => 9501,
],
];
$workerNum = count($backendServerList);
$pool = new Swoole\Process\Pool($workerNum);
$pool->on("WorkerStart", function ($pool, $workerId) use ($backendServerList) {
echo "Worker#{$workerId} is started\n";
$backendServer = $backendServerList[$workerId];
$serv = new ProxyServer($backendServer, $backendServer['proxy_port']);
echo "Remote {$backendServer['host']}:{$backendServer['port']} -> Local {$backendServer['proxy_port']}\n";
$serv->run();
});
$pool->start();
swoole 连接池的更多相关文章
- 用swoole简单实现MySQL连接池
MySQL连接池 在传统的网站开发中,比如LNMP模式,由Nginx的master进程接收请求然后分给多个worker进程,每个worker进程再链接php-fpm的master进程,php-fpm再 ...
- Swoole MySQL 连接池的实现
目录 概述 代码 扩展 小结 概述 这是关于 Swoole 入门学习的第八篇文章:Swoole MySQL 连接池的实现. 第七篇:Swoole RPC 的实现 第六篇:Swoole 整合成一个小框架 ...
- 如何在 Swoole 中优雅的实现 MySQL 连接池
如何在 Swoole 中优雅的实现 MySQL 连接池 一.为什么需要连接池 ? 数据库连接池指的是程序和数据库之间保持一定数量的连接不断开, 并且各个请求的连接可以相互复用, 减少重复连接数据库带来 ...
- Swoole Redis 连接池的实现
概述 这是关于 Swoole 入门学习的第九篇文章:Swoole Redis 连接池的实现. 第八篇:Swoole MySQL 连接池的实现 第七篇:Swoole RPC 的实现 第六篇:Swoole ...
- Swoole 实战:MySQL 查询器的实现(协程连接池版)
目录 需求分析 使用示例 模块设计 UML 类图 入口 事务 连接池 连接 查询器的组装 总结 需求分析 本篇我们将通过 Swoole 实现一个自带连接池的 MySQL 查询器: 支持通过链式调用构造 ...
- 转 Swoole】用swoole简单实现MySQL连接池
MySQL连接池 在传统的网站开发中,比如LNMP模式,由Nginx的master进程接收请求然后分给多个worker进程,每个worker进程再链接php-fpm的master进程,php-fpm再 ...
- Swoole 中使用 PDO 连接池、Redis 连接池、Mysqli 连接池
连接池使用说明 所有连接池的实现均基于 ConnectionPool 原始连接池: 连接池的底层原理是基于 Channel 的自动调度: 开发者需要自己保证归还的连接是可重用的: 若连接不可重用,需要 ...
- 实现一个协程版mysql连接池
实现一个协程版的mysql连接池,该连接池支持自动创建最小连接数,自动检测mysql健康:基于swoole的chanel. 最近事情忙,心态也有点不积极.技术倒是没有落下,只是越来越不想写博客了.想到 ...
- 关于PHP连接池扩展php-cp遇到的那些坑
php-cp是国内大神写的php第三方扩展,具体就不用多说了,细读https://github.com/swoole/php-cp,下面来说说今天安装方法. 环境:CentOS7.2.1511 由于本 ...
随机推荐
- PullToRefreshListView
@Override protected void onRefreshing(final boolean doScroll) { /** * If we're not showing the Refre ...
- (转)vimdiff 快速比较和合并少量文件
vimdiff 快速比较和合并少量文件 原文:http://www.cnblogs.com/abeen/p/4255754.html 纯文本文件比较和合并工具一直是软件开发过程中比较重要的组成部分,v ...
- Python 为threading.Thread添加 terminate
import threading import inspect import ctypes def _async_raise(tid, exc_type): """rai ...
- awk 分解行、字段
1. 格式 格式: awk 'pattern {action} pattern {action}' filename 注:多个文件时,读取从左到右,读完第一个再读取第二个 pattern 1-/正则表 ...
- JS绑定事件和移除事件的处理方法
addEventListener()与removeEventListener()用于处理指定和删除事件处理程序操作.所有的DOM节点中都包含这两种方法,并且它们都接受3个参数:要处理的事件名.作为事件 ...
- 移动开发,Webapp 淘宝手机 rem 布局
(function (doc, win) { var docEl = doc.documentElement, resizeEvt ="orientationchange"in w ...
- 安卓adb调试命令常见的问题
首先本人使用的是ubuntu系统,在Eclipse下开发的时候使用无线调试,在终端直接输入adb connect 114.114.114.114没有问题,给手机安装软件用adb install ** ...
- lazyload的使用心得
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $("img.lazy").lazyload({ placeholder : "img/grey.g ...
- DB2常用函数详解
(一) 字符串函数 VALUE函数 语法:VALUE(EXPRESSION1,EXPRESSION2) VALUE函数是用返回一个非空的值,当其第一个参数非空,直接返回该参数的值,如果第一个参数为空 ...
- Ajax 使用 FormData做为data的参数时 出现Illegal invocation
今天在用ajax向后台传递数据时出现此错误,在ajax的参数中加上 contentType: false, processData: false, 这两句即可.