swoole.php

 #!/bin/env php
<?php
/**
* 默认时区定义
*/
date_default_timezone_set('Asia/Shanghai'); /**
* 设置错误报告模式
*/
error_reporting(0); /**
* 设置默认区域
*/
setlocale(LC_ALL, "zh_CN.utf-8"); /**
* 检测 PDO_MYSQL
*/
if (!extension_loaded('pdo_mysql')) {
exit('PDO_MYSQL extension is not installed' . PHP_EOL);
}
/**
* 检查exec 函数是否启用
*/
if (!function_exists('exec')) {
exit('exec function is disabled' . PHP_EOL);
}
/**
* 检查命令 lsof 命令是否存在
*/
exec("whereis lsof", $out);
if ($out[0] == 'lsof:') {
exit('lsof is not found' . PHP_EOL);
}
/**
* 定义项目根目录&swoole-task pid
*/
define('SWOOLE_PATH', __DIR__);
define('SWOOLE_TASK_PID_PATH', SWOOLE_PATH . DIRECTORY_SEPARATOR . 'Swoole' . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . 'swoole-task.pid');
define('SWOOLE_TASK_NAME_PRE', 'swooleServ'); /**
* 加载 swoole server
*/
include SWOOLE_PATH . DIRECTORY_SEPARATOR . 'Swoole' . DIRECTORY_SEPARATOR . 'SwooleServer.php'; function portBind($port) {
$ret = [];
$cmd = "lsof -i :{$port}|awk '$1 != \"COMMAND\" {print $1, $2, $9}'";
exec($cmd, $out);
if ($out) {
foreach ($out as $v) {
$a = explode(' ', $v);
list($ip, $p) = explode(':', $a[2]);
$ret[$a[1]] = [
'cmd' => $a[0],
'ip' => $ip,
'port' => $p,
];
}
} return $ret;
} function servStart($host, $port, $daemon, $name) {
echo "正在启动 swoole-task 服务" . PHP_EOL;
if (!is_writable(dirname(SWOOLE_TASK_PID_PATH))) {
exit("swoole-task-pid文件需要目录的写入权限:" . dirname(SWOOLE_TASK_PID_PATH) . PHP_EOL);
}
if (file_exists(SWOOLE_TASK_PID_PATH)) {
$pid = explode("\n", file_get_contents(SWOOLE_TASK_PID_PATH));
$cmd = "ps ax | awk '{ print $1 }' | grep -e \"^{$pid[0]}$\"";
exec($cmd, $out);
if (!empty($out)) {
exit("swoole-task pid文件 " . SWOOLE_TASK_PID_PATH . " 存在,swoole-task 服务器已经启动,进程pid为:{$pid[0]}" . PHP_EOL);
} else {
echo "警告:swoole-task pid文件 " . SWOOLE_TASK_PID_PATH . " 存在,可能swoole-task服务上次异常退出(非守护模式ctrl+c终止造成是最大可能)" . PHP_EOL;
unlink(SWOOLE_TASK_PID_PATH);
}
}
$bind = portBind($port);
if ($bind) {
foreach ($bind as $k => $v) {
if ($v['ip'] == '*' || $v['ip'] == $host) {
exit("端口已经被占用 {$host}:$port, 占用端口进程ID {$k}" . PHP_EOL);
}
}
}
unset($_SERVER['argv']);
$_SERVER['argc'] = 0;
echo "启动 swoole-task 服务成功" . PHP_EOL;
$server = new SwooleServer('127.0.0.1', 9501);
$server->run();
//确保服务器启动后swoole-task-pid文件必须生成
/*if (!empty(portBind($port)) && !file_exists(SWOOLE_TASK_PID_PATH)) {
exit("swoole-task pid文件生成失败( " . SWOOLE_TASK_PID_PATH . ") ,请手动关闭当前启动的swoole-task服务检查原因" . PHP_EOL);
}*/
} function servStop($host, $port, $isRestart = false) {
echo "正在停止 swoole-task 服务" . PHP_EOL;
if (!file_exists(SWOOLE_TASK_PID_PATH)) {
exit('swoole-task-pid文件:' . SWOOLE_TASK_PID_PATH . '不存在' . PHP_EOL);
}
$pid = explode("\n", file_get_contents(SWOOLE_TASK_PID_PATH));
$bind = portBind($port);
if (empty($bind) || !isset($bind[$pid[0]])) {
exit("指定端口占用进程不存在 port:{$port}, pid:{$pid[0]}" . PHP_EOL);
}
$cmd = "kill {$pid[0]}";
exec($cmd);
do {
$out = [];
$c = "ps ax | awk '{ print $1 }' | grep -e \"^{$pid[0]}$\"";
exec($c, $out);
if (empty($out)) {
break;
}
} while (true);
//确保停止服务后swoole-task-pid文件被删除
if (file_exists(SWOOLE_TASK_PID_PATH)) {
unlink(SWOOLE_TASK_PID_PATH);
}
$msg = "执行命令 {$cmd} 成功,端口 {$host}:{$port} 进程结束" . PHP_EOL;
if ($isRestart) {
echo $msg;
} else {
exit($msg);
}
} function servReload($host, $port, $isRestart = false) {
echo "正在平滑重启 swoole-task 服务" . PHP_EOL;
try {
$client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
$ret = $client->connect($host, $port);
if (empty($ret)) {
exit("{$host}:{$port} swoole-task服务不存在或者已经关闭" . PHP_EOL);
} else {
$client->send(json_encode(array('action' => 'reload')));
}
$msg = "执行命令reload成功,端口 {$host}:{$port} 进程重启" . PHP_EOL;
if ($isRestart) {
echo $msg;
} else {
exit($msg);
}
} catch (Exception $e) {
exit($e->getMessage() . PHP_EOL . $e->getTraceAsString());
}
} function servClose($host, $port, $isRestart = false) {
echo "正在关闭 swoole-task 服务" . PHP_EOL;
try {
$client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
$ret = $client->connect($host, $port);
if (empty($ret)) {
exit("{$host}:{$port} swoole-task服务不存在或者已经关闭" . PHP_EOL);
} else {
$client->send(json_encode(array('action' => 'close')));
}
//确保停止服务后swoole-task-pid文件被删除
if (file_exists(SWOOLE_TASK_PID_PATH)) {
unlink(SWOOLE_TASK_PID_PATH);
}
$msg = "执行命令close成功,端口 {$host}:{$port} 进程结束" . PHP_EOL;
if ($isRestart) {
echo $msg;
} else {
exit($msg);
}
} catch (\Exception $e) {
exit($e->getMessage() . PHP_EOL . $e->getTraceAsString());
}
} function servStatus($host, $port) {
echo "swoole-task {$host}:{$port} 运行状态" . PHP_EOL;
$pid = explode("\n", file_get_contents(SWOOLE_TASK_PID_PATH));
$bind = portBind($port);
if (empty($bind) || !isset($bind[$pid[0]])) {
exit("指定端口占用进程不存在 port:{$port}, pid:{$pid[0]}" . PHP_EOL);
}
$client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
$ret = $client->connect($host, $port);
if (empty($ret)) {
exit("{$host}:{$port} swoole-task服务不存在或者已经停止" . PHP_EOL);
} else {
$client->send(json_encode(array('action' => 'status')));
$out = $client->recv();
$a = json_decode($out);
$b = array(
'start_time' => '服务器启动的时间',
'connection_num' => '当前连接的数量',
'accept_count' => '接受的连接数量',
'close_count' => '关闭的连接数量',
'tasking_num' => '当前正在排队的任务数',
'request_count' => '请求的连接数量',
'worker_request_count' => 'worker连接数量',
'task_process_num' => '任务进程数量'
);
foreach ($a as $k1 => $v1) {
if ($k1 == 'start_time') {
$v1 = date("Y-m-d H:i:s", $v1);
}
echo $b[$k1] . ":\t$v1" . PHP_EOL;
}
}
exit();
} function servList() {
echo "本机运行的swoole-task服务进程" . PHP_EOL;
$cmd = "ps aux|grep " . SWOOLE_TASK_NAME_PRE . "|grep -v grep|awk '{print $1, $2, $6, $8, $9, $11}'";
exec($cmd, $out);
if (empty($out)) {
exit("没有发现正在运行的swoole-task服务" . PHP_EOL);
}
echo "USER PID RSS(kb) STAT START COMMAND" . PHP_EOL;
foreach ($out as $v) {
echo $v . PHP_EOL;
}
exit();
} //可执行命令
$cmds = [
'start',
'stop',
'restart',
'reload',
'close',
'status',
'list',
];
$shortopts = "dDh:p:n:";
$longopts = [
'help',
'daemon',
'nondaemon',
'host:',
'port:',
'name:',
];
$opts = getopt($shortopts, $longopts); if (isset($opts['help']) || $argc < 2) {
echo <<<HELP
用法:php swoole.php 选项 ... 命令[start|stop|restart|reload|close|status|list]
管理swoole-task服务,确保系统 lsof 命令有效
如果不指定监听host或者port,使用配置参数 参数说明
--help 显示本帮助说明
-d, --daemon 指定此参数,以守护进程模式运行,不指定则读取配置文件值
-D, --nondaemon 指定此参数,以非守护进程模式运行,不指定则读取配置文件值
-h, --host 指定监听ip,例如 php swoole.php -h127.0.0.1
-p, --port 指定监听端口port, 例如 php swoole.php -h127.0.0.1 -p9520
-n, --name 指定服务进程名称,例如 php swoole.php -ntest start, 则进程名称为SWOOLE_TASK_NAME_PRE-name
启动swoole-task 如果不指定 host和port,读取默认配置
强制关闭swoole-task 必须指定port,没有指定host,关闭的监听端口是 *:port,指定了host,关闭 host:port端口
平滑关闭swoole-task 必须指定port,没有指定host,关闭的监听端口是 *:port,指定了host,关闭 host:port端口
强制重启swoole-task 必须指定端口
平滑重启swoole-task 必须指定端口
获取swoole-task 状态,必须指定port(不指定host默认127.0.0.1), tasking_num是正在处理的任务数量(0表示没有待处理任务) HELP;
exit;
}
//参数检查
foreach ($opts as $k => $v) {
if (($k == 'h' || $k == 'host')) {
if (empty($v)) {
exit("参数 -h --host 必须指定值\n");
}
}
if (($k == 'p' || $k == 'port')) {
if (empty($v)) {
exit("参数 -p --port 必须指定值\n");
}
}
if (($k == 'n' || $k == 'name')) {
if (empty($v)) {
exit("参数 -n --name 必须指定值\n");
}
}
} //命令检查
$cmd = $argv[$argc - 1];
if (!in_array($cmd, $cmds)) {
exit("输入命令有误 : {$cmd}, 请查看帮助文档\n");
} //监听ip 127.0.0.1,空读取配置文件
$host = '127.0.0.1';
if (!empty($opts['h'])) {
$host = $opts['h'];
if (!filter_var($host, FILTER_VALIDATE_IP)) {
exit("输入host有误:{$host}");
}
}
if (!empty($opts['host'])) {
$host = $opts['host'];
if (!filter_var($host, FILTER_VALIDATE_IP)) {
exit("输入host有误:{$host}");
}
}
//监听端口,9501 读取配置文件
$port = 9501;
if (!empty($opts['p'])) {
$port = (int)$opts['p'];
if ($port <= 0) {
exit("输入port有误:{$port}");
}
}
if (!empty($opts['port'])) {
$port = (int)$opts['port'];
if ($port <= 0) {
exit("输入port有误:{$port}");
}
}
//进程名称 没有默认为 SWOOLE_TASK_NAME_PRE;
$name = SWOOLE_TASK_NAME_PRE;
if (!empty($opts['n'])) {
$name = $opts['n'];
}
if (!empty($opts['name'])) {
$name = $opts['n'];
}
//是否守护进程 -1 读取配置文件
$isdaemon = -1;
if (isset($opts['D']) || isset($opts['nondaemon'])) {
$isdaemon = 0;
}
if (isset($opts['d']) || isset($opts['daemon'])) {
$isdaemon = 1;
}
//启动swoole-task服务
if ($cmd == 'start') {
servStart($host, $port, $isdaemon, $name);
}
//强制停止swoole-task服务
if ($cmd == 'stop') {
if (empty($port)) {
exit("停止swoole-task服务必须指定port" . PHP_EOL);
}
servStop($host, $port);
}
//关闭swoole-task服务
if ($cmd == 'close') {
if (empty($port)) {
exit("停止swoole-task服务必须指定port" . PHP_EOL);
}
servClose($host, $port);
}
//强制重启swoole-task服务
if ($cmd == 'restart') {
if (empty($port)) {
exit("重启swoole-task服务必须指定port" . PHP_EOL);
}
echo "重启swoole-task服务" . PHP_EOL;
servStop($host, $port, true);
servStart($host, $port, $isdaemon, $name);
}
//平滑重启swoole-task服务
if ($cmd == 'reload') {
if (empty($port)) {
exit("平滑重启swoole-task服务必须指定port" . PHP_EOL);
}
echo "平滑重启swoole-task服务" . PHP_EOL;
servReload($host, $port, true);
}
//查看swoole-task服务状态
if ($cmd == 'status') {
if (empty($host)) {
$host = '127.0.0.1';
}
if (empty($port)) {
exit("查看swoole-task服务必须指定port(host不指定默认使用127.0.0.1)" . PHP_EOL);
}
servStatus($host, $port);
}
//查看swoole-task服务进程列表
if ($cmd == 'list') {
servList();
}

SwooleServer.php

 <?php

 /**
* Swoole服务端
*/
class SwooleServer { private $_serv = null;
private $_setting = array(); public function __construct($host = '0.0.0.0', $port = 9501) {
$this->_setting = array(
'host' => $host,
'port' => $port,
'env' => 'dev', //环境 dev|test|prod
'process_name' => SWOOLE_TASK_NAME_PRE, //swoole 进程名称
'worker_num' => 4, //一般设置为服务器CPU数的1-4倍
'task_worker_num' => 4, //task进程的数量
'task_ipc_mode' => 3, //使用消息队列通信,并设置为争抢模式
'task_max_request' => 10000, //task进程的最大任务数
'daemonize' => 1, //以守护进程执行
'max_request' => 10000,
'dispatch_mode' => 2,
'log_file' => SWOOLE_PATH . DIRECTORY_SEPARATOR . 'App' . DIRECTORY_SEPARATOR . 'Runtime' . DIRECTORY_SEPARATOR . 'Logs' . DIRECTORY_SEPARATOR . 'Swoole' . date('Ymd') . '.log', //日志
);
} /**
* 运行swoole服务
*/
public function run() {
$this->_serv = new \swoole_server($this->_setting['host'], $this->_setting['port']);
$this->_serv->set(array(
'worker_num' => $this->_setting['worker_num'],
'task_worker_num' => $this->_setting['task_worker_num'],
'task_ipc_mode ' => $this->_setting['task_ipc_mode'],
'task_max_request' => $this->_setting['task_max_request'],
'daemonize' => $this->_setting['daemonize'],
'max_request' => $this->_setting['max_request'],
'dispatch_mode' => $this->_setting['dispatch_mode'],
'log_file' => $this->_setting['log_file']
));
$this->_serv->on('Start', array($this, 'onStart'));
$this->_serv->on('Connect', array($this, 'onConnect'));
$this->_serv->on('WorkerStart', array($this, 'onWorkerStart'));
$this->_serv->on('ManagerStart', array($this, 'onManagerStart'));
$this->_serv->on('WorkerStop', array($this, 'onWorkerStop'));
$this->_serv->on('Receive', array($this, 'onReceive'));
$this->_serv->on('Task', array($this, 'onTask'));
$this->_serv->on('Finish', array($this, 'onFinish'));
$this->_serv->on('Shutdown', array($this, 'onShutdown'));
$this->_serv->on('Close', array($this, 'onClose'));
$this->_serv->start();
} /**
* 设置swoole进程名称
* @param string $name swoole进程名称
*/
private function setProcessName($name) {
if (function_exists('cli_set_process_title')) {
cli_set_process_title($name);
} else {
if (function_exists('swoole_set_process_name')) {
swoole_set_process_name($name);
} else {
trigger_error(__METHOD__ . " failed. require cli_set_process_title or swoole_set_process_name.");
}
}
} /**
* Server启动在主进程的主线程回调此函数
* @param $serv
*/
public function onStart($serv) {
if (!$this->_setting['daemonize']) {
echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server master worker start\n";
}
$this->setProcessName($this->_setting['process_name'] . '-master');
//记录进程id,脚本实现自动重启
$pid = "{$serv->master_pid}\n{$serv->manager_pid}";
file_put_contents(SWOOLE_TASK_PID_PATH, $pid);
} /**
* worker start 加载业务脚本常驻内存
* @param $server
* @param $workerId
*/
public function onWorkerStart($serv, $workerId) {
if ($workerId >= $this->_setting['worker_num']) {
$this->setProcessName($this->_setting['process_name'] . '-task');
} else {
$this->setProcessName($this->_setting['process_name'] . '-event');
}
// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false
define('APP_DEBUG', True);
// 定义应用目录
define('APP_PATH', SWOOLE_PATH . DIRECTORY_SEPARATOR . 'Application' . DIRECTORY_SEPARATOR);
// 定义应用模式
define('APP_MODE', 'cli');
// 引入ThinkPHP入口文件
require SWOOLE_PATH . DIRECTORY_SEPARATOR . 'ThinkPHP' . DIRECTORY_SEPARATOR . 'ThinkPHP.php';
} /**
* 监听连接进入事件
* @param $serv
* @param $fd
*/
public function onConnect($serv, $fd) {
if (!$this->_setting['daemonize']) {
echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server connect[" . $fd . "]\n";
}
} /**
* worker 进程停止
* @param $server
* @param $workerId
*/
public function onWorkerStop($serv, $workerId) {
if (!$this->_setting['daemonize']) {
echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server[{$serv->setting['process_name']} worker:{$workerId} shutdown\n";
}
} /**
* 当管理进程启动时调用
* @param $serv
*/
public function onManagerStart($serv) {
if (!$this->_setting['daemonize']) {
echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server manager worker start\n";
}
$this->setProcessName($this->_setting['process_name'] . '-manager');
} /**
* 此事件在Server结束时发生
*/
public function onShutdown($serv) {
if (file_exists(SWOOLE_TASK_PID_PATH)) {
unlink(SWOOLE_TASK_PID_PATH);
}
if (!$this->_setting['daemonize']) {
echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server shutdown\n";
}
} /**
* 监听数据发送事件
* @param $serv
* @param $fd
* @param $from_id
* @param $data
*/
public function onReceive($serv, $fd, $from_id, $data) {
if (!$this->_setting['daemonize']) {
echo "Get Message From Client {$fd}:{$data}\n\n";
}
$result = json_decode($data, true);
switch ($result['action']) {
case 'reload': //重启
$serv->reload();
break;
case 'close': //关闭
$serv->shutdown();
break;
case 'status': //状态
$serv->send($fd, json_encode($serv->stats()));
break;
default:
$serv->task($data);
break;
}
} /**
* 监听连接Task事件
* @param $serv
* @param $task_id
* @param $from_id
* @param $data
*/
public function onTask($serv, $task_id, $from_id, $data) {
$result = json_decode($data, true);
//用TP处理各种逻辑
$serv->finish($data);
} /**
* 监听连接Finish事件
* @param $serv
* @param $task_id
* @param $data
*/
public function onFinish($serv, $task_id, $data) {
if (!$this->_setting['daemonize']) {
echo "Task {$task_id} finish\n\n";
echo "Result: {$data}\n\n";
}
} /**
* 监听连接关闭事件
* @param $serv
* @param $fd
*/
public function onClose($serv, $fd) {
if (!$this->_setting['daemonize']) {
echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server close[" . $fd . "]\n";
}
} }

相关命令:

1、服务启动
#启动服务,不指定绑定端口和ip,则使用默认配置
php swoole.php start
#启动服务 指定ip 和 port
php swoole.php -h127.0.0.1 -p9501 start
#启动服务 守护进程模式
php swoole.php -h127.0.0.1 -p9501 -d start
#启动服务 非守护进程模式
php swoole.php -h127.0.0.1 -p9501 -D start
#启动服务 指定进程名称(显示进程名为 swooleServ-9510-[master|manager|event|task]
php swoole.php -h127.0.0.1 -p9501 -n 9501 start

2、强制服务停止
php swoole.php stop
php swoole.php -p9501 stop
php swoole.php -h127.0.0.1 -p9501 stop

3、关闭服务
php swoole.php close
php swoole.php -p9501 close
php swoole.php -h127.0.0.1 -p9501 close

4、强制服务重启
php swoole.php restart
php swoole.php -p9501 restart
php swoole.php -h127.0.0.1 -p9501 restart

5、平滑服务重启
php swoole.php reload
php swoole.php -p9501 reload
php swoole.php -h127.0.0.1 -p9501 reload

6、服务状态
php swoole.php status
php swoole.php -h127.0.0.1 -p9501 status

7、swoole-task所有启动实例进程列表(一台服务器swoole-task可以有多个端口绑定的实例)
php swoole.php list

Swoole-ThinkPHP.zip ( 1.14 MB )

thinkPHP3.2.3集成swoole扩展的更多相关文章

  1. 在laravel5.8中集成swoole组件----初步测试

    铺垫 前提是先安装swoole组件,我采用从pecl-----php扩展组件网下载swoole扩展包,然后切入到解压缩的扩展包中运行phpize命令, phpize是一种编译命令,可以在安装文件中生成 ...

  2. 编译安装PHP7并安装Redis扩展Swoole扩展

    编译安装PHP7并安装Redis扩展Swoole扩展 在编译php7的机器上已经有编译安装过php5.3以上的版本,从而依赖库都有了 本php7是编译成fpm-php 使用的, 如果是apache那么 ...

  3. centos下php安装swoole扩展

    官网:http://wiki.swoole.com/wiki/index/prid-1 国内Git镜像:http://git.oschina.net/matyhtf/swoole.git 下载源码后, ...

  4. Mac Pro 编译安装 PHP扩展 -- Swoole扩展

    回顾下先前的安装笔记: PHP5不重新编译,如何安装自带的未安装过的扩展,如soap扩展? #下载 Swoole-1.8.10后,开始编译# cd /Users/jianbao/Downloads/s ...

  5. Node.js的颠覆者:PHP的Swoole扩展

          最近2年Node.js很火,异步与协程是网络开发方面热门的话题.在追求新技术的同时,也应该反思下这里面存在的陷阱.Node.js确实是一门有趣好玩有个性的语言和技术,动态性,全异步回调的方 ...

  6. 【Swoole应用教程】一、Swoole扩展的编译安装部署

    介绍swoole扩展,从源码的下载,环境依赖,编译参数配置,常见编译问题,安装,配置等内容.期间还会介绍: Linux发行版本的选择 不同版本内核的差异 gcc/g++/clang 3种编译器介绍 a ...

  7. 【原】用PHP搭建基于swoole扩展的socket服务(附PHP扩展的安装步骤及Linux/shell在线手册)

    最近公司的一项目中,需要用PHP搭建一个socket服务. 本来PHP是不适合做服务的,因为和第三方合作,需要采用高效而稳定的TCP协议进行数据通信.经过多次尝试,最终选择了开源的PHP扩展:swoo ...

  8. DDD:四色原型中Role的 “六” 种实现方式和PHP的Swoole扩展

    目录 背景六种实现方式第一种:未显式体现角色的模式.第二种:使用“显式接口”显式体现角色的模式.第三种:使用“扩张方法”显式体现角色的模式.第四种:使用“领域服务”显式体现角色的模式.第五种:使用“包 ...

  9. Windows下swoole扩展的编译安装部署

    1. 到cygwin官网下载cygwin. 官网地址:https://www.cygwin.com/ 2. 打开下载好的cygwin安装包,开始安装cygwin. 选择cygwin的安装目录(这个同时 ...

随机推荐

  1. 【spoj8222】Substrings

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  2. Entity Framework使用Sqlite时的一些配置

    前段时间试着用Entity Framework for Sqlite环境,发现了一些坑坑洼洼,记录一下. 同时试了一下配置多种数据库,包括Sqlite.Sql Server.Sql Server Lo ...

  3. 在CentOS上安装Sublime Text

    CentOS 是基于 Red Hat (RHEL) 的, 其中并没有包管理工具 apt. 最近需要在装了 CentOS 系统的服务器上安装Sublime Text, 到官网上看了一下, 对其他 (De ...

  4. JSP重定向小例子(不讲原理)

    编写一个JSP页面lucknum.jsp,产生0-9之间的随机数作为用户幸运数字,将其保存到会话中,并重定向到另一个页面showLuckNum.jsp中,在该页面中将用户的幸运数字显示出来 luckn ...

  5. Python – locals和globals

    转载: Python两个内置函数--locals 和globals (学习笔记) Python两个内置函数locals 和globals, 这两个函数主要提供,基于字典的访问局部和全局变量的方式.在理 ...

  6. linux 基础 shell脚本命令

    #########shell脚本命令#### 1.diff diff file file1 ####比较两个文件的不同 -c ####显示周围的行 -u ####按照一格式统一输出生成补丁 -r ## ...

  7. markdown安装和使用

    下载 运行markdownpad2-setup.exe文件,下一步一直到结束. 使用 标题 列表 引用.网页链接.图片链接 代码框 星号

  8. gnuplot使用2

    设置图中连线的颜色.宽度.连线样式等 set style line 每个显示终端都有默认的线类型和点类型集合,可以通过在命令行输入: test查看,如下图显示了在wxt终端模式下默认的线的集合和点的集 ...

  9. [中英双语] 数学缩写列表 (List of mathematical abbreviations)

    List of mathematical abbreviations From Wikipedia, the free encyclopedia 数学缩写列表 维基百科,自由的百科全书 This ar ...

  10. elasticsearch api

    count curl -XGET http://21.3.5.121:9200/ipv4geo/service/_count -d '{"query":{"match&q ...