Resin 3 pro高并发,响应性与稳定性方案

以下方案我是在Intel xeon(至强) 3.2G 2个双核物理CPU+2G内存(Ecc)上进行:

resin版本为resin-pro-3.0.21,JVM为Jrockit 1.5_06, resin java 启动参数 -Xms256m -Xmx512m

1. 以下为resin.conf配置
<!–

– Resin 3.0 configuration file.

–>

<resin xmlns=“http://caucho.com/ns/resin”
xmlns:resin=“http://caucho.com/ns/resin/core”>

<!–

– Logging configuration for the JDK logging API.

–>

<log name=“” level=“all” path=“stdout:” timestamp=“[%H:%M:%S.%s] “/>



<logger name=“com.caucho.java” level=“config”/>

<logger name=“com.caucho.loader” level=“config”/>



<dependency-check-interval>600s</dependency-check-interval>



<javac compiler=“internal” args=“”/>



<thread-pool>

<thread-max>10240</thread-max>

<spare-thread-min>50</spare-thread-min>

</thread-pool>



<min-free-memory>5M</min-free-memory>



<server>

<class-loader>

<tree-loader path=“${resin.home}/lib”/>

<tree-loader path=“${server.root}/lib”/>

</class-loader>



<keepalive-max>1024</keepalive-max>

<keepalive-timeout>60s</keepalive-timeout>



<resin:if test=“${resin.isProfessional()}”>

<select-manager enable=“true”/>

</resin:if>



<bind-ports-after-start/>



<http server-id=“” host=“*” port=“80”/>



<cluster>

<srun server-id=“” host=“127.0.0.1” port=“6802”/>

</cluster>



<resin:if test=“${resin.isProfessional()}”>

<persistent-store type=“cluster”>

<init path=“session”/>

</persistent-store>

</resin:if>



<ignore-client-disconnect>true</ignore-client-disconnect>



<resin:if test=“${isResinProfessional}”>

<cache path=“cache” memory-size=“20M”/>

</resin:if>



<web-app-default>

<class-loader>

<tree-loader path=“${server.root}/ext-webapp”/>

</class-loader>



<cache-mapping url-pattern=“/” expires=“60s”/>

<cache-mapping url-pattern=“*.gif” expires=“600s”/>

<cache-mapping url-pattern=“*.jpg” expires=“600s”/>



<servlet servlet-name=“directory”
servlet-class=“com.caucho.servlets.DirectoryServlet”>

<init enable=“false”/>

</servlet>



<allow-servlet-el/>



<session-config>

<enable-url-rewriting>false</enable-url-rewriting>

</session-config>



</web-app-default>



<host-default>

<class-loader>

<compiling-loader path=“webapps/WEB-INF/classes”/>

<library-loader path=“webapps/WEB-INF/lib”/>

</class-loader>



<!–access-log path=“logs/access.log”

format=‘%h %l %u %t “%r” %s %b “%{Referer}i” “%{User-Agent}i”‘
rollover-period=“1W”/–>



<web-app-deploy path=“webapps”/>



<ear-deploy path=“deploy”>

<ear-default>

<!– Configure this for the ejb server



– <ejb-server>

– <config-directory>WEB-INF</config-directory>

– <data-source>jdbc/test</data-source>

– </ejb-server>

–>

</ear-default>

</ear-deploy>



<resource-deploy path=“deploy”/>



<web-app-deploy path=“deploy”/>

</host-default>



<resin:import path=“${resin.home}/conf/app-default.xml”/>



<host-deploy path=“hosts”>

<host-default>

<resin:import path=“host.xml” optional=“true”/>

</host-default>

</host-deploy>



<host id=“” root-directory=“.”>

<web-app id=“/” document-directory=“d:\website\chat”>

</web-app>

</host>



</server>

</resin>





2. 在应用的web.xml中加入resin status查看servlet映射

      <servlet-mapping servlet-class=‘com.caucho.servlets.ResinStatusServlet’>

<url-pattern>/resin-status</url-pattern>

<init enable=“read”/>

</servlet-mapping>



3. 启动resin,确认应用正常启动。

4. 写访问测试程序

import java.io.InputStream;

import java.net.URL;


public class TestURL

{
public static void main(String[] args) throws Exception

{
long a = System.currentTimeMillis();

System.out.println(“Starting request url:”);

for(int i = 0; i < 10000; i++){
URL url = new URL(“http://192.168.1.200/main.jsp”);



InputStream is = url.openStream();

is.close();

System.out.println(“Starting request url:”+i);

}
System.out.println(“request url end.take “(System.currentTimeMillis()-a)“ms”);

}


}



5. 在Jbuilder中执行TestURL

在执行过程中,一边刷新http://192.168.1.200/resin-status,查看resin状态,在http://*:80 中的 Active Threads 和 Total,会一直增长,当长到512的时候不再增长,这时再刷新resin-status页面时,会发现打开很慢。原因是服务器已经达到最大连接数,在等待前面连接的释放而不能接受新的连接。

于是下载Resin 3.0.21源码,搜索 512,发现com.caucho.server.port.Port类中有以下代码:
// default timeout


private long _timeout = 65000L;



private int _connectionMax = 512;//就是这行,查找resin所有源码后,发现没有对这个值进行设置

private int _minSpareConnection = 16;



private int _keepaliveMax = -1;



private int _minSpareListen = 5;

private int _maxSpareListen = 10;


将_connectionMax 改为 20480,然后重新编译并替换resin.jar中的Port类。

6. 重新启动Resin,再次运行TestURL进行测试,这次你会发现Threads Active 和 Total 一直变大,且可以超过512一直增大,在测试程序运行过程中刷新页面,页面响应性能还是不错的.

另,测试过程中Resin会打印出 1-3次 强制执行GC的信息,属于正常。

7.待测试完毕,Threads Active 和 Total 马上降为1.Idle为9,总内存为536.87Meg 空闲内存为480.33M

再经多次测试,结果一致,内存回收正常,表明当前 resin 稳定性和响应性可靠。

出自 JAVA开发者(http://www.chinajavaworld.com)

resin服务器突然变慢问题解决办法.

  本人负责的一个网站不知道为什么,由周一开始,突然间变得很慢,有时则很快.搞来搞去,搞了差不多一个星期(部份时间开发新功能去了).终于找到原因了.

 

服务器情况:

linux as4

Intel(R) Xeon(R) CPU            5130  @ 2.00GHz

4G内存,

300Gscsi+320GSATA硬盘.

resin 3.0.23+ lighttpd

 

resin启动参数

-server -verbose:gc -Xdebug -Xloggc:gc.log -Djava.awt.headless=true -XX:PermSize=128M -XX:NewRatio=4 -XX:+UseConcMarkSweepGC -XX:MaxPermSize=200m -XX:NewSize=100 -XX:MaxNewSize=128m -Xmn256m -Xms512m -Xmx512m

 

  服务器运行一直很正常,到了周一,网站变慢,CPU占用50%以上,但内存点使用50%,其中大部分是mysql用去了.load average: 10.02, 10.03, 10.00 .

 

  全部程序都测试过.底层代码也查过.JDK换过,RESIN版本换过,mysql配置也换过.问题依然存在.

 

  利用resin-admin查看情况.

 









Total memory: 501.44Meg
Free memory:

350.37Meg


  

  看上去也正常.不过free memory 变化的很快,由100多M,突然变到300多M.一开始还以为是程序释放了内存.就不去管他了.

 

  经过好多晚的调度,发现一个规律.当启动resin时,一切正常.证明跟jdk版本无关.

 

  今天早上更新服务器程序时,发现resin目录有个gc.log文件.打开一看.全部是gc的执行记录.很多.于是使用tail命令一下.

 

        tail -f gc.log

 

  吓了我一跳,平均每秒就会执行一次gc.问题就在这里.是gc把服务器拖慢了.

 

  于是就把resin的启动参数改一下,把内存改大,gc就不会这么容易触发.

 

        -server -verbose:gc -Xdebug -Xloggc:gc.log -Djava.awt.headless=true -XX:PermSize=128M -XX:NewRatio=4 -XX:+UseConcMarkSweepGC -XX:MaxPermSize=200m -XX:NewSize=100 -XX:MaxNewSize=128m -Xmn256m -Xms1024m -Xmx1024m

 

 

  现在好了,CPU占用只有0.1%左右,有时上到30%多,但很快降下来.load average: 0.05, 0.01, 0.00 <—服务器很健康.

 

  利用resin-admin查看情况.









Total memory: 998.44Meg
Free memory: 607.76Meg

      resin平均使用400M左右的内存,一开始只配置了512给她,怪不得老是gc.呵.

使用ping功能使resin更健壮

由于种种原因,resin有时会遇到resin down机的情况,比如:java.lang.OutOfMemoryError。这样的问题如果从代码角度来解决问题,也不是一时半会能解决的,应急解决方案是启用resin-pro的ping功能。
    <resin:if test=”${isResinProfessional}”>
      <ping>
        <url>http://localhost:8080/ping.jsp</url>
        <sleep-time>1m</sleep-time>
        <try-count>5</try-count>
        <socket-timeout>30s</socket-timeout>
      </ping>
    </resin:if>


ping.jsp可随意写一些代码,纯html代码也行,只能服务器能响应返回200。


如果访问resin访问http://localhost:8080/ping.jsp返回不是200 code,然后再重试try-count次,如果依然不响应200,则将自动重启resin服务。


如果在resin tag下配置了:


  <system-property mail.smtp.host=”127.0.0.1″/>
  <system-property mail.smtp.port=”25″/>


还可以让resin自动给你发个邮件通知你它自动重启过了:


    <ping resin:type=”com.caucho.server.admin.PingMailer”>
      <url>http://localhost:8080/ping.jsp</url>
      <mail-to>[email protected]</mail-to>
      <mail-from>[email protected]</mail-from>
      <mail-subject>Resin ping has failed for server ${’${’}server.name}</mail-subject>
    </ping>


这样配置好了,不管resin出现什么故障,只要resin进程不死,就可以放心睡大觉了。


如果还启用了resin的session持久化存储,用户基本感觉不到服务已经重启过了。


如果启用了resin的cluster,那么请修改httpd.sh,将-server参数加上,不然重启resin后是没有cluster的。


破解resin-pro-3.1

在网上查看了很多关于resin性能的文章,比较公认的说法是resin比tomcat的性能要高很多。


但最近在csdn上看了一篇文章,说resin 3.x的免费版与tomcat性能已经不相上下了。原因有两个:


1、tomcat从5.0后就开始在性能上不断改进,以达到生产环境的要求;


2、resin从3.0开始分为免费版与pro版,更多的性能改进被放到了pro版中了,所以免费版的性能就下降了。


基于这样的一些原因,更由于resin的pro版支持session持久化存储、负载均衡及cache等高端特性,于是对破解resin pro版产生了兴趣。


经过N个夜晚的奋战,终于把这个pro版给破解了。


网上也有人说破解得不好的resin pro版可能会使性能下降,个人感觉不存在这样的问题,只要破解了即可享用pro版的各种特性,性能也有大幅提高。


以下的resin启动的部分输出:


Resin Professional 3.1.4 (built Tue, 04 Dec 2007 11:27:12 PST)
Copyright(c) 1998-2007 Caucho Technology.  All rights reserved.


Starting Resin on Mon, 31 Dec 2007 17:18:52 +0800 (CST)


[17:18:53.640] {main} Proxy Cache disk-size=1024M memory-size=64M
[17:18:53.656] {main} PingThread[] starting, checking []
[17:18:54.109] {main}
[17:18:54.234] {main} Windows XP 5.1 x86
[17:18:54.343] {main} Java 1.5.0_11-b03, 32, mixed mode, GBK, zh, Sun Microsystems Inc.
[17:18:54.468] {main} user.name: dingl
[17:18:54.593] {main} resin.home = C:\resin-pro-3.1.4
[17:18:54.718] {main} resin.root = C:\resin-pro-3.1.4
[17:18:54.828] {main} resin.conf = /D:/workspace/project/resin-3.1.conf
[17:18:54.828] {main}
[17:18:55.734] {main} WebApp[http://localhost:80] Set web app root system property: ‘webapp.root’ = [D:\workspace\project\WebContent\]
[17:18:59.515] {main} WebApp[http://localhost:80] active
[17:19:00.171] {main} WebApp[http://localhost:80/resin-doc] active
[17:19:00.390] {main} WebApp[http://localhost:80/resin-admin] active
[17:19:00.500] {main} Host[] active
[17:19:00.640] {main} Socket JNI library is not available.
[17:19:00.640] {main} Resin will still run but performance will be slower.
[17:19:00.640] {main} To compile the Socket JNI library on Unix, use ./configure; make; make install.
[17:19:00.796] {main} hmux listening to localhost:6800
[17:19:00.921] {main} http listening to *:80
[17:19:01.140] {main} Server[id=,cluster=app-tier] active
[17:19:01.281] {main} Resin started in 9547ms


 可以看到已经没有关于license的提示了,并且增加了Proxy Cache disk-size=1024M memory-size=64M的输出,说明已经使用了cache来提高性能。


 值得一提的是,要想获得更好的性能,请使用linux/unix系统,因为在windows下,默认安装的resin是不能使用JNI库的,需要手工编译。而在linux/unix下,make源码后就已经将JNI库编译好了。这个特性可以从输出中看出来:


[17:19:00.640] {main} Socket JNI library is not available.
[17:19:00.640] {main} Resin will still run but performance will be slower.


linux/unix系统中没有这样的提示。


目前本blog提供resin-pro-3.1.3版的下载,地址为:


resin-pro-3.1.3 for windows 下载


resin-pro-3.1.3 for linux/unix 下载


resin-pro-3.1.4由于目前标记为dev,暂不破解此版本。3.1.5目前正在开发,尚未发布,目前已经可以看到3.1.5的change log了。


lighttpd configure java web server

我的apache 2.061在window 2003 下老是报告错误,虽然也可以使用但感觉很不爽.
错误入下,找了很久也没有办法,包括修复sockt也没用.
报告队列中的错误: 错误应用程序 Apache.exe,版本 2.0.61.200,错误模块 ntdll.dll,版本 5.2.3790.3959,错误地

一直想找一个替代apache的软件,最近看了lighttpd想用lighttpd来替代apache,先下放过资料.
下载地址.
http://ftp.dtech.hu/pub/WLMP-Project/LightTPD-Win32/



. When to use lighttpd


You can use lighttpd to



  • secure access to your application server
  • reduce load on your server by offloading static requests
  • load balance your application servers
  • use lighttpd’s spambot and bad bot blocking capabilities
  • get more request rewriting and redirecting flexibility
  • use the above flexibility to improve your search engine rankings
  • profit.

2. When not to use lighttpd


You might not like lighttpd if you



  • don’t like configuring software
  • use URL rewriting and ;jsessionid (though a patch is available for this problem).

3. lighttpd modules you need


The following lighty modules are needed:



  • mod_access
  • mod_redirect
  • mod_rewrite
  • mod_proxy

Add them to your server.modules section:

server.modules = (
“mod_accesslog”,
“mod_access”,
“mod_redirect”,
“mod_rewrite”,
“mod_proxy”
,
“mod_status”,
“mod_evhost”,
“mod_expire”
)

4. Denying access to JEE directories


The WEB-INF and META-INF directories shouldn’t be accessible through lighttpd. Files from your development environment also shouldn’t be visible.

url.access-deny = ( “WEB-INF”, “.classpath”, “.project”, “META-INF” )

5. Binding your application server to localhost


To prevent duplicate content penalties, your application server shouldn’t be visible from the web. Even if you run it on a high port, someone might eventually find it.


Binding a web site to localhost looks like this in Orion’s <name>-web-site.xml:

<web-site host=”127.0.0.1″ port=”12345″>
<frontend host=”johannburkard.de” port=”80″/>

Consult your documentation if you aren’t using Orion.


6. Redirecting www. to non-www. hosts


Even if you don’t really need to do this, I recommend doing so. Removing duplicate content will improve your rankings.


The following snippet redirects all visitors from www.<domain> to <domain> with a 301 permanent redirect.

$HTTP[“host”] =~ “^www\.(.*)___FCKpd___3quot; {
url.redirect = ( “^/(.*)” => “http://%1/$1” )
}

You should also redirect all additional domains (johannburkard.com, johann-burkard.org) to your main domain.


7. Proxying dynamic requests


We will use mod_proxy to proxy some requests to your Java application server.


Depending on your site’s structure, one of the following approaches will work better.


Simple JSP


If all you have is a bunch of Java Server Pages, the following mod_proxy rule is sufficient:

proxy.server = ( “.jsp” =>
(
( “host” => “127.0.0.1”,
“port” => “12345”
)
)
)

Note that the JSP must be actual files. You cannot use Servlets mapped to these URIs.


Applications


If you use Servlets or more complex applications, you can proxy URIs by prefix:

proxy.server = ( “/blog/” =>
(
( “host” => “127.0.0.1”,
“port” => “12345”
)
)
)

Proxying with exceptions


If most of your site is dynamic and you have a directory for static content (/assets, /static or so), you can proxy all requests except requests for static files:

$HTTP[“url”] !~ “^/static” {
proxy.server = ( “” =>
(
( “host” => “127.0.0.1”,
“port” => “12345”
)
)
)
}

8. Rewriting requests


lighttpd can dynamically rewrite requests. I mostly use this to use default.jsp as dynamic index file instead of index.html. Here’s an example:

url.rewrite-once = ( “^(.*)/___FCKpd___7quot; => “$1/default.jsp”,
“^(.*)/([;?]+.*)___FCKpd___7quot; => “$1/default.jsp$2” )

This is visible at gra0.com and internally rewrites all requests from / to /default.jsp (including jsessionid and query string).


mod_rewrite can also be used to make URLs shorter. For example, to remove the ?page=comments query string, I use the following:

url.rewrite-once = (
“^/blog/(.*)\.html___FCKpd___8quot; => “/blog/$1.html?page=comments”
)

9. Redirecting requests


You can use mod_redirect to redirect the user to a different URL. Contrary to mod_rewrite where the request is rewritten, a 301 permanent redirect will be sent to the browser.


In this example, I’m redirecting requests to an old domain to a new domain:

$HTTP[“host”] == “olddomain.com” {
url.redirect = (
“^/(.*)___FCKpd___9quot; => “http://newdomain.com/$1”
)
}

10. More things to be aware of



  • The only IP address in your application server log files should be 127.0.0.1. If you need the original address, log the X-FORWARDED-FOR header.
  • Don’t analyze both lighttpd and application server logs – lighty’s log files already contain all requests.
  • You might want to set up virtual hosts sooner or later.
  • Use mod_expire to make resources cacheable. Doing so can make your site a lot faster and save you money.

Configure lighttpd alias (mod_alias)


This lighttpd module provides for mapping different parts of the host filesystem in the document tree. You can use it for mapping various directories. For example cgi-bin directory mapped to /var/lib/cgi-bin.


Configuration


Open your lighttpd configuration file:


vi /etc/lighttpd/lighttpd.conf


Append/add mod_ alias to list of server modules:
server.modules += ( “mod_alias” )


Examples


Add cgi-bin alias for doamin theos.in
alias.url = ( “/cgi-bin/” => “/home/lighttpd/theos.in/cgi-bin/” )


Browse all documents installed at /usr/share/doc/ directory with following alias:
alias.url = ( “/docs/” => “/usr/share/doc/” )
alias.url += ( “/stats/” => “/home/theos.in/http/webalizer/” )


Open a browser and type url http://theos.in/docs/ or http://your-domain.com/docs/


巧用tmpfs加速你的linux服务器

巧用tmpfs加速你的linux服务器


今天从朋友高春辉那里又学了一招,就是使用tmpfs,我把他消化后用来实现虚拟磁盘来存放squid的缓存文件和php的seesion。速度快不少哦!


默认系统就会加载/dev/shm ,它就是所谓的tmpfs,有人说跟ramdisk(虚拟磁盘),但不一样。象虚拟磁盘一样,tmpfs 可以使用您的 RAM,但它也可以使用您的交换分区来存储。而且传统的虚拟磁盘是个块设备,并需要一个 mkfs 之类的命令才能真正地使用它,tmpfs 是一个文件系统,而不是块设备;您只是安装它,它就可以使用了。


tmpfs有以下优势:
1。动态文件系统的大小,
2。tmpfs 的另一个主要的好处是它闪电般的速度。因为典型的 tmpfs 文件系统会完全驻留在 RAM 中,读写几乎可以是瞬间的。
3。tmpfs 数据在重新启动之后不会保留,因为虚拟内存本质上就是易失的。所以有必要做一些脚本做诸如加载,绑定的操作。


好了讲了一些大道理,大家看的烦了吧,还是讲讲我的应用吧:)


首先在/dev/stm建个tmp文件夹,然后与实际/tmp绑定


mkdir /dev/shm/tmp
chmod 1777 /dev/shm/tmp
mount –bind /dev/shm/tmp /tmp



1。squid的缓存目录设置


vi /etc/squid/squid.conf


修改成
cache_dir ufs /tmp 256 16 256
这里的第一个256表示使用256M内存,我觉得高性能LINUX双效防火墙HOWTO使用ramdisk的方法还不如直接使用tmpfs,至少每次启动不用mkfs,还可以动态改变大小。


然后重启一下服务,ok,现在所有的squid缓存文件都保存倒tmpfs文件系统里了,很快哦。



2。对php性能的优化


对于一个访问量大的以apache+php的网站,可能tmp下的临时文件都会很多,比如seesion或者一些缓存文件,那么你可以把它保存到tmpfs文件。


保存seesion的方法很简单了只要修改php.ini就行了,由于我已经把/dev/stm/tmp与/tmp绑定,所以不改写也行,至于php程序产生的缓存文件那只能改自己的php程序了:)


希望我的这个方法,能对你有所启发。


参考文档:使用虚拟内存(virtual memory,VM)文件系统和绑定安装


lucene简单实例<二>

 写文章的时候,感觉比较难写的就是标题,有时候不知道起什么名字好,反正这里写的都是关于lucene的一些简单的实例,就随便起啦.

Lucene 其实很简单的,它最主要就是做两件事:建立索引和进行搜索
来看一些在lucene中使用的术语,这里并不打算作详细的介绍,只是点一下而已—-因为这一个世界有一种好东西,叫搜索。

IndexWriter:lucene中最重要的的类之一,它主要是用来将文档加入索引,同时控制索引过程中的一些参数使用。

Analyzer:分析器,主要用于分析搜索引擎遇到的各种文本。常用的有StandardAnalyzer分析器,StopAnalyzer分析器,WhitespaceAnalyzer分析器等。

Directory:索引存放的位置;lucene提供了两种索引存放的位置,一种是磁盘,一种是内存。一般情况将索引放在磁盘上;相应地lucene提供了FSDirectory和RAMDirectory两个类。

Document:文档;Document相当于一个要进行索引的单元,任何可以想要被索引的文件都必须转化为Document对象才能进行索引。

Field:字段。

IndexSearcher:是lucene中最基本的检索工具,所有的检索都会用到IndexSearcher工具;

Query:查询,lucene中支持模糊查询,语义查询,短语查询,组合查询等等,如有TermQuery,BooleanQuery,RangeQuery,WildcardQuery等一些类。

QueryParser: 是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象。

Hits:在搜索完成之后,需要把搜索结果返回并显示给用户,只有这样才算是完成搜索的目的。在lucene中,搜索的结果的集合是用Hits类的实例来表示的。

上面作了一大堆名词解释,下面就看几个简单的实例吧:
1、简单的的StandardAnalyzer测试例子



Java代码


  1. package lighter.javaeye.com;  

  2.   

  3. import java.io.IOException;  

  4. import java.io.StringReader;  

  5.   

  6. import org.apache.lucene.analysis.Analyzer;  

  7. import org.apache.lucene.analysis.Token;  

  8. import org.apache.lucene.analysis.TokenStream;  

  9. import org.apache.lucene.analysis.standard.StandardAnalyzer;  

  10.   

  11. public class StandardAnalyzerTest   

  12. {  

  13.     //构造函数,  

  14.     public StandardAnalyzerTest()  

  15.     {  

  16.     }  

  17.     public static void main(String[] args)   

  18.     {  

  19.         //生成一个StandardAnalyzer对象  

  20.         Analyzer aAnalyzer = new StandardAnalyzer();  

  21.         //测试字符串  

  22.         StringReader sr = new StringReader(“lighter javaeye com is the are on”);  

  23.         //生成TokenStream对象  

  24.         TokenStream ts = aAnalyzer.tokenStream(“name”, sr);   

  25.         try {  

  26.             int i=0;  

  27.             Token t = ts.next();  

  28.             while(t!=null)  

  29.             {  

  30.                 //辅助输出时显示行号  

  31.                 i++;  

  32.                 //输出处理后的字符  

  33.                 System.out.println(“第”+i+“行:”+t.termText());  

  34.                 //取得下一个字符  

  35.                 t=ts.next();  

  36.             }  

  37.         } catch (IOException e) {  

  38.             e.printStackTrace();  

  39.         }  

  40.     }  

  41. }  

显示结果:

引用

第1行:lighter
第2行:javaeye
第3行:com

提示一下:
StandardAnalyzer是lucene中内置的”标准分析器”,可以做如下功能:
1、对原有句子按照空格进行了分词
2、所有的大写字母都可以能转换为小写的字母
3、可以去掉一些没有用处的单词,例如”is”,”the”,”are”等单词,也删除了所有的标点
查看一下结果与”new StringReader(“lighter javaeye com is the are on”)”作一个比较就清楚明了。
这里不对其API进行解释了,具体见lucene的官方文档。需要注意一点,这里的代码使用的是lucene2的API,与1.43版有一些明显的差别。

2、看另一个实例,简单地建立索引,进行搜索



Java代码


  1. package lighter.javaeye.com;  

  2. import org.apache.lucene.analysis.standard.StandardAnalyzer;  

  3. import org.apache.lucene.document.Document;  

  4. import org.apache.lucene.document.Field;  

  5. import org.apache.lucene.index.IndexWriter;  

  6. import org.apache.lucene.queryParser.QueryParser;  

  7. import org.apache.lucene.search.Hits;  

  8. import org.apache.lucene.search.IndexSearcher;  

  9. import org.apache.lucene.search.Query;  

  10. import org.apache.lucene.store.FSDirectory;  

  11.   

  12. public class FSDirectoryTest {  

  13.   

  14.     //建立索引的路径  

  15.     public static final String path = “c:\\index2”;  

  16.   

  17.     public static void main(String[] args) throws Exception {  

  18.         Document doc1 = new Document();  

  19.         doc1.add( new Field(“name”“lighter javaeye com”,Field.Store.YES,Field.Index.TOKENIZED));  

  20.   

  21.         Document doc2 = new Document();  

  22.         doc2.add(new Field(“name”“lighter blog”,Field.Store.YES,Field.Index.TOKENIZED));  

  23.   

  24.         IndexWriter writer = new IndexWriter(FSDirectory.getDirectory(path, true), new StandardAnalyzer(), true);  

  25.         writer.setMaxFieldLength(3);  

  26.         writer.addDocument(doc1);  

  27.         writer.setMaxFieldLength(3);  

  28.         writer.addDocument(doc2);  

  29.         writer.close();  

  30.   

  31.         IndexSearcher searcher = new IndexSearcher(path);  

  32.         Hits hits = null;  

  33.         Query query = null;  

  34.         QueryParser qp = new QueryParser(“name”,new StandardAnalyzer());  

  35.           

  36.         query = qp.parse(“lighter”);  

  37.         hits = searcher.search(query);  

  38.         System.out.println(“查找\”lighter\” 共” + hits.length() + “个结果”);  

  39.   

  40.         query = qp.parse(“javaeye”);  

  41.         hits = searcher.search(query);  

  42.         System.out.println(“查找\”javaeye\” 共” + hits.length() + “个结果”);  

  43.   

  44.     }  

  45.   

  46. }  

运行结果:



Java代码


  1. 查找“lighter” 共2个结果  

  2. 查找“javaeye” 共1个结果  

lucene的简单实例<一>

 说明一下,这一篇文章的用到的lucene,是用2.0版本的,主要在查询的时候2.0版本的lucene与以前的版本有了一些区别.
其实这一些代码都是早几个月写的,自己很懒,所以到今天才写到自己的博客上,高深的文章自己写不了,只能记录下一些简单的记录与点滴,其中的代码算是自娱自乐的,希望高手不要把重构之类的砸下来…

1、在windows系统下的的C盘,建一个名叫s的文件夹,在该文件夹里面随便建三个txt文件,随便起名啦,就叫”1.txt”,”2.txt”和”3.txt”啦
其中1.txt的内容如下:



Java代码


  1. 中华人民共和国  

  2. 全国人民  

  3. 2006年  

而”2.txt”和”3.txt”的内容也可以随便写几写,这里懒写,就复制一个和1.txt文件的内容一样吧

2、下载lucene包,放在classpath路径中
建立索引:



Java代码


  1. package lighter.javaeye.com;  

  2.   

  3. import java.io.BufferedReader;  

  4. import java.io.File;  

  5. import java.io.FileInputStream;  

  6. import java.io.IOException;  

  7. import java.io.InputStreamReader;  

  8. import java.util.Date;  

  9.   

  10. import org.apache.lucene.analysis.Analyzer;  

  11. import org.apache.lucene.analysis.standard.StandardAnalyzer;  

  12. import org.apache.lucene.document.Document;  

  13. import org.apache.lucene.document.Field;  

  14. import org.apache.lucene.index.IndexWriter;  

  15.   

  16. /** 

  17.  * author lighter date 2006-8-7 

  18.  */  

  19. public class TextFileIndexer {  

  20.     public static void main(String[] args) throws Exception {  

  21.         /* 指明要索引文件夹的位置,这里是C盘的S文件夹下 */  

  22.         File fileDir = new File(“c:\\s”);  

  23.   

  24.         /* 这里放索引文件的位置 */  

  25.         File indexDir = new File(“c:\\index”);  

  26.         Analyzer luceneAnalyzer = new StandardAnalyzer();  

  27.         IndexWriter indexWriter = new IndexWriter(indexDir, luceneAnalyzer,  

  28.                 true);  

  29.         File[] textFiles = fileDir.listFiles();  

  30.         long startTime = new Date().getTime();  

  31.           

  32.         //增加document到索引去  

  33.         for (int i = 0; i < textFiles.length; i++) {  

  34.             if (textFiles[i].isFile()  

  35.                     && textFiles[i].getName().endsWith(“.txt”)) {  

  36.                 System.out.println(“File “ + textFiles[i].getCanonicalPath()  

  37.                         + “正在被索引….”);  

  38.                 String temp = FileReaderAll(textFiles[i].getCanonicalPath(),  

  39.                         “GBK”);  

  40.                 System.out.println(temp);  

  41.                 Document document = new Document();  

  42.                 Field FieldPath = new Field(“path”, textFiles[i].getPath(),  

  43.                         Field.Store.YES, Field.Index.NO);  

  44.                 Field FieldBody = new Field(“body”, temp, Field.Store.YES,  

  45.                         Field.Index.TOKENIZED,  

  46.                         Field.TermVector.WITH_POSITIONS_OFFSETS);  

  47.                 document.add(FieldPath);  

  48.                 document.add(FieldBody);  

  49.                 indexWriter.addDocument(document);  

  50.             }  

  51.         }  

  52.         //optimize()方法是对索引进行优化  

  53.         indexWriter.optimize();  

  54.         indexWriter.close();  

  55.           

  56.         //测试一下索引的时间  

  57.         long endTime = new Date().getTime();  

  58.         System.out  

  59.                 .println(“这花费了”  

  60.                         + (endTime – startTime)  

  61.                         + ” 毫秒来把文档增加到索引里面去!”  

  62.                         + fileDir.getPath());  

  63.     }  

  64.   

  65.     public static String FileReaderAll(String FileName, String charset)  

  66.             throws IOException {  

  67.         BufferedReader reader = new BufferedReader(new InputStreamReader(  

  68.                 new FileInputStream(FileName), charset));  

  69.         String line = new String();  

  70.         String temp = new String();  

  71.           

  72.         while ((line = reader.readLine()) != null) {  

  73.             temp += line;  

  74.         }  

  75.         reader.close();  

  76.         return temp;  

  77.     }  

  78. }  


索引的结果:



Java代码


  1. File C:\s\1.txt正在被索引….  

  2. 中华人民共和国全国人民2006年  

  3. File C:\s\2.txt正在被索引….  

  4. 中华人民共和国全国人民2006年  

  5. File C:\s\3.txt正在被索引….  

  6. 中华人民共和国全国人民2006年  

  7. 这花费了297 毫秒来把文档增加到索引里面去!c:\s  


3、建立了索引之后,查询啦….



Java代码


  1. package lighter.javaeye.com;  

  2.   

  3. import java.io.IOException;  

  4.   

  5. import org.apache.lucene.analysis.Analyzer;  

  6. import org.apache.lucene.analysis.standard.StandardAnalyzer;  

  7. import org.apache.lucene.queryParser.ParseException;  

  8. import org.apache.lucene.queryParser.QueryParser;  

  9. import org.apache.lucene.search.Hits;  

  10. import org.apache.lucene.search.IndexSearcher;  

  11. import org.apache.lucene.search.Query;  

  12.   

  13. public class TestQuery {  

  14.     public static void main(String[] args) throws IOException, ParseException {  

  15.         Hits hits = null;  

  16.         String queryString = “中华”;  

  17.         Query query = null;  

  18.         IndexSearcher searcher = new IndexSearcher(“c:\\index”);  

  19.   

  20.         Analyzer analyzer = new StandardAnalyzer();  

  21.         try {  

  22.             QueryParser qp = new QueryParser(“body”, analyzer);  

  23.             query = qp.parse(queryString);  

  24.         } catch (ParseException e) {  

  25.         }  

  26.         if (searcher != null) {  

  27.             hits = searcher.search(query);  

  28.             if (hits.length() > 0) {  

  29.                 System.out.println(“找到:” + hits.length() + ” 个结果!”);  

  30.             }  

  31.         }  

  32.     }  

  33.   

  34. }  


其运行结果:

引用

找到:3 个结果!

具体的API的用法,这里就不说了,具体的做法参考lucene的官方文档吧…

Linux user commands

Every user who has access to a Linux system needs a login and a password. Each user must belong to a primary group and for security or access purposes can belong to several secondary groups.


In order to create new logins, modify or delete users, you must already be logged in as root.  The root login is the highest level and only certain individuals should have access to the root account.


useradd – Adding a new user

Options:

  • -d home directory
  • -s starting program (shell)
  • -p password
  • -g (primary group assigned to the users)
  • -G (Other groups the user belongs to)
  • -m (Create the user’s home directory

Example: To add a new user with



  • a primary group of users
  • a second group mgmt
  • starting shell /bin/bash
  • password of xxxx
  • home directory of roger
  • create home directory
  • a login name of roger

useradd -gusers -Gmgmt -s/bin/shell -pxxxx -d/home/roger -m roger


 



usermod – Modifying existing user


Options:



  • -d home directory
  • -s starting program (shell)
  • -p password
  • g (primary group assigned to the users)
  • -G (Other groups the user belongs to)

Example: To add the group ‘others’ to the user roger


usermod -Gothers roger



userdel – Deleting a user


Options:



  • -r (remove home directory)

Example: To remove the user ‘roger’ and his home directory


userdel -r roger



passwd – User’s Password

Options:

  • user’s name (Only required if you are root and want to change another user’s password)

Example: To change the password for the account you are currently logged in as…



passwd
Enter existing password
Enter new password
Enter new password again (to validate)


Example: To change the password for the user ‘roger’ (only you are logged in as root)…



passwd roger
Enter existing password
(can be either roger’s password or root’s password)
Enter new password
Enter new password again (to validate)



Where user and group information stored


User names and primary groups are stored in /etc/passwd. This file can be directly edited using the ‘vi’ editor, although this is not recommended. Format of the file is…



  • User name (normally all lower case)
  • Password (encrypted – only contains the letter ‘x’)
  • User ID (a unique number of each user)
  • Primary Group ID
  • Comment (Normally the person’s full name)
  • Home directory (normally /home/<user name>
  • Default shell (normally /bin/bash)

Each field is separated by a colon.


Passwords for each user are stored in /etc/shadow. This file should only be changed using the passwd command.


Group information is stored in /etc/group. This file can be directly edited using the ‘vi’ editor. Format of the file is…



  • Group name
  • Group password (hardly ever used)
  • Group ID
  • User names (separated by commas)

Each field is separated by a colon.


Default files


When a new user is created, the default files and directories that are created are stored in /etc/skel.


This directory can be modified to fit your needs. Modifications only effect new users and does not change anything for existing users.



su – Switch User


To switch to another user, use the su command. This is most commonly used to switch to the root account.



Example: To switch to root account…
su
Enter root’s passwd


Example: To switch to the user ‘roger’…
su roger
Enter roger’s or root’s passwd


To return to original user, enter exit