文档章节

fooking文档(不定期更新)

呵大官人
 呵大官人
发布于 2015/06/10 17:22
字数 1898
阅读 1326
收藏 7
点赞 2
评论 23

简介

fooking是一个分布式网关,其主要目的是用于承载客户端长连接,然后将接受的客户端数据以fastcgi协议转发给后端业务逻辑处理服务器,让后端服务真正独立的同时还无需关心扩展的问题,简单配置即可。

fooking服务包含两部分,一部分是gateway主要用于承载客户端链接、转发请求;另一部分是router,主要用于各gateway之间的消息传递、数据统计等。gateway可以开多个进程,并且可以配置多台服务器来提升连接数。

优势

1、非侵入式,无需安装扩展,php版本随你挑,后端错误逻辑不会影响网关正常服务

2、开发简单,做为后端php可以像写web一样,轻松echo即可

3、动态网关,方便线上应急扩容

4、session维持,每个客户端分配唯一ID,无需关心fd

5、单播/组播,指定一人或者多人或者群组发送消息

6、服务器状态监控,监控信息细化到每个gateway的进程

7、客户端事件通知,连接打开与关闭

8、无语言限制,后端只需遵循fastcgi协议即可

9、自定义协议,可用lua自定义协议处理

10、负载均衡,配合分配策略,可让每台服务器,甚至每个进程的连接数量基本相同

getting started

既然你已经点到这里了,那么我相信你应该了解fooking的基本架构了,那么开始我们的fooking初体验。

fooking使用c++开发,安装g++、make等基础开发工具,那么接下来的事就简单了(windows下可以使用cygwin编译为exe)。

git clone http://git.oschina.net/scgywx/fooking.git
make

第一招,启动router。在启动之前我得再BB两句,fooking的配置文件和脚本都是使用lua,所以建议了解一下lua的基本知识(只是建议,不是必须)。

router的配置文件位于src/router.lua,配置文件里面的参数都有详细的解释,这里就不多说了,接下来只需要按这个姿势执行命令就能启动router了。

cd src
./fooking ../router.lua

第二招,启动gateway。配置文件位于src/config.lua,配置参数相必阁下见其名便能知其意,只是其中几个参数需要说明,1是ROUTER_HOST与ROUTER_PORT,这里配置刚刚启动router的host与port,主要与router连通;2是BACKEND_SERVER,列出php-fpm的host与port即可(如果是unix domain socket,要在前面加unix://前缀),3是FASTCGI_ROOT与FASTCGI_FILE,分别是php脚本路径与脚本文件名(仅测试可指到example/chat目录下)。启动命令如下

./fooking ../config.lua

第三招,启动fpm;作为php后端服务端,php-fpm肯定少不了。

service php-fpm start

第四招,启动nginx,其实这一步,可有可无的,主要就是用来访问example/chat下面的静态资源,把目录指到example/chat目录下即可(当然你也可以不用装nginx,直接用浏览器打开example/chat/index.html也行)。

service nginx start

第五招,测试chat,打开你的浏览器(需要支持websocket协议的浏览器),直接localhost,应该就能聊天了。这个聊天的例子使用了websocket协议,协议部分的实现位于scripts/WebSocket.lua,并且这个文件也配置在config.lua的SCRIPT_FILE参数中。

协议说明

前端协议

前端协议是指gateway与客户端的通信协议,默认是使用4字节数据长度(大端)+数据,当然你可以使用lua来自定义协议(需要配置SCRIPT_FILE),在lua自定义协议的脚本里有4个事件onConnect,onClose,onInput,onOutput分别对应连接、关闭、输入(解包)、输出(打包),具体更详细的用法可以参见scripts/WebSocket.lua,里面实现了websocket协议的打包与解包。

后端协议

后端协议是指gateway与后端服务的通信协议,使用fastcgi与php-fpm通信,这个对于phper来说应该不陌生,并且使用很简单;由于客户端的请求已经在前端协议中处理了,所以发给php的都是完整的数据包,所以在php里面要获取数据包内容就很简单了,只需要这样:

file_get_contents("php://input");

另外自定义参数还可以通过配置文件的FASTCGI_PARAMS来随意添加,在php里面只需要使用$_SERVER就能获取参数值了,需要注意的是SESSIONID、EVENT、REMOTE_ADDR、REMOTE_PORT已经被fooking使用,请不需添加在自定义参数列表内,具体说明如下:

$sessionid = $_SERVER['SESSIONID'];//客户端唯一ID
$event = $_SERVER['EVENT'];//事件类型(0-表示消息事件,1-表示连接事件,2-表示关闭事件)
$ip = $_SERVER['REMOTE_ADDR'];//客户端ip
$port = $_SERVER['REMOTE_PORT'];//客户端端口
$myparam = $_SERVER['MY_PARAM'];//自定义参数

那么php需要返回消息给客户端怎么办?首先你要告诉fooking,你要返回多少数据给客户端,因此你需要设置header("Content-Length: 字节数"), 接下来只需要echo数据就好了,是不是很简单?

header("Content-Length: 11");
echo "hello world";

如果你还想指定数据数据的偏移位置,那么你可以使用Content-Offset,比如:

header("Content-Length: 5");
header("Content-Offset: 6");//也可以使用-5,效果一样。
echo "hello world";//客户端会收到world

什么时候会用到Content-Offset呢?比如你有debug、warning等调试信息在消息前面,这时候就可以使用Content-Offset做负值偏移,同时还能在fooking的日志中完整的看到debug、warning等信息。

那为什么要把debug、warning信息放在消息前面?因为正文消息可能是加密或者其它二进制流信息,如果带有\0的字符,那么日志就会被截断,所以把消息放在最后确保日志能完整输出。

单播/组播

fooking提供的组播类似于redis的pub/sub,当你对某个组感兴趣,可以加入到该组,而该组有消息则会通知你。同时每个client的信息和组信息在gateway上有存储,并且会同步到router上,所以如果你想要给某个组或者单人发消息,只需要发到router即可,那么对应php的后端,只需要包含api.php即可。

include 'api.php';
$router = new RouterClient('router host', 'router port');
$router->sendMsg('session id', 'hi');//指定单人发消息
$router->sendAllMsg('hi');//给所有人发消息
$router->kickUser('session id');//关闭指定连接
$router->addChannel('channel name', 'session id');//加入到指定组
$router->delChannel('channel name', 'session id');//从指定组移除
$router->publish('channel name', 'msg');//向指定组发送消息
$router->info();//获取当前router信息

服务器分配策略

通过使用info接口拉取到各服务器监控信息,可以很轻松实现服务器均匀分配,info接口返回如下:

Array(
    [clients] => 8 //当前总连接数
    [channels] => 0 //当前channel总数
    [gateways] => Array(//服务器列表
         [1] => Array(
             [0] => Array(
                  [serverid] => 1,//服务器id(这个就是config.lua里面的SERVER_ID)
                  [workerid] => 0,//进程编号
                  [clients] => 4,//当前进程负责连接数
                  [channels] => 0,//当前进程负责channel数
              )
             [1] => Array(
                  [serverid] => 1,
                  [workerid] => 1,
                  [clients] => 4,
                  [channels] => 0,
             )  
        )
    ) 
)

知道info接口数据之后,我们再根据每台服务器ID当前连接数进行处理,分配当前连接数最少的服务器给客户端,代码如下:

$router = new RouterClient();
$info = $router->info();
$gateways = array();
foreach($info[‘gateway’] as $serverid => $workers){
	foreach($workers as $worker){
		$gateways[$serverid]+= $worker[‘clients’];
	}
}

asort($gateways);
$serverid = key($gateways);

 

© 著作权归作者所有

共有 人打赏支持
呵大官人

呵大官人

粉丝 118
博文 17
码字总数 15799
作品 1
普陀
加载中

评论(23)

pinopino
pinopino

引用来自“pinopino”的评论

博主你好,请教一个比较泛化的问题,网关一般跟后端实际业务服之间一般是怎么连接的呢?前端可能有n多客户端连接到网关上来,然后发送自己的请求,那对于这些请求网关也需要建立n多个连接到后端业务服吗?

引用来自“呵大官人”的评论

N个客户端并不代表他们都同时发起请求,假设有M个客户端同时发起请求,那么网关则需要M个连接到后端业务上。但如果业务服务器使用一些支持多路复用协议(比如fastcgi,http2.0),就可以减少很多连接,甚至有时候只需要一个连接就可以了。

引用来自“pinopino”的评论

感谢!
让我们现在假设有N个客户端,他们之中有M个同时发送请求,所以我期望能在网关这里有一个连接池,这样M个请求同时过来我也可以有M个可用的连接(再多的话只能排队等候)。
那么问,
1. 这样的结构可行吗?
2. 仔细思考一下就会发现,M个可用连接在同一时间只能允许一个请求/响应经过,这样假如后续请求想要复用这个链接就必须等到前一个完成才行,略坑,这是否就是你所说的支持多路复用?
3. 接问题2,如果是,我现在并没有工作在http层,我是直接撸socket tcp,这个有现成的可用的实现么?
4. 接问题3,如果没有,现在业界一般还有哪些比较成熟的处理方式呢?我在猜想能不能搞一个“缓冲区”--队列,请求可以先塞队列,然后做人工合并之类的处理。这样也许也能达到多路复用的效果

5. 跟上述不相关的一个小问题,网关能不能直接解包根据ip做纯转发?fooking是这样的角色吗?还是说fooking是应用层网关,自定义协议之后根据规则做转发?
thx in advance :)

引用来自“呵大官人”的评论

1、理论上是可行的
2、多路复用协议是指同一个连接上可以发送多个数据包,每个数据包有唯一ID,业务处理了哪一条就返回哪一条,无需关心数据包顺序。所以就算只有M个连接,也可以发送N个数据包(N>M)。你所说的连接池的方式是把请求队列在网关上(数据还在网关服务器),而使用多路复用的方式是把请求队列在业务服务器上(数据已经送达到业务服务器)。
3、fooking就是tcp的
4、如上,但是现在没有转发规则支持,如果你需要定制化的方案,可以自己撸的。
5、fooking就是这样,解包,然后转发至后端
感谢博主的细心回复,笔芯 :)
呵大官人
呵大官人

引用来自“pinopino”的评论

博主你好,请教一个比较泛化的问题,网关一般跟后端实际业务服之间一般是怎么连接的呢?前端可能有n多客户端连接到网关上来,然后发送自己的请求,那对于这些请求网关也需要建立n多个连接到后端业务服吗?

引用来自“呵大官人”的评论

N个客户端并不代表他们都同时发起请求,假设有M个客户端同时发起请求,那么网关则需要M个连接到后端业务上。但如果业务服务器使用一些支持多路复用协议(比如fastcgi,http2.0),就可以减少很多连接,甚至有时候只需要一个连接就可以了。

引用来自“pinopino”的评论

感谢!
让我们现在假设有N个客户端,他们之中有M个同时发送请求,所以我期望能在网关这里有一个连接池,这样M个请求同时过来我也可以有M个可用的连接(再多的话只能排队等候)。
那么问,
1. 这样的结构可行吗?
2. 仔细思考一下就会发现,M个可用连接在同一时间只能允许一个请求/响应经过,这样假如后续请求想要复用这个链接就必须等到前一个完成才行,略坑,这是否就是你所说的支持多路复用?
3. 接问题2,如果是,我现在并没有工作在http层,我是直接撸socket tcp,这个有现成的可用的实现么?
4. 接问题3,如果没有,现在业界一般还有哪些比较成熟的处理方式呢?我在猜想能不能搞一个“缓冲区”--队列,请求可以先塞队列,然后做人工合并之类的处理。这样也许也能达到多路复用的效果

5. 跟上述不相关的一个小问题,网关能不能直接解包根据ip做纯转发?fooking是这样的角色吗?还是说fooking是应用层网关,自定义协议之后根据规则做转发?
thx in advance :)
1、理论上是可行的
2、多路复用协议是指同一个连接上可以发送多个数据包,每个数据包有唯一ID,业务处理了哪一条就返回哪一条,无需关心数据包顺序。所以就算只有M个连接,也可以发送N个数据包(N>M)。你所说的连接池的方式是把请求队列在网关上(数据还在网关服务器),而使用多路复用的方式是把请求队列在业务服务器上(数据已经送达到业务服务器)。
3、fooking就是tcp的
4、如上,但是现在没有转发规则支持,如果你需要定制化的方案,可以自己撸的。
5、fooking就是这样,解包,然后转发至后端
pinopino
pinopino

引用来自“pinopino”的评论

博主你好,请教一个比较泛化的问题,网关一般跟后端实际业务服之间一般是怎么连接的呢?前端可能有n多客户端连接到网关上来,然后发送自己的请求,那对于这些请求网关也需要建立n多个连接到后端业务服吗?

引用来自“呵大官人”的评论

N个客户端并不代表他们都同时发起请求,假设有M个客户端同时发起请求,那么网关则需要M个连接到后端业务上。但如果业务服务器使用一些支持多路复用协议(比如fastcgi,http2.0),就可以减少很多连接,甚至有时候只需要一个连接就可以了。
感谢!
让我们现在假设有N个客户端,他们之中有M个同时发送请求,所以我期望能在网关这里有一个连接池,这样M个请求同时过来我也可以有M个可用的连接(再多的话只能排队等候)。
那么问,
1. 这样的结构可行吗?
2. 仔细思考一下就会发现,M个可用连接在同一时间只能允许一个请求/响应经过,这样假如后续请求想要复用这个链接就必须等到前一个完成才行,略坑,这是否就是你所说的支持多路复用?
3. 接问题2,如果是,我现在并没有工作在http层,我是直接撸socket tcp,这个有现成的可用的实现么?
4. 接问题3,如果没有,现在业界一般还有哪些比较成熟的处理方式呢?我在猜想能不能搞一个“缓冲区”--队列,请求可以先塞队列,然后做人工合并之类的处理。这样也许也能达到多路复用的效果

5. 跟上述不相关的一个小问题,网关能不能直接解包根据ip做纯转发?fooking是这样的角色吗?还是说fooking是应用层网关,自定义协议之后根据规则做转发?
thx in advance :)
呵大官人
呵大官人

引用来自“pinopino”的评论

博主你好,请教一个比较泛化的问题,网关一般跟后端实际业务服之间一般是怎么连接的呢?前端可能有n多客户端连接到网关上来,然后发送自己的请求,那对于这些请求网关也需要建立n多个连接到后端业务服吗?
N个客户端并不代表他们都同时发起请求,假设有M个客户端同时发起请求,那么网关则需要M个连接到后端业务上。但如果业务服务器使用一些支持多路复用协议(比如fastcgi,http2.0),就可以减少很多连接,甚至有时候只需要一个连接就可以了。
pinopino
pinopino
博主你好,请教一个比较泛化的问题,网关一般跟后端实际业务服之间一般是怎么连接的呢?前端可能有n多客户端连接到网关上来,然后发送自己的请求,那对于这些请求网关也需要建立n多个连接到后端业务服吗?
rochael
rochael

引用来自“呵大官人”的评论

引用来自“rochael”的评论

引用来自“呵大官人”的评论

引用来自“rochael”的评论

问一下,fooking 怎么处理粘包的问题,比较可能由于网络问题,两个请求包差不多同时到达服务器, onRead收到的数据是两个请求的,即使在 lua中的 onRead中把两个包分开,但是 onRead只能 return 1次,这个要怎么处理,才能使两个粘在一起的包客户端都能收到回复?
因为fooking本身带有协议处理,所以会根据协议分包,即使两个包粘在一起,分包之后就会是两个包,同时也就会有两次onread的调用。

回复@呵大官人 : 我现在遇到的问题是,两次客户端发过来的数据在一次onRead 的input 里,在onRead里手动分开了,都还是没有用,有没有办法把分开的两个包分两次 发给 backend服务器?

引用来自“呵大官人”的评论

哦,我知道了,你在onRead里面,你单个包占用多大你就调用fb.seek(input, 包大小),就可以了。不要直接seek整个input大小。。

引用来自“rochael”的评论

是这样写的,但是还是不行,代码贴出来了,帮我看看吧,谢谢了
不要用递归。。onRead返回之后,才会把output发给后端。
递归后output里面包含了两个包的数据,一次性发到后端了。

回复@呵大官人 : 好的,搞定了,不递归,没处理完的数据下次会自动再回调一次onRead,我开始以为后面会丢掉,谢谢了!
呵大官人
呵大官人

引用来自“rochael”的评论

引用来自“呵大官人”的评论

引用来自“rochael”的评论

问一下,fooking 怎么处理粘包的问题,比较可能由于网络问题,两个请求包差不多同时到达服务器, onRead收到的数据是两个请求的,即使在 lua中的 onRead中把两个包分开,但是 onRead只能 return 1次,这个要怎么处理,才能使两个粘在一起的包客户端都能收到回复?
因为fooking本身带有协议处理,所以会根据协议分包,即使两个包粘在一起,分包之后就会是两个包,同时也就会有两次onread的调用。

回复@呵大官人 : 我现在遇到的问题是,两次客户端发过来的数据在一次onRead 的input 里,在onRead里手动分开了,都还是没有用,有没有办法把分开的两个包分两次 发给 backend服务器?

引用来自“呵大官人”的评论

哦,我知道了,你在onRead里面,你单个包占用多大你就调用fb.seek(input, 包大小),就可以了。不要直接seek整个input大小。。

引用来自“rochael”的评论

是这样写的,但是还是不行,代码贴出来了,帮我看看吧,谢谢了
local startpos = 0
if len + headLen < l then
startpos = len + headLen + 1
s = string.sub(s, startpos)
-- print(" 包长 > 1个包", l, len, startpos)
return parse(l - len - headLen, s, input, output)
end

把你上面这段代码删了,应该就好了。
呵大官人
呵大官人

引用来自“rochael”的评论

引用来自“呵大官人”的评论

引用来自“rochael”的评论

问一下,fooking 怎么处理粘包的问题,比较可能由于网络问题,两个请求包差不多同时到达服务器, onRead收到的数据是两个请求的,即使在 lua中的 onRead中把两个包分开,但是 onRead只能 return 1次,这个要怎么处理,才能使两个粘在一起的包客户端都能收到回复?
因为fooking本身带有协议处理,所以会根据协议分包,即使两个包粘在一起,分包之后就会是两个包,同时也就会有两次onread的调用。

回复@呵大官人 : 我现在遇到的问题是,两次客户端发过来的数据在一次onRead 的input 里,在onRead里手动分开了,都还是没有用,有没有办法把分开的两个包分两次 发给 backend服务器?

引用来自“呵大官人”的评论

哦,我知道了,你在onRead里面,你单个包占用多大你就调用fb.seek(input, 包大小),就可以了。不要直接seek整个input大小。。

引用来自“rochael”的评论

是这样写的,但是还是不行,代码贴出来了,帮我看看吧,谢谢了
不要用递归。。onRead返回之后,才会把output发给后端。
递归后output里面包含了两个包的数据,一次性发到后端了。
rochael
rochael

引用来自“rochael”的评论

引用来自“呵大官人”的评论

引用来自“rochael”的评论

问一下,fooking 怎么处理粘包的问题,比较可能由于网络问题,两个请求包差不多同时到达服务器, onRead收到的数据是两个请求的,即使在 lua中的 onRead中把两个包分开,但是 onRead只能 return 1次,这个要怎么处理,才能使两个粘在一起的包客户端都能收到回复?
因为fooking本身带有协议处理,所以会根据协议分包,即使两个包粘在一起,分包之后就会是两个包,同时也就会有两次onread的调用。

回复@呵大官人 : 我现在遇到的问题是,两次客户端发过来的数据在一次onRead 的input 里,在onRead里手动分开了,都还是没有用,有没有办法把分开的两个包分两次 发给 backend服务器?

引用来自“呵大官人”的评论

哦,我知道了,你在onRead里面,你单个包占用多大你就调用fb.seek(input, 包大小),就可以了。不要直接seek整个input大小。。
是这样写的,但是还是不行,代码贴出来了,帮我看看吧,谢谢了
rochael
rochael
```
function onRead(conn, requestid, input, output)
  local l = fb.size(input);
  local s = fb.data(input);
  return parse(l, s, input, output)
end
function parse( l, s, input, output )
  local headLen = 13
  local pack = SocketPack.new()
  pack:writeBuf(s)
  local flag, len = pack:parsePack()
  if not flag then
    print("check header error")
    return -1
  end


  str = pack:readStringUInt()
  fb.append(output, str)
  fb.seek(input, len + headLen)
  -- print(" 发送数据 ---> len, str", len, str)
  local startpos = 0
  if len + headLen < l then
    startpos = len + headLen + 1
    s = string.sub(s, startpos)
    -- print(" 包长 > 1个包", l, len, startpos)
    return parse(l - len - headLen, s, input, output)
  end
  return 1
end
```

代码是这样的
Go语言开发分布式聊天室

声明 我是一个刚学go语言的菜鸟,还没有资格谈论什么技术分享,只是为了展示fooking的实际应用,同时把我用go写的聊天室代码贴出来供大家消遣,如果有入不了各位法眼的代码,望轻喷。该聊天室...

呵大官人 ⋅ 2015/08/28 ⋅ 6

php长连接,奏是这么简单

说到长链接大家肯定不陌生,就是复用一个链接持续不断的进行数据交互,它不像那些一夜情似的服务,需要频繁的打开和关闭链接,效率低的同时还增加了业务的复杂度。在裆下很多互联网业务场景都...

呵大官人 ⋅ 2015/06/09 ⋅ 49

fooking 0.1.0 发布,分布式网关服务器

fooking是一个分布式网关服务器,主要用于承载客户端连接,将客户端请求转发到后端逻辑服务器,然后把逻辑服务器返回的结果转发到客户端。他类似Nginx,使用Nginx + FastCGI Server(如:FPM...

呵大官人 ⋅ 2015/08/28 ⋅ 14

PHP游戏开发之大家一起来玩泡泡堂

在fooking完成的第一版里面附带了一个简单的聊天室来说明了fooking的功能,这次利用周末两天写了一个稍微比聊天室复杂点的小游戏!能跑动,能放泡,能聊天,能控制死亡。演示地址:http://18...

呵大官人 ⋅ 2014/12/15 ⋅ 5

呵大官人/fooking

fooking是一个分布式网关服务器,主要用于承载客户端连接,将客户端请求转发到后端逻辑服务器,然后把逻辑服务器返回的结果转发到客户端. 他类似Nginx,使用Nginx + FastCGI Server(如:FPM...

呵大官人 ⋅ 2014/12/10 ⋅ 0

PHP分组聊天室--fooking现实

最近也是比较忙,公司打码,回家继续打,越忙越折腾! 一个不小心半夜一点了,花了一晚上时间终于把这个分组聊天室写完了,前两天刚把fooking的websocket协议加上,纯lua实现。 fooking的项目...

呵大官人 ⋅ 2015/04/02 ⋅ 13

./src/fooking config.lua 执行的时候遇到问题。

@IM鑫爷 你好,想跟你请教个问题: 我在编译成功以后,./src/fooking config.lua 执行的时候遇到问题。,以下是报错信息,还请能给个回复 root@vagrant-ubuntu-trusty:/home/vagrant/fooking...

catro2011 ⋅ 2016/05/13 ⋅ 1

分布式游戏网关--fooking

fooking 不是什么 1、不是框架 2、不是扩展 3、不是Http server 是什么 fooking是一个分布式游戏网关,主要用于承载长连接,将客户端的数据包完整的转发给后端,后端服务处理完之后由fooking...

呵大官人 ⋅ 2014/12/23 ⋅ 3

EasyMybatis 1.5.0 发布,支持 PostgreSQL , SQLite

EasyMybatis 1.5.0 发布,此次更新内容如下: 支持PostgreSQL、SQLite 新增在线开发文档,文档地址:http://durcframework.gitee.io/easymybatis-doc/ 修复若干BUG 开发文档包含了对框架的介...

tanghc ⋅ 2017/12/26 ⋅ 4

Shell和Python学习教程总结

博友们好,由于运维相关技术不断发展,个人能力也不断提高,渐渐积累的经验不能及时更新到以往的博文中。因此,为了更好的帮助大家学习运维技术,特地针对Shell和Python脚本语言总结了文档,...

李振良OK ⋅ 2017/02/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 12分钟前 ⋅ 0

CentOS开机启动subversion

建立自启动脚本: vim /etc/init.d/subversion 输入如下内容: #!/bin/bash## subversion startup script for the server## chkconfig: 2345 90 10# description: start the subve......

随风而飘 ⋅ 15分钟前 ⋅ 0

Nginx + uwsgi @ubuntu

uwsgi 安装 sudo apt-get install python3-pip # 注意 ubuntu python3默认没有安装pippython3 -m pip install uwsgi 代码(test.py) def application(env, start_response): start_res......

袁祾 ⋅ 16分钟前 ⋅ 0

版本控制工具

CSV , SVN , GIT ,VSS

颖伙虫 ⋅ 19分钟前 ⋅ 0

【2018.06.19学习笔记】【linux高级知识 13.1-13.3】

13.1 设置更改root密码 13.2 连接mysql 13.3 mysql常用命令

lgsxp ⋅ 26分钟前 ⋅ 0

LVM

LVM: 硬盘划分分区成物理卷->物理卷组成卷组->卷组划分逻辑分区。 1.磁盘分区: fdisk /dev/sdb 划分几个主分区 输入t更改每个分区类型为8e(LVM) 使用partprobe生成分区的文件:如/dev/sd...

ZHENG-JY ⋅ 54分钟前 ⋅ 0

彻底删除Microsoft Office的方法

参照此链接彻底删除Office https://support.office.com/zh-cn/article/%e4%bb%8e-pc-%e5%8d%b8%e8%bd%bd-office-9dd49b83-264a-477a-8fcc-2fdf5dbf61d8?ui=zh-CN&rs=zh-CN&ad=CN......

Kampfer ⋅ 今天 ⋅ 0

大盘与个股之间关系

大盘走多:积极出手 顺势加码 大盘走空: 少量出手 退场观望 大盘做头:逆势减码 少量操作 大盘做底 : 小量建仓 小量试单

guozenhua ⋅ 今天 ⋅ 0

Day16 LVM(逻辑卷管理)与磁盘故障小案例

lvm详解 简述 LVM的产生是因为传统的分区一旦分区好后就无法在线扩充空间,也存在一些工具能实现在线扩充空间但是还是会面临数据损坏的风险;传统的分区当分区空间不足时,一般的解决办法是再...

杉下 ⋅ 今天 ⋅ 0

rsync实现多台linux服务器的文件同步

一、首先安装rsync,怎样安装都行,rpm,yum,还是你用源码安装都可以。因为我用的是阿里云的ESC,yum install rsync就ok了。 二、配置rsync服务 1.先建立个同步数据的帐号 123 groupadd r...

在下头真的很硬 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部