登录后台

页面导航

本文编写于 1244 天前,最后修改于 164 天前,其中某些信息可能已经过时。

Tomcat 部署方案

通常,我们对tomcat部署需求可以分为几种:单实例单应用,单实例多应用,多实例单应用,多实例多应用。

单实例单应用:如果不要求周期性地维护tomcat版本,一般的做法是把项目war包直接放到webapps目录下,这是非常常见的部署方案。

单实例多应用:把多个项目的war包放在同一个tomcat的webapps目录,关闭和启动tomcat会影响所有项目。

多实例单应用:多个tomcat都运行同一个项目,对应地需要修改不同的监听端口,这种方式通常会和apache httpd或者nginx整合使用,做一些负载均衡的处理。

多实例多应用:多个tomcat运行不同的项目,监听不同的端口。关闭和启动单个项目,不会影响到其他项目的运行。

Tomcat 部署方案选择

而作为服务器,一般处理能力和内存都比较强大,为了充分利用服务器资源,应该尽可能多地采用多实例部署。

但如果是个人使用的云服务器,一般CPU核数少,内存低。采用多实例部署,对系统将是不小的开销。所以选择单实例多应用来部署项目,每个项目独立开设一个端口。

设置server.xml

去掉默认的 Service 节点
添加以下节点供参考

  <!-- a.domain.com -->
  <Service name="a.domain.com">
    <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="20000" />
    <Engine name="a.domain.com" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="a.domain.com">
        <Context path="" docBase="/var/www/a.domain.com/" reloadable="false" />
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="a.domain.com_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>

  <!-- b.domain.com -->
  <Service name="b.domain.com">
    <Connector port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol"
               connectionTimeout="20000" />
    <Engine name="b.domain.com" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="b.domain.com">
        <Context path="" docBase="/var/www/b.domain.com/" reloadable="false" />
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="b.domain.com_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>

配置解释

  1. 去掉 Connector 节点的 redirectPort 属性,目前服务器都采用了反向代理的模式,https应该交与反向大力服务器去处理;
  2. 修改 Connector 节点的 protocol 属性为 org.apache.coyote.http11.Http11NioProtocol,Tomcat默认采用的BIO模型,在几百并发下性能会有很严重的下降。Tomcat自带还有NIO的模型,另外也可以调用APR的库来实现操作系统级别控制;
  3. 多个应用下需要修改 Connector 节点的 port ,来监听不同的端口,以此保证每个应用都能在根目录下访问;
  4. 设置 Context 节点的属性 path"",来避免不必要的路径错错误;
  5. 设置 Context 节点的属性 docBase 为项目实际存放位置,在示例中,将项目放置在目录 /var/www 下;
  6. 设置 Context 节点的属性 reloadablefalse,避免不必要的错误发生。

Nginx设置

在nginx设置中,将https服务放置到nginx中,将访问不同项目的域名通过Nginx访问不同端口,这里只举例 a.domain.com 的Nginx配置

server {
  listen       80;
  server_name  a.domain.com;

  location / {
    rewrite ^ https://a.domain.com$request_uri? permanent;
  }
}

server {
  listen 443;
  server_name  a.domain.com;
  ssl on;
  ssl_certificate #SSL证书路径配置;
  ssl_certificate_key #SSL证书路径配置;
  ssl_trusted_certificate #SSL证书路径配置;
  ssl_session_timeout  5m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
  ssl_prefer_server_ciphers   on;
  proxy_set_header X-Forwarded-For $remote_addr;

  gzip on;
  gzip_min_length 1k;
  gzip_buffers 4 16k;
  #gzip_http_version 1.0;
  gzip_comp_level 5;
  gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
  gzip_vary off;
  gzip_disable "MSIE [1-6]\.";

  location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_buffering off;
        proxy_pass http://127.0.0.1:8080;

        access_log      /var/log/nginx/a.domain.com/access.log;
        error_log       /var/log/nginx/a.domain.com/error.log;
  }
}

配置解释

  1. 在第一个 server 模块中,将所有的HTTP请求,跳转到HTTPS访问;
  2. 在第二个 server 模块中,location / 请所有请求代理访问到Tomcat;
  3. 不同应用在Nginx中需要访问不同的端口。