#pragma pack(n)的意思是告诉编译器字节对齐方式为n字节对齐,n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。
举个例子
#pragma pack(2)
union U
{
char buf[13];
int i;
};
enum color{red,blue,yellow};
struct T
{
int i;
union U u;
color c;
};
sizeof(struct T)==22
如果#pragma pack(4)则sizeof(struct T)==24.
还可以使用push和pop进行默认的恢复
#pragma pack(push)
#pragma pack(2)
...
#pragma pack(pop)
注意,一般n只取1,2,4等,取其它值编译器应该会自动把n变成接近上述值的值。
原文:http://blog.csdn.net/hongchangfirst/article/details/8886269
作者:hongchangfirst
hongchangfirst的主页:http://blog.csdn.net/hongchangfirst
笔者最近一年都在从事企业私有云存储的开发,主导并推动了服务器架构的重构。在架构演化的过程中,有了很多的心得体会,这里记录一下,算是对自己架构成长的一个总结。
原则对于笔者来说,设计一个web服务器架构方案,最先考虑的就是简单以及可扩展性。而这两个也是笔者设计架构的首要原则。
简单对于一个企业级web产品来说,它其实是由非常多的基础服务来组合起来的。以私有云产品来说,如果想实现一个简单的文件共享功能,至少需要共享服务,文件服务,账号服务三个服务来共同实现。
- 共享服务,用来管理文件共享关系,如用户A给用户B共享了一个文件abc.txt
- 文件服务,用来提供共享文件下载,如用户B需要在哪里以及如何下载abc.txt这个文件
- 账号服务,用来提供共享人员的相关信息,如用户A和B的账号,姓名等信息
上面三个服务,缺少了任何一个都不能实现共享功能。但是为了实现一个功能就要与3个服务进行交互,有些童鞋就觉得非常麻烦,简单起见,他们将其糅合在一起,这样就能很好的进行代码编写了。但是这样做的弊端也非常明显,可维护性非常的差,因为功能都是耦合在一起了,如果这时候我们想用另一套企业自己的账号数据,那么完全无法实现。
上面说的只是笔者列举的一个例子,实际项目中,共享功能还是很好的进行了切分,但是仍然有很多功能过于耦合,以至于笔者的团队在很长的一段时间里面都在为以前的某些童鞋的错误设计买单。
鉴于有了上面的经验教训,笔者在考虑架构方案的时候最先想的就是简单。
所谓简单,其实很好理解,就是一个服务就干一件事情,不同的功能逻辑别糅在一个服务里面实现。更上层的服务是通过集成底层的服务来实现。其实这个就跟程序设计里面模块化的思想一样,只不过这里的模块就是单个服务。
一个服务一个模块,好处是很多的,但也不可能100%的完美,仍然很多问题需要考虑,譬如:
- 服务的可用性问题,如何判断一个服务是否可用,以及当机服务的恢复。
- 服务的运维管理问题,系统可能随着功能的增多而有了太多的服务,对这些服务的监控管理就是一个很难的问题,毕竟每个人都不希望凌晨因为服务当掉了这些问题被电话叫醒。
上面的这些问题,笔者认为已经涉及到服务的高可用问题了,与是否采用简单服务方案无关。而对于服务的高可用,分布式这些问题,笔者反而认为在简单这个原则下面,反而能更好的处理解决。
可扩展性对于大规模web系统来说,随时可能面临着突然大并发量访问而造成系统负载撑不住的问题。对于这种情况,我们就需要扩展我们的系统使其能够处理过载的情况。
对于web系统的扩展,通常采用横向扩展的方式,当某一个服务出现性能瓶颈,我们只需要动态增加该服务就能减轻过载问题。因为服务是可以动态进行横向扩展的,所以服务提供的功能都应该是状态无关的。所谓无状态性,就是每一次服务器的请求都应该是独立的,如果服务是有状态的,为了维护调用的状态,我们会做非常多的事情,这非常不利于扩展,同时也增加了系统的复杂性。
starsstars是私有云项目开始的时候葱头写的一套web服务器框架。
在项目开始的时候,大部分的开发同学都没有web服务器开发的经验,为了解决这个问题,葱头设计了stars,使得大家能够非常的使用python进行web服务器的开发。stars有很多设计巧妙以及值得学习的地方。虽然现在看来有些设计无法满足现有的需求。但是笔者一直认为没有最好的架构,只有合适的架构,作为一个架构师,即使你考虑了很多后续扩展的问题,但是仍然有一些需求变化是你考虑不到的。
rpcstars最大的特点,就在于封装了复杂的http调用,使得开发的同学不需要关注底层http知识。而做到这一点,就是将http的调用封装变成了大家熟悉的函数调用RPC。譬如我们有如下的一个http请求:
http://domain.com/file/getFileInfo?fileId=1
该HTTP请求获取一个fileId为1的文件相关信息,在stars里面,我们可以这样写:
remote = RPC("domain.com") remote.file.getFileInfo(fileId = 1)
而stars不光封装了http调用,同时为了方便大家的开发,也定义了一套API规范,只要大家写的API满足一定规则,就自动能够被注册到stars里面,这样外面就能使用RPC来调用。
对于web服务API的模式,笔者认为,通常有RPC以及Restful等几种方式:
RPC Pattern: GET http://domain.com/file/getFileInfo?fileId=1 GET http://domain.com/file/deleteFile?fileId=1 Restful Pattern: GET http://domain.com/file/1 DELETE http://domain.com/file/1
stars采用的是RPC Pattern,对于这种模式,它对于开发同学很好理解,因为它就跟普通的函数调用一样,使用起来则比较自然。反而Restful Pattern则对于开发同学不怎么好理解。只是随着现今系统规模的扩大,笔者越发觉得stars遇到了问题:
项目范围:
指为了成功达到项目的目标,项目所规定包含且只包含所有需要完成的工作。
产品范围:
一个产品或一项服务应该包含哪些特征和功能。标志产品范围完成的对比依据是产品(需求)说明。
项目提交成果:
每个阶段都可能需要提交、以反映项目进展的中间成果或最终成果。
范围定义:
把项目的主要可交付成果划分为较小的、更易管理的单元。
范围规划:
确定项目范围并编写项目说明书的过程。
项目工作分解结构(WBS):
指项目范围的细分,是将项目范围说明书中描述的项目主要提交成果,按照一定的结构层次,进一步分解为更小、更加便于控制和管理的许多组成部分。