月度归档:2012年08月

解决fileSystemWatcher的onChanged的事件触发多次的问题

Q:

FileSystemWatcher 的Changed事件,在我保存某个文本文件的时候,该事件可能会被出发多次,如何使他触发一次?

 

A:

解决fileSystemWatcher的onChanged的事件触发多次的WorkAround方法就是尝试在监视的文件或文件夹发生变化时通知Framework, 具体的代码如下:

 

My best guess is the FileWatcher fires the Create event once the file is opened for 
write and then again when it completes. I've added a test for file existence in the 
Event Handler and it does indeed FAIL on the first callback. The code below produced
 a series of debug prints showing every other callback has the OS reporting the file
 exists, i.e., 2,4,6,...


namespace MyExample
{
    class Program
    {
        private static FileSystemWatcher watcher;
        private static string mailbox = @"c:\Mailbox";
        private static int callbacks = 0;

        static void Main(string[] args)
        {
            watcher = new FileSystemWatcher();
            watcher.Path = mailbox;
            watcher.NotifyFilter = NotifyFilters.FileName;
            watcher.Created += new FileSystemEventHandler(OnChanged);
            watcher.EnableRaisingEvents = true;
        

            Console.WriteLine("Press Enter to quit\r\n");
            Console.ReadLine();    
        }



        public static void OnChanged(object source, FileSystemEventArgs e)
        {
            try
            {
                watcher.EnableRaisingEvents = false;
                callbacks++;
                FileInfo objFileInfo = new FileInfo(e.FullPath);
                if (!objFileInfo.Exists) return;   
// ignore the file open, wait for complete write
                ProcessAllFiles(e.FullPath);

            }
            catch (Exception ex)
            {
                string msg = ex.Message;
                // do something?
            }
            finally
            {
                watcher.EnableRaisingEvents = true;
            }
        }




        public static void ProcessAllFiles(string FullPath)
        {
            // stub

	    string directory = FullPath.Substring(0, FullPath.LastIndexOf(@"\"));
            string filename = FullPath.Substring(FullPath.LastIndexOf(@"\"));
            Console.WriteLine("file: {0} Callback # {1} ", filename, callbacks);  
        }

 

关于解决fileSystemWatcher的onChanged的事件触发多次的WorkAround方法的详细信息,请参考下述文章:http://www.codeproject.com/useritems/FileWatcher.asp

NPOI简介

作者:Tony Qu

========================================

[更新] NPOI 1.2.4 新教程地址:http://tonyqus.sinaapp.com

========================================

NPOI 微博: http://weibo.com/npoi

NPOI QQ交流群: 

群1:189925337

群2:124527967

群3: 116053476

 

更新

2009.3.24  把npoi 1.2 alpha的链接换成NPOI 1.2 beta

2009.11.18  把npoi 1.2 beta的链接换成NPOI 1.2.1; 增加NPOI教程链接

2009.12.1 增加QQ群

===================================================

本文将通过问答的方式帮助你了解NPOI。

 

什么是NPOI?

NPOI,顾名思义,就是POI的.NET版本。那POI又是什么呢?POI是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office 97-2003的文件,支持的文件格式包括xls, doc, ppt等。目前POI的稳定版本中仅支持Excel文件格式xls,其他的都属于不稳定版本(放在poi的scrachpad目录中)。NPOI是构建在POI 3.x版本之上的,本月发布的NPOI 1.2是对应于POI 3.2 final的,所以它支持Excel文件读写,但由于人手和精力原因,还没有实现读写Word, PowerPoint, Visio的文件格式。

 

NPOI的官方网站是啥?

npoi.codeplex.com

 

为什么用NPOI?

因为它能够帮助你生成真正的Office文件格式,比如说Excel文件格式。我曾经看到好几个园友发过有关如何生成Excel报表的帖子,大家确实花了很多心思,具体的帖子如下:

生成Excel高级报表(用的是Office PIA库)

http://www.cnblogs.com/xiaobier/archive/2008/10/13/1310399.html

Datagrid数据导出到excel文件的三种方法

http://www.cnblogs.com/xieduo/articles/606202.html

其中提到了的2种方法分别是:cvs法、html法

.net 操作 EXCEL

http://www.cnblogs.com/jhobo/archive/2009/02/17/1392423.html

其中提到了Office PIA法、OLEDB法、OPENXML法

 

特别是其中的cvs法和html法值得提一下,这得感谢Microsoft Office对于格式的强大兼容性,貌似国产某某Office软件就无法正常显示基于html的xls文件。

好了,回到我们的问题上,为什么要用NPOI呢?

第一点,你不需要在服务器上安装微软的Office,可以避免版权问题。

第二点,使用起来比Office PIA的API更加方便,更人性化。

第三点,你不用去花大力气维护NPOI,NPOI Team会不断更新、改善NPOI,绝对省成本。

第四点,很多事情是html和cvs法做不到的,比如说公式计算[Cell C1]=A1+B1*A2、单元格高级样式(如文本旋转、对齐、宽度)等,其中公式计算可以适当减轻服务器端的计算压力

第五点,你很难保证你的客户机器上都安装了Office 2007或Office Compatiblity Pack for Office 2003,出于向前兼容的考虑,还是生成Office 97-2003格式比较可靠

 

当然有人要说了,那我用myXls等同类产品可不可以?当然可以,纯属个人喜好,这就好比你愿意用NHibernate还是NBear,完全可以自由选择。

 

NPOI由哪些东西组成?

NPOI目前主要由以下部分组成

NPOI.POIFS OLE2 Document File System Library
NPOI.DDF Microsoft Office Drawing format Library
NPOI.HPSF OLE2 Propertyset library (包括SummaryInformation和DocumentSummaryInformation)
NPOI.HSSF Microsoft Excel BIFF library
NPOI.SS Formula Evaluation library
NPOI.Util 基础类库,提供了很多实用功能,可用于其他读写文件格式项目的开发

 

NPOI目前的版本如何?包括哪些功能?

目前NPOI的最新版是NPOI 1.2.1,其中包括了以下功能:

a. 读写OLE2文档

b. 读写DocummentSummaryInformation和SummaryInformation

c. 基于LittleEndian的字节读写

d. 读写Excel BIFF格式

e. 识别并读写Excel BIFF中的常见Record,如RowRecord, StyleRecord, ExtendedFormatRecord

f. 支持设置单元格的高、宽、样式等

g. 支持调用部分Excel内建函数,比如说sum, countif以及计算符号

h. 支持在生成的Xls内嵌入打印设置,比如说横向/纵向打印、缩放、使用的纸张等

i. ……  (功能太多,无法一一例举,大家自己研究吧)

下载地址:http://npoi.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=19351

 

在开发中哪些地方可以使用NPOI

a. 生成Excel报表

b. Excel中的文本提取(主要用于搜索引擎)

c. 批量生成Excel文件

d. 基于Excel文件模板生成新的Excel

e. 研究Excel BIFF文件格式及OLE2文件格式

 

NPOI的最终目标是什么?

a. 能够读写几乎所有的Office 97-2003文件格式,至少能够支持Word, PowerPoint, Excel, Visio的格式,其他的会根据实际需求而定。

b. 作为教学Office文件格式的“活”教材,也可作为研究生阶段研究数据结构的教材。

即使是目前的1.2版本也很不完善,支持的Excel功能还很有限,没有搞过NPOI的研发,包括我在内的很多人很难想象微软这样一个Excel软件的开发量,其中除了我们常用的基本功能以外,还有很多内置函数的实现、对行进行分组、行的锁定、表单的保护等。说实话有些功能我也是第一次听说,是在开发中一边看Excel界面一边实现的(呵呵,是不是很土)。由于Office 2007为了兼容Office 97-2003,在其基础上增加了很多新的Record,所以要生成真正意义上的全新的Excel BIFF很难(话说微软的开发速度贼快)。

在NPOI以后的版本中还会支持Pivot表和图表(Chart),其实你在poi的svn中已经可以看到最新的pivot和chart的代码了,只是还在开发中,没有发布正式版本,估计今年中旬会发一个新的版本。

 

我也想研究Office文件格式,有没有相关的文档和工具可供参考?

首先是文件格式的说明文档,你可以去微软的官方网站下载:http://www.microsoft.com/interop/docs/officebinaryformats.mspx

接着是,我和Huseyin共同开发了POIFS Browser,目前的版本是1.2,已经能够识别Excel BIFF了。

你可以去http://npoi.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=23409下载。

 

我可以参加NPOI开发组吗?

当然可以,我非常欢迎大家加入NPOI Team,因为目前狂缺人手,很多事情要做,比如说实现读写Word格式的库,即HWPF;还需要有人帮忙一起写文档、写范例、写教程。目前团队中只有2个人,我和Huseyin(土耳其人),最近Huseyin也很忙,没时间维护NPOI,所以我很需要你的加入。大家有兴趣可以到http://npoi.codeplex.com/Thread/View.aspx?ThreadId=36157回帖,或者直接发邮件给我(具体邮件地址见我blog的左边栏)。

 

NPOI有教程吗?

有,该教程是为NPOI 1.2写的,详细目录请见http://www.cnblogs.com/tonyqus/archive/2009/04/12/1434209.html

 

NPOI Team下一步准备干嘛?

上一个问题中提到事情真的很多,下面罗列一下:

a. 使Excel读写库(HSSF)更加稳定

b. 开发HSSF对Pivot Table和Chart的支持

c. 开发Word读写库(HWPF)、PowerPoint读写库(HSLF)

d. 把HSSF的注释补全,把java的注释转成.NET的,便于用NDoc生成文档和智能感知

e. 写NPOI 1.2的范例(目前只有10个左右,目标是>50个,类似于微软的SDK,这样方便大家学习和理解)

f.  写NPOI 1.2的教程

 

引用:http://www.cnblogs.com/tonyqus/archive/2009/03/16/1409966.html

分布式系统邮件服务器架设

来源:拓波软件 技术支持部

 

设计目标

邮件系统在当今社会,作为一种基础通讯平台,已经不单纯是简单收发邮件,而是成为互联网各种应用的核心,承载越来越重要的应用。中国人口众多,上网人数逐年剧增,使用邮件也日益频繁。邮件系统从建成的那一天起,就面临升级的压力。如何设计一个结构良好的大容量邮件系统,对于系统稳定性、可靠性,对于日后的升级维护有着至关重要的作用。

拓波公司作为一个在邮件领域默默耕耘的公司,以小用户量的企业邮件系统立身,最终希望打造一个坚固的、高度可扩展的、容易管理维护的大容量分布式邮件系统。在设计时,我们主要考虑如下方面:

1. 底层坚固、高度稳定。

为保证系统的稳定可靠,需要在硬件、操作系统、核心MTA、应用层在内的每一个环节都稳定可靠才行。硬件通常选取知名品牌服务器,稳定性、可靠性都有保障,差别不大。操作系统选择Linux 或者FreeBSD, 针对邮件系统的特点,内核需要特殊调整:如打开文件数(open files)、stack size 、max user processes 等。除了操作系统核心外,系统只加载必须的软件,屏蔽一切不不要的服务端口。

在操作系统之上,处理smtp、pop3 请求的MTA 的稳定性、效率也至关重要。当今世界上使用比较多的是qmail 和postfix, 都有分布世界各地的大批用户。相比较而言,qmail有着更好的模块化设计、更好的安全性,更高的投递效率、更可靠的队列设计。Postfix 优势在于和sendmail 有着很好的兼容性,部署容易,集成程度比较高,也是一个非常不错的MTA 软件。

应用层我们选取Apache+tomcat。Apache 久负盛名、久经考验,tomcat 背后有SUN 支持,最重要的是tomcat5 支持应用层负载均衡(Load Balance)。另外,java 作为一种面向对象的编程语言,最能体现软件工程思想,有一系列的UML 设计工具、集成开发环境、应用服务器可以选择。很多学校也开设JAVA 课程,以后JAVA 会像c 语言那样普及,变成程序员必备的技能之一。邮件系统应用层会根据用户的反馈增加信的增值服务品种,如果基于

java 开发,很容找到相关人才。这样缩短开发周期、节省开发成本、降低维护难度。Google很多服务是基于java 开发的。当然,java 也有执行效率低的缺点,但随着硬件速度的提升,单只程序运行速度的劣势很容易被良好的设计模式优势取代。

2. 容易管理、维护。

系统结构复杂之后,必然会带来管理维护上的麻烦。我们的设计思想是希望通过统一的一个管理控制界面,让系统管理员对每台服务器的运行状况、负载情况、流量了如指掌;同时通过一个管控界面,可以远程控制服务器启动、关闭,对服务进程远程启动、停止,对流量调配。当出现异常时,系统自动通过短信通知到管理人员的手机上。

3. 增加设备简单、有效。

系统扩展性是衡量系统设计好坏的一个重要指标。好的系统能够通过简单添置硬件、软件做少许配置即可满足需要。我们设计的是让用户数量的增长和邮件服务器数量呈线性关系。由于PC 服务器的硬件成本比较低,以一台高性能PC 服务器3 万元人民币计算,如果作为SMTP 服务器可以支撑15 万用户,作为POP 服务器可以支撑30 万用户,作为存储服务器,可以支撑3 万用户。平均每用户为0.2 元、0.1 元、1 元。

在保证系统稳定可靠的同时,能够最大地降低成本。降低成本有2 个途径,一是最大限度利用硬件,二是避免使用高端的存储备份设备、负载均衡设备、四层交换机等。

点击查看原图
4. 具有多级权限管理,支持个人用户、企业用户、运营商等。

大容量邮件系统,不仅仅是个人用户,还有企业用户。不同用户群体的需求是不同的。针对不同用户群,提供不同的服务套餐,无疑是市场营销重要手段。而这,需要有技术上做保障才行。TurboMail邮件应用层采用java 技术,无疑是体现用户需求的最佳技术手段。

作为运营商,要有丰富权限管理体系,使邮件系统的每一个管理环节严紧、严密。

5. 高度模块化,模块之间最小耦合。

模块化程度的高低,可以体现的系统的成熟度。充分利用开源宝库中的免费资源,将优秀的开源项目经过改良、优化,会搭建出优秀的系统。不赞成完全从底层开发。模块之间通过标准接口通讯,耦合程度尽可能小,这样,即使出问题也不会影响全局。最重要的是,系统扩展性大大增强。如可以随时将病毒扫描过滤模块升级,或者将

垃圾邮件过滤模块升级,其它模块无需做任何改动。

6. 提供与其它系统直接的接口:如计费平台、短信彩信平台、防毒网关等。

作为邮件运营,计费模块很重要。良好的设计可以为灵活的计费提供原始数据。根据这些计费数据,可以制定灵活的促销手段。随着彩信的普及,邮件系统与彩信会逐渐融合。其它的扩展平台,如防病毒网关、
反垃圾网关、反黄网关都可以灵活对接。

7. 应用层二次开发、部署简单方便。

邮件系统的生命力来自客户的需求,只有不断满足客户需求,推陈出新,与时俱进,才会不断有新的用户加入。根据用户需求进行二次开发,这是必不可少的。二次开发必须简单,方便。TurboMail邮件通过统一的二次开发接口Jindi-Mailet 实现服务端应用的扩展。

邮件系统架构上的演化和优劣比较

大容量邮件系统按照存储方式不同,大致可以分为2 类:
1. 统一存储

邮件队列和邮件数据集中放在存储设备上。前端smtp 服务器多台,POP 服务器多台,随机选择一台smtp 服务器或者POP 服务器(这个过程一般采用DNS 轮询方式完成)。选定某台服务器后,与该服务器建立连接,通过认证系统确认用户身份后,发送或者接收邮件数据。因为是统一存储,数据都是放在磁盘阵列上,通过NFS 方式挂在

每台服务器上。不论是通过哪台功能服务器,都可以完成邮件收发。
用户对Webmail 的请求和smtp/pop3 类似,也是通过多台机器随机选取实现负载分布。
2. 分布式存储

邮件数据分布在每一台服务器上,每台服务器都提供完整的邮件服务:smtp/pop3/imap/webmail/数据库。用户请求过来之后,首先查询目录服务器,验证用户身份,然后找到对应的服务器,建立连接,收取或者发送邮件。

这种方式最大的优点是用户数量和邮件服务器数量可以保持线性增长。每台服务器支持10 万邮箱,当一台服务器用户已达这个数字时,启用另外一台。可以通过管理程序在不同服务器直接迁移用户。动态管理服务器。

从早期UNIX 几十用户的简单邮件系统,到现在几百万、上千万邮件系统,中间经历很多变化。不妨把这些梳理一下,比较邮件系统各种技术的优劣。

1. 一机一域、一机多域(虚拟域)

一机一域代表用户是企业用户。一台服务器作为邮件服务器。一机多域象新网、万网,给很多企业提供邮箱。所有的服务,如smtp,pop3,imap 都在一台服务器上,对方邮件服务器通过查询DNS 即可唯一锁定收件方服务IP,直接投递过去。

这种单机邮件系统,由于受cpu、内存、硬盘的制约,用户最多一般不超过10 万用户。考虑可靠性,一般采用HA,将用户数据存放磁盘阵列上,正常只有一台服务器工作,异常时自动切换到另外一台。对于一般的企业用户,这种单机邮件系统已经够用。但对于大型邮件系统,这种单机系统显然无法满足。

2. 多机一域,功能分割,集中存储。
点击查看原图

邮件服务器smtp、pop3、imap、webmail 服务分布在不同的服务器上,通过NFS 统一访问同一存储区域。

这种做法,实现一个简单功能分布,使每一台服务器功能单一,几台服务器各司其职,处理能力大大增强。这种简单的功能分散,实现起来比较简单,只要在不同的服务器其上部署相关服务即可,将存储服务器通过NFS mount 到每一个服务器上,然后在DNS 中做相关配置。

当用户增大到一定数量,并发量会比较大,单台smtp 可以到256 并发量,最多不会超

过1000 并发量。因此smtp 很容易成为瓶颈。

3. 多机一域,负载均衡,集中存储。
点击查看原图 

当邮件用户并发量大时,smtp 很容易成为瓶颈,在系统中出现瓶颈的地方可以多增加几台服务器,然后更新DNS,通过 DNS 查询解析不同的smtp 服务器地址,可以使请求平均分配到每一台服务器上。

现在许多大容量邮件系统都脱胎于此,特点是部署容易,简单易行。缺点是当访问量增

大后,数据访问全部通过NFS,也很容易出现磁盘IO 瓶颈。

4. 多机一域,功能分布,存储分布。

该系统前端(front-end)是一个邮件交换器和目录服务器LDAP,后端是多台独立的存储服务器,通过管理中心调度,将存储服务器通过NFS 挂在相应的smtp 服务器或者pop 服务上。

在目录服务器上,会保存用户名、密码、smtpserver、popserver、storeserver 等信息,当用户请求过来是,先查询LDAP,如果是收信,找到该用户对应的smtp, 通过直接路由方式连接smtpserver,发信;如果是收信,找到对应的pop,连接popserver 下载邮件。

该架构解决了服务器处理瓶颈、数据存储IO 瓶颈。缺点是主要的任务分发通过邮件交换器完成。一但邮件交换器出问题,整个系统都将无法运行。

点击查看原图
5. 多机一域,双层负载均衡,存储分布。

为避免出现单点故障,将4 改良,增加多台邮件交换器和LDAP 服务器。邮件交换器通过DNS 轮询实现负载均衡,LDAP 服务器做成双机热备,任何一台有故障,另一台接替。存储服务器通过DRBD 实现两两镜像,避免出现存储故障。

这样一套系统,可以支持千万用户级。以2000 万用户为例,4000 并发量测算,按照处理能力:

Smtp:15 万用户/台,pop:30 万/台

需要:smtp:133 台,pop:66 台,共计约199 台PC 服务器。

这个方案的优点是没有瓶颈,可以无限扩充,缺点是需要很多存储服务器,资源上有些浪费。 点击查看原图
6. 多机一域,邮件功能服务器。

这种方案将以邮件服务器为单位,形成邮件服务器阵列。每台邮件服务器具有完整的邮件服务功能:smtp/pop3/imap/webmail 等。用户认证信息集中存放于LDAP 服务器,通过LDAP查找用户所在邮件服务器。

系统管理通过集中管控界面可以控制用户数据在服务器之间进行移动、复制、删除。邮件服务器进行两两互备。

设置独立的过滤服务器,主要过滤病毒、垃圾邮件和黄色图片。过滤服务器与邮件服务器之间通过socket 通讯,所有处理在内存完成,大大加快了处理速度。

该系统有如下特点:
(1) 这种方案系统造价比较低。以每台服务15 万用户计算,100 台服务器可以承
载1500 万用户。100 台服务器大约200 万-300 万人民币左右。
(2) 结构简单,布置方便,容易维护。
(3) 用户容量与服务器数量保持线性增长,扩容只需要增加服务器即可。
(4) 帐户在服务器直接动态可调,可迁移。
(5) 没有瓶颈,应付突发事件的能力强。
(6) 小面积的故障,不会影响整理系统。
基于以上优点,我们推荐优先考虑此方案。
点击查看原图

功能设计

功能上我们遵循如下设计理念:
1. 集中管控。
管理一个大型邮件系统,就象管理一台服务器那样简单。在单一管理界面下,通过web浏览器即可监控任何环节,完成大部分操作。
2. 自动化、智能化。
通过自动装置,如SMS 监控系统流量、内存、进程、磁盘空间等,设定报警阀值,超过阀值就会自动报警,防范于未然。
3. 最简化、最优化。
用简单办法完成简单的事情。简单意味着效率、稳定、可靠。

1
.主要功能:

基本功能:

Smtp,pop3,imap,webmail

增值模块:

SMS,MMS,NETFile,Photo,largeFile, Schedule,AntiSPAM,Anti-Virus, Anti-pronography, …

可选模块

语音邮件、视频邮件、邮件传真服务


2
.功能清单:

系统管理员

域管理员

普通用户(见263 需求)

1.统计、审计功能:

域用户管理

认证登录WebMail

2.监控功能:

邮件广播

用户session 信息初始化

3.服务器管理:远程开机、关机、启动服务、停止服务

域级过滤规则设定

显示首页

4.域管理:添加、变更、转移、删除

域级黑名单

保存图标位置

5.过滤服务器管理

用户邮箱大小、附件大小、邮件大小控制

邮件索引显示

6.DNS 管理

功能服务定制:sms/防病毒等

邮件移动

 

 

邮件排序

 

 

显示页码

 

 

回复信件

 

 

转发信件

 

 

删除信件

 

 

永久删除信件

 

 

显示信件原文

 

 

显示邮件内容

 

 

加入到地址本

 

 

加入到拒收列表

 

 

保存邮件

 

 

pop 取信

 

 

文件夹显示

 

 

文件夹删除

 

 

文件夹添加

 

 

文件夹重命名

 

 

查找邮件

 

 

发邮件页面显示

 

 

立即发送邮件

 

 

定时发送邮件

 

 

保存草稿

 

 

发送短信邮件

 

 

添加附件

 

 

删除附件

 

 

个人地址本显示

 

 

团体地址本显示

 

 

添加个人地址本

 

 

删除个人地址本

 

 

修改个人地址本

 

 

添加团体地址本

 

 

删除团体地址本

 

 

修改团体地址本

 

 

地址本排序

 

 

导出地址本

 

 

导入地址本

 

 

显示自动转发

 

 

修改自动转发

 

 

显示自动回复

 

 

修改自动回复

 

 

显示签名档

 

 

删除签名档

 

 

增加签名档

 

 

修改签名档

 

 

显示pop 收信设置

 

 

pop 收信设置修改

 

 

pop 收信设置增加

 

 

pop 收信设置删除

 

 

修改密码

 

 

显示参数设置

 

 

参数设置修改

 

 

显示多风格设置

 

 

多风格设置修改

 

 

显示反垃圾级别设置

 

 

反垃圾级别设置

 

 

显示杀毒状态

 

 

修改杀毒状态

 

 

显示过滤设置

 

 

邮件过滤设置添加

 

 

邮件过滤设置修改

 

 

邮件过滤设置删除

 

 

显示拒收设置

 

 

拒收设置修改

 

 

外挂一次认证

 

 

session 维护进程


3
.后端统计

统计类别

?统计项目

描述

系统资源

负载情况

5 分钟采样一次,自动绘制统计图

计图

CPU 使用情况

User,system,nice and idel

 

内存

Totoal,used,free

 

交换分区

Used ,free,cached,shared

 

硬盘

Total,used,free, inode

 

网络状况

收到字节数,发送字节数

邮件总量统计

邮件数量,总流量

统计每域、每用户收发邮件总量和字节数。

投递失败统计

统计投递失败的记录

按照每域、每用户统计

隔离邮件统计

邮件感染病毒,或者认定为垃圾邮件的

按照每域、每用户统计

短信统计

短信发送数统计

按照每域、每用户统计


4
.后端服务器管控功能

功能

描述

服务器节点远程管理

添加

向集群中添加一台服务器

 

除去

从集群中拿掉一台服务器

 

重启

远程重启服务器

 

关机

远程关机

服务远程管理

启动

远程启动某服务器服务进程

 

停止

远程停止服务器进程

监控、报警

设定监控项目,过载报警

发送SMS 到管理员手机

负载均衡管理

LVS,RR-DNS, LDAP

负载均衡远程调控

Tomcat 集群管理

添加节点、删除、更新

管理webmail 服务器

Session 服务器管理

集中管理用户session

小规模增值税计算

一般合同金额都是指含税的,要换算成:
    不含税金额=含税金额/(1+税率)
    应交税=不含税金额*税率
 

含税计算方式:

例:20000

公式:金额/(1+3%)*3% 

计算:20000/1.03*0.03 = 582.52

         货款:20000/1.03 = 19417.48 (19417.475728155 )

         税款:19417.48(19417.475728155) * 0.03 = 582.52 (582.52427184465) 

         计:  19417.48 + 582.52 = 20000

lucene 搜索语法

Lucene提供了丰富的API来组合定制你所需要的查询器,同时也可以利用Query Parser提供的强大的查询语法解析来构造你想要的查询器。本文章详细的介绍了Lucene的查询语法。通过Java语法分析器把一个查询字符串解析成 Lucene的查询器。在你选择使用Query Parser前,请考虑以下事项:

如果你打算在程序中拼接查询语法串然后再利用Query Parser转换,那么强烈建议你利用相应的API来自己构造查询器。也就是说,Query Parser是为手工输入高级查询设计的,而不是为程序拼接语法串而设计的。不分词的字段也最好通过相应的API添加到查询器中,而不是通过Query Parser。Query Parser 使用的Analyser分析器,作用是将用户手工输入的文本转化为相应的Term。如果一个字段的值是通过程序生成的(例如日期字段,关键词字段等),那么在查询的时候也应该保持前后一致,利用程序生成相应的格式来查询。

在查询的目标中,如果字段全部是程序生成的文本,(例如补齐的日期字段等),最好使用Query Parser以便查询的时候也是一致的格式。至于其它的,例如日期范围查询,关键字查询等,最好调用相应的API来构建查询器。目标字段中如果仅仅拥有有限的枚举值时,最好通过下拉列表提供给用户选择,然后利用TermQuery添加到查询器中,而不是而其拼接到查询字符串然后利用Query Parser来解析。

Terms 
一个查询将分解为若干Term以及操作符,有两种Term,其一是单一Term,其二为短语。单一Term是经过分析器分词后的最小单元,他就是一个简单的词,例如“Test”和“Hello”。短语则是一组被双引号括起来的一组词,例如:“Hello dolly”,多个Term可以通过布尔操作合并在一个更加复杂的查询器中。
注意:一般来说,创建索引的分析器和查询的分析器最好保持一致(当然也有特殊情况,比如单字索引,分词组合查询),所以选择一个不会干扰查询词的分析器是很重要的。

Fields 
Lucene支持多字段数据,当你在查询的时候你可以指定一个字段查询,也可以使用默认的字段。你可以使用 字段名 + “:” + 查询词来指定字段名搜索。举个例子,让我们假定Lucene的索引中含有两个字段,Title字段和Text字段,其中Text字段是默认字段,当你想找到一篇文档其中标题包含“The Right Way”同时文本中包含“go”,你可以输入:
title:"The Right Way" AND text:go 
或者:
title:" The Right Way " AND go 
如果字段是默认字段的话,在查询语法中可以不需要显式指定。注意,使用默认字段有可能会造成如下的结果:
title:Do it right 
以上查询将查找标题中含有“Do”,Text字段字段中含有“it”和“right”的文档,因为Text是默认字段,所以如果想要查找Title中完整包含的很用引号引起来。

Term Modifiers
Lucene支持在Term中使用通配符来支持模糊查询。

Wildcard Searches 
Lucene支持单个或者多个字符的通配符查询,匹配单一字符使用符号“?”,匹配多个字符使用符号“*”。
“?”通配符将查找所有满足通过一个字符替换后符合条件的文档。比如:搜索“test”和“text”你可以使用:
te?t 
“*”通配符将查询0个或者多个字符替换后符合条件的。举例来说,查询test,tests或者tester,你可以使用一下字符串来搜索:
test*
当然,你也可以将“*”放在字符的中间
te*t 
注意:你不能将“*”和“?”放在第一个字符来查询。(Lucene应该是出于性能考虑,所以不支持该功能)

Fuzzy Searches 
Lucene支持基于编辑距离算法的模糊搜索,你可以使用波浪符号“~”放在查询词的后面,比如搜索一个与“roam”拼写相近的词可以使用:
roam~ 
该查询将寻找类似“foam”和“roams”等的词语。也可以说是相似度查询。

Proximity Searches 
Lucene支持指定距离查询,你可以使用波浪号“~”加数字在查询词后。举例来说搜索“apache”和“jakarta”距离10个字符以内,你可以使用如下语法:
"jakarta apache"~10 
通过这个语法支持,我们可以单字索引,分词查询,分词完后,满足每个词的单字必须间距为0。这样可以保证100%的召回率,但是在索引方面将造成索引臃肿,同时查询速度也将在某程度上降低,一般来说,在150W文章数据到200W数据的时候性能将会明显的降低。

Range Searches 
范围查询允许你指定某个字段最大值和最小值,查询在二者之间的所有文档。范围查询可以包含或者不包含最大值和最小值,排序是按照字典顺序来排序的。
mod_date:[20020101 TO 20030101] 
这个将查找满足mode_date字段在大于等于20020101,小于等于20030101范围的所有文档,注意:范围查询并不是为日期字段专设的,你也可以对非日期字段进行范围查询。
title:{Aida TO Carmen} 
这个将查找所有标题在Aida和Carmen之间但不包含Aida和Carmen的文档。包含最大值和最小值的查询使用方括号,排除则使用花括号。

Boosting a Term 
Lucene支持给不同的查询词设置不同的权重。设置权重使用“^”符号,将“^”放于查询词的尾部,同时跟上权重值,权重因子越大,该词越重要。设置权重允许你通过给不同的查询词设置不同的权重来影响文档的相关性,假如你在搜索:
jakarta apache 
如果你认为“jakarta”在查询时中更加重要,你可以使用如下语法:
jakarta^4 apache 
这将使含有Jakarta的文档具有更高的相关性,同样你也可以给短语设置权重如下:
"jakarta apache"^4 "jakarta lucene" 
在默认情况下,权重因子为1,当然权重因子也可以小于1。

Boolean operators 
布尔操作符可以将多个Term合并为一个复杂的逻辑查询。Lucene支持AND,
+,OR,NOT, -作为操作符号。注意,所有的符号必须为大写。

OR 
OR操作符默认的连接操作符。这意味着,当没有给多个Term显式指定操作符时,将使用OR,只要其中一个Term含有,则可以查询出文档,这跟逻辑符号||的意思相似。假设我们查询一个文档含有“jakarta apache”或者“jakarta”时,我们可以使用如下语法:
"jakarta apache" jakarta 
或者
"jakarta apache" OR jakarta 

AND 
AND操作符规定必须所有的Term都出现才能满足查询条件,这跟逻辑符号&&意思相似。如果我们要搜索一个文档中同时含有“jakarta apache”和“jakarta lucene”,我们可以使用如下语法:
   "jakarta apache" AND "jakarta lucene" 

+
+操作符规定在其后的Term必须出现在文档中,也就是查询词中的MUST属性。举个例子来说,当我们要查询一个文档必须包含“jakarta”,同时可以包含也可以不包含“lucene”时,我们可以使用如下语法:
+jakarta apache 

NOT 
NOT操作符规定查询的文档必须不包含NOT之后的Term,这跟逻辑符号中的!相似。当我们要搜索一篇文档中必须含有“jakarta apache”同时不能含有“Jakarta lucene”时,我们可以使用如下查询;
"jakarta apache" NOT "jakarta lucene" 
注意:NOT操作符不能使用在单独Term中,举例来说,以下查询将返回无结果:
NOT "jakarta apache" 


-操作符排除了包含其后Term的文档,跟NOT有点类似,假设我们要搜索“Jakarta apache”但不包含“Jakarta lucene”时,我们使用如下语法:
"jakarta apache" -"jakarta lucene" 

Grouping 
Lucene支持使用圆括号来将查询表达式分组,这将在控制布尔控制查询中非常有用。举例来说:当搜索必须含有“website”,另外必须含有“jakarta”和“apache”之一,我们可以用如下语法:
(jakarta OR apache) AND website 
这种语法对消除歧义,确保查询表达式的正确性具有很大的意义。

Field Grouping 
Lucene支持对字段用圆括号来进行分组,当我们要查询标题中含有“return”和“pink ranther”时,我们可以使用如下语法:
title:(+return +"pink panther") 

Escaping Special Characters 
Lucene支持转义查询中的特殊字符,以下是Lucene的特殊字符清单:
+ - && || ! ( ) { } [ ] ^ " ~ * ? : \
转义特殊字符我们可以使用符号“\”放于字符之前。比如我们要搜索(1+1):2,我们可以使用如下语法:
\(1\+1\)\:2 

转自:http://hi.baidu.com/expertsearch/blog/item/8d4f7d355a2e413c5ab5f547.html

 

如何用hash关键字提高数据库性能

本文讨论了一个应用称为hash桶(hash bucket)或hash关键字(hash key)的字符串目录的优秀方法。了解如何应用hash关键字有助于提高性能并节省磁盘空间。

普通的SQL Server应用程序要求支持一个或几个长字符串搜索。(本文中,我们称超过20个字符的字符串为长字符串。)假如前端应用程序希望允许用户提供两个字符串;你启动一个执行这两个字符串搜索任务的存储程序,然后应用两个相关列目录对搜索进行优化。在小型的表格中,你可能注意不到产生的效果。但是,如果表格包含5 000万行,它就会影响存储程序与搜索性能。

应用称为hash关键字(引用单独一个hash)或hash桶(一个hash关键字集合)的字符串目录的优秀方法可大大节省磁盘空间并提高性能。

何为hashhash

hash是应用一个指定字符串算法的整数结果。有各式各样的hash算法,但最常用的是内置的SQL函数Checksum()。通常,你给这个函数一个字符串,它就返回一个整数(在大型表格中,我们不能保证这个整数的唯一性)。

数据库设计中的hash表格

假设在我们感兴趣的表格中有这些列:

列名

数据类型

名称

Varchar(50)

组名称

Varchar(50)

这两个列的多列目录每行会耗用50+50个字符,加上上面提到的5 000万行,这可是个相当大的难题。

基于这两个列的hash关键字相当的小,即每行四个字节。如果我们不将hash关键字存储在这一列的目录中,它还会更小。相反,我们应该建立一个计算列,该列的公式是这两个列的hash关键字,然后将那个列编入目录并忽视字符串对的目录。

用户(不管是人还是应用程序)查询感兴趣的值;然后我们将参数转换为hash关键字并搜索hash目录。副本集合要比引擎必须访问的行集合小得多,以便对查询值进行精确匹配。然后将hash关键字搜索与两个感兴趣的列的比较结合起来,隔离出一个小型的行子集,并对两个列进行检验,找出匹配值。基于整数列的搜索比基于长字符串关键字的搜索要快得多,同样也比复合关键字搜索快得多。

应用Checksum函数作hash关键字运算

尝试运行这段样本代码,它表明如何获得指定值或值组合的hash关键字:

USE AdventureWorks

SELECT Name, GroupName, Checksum(Name,GroupName)AS HashKey

FROM Adventureworks.HumanResources.Department

ORDER BY HashKey

所得的结果显示在下表中(为求简洁,只选用了10个结果)。

名称

组名称

hash关键字

工具设计

研究与开发

-2142514043

生产

制造

-2110292704

发货与收货

存货管理

-1405505115

购买

存货管理

-1264922199

文件控制

质量保证

-922796840

信息服务

总执行管理

-904518583

质量保证

质量保证

-846578145

销售

销售与营销

-493399545

生产控制

制造

-216183716

营销

销售与营销

-150901473

在现实环境中,你可以建立一个调用Name_GroupName_hb的计算列。假设前端传入名称(Name)与组名称(GroupName)的目标值,你就可以用下列代码来处理这一问题:

CREATE PROCEDURE DemoHash

( ?@Name Varchar(50), ?@GroupName Varchar(50)

)

AS

-- USE AdventureWorks

DECLARE @id as int SET @id = Checksum(@Name,@GroupName)

SELECT * FROM Adventureworks.HumanResources.Department

WHERE HashKey = @id

AND Name = @Name

AND GroupName = @GroupName

想象一下,在一个5 000万行的表格中,返回了100行指定的hash关键字。由于这两个列没有其它的目录,查询优化器就应用hash桶目录。这样就可以快速地隔离出100个感兴趣的行。然后我们访问这些行,检验名称(Name)与组名称(GroupName)列来进行精确匹配。这样就大大提高了性能,同时节省了大量的磁盘空间。

引例假设搜索目标存在于一个单独的表格中。假如要从多个表格中选择目标来进行搜索,也可以应用同样的技巧。只需建立一个连接表格的表格函数,然后建立一个hash不同表格列的目录即可。

结论

在相对较小的表格中,建立一个目录hash桶对于提高性能可能没有太大的作用,但这样做可节省磁盘空间。如果你使用大型的表格,本技巧就极为实用。

Arthur Fuller从事数据库应用程序开发20余年。在Access ADP、微软SQL 2000MySQL.NET方面有丰富的经验。

 

索引与散列

11-1 什么是静态索引结构?什么是动态索引结构?它们各有哪些优缺点?

 

 

11-2 设有10000个记录对象, 通过分块划分为若干子表并建立索引, 那么为了提高搜索效率, 每一个子表的大小应设计为多大?

 

 

11-3如果一个磁盘页块大小为1024 (=1K) 字节,存储的每个记录对象需要占用16字节,其中关键码占4字节,其它数据占12字节。所有记录均已按关键码有序地存储在磁盘文件中,每个页块的第1个记录用于存放线性索引。另外在内存中开辟了256K字节的空间可用于存放线性索引。试问:

(1) 若将线性索引常驻内存,文件中最多可以存放多少个记录?(每个索引项8字节,其中关键码4字节,地址4字节)

(2) 如果使用二级索引,第二级索引占用1024字节(有128个索引项),这时文件中最多可以存放多少个记录?

  

 

   397

 Hello World!

    82

 XYZ

  1038

 This string is rather long

  1037

 This is Shorter

    42

 ABC

  2222

 Hello new World!

11-4 假设在数据库文件中的每一个记录是由占2个字节的整型数关键码和一个变长的数据字段组成。数据字段都是字符串。为了存放右面的那些记录,应如何组织线性索引?

 

      

11-5 设有一个职工文件:

  记录地址

  职工号

   

  性别

    

  年龄

  籍贯

 月工资()

     10032

   034

  刘激扬

  

    

   29

  山东

720.00

     10068

   064

  蔡晓莉

  

    

   32

  辽宁

1200.00

     10104

   073

   

  

   实验员

   26

  广东

480.00

     10140

   081

   

  

    

   36

  北京

1400.00

     10176

   092

  卢声凯

  

    

   28

  湖北

720.00

     10212

   123

  林德康

  

  行政秘书

   33

  江西

480.00

     10248

   140

  熊南燕

  

    

   27

  上海 

780.00

     10284

   175

   

  

   实验员

   28

  江苏

480.00

     10320

   209

  袁秋慧

  

    

   24

  广东

720.00

其中,关键码为职工号。试根据此文件,对下列查询组织主索引和倒排索引,再写出搜索结果关键码。(1) 男性职工;(2) 月工资超过800元的职工;(3) 月工资超过平均工资的职工;(4) 职业为实验员和行政秘书的男性职工;(5) 男性教师或者年龄超过25岁且职业为实验员和教师的女性职工。

 

11-6 倒排索引中的记录地址可以是记录的实际存放地址,也可以是记录的关键码。试比较这两种方式的优缺点。

 

11-7 m = 2的平衡m路搜索树是AVL树,m = 3的平衡m路搜索树是2-3树。它们的叶结点必须在同一层吗?mB树是平衡m路搜索树,反过来,平衡m路搜索树一定是B树吗?为什么?

 

11-8 下图是一个3B树。试分别画出在插入65154030之后B树的变化。

点击查看原图

11-9 下图是一个3B树。试分别画出在删除5040之后B树的变化。

点击查看原图

11-10 对于一棵有1999999个关键码的199B树,试估计其最大层数(不包括失败结点)及最小层数(不包括失败结点)

 

11-11 给定一组记录,其关键码为字符。记录的插入顺序为 { C, S, D, T, A, M, P, I, B, W, N, G, U, R, K, E, H, O, L, J },给出插入这些记录后的4B+树。假定叶结点最多可存放3个记录。

11-12 设有一棵B+树,其内部结点最多可存放100个子女,叶结点最多可存储15个记录。对于1, 2, 3, 4, 5层的B+树,最多能存储多少记录,最少能存储多少记录。

11-13设散列表为HT[13], 散列函数为 H (key) = key %13。用闭散列法解决冲突, 对下列关键码序列 12, 23, 45, 57, 20, 03, 78, 31, 15, 36 造表。

       (1) 采用线性探查法寻找下一个空位, 画出相应的散列表, 并计算等概率下搜索成功的平均搜索长度和搜索不成功的平均搜索长度。

       (2) 采用双散列法寻找下一个空位, 再散列函数为 RH (key) = (7*key) % 10 + 1, 寻找下一个空位的公式为 Hi = (Hi-1 + RH (key)) % 13, H1 = H (key)。画出相应的散列表, 并计算等概率下搜索成功的平均搜索长度。

 

11-14 设有150个记录要存储到散列表中, 要求利用线性探查法解决冲突, 同时要求找到所需记录的平均比较次数不超过2次。试问散列表需要设计多大? a是散列表的装载因子,则有

                    

 

11-15 若设散列表的大小为m,利用散列函数计算出的散列地址为h = hash(x)

       (1) 试证明:如果二次探查的顺序为(h + q2), (h + (q-1)2), , (h+1), h, (h-1), , (h-q2),其中, q = (m-1)/2。因此在相继被探查的两个桶之间地址相减所得的差取模(%m)的结果为

              m-2, m-4, m-6, , 5, 3, 1, 1, 3, 5, , m-6, m-4, m-2

       (2) 编写一个算法,使用课文中讨论的散列函数h(x)和二次探查解决冲突的方法,按给定值x来搜索一个大小为m的散列表。如果x不在表中,则将它插入到表中。

11-16 编写一个算法,以字典顺序输出散列表中的所有标识符。设散列函数为hash(x) = x中的第一个字符,采用线性探查法来解决冲突。试估计该算法所需的时间。

11-17 设有1000个值在110000的整数,试设计一个利用散列方法的算法,以最少的数据比较次数和移动次数对它们进行排序。

11-18 设有15000个记录需放在散列文件中,文件中每个桶内各页块采用链接方式连结,每个页块可存放30个记录。若采用按桶散列,且要求搜索到一个已有记录的平均读盘时间不超过1.5次,则该文件应设置多少个桶?  

 

11-19 用可扩充散列法组织文件时,若目录深度为d,指向某个页块的指针有n个,则该页块的局部深度有多大?

 

11-20 设一组对象的关键码为 { 69, 115, 110, 255, 185, 143, 208, 96, 63, 175, 160, 99, 171, 137, 149, 229, 167, 121, 204, 52, 127, 57, 1040 }。要求用散列函数将这些对象的关键码转换成二进制地址,存入用可扩充散列法组织的文件里。定义散列函数为hash(key) = key % 64, 二进制地址取6位。设每个页块可容纳4个对象。要求按10 .4节介绍的方法设置目录表的初始状态,使目录表的深度为3。然后按题中所给的顺序,将各个对象插入的可扩充散列文件中。试画出每次页块分裂或目录扩充时的状态和文件的最后状态。