统内部数据建立索引提供给用户进行检索。
它既能满足用户对全文检索,模糊匹配的需求,解决数据库like查询效率低下的问题,又能够解决分布式环境下,由于采用分库分表或使用NoSQL数据库,导致无法进行多表关联或者进行复杂查询的问题。
lucene将文档中的词作为关键字,建立词与文档的映射关系,通过对倒排索引的检索,可以根据词快速获取包含这个词的文档列表。
能对句子或段落进行切割,从中取出包含固定语义的词。
当输入一个关键字进行搜索时,可能会命中许多文档,搜索引擎给用户的价值就是快速地找到需要的文档,根据排序算法,将相关度更大的内容排在前面,命中多次的文档比命中一次的文档有更高的相关性。
6.3文件的处理
传统系统用户只能下载文件后才能查看文件内容,并不能让用户在文件下载之前就能查看文件的内容,经常导致用户下载文件后发现文件不是自己想要的,不仅影响用户的体验,同时也给网站带来流量开销和连接的压力。为了实现文件预览,我们需要将文件转换为swf文件,实现flash播放达到预览,在这里面我们不仅要考虑不用版本office文件处理问题,还要考虑如果文件里面有图片如何准确提取出来把数据正确的存储到swf文件中。在这我们通过java代码使用OpenOffice服务把文件转换为swf文件,使用FlexPaper,swfTools在线预览,从而达到用户不需下载文件就能看到文件内容。
6.4敏感词过滤
由于本系统收录的敏感词库中包含上万个敏感词,系统要对用户输入的文件信息进行处理,检查用户输入的信息是否含有敏感词,但是这里带来一个效率问题,采用传统思路,系统会对用户输入的一个文本数据比对上万次,来验证文本数据是否包含敏感词库的词。显然这是十分耗时的。NFA是非确定性的状态机,DFA是确定性的状态机。确定性和非确定性的最大区 别就是:从一个状态读入一个字符,确定性的状态机得到一个状态,而非确定性的状态机得到一个状态的集合。如果我们把NFA的起始状态S看成一个集合{S} 的话,对于一个状态集合S’,给定一个输入,就可以用NFA计算出对应的状态集合T’。因此我们在构造DFA的时候,只需要把起始状态对应到S’,并且找 到所有可能在NFA同时出现的状态集合,把这些集合都转换成DFA的一个状态,那么任务就完成了。因为NFA的状态是有限的,所以NFA所有状态的集合的 幂集的元素个数也是有限的,因此使用这个方法构造DFA是完全可能的。
6.5网站高并发
一台tomcat服务器最大能支持的稳定并发数在100—120之间,因为本系统是面向互联网用户的,所以在同一时刻本系统面对的并发数远远大于120,当实际并发数大于tomcat服务器的支持数量后,会导致服务器因为压力过大而无法及时处理其他请求,甚至导致服务器宕机。考虑到高并发访问的情况,本系统使用Nginx服务器的负载均衡技术构建一个由多台服务器组成的服务器集群,将来自客户端的并发访问请求分发到多台服务器上处理,避免单一服务器出现负载压力过大的情况。
为了保证当任意一台或多台服务器宕机,Nginx服务器将请求提交给集群中其他任意一台可用服务器能够正确处理处理,本系统需要设置每一台服务器不保存请求的状态,这样所有的服务器完全对等,服务器就可以成功处理其他服务器之前处理的请求了。
6.6服务器集群下状态共享
集群中所有的应用服务器都是无状态的,但是在业务上系统总是有状态的,因为系统需要记录用户当前的登录状态来确定用户是否可以执行接下来的操作。web应用中将这些多次请求使用的上下文对象称作会话(session),单机情况下,session可由部署在服务器上的web容器管理。在使用负载均衡的集群环境中,请求由负载均衡服务器分发到集群上任意一台应用服务器上,如何保证任意一台应用服务器对每次请求依然能够获得正确的session是一个挑战。
通过将一部分数据存储在cookie中,来解决分布式环境下session操作同步的问题。但是这样做的弊端有很多,比如cookie的安全性,cookie存储数据的大小的限制。
本系统的解决方案是将session统一存储在缓存集群memcache上,这样保证较高的读,写性能,再从安全性上看,利用缓存的失效机制,达到控制session有效期的的作业。
6.7高并发下磁盘读写速度
系统在面对高并发的情况下,大量地读,写请求涌向数据库,磁盘的处理速度与内存显然不在一个量级,为了能提高系统对数据的读取速度,通常将常用的数据放在内存中,这样就避免了应用程序读取硬盘而增加时间开销。
memcache是一个高性能的内存对象缓存系统,为了提高在内存中查找数据的速度,memcache在内存中维护一张巨大的HashTable,使得对数据查询的时间复杂度降低到O(1)。内存的空间总是有限的,当内存没有更多的空间来存储新数据时,memcache会使用LRU算法,将最近不常访问的数据淘汰掉,以腾出空间来存放新的数据。
6.8分布式数据库事务一致性
软件系统对单个数据库内部的多个DML操作都会组成一个局部事务,因为这些操作不会跨越多个事务性资源,软件系统可以直接使用底层数据库的事务支持;但是当软件系统的功能操作涉及对多个数据库的修改时,就面临多个数据库事务的一致性问题,这些数据库的操作要么全部成功要么全部不成功,这就是分布式事务,分布式事务处理的对象是全局事务。
使用JTA编程就可以用一种与事务管理器无关的方式来开始,提交或回滚事务,Java EE应用服务器通过java事务服务来实现事务管理器。JTA事务由java EE事务管理器负责控制,它可以保证多个数据库更新的一致性,通过JTA即可实现全局事务控制。
6.9集群下quartz协调处理
在集群环境下,大家会碰到一直困扰的问题,即多个应用程序下如何用quartz协调处理自动化工作。比如现在有A,B,C三台服务器同时作为集群服务器对外统一提供服务;A,B,C三台台机器上各有一个Quarzt,他们会按照即定的时间频率自动执行各自的任务。这样的架构其实有点像多线程,那多线程里就会存在“资源竞争”的问题,即可能产生脏读,脏写,由于三台应用服务器里都有Quarzt,因此会存在重复处理任务的现象。quartz的任务实例化如数据库,基于数据库引擎及High-Available的策略(集群的一种策略)自动协调每个节点的quartz,当任一一节点的quartz非正常关闭或出错时,另几个节点的quartz会自动启动;这样每台作为集群点的应用程序上都可以部署quartz;无需开发人员更改原已经实现的quartz,使用Spring类反射的机制对原有程序作切面重构。