本版本3.08版。 一、在Windows下,如何启动UFO? 答:1. 首先,您的计算机要安装JDK1.5.0以及以上版本的JDK! 低版本的JDK将无法运行UFO; 2. 进入bin目录,Windows操作系统敲startup.bat, 回车。 重要注意:如果您在Windows下运行startup.bat而不能启动UFO,则只需要做一件事情: 打开bin目录下的setclasspath.bat文件,插入一行:set JAVA_HOME=D:\jdk1.5.0_16 把JAVA_HOME设置成JDK在您计算机上的安装目录。然后,再运行startup.bat文件即可。 进一步说明:在UFO发布的setclasspath.bat文件中的第4行是这样的: rem set JAVA_HOME=D:\jdk1.5.0_16 在Windows下运行startup.bat而不能启动UFO的时候,您只需要把上面的那行的"rem "去 掉,并且把"D:\jdk1.5.0_16"替换成您计算机里的JDK的安装目录(所谓安装目录就是含 有bin的目录),然后重新运行startup.bat文件即可。 二、在Linux (redhat/centOS/ubuntu)下,如何安装、启动UFO? 答: (下面的操作是在redhat/centOS下进行的,ubuntu下类似) 1. 从java.sun.com官方网站下载Linux平台的JDK: jdk-7u2-linux-i586.rpm; 2. 从www.gm365.com官方网站下载Linux平台的UFO版:UFO_3.08.tar.gz; 3. 把上面2个文件上传到你的Linux服务器的/usr/local目录下; 4. 安装JDK # cd /usr/local # rpm -ivh jdk-7u2-linux-i586.rpm 5. 安装UFO # cd /usr/local # tar -zxvf UFO_3.08.tar.gz 6. 配置环境变量 # vi /etc/profile (1) 在这个文件末尾加上 export JAVA_HOME=/usr/local/jdk1.7.0_02 export CLASSPATH=.:$JAVA_HOME/lib/tools.jar export PATH=$PATH:$JAVA_HOME/bin (2) 利用下面命令使配置生效,并且查看JDK版本 # source /etc/profile # java -version 7. 配置放火墙 # vi /etc/sysconfig/iptables 添加如下代码 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT 重启iptables service iptables restart (注意:一些机房为了防止DDOS攻击,在机房本身还有一道放火墙,您要向机房申请对您的 IP的80端口开通!) 8. 对.sh添加执行权限 # cd /usr/local/UFO/bin # chmod a+x ./*.sh 9. 启动UFO # cd /usr/local/UFO/bin # ./startup.sh 三、在Linux (redhat/centOS/ubuntu)下,如何关掉UFO? 答:(条件同问题二) # cd /usr/local/UFO/bin # ./shutdown.sh 四、在Linux (redhat/centOS/ubuntu)下,如何开机启动UFO? 答:(条件同问题二) #vi /etc/rc.d/rc.local    添加以下内容: export JAVA_HOME=/usr/local/jdk1.7.0_02 cd /usr/local/UFO/bin ./startup.sh 五、在Windows下,如何关掉UFO? 答:进入UFO的bin目录,敲shutdown.bat, 回车。 六、如何把UFO注册成windows服务启动啊? 答:我不知道您怎么会有这样的需求。 关于UFO作为windows service的所有东西都在UFO的win-service子目录里。 要把UFO作为windows service安装或启动,您所要做的唯一事情是修改wrapper.conf, 一共需要 修改4个地方(这4个地方都用一对"# !!!!!!!!!!!!!!!!!!"行标记起来): 1. wrapper.java.command=D:\jdk1.5.0_16\bin\java 根据您计算机的JDK,把wrapper.java.command指向java.exe(注意:设置时可不带.exe). 2. wrapper.java.classpath.3=D:\jdk1.5.0_16\lib\tools.jar 根据您计算机的JDK,把wrapper.java.classpath.3指向lib\tools.jar 3. wrapper.java.classpath.4=D:\UFO\lib\javax.zip wrapper.java.classpath.5=D:\UFO\lib\mysql-connector-java-3.1.14-bin.jar wrapper.java.classpath.6=D:\UFO\lib\UFO-db.zip wrapper.java.classpath.7=D:\UFO\lib\UFO-jdt.jar 把classpath指向UFO的lib目录里的.zip和.jar. 4. wrapper.app.parameter.3=D:\UFO 把wrapper.app.parameter.3指向UFO的安装目录(所谓安装目录就是含有bin子目录的目录)。 在修改好wrapper.conf后,运行install_service.bat,安装成功后,再运行start_service.bat, UFO就是作为windows service启动起来了。 七、3.08版UFO有何改动? 答:1. 3.08版对server.xml里的Connector标签的各个属性从程序上进行了校对,更好地防Hacker。 (参见问题三十二) 2. 3.07版对Post方法请求静态网页时给予输出。 3. 3.06版改正UFO一种可能down掉的Bug。 4. 3.05版重做了UFO的windows service部分。 5. 3.05版对各个.bat和.sh文件进行了校对,并调整了发布目录结构。 6. 3.05版不再要求站在UFO的bin目录下发出startup/reload/shutdown命令。在Linux下, 可以站在任何目录位置发出命令,例如:./startup.sh, ./bin/startup.sh, /usr/local/ UFO/bin/startup.sh都是正确的。在Windows下,要求站在UFO的安装目录或bin目录下 发出startup/reload/shutdown命令,例如:startup.bat, bin\startup.bat都是正确的, 而UFO\bin\startup.bat则是不正确的。 7. 3.05版在Linux下启动多个UFO进程时,用ps -efw命令查找进程PID时得到了很好的区分。 8. 3.05版修改了reload的Bug. 9. 3.01版在程序内部检查UFO安装路径的正确性。 10. 3.00版修改shutdown.sh有时不能kill UFO(尤其是在ubuntu操作系统下)的Bug。 11. 2.99版修改UFO Web Server一种不能启动的情形。 12. 2.98版支持Head方法(从而支持一些搜索引擎的蜘蛛爬虫)。 13. 2.97版修改有关Post方法的一个Bug。(与Apache cxf项目,SOA有关) 14. 2.96版修改pathInfo里含有"/"时,Request的getPathInfo(), getServletPath()返回值不对的Bug。 (与Apache cxf项目有关) 15. 2.96版修改RequestDispatcher.forward()后,Request的getQueryString()返回值不对的Bug。 (与Apache cxf项目有关) 16. 2.96版对web.xml里的里的的*通配符进行了标准实现。 17. 2.95版支持ETag, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since等Http 头。(控制利用浏览器端缓存、节省带宽、提高负载、提高静态网页响应速度,So, 聪明的网站应 采用静态网页做首页,并且能使用静态网页的地方决不使用动态网页) 18. 2.95版支持If-Range, Range等Http头(断点续传)。 19. 2.93版修改了GET方法的URL含有"?"时,Request的getPathInfo(), getServletPath(), getPathTranslated(), getRequestURL()返回值不对的问题(与axis和struts项目有关)。 20. 2.93版修改了"Last-Modified: " http头的值不对的问题。 21. 2.91版修改这样一个ClassCastException的问题:以前版本如果一个jsp里import了WEB-INF\classes\ 里的类,先访问这个jsp,然后在不重启UFO的情况下,修改这个jsp,再访问,可能throw ClassCastException的Bug. 22. 2.90版支持gzip压缩。 23. 2.90版支持"chunked" Transfer-Encoding,但从Client向Server端"chunked" Transfer-Encoding暂 不支持。 24. 2.90版修改jsp/servlet的"Server"和"Date" Header重复输出的问题。 25. 2.90版修改RequestDispatcher的forward在"File Not Found"时,显示空白页的Bug。 26. 2.90版将/lib/javax.zip里的UFO自己的javax.db目录分离出来,形成UFO-db.zip,以方便用户用JDT 开发调试程序。 27. 2.90版增加了Connector标签的keepAlive等多个属性。 28. 2.90版在server.xml里增加了Probe标签和属性。 29. 2.90版在server.xml里增加了Session标签和属性。 30. 2.85版填写ServletContext.getResourcePaths()方法,以支持Spring。 31. 2.85版修改了UFO.bat、UFO.sh、UFOW.bat以及发布目录结构,以防止Spring(试图)重复装载类。 32. 2.83版修改Reponse.flushBuffer()的Bug。(主要与Struts项目有关) 33. 2.82版修改server.xml、web.xml等xml文件里有注释行时可能出错的Bug。 34. 2.82版修改Request.getParameterMap().entrySet()不正确的Bug。(主要与Struts项目有关) 35. 2.81版支持web.xml里的属性。 36. 2.81版正确设置Request的javax.servlet.include.servlet_path的属性值(与Struts的include有关)。 37. 2.81版修改ServletContext的getResource()方法的一个Bug。 38. 2.80版修改一处较严重的内存泄漏的Bug。 39. 2.77版改正未在server.xml里显式配置Context的Dir和war部署的web.xml里的welcome-file无效的Bug。 40. 2.77版改正把"/*"的url映射成Struts的Filter时,当url不以"/"结尾并且不是文件名时,访问不到 welcome-file的Bug。 41. 2.77版修改以前部分版本中由于“笔误”,在有多个Context时,配置Filter时可能引起混乱的Bug。 42. 2.76版大大提高了ClassLoader从zip/jar包装载类的速度。 43. 2.76版支持从zip/jar包装载Servlet类。 44. 2.75版修改并优化了UFO的ClassLoader。 45. 2.75版修改了编译的jsp的class格式,使之与Pro版编译的jsp的class格式一样。就是说,今后UFO 无论是Pro版还是普通版,都只有一种格式的jsp编译格式的class。这样做,既是为了方便用户也是 为了方便开发者。 46. 2.75版正确处理URL里含有"./"字符串的情形。 47. 2.75版在conf/server.xml文件里时,当"File Not Found"时,以相对路径显示 文件,这是为了防止向Hacker暴露Server采用何种操作系统。而在Debug mode为"1"等其它值时,当 "File Not Found"时,以绝对路径显示文件。 48. 2.75版的UFO Probe在UFO进程产生hs_err_pidxxx.log时,显示为要求重启的警告状态。 49. 2.72版修改web.xml里servlet标签和filter标签的init-param属性不起作用的Bug。 50. 2.71版修改examples的数据库连接池的例子,并修改server.xml中一个注释行位置不对的问题, 以免用户上帝纳闷。 51. 2.70版修改war部署时忘了处理web.xml文件的问题。 52. 2.69版修改在Linux下敲./shutdown.sh有时不能Kill掉UFO进程的Bug。 53. 2.68版修改UFO Probe的下行流量有时突然增大几十M(而实际上流量并没有增大)的问题。 54. 2.67版修改Request.getParameterMap()相关的中文乱码问题。 55. 2.66版增加struts的demo和EL表达式的demo。 56. 2.65版修改把"/*"的url映射成Filter时,不能输出静态网页的Bug。本版本对支持struts进行了比较 充分的测试。 57. 2.64版针对支持struts,将UFO的两个对外接口规范化。本版本对支持struts进行了比较充分的测试。 58. 2.63版关于RequestDispatcher的Bug。 59. 2.62版修改关于Filter的Bug。 60. 2.61版修正在一种情况下Servlet不能装载的Bug,就是Ajax的demo中ProgressBar、ToolTip、 YahooSearch不能运行的问题,这个Bug是在2.60版中引入的。 61. 2.60版大幅降低运行内存,特别是对有很多个Context和Host的大项目。 62. 2.60版在编译了jsp/servlet后,内存泄漏大为下降,这样在UFO编译了jsp/servlet不重启也问题不大。 63. 2.60版动态装载更新的servlet class,以前版本虽然能动态编译servlet却不能动态装载。 64. 2.60版动态更新类路径,在UFO类路径上的类jar包、zip包发生增加,UFO编译时立即生效, 而不需要重新启动UFO(而jar包、zip包发生更新、删除时,则要求重启动UFO)。 65. 2.60版修改https状态下不能显示图片验证码的Bug。 66. 2.51版在每天休闲时候执行一次System.gc()对UFO进程进行垃圾回收。 67. 2.50版采用eclipse的JDT Java编译器作为UFO的默认编译器。 68. 2.38版修改RequestDispatcher的相对路径的Bug。 69. 2.37版支持Debug模式,可显示必要的信息。 70. 2.36版修改jsp:include和jsp:forward的路径中含有"../"时的Bug。 71. 2.35版修改taglib和EL表达式方面的Bug。 72. 2.32版将jsp文件中的等注释行全盘输出,因为它们可能在一些场合不表示注释行的意思。 73. 2.31版修改war部署的Bug。 74. 2.30版修改Listener的一个Bug。 75. 2.30版就中文乱码问题对examples Context下的demo示例进行了校对。 76. 2.30版支持有图片验证码、download的jsp文件除了保存为编码方式为ANSI外,还可以保存为UTF-8、 UTF-16LE、UTF-16BE等。 77. 2.30版支持server.xml文件里对标签的URIEncoding属性。 78. 2.20版支持通过JNDI和DataSource来配置数据库连接池的做法(并在examples Context增加示例), 从而实现对Tomcat等Web Server 100%的兼容。 79. 2.20版修改jsp, servlet实例池的UFO Probe监测数据略微异常的问题,使UFO的运行内存更小。 80. 2.20版对UFO进程结束时,进行更详细的写log文件。 81. 2.00版改正不能显示图片验证码的Bug,这个Bug是在1.90版中由于笔误引入的。 82. 2.00版支持动态编译servlet.java。 83. 1.99版修改当1500个点满时,UFO Probe显示紊乱的Bug。 84. 1.98版支持Servlet规范的Filter。 85. 1.98版支持Servlet规范的各种Listener。 86. 1.98版支持双向SSL认证。 87. 1.98版修改UFO probe的一个显示上的Bug。 88. 1.91版修改1.90版中引入的轻微内存泄漏和keepAliveConns的UFO Probe监测指标异常的Bug。 89. 1.90版提供英文版:examples英文版、UFO probe英文版和Howto文档英文版。 90. 1.90版修改一个不稳定因素。由于在1.70版中对"keep-alive"进行了标准的实现,改动比较大, 1.70-1.88版本并不能保证“永远不down”。 91. 1.90版在UFO Probe中增加keepAlive Connection数的指标监测。 92. 1.88版对体积小(<30KB)的静态网页的输出吞吐量接近100% Pure Java所能达到的最大值。 93. 1.87版将Probe采点从3000个下降为1500个,并修改Probe Client的一个数组越界错误。 94. 1.87版在bin目录下增加reload.bat和reload.sh,运行它们,可以不重新启动UFO,而能使 对任何.xml配置(port, ssport参数除外)的修改、增删生效。 95. 1.85版修改不能读一些xml配置文件的Bug。 96. 1.85版对启动时的一些信息的提示更正确。 97. 1.85版在请求文件"Not Found"时,以绝对路径显示,查错更容易,UFO不用担心Hacker。 98. 1.83版完全支持将docBase和appbase设置成绝对路径。当它们以"/"或者"D:"开头,UFO就把它们 判定为绝对路径。关于appBase的意义:如果配置了path=""的Context,appBase的唯一意义是放置 war包的目录。 99. 1.81版修改UFO Probe的若干小问题。 100. 1.80版内置UFO Probe,监测UFO Web Server的重要运行数据,及时报警。 101. 1.71版在bin/UFO.bat, UFO.sh, UFOW.bat三个文件中增加JAVA_OPTS变量,让您方便地修改这个 变量的值,以控制UFO进程的堆内存大小。关于JVM的堆内存的概念请查网上的相关文章。 102. 1.70版的评测指标应有进一步的提高,负载能力和响应速度等应有明显提高。 103. 1.70版对Http头信息里的"Connection: keep-alive"进行了标准的实现,从而支持一些Ajax网页 的运行正确。 104. 1.70版对Cookie进行了改变,不再支持将Cookie的Value等直接设置为中文,而需要先进行转化, 参见本发布的相关例子。 105. 1.70版预防了一种Hacker攻击的可能。 106. 1.70版对出错提示更友好。 107. 1.70版在exmaples Context里增加了Ajax栏目例子。并在这些Ajax例子对UFO唯一根据URL里的"/servlet/" 字符串识别servlet的用法进行了足够的demo。(那种每增加一个servlet都需要配置一番的做法太麻烦了!) 108. 1.59版由UFO Web Server主程亲自校对整理增删修改examples Context,向您demo UFO Web Server精彩强大的功能。 109. 1.56版修改当response的头信息"Content-disposition"为"attachment;filename=xxx"时, response.getWriter()的一个Bug。 110. 1.55版修改与response.getOutputStream()相关的一个较严重的Bug。 111. 1.50版按照Jsp规范和Servlet规范,进行了全面的仔细的校对,修改了若干个不常用的地方, 保持与Tomcat兼容。 112. 1.50版增加bin/startupW.bat,提供另外一种保险的把UFO作为Windows service启动办法。 113. 1.45版支持jsp规范的pageEncoding属性。 114. 1.45版将servlet的destroy()方法调用规范化。 115. 1.45版解决request的setCharacterEncoding(String env)方法不起作用的Bug。 116. 1.30版完全兼容Tomcat在web.xml对servlet进行配置的做法。 117. 1.30版对错误提示更标准。从而解决一些含有错误url连接的网页显示不出来或"Not Found"的问题。 118. 1.20版解决一些浏览器不标准规范含有一些固有的名字为Cookie保留关键字或字符的Cookie时, 语句"Cookie[] cookies=req.getCookies()"不能返回Cookie数组,而是throw了例外的问题。 1.20版UFO修改成:当浏览器含有一些固有的名字为Cookie保留关键字或字符的Cookie时或用户 设置了名字为Cookie保留关键字或字符的Cookie时,语句"Cookie[] cookies=req.getCookies()" 都返回Cookie数组,但不包含那些名字不规范的Cookie,只包含那些名字规范的Cookie,而不 会throw例外。 119. 1.19版更好地支持特大文件的上传(100M以上的)。 120. 1.18版支持文件上传,支持UFOUpload、jspSmartUpload和Apache组织的commons-fileupload包。 也就是很好地支持RFC 1867规范(参见http://www.ietf.org/rfc/rfc1867.txt)。这是一个很 实用的功能。 121. 1.17版修改了如果jsp中用到了第三方类,这个第三方类的类名与JDK中的类名一样,并且UFO在 编译这个jsp时正好用到了这个类名,导致UFO编译jsp失败的问题。 122. 1.16版修改了以前版本UFO用来搭建wap网站时,由于一些地方的无线网关不标准,手机用户需要 访问两次http://wap.xxx.com,才能出内容的问题。也就是说,用1.16版本的UFO搭建wap网站, 即使一些地方的无线网关不标准,手机用户也可顺利访问wap网站。 123. 1.15版修改了1.10版可能不能显示“验证码”图片的Bug; 124. 1.10版修改了以前版本中对新建的Context需要手工创建"_work"子目录的大Bug; 125. 1.10版修改了https状态下的多个Bug; 126. 1.05版修改了由于模糊打包导致1.00版中数据库连接池不能用的Bug; 127. 1.00版提供全新的demo的jsp和servlet示例,尤其对中文乱码问题的解决进行足够的demo; 128. 1.00版允许在一个UFO进程内配置多个DBConnectionPool,根据poolName访问; 129. 1.00版对servlet自动检查servlet.class是否更新,如果有更新,自动对UFO的servlet对象更新, 而不需要重新启动UFO; 130. 0.999x版在测试150个jsp和servlet程序的基础上,修改了几个Bug,并提高各种“评测”指标; 131. 0.9985版在测试350个jsp和servlet程序的基础上,修改了几个Bug。 八、我能否不用理睬web.xml、server.xml、UFO-users.xml(/conf目录下的)?我不想动脑筋去看那些麻烦的 配置参数。 答:如果您的网站没有认证,您完全可以不用理睬UFO-users.xml;相反,如果您的网站有认证,您还不理解 UFO-users.xml里那些配置的含义么。 如果您对mimeType没有特殊的约定,您完全不需要理睬所有的web.xml,甚至可以把所有的web.xml全部 删除掉。在这些情况下(不修改或者删除),UFO采取默认的最新的mimeType,“最新”的含义是完全支 持无线互联网的mimeType标准,搭建手机wap网站没有任何问题。 您也可以不理睬/conf/server.xml文件,甚至在启动UFO之前把它删掉,这两种情况下,您要记住一点: 把html、jsp等文件和子目录都放在/webapps/ROOT/目录下就可以了。 九、本版本的稳定性如何? 答:UFO自0.975版以来,已很稳定地运行于gm365网站上,作为www.gm365.com的Web Server,启动后,内存 两天内稳定在32M,不会出现一个字节的内存泄漏和一个线程的不能回收。 十、本版本的UFO为什么有时比较消耗内存? 答:由于Java编译器的问题,在编译一个jsp文件后,内存不能释放,导致本版本的UFO有的时候看上去比较 消耗内存。但是这个问题并不影响UFO的稳定性。 用户可用这个办法解决这个问题:启动UFO,打开浏览器,将所有的jsp都访问一次(使UFO先编译它们); 然后,Kill掉UFO;然后再启动UFO(以后再访问jsp就不需要编译了),这样UFO的运行内存就很小了。 如果您看到UFO的内存突然增加了几M,那一定是由于编译器编译jsp的原因,把UFO重启一下就是了。 与修改jsp程序的麻烦和工作量相比,将UFO重启一下,不过是举手之劳。由于仅仅是新修改过的jsp需要 编译,由于编译而将UFO重启的情况其实是很少的。 将尽快在UFO中采用更加完美的Java编译器,即使这样(采用最好的Java编译器),您最好在jsp编译后, 把UFO重启一下,因为再好的Java编译器,也会消耗不少的内存,只不过相对来说,小些而已。 十一、本版本的UFO功能如何? 答:UFO支持jsp、servlet、http、https、虚拟主机、认证、数据库连接池、无线互联网mimeType标准、EL 表达式、Tag库等。 是一标准的支持jsp的Web Server。 但有一点:目前不支持用文件生成Tag的做法。 十二、UFO对Tomcat的兼容情况怎样? 答:完全兼容。 需要说明的地方有: A. UFO Web Server不完全支持的做法,含义是,如果您在/conf/web.xml的 中指定了多个welcome-file,永远只支持第一个welcome-file,后面的 welcome-file永远无效。 在写法上,去掉了外面的标签,而只需要标签就可以了,参见 本发布的/conf/web.xml的写法。 当然,如果您还是写原来Tomcat的形式,本版本的UFO也照样读取(如上述,只认第一个welcome-file)。 B. 在servlet问题上,UFO除了支持Tomcat的在web.xml进行配置的做法外,还支持提倡另外一种简单的 做法:就是URL中的最后一个"/servlet/"字符串表示后面跟的是一个servlet。在examples的Ajax篇 中对这一用法进行了足够的demo。 C. 其它一些无关紧要的配置参数,将在后面的问题回答中逐一提及,参见问题三十二。 十三、UFO是否抄袭了Tomcat等开源的Web Server? 答:UFO的源代码与Tomcat等的Web Server的代码是不一样的。但是不少web server方面的知识确实来源于这 些前辈。 十四、UFO的收费情况怎样? 答:本3.08版本UFO是永远免费的,是普通版。 十五、在Linux操作系统下,即使我以root身份登陆,在/bin目录下敲./startup.sh,被告之:权限不够。 怎么办? 答:这其实不是UFO的问题,而是Linux操作系统的问题。解决办法如下: chmod a+x startup.sh chmod a+x UFO.sh chmod a+x setclasspath.sh 添加可执行权限即可。 十六、我配置了多个虚拟主机,如何指定默认的虚拟主机? 答:第一个虚拟主机便是默认的虚拟主机。在/conf/server.wml中请您把要作为默认的虚拟主机放在最前面。 “默认”的意思您明白吧,就是当一个URL找不到所属的虚拟主机的时候,就由默认的虚拟主机来处理。 十七、关于虚拟主机的问题,我只需要UFO来运行一个同学录网站:www.rnx.com,没有虚拟主机,那不需要 配置虚拟主机了吧? 答:这种情况下,您可以不必配置标签,把所有的html、jsp等所有的文件和子目录都要放在webapps /ROOT目录下。 如果您要灵活指定html等文件子目录存放位置,您就要在/conf/server.xml里配置标签,象下面 这样: 十八、关于虚拟主机的另外一个问题:我对虚拟主机很感兴趣,于是我在/conf/server.xml里配置了两个 ,一个Host的name="www.a.com",另外一个Host的name="www.b.com";然后成功启动了UFO; 然后在浏览器里输入http://www.a.com或者http://www.b.com,UFO都没有回应!Why? 答:UFO根本就没有收到您的连接请求。老兄,您是个Internet新手吧。域名需要到域名注册公司(例如万网) 去申请开通,才能指向一个IP;另外您运行UFO的计算机也需要托管,才能拥有一个Internet IP。 如果您要在您的桌面计算机上练习UFO的虚拟主机功能,您可以这么做: 在/conf/server.xml里配置了两个,一个Host的name="localhost",另外一个Host的name="127.0.0.1"; 然后成功启动了UFO;然后在浏览器里输入http://localhost或者http://127.0.0.1就可以了。 十九、只需要配置一下就可以了,虚拟主机使用起来这么简单?在网页制作方面是否需要注意些什么? 答:是有需要注意的地方,就是UFO是根据URL的host参数来区分它属于哪个虚拟主机的。含义是:虽然 localhost和127.0.0.1都指向了同一个地方,但是在网页制作里却不能随便替代。 什么是URL里的host参数?URL里以"http://"开始的位置到后面第一个"/"所夹着的字符串,为host。例如: http://www.gm365.com/index.html, host为www.gm365.com http://www.gm365.com:81/wap/index.wml host为www.gm365.com:81 http://www.gm365.com host为www.gm365.com www.gm365.com/index.html host为www.gm365.com group3.rnx.com host为group3.rnx.com http://localhost host为localhost 127.0.0.1/index.wml host为127.0.0.1 二十、在UFO的/conf/目录下有一个web.xml,然后在各个Context的/WEB-INF/目录下也有一个web.xml,这些 web.xml都可以对mime-mapping配置,这是否有点混乱? 答:不混乱。你应该知道面向对象的“继承”和“重载”的关系吧。在/conf/web.xml里对mime的extension与 mime-type对应关系进行配置,各个Context都拥有这些配置。但是,个别Context要对某一个mime的 extension所对应的mime-type定义新的值,怎么办?可以在那个Context的/WEB-INF/目录下的web.xml对 那个extension与那个mime-type重新对应。 二十一、对welcome-file这个参数,在UFO里可以在/conf/web.xml、/conf/server.xml和各个Context的 /WEB-INF/目录下的web.xml文件里都可以对它进行配置,是这样的吗? 答:是这样的。与mime参数相比,多了一个配置的地方:/conf/server.xml。 各个文件配置的welcome-file的“继承”和“重载”的关系是:/conf/web.xml配置的welcome参数在所有 虚拟主机的各个Context下都得到“继承”;/conf/server.xml里配置的welcome参数对所在虚拟主机的各 个Context的welcome参数进行“重载”;每个Context的/WEB-INF/目录下的web.xml文件对welcome参数的 配置,对自己的welcome参数进行“重载”。 二十二、我是个资深的Java工程师,我知道JVM在垃圾回收的时候产生不少运算,消耗不少CPU,因此,我宁可 采用那些用C写的Web Server,而不会采用使用起来简单的UFO。 答:UFO采用了非常优秀的对象管理机制和算法,UFO的JVM极少进行垃圾回收。用UFO运行网站,绝大多数时间 CPU消耗<0.1%,最多的时候也不会超过5%,几乎永远保持很快的响应速度和高负载能力。 二十三、我的网站如果要从Tomcat迁移到UFO上,配置上需要做哪些改动? 答:您只需要把Tomcat的webapps目录和conf目录Copy覆盖UFO的webapps目录和conf目录,然后启动UFO就可以 了。 虽然UFO的/conf/server.xml文件里不需要三个标签,但是对Tomcat的 server.xml文件格式,UFO也完全支持读取。不过从简洁的立场出发,建议您还是参照UFO(发布)里的 /conf/server.xml的样子把Tomcat的server.xml改过来(主要是去掉 三个标签)。 对一些特殊的网站,从Tomcat迁移到UFO上,您还需要做如下一些事情(一般情况您不需要理这些): 1. 如果您的网站用到了认证,请把tomcat-users.xml重命名为UFO-users.xml。 2. 如果您的jsp文件使用了include文件,请注意UFO对被include的文件的保存的文件编码要求可能与 Tomcat是不一样的,您或许需要对被include的文件重新保存为不同的文件编码。参见问题五十二。 二十四、大师,前面您给我回答的问题我基本明白了,但是有一个地方:不少问题回答都提到了"Context", 什么是Context? 答:简单一点说Context就是让您灵活地设置文档的目录,您知道,在Apache里,文档的目录为htdocs目录, 但是在UFO里,有了Context的概念后,文档的目录就可以任意指定。Context是一个比虚拟主机更重要 的概念。从字面上看,Context是上下文环境的意思,显然,Context是一组含义。其中最重要的一个含 义是Context的识别字符串。在/conf/server.xml里有对一个的配置: 这个path的理解很重要,它将决定一个URL属于那个Context。UFO对所接收到URL并不是单纯地理解成: (路径)+(文件名),而是理解成:(虚拟主机)+(Context)+(路径)+(文件名)。举一个例子, 在浏览里输入: http://www.gm365.com/examples/servlets/index.html UFO如何理解这个URL呢?它首先根据www.gm365.com(也就是host,见前述),确定这是属于哪个虚拟主机 的URL;接着,它把/examples理解成是这个虚拟主机下的一个Context;再接着,它把/servlets/index.html 理解成这个Context下的servlets目录下的index.html文件。/servlets/index.html的父目录是什么呢?就 是在/conf/server.xml里为/examples这个Context配置的docBase,也就是webapps/examples。 Context除了上面所说的识别字符串和docBase两个概念外,还有:可以配置Context的mime的extension与 mime-type的对应关系,以及配置Context的welcome-file。 二十五、接上面问题,我配置了两个Context,它们是: 然后,对URL: http://www.gm365.com/examples/example/test/index.html UFO是如何理解的?最后是输出webapps/examples/test/index.html还是输出了webapps/examples/example/test/index.html? 答:UFO是按照“最长匹配”来寻找Context的,对于上面的URL,UFO寻找Context的步骤如下: 第一步:把host部分去掉,得到一个字符串:/examples/example/test/index.html; 第二步:把文件名部分去掉,得到字符串:/examples/example/test,并寻找是否有path值等于这个字符 串的Context,结果发现没有; 第三步:把上面字符串:/examples/example/test的最后一个目录名去掉,得到字符串:/examples/example, 并寻找是否有path值等于这个字符串的Context,结果找到了! 因此,对您这个URL,UFO的理解是请求"/examples/example"这个Context下的/test/index.html文件。 由于"/examples/example"这个Context的docBase是"webapps/examples",因此最后输出了webapps/examples/test/index.html。 二十六、接上面问题,照您这么说,把那个字符串去完了,还没有找到Context,那就坏了。因此,一个 里一定要配置一个path为空的Context,就象这样: 我的理解是否正确? 答:您的悟性真高。您迟早会成为用UFO做网站的高手的。不过,UFO从0.999版开始,如果发现您没有配置这 样的一个Context,会在启动的时候,自动为您加上这样的一个Context。 二十七、接上面问题,我可否将Context的docBase设置为绝对路径?例如,设置成: 答:在UFO里,Context的docBase可以设置为绝对路径也可以为相对路径。 二十八、什么是https? 答:关于https方面的知识您可以到网上去查相关文章。我这里要告诉您的是,关于https方面的知识您可能不 需要知道得太多,只要知道它是用来防止Web Server与浏览器之间的字节流在Internet上传输过程中,被 截获后,被他人破译信息的。也就是,加密传输。 二十九、我如何建立一个https的网站?我是一个银行系统,网站是用来让用户注册帐户和密码的,我不希望 用户的密码在Internet传输过程中被Hacker截获得到。 答:在/conf/server.xml文件里,配置一个标签: 注意:一定要指明scheme为https,UFO唯一根据scheme为https还是http来决定启动一个https的ServerSocket 还是启动一个普通的。另外,您最好指定keystoreFile的存放位置。 三十、我如何制作keystoreFile文件? 答:请按照https_Howto.txt所说的来做。https_Howto.txt与本Howto.txt存放在同一目录下。 三十一、UFO能否配置任意多个标签,让UFO在多个port上listening? 答:UFO至多只支持两个标签:一个是scheme为http的,另外一个是scheme为https的。两个或以 上的scheme相同的没有任何实质的意义。 如果/conf/server.xml文件里出现了两个或以上的scheme相同的,只取最后一个。 如果您一定要弄两个或以上的scheme相同的,也就是两个或以上的port来listening相同 scheme的连接,请启动多个UFO进程。 三十二、UFO的标签是这样的: 请解释其各个属性的意义。 答:connectionTimeout: 单位ms, 是指UFO接收了连接请求到接收到数据这段时间的Socket的soTimeout值, 从UFO接收到连接请求算起,如果过了connectionTimeout ms还没有接收到数据, 就把这个连接kill掉。 soTimeout: 单位ms, 当一个连接接受到数据后,UFO就把这个连接的Socket的soTimeout设置为这个, 以后只要这个连接的Socket不活动的时间>=soTimout ms时,就把这个连接kill掉。 maxURISize: 单位byte, URI的最大长度,当URI的长度>=maxURISize时,就kill掉这个连接。它的主要 作用是用来防止Hacker的,如果Hacker(或你自己不小心)向UFO发去了一个超长的URL, 岂不是使UFO的内存消耗很厉害,甚至使UFO down掉? maxHttpHeaderSize: 单位byte, 连接到UFO的一个连接的所有http头的长度的总和的最大值。当总和>= maxHttpHeaderSize时,就把这个连接kill掉。它的主要作用也是用来防止Hacker的。 maxHttpTailSize: 单位byte, 连接到UFO的一个连接在http头以后的Byte数的最大值。如果http头以后的 Byte数>=maxHttpTailSize, 就把这个连接kill掉。它的主要作用也是用来防止Hacker的。 当一个Http连接是Post方法时,除了http头外,后面还可能跟有Form数据。 特别注意的是:如果您的网站要有Upload(例如,上传照片),请把maxHttpTailSize 设置得更大,它应该是您要Upload的文件体积+10K左右。 maxKeepAliveConnections: 单位个,本Connector所能保存keep-alive的连接的最大数。保存keep-alive连 接是要消耗内存的,如果无限制地保存,那岂不是要用光内存? 要注意的是:Tomcat里的maxKeepAliveRequests对应UFO里的keepAliveMax,它与 maxKeepAliveConnections是不一样的,maxKeepAliveConnections是一个重要参数。 keepAliveTimeout: 单位s! (注意:不是ms), 它是keep-alive连接的Socket的soTimout, 就是说,当一个 连接被确认为是keep-alive的连接后,它的Socket的soTimeout就改为keepAliveTimeout 了!(而不再是前面的"soTimeout")。 要注意的是:keepAliveTimeout不是keep-alive连接的生命时间! keepAliveMax: 单位次,一个keep-alive连接所能处理的最多请求数,超过了keepAliveMax次,这个连接就 被kill。 clientSetKeepAlive: 是否允许浏览器等Client端来设置keepAliveTimeout和keepAliveMax, 当它为"off"时, 每个keep-alive连接的keepAliveTimeout和keepAliveMax都是Conector标签里配置的; 当它为"on"时,UFO根据连接的http头"keep-alive: timeout=15,max=200"(有其它类似 写法),来设置本keep-alive的连接的keepAliveTimeout和keepAliveMax。 其它属性含义与其它Web Server一样,省去。 三十三、什么是认证? 答:Web Server上的一些网页、jsp程序、servlet程序、文件download等资源需要用户输入密码才能访问, 这就是认证。 三十四、UFO支持哪些认证? 答:UFO支持BASIC、DIGEST和FORM等三种方式。 BASIC认证:浏览器弹出默认的登陆框,让用户输入用户名和密码,如果有一个不对,默认的登陆框继续 弹出,直到输入正确为止。在传输用户名和密码上,只用简单的加密,Hacker截获字节流后,将轻易破译。 FORM认证:登陆框可以自己设置成自己的风格,用户名或密码输错后,出现自己定制的页面。在传输用户 名和密码上,用POST方法的参数编码方式,Hacker截获字节流后,也将轻易破译。 DIGEST认证:在界面表现上与BASIC认证无异。在传输用户名和密码上,采用复杂Hash加密,Hacker截获 字节流后,将很难破译。 三十五、这样说来,https和认证是两个不同外延的概念,也就是说,https网站也同样可以做认证,是这样 的吗? 答:是。 三十六、关于FORM认证,看了examples/jsp/security/protected/login.jsp,也就是自己制作的登陆框。 我的问题是:我是否可以把里面的"j_username"、"j_password"、"j_security_check"、"POST" 等4个关键字符串改成别的? 答:不可以。这个四个字符串不能修改的,是FORM认证登陆的四个“关键词”。简单地说,您如果要制作其 它风格的登陆框,可以修改上面login.jsp的界面部分,却不可以修改其中的“程序”部分。 三十七、在Tomcat中,在https状态下,还提供了一种"Client-Auth"认证,在UFO里,是否支持这个认证? 答:3.08版UFO中双向SSL认证已经得到支持。 关于如何做双向SSL认证请参见本发布的docs目录下的相关文档。也可到网上查相关文章。 三十八、关于认证的配置,只能在每个Context的/WEB-INF/web.xml文件里做,而不能在conf/web.xml做; 而关于mimeType-mapping却可以在两个文件里都配置;而关于welcome-file的配置,除了这两个文 件,还可以在conf/server.xml里的标签里做。为什么会出现这种不对称? 答:这是由需求决定的。您自己可以思考其中的原因。 三十九、有关认证的,什么是role?有用户名还要role干什么? 答:role就是角色的意思。role是与权限密切相关的,UFO里的role的意思与普通系统里的role没有差别。 设置某个权限,要填写一堆用户名,没有什么;如果每次设置其它权限,都要填写一堆用户名,那就很 麻烦了。有了role,就解决了这个问题,将权限授于角色,而把用户名设置成是否拥有某个角色。 一个角色可以拥有多个用户名(相当于一个权利授于多个用户名),而一个用户名可以拥有多个角色 (相当于一个用户名拥有多个权利)。 四十、有关认证的,那什么是Realm和Principal? 答:这个两个概念其实与您关系不大,您只需要大体上了解一下就可以了。这两个概念基本上是写Web Server 的人在自言自语。大体上讲:Realm是认证方法(BASIC、DIGEST、FORM)的别称。而Principal就是分配 了角色后的用户,也就是/conf/UFO-users.xml里的 这行。 四十一、关于认证的,在Context的WEB-INF/web.xml里的等标签是否有数量限制,也就是能否配置多个相同 的标签? 答:是这样的,标签只能设置一个,含义是一个Context下的认证方法只能用一个,要么是 BASIC、要么是DIGEST、要么是FORM。 标签可以设置多个,同一个标签里可以设置多个 标签,含义是,您可以对多个资源进行约束,并把不同 的资源分配给不同的角色。 总之,这个问题,您认为怎样才是合理的,UFO就会是那样的。 四十二、关于认证的,标签体是能用*号进行通配,含义是,如果我要对一个目录下的所有资源 都要求认证,总不至于一个个填写吧? 答:支持*号通配! 四十三、UFO是否支持数据库连接池? 答:支持。 预先创建好数据库连接,可以提高jsp程序的响应速度;可以避免随意创建数据库连接而“打爆”数据库 (数据库能带的连接数是有限的)。 四十四、如何在UFO中使用数据库连接池? 答:第一步,在/conf/server.xml里配置一个标签: 第二步,把相应的jdbc driver的.zip包或.jar包放到/lib目录下。 (重启UFO,当然) 第三步,编写jsp程序,参见examples/jsp/DB/DBJsp.jsp程序: <%@ page contentType="text/html; charset=gb2312" %> <%@ page import="java.sql.*"%> <%@ page import="javax.db.DBConnectionPool"%> <%@ page import="core.UFO"%> 以下是从MySQL数据库读取的数据:
<% DBConnectionPool dbConnPool=UFO.getDBConnectionPool("gm365DB"); java.sql.Connection conn=null; java.sql.Statement stmt=null; java.sql.ResultSet rs=null; try{ conn=dbConnPool.getConnection(); stmt=conn.createStatement(); rs=stmt.executeQuery("select * from book"); while (rs.next()){ out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); } } catch (Throwable e){ } if (rs!=null){ try{ rs.close(); } catch (Throwable e){ } } if (stmt!=null){ try{ stmt.close(); } catch (Throwable e){ } } dbConnPool.returnToPool(conn); %>
ID书名出版社价格
"+rs.getString("bookId")+""+rs.getString("bookName")+""+rs.getString("publisher")+""+rs.getFloat("price")+"
四十五、标签内的属性都不难理解,但是有一个属性:timeout="2000",我有点含糊, 能否解释一下? 答:当到数据库连接池取连接时,如果没有空闲的连接,并且连接池打开的连接数已经达到了最大数,这时 如果立即返回null,就有问题了,因为再过几ms就可能有一个连接返回池中;如果无限时间地等待下去, 也有问题,因为有可能永远也没有连接返回池中,导致调用线程“吊死”。timeout属性就是用来解决这 个问题的,等待timeout ms,若还没有连接可取,则throw Exception。 程序本身是最精确的文档,请参见DBConnectionPool.java 四十六、大家都知道,UFO在找类的时候,会到Context的/WEB-INF/classes/目录下去找,那么我把 JDBC Driver的.zip包放到某个Context的/WEB-INF/classes/目录下,是否可以? 答:不可以!由于java.sql.DriverManager特殊的寻找JDBC Driver的做法,您必须把JDBC Driver的.zip包 或.jar放在/lib目录下! 四十七、请对用到数据库连接池的jsp程序的写法给些指导? 答:如果您在/conf/server.xml配置正确的标签,并且数据库确实已经启动,当UFO启动 时,就已经创建了数据库连接池。以后您只要在jsp程序里取出DBConnectionPool的引用就可以了,为此 您需要: 1. 在jsp程序的一开头写上: <%@ page import="javax.db.DBConnectionPool"%> <%@ page import="core.UFO"%> 2. 在jsp程序里取出UFO的DBConnectionPool的引用: DBConnectionPool dbConnPool=UFO.getDBConnectionPool("gm365DB"); 这里的"gm365DB"是poolName,要在配置文件里配置过的。 3. 从数据库连接池中取连接: java.sql.Connection conn=dbConnPool.getConnection(); 以后的做法,都是正常的数据库的jdbc操作。 四十八、在examples/jsp/DB/DBJsp.jsp程序的后部分,有一个语句: dbConnPool.returnToPool(conn); 请问这语句是否是必须的? 答:必须!从数据库连接池中取出连接后,用完后,一定要调用dbConnPool.returnToPool(conn)或 dbConnPool.wipe(conn)中的一个,即使发现这个连接已死,也要这么做!否则,数据库连接池关于连接 数的数据就不对了,导致您的网站down掉! 请参见DBConnectionPool.java 四十九、数据库连接池可以在哪些文件里配置?如何配置多个数据库连接池? 答:标签可以在两种文件里配置: 1. 在/conf/server.xml文件里配置,可以配置多个标签,请不要将 标签嵌在标签里面(目前不支持这种做法); 2. 可以在各个Context里的web.xml里配置多个标签,但是不能在/conf/web.xml里配 置标签。 特别注意的是:无论在什么地方配置,配置多少个,请保持poolName属性的唯一性。 五十、我配置了标签,并且把JDBC Driver的.zip包放到了/lib目录下,结果启动UFO, 发现UFO消耗的内存多了好几M,启动速度也慢了不少,这令人很不舒服,正常否? 答:是这样的。这是因为UFO启动时装载JDBC Driver类的结果。因此,对于那些不用数据库连接的网站,请您 在/conf/server.xml里把标签注释掉,就没有这个问题了。 五十一、jsp或servlet程序中取Request参数,为什么取出来后中文显示为乱码?我的取法是: String username=request.getParameter("user_name"); 结果username在网页中显示为乱码。 答:如果您设置了request的characterEncoding,request.getParameter()就按您设置过的字符编码返回 String;否则,按照ISO-8859-1字符编码返回String。在ISO-8859-1字符编码里,中文字符显示为乱码。 对此中文乱码问题,有两种解决办法: 1. 先设置request的characterEncoding,再取参数。即: request.setCharacterEncoding("UTF-8"); String username=request.getParameter("user_name"); 2. 不设置request的characterEncoding,自己转换(推荐)。转换办法如下: String oldName=request.getParameter("user_name"); byte[] bs=oldName.getBytes("ISO-8859-1"); String username=new String(bs, "UTF-8"); 特别注意的是,您要确保浏览器端发送这些参数的html网页的编码与Server端取这些参数的编码的一致。 例如,上面的方法中采用"UTF-8"来取参数,那么,对应的发送参数的网页应该是这样的: XXX (当然,所有其它地方也都是UTF-8,即html文件保存的编码方式为UTF-8;html文件里其它如果出现 GB2312等编码都把它们换成UTF-8) 五十二、关于jsp程序中include文件的乱码问题。有两个文件,一个是Include.jsp,另外一个是 jspInsert.jsp,它们在Notepad下保存的文件编码格式都是ANSI。文件的具体内容是这样的, Include.jsp的内容是: <%@ page contentType="text/html; charset=GB2312" %> <%@ page language="java" %> 动态加载文件
动态加载文件



jspInsert.jsp的内容是: 您好!这里我们用到了 <%= request.getParameter("name")%> 指令!
我们在这里加载了文件: <%= request.getParameter("file")%>
我的问题是:它们运行在Tomcat 6.x.x下,Include.jsp输出的中文全部是乱码,而运行在UFO下, Include.jsp输出的中文却是正确的,那么在这个问题上,Tomcat与UFO哪个对了? 答:谈不上谁对谁错,Tomcat与UFO对被Include文件的文件编码识别不一样。 Tomcat把Include文件和被Include文件看成独立的,每个文件都去寻找它的开头是否有"charset="字符 串或pageEncoding属性,以确定那个文件的字符编码,如果发现没有"charset="字符串或pageEncoding 属性,就认为那个文件的字符编码是UTF-8。因此,上面的这个例子Include.jsp输出的中文要正确, jspInsert.jsp就应该保存为UTF-8字符编码。 UFO在处理Include文件和被Include文件的字符编码时,先去寻找Include文件的开头是否有"charset=" 字符串或pageEncoding属性确定Include文件的字符编码,然后要求被Include文件的字符编码与它一样 (而不再去寻找确定被Include文件的字符编码)。 因此,在您的网站从Tomcat迁移到UFO上时,如果存在include文件的jsp程序,请确保被Include文件与 Include的jsp文件的字符编码一致(需要做的事情是对被Include文件重新保存新的字符编码)。 五十三、如何选择UFO的Java编译器? 答:在conf/server.xml里有一行是这样的: 这表示UFO的Java编译器采用eclipse的JDT Java编译器。 如果把那行修改成: UFO就采用了Sun公司的Java编译器。 如果不设置Compiler标签,或者错误地配置Compiler标签的name属性,UFO都采用eclipse的JDT Java编 译器。 五十四、UFO为什么把eclipse的JDT Java编译器作为默认的Java编译器呢? 答:与Sun的Java编译器相比,JDT Java编译器的优点有: 1. 编译的速度明显快; 2. 内存泄漏好象小一点; 3. JDT Java编译器编译时是启动线程,而Sun的Java编译器编译时好象是启动进程,在偶然的情况下, 这个编译进程在编译结束后居然死不掉,变成一个垃圾进程。关于第1、2点,通过重启UFO,采用何 种编译器就没有影响了;而对第3点,一旦发生(概论很小)只有重启操作系统才能消除。 感觉上,JDT Java编译器比Sun的Java编译器要稍微好一点点。 无论采用哪个Java编译器,jsp/servlet编译后,把UFO重启是绝对真理的做法。 五十五、现在有那么多Web Server,我为什么要采用UFO作为Web Server呢? 答:使用UFO做Web Server的好处是只简单地管理一个UFO Web Server(而不需要管理配置其它模块), 网站 能做得很稳定,永远也不会自己down掉;UFO在托管机房Ping的TimeOut比率很高、遭受Hacker攻击、高 负载压力请求、互联网骨干网被黑等恶劣的环境条件下仍然能很好地运行;UFO在对付Hacker方面 (防Hacker弄down和Hacker抓取不该访问的资源)也有足够措施。 将网站做得很稳定是非常重要的: 1. 将网站做得很稳定,就可以天天睡大觉也收钱;相反网站不稳定,公司上下经常受到折腾。 2. 网站容易down,用户、业务就发展不起来;每down一次会有可观的用户倒向竞争对手。 3. 对于一个要down的网站,绝大多数情况是Web Server有垃圾资源的积累,垃圾的积累会使网站的响应 速度变慢。因此,对于一个不是很稳定的网站,最大的坏处是它没有down的时候的响应速度的变慢, 研究表明每慢0.5s,就有20%的用户流失。 4. Web Server过多的垃圾积累,会导致整个Server计算机的变慢,导致别的Server程序响应变慢。 5. 网站现在越来越成为公司门面,公司网站不稳定或响应速度慢,公司形象受损。 6. 网站做不稳定,老板就容易失去信心,公司关门;做单子则不能干净利索地交活;技术人员就容易被 炒鱿鱼。 另外,UFO自带很Cool的UFO Probe,对UFO Web Server的运行状况提供实时监测、诊断和报警。 另外,UFO几乎不会进行垃圾回收,消耗CPU很少,在普通的PC Server上用UFO运行网站,平时CPU占用率 <0.1%,最多时也不会超过5%。您知道,JVM的垃圾回收会导致不少的运算,消耗不少CPU,从而导致Server 的负载能力和响应速度下降。UFO在对象管理方面采用了很好的机制和算法,做得很出色。用UFO运行网站, 可以一直保证高负载能力,快速的响应速度和低CPU消耗。 另外,UFO有超一流的响应速度,用UFO运行网站网页刷地一下就出来了,在相等的Server硬件条件和出口 带宽的情况下,当任务忙时UFO的响应速度(确切地说是用户的速度体验)好于或不差于用C写的Web Server中的佼佼者和Java写的Web Server中的佼佼者。 另外,UFO在启动不起来的时候,会足够的提示让用户有足够的时间看清楚原因(不会出现窗口一闪而过 的情况)。 另外,UFO的启动速度也很快。 五十六、怎样判断一个网站是否很稳定?将来是否有可能down掉? 答:一个充分条件:如果一个Server程序(例如,Web Server)在启动后,经过一段时间的运行(一般<7天), 内存不能稳定下来,一直在增长,那么这个Server迟早要自己down掉。 相反,如果一个Server程序经过一段时间的运行,内存能稳定下来,CPU峰值和响应速度都很正常,那么 这个Server程序是一个很稳定的Server。 五十七、即使UFO很稳定,如果jsp或servlet程序没有写好,或者系统的构架有问题,网站仍然可能会down掉, 您有何措施能保证UFO的网站做到很稳定? 答:我公司会对UFO的前1000个用户网站提供免费的阅读代码服务,以及免费地解决系统构架、中文字符乱码 等问题,为您精确解释您的网站为什么会down掉。联系mail: gm365_market@yahoo.com.cn 五十八、我又不是VC,您把UFO说得那么好有什么用?能否举一实例,展示一下UFO做网站的效果? 答:www.gm365.com网站的Web Server就是UFO。www.gm365.com网站的“硬”条件是: 1. 与其它六家左右的公司网站,共享100M出口; 2. www.gm365.com只托管了一台普通的PC Server,UFO与gm365的数据库Server、几十个游戏应用Server 同时运行在这台PC Server上,并且,这个UFO还有同时运行wap.gm365.com手机wap网站。 3. 这台PC Server最近5年操作系统没有重启过。 五十九、您为什么不加入GNU组织去参与开发完善Tomcat(而是自己写了一个UFO),那样不是出名了吗?您 为什么要这么做?! 答:1. 实话告诉您,由于习惯上的原因,我公司的程序在规范和可读性等方面,可能永远也达不到GNU组织 的那样的水平(当然,这并不意味着我公司的程序的性能达不到真理); 2. 我公司不会去追求荣誉; 3. UFO主要以收费为主,不会挖走Tomcat的多少市场分额; 4. GNU组织是当之无愧的世界冠军,UFO即使是赢了Tomcat,由于Tomcat开源的原因,也不能说明什么。 就好象下围棋,A让B九子,B胜了,能说明什么? 六十、接上面问题,在UFO中有两个URL: http://www.gm365.com/examples/servlets/servlet/HelloWorld http://www.gm365.com/examples/servlet/servlets/HelloWorld UFO对它们怎样解释?存放路径是否一样? 答:第一个URL,UFO对它的解释:请求examples这个Context的类路径下的servlets子目录下的HelloWorld这 个servlet程序服务。因此在examples这个Context下的/WEB-INF/classes/servlets/目录下要有 HelloWorld类,这个HelloWorld类没有包名。 第二个URL,UFO对它的解释:请求examples这个Context的类路径下的servlets.HelloWorld这个servlet 程序服务。由于包名在路径解释上相当于子目录,因此在examples这个Context下的WEB-INF/classes /servlets/目录下要有HelloWorld类,这个HelloWorld类有包名servlets。 可见两个URL的servlet的类存放路径是一样的,但是类本身,一个无包名,另外一个则有包名。 六十一、接上面问题,假定www.gm365.com的运行Web Server是UFO,那么我要访问www.gm365.com的examples 这个Context的类路径下(/WEB-INF/classes/)下的servlet子目录下的HelloWorld这个servlet服务, URL怎么写? 答:http://www.gm365.com/examples/servlet/servlet/HellWorld 六十二、接上面问题,我要访问www.gm365.com的examples这个Context的类路径下(/WEB-INF/classes/)下 的servlet子目录下的HelloWorld这个servlet服务,但是这个HelloWorld类有包名servlet,这个URL 怎么写? 答:由于UFO总是把URL路径中最后一个/servlet/作为servlet的识别字符串,因此包名为servlet的HelloWorld 类是没有办法访问的。请修改HelloWorld的包名,例如,改成servlets,当然,把它的存放目录也改成 servlets,这样,URL就可以写成: http://www.gm365.com/examples/servlet/servlets/HellWorld 六十三、我在使用UFO的过程中遇到问题或者发现Bug,找谁? 答:将来,您可将问题发帖到UFO Web Server的技术论坛:ufo.gm365.com(待开通),我们的技术人员会在 24小时内给予回答。您也可以直接将问题发到信箱:gm365_market@yahoo.com.cn 六十四、能否给出一个UFO相对于其它Web Server的性能指标的评测报告啊? 答:作为开发者,我们不便做出这样的评测报告,无论是数据好坏,由开发者给出评测报告总会带来道德甚 至法律上的问题。 您可以自己下载JMeter等测试工具自己来评测。 目前我公司已经把3.08版UFO和其它著名Web Server初步做了比较仔细的评测,3.08版UFO在maxTime, 90%Line, Error%等三个反应速度体验的指标上,算最好的,也就是说,用UFO做网站,用户速度体验很 好!这就是gm365网站在“硬条件”差的情况下,仍然很快的原因(参见问题五十八)。对于KB/sec, RequestNum/sec两个反映负载能力的指标,也十分优秀,但UFO还可以提高10-15%,这将以后提高。 六十五、现在正在大推3G,UFO能否用来搭建wap网站啊?需要做哪里些配置上事情啊? 答:UFO默认完全支持无线互联网的mime type,因此用UFO搭建wap网站不需求做任何配置上的工作。UFO的发 布里就带有如何用UFO搭建wap网站的例子。 而且,UFO的虚拟主机功能简单易用,可以在一个UFO上既运行www网站又可以同时运行wap网站,UFO的发 布里也带有这样的例子。由于www.xxx.com和wap.xxx.com都只能映射到80端口,如果没有虚拟主机功能, 要同时运行www网站和wap网站就需要托管两台Server,但是有了UFO的虚拟主机功能,就只需要托管一台 PC Server就可以了。(绝大多数网站在UFO看来任务很轻,只需要1/10台PC Server就足够了) 六十六、UFO支持群集吗? 答:gm365网站目前流量不大,并且Server程序都很稳定,所以所有的Server程序如UFO Web Server、数据库、 各种App Server都放到了一台计算机上。 但是,我经常被问及群集的问题。于是,我到网上去查文章、找高手讨论,结果发现您的问题问的不准确, 您应该问:我的网站的访问量很大,要托管好几台Server,如果我用UFO Web Server,怎么用法? 不知道您注意到Google网站没有。Google网站的访问量很大,托管一台Server肯定是吃不消的,他们肯定 托管了很多Server。当我们(中国)在浏览器输入www.google.com访问google主页时,浏览器出现了 Google的主页,但是浏览器上的网址却变成了www.google.cn! 这就是当网站访问量大要托管很多Server时的正确的解决方案:Response.sendRedirect(String location)! 让我再给您讲具体点:现在假定www.gm365.com的访问变得很大了,一台Server吃不消了,要托管多台 Server,我们怎么解决这个问题呢? 1. 在上海的Ping的TimeOut比率很低的机房托管一台硬件性能不错的Server,www.gm365.com指向这台 Server。 2. 考虑到跨网段访问对用户响应速度的影响,我们在北京、深圳、美国、德国各托管一台Server。 3. 在所有的这些Server上都运行UFO Web Server,并放上相同的网站页面和jsp/servlet程序。但是, 有一点不一样:上海的Server的welcome file是index.jsp。 4. 全世界的用户在浏览器输入www.gm365.com的时候,都访问到上海的Server。 5. 上海Server上的index.jsp,做出判断,如果是北京用户,就调用Response.sendRedirect("121.14. 0.8/index.html") ,这样,gm365的北京的Server就以后为这个北京用户服务了。同样的办法,把来 自深圳、美国、德国的用户让离他们最近的gm365的当地的Server为他们服务。 六十七、我经常看到一些“群集”方案,例如,(好象)微软提出的弄若干台计算机,这些计算机共享 Session以及Application的数据,当一台计算机出故障时,就由其它的计算机承接继续提供服务。 再例如,我经常看到一个Apache+n个Tomcat的群集的解决方案,静态网页由Apache处理,动态网页 轮流分配给Tomcat,由Tomcat来处理,这些Tomcat之间也共享Session等重要数据。请您解释他们是 怎么回事? 答:对于瘸子来说,拐杖是很重要的。但是对一个正常人而言,他如果平时也随身带着一个拐杖,会是什么样 子呢?一方面他如果不小心摔交了,把脚扭坏了,由于随身带的拐杖,他的确无忧了;但是另一方面,随 身带着一个拐杖,是一个负担。 对于一些不稳定的Web Server而言,采用“群集”方案,的确是应该的。 至于1个Apache+n个Tomcat方案,我想,应该是一个误会,就是Web Server处理静态网页和处理动态网页 的速度是差不多的,即使动态网页的servlet或jsp程序要访问数据库。因此,Apache将连接请求转发给其 它Web Server,等它处理好后,再将字节流送回Apache,Apache再将字节流送出,基本上是在浪费带宽、 计算机和产生延时。 六十八、我采用您在第六十八问题中所采用的方案,但是我要求Web Server之间Session数据共享,怎么办? 答:您需要Session数据共享吗?您是因为看了别的群集方案里的Session数据共享,才受到了影响吧? 再说,那些Web Server访问的数据库只有一个,即使真的有“共享”需求,最坏的情况下,可以利用数据 库来解决。 六十九、我的网站的运算量很大,当用户访问我的网站的时候,要为他做很多计算,最好需要很多台计算机参 与,好象涉及到“群集”。 答:这时候,您应该做一些Application Server,由这些Application Server来计算。Application Server 之间的共享,您应该不难操纵吧。 在您的servlet或jsp程序里创建Socket连接到Application Server,告诉它们要做的事情。 七十、php速度很快,而且很流行,UFO是否也支持php啊? 答:您的说法不正确。“猫走不走直线,完全取决于老鼠”。php速度快不快完全取决于运行它的Web Server。 类似的错误说法还有:看,利用Google的python做的网站速度有多快。 php, asp, jsp, python只是产生动态网页的语法。 实际上,我公司正准备使UFO也支持php,asp,以使那些利用php, asp开发的网站只需要简单Copy一下, 就可以迁移到UFO下,但是最后还是放弃了。UFO支持php, asp不难,但是好象没有什么意义。 首先,我们看不出来php, asp, jsp在绝对大多数地方语法上有什么本质上区别,只是改头换面而言,例 如,php的echo对应jsp的print等等。这就是说,网站如果想从php迁移到jsp上,利用jsp把动态网页部分 重写一遍,是个不费脑筋的事情,只是花点时间干点体力活而已。 其次,我看不出来一些语言有什么前途,例如,一些语言连数据库连接池都没有,这非常致命;再例如, 一些语言虽然提供了不少function,但是与jsp的在网页里编程相比是小巫见大巫了;再例如,一些语言 是弱类型,这很糟糕。一些语言流行只能说明以前还没有出现稳定运行jsp的Web Server。 但是,现在UFO Web Server出现了,情况就不同了。 七十一、UFO的log文件的在什么地方?UFO在哪些时候会写log文件? 答:UFO的log文件名为rlog.txt,在webapps\admin\probe\logs\目录里。 UFO会在如下情况下写rlog文件: 1. 启动时,记下free/total Memeory。 2. UFO在被Kill时,记下free/total Memeory。并记下被Kill的原因(是被UFO自己Kill掉还是被操作系 统Kill掉)。 3. 运行过程中的不正常情况。对于正常情况下的Exception,UFO是不记录的。 重要注意的是,UFO在启动时,都会把原来的rlog.txt删除重新创建新的rlog.txt文件,因此,再次启动 注意Copy保存。 七十二、关于数据库连接池的,UFO同时支持两种数据库连接池 的配置方法,是吗? 答:是。方式配置的数据库连接池在UFO Probe看来与配置的数据库连接池没 有差别。 建议您采用配置方式,UFO支持的配置方式主要是为了对Tomcat的兼容。 有关数据库连接池、DataSource、JNDI部分的所有源代码在javax.db目录下。 七十三、如何在UFO Web Server窗口里显示调试信息?就是我想看看UFO Web Server所接收到的重要信息。 答:在server.xml文件里,有一个Debug标签,它是这样的: 当您需要在UFO Web Server窗口显示信息时,它修改成: (然后重新启动UFO Web Server) 解释如下: 当mode为"0"时,是正常情况,不显示信息。 当mode为"1"时,显示UFO Web Server所接收到的所有连接请求的requestURI, queryString和method。 当mode为"2"时,除了显示mode为"1"时的信息外,还显示这个请求所对应的文件名以及它是否存在。 当mode为"3"时,除了显示mode为"2"时的信息外,还显示连接请求的所有的http头信息的内容。 七十四、有关war部署的问题。我能否把war包放在UFO的任何目录下? 答:war包只能放在server.xml文件里Host标签的appBase所指定的目录下。例如: ..... 那么要求您把所有的war包都放在webapps目录下。 七十五、请解释:appBase具体有哪些意义? 答:appBase的意义有两点: 1. 是放置war包的目录; 2. UFO在启动时,会检查appBase下的每个子目录,如果发现server.xml里没有一个配置的Context的path 是"/"+目录名,那么UFO会自动加上这样一个Context,它的path是"/"+目录名,它的docBase指向这个 子目录。 但是有一个例外!就是UFO始终把ROOT子目录的所对应的Context的path设置成"/"。 七十六、startupW.bat与startup.bat有什么区别?它启动的是UFO service吗?与它对应的reload和shutdown 的bat文件在哪里? 答:(在Windows下)用startup.bat启动的UFO进程,Dos窗口不能关掉,否则,UFO进程也随之被kill掉,这 有点烦。如果要使Dos窗口关掉后,UFO进程仍然在(后台)运行,应该怎么办?这时就应该用startupW.bat 来启动UFO进程。 用startupW.bat启动的UFO进程,在计算机关机重启后,消失了,因此它所启动的不是UFO service. 用startupW.bat启动的UFO进程,要关掉它,(也)运行shutdown.bat; 要对它reload,(也)运行 reload.bat. UFO用户问题解答。 1. 一UFO用户问:我有一个jsp程序,里面有一行代码是这样的: out.print(x>0 ? 9 : "0"); 结果这个jsp程序在Tomcat下运行没有问题,而在UFO下,却出现错误:"java.lang.Int不能转换成java.lang.String"。 这是不是UFO的Bug? 答:经查,Tomcat采用的是JDT编译器,而当UFO采用sun公司的com.sun.tools里的Java编译器时就出现这个问 题,也就是说,是这个Sun的Java编译器的Bug。 可请采用如下的解决办法: out.print(x>0 ? 9 : 0); 或 out.print(x>0 ? 9+"" : "0"); 2. 一UFO用户问:我用浏览器打开UFO Probe,屏幕全屏灰屏,不显示数据,是不是Bug? 我按照UFO Probe文 档正确操作。 答:当浏览器的JVM是MS JVM时,就出现这个问题。 由于UFO Probe用到了支持https的类,这在MS JVM里不支持,UFO Probe没有办法去掉https有关的类 (因UFO可能会在https状态下运行)。 因此,对本问题的结论是,使用UFO Probe要求浏览器采用Sun JVM。(就是在您的计算机里安装一下JDK 就可以了。)