当前位置:  编程技术>软件工程/软件设计
本页文章导读:
    ▪轻量级web框架node.js和bottle      一.介绍 nodejs是一个轻量级的webserver框架,和python的bottle很类似,都是轻量级的web框架:写一个web server只需要一行代码就可以。 node.js平台的构建是基于Chrome's JavaScript runtime,即它是对Googl.........
    ▪设计模式之Proxy模式(C++实现)      代理模式,那么什么是代理模式勒,我们可以这样来理解,我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道 被代理人能做哪些事情不能做哪些事情吧,那就是.........
    ▪对多个tomcat部署同一个应用的认识      我做的客户端自动升级系统需要在内存或缓存中维持一根可用客户端产品的列表。考虑到在内存中进行读取的速度更快,于是选择在内存中存储一份可用客户端产品的列表。这个列表用一个静.........

[1]轻量级web框架node.js和bottle
    来源: 互联网  发布时间: 2013-11-19
一.介绍

nodejs是一个轻量级的webserver框架,和python的bottle很类似,都是轻量级的web框架:写一个web server只需要一行代码就可以。

node.js平台的构建是基于Chrome's JavaScript runtime,即它是对GoogleV8引擎(应用于Google Chrome浏览器)进行了封装。V8引擎执行Javascript的速度非常快,性能非常好。Node对一些特殊用例进行了优化,提供了替代的API,使得V8在非浏览器环境下运行得更好。

Node.js的官网为:http://www.nodejs.org/
Bottle的官网为:http://bottlepy.org/docs/dev/
二.安装说明

linux下的安装命令如下所示:

wget http://nodejs.org/dist/v0.10.5/node-v0.10.5.tar.gz
tar zxvf node-v0.10.5.tar.gz
cd node-v0.10.5.tar.gz
./configure --prefix=/home/zhaolincheung/local/nodejs
make && make intall

注:这里将node.js安装在/home/zhaolincheung/local/nodejs目录下。node.js的安装需要python2.6以上的支持,否则在执行./configure时会出错;node.js还需要gcc-c++的支持,所以系统需要实现安装gcc-c++。

通过 node -v来检查安装是否成功,如果返回:v.0.10.5,则说明安装成功。

至此node.js已经编译并安装完成。如需卸载,可以执行make uninstall进行卸载。

三.简单的hello world程序

学习任何语言或者框架,首先要写的程序就是hello world程序。这里也是这样,我们来写一个简单的hello world程序。

首先,编写helloworld.js,内容如下:

var http = require('http');

http.createServer(function(req, res) {
    res.writeHead(200, {'Content-Type':'text/plain'});
    res.end('Hello World\n');
}).listen(10001);

console.log('Server running at http://127.0.0.1:10001/');
其次,执行该文件:/home/zhaolincheung/local/nodejs/bin/node  helloworld.js
最后,通过浏览器访问http://127.0.0.1:1337便得到了hello world的响应。
四.开发进阶

当我们在使用node.js进行开发时,由于node.js是单线程的,所以对于耗时的操作,我们将它封装成函数采用回调函数的方式进行调用,这样可以让代码继续往下执行。当把耗时操作放在回调函数中,当耗时操作执行完毕后,回调函数会继续执行其函数内剩余的代码,它不会耽误回调函数外其他方法(请求)的执行。这个就是传说中的 回调 。我们给某个方法传递了一个函数,这个方法在有相应事件发生时调用这个函数来进行回调。这就是事件驱动的异步服务器端JavaScript和它的回调啦!

作者在网上看到了一个很好的node.js的入门资料,分享给大家,参考链接为:http://www.nodebeginner.org/index-zh-cn.html

下面介绍该资料中的一个例子,对不同的请求(url)进行相应的处理(路由)。它包含4个文件,index.js、server.js、router.js和requestHandlers.js。

其中index.js是定义了不同请求(url)的相应的处理(路由)方法,和启动webserver。

index.js的代码如下:

    var server = require("./server");
    var router = require("./router");
    var requestHandlers = require("./requestHandlers");

    var handle = {};
    handle["/"] = requestHandlers.start;
    handle["/start"] = requestHandlers.start;
    handle["/upload"] = requestHandlers.upload;

    server.start(router.route, handle);

server.js是server的创建和启动的实现。server.js的代码如下:

    var http = require("http");
    var url = require("url");   

    function start(route, handle) {
        function onRequest(request, response) {
            var pathname = url.parse(request.url).pathname;
            console.log("Request for " + pathname + " received.");
            
            route(handle, pathname, response);           
        } 
        
        http.createServer(onRequest).listen(65535);
        console.log('Server has started.');
    } 
    
    exports.start = start;

上面的onRequest函数就是回调函数。
回调函数就是将一个函数f1作为函数f2的参数进行调用,这样f2就不会因为f1的耗时操作而影响下面代码的执行,f1会等待相应事件的触发,即f1和f2会并行执行。

router.js是对不同的url调用函数(即下面的handler[pathname](response))进行处理。router.js的代码如下:

    function route(handle, pathname, response) {
        console.log("About to route a request for "+ pathname);
        if (typeof handle[pathname] == 'function') {
            handle[pathname](response);
        } else {
            console.log("No request handler found for " + pathname);
            response.writeHead(404,{'Content-Type': 'text/plain'});
            response.write('node.js: 404 Not found');
            response.end();
        } 
    }

    exports.route = route;
requestHandlers.js是不同url调用(路由)的方法的具体实现。requestHandlers.js的代码如下:

    function start(response) {
        console.log("Request handler 'start' was called.");
        response.writeHead(200, {'Content-Type': 'text/plain'});
        response.write("node.js: hello,start");
        response.end();
    }

    function upload(response){
        console.log("Request handler 'upload' was called.");    
        response.writeHead(200, {'Content-Type': 'text/plain'});
        response.write("node.js: hello,upload");
        response.end();
    }

    exports.start = start;
    exports.upload = upload;

运行这个例子的命令为:node index.js

当请求:http://127.0.0.1:65535/后的运行结果如下:


当请求:http://127.0.0.1:65535/upload后的运行结果如下:


代码链接:https://github.com/zhaolincheung/nodejs_demo

五.python的轻量级web框架bottle介绍

编写一个文件bottle_example.py,内容如下:

from bottle import route, run, template, static_file

@route('/hello')
def hello():
    return "Hello,world!"

test_home = './resource/'
@route('/rsrc/<p:path>')
def foo(p):
    return static_file(p, test_home)

run(host='localhost', port=8080)

执行这个文件,然后在浏览器中输入:http://localhost:8080/hello,页面会输出”hello,world”。

如下所示:


好,webserver已经跑起来了。接下来,我们研究webserver如何加载一个页面,首先我们在bottle_example.py的当前目录下新建一个文件夹resource,在resource目录下再建立一个docs文件夹,在docs目录下我们建一个index.html页面(即index.html存在在./resource/docs/目录下)。目录结构如下图所示:


因为bottle是基于路由进行响应处理的,我们该如何让bottle来加载这个index.html页面呢?
答案是:@route('/rsrc/<p:path>')这个路由能够实现。当用户在浏览器中打开http://localhost:8080/rsrc/docs/index.html页面时,就会触发这个路由,然后执行static_file这个方法来加载path路径指定的静态文件。这样便实现了加载静态页面的功能。



 
作者:lianxiang_biancheng 发表于2013-5-9 22:18:48 原文链接
阅读:115 评论:0 查看评论

    
[2]设计模式之Proxy模式(C++实现)
    来源: 互联网  发布时间: 2013-11-19

代理模式,那么什么是代理模式勒,我们可以这样来理解,我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道
被代理人能做哪些事情不能做哪些事情吧,那就是两个人具备同一个接口,代理人虽然不能干活,但是被
代理的人能干活呀。说起来很抽象,具体看实例还是来的实在!

 

比如西门庆找潘金莲,那潘金莲不好意思答复呀,咋办,找那个王婆做代理,表现在程序上时这样的:
先定义一种类型的女人

class KindWomen                           //指示这一类女人,王婆和潘金莲都属于这种女人
{
public:
	virtual void HappyWithMan() = 0;      //和男人开心,你懂的,王婆和潘金莲都会
	virtual void MakeEyesWithMan() = 0;   //给男人抛媚眼,王婆和潘金莲都会抛
};

//潘金莲出场
class Panjinlian:public KindWomen
{
public:
	virtual void HappyWithMan()
	{
		cout<<"潘金莲和男人开心.........."<<endl;
	}

	virtual void MakeEyesWithMan()
	{
		cout<<"潘金莲给男人抛媚眼."<<endl;
	}
};

//王婆出场
class WangPo:public KindWomen
{
private:
	KindWomen *kindWomen;
public:
	virtual void HappyWithMan()   //王婆自知老了,happy不动了,所以叫别人去干
	{
		kindWomen->HappyWithMan();
	}

	virtual void MakeEyesWithMan()  //王婆这么丑抛媚眼谁看啊,所以她又喊别人去抛
	{
		kindWomen->MakeEyesWithMan();
	}

	WangPo(KindWomen *m_pKindWomen)   //设置王婆到底代理的是谁,王婆开始构造
	{
		this->kindWomen = m_pKindWomen;
	}
};

//西门庆控制主函数
int main()
{
	//西门庆看上了潘金莲,但是潘金莲害羞啊,也不敢去抛媚眼,所以这时候就需要王婆帮他做一些事撒

	WangPo wangpo = new WangPo(new Panjinlian() );     //王婆出场,代理的是潘金莲

	wangpo.MakeEyesWithMan();                          //王婆开始抛媚眼,但是实际上是潘金莲在抛媚眼

	wangpo.HappyWithMan();                            //王婆开始和男人happy.....   实际上王婆哪能和男人开心,幕后是潘金莲在happy
	system("pause");
	return 0;
}

假如到现在还有个卢俊义他老婆也想和西门庆玩玩,那么他也可以找到王婆做代理人,同样继承了抽象类并实现方法,传递给王婆就可以做代理了,有的时候如果需要代理的对象过多,也可以结合享元模式使用,享元模式以后再说

 

总结一下:代理模式就是利用接口和多态来实现,对需要代理的人进行了浅封装,直接出面做事的人是代理人,但是实际上在做的是被代理的人

 

 

作者:effective_coder 发表于2013-5-11 1:09:18 原文链接
阅读:44 评论:0 查看评论

    
[3]对多个tomcat部署同一个应用的认识
    来源: 互联网  发布时间: 2013-11-19

我做的客户端自动升级系统需要在内存或缓存中维持一根可用客户端产品的列表。考虑到在内存中进行读取的速度更快,于是选择在内存中存储一份可用客户端产品的列表。这个列表用一个静态列表对象保存。当新增,修改,淘汰客户端产品时,会对从数据库向这个内存对象中进行同步。

这个设计是完全没有问题的。但是应用到多个tomcat部署这样的同一个实例的时候,问题就出来了。这也是今天上线的积累到的一个教训。上线之后发现,新增了两个客户端产品之后,刷客户端列表却时而能不显示任何信息,时而值显示一个客户端,有时候显示2个客户端,很不稳定。程序要做到的精确在这里变成了不确定因素。

和项目负责人沟通之后,发现问题的根源了。问题在于,我们同一个应用部署了6个tomcat,每个tomcat进程都有自己的进程空间,各自维护自己的内存变量。我通过Action进行可用客户端列表的更新操作只会触发一个tomcat下的应用进行数据同步。最终导致每次刷客户端列表的结果都不一样。

 

根据这个流程图可以发现,依赖Action进行数据操作,最终只会更新一个tomcat进程下的内存数据。这个问题最后通过设缓存的方式得以解决,即共享数据。如果一定要用将数据存在内存中的话,其实也是可以的,程序中增加一个轮询线程即可,用这个线程同步数据库中的数据。

其实一开始我是想到要用redis的方式缓存数据,但是我喜欢用新的方式解决问题。毕竟用内存存数据比用redis更快。虽然造成上线出问题,最后重新上线,但是并不后悔采用新的方式进行开发。

作者:bruce128 发表于2013-5-10 6:19:23 原文链接
阅读:17 评论:0 查看评论

    
最新技术文章:
▪主-主数据库系统架构    ▪java.lang.UnsupportedClassVersionError: Bad version number i...    ▪eclipse项目出现红色叉叉解决方案
▪Play!framework 项目部署到Tomcat    ▪dedecms如何做中英文网站?    ▪Spring Batch Framework– introduction chapter(上)
▪第三章 AOP 基于@AspectJ的AOP    ▪基于插件的服务集成方式    ▪Online Coding开发模式 (通过在线配置实现一个表...
▪观察者模式(Observer)    ▪工厂模式 - 程序实现(java)    ▪几种web并行化编程实现
▪机器学习理论与实战(二)决策树    ▪Hibernate(四)——全面解析一对多关联映射    ▪我所理解的设计模式(C++实现)——解释器模...
▪利用规则引擎打造轻量级的面向服务编程模式...    ▪google blink的设计计划: Out-of-Progress iframes    ▪FS SIP呼叫的消息线程和状态机线程
▪XML FREESWITCH APPLICATION 实现    ▪Drupal 实战    ▪Blink: Chromium的新渲染引擎
▪(十四)桥接模式详解(都市异能版)    ▪你不知道的Eclipse用法:使用Allocation tracker跟...    ▪Linux内核-进程
▪你不知道的Eclipse用法:使用Metrics 测量复杂度    ▪IT行业为什么没有进度    ▪Exchange Server 2010/2013三种不同的故障转移
▪第二章 IoC Spring自动扫描和管理Bean    ▪CMMI简介    ▪目标检测(Object Detection)原理与实现(六)
▪值班总结(1)——探讨sql语句的执行机制    ▪第二章 IoC Annotation注入    ▪CentOS 6.4下安装Vagrant
▪Java NIO框架Netty1简单发送接受    ▪漫画研发之八:会吃的孩子有奶吃    ▪比较ASP和ASP.NET
▪SPRING中的CONTEXTLOADERLISTENER    ▪在Nginx下对网站进行密码保护    ▪Hibernate从入门到精通(五)一对一单向关联映...
▪.NET领域驱动设计—初尝(三:穿过迷雾走向光...    ▪linux下的块设备驱动(一)    ▪Modem项目工作总结
▪工作流--JBPM简介及开发环境搭建    ▪工作流--JBPM核心服务及表结构    ▪Eclipse:使用JDepend 进行依赖项检查
▪windows下用putty上传文件到远程Linux方法    ▪iBatis和Hibernate的5点区别    ▪基于学习的Indexing算法
▪设计模式11---设计模式之中介者模式(Mediator...    ▪带你走进EJB--JMS编程模型    ▪从抽象谈起(二):观察者模式与回调
▪设计模式09---设计模式之生成器模式(Builder)也...    ▪svn_resin_持续优化中    ▪Bitmap recycle方法与制作Bitmap的内存缓存
▪Hibernate从入门到精通(四)基本映射    ▪设计模式10---设计模式之原型模式(Prototype)    ▪Dreamer 3.0 支持json、xml、文件上传
▪Eclipse:使用PMD预先检测错误    ▪Jspx.net Framework 5.1 发布    ▪从抽象谈起(一):工厂模式与策略模式
▪Eclipse:使用CheckStyle实施编码标准    ▪【论文阅读】《Chain Replication for Supporting High T...    ▪Struts2 Path_路径问题
▪spring 配置文件详解    ▪Struts2第一个工程helloStruts极其基本配置    ▪Python学习入门基础教程(learning Python)--2 Python简...
▪maven springmvc环境配置    ▪基于SCRUM的金融软件开发项目    ▪software quality assurance 常见问题收录
▪Redis集群明细文档    ▪Dreamer 框架 比Struts2 更加灵活    ▪Maven POM入门
▪git 分支篇-----不断更新中    ▪Oracle非主键自增长    ▪php设计模式——UML类图
▪Matlab,Visio等生成的图片的字体嵌入问题解决...    ▪用Darwin和live555实现的直播框架    ▪学习ORM框架—hibernate(二):由hibernate接口谈...
▪(十)装饰器模式详解(与IO不解的情缘)    ▪无锁编程:最简单例子    ▪【虚拟化实战】网络设计之四Teaming
▪OSGi:生命周期层    ▪Javascript/Jquery——简单定时器    ▪java代码 发送GET、POST请求
▪Entity Framework底层操作封装(3)    ▪HttpClient 发送GET、POST请求    ▪使用spring框架,应用启动时,加载数据
▪Linux下Apache网站目录读写权限的设置    ▪单键模式的C++描述    ▪学习ORM框架—hibernate(一):初识hibernate
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3