Tomcat 8.0 同一个项目部署多个服务
看标题有点奇怪,同一个项目为什么部署多个服务?实际场景是这样的,Java 开发了一个 reset api 接口项目,部署到一个资源相当富裕的服务器上,单单使用一个 tomcat 跑 Java 项目总会遇到瓶颈,打个比方说,县城里只有一条高速,进城的车子来来往往,遇到赶集,车子越来越多,结果只能排成长龙车头车尾缓缓而行。但如果富裕的县城拥有四条高速路,那情况就完全不同了,车辆即便任意选择一条高速路,都比以前来得通畅,另外还有一个好处就是:这四条路中有一条不幸发生事故,其他还照常跑...
实际的 APP 接口项目中,正好遇到了这种拥堵的情形,不打算增加 Tomcat 的内存分配,原因上面的列子可以看得出,单单铺宽路子,提升是不明显的,始终是一个出入口。
所以打算使用两个 Tomcat 部署该项目,一个 Tomcat 使用不用的端口开启两个服务,最终两个 Tomcat 开启了 四个服务,这四个服务都是同一个项目。一般来说,分成四个同样的包扔到 Tomcat 里就完事了。但这次不这么干,四个都是同一个包,Tomcat 引用同一个路径下的包即可,一来可以少装载点重复的 jar 包,二来部署也方便。
下面说说步骤:
1. 计划使用 8081 8082 8083 8084 端口来跑服务。
2. 项目编译的文件路径在 /var/www/java/myproject/ROOT 里
3. 两个Tomcat 分别解压缩在 /var/www/tomcat/service01 /var/www/tomcat/service02
两个 Tomcat 的配置文件分别如下:
service01/conf/server.xml
<Service name="service01"> <Executor name="tomcatThreadPool_01" namePrefix="HTTP-service01-exec-" prestartminSpareThreads="true" maxThreads="200" maxQueueSize="100" minSpareThreads="6" maxIdleTime="20000" /> <!--HTTP/1.1--> <Connector port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol" URIEncoding="UTF-8" connectionTimeout="5000" enableLookups="false" compression="on" compressionMinSize="2048" compressableMimeType="application/json,text/html,text/xml,text/javascript,text/css,text/plain" redirectPort="443" executor="tomcatThreadPool_01"/> <Connector port="8082" protocol="org.apache.coyote.http11.Http11NioProtocol" URIEncoding="UTF-8" connectionTimeout="5000" enableLookups="false" compression="on" compressionMinSize="2048" compressableMimeType="application/json,text/html,text/xml,text/javascript,text/css,text/plain" redirectPort="443" executor="tomcatThreadPool_01"/> <Engine name="service01" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="/var/www/java/myproject" unpackWARs="false" autoDeploy="false"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="service01_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-real-ip" proxiesHeader="x-forwarded-by" protocolHeader="x-forwarded-proto" /> </Host> </Engine> </Service>
service02/conf/server.xml
<Service name="service02"> <Executor name="tomcatThreadPool_02" namePrefix="HTTP-service02-exec-" prestartminSpareThreads="true" maxThreads="200" maxQueueSize="100" minSpareThreads="6" maxIdleTime="20000" /> <!--HTTP/1.1--> <Connector port="8083" protocol="org.apache.coyote.http11.Http11NioProtocol" URIEncoding="UTF-8" connectionTimeout="5000" enableLookups="false" compression="on" compressionMinSize="2048" compressableMimeType="application/json,text/html,text/xml,text/javascript,text/css,text/plain" redirectPort="443" executor="tomcatThreadPool_02"/> <Connector port="8084" protocol="org.apache.coyote.http11.Http11NioProtocol" URIEncoding="UTF-8" connectionTimeout="5000" enableLookups="false" compression="on" compressionMinSize="2048" compressableMimeType="application/json,text/html,text/xml,text/javascript,text/css,text/plain" redirectPort="443" executor="tomcatThreadPool_02"/> <Engine name="service02" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="/var/www/java/myproject" unpackWARs="false" autoDeploy="false"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="service02_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-real-ip" proxiesHeader="x-forwarded-by" protocolHeader="x-forwarded-proto" /> </Host> </Engine> </Service>
Tomcat 配置需要注意的是Connector端口号不重复,redirectPort可以同一个端口;而项目路径appBase 都是同一个路径(appBase="/var/www/java/myproject"),每个 Tomcat 暂时两个 Connector,分别分配了 2G 的内存。
一个项目已通过四个端口跑起来,四个端口分别提供服务。APP 怎么找到这四个端口呢?这里使用 Nginx 均衡代理这四个服务,Nginx 支持足够大并发量的请求是有案例的,这倒不用担心什么。看看 Nginx 主要配置:
upstream service_domain_com { ip_hash; server localhost:8081 max_fails=3 fail_timeout=50s; server localhost:8082 max_fails=3 fail_timeout=50s; server localhost:8083 max_fails=3 fail_timeout=50s; server localhost:8084 max_fails=3 fail_timeout=50s; keepalive 40; } server { listen 80; server_name service.domain.com; index /index; root /var/www/java/myproject/ROOT/; location / { proxy_http_version 1.1; proxy_pass http://service_domain_com ; proxy_redirect off; proxy_set_header Cookie $http_cookie; proxy_set_header Host $host; proxy_set_header Remote_Addr $remote_addr; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 60; proxy_send_timeout 60; proxy_read_timeout 60; proxy_buffer_size 16k; proxy_buffers 4 64k; proxy_busy_buffers_size 128k; proxy_temp_file_write_size 128k; client_max_body_size 80m; client_body_buffer_size 1024k; #client_header_buffer_size 4k; } location ~ ^/static/ { root /var/www/java/myproject/ROOT/; expires 30d; } }
这个配置注意的是 upstream 的负载均衡配置,方式我选了 ip_hash ,这个根据自己的需要来配置。
哇~~~ 竟然还没有评论!