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 由于本 ...
随机推荐
- Java面向对象_增强for可变参数与代码块
1.foreach循环 for(类型 变量名称:数组或集合){ //输出操作 } 2.可变参数:根据需要自动传入任意个数的参数,就是可变参数. 语法:返回值类型 方法名称(数据类型...参数名称){ ...
- Python 类总结
Python可以继承多个父类,多重继承. 类支持多个对象的产生,命名空间的继承,运算符重载1).类产生多个实例对象Python OOP模型中的两种对象:类对象和实例对象.类对象提供默认的行为,是实例对 ...
- 打印流-PrintStream
打印流-PrintStream java.io.PrintStream为其他输出流添加了功能,使其他的流能够更方便的打印各种数据值表现形式 PrintStream特点: 1.只负责数据的输入,不负责数 ...
- Docker | 第二章:第一个Docker应用
前言 上一章节,已经简单讲解了Docker相关方面的知识,相信大家已经有个概念了.这章节开始,开始进行实践操作.和学习任何一门语言一样,我们今天也开始从Hello,World开始~ 对Docker不了 ...
- MPAndroidChart开源图表库---折线图
项目地址:点击打开,原文参考地址:点击打开 1. 将mpandroidchartlibrary-2-0-8.jar包copy到项目的libs中 2. 定义xml文件 <?xml version= ...
- Google地址
Google的访问一直很不稳定,经常被墙,无意间发现以下一些地址,特此记录. https://g.ttlsa.com/ https://wen.lu/ http://sinaapp.co https: ...
- System Center Configuration Manager 2016 域准备篇(Part3)
步骤2.将CM16加入域 注意:在ConfigMgr服务器(CM16 )上以本地管理员身份执行以下操作 手动加入域,请登录CM16.启动Windows文件资源管理器 右键单击This-PC,然后选择 ...
- oracle 11g r2卸载
1. 进入计算机管理>>服务里,停止所有oracle的服务 2. 开始菜单>>程序>>Oracle>>Oracle安装产品>>Univers ...
- 项目移动后报error LNK1123
VS20101.解决方案窗口 项目|项目属性|配置属性|清单工具|输入和输出|嵌入清单 “是”改为“否”:2.项目|项目属性|配置属性|连接器|清单文件|嵌入清单 “是”改为“否”:3.对于64位的操 ...
- World Wind Java开发之一(转)
http://blog.csdn.net/giser_whu/article/details/40477235 参照<World wind Java三维地理信息系统开发指南随书光盘>以及官 ...