1. tcp 服务端简单demo与client .
 <?php
/**
* author : rookiejin <mrjnamei@gmail.com>
* createTime : 2018/1/4 10:26
* description: tcp.php - swoole-demo
* 该代码是一份简单的面向对象形式的 tcp 服务器和客户端通讯的demo
* 功能:实现服务器端tcp简单demo
*/
// 创建一个tcp服务器 $server = new swoole_server("127.0.0.1", 9501); /**
* @var $server swoole_server
* @var $fd int 文件描述符
*/
$server->on("connect", function($server , $fd){
echo "a client connected\n" ;
}); /**
* @var $server swoole_server
* @var $fd int 文件描述符
* @var $from_id worker_id worker进程id
* @var $data 接受的数据
*/
$server->on("receive", function($server , $fd , $from_id ,$data){
echo "#server received msg:" , $data , "\n";
$server->send($fd , "i received");
}); /**
* @var $server swoole_server
* @var $fd 文件描述符
*/
$server->on("close",function($server, $fd){
echo "# client closed\n";
});
// 启动服务器
$server->start();
client.php <?php $client = new swoole_client(SWOOLE_SOCK_TCP); if(!$client->connect("127.0.0.1", 9501, -1)){
exit("connect failed" . $client->errCode . "\n");
} $client->send("helloworld");
echo $client->recv() , "\n";
$client->close();

2. 使用面向对象的方式来写TCP服务器.

 <?php
/**
* author : rookiejin <mrjnamei@gmail.com>
* createTime : 2018/1/4 10:26
* description: php_oop.php - swoole-demo
* 该代码是一份干净的tcp server 事件回调,
* 没有任何对事件回调的业务处理 .
* 以该代码为基准,后面的demo都在此基础上修改 .
*/ class Server { /**
* @var \swoole_server
*/
public $server ; /**
* 配置项
* @var $config array
*/
public $config ; /**
* @var \Server
*/
public static $_worker ; /**
* 存储pid文件的位置
*/
public $pidFile ; /**
* worker 进程的数量
* @var $worker_num
*/
public $worker_num; /**
* 当前进程的worker_id
* @var $worker_id
*/
public $worker_id ; /**
* task 进程数 + worker 进程数 = 总的服务进程
* 给其他的进程发送消息:
* for($i = 0 ; $i < $count ; $i ++) {
* if($i == $this->worker_id) continue;表示是该进程
* $this->server->sendMessage($i , $data);
* }
* task 进程的数量
* @var $task_num
*/
public $task_num ; /**
* Server constructor.
*
* @param array $config
*/
public function __construct(array $config)
{
$this->server = new swoole_server($config ['host'] , $config ['port']);
$this->config = $config;
$this->serverConfig();
self::$_worker = & $this; // 引用
} public function serverConfig()
{
$this->server->set($this->config['server']);
} public function start()
{
// Server启动在主进程的主线程回调此函数
$this->server->on("start",[$this , "onSwooleStart"]);
// 此事件在Server正常结束时发生
$this->server->on("shutDown", [$this , "onSwooleShutDown"]);
//事件在Worker进程/Task进程启动时发生。这里创建的对象可以在进程生命周期内使用。
$this->server->on("workerStart", [$this , "onSwooleWorkerStart"]);
// 此事件在worker进程终止时发生。在此函数中可以回收worker进程申请的各类资源。
$this->server->on("workerStop",[$this, "onSwooleWorkerStop"]);
// worker 向task_worker进程投递任务触发
$this->server->on("task", [$this, "onSwooleTask"]);
// task_worker 返回值传给worker进程时触发
$this->server->on("finish",[$this , "onSwooleFinish"]);
// 当工作进程收到由 sendMessage 发送的管道消息时会触发onPipeMessage事件
$this->server->on("pipeMessage",[$this ,"onSwoolePipeMessage"]);
// 当worker/task_worker进程发生异常后会在Manager进程内回调此函数
$this->server->on("workerError", [$this , "onSwooleWrokerError"]);
// 当管理进程启动时调用它,函数原型:
$this->server->on("managerStart", [$this , "onSwooleManagerStart"]);
// onManagerStop
$this->server->on("managerStop", [$this , "onSwooleManagerStop"]);
// 有新的连接进入时,在worker进程中回调。
$this->server->on("connect" , [$this ,'onSwooleConnect']);
// 接收到数据时回调此函数,发生在worker进程中
$this->server->on("receive", [$this, 'onSwooleReceive']);
//CP客户端连接关闭后,在worker进程中回调此函数。函数原型:
$this->server->on("close", [$this ,"onSwooleClose"]);
$this->server->start();
} /**
* @warning 进程隔离
* 该步骤一般用于存储进程的 master_pid 和 manager_pid 到文件中
* 本例子存储的位置是 __DIR__ . "/tmp/" 下面
* 可以用 kill -15 master_pid 发送信号给进程关闭服务器,并且触发下面的onSwooleShutDown事件
* @param $server
*/
public function onSwooleStart($server)
{
$this->setProcessName('SwooleMaster');
$debug = debug_backtrace();
$this->pidFile = __DIR__ . "/temp/" . str_replace("/" , "_" , $debug[count($debug) - 1] ["file"] . ".pid" );
$pid = [$server->master_pid , $server->manager_pid];
file_put_contents($this->pidFile , implode(",", $pid));
} /**
* @param $server
* 已关闭所有Reactor线程、HeartbeatCheck线程、UdpRecv线程
* 已关闭所有Worker进程、Task进程、User进程
* 已close所有TCP/UDP/UnixSocket监听端口
* 已关闭主Reactor
* @warning
* 强制kill进程不会回调onShutdown,如kill -9
* 需要使用kill -15来发送SIGTREM信号到主进程才能按照正常的流程终止
* 在命令行中使用Ctrl+C中断程序会立即停止,底层不会回调onShutdown
*/
public function onSwooleShutDown($server)
{
echo "shutdown\n";
} /**
* @warning 进程隔离
* 该函数具有进程隔离性 ,
* {$this} 对象从 swoole_server->start() 开始前设置的属性全部继承
* {$this} 对象在 onSwooleStart,onSwooleManagerStart中设置的对象属于不同的进程中.
* 因此这里的pidFile虽然在onSwooleStart中设置了,但是是不同的进程,所以找不到该值.
* @param \swoole_server $server
* @param int $worker_id
*/
public function onSwooleWorkerStart(swoole_server $server, int $worker_id)
{
if($this->isTaskProcess($server))
{
$this->setProcessName('SwooleTask');
}
else{
$this->setProcessName('SwooleWorker');
}
$debug = debug_backtrace();
$this->pidFile = __DIR__ . "/temp/" . str_replace("/" , "_" , $debug[count($debug) - 1] ["file"] . ".pid" );
file_put_contents($this->pidFile , ",{$worker_id}" , FILE_APPEND);
} public function onSwooleWorkerStop($server,$worker_id)
{
echo "#worker exited {$worker_id}\n";
} /**
* @warning 进程隔离 在task_worker进程内被调用
* worker进程可以使用swoole_server_task函数向task_worker进程投递新的任务
* $task_id和$src_worker_id组合起来才是全局唯一的,不同的worker进程投递的任务ID可能会有相同
* 函数执行时遇到致命错误退出,或者被外部进程强制kill,当前的任务会被丢弃,但不会影响其他正在排队的Task
* @param $server
* @param $task_id 是任务ID 由swoole扩展内自动生成,用于区分不同的任务
* @param $src_worker_id 来自于哪个worker进程
* @param $data 是任务的内容
* @return mixed $data
*/
public function onSwooleTask($server , $task_id, $src_worker_id,$data)
{
return $data ;
} public function onSwooleFinish()
{ } /**
* 当工作进程收到由 sendMessage 发送的管道消息时会触发onPipeMessage事件。worker/task进程都可能会触发onPipeMessage事件。
* @param $server
* @param $src_worker_id 消息来自哪个Worker进程
* @param $message 消息内容,可以是任意PHP类型
*/
public function onSwoolePipeMessage($server , $src_worker_id,$message)
{ } /**
* worker进程发送错误的错误处理回调 .
* 记录日志等操作
* 此函数主要用于报警和监控,一旦发现Worker进程异常退出,那么很有可能是遇到了致命错误或者进程CoreDump。通过记录日志或者发送报警的信息来提示开发者进行相应的处理。
* @param $server
* @param $worker_id 是异常进程的编号
* @param $worker_pid 是异常进程的ID
* @param $exit_code 退出的状态码,范围是 1 ~255
* @param $signal 进程退出的信号
*/
public function onSwooleWrokerError($server ,$worker_id,$worker_pid,$exit_code,$signal)
{
echo "#workerError:{$worker_id}\n";
} /**
*
*/
public function onSwooleManagerStart()
{
$this->setProcessName('SwooleManager');
} /**
* @param $server
*/
public function onSwooleManagerStop($server)
{
echo "#managerstop\n";
} /**
* 客户端连接
* onConnect/onClose这2个回调发生在worker进程内,而不是主进程。
* UDP协议下只有onReceive事件,没有onConnect/onClose事件
* @param $server
* @param $fd
* @param $reactorId
*/
public function onSwooleConnect($server ,$fd ,$reactorId)
{
echo "#connected\n";
} /**
* @param $server server对象
* @param $fd 文件描述符
* @param $reactorId reactor线程id
*/
public function onSwooleReceive($server,$fd,$reactorId)
{
echo "#received\n";
} /**
* 连接断开,广播业务需要从redis | memcached | 内存 中删除该fd
* @param $server
* @param $fd
* @param $reactorId
*/
public function onSwooleClose($server, $fd ,$reactorId)
{
echo "#swooleClosed\n" ;
} public function setProcessName($name)
{
if(function_exists('cli_set_process_title'))
{
@cli_set_process_title($name);
}
else{
@swoole_set_process_name($name);
}
} /**
* 返回真说明该进程是task进程
* @param $server
* @return bool
*/
public function isTaskProcess($server)
{
return $server->taskworker === true ;
} /**
* main 运行入口方法
*/
public static function main()
{
self::$_worker->start();
}
} $config = ['server' => ['worker_num' => 4 , "task_worker_num" => "20" , "dispatch_mode" => 3 ] , 'host' => '0.0.0.0' , 'port' => 9501];
$server = new Server($config);
Server::main() ;
  1. 本例子是注册了swoole的基本事件监听,回调没有做,为下面的代码先做一份铺垫。
  2. 这里主要要讲的是swoole的启动步骤.
* note
1. $server = new Server ($config);
在new了一个单例Server类以后,将Server::$_worker代理到本身$this. 并且做好服务器的配置.
2. Server::main();
该代码为server注册事件回调函数. 然后启动 swoole_server::start();

3. 启动过程:
1). 先会开启master进程. 触发onSwooleStart事件,
可以获取到master进程的pid和manager进程的pid.
该函数式在master进程执行的.在事件回调里实例化的任何对象只针对master进程有效.
2). 接着触发onSwooleManagerStart. 在manager进程中执行.
该函数式在master进程执行的.在事件回调里实例化的任何对象只针对manager进程有效.
3). 接着触发onSwooleWorkerStart. 该过程启动worker与task_worker进程.步骤是并行的,
不分先后.
worker进程与task_worker进程其实一样,都属于worker进程,具有进程隔离性,自己进程内
实例化的类只有在自己进程内部有用,
worker_num + worker_task_num = 总的worker_id数量.
如果需要从worker进程向其他进程发送消息的话,可以这么做:
    for($i = 0 ; $i < $worker_num + $task_worker_num ; $i ++) {
if($i == $this->worker_id) continue;
$this->server_sendMessage($i ,$message);
}

4). 然后监听connect与receive事件, 就属于具体的业务范畴了.

下面带来一个 tcp 聊天室的简单案例,例子是用swoole_table存储所有的链接信息. 功能可以实现群聊,单聊: 主要业务逻辑在onSwooleReceive回调中

 <?php
/**
* author : rookiejin <mrjnamei@gmail.com>
* createTime : 2018/1/4 10:26
* description: tcp_get_and_send.php - swoole-demo
* 该代码是一份简单的面向对象形式的 tcp 服务器和客户端通讯的demo
* 功能:单发. 群发.
*/ class Server { /**
* @var \swoole_server
*/
public $server ; /**
* 配置项
* @var $config array
*/
public $config ; /**
* @var \Server
*/
public static $_worker ; /**
* 存储pid文件的位置
*/
public $pidFile ; /**
* worker 进程的数量
* @var $worker_num
*/
public $worker_num; /**
* 当前进程的worker_id
* @var $worker_id
*/
public $worker_id ; /**
* task 进程数 + worker 进程数 = 总的服务进程
* 给其他的进程发送消息:
* for($i = 0 ; $i < $count ; $i ++) {
* if($i == $this->worker_id) continue;表示是该进程
* $this->server->sendMessage($i , $data);
* }
* task 进程的数量
* @var $task_num
*/
public $task_num ; /**
* @var $table swoole_table 内存表
*/
public $table; /**
* Server constructor.
*
* @param array $config
*/
public function __construct(array $config)
{
$this->server = new swoole_server($config ['host'] , $config ['port']);
$this->config = $config;
$this->serverConfig();
$this->createTable();
self::$_worker = & $this; // 引用
} private function serverConfig()
{
$this->server->set($this->config['server']);
} /**
* 创建swoole_table
*/
private function createTable()
{
$this->table = new swoole_table( 65536 );
$this->table->column("fd",swoole_table::TYPE_INT , 8);
$this->table->column("worker_id", swoole_table::TYPE_INT , 4);
$this->table->column("name",swoole_table::TYPE_STRING,255);
$this->table->create();
} public function start()
{
// Server启动在主进程的主线程回调此函数
$this->server->on("start",[$this , "onSwooleStart"]);
// 此事件在Server正常结束时发生
$this->server->on("shutDown", [$this , "onSwooleShutDown"]);
//事件在Worker进程/Task进程启动时发生。这里创建的对象可以在进程生命周期内使用。
$this->server->on("workerStart", [$this , "onSwooleWorkerStart"]);
// 此事件在worker进程终止时发生。在此函数中可以回收worker进程申请的各类资源。
$this->server->on("workerStop",[$this, "onSwooleWorkerStop"]);
// worker 向task_worker进程投递任务触发
$this->server->on("task", [$this, "onSwooleTask"]);
// task_worker 返回值传给worker进程时触发
$this->server->on("finish",[$this , "onSwooleFinish"]);
// 当工作进程收到由 sendMessage 发送的管道消息时会触发onPipeMessage事件
$this->server->on("pipeMessage",[$this ,"onSwoolePipeMessage"]);
// 当worker/task_worker进程发生异常后会在Manager进程内回调此函数
$this->server->on("workerError", [$this , "onSwooleWrokerError"]);
// 当管理进程启动时调用它,函数原型:
$this->server->on("managerStart", [$this , "onSwooleManagerStart"]);
// onManagerStop
$this->server->on("managerStop", [$this , "onSwooleManagerStop"]);
// 有新的连接进入时,在worker进程中回调。
$this->server->on("connect" , [$this ,'onSwooleConnect']);
// 接收到数据时回调此函数,发生在worker进程中
$this->server->on("receive", [$this, 'onSwooleReceive']);
//CP客户端连接关闭后,在worker进程中回调此函数。函数原型:
$this->server->on("close", [$this ,"onSwooleClose"]);
$this->server->start();
} /**
* @warning 进程隔离
* 该步骤一般用于存储进程的 master_pid 和 manager_pid 到文件中
* 本例子存储的位置是 __DIR__ . "/tmp/" 下面
* 可以用 kill -15 master_pid 发送信号给进程关闭服务器,并且触发下面的onSwooleShutDown事件
* @param $server
*/
public function onSwooleStart($server)
{
$this->setProcessName('SwooleMaster');
$debug = debug_backtrace();
$this->pidFile = __DIR__ . "/temp/" . str_replace("/" , "_" , $debug[count($debug) - 1] ["file"] . ".pid" );
$pid = [$server->master_pid , $server->manager_pid];
file_put_contents($this->pidFile , implode(",", $pid));
} /**
* @param $server
* 已关闭所有Reactor线程、HeartbeatCheck线程、UdpRecv线程
* 已关闭所有Worker进程、Task进程、User进程
* 已close所有TCP/UDP/UnixSocket监听端口
* 已关闭主Reactor
* @warning
* 强制kill进程不会回调onShutdown,如kill -9
* 需要使用kill -15来发送SIGTREM信号到主进程才能按照正常的流程终止
* 在命令行中使用Ctrl+C中断程序会立即停止,底层不会回调onShutdown
*/
public function onSwooleShutDown($server)
{
echo "shutdown\n";
} /**
* @warning 进程隔离
* 该函数具有进程隔离性 ,
* {$this} 对象从 swoole_server->start() 开始前设置的属性全部继承
* {$this} 对象在 onSwooleStart,onSwooleManagerStart中设置的对象属于不同的进程中.
* 因此这里的pidFile虽然在onSwooleStart中设置了,但是是不同的进程,所以找不到该值.
* @param \swoole_server $server
* @param int $worker_id
*/
public function onSwooleWorkerStart(swoole_server $server, int $worker_id)
{
if($this->isTaskProcess($server))
{
$this->setProcessName('SwooleTask');
}
else{
$this->setProcessName('SwooleWorker');
}
$debug = debug_backtrace();
$this->pidFile = __DIR__ . "/temp/" . str_replace("/" , "_" , $debug[count($debug) - 1] ["file"] . ".pid" );
file_put_contents($this->pidFile , ",{$worker_id}" , FILE_APPEND);
} public function onSwooleWorkerStop($server,$worker_id)
{
echo "#worker exited {$worker_id}\n";
} /**
* @warning 进程隔离 在task_worker进程内被调用
* worker进程可以使用swoole_server_task函数向task_worker进程投递新的任务
* $task_id和$src_worker_id组合起来才是全局唯一的,不同的worker进程投递的任务ID可能会有相同
* 函数执行时遇到致命错误退出,或者被外部进程强制kill,当前的任务会被丢弃,但不会影响其他正在排队的Task
* @param $server
* @param $task_id 是任务ID 由swoole扩展内自动生成,用于区分不同的任务
* @param $src_worker_id 来自于哪个worker进程
* @param $data 是任务的内容
* @return mixed $data
*/
public function onSwooleTask($server , $task_id, $src_worker_id,$data)
{
// todo
} public function onSwooleFinish()
{
// todo
} /**
* 当工作进程收到由 sendMessage 发送的管道消息时会触发onPipeMessage事件。worker/task进程都可能会触发onPipeMessage事件。
* @param $server
* @param $src_worker_id 消息来自哪个Worker进程
* @param $message 消息内容,可以是任意PHP类型
*/
public function onSwoolePipeMessage($server , $src_worker_id,$message)
{
// todo
} /**
* worker进程发送错误的错误处理回调 .
* 记录日志等操作
* 此函数主要用于报警和监控,一旦发现Worker进程异常退出,那么很有可能是遇到了致命错误或者进程CoreDump。通过记录日志或者发送报警的信息来提示开发者进行相应的处理。
* @param $server
* @param $worker_id 是异常进程的编号
* @param $worker_pid 是异常进程的ID
* @param $exit_code 退出的状态码,范围是 1 ~255
* @param $signal 进程退出的信号
*/
public function onSwooleWrokerError($server ,$worker_id,$worker_pid,$exit_code,$signal)
{
echo "#workerError:{$worker_id}\n";
} /**
*
*/
public function onSwooleManagerStart()
{
$this->setProcessName('SwooleManager');
} /**
* @param $server
*/
public function onSwooleManagerStop($server)
{
echo "#managerstop\n";
} /**
* 客户端连接
* onConnect/onClose这2个回调发生在worker进程内,而不是主进程。
* UDP协议下只有onReceive事件,没有onConnect/onClose事件
* @param $server
* @param $fd
* @param $reactorId
*/
public function onSwooleConnect($server ,$fd ,$reactorId)
{
echo "#{$fd} has connected\n";
$server->send($fd , "please input your name\n");
} /**
* @param $server server对象
* @param $fd 文件描述符
* @param $reactorId reactor线程id
* @param $data 数据
*/
public function onSwooleReceive($server,$fd,$reactorId, $data)
{
$data = json_decode($data, true);
$exist = $this->table->exist($fd);
$from = $data ['from'];
$to = $data ['to'];
$message = $data ['message']; if(!$exist) {
foreach ($this->table as $row)
{
if($row ['name'] == $from)
{
$server->send($fd , 'name already exists');
return ;
}
}
$this->table->set($fd , ['name' => $from , 'fd' => $fd]);
$server->send($fd , "welcome to join tcp chat room\n");
}
// 发送给其他人 .
if($to == 'all')
{
$this->sendToAllExceptHim($server , $message , $fd);
return ;
}
if(!empty($to) && !empty($message))
{
$this->sendToOne($server ,$message ,$to);
}
return ;
} private function sendToOne($server , $message , $name)
{
foreach ($this->table as $row)
{
if($row ['name'] == $name)
{
$server->send($row ['fd'] , $message);
return ;
}
}
} private function sendToAllExceptHim($server , $message, $fd)
{
foreach ($this->table as $row)
{
if($row['fd'] == $fd) continue ;
$server->send($row ['fd'] , $message);
}
} /**
* 连接断开,广播业务需要从redis | memcached | 内存 中删除该fd
* @param $server
* @param $fd
* @param $reactorId
*/
public function onSwooleClose($server, $fd ,$reactorId)
{
$this->table->del($fd);
} public function setProcessName($name)
{
if(function_exists('cli_set_process_title'))
{
@cli_set_process_title($name);
}
else{
@swoole_set_process_name($name);
}
} /**
* 返回真说明该进程是task进程
* @param $server
* @return bool
*/
public function isTaskProcess($server)
{
return $server->taskworker === true ;
} /**
* main 运行入口方法
*/
public static function main()
{
self::$_worker->start();
}
} $config = ['server' => ['worker_num' => 4 , "task_worker_num" => "20" , "dispatch_mode" => 3 ] , 'host' => '0.0.0.0' , 'port' => 9501];
$server = new Server($config);
Server::main() ;

如有错误,敬请纠正!

PHP Swoole-Demo TCP服务端简单实现的更多相关文章

  1. swoole创建TCP服务端和客户端

    服务端: server.php <?php //创建Server对象,监听 127.0.0.1:9501端口    $serv = new swoole_server("127.0.0 ...

  2. python编程系列---tcp服务端的简单实现

    流程如下: """tcp服务端创建流程1. 创建服务端的tcp socket : server_socket 用于监听客户端的请求2. 绑定端口3. server_soc ...

  3. TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端

    目录 说明 TCP/UDP通信主要结构 管理多个Socket的解决方案 框架中TCP部分的使用 框架中UDP部分的使用 框架源码结构 补充说明 源码地址 说明 之前有好几篇博客在讲TCP/UDP通信方 ...

  4. 【转】TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端

    [转]TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端).UDP客户端 目录 说明 TCP/UDP通信主要结构 管理多个Socket的解决方案 框架中TCP部分的使用 框架中UDP ...

  5. vertx 从Tcp服务端和客户端开始翻译

    写TCP 服务器和客户端 vert.x能够使你很容易写出非阻塞的TCP客户端和服务器 创建一个TCP服务 最简单的创建TCP服务的方法是使用默认的配置:如下 NetServer server = ve ...

  6. 子进程回收资源两种方式,僵尸进程与孤儿进程,守护进程,进程间数据隔离,进程互斥锁,队列,IPC机制,线程,守护线程,线程池,回调函数add_done_callback,TCP服务端实现并发

    子进程回收资源两种方式 - 1) join让主进程等待子进程结束,并回收子进程资源,主进程再结束并回收资源. - 2) 主进程 “正常结束” ,子进程与主进程一并被回收资源. from multipr ...

  7. 基于Select模型的Windows TCP服务端和客户端程序示例

    最近跟着刘远东老师的<C++百万并发网络通信引擎架构与实现(服务端.客户端.跨平台)>,Bilibili视频地址为C++百万并发网络通信引擎架构与实现(服务端.客户端.跨平台),重新复习下 ...

  8. C++封装的基于WinSock2的TCP服务端、客户端

    无聊研究Winsock套接字编程,用原生的C语言接口写出来的代码看着难受,于是自己简单用C++封装一下,把思路过程理清,方便自己后续翻看和新手学习. 只写好了TCP通信服务端,有空把客户端流程也封装一 ...

  9. 利用select实现IO多路复用TCP服务端

    一.相关函数 1.  int select(int maxfdp, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeva ...

随机推荐

  1. Nmon监控结果分析

    一:CPU信息 SYS_SUMM图表: 1.折线图中蓝线为cpu占有率变化情况:粉线为磁盘IO的变化情况: 2.下面表各种左边的位磁盘的总体数据,包括如下几个: Avg tps during an i ...

  2. Python之单例模式的多种实现

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  3. [Luogu2737] [USACO4.1]麦香牛块Beef McNuggets

    题目描述 农夫布朗的奶牛们正在进行斗争,因为它们听说麦当劳正在考虑引进一种新产品:麦香牛块.奶牛们正在想尽一切办法让这种可怕的设想泡汤.奶牛们进行斗争的策略之一是“劣质的包装”.“看,”奶牛们说,“如 ...

  4. vue——前端跨域

    ***针对的是不同域名.不同协议的跨域: 1.找到config文件中开发环境的配置文件——dev.env.js,在里面将要跨域的域名配置进去 2.找到config文件中线上环境的配置文件——prod. ...

  5. php的cookie怎么使用

    PHP中Cookie的使用---添加/更新/删除/获取Cookie 及 自动填写该用户的用户名和密码和判断是否第一次登陆 什么是cookie? 服务器在客户端保存用户的信息,比如登录名,密码等. 这些 ...

  6. shell传递参数(三)

    $n:n代表一个数字,指执行脚本的第n个参数.特别地,$0指执行的文件名 [root@ipha-dev71- exercise_shell]# cat test.sh #!/bin/bash echo ...

  7. Jenkins构建 前端node项目

    1.新建一个自由风格的项目 2.配置git 3.构建-增加构建步骤-执行shell cd $WORKSPACE npm install --registry=http://ip:port --unsa ...

  8. Uipath 勾选checkbox

    东京IT青年前线 http://www.rpatokyo.com/ Uipath 勾选checkbox 使用check Activity可以对check box 复选框进行勾选. 虽然Click也可以 ...

  9. Python 的多线程是鸡肋?

    "唉,还没毕业就受到甲方的支配,等以后进了公司可咋整啊."小白嘴里这么吐槽,但心理上还是不敢怠慢,只能恋恋不舍地关掉眼前的游戏,打开了 Python 代码思考了起来. " ...

  10. CountDownLatch和CycliBarrier介绍

    一.CountDownLatch 它被用来同步一个或多个任务,强制他们等待其他任务完成,这就是闭锁. public CountDownLatch(int count) { if (count < ...