Winstone 小型容器 注* v0.9.10

Winstone 小型容器 注* v0.9.10

这是Winstone Servlet Container的一个贝塔发行版本.主页在地址:‘http://winstone.sourceforge.net’

作者: Rick Knowles (具体细节在下面)

Winstone 是什么?

Winstone 是一个出于提供完全符合J2EE规范的Servlet服务意愿而写出来的小型容器

它并不打算成为一个完全支持J2EE的WEB容器(这一点,我指无关支持的servlet 的Api , 例如JNDI, JavaMail, EJBs等等 ) 这是 Tomcat, Jetty, Resin, JRun, Weblogic 等应该做的

有些时候,你就是需要一个简单的servlet容器,而不是全部所有的垃圾(译者注: 原文junk这翻译成别的?有时候我也觉得太多功能就是废物).这个时候Winstone最适合了.

写Winstone最初的目标:

  • 快速,可靠,单一web应用为一个服务的servlet容器
  • 尽可能的控制核心jar文件的大小 (目前 166KB 译者注:这大概是0.9版本的核心包,找到这个文档时候我在用它的maven插件,打好的jar文件要320KB.)
  • 尽量尽量少的使用配置文件,使用参数来修改默认的配置
  • 最终将使用GCJ编译成3-4M的windows可执行文件,不过还没有实现,因为一些GCJ类加载问题.
  • 可以支持JSP编译,使用Apache的Jasper.(http://jakarta.apache.org)

为什么它被称为 Winstone ?

使用这个版本号(主版本号太政治,不正确 (译者: politically incorrect 这咋翻译0 0 ) )原因如下:

Winstone 是一天晚上我朋友遇到的一个牙买加朋友的名字, 当时他正在东京六本木区泡吧. 他(我朋友)这个时候有点小醉,这时Winstone建议他们去 “这真的很酷酒吧”, 他并没有觉得这哪有错. 直到Winstone带着他走到一个黑暗的楼梯间并脱掉了裤子,而我的朋友则像躲避地狱一样逃跑.(译者: 偷笑,差点菊花残,如果翻译错了.我要向作者的朋友道歉了,哈哈)

这是个该死的好故事,所以我用Winstone作为项目的名字,继续提醒我朋友.Heheheh …. (译者: 老外的幽默感)

License

Web-App DTD文件(src/javax/servlet/resources和src/javax/servlet/jsp/resources文件夹下所有的)所涵盖的每个文件的顶部描述许可证(通常由Sun Microsystems许可).

v0.8.1,所有其他文件是双授权下,无论是小的GNU公共许可证(LGPL).描述的许可证LGPL.txt,共同发展和发布许可(CDDL).中的CDDL许可证。TXT。直到V0.8,使用的许可证是GNU通用公共许可证(GPL)./p>

双重授权的目标是让Winstone尽可能具有吸引力发布更多商业web应用,更多人获利并同时确保获得任何改进.(译者: 开源作品质量与生命力的法律保证吧.) CDDL允许自由的发布任何商业版本,同时也可以发布LGPL与GPL许可的web应用.如果你不清楚该许可证是否适用于一个你希望分发或出售的应用程序,请与作者联系.

联系作者

你可以从sourceforge上Winstone项目开发者列表上找到我的联系方式(winstone-devel@lists.sourceforge.net). 如果你有评述或问题可以发到我的email我会尽力尽快启动常见问题解答.

我开放help页面给任何愿意帮助我解决上述关于Winstone的问题的人.只需要发email到联系列表(winstone-devel@lists.sourceforge.net)

使用Winstone

如果你想要构建这些源码,你需要下载并安装Apache Maven (v1.x). 以下说明假设你已经安装了maven并可以执行maven脚本(得到Maven, 请看: Apache Maven).

要构建Winstone, 先解压:

1
tar zxf winstone-src-0.9.10.tar.gz

构建命令:

1
2
cd winstone
maven clean jar

winstone.jar 文件将生成到target目录下

运行:

1
java -jar target/winstone-0.9.10.jar --webroot=<location of webroot>  [+ 其它参数]

- 或 -

1
java -jar target/winstone-0.9.10.jar --warfile=<location of warfile>  [+ 其它参数]

- 或 -

1
java -jar target/winstone-0.9.10.jar --webappsDir=<location of webapps directory>  [+ 其它参数]

- 或 -

1
java -jar target/winstone-0.9.10.jar --hostsDir=<location of hosts directory>  [+ 其它参数]

命令行参数:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
语法:
java -jar winstone-0.9.10.jar [--option=value] [--option=value] ...
 
必需的选项: 后面任选一个 --webroot OR --warfile OR --webappsDir OR --hostsDir
--webroot                = 设置文档根目录文件夹.
--warfile                = 设置本地war文件路径.
--webappsDir             = 设置多个要部署的webapps目录.
--hostsDir               = 部署基于域名的虚拟主机设置目录
 
其它选项:
--javaHome               = 覆盖JAVA_HOME地址
--toolsJar               = 本地tools.jar文件地址 (默认为 JAVA_HOME/lib/tools.jar)
--config                 = 加载配置文件(如果提供).
--prefix                 = 为所有的URL添加此前缀 (例如 http://host/prefix/etc).
--commonLibFolder        = 添加额外jar文件的目录. 默认为 ./lib
 
--logfile                = winstone 日志消息文件地址
--logThrowingLineNo      = 显示该日志的行数,(慢). 默认为 false
--logThrowingThread      = 显示记录消息的线程号. 默认为 false
--debug                  = 设置Debug消息级别(1-9). 默认为 5 (INFO 级别)
 
--httpPort               = 设置HTTP连接监听的端口号. -1 为禁用, 默认为 8080
--httpListenAddress      = 设置HTTP连接监听的IP地址. 默认为 all interfaces
--httpDoHostnameLookups  = 打开HTTP连接主机名检查. 默认为 false
--httpsPort              = 设置HTTPS连接监听的端口号. -1 为禁用, 默认为 disabled
--httpsListenAddress     = 设置HTTPS连接监听的IP地址. 默认为 all interfaces
--httpsDoHostnameLookups = 打开HTTPS连接主机名检查. 默认为 false
--httpsKeyStore          = 一个本地的SSL KeyStore文件. 默认为 ./winstone.ks
--httpsKeyStorePassword  = SSL KeyStore文件的密码. 默认为 null
--httpsKeyManagerType    = SSL KeyManagerFactory 类型 (例如 SunX509, IbmX509). 默认为 SunX509
--ajp13Port              = ajp13 监听 port. -1 为禁用, 默认为 8009
--ajp13ListenAddress     = ajp13 监听地址. 默认为 all interfaces
--controlPort            = 关闭/控制一个端口. -1 为禁用, 默认为 disabled
 
--handlerCountStartup    = 设置启动时的线程数. 默认为 5
--handlerCountMax        = 设置最大的线程数. 默认为 300
--handlerCountMaxIdle    = 设置最大空闲线程数. 默认为 50
 
--directoryListings      = 启用目录列表 (true/false). 默认为 true
--useJasper              = 启用 jasper JSP 处理器 (true/false). 默认为 false
--useServletReloading    = 启用 servlet 自动重装 (true/false). 默认为 false
--preferredClassLoader   = 覆盖的首选webapp的类加载器.
--useInvoker             = 启用 servlet invoker (true/false). 默认为 true
--invokerPrefix          = 设置调用前缀. 默认为 /servlet/
--simulateModUniqueId    = 模拟 apache mod_unique_id 功能. 默认为 false
--useSavedSessions       = 使 session 持久化 (true/false). 默认为 false
--usage / --help         = 显示此消息
 
集群选项:
--useCluster             = 启用集群支持(true/false). 默认为 false
--clusterClassName       = 设置使用的集群class . 默认 SimpleCluster class
--clusterNodes           = 用逗号分隔的节点地址列表 (IP:ControlPort,IP:ControlPort,...)
 
JNDI 选项:
--useJNDI                      = 启用JNDI支持 (true/false). 默认为 false
--containerJndiClassName       = 设置容器使用JNDI的管理类. 默认为 ContainerJNDIManager
--webappJndiClassName          = Set the web-app JNDI manager class to use. 默认为 WebAppJNDIManager
--jndi.resource.<name>         = 设置的类标记的资源被用于 <name>
--jndi.param.<name>.<att>      = 设置一个 <att> 标记的资源 <name>
 
安全选项:
--realmClassName               = 设置用于用户认证的类 默认为 ArgumentsRealm class
 
--argumentsRealm.passwd.<user> = 设置 <user> 的密码. (为 ArgumentsRealm)
--argumentsRealm.roles.<user>  = 设置 <user> 的权限 (逗号隔开) (为 ArgumentsRealm)
 
--fileRealm.configFile         = 文件包含 users/passwds/roles. 只适用于 FileRealm realm class
 
Access logging:
--accessLoggerClassName        = 设置存取记录器类,以用于用户认证. 默认为 disabled
--simpleAccessLogger.format    = 使用日志格式. 支持 combined/common/resin/custom (SimpleAccessLogger only)
--simpleAccessLogger.file      = 日志文件的位置模式(SimpleAccessLogger only)

配置文件

你并不是真的需要一个配置文件,但有时它的方便,可以在没有命令行历史的环境中每次使用相同的设置.

Winstone 启动时在当前目录锁住一个配置文件

1
winstone.properties

(或者一个指定的位置 使用–config 参数) 在这个文件中加载的属性, 覆盖他们所提供的任何命令行属性, 并自行启动 (译者注: 这里用的是starts itself 我怎么觉得是重加载或者重启更合适).

这就是一个 人们想要缓存定期启动选项的一个方便特色,当使用批处理文件时

部署选择

最简单的方法 使用winstone就是一个单一的web应用.要做到这一点 , 就必需提供一个war文件或者一个web根目录参数.

  • 1
    java -jar winstone.jar <webroot or warfile>

    , (这种方法自动检测类型) 或

  • 1
    java -jar winstone.jar --webroot=<webroot>

    , 或

  • 1
    java -jar winstone.jar --warfile=<warfile>

如果你需要支持多web应用,使用

1
--webappsDir

参数,传递一个目录包含多个war文件/web根目录.

  • 1
    java -jar winstone.jar --webappsDir=<dir containing multiple webroots>

该目录将成为该web应用的前缀名(例如 hello 变成 /hello, 等等). 目录名ROOT 变成没有前缀的web应用.

while other requests would go to the webapp in the ROOT folder
因此,例举来说,如果你有一个目录 /usr/local/webapps 包含子目录ROOT和test如果你执行

1
java -jar winstone.jar --webappsDir=/usr/local/webapps

,你请求前缀

1
/test

将找到这个test文件夹作为web根目录的 ,而其他的请求会去webapp的根文件夹中

从v0.8开始 , 如果你需要 多主机 (有时也被称作虚拟主机)有一个新的选项

1
--hostsDir

. 这种行为有些类似

1
--webappsDir

. 但它定义了一个额外级别的子目录 第一个是主机名,第二个是每个web应用

1
--webappsDir

.

目录名称变成访问名:就是说, 请求 ip:port/aaa 只会访问aaa目录下, 除非它是默认的路径 ip:port/ 这样它会访问ROOT目录,如果没有指定ROOT则会访问当前目录下.以字母顺序排序的第一个文件夹做为默认目录.(译者注: 这段实在看不知道怎么翻译, 大致意思和我描述的应该一致.但直译实在太难受.)

  • 1
    java -jar winstone.jar --hostsDir=<目录包含多个项目目录>

注意

作为最终设计目标,Winstone有一些事情没有做:

  • 目前Winstone提供三种连接器:
    1. 内部HTTP连接器 – 只允许纯 HTTP/1.1 连接
    2. 内部的HTTPS连接器 – 允许HTTP/1.1通过SSL连接
    3. 一个AJP13连接器 – 允许连接到Apache / IIS /iPlanet等

    虽然有一个内部的HTTPS / SSL连接器,我建议使用Apache 2.0的AJP13连接器(下面说明)它有更多的配置方式比Winstone更多连接选项

  • HttpSession的支持仅是基于cookie的(没有重写URL). URL重写引入了很多不必要的复杂的请求处理,并考虑到常见的浏览器基本都支持cookie.
  • 消息都只有英文.有相应的国际化,但没有翻译.

安全警告

如果控制台生效,在这个端口上,是没有密码保护的.任何人都可以通过这个端口停止或重启这个服务.我计划在这点上,加入简单的用户认证功能,但我在等待,直到有人提到这个问题.(译者: 作者估计太忙,懒得弄了吧.哈哈.)

默认情况, 这个控制台的端口是禁用的.如果你不选择打开它,关闭Winstone唯一的方法就是kill(杀死)这个进程(按Ctrl-C或关闭命令)

最近更新

v0.9的新特性:

  • 增加 Servlet v2.5支持(译者:靠,到底支持不支持啊,作者文档更新的不全.)请注意,注释中提到的规范的支持仅仅是为J2EE兼容的容器,并且 Winstone 故意只支持JSR154标准.增加2.5支持纯粹是因为一个api许可的要求,因此,除了一些糖语法(译者: 坦白说.这个词已经看到N年了.但是依然不了解啥是语法糖)和确认web.xml的规范,这不是真正的大问题. 并且新规范要求jdk1.5或更高,winstone继续采用JDK1.2+的jvm.
  • 增加重启Session持久性.Winstone(我觉得).好的是它的启动时间,但重新启动是一个痛苦过程,如果为了得到一个页面,你必须重建一个会话继续你的工作.加入一个–useSavedSessions参数到你的启动命令中,你将启用这个特性.点击这里了解更多.
  • 许多会话和转发相关的修复 – 感谢 Martin Cordova 和 Robert Boyce 提出这些问题.我已经知道这些bug已经存在一段时间了,但是有人给你重现错误案例往往需要解决由来已久的问题,而这些家伙提供了关键线索.
  • 修改了JSP部署要求.如果你使用JSP,请点击 这里.
  • AJP connector 现在可以和IIS一起工作. 非常感谢 Cory Osborn 单枪匹马的发现并修复了这个bug.
  • 类加载的变化.每个web应用更彻底的隔离加载类.

v0.8的新特性:

  • 扩大的JDBC连接池的功能,包括keep-alive 查询和池已经耗尽时block-and-retry行为
  • 添加匹配缓存过滤器(性能改进)
  • 基于域名的虚拟主机.使用
    1
    --hostsDir

    参数, 你你可以定义一个 目录中包含由主机名命名的目录,就象这样

    1
    --webappsDir

    . 点击这里查看更多.

  • 访问日志.默认情况关闭,可以使用
    1
    --accessLoggerClassName=winstone.accesslog.SimpleAccessLogger

    打开. 您可以提供自己实现的日志工具,简单的访问记录器包含Apache的组合/通用格式 日志记录和Resin格式的记录,它应该足以应付大多数情况.点击这里查看更多.

  • 更好的嵌入式支持. 你现在能嵌入一个war文件和properties文件到winstone jar文件中,生成一个功能完整的jar文件.点击这里查看更多.
  • 测试使用WebDAV应用.Winstone现在已经可以测试/调试Jakarta Slide和Davenport WebDAV 应用 ,并可以正常工作(以前的版本有一些不明显的错误造成的WebDAV失败).

v0.7的新特性:

  • 更新构建工具Apache Maven(参考

    http://maven.apache.org).构建指南更新以匹配。

  • 源码被重新格式化 – 更加容易阅读
  • 增加多web应用支持. 依然没有自动部署特性,但很快就会实现它. 使用
    1
    --webappsDir=<webapps directory>

    增加一个文件夹,将其下任何目录自动安装和任何war文件自动部署.(本来我说,这个功能不会被列入开发,但是我发现加上它,也仅仅使jar的大小增加10k而已.)

  • 修正的bug中的异常处理和错误的servlet重定向, 以及在网页XML解析和更多的其他地方,我尽量在这里列出.如果你有其它bug或者不兼容,很有可能在这个版本被修改掉.
  • 通过 JSR-154 SUN Servlet的兼容性测试工具包( TCK )测试。
  • 我也尝试在开启Winstone的Jasper支持时运行JSR-152 JSP TCK 测试, 但它没有通过所有测试,它的失败案例与tomcat的失败案例是相同的(译者:因为Winstone的Jasper支持是需要第三方包的.所以意思是Winstone没问题/嘿嘿). 目前等待回应. 在任何案例下,我怀疑这些实际测试错误,而不是的实现错误.
  • 很好的支持开源JVM.各种版本JVM测试中 Martin Cordova给了非常大的帮助,测试所需的功能,以及提供一些很好的反馈
  • 用户可以指定web应用的类加载器: 面向切面编程的人群对这个比较有兴趣.它允许你编写自己的类加载器(符合URLClassLoader的相同的构造器签名(译者: 原文conforming to the same contructor signature as URLClassLoader 我怎么感觉应该翻译成- 需要继承URLClassLoader )),然后使用
    1
    --preferredClassLoader

    把它用在正常的Web应用程序的类加载器的地方 .

v0.6的新特性:

  • 更新到Servlet 2.4标准,虽然我还没有运行sun的测试套件 – 我还在等待. 我已经尝试2.4版本的web应用.唯一需要注意的是,你将需要Apache Xerces的系统类路径中,使其工作(见下文).
  • 更新到 JSP 2.0 标准. 主要原因是大量大的jar文件,但实际设计为Jasper要简单的多(见下文).
  • 增加命令行工具中的控制端口选项,控制关闭重启.重启是这个版本才有的,关闭并重启发布.
  • 增加 lib文件夹 用来添加额外的jar. 默认的 lib目录为当前文件夹, 任何jar或zip文件,都可以放到Web应用的classpath目录中.
  • 广泛的使用Apache Struts和JSTL frameworks进行测试.这突出了一些国际化相关的错误,否则我不会发现.
  • 许多小功能.如范围下载静态资源,logfile控制输出日志地址,还有很多很多错误修正和性能调优.请看TODO.txt 有完整的列表.
  • 2004/6/28更新 – 增加HTTPS支持

v0.5的新特性:

  • 实现DIGESTCERT 安全认证方法.很大程度上是未经考验的CERT类型( 由于缺乏 A:获取证书 B: 浏览器客户端证书配置的相关知识 ) – 如果有人想帮助测试这部分 , 我会非常感激.
  • 实现简单的集群( 即在多个Winstone实例之间共享session ). 请参考下面的集群配置部分.
  • 实现了可选的JNDI支持.这是一个基于内存的上下文,用于存储和查找
    1
    <env-entry>

    1
    <resource-ref>

    , 但是也包括一个JDBC源对象池…. 这很有趣,你怎么不明白有些事情是多么的重要,直到你没有他们….

  • 控制端口已经被修改,用来支持更多. 请看下面的使用说明.
  • 分配JAR现在是有两种形式:
    1. 完整版(winstone.jar): 包含了完整的winstone功能集, 包含 AJP13 Apache连接器, Authentication/Realm支持和集群支持.
    2. 简单版 (winstone-lite.jar): 只包含winstone的核心功能集,一些通常会用到的servlet特性,尽可能的快速可靠,删除不必要的选项.

v0.4的新特性:

  • 实现了指令
  • 因为性能原因增加request/response对象池.
  • 操作池(handler pools)可以通过启动参数控制
  • 支持Servlet重载 (任意的 – 包括使用
    1
    --useServletReloading=true

    启动)

  • 适当的初始安全认证模块 (请看帮助文档).有两个使其工作的类 :
    1
    AuthenticationRealm

    1
    AuthenticationHandler

    .目前realms基于参数和基于文件 (通过命令行或者xml文件,使用user/password) 对HTTP连接和表单进行认证,其它类型即将可用(DIGEST和CERT 认证表单)

v0.3的新特性:

  • 请求线程现在使用monitors,这使得他们能够超越单一请求/响应周期存在.这里的好处是性能 – 它消除了一个严重的瓶颈.
  • 现在支持War文件使用–warfile参数. 如果你这样指定war文件,将自动提取文件并生成一个临时目录,根据时间来覆盖已有的文件.
  • Servlet 属性, session, 上下文监听器(Servlet v2.3版本) 现在已经完全支持.一旦实现会话转移,将全力支持HttpSessionActivationListener类
  • Servlet Filters (Servlet v2.3版本) 现在已经完全支持.
  • 支持 AJP13 连接器,这将意味着Winstone可以在Apache/IIS/等下面工作使用Tomcat’s mod_jk.试试看吧,下面有一节使用mod_jk连接.

使用 Xerces as an XML 分析器 (必需servlet v2.4标准)

作为在Servlet规范升级的一部分, servlet v2.4 建议使用XML Schema Documents (XSD)验证而不使用Document Type
Definitions (DTD).虽然我仍不知道这样的改变是必要的 – 尤其是考虑到DTD验证似乎是绰绰有余的,在这种情况下 – 我没有实现它. 也许规范委员会的人可能下一次要想一想容器的大小,作为这一变化的大小会提高5倍.

总之,使用 Xerces, 你将需要从这里下载最新的Xerces-J, 并复制 xercesImpl.jar 和 xml-apis.jar到文件夹的某处(命名为”endorsed”).他们在winstone/lib文件夹将无法正常工作.因为他们必须在系统classpath下覆盖JDK内部的XML解析器.

增加

1
-Djava.endorsed.dirs=<endorsed dir name>

一个JVM参数到你的winstone启动命令行,例如:

1
java -Djava.endorsed.dirs=/jdk/endorsed -jar winstone.jar --webroot=...

JSPs (又名 Jasper)

Winstone使用Apache’s Jasper支持JSP编辑.感谢非常聪明的Jasper团队的工程师,使我作了比预想的少得多的工作 – 干的好Jasper团队.

所需的步骤:

  1. 添加 –useJasper 到你的启动命令行,之后.默认JSP支持是关闭的.
  2. 同时支持Jasper v1.x 和 v2.x 版本.为了打开温斯顿JSP编译,你需要将下面的jar文件添加到当前目录下的lib文件夹在文件夹(或者使用 – commonLibFolder指令指定).
    • jasper-compiler.jar, jasper-runtime.jar, ant.jar, jsp-api.jar – Winstone 不附带以上文件. 你可以从这个标准的Tomcat二进制下载位置,只需下载最新的Tomcat,和这三个文件复制到Winstone的lib文件夹,他们在TOMCAT_HOME/common/lib文件夹下.
    • commons-logging-api.jar, commons-el.jar (Jasper 2 only) – 这些是必需的,如果您使用的是Jasper 2.0 . 你可以让他们从tomcat的二进制分发版或从下面的链接下载

    所有这些都可以从Jakarta下载

  3. 你同时需要tools.jar, 这里面的操作有些不同. ant的javac编译任务需要它把java文件生成可以执行的class文件. 你可以到jdk的java_home/lib文件夹下找到它两个新的Winstone启动参数. –javaHome 和 –toolsJar. 你只需要使用 –javaHome 就可以让Jasper正常工作.你的启动脚本看下来像这样:
    1
    2
    3
    java -jar winstone.jar --useJasper \
                     --javaHome=c:\java\jdk1.4.2 \
                     --webroot=...

    额外的, 你可以具体的指明外部toolsJar文件,像这样:

    1
    2
    3
    4
    java -jar winstone.jar --useJasper \
                     --javaHome=c:\java\jdk1.4.2 \
                     --toolsJar=c:\tools.jar \
                     --webroot=...

新版本的Jasper似乎是使用Eclipse JDT 编译的,因此不需要tools.jar.你可以尝试部署自己的jasper相关的jar – 看看你是否能得到一个运行时的配置,不仅仅是JRE的. 应该不是什么难事, 只需要一点点debug调试.

修改直到v0.9.5版本,jsp-api.jar都不是必需添加的,因为winstone包含自己的JSP API副本(译者:反正我尝试了几次都不行,难道是因为用的maven插件版本.生成的是mini版? – - ).然而, JSP v2.1 标准中的反省需要JDK1.5以上版本,所以为了继续支持,Winstone最低需要使用JDK1.5编译.由于很多人都是希望使用Winstone的体积小,时间受PDA设备上老的JVM规范影响,它似乎更合理,只下降了JSP API类和保持向后兼容性.

我不同意专家组的嗜好,为了不必要的功能,使向后兼容性变差(如泛型和XSD支持).但说到低他们作主,所以我只是尽我所能,以尽量减少在实践中的缺点.

整合 Apache

对于初学者:如果你知道 Apache 和 Tomcat ,你会知道这里发生了什么事情.

下载并安装Apache到你的平台(一同安装Winstone),并接着下面三个步骤:

  1. 下载 mod_jk.dll/so 加入 apache modules 目录
  2. 接着修改apache的配置文件(httpd.conf):
    1
    2
    3
    4
    LoadModule jk_module modules/mod_jk.dll
    <Location "/<Winstone Prefix>/*">
    JkMount /* ajp13
    </Location>
  3. 建立一个 workers.properties文件在apache配置文件目录,包含如下内容:
    1
    2
    3
    4
    worker.list=ajp13
    worker.ajp13.port=8009
    worker.ajp13.host=localhost
    worker.ajp13.type=ajp13
  4. 启动Winstone 确保–ajp13Port=8009 在启动参数中.这是默认值,但是需要确认.(译者: 这算是严禁呢.还是没自信呢/哈哈)
  5. 启动Apache尝试连接你的web应用apache端口,使用Winstone URL 前缀. 如果它没有工作,尝试查看apache error.log文件中的错误提示.如果你得到一个hex dumps文件(译者: 恭喜你,得到一个低层错误),请连同winstone的任何堆栈信息发邮件到开发者列表.

请注意,这并不是一个很好的生产配置.这是一个纯粹为了尝试而使用的例子.阅读与tomcat连接使用的mod_jk文档获取更多.另外,Tomcat 团队的 Costin Manolache 建议我指出不支持 “jvmRoute” 特性(在使用单一apache代理Winstone集群时使用sticky session管理行为).未来可能会支持它 – 我们会看它未来走向(译者: 意思如果这玩火了就支持).

使用Authentication Realms

这个过程几乎和tomcat是相同的(我知道是因为我使用tomcat实例web应用开发的). 有两个组成部分 – web.xml 和 选择/配置 一个AuthenticationRealm类.

  • 所有的Web应用中, web.xml 是相同的 – 你可以引入
    1
    <security-constraint>

    1
    <login-config>

    等所需的元素 (从Tomcat的例子的web.xml文件):

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <security-constraint>
    <display-name>Example Security Constraint</display-name>
    <web-resource-collection>
    <web-resource-name>Protected Area</web-resource-name>
    <url-pattern>/jsp/security/protected/*</url-pattern>
    <http-method>DELETE</http-method>
    <http-method>GET</http-method>
    <http-method>POST</http-method>
    <http-method>PUT</http-method>
    </web-resource-collection>
    <auth-constraint>
    <role-name>tomcat</role-name>
    <role-name>role1</role-name>
    </auth-constraint>
    </security-constraint>
     
    <login-config>
    <auth-method>FORM</auth-method>
    <realm-name>Example Form-Based Authentication Area</realm-name>
    <form-login-config>
    <form-login-page>/jsp/security/protected/login.jsp</form-login-page>
    <form-error-page>/jsp/security/protected/error.jsp</form-error-page>
    </form-login-config>
    </login-config>
  • AuthenticationRealm是Winstone的特性. 你有三个选项:
    1. ArgumentsRealm: 你可以简单的在命令行,为每一个用户添加密码和权限. 添加密码
      1
      --argumentsRealm.passwd.<username>=<password>

      ,添加权限

      1
      --argumentsRealm.roles.<username>=<role1>,<role2>
    2. FileRealm: 这与tomcat一样使用
      1
      tomcat-users.xml

      文件. 在命令行加入

      1
      2
      --realmClassName=winstone.realm.FileRealm
                --fileRealm.configFile=<filename>

      ,在默认情况下,它与tomcat的工作方式一致.

    3. 自定义:你只需要继承
      1
      winstone.AuthenticationRealm

      类, 复写适当的方法 (做为Realms的参数或配置),并指定中的类名参数

      1
      --realmClassName

      .

这部分是故意留下的,非常简单比较精炼.自从看到很多不使用它的web应用以来我打算拆散realm 和 authentication 部分,稍后作成一个可选的jar文件.

集群支持

应该指出,在开始时实现Winstone集群支持目前实际上只是会话共享. 如果一个请求来到集群中的一个节点, 并不提供一个共享的sessionId, 这个节点只会询问”这有你的seesion吗?”.如果不知道,它就会转移请求节点,一直到首先给它session的节点.

如果集群中的特定节点掉线,这种情况下,它所持有的所有session.把未激活的session推到其它节点,尽可能的防止失败,这个集群相当的弱.

就是说,这个配置相当简单.你唯一需要的信息是集群中的至少一个其他活动节点的IP地址和控制端口. 一旦你有这些,只需要在命令行添加如下信息:

1
2
3
4
java -jar winstone.jar ...< other options > ... \
                   --controlPort=<myControlPort> \
                   --useCluster \
                   --clusterNodes=<IP1:controlPort1>

如果IP1是集群中其它的一个IP,myControlPort和controlPort1的端口号分别用于控制此实例的其他节点端口,注意,必需要的主动设置controlPort的这个实例上,因为它在默认情况下是禁用的.

同样,你会相互设置其他实例选项( 即适当修改IP和控制端口值 译者:有点啰嗦,但也是必要的.保证程序有效的更优先前提是: 它看起来更安全.).

注意: 在你的集群web应用成功使用session ,有一些额外的要求.

  1. 你需要引入<distributable/> 元素到你的 web.xml 文件. 这些元素告诉Winstone你的web应用是支持集群的程序.如果没有,集群功能将被关闭.
  2. 添加到你的Session中的对象必需实现java.io.Serializable. 这是必需的,因为Winstone序列化这些对象并通过controlPort传送到其它节点,并在目的地重构的序列化session.如果你尝试放一个没有序列化的对象到session中, Winstone将抛出一个exception来提醒你所有的会话对象序列化
    .

控制端口功能/协议

从v0.5版本起,控制端口的行为,稍微改变.由于增加使用控制端口集群功能,一个基本的协议已添加.

这个协议非常简单. 发送的第一个字节来标记这是一个什么类型的请求被发出.除此之外该协议因每个请求类型而异,
下面列出请求类型的标志:

  • 0 (ASCII 48) = 关闭
  • 1 (ASCII 49) = 请求查找一个session
  • 2 (ASCII 50) = 当前连接的集群节点的请求列表
  • 3 (ASCII 51) = 集群节点心跳
  • 4 (ASCII 52) = 请求重载一个web应用上下文

明显的,除非你打算写你自己的集群扩展,你将只对两个选项感兴趣关机和重载.幸运的是,有个包装类可以访问这些功能
,

1
winstone.tools.WinstoneControl

尝试使用下面的命令查看方法:(译者:这算JDK初级教程?)

1
java -cp winstone.jar winstone.tools.WinstoneControl

JNDI支持

我知道,在我介绍说,Winstone只是要支持的servlet API的核心,但因为我发现,大多数人只使用略多于servlet API核心提供的东西.例如,有些人只是使用JNDI发送管理员错误邮件,而另一些人则是用SSL使用一个servlet(因此需要用apache),还有一些人只使用一个JNDI数据源连接池保持一个引用.(译者: 这段看得我蛋都碎了,看来应该去看看servlet核心API 都有啥.)

出于这个原因,Winstone包括了非常基本的可选的JNDI服务.目前,它支持简单的操作(如绑定,查找,重新绑定,等)并且允许你调用环境变量( 来自 web.xml的env-entry元素 和/或 命令行的参数 ).

注意: JNDI支持默认是失效的. 必需使用

1
--useJNDI=true

使其生效

有两种方式可以配置它:

  • <env-entry>元素 – 这是标准的添加方式, 例如sql字符 或 配置 数字/字符串.举例:
    1
    2
    3
    4
    5
    <env-entry>
    <env-entry-name>test/hello</env-entry-name>
    <env-entry-type>java.lang.Integer</env-entry-type>
    <env-entry-value>45</env-entry-value>
    </env-entry>
  • 命令行参数 – 这是需要创建更复杂的对象的方式(例如JDBC DataSources). 这里的语法需要加入一个子句的种类
    1
    --jndi.resource.<resName>=<className>

    为每个各类创建对象,其次是

    1
    --jndi.param.<resName>.<attName>=<attValue>

    为每个属性赋值.举例:

    1
    2
    3
    4
    java -jar winstone.jar ...< other options > ... \
                        --useJNDI=true \
                        --jndi.resource.test=java.lang.Float \
                        --jndi.param.test.value=45.56

额外的, 如果引入一个JDBC DataSource对象必需使用一个正常的JDBC驱动包.现在这非常简单, 但它需要满足我上述的要求. 选项如下 :

  1. url (必需) – JDBC URL (

    )

  2. driverClassName (必需) – JDBC 驱动名 (如
    1
    com.mysql.jdbc.Driver

    )

  3. username – 数据库用户名
  4. password – 数据库认证密码
  5. maxConnections – 在池中允许的最大连接数. 默认 20
  6. maxIdle – 在池中允许的最大闲置连接数. 默认 10
  7. startConnections – 打开池的连接数. 默认 2
  8. keepAliveSQL – 保持(或检查)连接指定的操作sql .默认 empty
  9. checkBeforeGet – 如果为true, 任何从池中返回连接前执行keepAliveSQL.默认为 true 如果 keepAliveSQL有定义的话
  10. keepAlivePeriod – 在所有未使用的连接每隔n分钟执行keepAliveSQL . 默认为 disabled
  11. killInactivePeriod – 每隔n分钟杀死多余的未连接. 默认 disabled
  12. retryCount – 当池被刷爆,阻止和重试n次. 默认重试1次
  13. retryPeriod – 出错时重试的时间(毫秒). 默认1000ms

例如: 建立一个本地JNDI数据源对象 java:/comp/env/jdbc/connPool,使用命令行参数:

1
2
3
4
5
6
7
java -jar winstone.jar ...< other options > ... \
                    --useJNDI=true \
                    --jndi.resource.jdbc/connPool=javax.sql.DataSource \
                    --jndi.param.jdbc/connPool.url=jdbc:mysql://db.widgets.com/db \
                    --jndi.param.jdbc/connPool.driverClassName=com.mysql.jdbc.Driver \
                    --jndi.param.jdbc/connPool.username=foo \
                    --jndi.param.jdbc/connPool.password=bar

HTTPS 支持

有些人提出我需要增加HTTPS支持, 使用JDK1.4的SSL socket类, 所以我决定尝试一下.它比我预期简单的多 – 这些api真的是很好用. 不幸的是,艰苦的工作,似乎是在配置,而不是编程.

我建议使用一个共享的工具KeyStore Explorer,称为 点击这里. 比所有CLI的凌乱东西,它更容易使用.(译者:老外的思路.你永远搞不清楚,其它东西写的也不是很详细,介绍别人软件的时候.到是没少写)

步骤基本如下:

  1. 创建一个空的JKS密钥库
  2. 生成密匙对(Tools -> Generate Key Pair). 并使用”MD5 with RSA”算法. 设置一个密码,并记住它.
  3. 产生一个CSR(右键 ,Generate CSR).
  4. 发送CSR到Certifying Authority (CA) 进行认证. 我使用 FreeSSL.com, 因为只它每年只要US$39(译者:”只要”RMB240大洋,估计是个人版的).
  5. 一旦你获得了批准证书, 它导入到正在使用密钥库(Tools -> import CA reply).你现在应该有一个 密钥对和证书. 保存密钥库,使用你之前设置的密码.
  6. 使用以下命令启动winstone :
    1
    2
    3
    4
    java -jar winstone.jar --webroot=<webroot>
                       --httpsPort=443
                       --httpsKeyStore=<keystore file>
                       --httpsKeyStorePassword=<password>
  7. 修改你的host文件(/etc/hosts or c:/Winnt/system32/drivers/etc/hosts) 证书上的名称指向127.0.0.1,并尝试访问https://(证书上的名称)/

访问日志

从v0.8版本开始,有一个选项可以选择记录日志(译者: 应该是单独记文件,控制台应该一直有日志的). 它默认是disabled,但能使用–accessLoggerClassName定义一个日志实现类来打开它. 这个类必需实现winstone.AccessLogger接口,为第个web应用,定义容器范围.

日志功能需要调用 winstone.accesslog.SimpleAccessLogger, 它支持Apache风格的合并/通用格式日志, 以及Resin格式的(这实际上只是Apache通用格式加上一个用户代理).

  • –simpleAccessLogger.format: 任意 “combined”, “common”, “resin” 或一种模式通配符.例如,组合格式字符串:
    1
    ###ip### - ###user### ###time### "###uriLine###" ###status### ###size### "###referer###" "###userAgent###"

    你可以使用 –accessLoggerFormat 重新安排上文说的样式或通配符,默认为 “combined”

  • –simpleAccessLogger.file一个模式定义文件记录到哪个目录.默认值
    1
    logs/###host###/###webapp###_access.log

    , 拆分到不同的Web应用程序目录和主机的日志文件.通配符

    1
    ###host###

    1
    ###webapp###

    可以到处移动,甚至省略. 省略通配符将意味着访问日志将被合并成共享文件(将使用同一个文件名).

例如: 记录到单独的文件中启用Apache的组合风格命令行如下:

1
2
java -jar winstone.jar --hostsDir=<vhostsDir>
                       --accessLoggerClassName=winstone.accesslog.SimpleAccessLogger

或按日期生和URI生成到hosts/webapps下单一文件,使用命令行:

1
2
3
4
java -jar winstone.jar --hostsDir=<vhostsDir>
                   --accessLoggerClassName=winstone.accesslog.SimpleAccessLogger
                   --simpleAccessLogger.format=###date###\ ###uriLine###
                   --simpleAccessLogger.file=/mylogs/access_log.txt

嵌入式Winstone

Winstone的设计一直允许其易于嵌入在另一个应用程序中. 这非常简单:

01
02
03
04
05
06
07
08
09
10
// at startup
Map args = new HashMap();
args.put("webroot", "<my webroot dir>"); // or any other command line args, eg port
Launcher.initLogger(args);
Launcher winstone = new Launcher(args); // spawns threads, so your application doesn't block
 
... (your application code)
 
// before shutdown
winstone.shutdown();

从v0.8开始,虽然也有可以嵌入在相反的方向: 把war文件嵌入到winstone的JAR文件. 这使得在一个容器加WEB应用程序的JAR文件被下载后在执行时被解压.

使用它,只需要解压 winstone JAR, 将WAR文件放在解压后的文件夹内(具有相同父文件夹名为”winstone”).然后重命名
你的WAR文件”embedded.war”,并重新包装和以前一样的jar文件(请务必保存META-INF目录和清单).

现在如果你键入:

1
"java -jar winstone.jar"

, 你的应用将自动的生成为ROOT web应用 .访问

查看它.

如果你需要添加默认的命令行参数(例如端口或前缀), 你能以完全相同的方式嵌入properties文件, 但该文件必须命名为”embedded.properties”.

重启保存session

从v0.9.5版本起, 如果你使用–useSavedSessions参数启动,容器所有的请求的session都将被存储到磁盘,并在容器启动时加载.其效果是,在你重启动时,session依然有效,而不是被丢掉在(这是默认行为,或者设置为–useSavedSessions=false ).

这是非常有用的调试时间,如果仅仅是为了防止你登录到你的webapp每次重新启动容器. 不过想想有些成本/副作用:

  • 安全:Session被持久化在web应用的temp目录中(参考规范细节) ,默认情况,系统临时目录内.如果你担心有人从共享计算机上能够读取这些文件,可以使用-Djava.io.tmpdir=<path> 设置目录位置.
  • 性能:每次请求访问一个会话, 请求之前完成该session一直保存在磁盘上. 这像是个明显影响性能的存在,但它的请求结束后,将在输出流中释放, 所以你大概不会感觉到任何变慢现象,也许除了负载或使用keep-alive(连接保持)时.
  • 序列化: 你需要任何你放入session中 的对象实现了java.io.Serializable (显而易见的原因). 有关session的内容遵循相同的规则, “可分配的” web应用/集群 特性.因为它共享一大块代码.

如果你有时间请给测试这个功能,如果有问题请让我知道. 它仍然是一个边缘的小绿色项目 , 所以感谢任何反馈或修正.

注: 原本想写成英文原文和翻译在一起的文章来的,但是内容实在太长.这个blog不太适合做.所以改成只有中文了. 文档标题如果是口述,我肯定是说英文的. 这个翻译很搓.不过也很贴切,这个工具打过包后,只有320K.很强大.

PS. 这篇文档是我第一次翻译英文文档,一定很渣. 90%的时间我都在参考翻译软件.大约5%靠猜 5%用的真的平时用的多了会了的英文 , 对于我这个学了12年俄语 每次考试都不及格的选手来说.我很知足.哈哈.



声明:未作说明,则本文为zhu8fei原创。转载务必注明出处。 
注意:转载须保留全文,如需修改请 联系作者。 
本文永久地址:
http://zhu8fei.sinaapp.com/2013/05/02/winstone/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值