Linux C 开发 – libevent

Libevent介绍
libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。著名分布式缓存软件memcached也是libevent based,而且libevent在使用上可以做到跨平台,而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。
官方网站:http://libevent.org/
英文文档:http://www.wangafu.net/~nickm/libevent-book/
中文文档:http://www.cppblog.com/mysileng/category/20374.html
Libevent是基于事件的网络库。说的通俗点,例如我的客户端连接到服务端属于一个连接的事件,当这个事件触发的时候就会去处理。
该文章阅读过程中,请结合下面的socket例子,可能会更加清晰的理解每一个接口的用法。

Continue reading “Linux C 开发 – libevent”

常用的C/C++框架和库、开发资源

– 1. Webbench

Webbench是一个在Linux下使用的非常简单的网站压测工具。它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力。Webbench使用C语言编写, 代码实在太简洁,源码加起来不到600行。

下载链接:http://home.tiscali.cz/~cz210552/webbench.html

Continue reading “常用的C/C++框架和库、开发资源”

JS是按值传递还是按引用传递

按值传递 VS. 按引用传递

按值传递(call by value)是最常用的求值策略:函数的形参是被调用时所传实参的副本。修改形参的值并不会影响实参。
按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被修改,实参也会被修改。同时两者指向相同的值。
按引用传递会使函数调用的追踪更加困难,有时也会引起一些微妙的BUG。
按值传递由于每次都需要克隆副本,对一些复杂类型,性能较低。两种传值方式都有各自的问题。
Continue reading “JS是按值传递还是按引用传递”

构建负载均衡服务器之二 LVS详解及应用

在上一篇中介绍了负载均衡及集群的原理,本篇主要介绍下下实现负载均衡的软件之LVS的原理及应用。

 

一、LVS的介绍

1、  LVS的定义

一般来说,LVS采用三层结构:负载调度器、服务器池、共享存储。工作在TCP/IP协议的四层,其转发是依赖于四层协议的特征进行转发的,由于其转发要依赖于协议的特征进行转发,因此需要在内核的TCP/IP协议栈进行过滤筛选,可想而知,这就需要在内核的模块来完成,而这样的过滤转发规则又是由管理员进行定义的,所以,LVS就是两段式的架构设计,在内核空间中工作的是”ipvs”,而在用户空间中工作的,用来定义集群服务规则的是”ipvsadm”。这就很容易想到iptables而LVS正好工作在iptables的input链上。

 

2、  LVS的组成

ipvsadm:用于管理集群服务的命令行工具,工作于Linux系统中的用户空间。

ipvs:为lvs提供服务的内核模块,工作于内核空间 (相对于是框架,通过ipvsadm添加规则,来实现ipvs功能)。

注:在linux内核2.4.23之前的内核中模块默认是不存在的,需要自己手动打补丁,然后把此模块编译进内核才可以使用此功能。

Continue reading “构建负载均衡服务器之二 LVS详解及应用”

构建负载均衡服务器之一 负载均衡与集群详解

一、什么是负载均衡

    首先我们先介绍一下什么是负载均衡: 负载平衡(Load balancing)是一种计算机网络技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最佳化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。这是来自维基百科的介绍。负载均衡的目的,就在于平衡负载,给用户提供优质,可靠,稳定的服务。

wKiom1VhRJrRo4JbAAD2NT8fP1M497.jpg

上图是个最简单的负载均衡实例, 应用服务器并不直接与用户相连, 用户连接负载均衡服务器,然后由负载均衡服务器把消息转发给实际应用服务器。负载均衡器内部会根据应用服务器的负载情况,决定把消息转发给哪台服务器处理。同时负载均衡器还可以对用户屏蔽应用服务器失效,只要把用户的消息转发到非失效服务器即可。

 

提到负载均衡,就不能不介绍另外一个概念: 集群。集群就是一组部署有相同应用的服务器。例如web 服务器。用户的请求无论连接到哪台服务器上,都能得到相同的处理。这样我们实现一种服务器,可以将用户的请求根据特定规则转发到应用服务器上进行处理。就实现了完整的集群处理系统。这个服务器如果实现了后台服务器感知和配置功能,能够了解后台服务器的可用情况。就可以被称作为负载均衡器。

 

负载均衡在目前网络服务规模越来越庞大的情况下,成为一个大型服务器系统必须要面对的问题。随着用户和业务的增多,来自用户的访问量和数据流量不断增大,对服务器的计算能力和储存要求也在不断增加,单台服务器根本无法承担这么庞大的数据处理请求。这个时候,我们必须利用集群技术,采用一组服务器对来自用户的请求进行处理,服务器的数量要能够不断的扩充。在集群的前端,我们采用负载均衡技术,平均分散用户的请求到不同的处理服务器,并且能够在集群中某个服务失效时,即时感知,屏蔽,将消息转发到其他可用服务器上。

Continue reading “构建负载均衡服务器之一 负载均衡与集群详解”

浅谈MVC,MVP 和 MVVM 的区别

复杂的软件必须有清晰合理的架构,否则无法开发和维护。

以下以Javascript客户端页面开发为例使用图示简单阐述三者的联系和区别。

需要注意的是,MVC开发模式备广泛用于各种软件开发中,包括互联网的B/S模式的产品,而其他两种模式大多数用在客户端开发中,例如:Javascrtipt、WPF、Adnroid开发等等。
Continue reading “浅谈MVC,MVP 和 MVVM 的区别”

为什么PHP不适合计算密集型业务

回答这个问题,我们来了解一下为什么说PHP慢?

PHP的慢是相对于C/C++级别的语言来说,事实上,PHP语言最初的设计,就不是用来解决计算密集型的应用场景。我们可以这样粗略理解为,PHP为了提升开发效率,而牺牲了执行效率。

我们知道PHP一个很大的特点,就是弱类型特性,也就是说,我可以随意定义一个变量,然后给它随意赋值为各种类型的数据。以一个int整型数字为例子,在C语言中:

但是,如果是PHP定义了一个同样的变量,实际对应的存储结构则是:

 

Continue reading “为什么PHP不适合计算密集型业务”

进攻式编程 与 防御式编程

1、防御式编程
业务的流转应该在参数的正确性下进行。简言之,就是先进行安全性或者存在性检查,然后再执行业务流程。
防御式编程方式例如:DATABASE需要对目标表进行两次扫描,一次是存在性检查,一次为执行业务(如果参数正确的话)。
防御式编程的思想为:在没有真正的操作数据之前,要保证所有的操作或者参数都是正确的,DATABASE只做正确的事。程序编写者应该尽量的预料出可以预料到的错误。我们不应该认为,在表中添加了check约束,就不用在程序中判断某个人的性别只能是男和女。

2、进攻式编程
一般情况下,调用环境已经把要传入程序的参数进行了验证以保证参数是正确的或者大部分是正确的,而此时再采用防御式编程无疑浪费了资源和时间。貌似这个时候采用进攻是编程是正确英明的选择。
先不管参数正确与否,先进行业务操作,在出现错误的时候再进行处理。

 

防御式多用在需要给其他人使用的接口上,
进攻式多用在自己可以掌控的程序开发中。

 

契约式编程

契约式编程是编程的一种方法。那么什么是契约式编程呢?我想这个概念是从“合同”演变过来的。

在人类的社会活动中,契约一般是用于两方,一方(供应者)为另一方(客户)完成一些任务。每一方都期待从契约中获得利益,同时也要接受一些义务。通常,一方视为义务的对另一方来说是权利。契约文档要清楚地写明双方的权利与义务。

契约合同能保障双方的利益,对客户来说,合同规定了供应者要做的工作;对供应者来说,合同说明了如果约定的条件不满足,供应者没有义务一定要完成规定的任务。

同样的道理也适合于软件。设想一个软件单元E。它要达到它的目的(履行契约), E使用的策略可能会包括一系列的子任务,t1, … tn。如果子任务ti 不是那么简单的,它得调用另一个功能例程(routine)R。换句话说,E把子任务转包给R。这样的情形应该被一个很好定义的“登记表”(roster)来管理双方的义务与权利--契约。

简单的说,就是你不给我想要的东西,我就不干活。

Continue reading “契约式编程”

防御式编程

什么是防御式编程 ?

顾名思义,防御性编程是一种细致、谨慎的编程方法。为了开发可靠的软件,我们要设计系统中的每个组件,以使其尽可能地“保护”自己。我们通过明确地在代码中对设想进行检查,击碎了未记录下来的设想。这是一种努力,防止(或至少是观察)我们的代码以将会展现错误行为的方式被调用。

在软件开发过程中,不可避免的会遇到错误处理,而且这部分对于整个软件的健壮性有非常大的作用,它是软件除了功能性以外最重要的指标了,一个软件成功与否与其健壮性有很大的联系。我在以前的开发中也时常思考错误处理,因为这部分代码逻辑比较不容易梳理清楚。以异常的处理为例,以前通常就采用比较简单粗暴的处理方式:用try..catch加Exception把所有异常都包起来,这样简单省事,写的代码最少,相信很多童鞋曾经跟我一样写过这样的代码,很明显,这样写有很大的问题,最主要的问题在于:

  • Exception会吃掉所有可以处理的异常,使得对于某些我们关心的异常无法捕获,因为对于不同的异常我们可能需要做不同的处理,有些可以在本函数内处理掉,有些需要提示用户(例如文件不存在,网络无法访问),有些需要告诉上一层代码该如何处理,所有这些在直接用Exception处理异常时都无法做到,简而言之就是无法做到异常的精细化处理

那么怎么做才好呢?这部分代码真不少,虽然无关软件功能性,但是确是健壮性的基础。具体如何处理这些没有完全标准的答案,软件设计本来就是一项带有艺术色彩的智力劳动,没有一劳永逸的解决方案,最关键的在于掌握好基础知识,因地制宜地采取措施。下面主要谈谈实现健壮性的基本技术,基本的实现软件健壮性的技术有以下几种:

  • 断言
  • 错误处理
  • 异常
  • 从设计上简化异常处理的技术;隔离程序
  • 辅助调试的代码(print打印之类的小段函数)

Continue reading “防御式编程”