一般,指定JVM的native library路径,只需要用下面的参数就好了
-Djava.library.path=PATH_TO_NATIVE_LIBRARY
Tomcat指定native library路径时,还是不要使用这边参数的好。
建议直接修改PATH环境变量,将dll或so放到环境变量PATH的路径下就好了。
TOMCAT默认将PATH赋值给-Djava.library.path参数的。
Learn and share.
一般,指定JVM的native library路径,只需要用下面的参数就好了
-Djava.library.path=PATH_TO_NATIVE_LIBRARY
Tomcat指定native library路径时,还是不要使用这边参数的好。
建议直接修改PATH环境变量,将dll或so放到环境变量PATH的路径下就好了。
TOMCAT默认将PATH赋值给-Djava.library.path参数的。
在网站访问量急剧上升时,通常需要使用集群的方法进行横向扩展。
对于没有状态的应用来说,直接用nginx进行处理即可。
但对于有状态的应用来说,比如登录状态等,除了使用nginx进行扩展外,就需要考虑到Session共享的问题了。
大家知道可以用apache+tomcat来实现Session共享,但效率太低了,而且容易出错。
今天说的主要是用nginx+tomcat+redis+tomcat-redis-session-manager的方式实现共享。
原理比较简单:
1、tomcat-redis-session-manage扩展了 org.apache.catalina.valves.ValveBase; org.apache.catalina.session.ManagerBase; org.apache.catalina.session.StandardSession; 并通过Tomcat配置,替代了这几个类。 2、Set属性时,用session id作为key,将Tomcat的整个Session拆分为SessionSerializationMetadata+RedisSession然后序列化为byte[],存放到Redis。 3、Get属性时,用session id作为key,从Redis获取byte[],然后反序列化为SessionSerializationMetadata+RedisSession,供Tomcat使用。
配置也很简单:
1、从github下载源码tomcat-redis-session-manager
2、用gradle进行编译
#master分支下面,要把signing段和uploadArchives段删掉,才能正常编译 #release就不需要了 gradle build
3、将三个Jar包拷贝到Tomcat的lib文件夹下
#%TOMCAT_HOME%/lib tomcat-redis-session-manager-master-2.0.0.jar commons-pool2-2.2.jar jedis-2.5.2.jar
4、修改context.xml配置文件,新增下面内容就搞定咯
<!--%TOMCAT_HOME%/conf/context.xml--> <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" /> <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager" host="localhost" port="6379" database="0" maxInactiveInterval="60"/>
好处是:不需要修改应用
坏处是:要耗费一定的时间来(序列化+保存到Redis)、(反序列化+从Redis读取)。
1. Download one source tag from Apache
For example, I used this tag:
http://svn.apache.org/repos/asf/tomcat/tc6.0.x/tags/TOMCAT_6_0_41
2. Read this:
http://tomcat.apache.org/tomcat-6.0-doc/building.html
3. Prepare JDK and Ant
SET JAVA_HOME=C:\Languages\Java\JDK\jdk_x86_1.6.0_34 SET ANT_HOME=C:\Languages\Java\JavaTools\apache-ant-1.9.0 SET PATH=%ANT_HOME%\bin;%JAVA_HOME%\bin;%PATH% CMD
4. Copy build.properties.default to build.properties
5. Edit build.properties and set base.path
base.path=the path to store thirdpart libs
6. Run “Ant download”
7. Run “Ant”
8. Rename files
move eclipse.classpath .classpath move eclipse.project .project
9. Use eclipse to import this project
10. Set break point and debug
配置好Tomcat的SSL后,强制使用HTTPS方法如下:
1、全局强制HTTPS
修改%tomcat_home%\conf\web.xml,在文件底部,后面加上这样一段:
<login-config> <!-- Authorization setting for SSL --> <auth-method>CLIENT-CERT</auth-method> <realm-name>Client Cert Users-only Area</realm-name> </login-config> <security-constraint> <!-- Authorization setting for SSL --> <web-resource-collection > <web-resource-name >SSL</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>
2、某个webapp强制使用HTTPS
编辑该webapp的web.xml文件,增加以下内容:
<security-constraint> <web-resource-collection> <web-resource-name>securedapp</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>
关闭 SSL,只需要将CONFIDENTIAL改为NONE即可。
1、%Tomcat%/server/server.xml
找到下面一段:
<!-- <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> -->
替换为:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" disableUploadTimeout="true" enableLookups="false" keystoreFile="D:/JavaContainer/apache-tomcat-6.0.35-x86/myKeyStore.jks" keystorePass="sslTestPwd" />
这样,就可以用https://127.0.0.1:8443访问Tomcat了。
2、在需要使用https项目的axis2.xml文件中,增加下面内容
<!--修改--> <transportReceiver name="http" class="org.apache.axis2.transport.http.AxisServletListener"> <parameter name="port">8080</parameter> </transportReceiver> <!--新增--> <transportReceiver name="https" class="org.apache.axis2.transport.http.AxisServletListener"> <parameter name="port">8443</parameter> </transportReceiver>
这样,该WebService就可以使用https进行访问了:)
以Tomcat为例,说明一下容器如何编译JSP
1.1 命令行方式
java -classpath %CLASS_PATH% org.apache.jasper.JspC -uriroot PATH_TO_WEB\website\ -d PATH_TO_WEB\website\WEB-INF\jspclasses -p com.neohope.pages -c hello -javaEncoding UTF-8 -compile PATH_TO_WEB\website\jsp\hello.jsp
上面的命令行是,将website项目中jsp\hello.jsp文件,生成对应的java文件,文件输出路径为WEB-INF\jspclasses,类包名为com.neohope.pages,类名hello,编码为UTF-8
1.2 Java代码方式
package com.neohope.jsp.complier; import org.apache.jasper.JspC; public class MyComplier { public static void main(String args[]) { try { JspC jspc = new JspC(); jspc.setUriroot("PATH_TO_WEB\\JSP\\JSPComplier\\website"); jspc.setJspFiles("PATH_TO_WEB\\JSP\\JSPComplier\\website\\jsp\\hello.jsp"); jspc.setOutputDir("PATH_TO_WEB\\JSP\\JSPComplier\\website\\WEB-INF\\jspclasses"); jspc.setPackage("com.neohope.pages"); jspc.setClassName("hello"); jspc.setJavaEncoding("UTF-8"); jspc.setCompile(true); jspc.execute(); System.out.println("job done!"); } catch (Exception ex) { ex.printStackTrace(); } } }
代码地址:
JSPComplierSample
Tomcat7采用服务模式运行,主要靠两个EXE和一个BAT文件:
Tomcat7w.exe用于配置、监控服务
Tomcat7.exe用于服务的安装、卸载、更新、运行、停止等
service.bat提供了一些预设的脚本方便大家安装卸载服务
1、Tomcat7w.exe //XX//ServiceName
#服务配置界面 Tomcat7w //ES//ServiceName #服务监控 Tomcat7w //MS//ServiceName
2、Tomcat7.exe //XX//ServiceName
#命令行运行服务 Tomcat7 //TS//ServiceName #启动服务 Tomcat7 //RS//ServiceName #关闭服务 Tomcat7 //SS//ServiceName #更新服务参数 Tomcat7 //US//ServiceName #安装服务 Tomcat7 //IS//ServiceName #删除服务 Tomcat7 //DS//ServiceName
其他可用参数有:
ParameterName | Default | Description |
---|---|---|
–Description | Service name description (maximum 1024 characters) | |
–DisplayName | ServiceName | Service display name |
–Install | procrun.exe //RS//ServiceName | Install image |
–Startup | manual | Service startup mode can be either auto or manual |
++DependsOn | List of services that this service depend on. Dependent services are separated using either # or ; characters |
|
++Environment | List of environment variables that will be provided to the service in the form key=value. They are separated using either # or ; characters. If you need to use either the # or ; character within a value then the entire value must be enclosed inside single quotes. |
|
–User | User account used for running executable. It is used only for StartMode java or exe and enables running applications as service under account without LogonAsService privilege. |
|
–Password | Password for user account set by –User parameter | |
–JavaHome | JAVA_HOME | Set a different JAVA_HOME than defined by JAVA_HOME environment variable |
–Jvm | auto | Use either auto (i.e. find the JVM from the Windows registry) or specify the full path to the jvm.dll. You can use the environment variable expansion here. |
++JvmOptions | -Xrs | List of options in the form of -D or -X that will be passed to the JVM. The options are separated using either # or ; characters. (Not used in exe mode.) |
–Classpath | Set the Java classpath. (Not used in exe mode.) | |
–JvmMs | Initial memory pool size in MB. (Not used in exe mode.) | |
–JvmMx | Maximum memory pool size in MB. (Not used in exe mode.) | |
–JvmSs | Thread stack size in KB. (Not used in exe mode.) | |
–StartMode | One of jvm, Java or exe. The modes are:
|
|
–StartImage | Executable that will be run. Only applies to exe mode. | |
–StartPath | Working path for the start image executable. | |
–StartClass | Main | Class that contains the startup method. Applies to the jvm and Java modes. (Not used in exe mode.) |
–StartMethod | main | Method name if differs then main |
++StartParams | List of parameters that will be passed to either StartImage or StartClass. Parameters are separated using either # or ; character. |
|
–StopMode | One of jvm, Java or exe. See –StartMode for further details. |
|
–StopImage | Executable that will be run on Stop service signal. Only applies to exe mode. |
|
–StopPath | Working path for the stop image executable. Does not apply to jvm mode. |
|
–StopClass | Main | Class that will be used on Stop service signal. Applies to the jvm and Java modes. |
–StopMethod | main | Method name if differs then main |
++StopParams | List of parameters that will be passed to either StopImage or StopClass. Parameters are separated using either # or ; character. |
|
–StopTimeout | No Timeout | Defines the timeout in seconds that procrun waits for service to exit gracefully. |
–LogPath | %SystemRoot%\System32\LogFiles\Apache | Defines the path for logging. Creates the directory if necessary. |
–LogPrefix | commons-daemon | Defines the service log filename prefix. The log file is created in the LogPath directory with .YEAR-MONTH-DAY.log suffix |
–LogLevel | Info | Defines the logging level and can be either Error, Info, Warn or Debug. (Case insensitive). |
–StdOutput | Redirected stdout filename. If named auto then file is created inside LogPath with the name service-stdout.YEAR-MONTH-DAY.log. |
|
–StdError | Redirected stderr filename. If named auto then file is created inside LogPath with the name service-stderr.YEAR-MONTH-DAY.log. |
|
–PidFile | Defines the file name for storing the running process id. Actual file is created in the LogPath directory |
3、service.bat安装卸载服务
service.bat install/uninstall/remove ServiceName
4、启动关闭服务
net start ServiceName net stop ServiceName
今天把Mule ESB集成到Tomcat时,出现了下面的错误:
Already in lifecycle phase 'start', cannot fire the same phase twice
解决方法:
把MuleESB官方网站建议的:
<listener-class>org.mule.config.builders.MuleXmlBuilderContextListener</listener-class>
替换为:
<listener-class>org.mule.config.builders.DeployableMuleXmlContextListener</listener-class>
就可以了
%TOMCAT_HOME%/conf/server.xml中添加以下配置即可
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="TOMCAT_HOME\conf\AXDS_2012_Keystore.jks" keystorePass="password" truststoreFile="TOMCAT_HOME\conf\AXDS_2012_Truststore.jks" truststorePass="password" />
Realm其实就是一个存放用户名,密码及角色的一个“数据库”。
Tomcat中的Realm有下面几种,你也可以使用自己的Realm,只要实现org.apache.catalina.Realm就可以了。
1.JDBCRealm
授权信息存在关系数据库中, 通过JDBC驱动访问
数据库中必须至少有两张表,表示用户及角色
用户表必须至少有两个字段,用户名及密码
角色表必须至少有两个字段,用户名及角色
create table users ( user_name varchar(15) not null primary key, user_pass varchar(15) not null ); create table user_roles ( user_name varchar(15) not null, role_name varchar(15) not null, primary key (user_name, role_name) );
<Realm className="org.apache.catalina.realm.JDBCRealm" driverName="org.gjt.mm.mysql.Driver" connectionURL="jdbc:mysql://localhost/authority?user=dbuser&password=dbpass" userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles" roleNameCol="role_name"/>
2.DataSourceRealm
授权信息存在关系数据库中, 通过JNDI JDBC数据源访问
数据库中必须至少有两张表,表示用户及角色
用户表必须至少有两个字段,用户名及密码
角色表必须至少有两个字段,用户名及角色
create table users ( user_name varchar(15) not null primary key, user_pass varchar(15) not null ); create table user_roles ( user_name varchar(15) not null, role_name varchar(15) not null, primary key (user_name, role_name) );
<Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="jdbc/authority" userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles" roleNameCol="role_name"/>
3.JNDIRealm
授权信息存在LDAP目录服务器中,通过JNDI提供者访问
<Realm className="org.apache.catalina.realm.JNDIRealm" connectionName="cn=Manager,dc=mycompany,dc=com" connectionPassword="secret" connectionURL="ldap://localhost:389" userPassword="userPassword" userPattern="uid={0},ou=people,dc=mycompany,dc=com" roleBase="ou=groups,dc=mycompany,dc=com" roleName="cn" roleSearch="(uniqueMember={0})" />
4.UserDatabaseRealm
默认配置,只是用于少量用户
授权信息存在用户数据JNDI资源中,该资源通常是一个XML文档 (conf/tomcat-users.xml)
<tomcat-users> <user name="tomcat" password="tomcat" roles="tomcat" /> <user name="role1" password="tomcat" roles="role1" /> <user name="both" password="tomcat" roles="tomcat,role1" /> </tomcat-users>
5.MemoryRealm
授权信息存在内存中的对象集合中,该对象集合来自XML文档 (conf/tomcat-users.xml).
仅用于测试。
6.JAASRealm
通过JAAS框架访问授权信息,最灵活最开放的一种授权方式。
如果前面几种方式满足不了你的需求,可以先试试这种方式。
<Realm className="org.apache.catalina.realm.JAASRealm" appName="MyFooRealm" userClassNames="org.foobar.realm.FooUser" roleClassNames="org.foobar.realm.FooRole"/>
7.CombinedRealm
采用多种方式授权。
<Realm className="org.apache.catalina.realm.CombinedRealm" > <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> <Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="jdbc/authority" userTable="users" userNameCol="user_name" userCredCol="user_pass" userRoleTable="user_roles" roleNameCol="role_name"/> </Realm>
8.LockOutRealm
多次登录失败后,锁定用户
<Realm className="org.apache.catalina.realm.LockOutRealm" > <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm>
最后,如果你需要加密密码,那么需要只需要在Realm配置中指定所用的摘要算法就可以了
digest="MD5" digest="SHA"