nginx+tomcat+java部署总结

前言

之前使用nginx配置代理,还是nginx + php。记忆中就是配置一下虚拟主机,以及修改一下linux的hosts文件。。。总之,对nginx的使用很少。前几天阿里云服务器到期了,又入手了腾讯云一款服务器。(ps:个人觉得这款服务器性价比很高,对喜欢折腾服务器的同学来说,还不错。有意愿入手的朋友:点这里腾讯云:1核2G 1M带宽 50G系统盘,18个月120元,活动8月20号到期哦QAQ)

入手服务器后,先搭好java的开发环境以及目前流行的redis和消息队列(包括jdk + tomcat + nginx + mysql + redis + rabbimq)。
然后昨天又部署了一下nginx+tomcat+java,主要玩一下nginx的反向代理和负载均衡,出现了很多问题,记录一下。。

这里我使用war部署到tomcat。
了解nginx配置:
Nginx配置文件详解
Nginx location模块整理
Nginx配置文件详解2

服务器环境

操作系统:腾讯云 Ubuntu Server 16.04.1 LTS 64位
数据库:mysql5.7

demo项目:Spring Boot

看我操作

一、软件安装

// 安装过程及查询资料 //

  1. 安装jdk1.8
    https://www.cnblogs.com/eczhou/p/7860592.html

  2. 安装tomcat

  3. 安装mysql
    https://www.linuxidc.com/Linux/2017-05/143864.htm

  4. 安装git

  5. 安装nginx
    使用命令apt-get install nginx直接安装;

  6. 安装redis
    https://blog.csdn.net/hkw207/article/details/72850306

  7. 安装rabbitmq

/// 安装目录记录 //

  1. jdk1.8
    安装目录:/usr/lib/jdk
  2. tomcat

  3. mysql
    root 123456

  4. nginx
    默认配置文件位置:/ect/nginx
  5. redis
    /opt/soft/
二、同一项目启动多个tomcat

ps:java web项目打war包部署到tomcat具体方法可以参考我上一篇博客:spring boot 项目部署到服务器 两种方式

这里,要做nginx负载均衡,因为我只有一台服务器,那我们启动两个tomcat(tomcat1和tomcat2),运行同一个项目,tomcat1配置端口:8080;tomcat2配置端口:8081;

1.我新建了一个基于spring boot的简单demo项目,源码在这:demo1
嫌麻烦的同学可以下载到本地,打成war包。这个demo项目只是简单的输出了一下日志,所有测试代码都在入口文件里面:

package com.example.demo1;

import com.example.demo1.utils.BusiException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@SpringBootApplication
@RestController
public class Demo1Application extends SpringBootServletInitializer {

    private static Logger logger = LoggerFactory.getLogger(Demo1Application.class);

    @RequestMapping("/")
    public String home() {
        Date now = new Date();
        // 访问时,tomcat日志打印,便于观察
        logger.info("url:{},time:{},", "/", now);
        return "hello 朋友";
    }

    @RequestMapping("/user/{id}")
    public String getUser(@PathVariable("id") Integer id) {
        if (id == null) {
            throw new BusiException(500, "参数错误");
        }

        Date now = new Date();
        logger.info("url:{},time:{},id:{}", "/user/{id}", now, id);
        return "user:...........";
    }

    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Demo1Application.class);
    }
}

2.下载一个Apache tomcat8,并复制一份
复制的tomcat需要修改配置文件:server.xml
server.xml文件中有三个端口必须重新设置,不然端口会冲突:

<Server port="8005" shutdown="SHUTDOWN"> :关闭时使用
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> : 一般应用使用
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:为AJP端口,即容器使用,如 APACHE能通过AJP协议访问Tomcat的8009端口

####  上面的3个端口,复制的时候,一定要修改;不然启动时端口会冲突。
####  这里我们把复制的tomcat中这3个端口对应都加上1。
####  8006/8081/8010

这里写图片描述
上面的截图中,你会发现我将demo1.war包放到了两个tomcat的同级目录下面,而不是直接放到tomcat的webapps目录下。如果你跟我一样,将demo1.war放到tomcat外面,那么你需要做一件事情,就是在tomcat中指定启动的时候,tomcat去哪里找war包。你也可以将war包直接放到两个tomcat的webapps下面运行,就不需要管下面的步骤。
具体操作:找到tomcat的server.xml配置文件,往文件中的<host></host>节点添加下面一句:

<!-- 指定tomcat去/opt/priject/下面找demo1.war, 访问路径localhost:端口/demo1 -->
<Context path="/demo1" docBase="/opt/project/demo1.war" reloadable="true"/>

tomcat1,server.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />

  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />


    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">

        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <!-- 指定tomcat去/opt/priject/下面找demo1.war, 访问路径localhost:端口/demo1 -->
        <Context path="/demo1" docBase="/opt/project/demo1.war" reloadable="true"/>
        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>

tomcat2,server.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<Server port="8006" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />

  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">
    <Connector port="8081" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />


    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">

        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Context path="/demo1" docBase="/opt/project/demo1.war" reloadable="true"/> 
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>

启动两个tomcat,然后访问,看是否启动成功:服务器Ip:端口/项目名称
这里写图片描述
这里写图片描述

ok,同一项目部署到多个tomcat这一步成功!!!!!!!!

三、配置Nginx,简单实现负载均衡

1.修改nginx配置

vim /etc/nginx/nginx.conf

# 修改nginx配置文件,加入upstream location

nginx -t  # 检查配置是否正确

nginx -s reload  #重新读取配置,让配置生效,不需要重启nginx

2.ok,现在我们测试是否nginx简单的负载均衡是否成功了。

2.1 先用tail命令,打开两个tomcat的日志:如下

root@VM-0-14-ubuntu:/etc/nginx# cd /opt/project/
root@VM-0-14-ubuntu:/opt/project# ll
total 17628
drwxr-xr-x 4 root root     4096 Aug 14 09:47 ./
drwxr-xr-x 6 root root     4096 Aug 13 12:42 ../
drwxr-xr-x 9 root root     4096 Aug 13 11:09 apache-tomcat-8.5.32/
drwxr-xr-x 9 root root     4096 Aug 13 14:08 apache-tomcat-8.5.32-2/
-rw-r--r-- 1 root root 18008700 Aug 14 09:47 demo1.war
root@VM-0-14-ubuntu:/opt/project# tail -f apache-tomcat-8.5.32*/logs/catalina.out    # 同时查看两个tomcat的日志,这里用了通配符*
==> apache-tomcat-8.5.32-2/logs/catalina.out <==
2018-08-14 10:02:30.434  INFO 23146 --- [nio-8081-exec-3] com.example.demo1.Demo1Application       : url:/,time:Tue Aug 14 10:02:30 CST 2018,

==> apache-tomcat-8.5.32/logs/catalina.out <==
2018-08-14 10:02:29.181  INFO 23115 --- [nio-8080-exec-4] com.example.demo1.Demo1Application       : url:/,time:Tue Aug 14 10:02:29 CST 2018,

2.2 浏览器请求多次(比如连续20次),查看日志变化
注意,这个时候请求就不要端口号了,直接访问ip/项目名称。nginx会负责去判断这一次由哪一个tomcat处理该请求,并转发给2个tomcat中的其中一个处理。
这里写图片描述

请求日志:
这里写图片描述

从日志看出,tomcat1执行一次,马上tomca2执行一次,紧接着下一次收到请求,tomcat1又执行了。这个跟nginx的调度有关系,且可以配置每个服务器的权重!!这个后续再研究!

我的nginx:

# Default server configuration
#
upstream malls_server{
         server localhost:8080;
         server localhost:8081;
    }


server {
    listen 80 default_server;
    listen [::]:80 default_server;

    #root /var/www/html;

    # Add index.php to the list if you are using PHP
    #index index.html index.htm index.nginx-debian.html;

    server_name 132.232.54.105 localhost;

    location = /upgrading.html {
            root /var/www/html/;
    }

#   location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
#       try_files $uri $uri/ =404;
        # return 200 '<font size="20px">系统维护中......</font>';
        # return 503; 
#   }
    location / {

                     if ($request_method = OPTIONS ) {
                        add_header Access-Control-Allow-Origin *;
                        add_header Access-Control-Allow-Headers Origin,X-Requested-With,Content-Type,Accept;
                        return 200;
                     }

                     proxy_pass http://malls_server;
                     proxy_http_version 1.1;
                     proxy_set_header Upgrade $http_upgrade;
                     proxy_set_header Connection 'upgrade';
                     proxy_set_header Host $host;
                     proxy_cache_bypass $http_upgrade;
                     proxy_set_header X-Real-IP $remote_addr;
                     proxy_set_header X-Real-Port $remote_port;
                     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                     #proxy_set_header   Connection "";
                     client_max_body_size 250m;
                }
                error_page   500 502 503 504  /50x.html;

                location = /50x.html {
                        #root   html;
                        root   /var/www/html/upgrading.html;

                 }
}
  • 12
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值