windows下Tomcat安裝配置

朝聞道-夕死可矣發表於2019-03-30

目錄

 

安裝tomcat

配置windows服務

目錄結構組成

修改預設埠

新增使用者

部署Web應用

配置資料來源

tomcat拋java.lang.OutOfMemoryError解決


 

本篇以Tomcat8的版本windows10環境下配置

安裝tomcat

前提安裝jdk

1,下載,連線地址https://tomcat.apache.org/download-80.cgi  這裡我下載的是tomcat8免安裝壓縮包版本

2,解壓到指定目錄,比如我這裡是c:\soft\tomcat8

3,配置環境變數

CATALINA_HOME=c:\soft\tomcat8,然後將%CATALINA_HOME%\bin在加入path環境變數中

可選環境變數:MAVEN_OPTS 值為:-Xms128m -Xmx512m

初始化分配的最小最大記憶體,下面有摘抄網上經常遇到的out of memory錯誤解釋解決方式
 

然後可以在cmd中startup啟動,之後瀏覽器中檢視localhost:8080

配置windows服務

cmd進入tomcat_home的bin目錄,輸入service.bat install,同樣service.bat remove可以移除註冊服務

c:\soft\apache-tomcat-8.5.39\bin>service.bat install
Installing the service 'Tomcat8' ...
Using CATALINA_HOME:    "c:\soft\apache-tomcat-8.5.39"
Using CATALINA_BASE:    "c:\soft\apache-tomcat-8.5.39"
Using JAVA_HOME:        "C:\soft\jdk8"
Using JRE_HOME:         "C:\soft\jdk8\jre"
Using JVM:              "C:\soft\jdk8\jre\bin\server\jvm.dll"
The service 'Tomcat8' has been installed.

        啟動服務 net Start Tomcat8

        關閉服務 net stop  Tomcat8

問題:有些人說怎麼沒有service命令呢,可能是你下載的檔案中本身不包含,需要重新下載

目錄結構組成

  •  bin:目錄存放一些啟動執行Tomcat的可執行程式和相關內容。            
  •  conf:存放關於Tomcat伺服器的全域性配置。      
  •  lib:目錄存放Tomcat執行或者站點執行所需的jar包,所有在此Tomcat上的站點共享這些jar包。      
  •  logs: 存放日誌檔案,用於每次tomcat執行後的日誌
  •  temp:  存放臨時檔案
  • wabapps:目錄是預設的站點根目錄,自動部署web應用,將web應用複製到此目錄,tomcat會將該應用自動部署到容器      
  •  work:簡單來說,就是儲存jsp、servlet翻譯、編譯後的結果

修改預設埠

可以在conf中的server.xml中修改

 可以修改預設的8080埠,但是建議埠在1024以上避免與公共埠衝突

新增使用者

1,啟動tomcat

2,進入控制檯頁面

提示要輸入密碼,下邊配置

控制檯密碼是通過JAAS(Java Authentication Authorization Service Java驗證和授權API)控制

開啟Tomcat配置路徑conf下的tomcat.xml

可以配置一個賬號:

如果角色不清楚,可以在%CATALINA_HOME%\webapps\manager\WEB-INF中的web.xml中檢視,其中%CATALINA_HOME%是你的tomcat根目錄,然後重啟tomcat服務,輸入賬號密碼即可登入:

在這裡可以管理你的應用

部署Web應用

  • 自動部署

只需將一個Web應用複製到Tomcat的webapps下,系統就會吧該應用部署到Tomcat中,很簡單複製貼上即可

  • 控制檯部署

在上一步驟中進行配置

實際上具體執行的就是在tomcatwebapps中建立一個資料夾webdemo,然後將你target中的檔案複製過去,其實跟第一步一致

然後訪問:

其他部署不在說明

配置資料來源

在實際開發中,我們有時候還會使用伺服器提供給我們的資料庫連線池,比如我們希望Tomcat伺服器在啟動的時候可以幫我們建立一個資料庫連線池,那麼我們在應用程式中就不需要手動去建立資料庫連線池,直接使用Tomcat伺服器建立好的資料庫連線池即可

DHCP資料庫連線池,這是apache的一個專案,凡是資料庫連線池都要實現javax.sql.DataSource介面,換句話說,實現了這個藉口的類就是一個資料庫連線池,還有C3P0資料庫連線池,下面配置DHCP區域性資料來源,對應還有全域性的

不管什麼資料來源,都需要提供特定資料庫的JDBC驅動,以MySQL為例進行操作,這裡驅動使用mysql-connector-java-5.1.39-bin.jar,將此檔案複製到tomcat的lib路徑下

區域性資料來源只需要修改使用者自己的Web部署檔案,只與特定的應用相關,不需要修改系統的配置,這樣不會造成混亂,這樣就提供了更好的封裝性

JNDI(Java Naming and Directory Interface),Java命名和目錄介面,它對應於J2SE中的javax.naming包,

這 套API的主要作用在於:它可以把Java物件放在一個容器中(JNDI容器),併為容器中的java物件取一個名稱,以後程式想獲得Java物件,只需 通過名稱檢索即可。其核心API為Context,它代表JNDI容器,其lookup方法為檢索容器中對應名稱的物件
Tomcat伺服器建立的資料來源是以JNDI資源的形式釋出的,所以說在Tomat伺服器中配置一個資料來源實際上就是在配置一個JNDI資源,如下是測試步驟:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd">
<Context>
<!-- 其中name指定資料來源在容器中的JNDI名,可以隨便指定
	driverClassName指定連線資料庫的驅動
	url指定資料庫服務的URL
	username指定連線資料庫的使用者名稱
	password指定連線資料庫的密碼
	maxActive指定資料來源最大活動連線數
	maxIdle指定資料池中最大的空閒連線數
	-->
   <Resource 
       name="jdbc/datasource" 
       auth="Container"
       type="javax.sql.DataSource" 
       username="root" 
       password="123456"
       driverClassName="com.mysql.jdbc.Driver" 
       url="jdbc:mysql://localhost:3306/db1"
       maxActive="8" 
       maxIdle="4"/>
</Context>

Tomcat伺服器建立好資料來源之後是以JNDI的形式繫結到一個JNDI容器中的,我們可以把JNDI想象成一個大大的容器,我們可以往這個容器中存放一些物件,一些資源,JNDI容器中存放的物件和資源都會有一個獨一無二的名稱,應用程式想從JNDI容器中獲取資源時,只需要告訴JNDI容器要獲取的資源的名稱,JNDI根據名稱去找到對應的資源後返回給應用程式
建立測試頁面

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<%@ page import="javax.naming.*,java.sql.*,javax.sql.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>測試Tomcat資料來源</title>
</head>
<body>
<%
//初始化Context,使用InitialContext初始化Context
Context ctx=new InitialContext(); 
/*
通過JNDI查詢資料來源,該JNDI為java:comp/env/jdbc/dstest,分成兩個部分
java:comp/env是Tomcat固定的,Tomcat提供的JNDI繫結都必須加該字首
jdbc/dstest是定義資料來源時的資料來源名
*/
DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/datasource");
//獲取資料庫連線
Connection conn=ds.getConnection();
//獲取Statement
Statement stmt=conn.createStatement();
//執行查詢,返回ResulteSet物件
ResultSet rs=stmt.executeQuery("select * from tbl2");
while(rs.next())
{
	out.println(rs.getString(1) 
		+ "\t" + rs.getString(2) + "<br/>");
}
%>
</body>
</html>

測試結果:

注意:上面測試頁面中有配置匯入包的地方,

這個是肯定不能少的,在普通的JAVA專案,也要匯入這些包類似這種形式:

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

測試完畢!

我們平時做javaEE開發時,伺服器會為我們的應用程式建立很多資源,比如request物件,response物件,伺服器建立的這些資源有兩種方式提供給我們的應用程式使用:一種是JNDI的方式,伺服器把建立好的資源繫結到JNDI容器中去,應用程式想要使用資源時,就直接從JNDI容器中獲取相應的資源即可,;一種是通過方法引數的形式傳遞進來,比如我們在Servlet中寫的doPost和doGet方法中使用到的request物件和response物件就是伺服器以引數的形式傳遞給我們的

以下是測試程式碼:

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import me.gacl.util.JdbcUtils_JNDI;

public class JNDITest extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try{
            //獲取資料庫連線
            conn = JdbcUtils_JNDI.getConnection();
            String sql = "insert into test1(name) values(?)";
            st = conn.prepareStatement(sql);
            st.setString(1, "gacl");
            st.executeUpdate();
            //獲取資料庫自動生成的主鍵
            rs = st.getGeneratedKeys();
            if(rs.next()){
                System.out.println(rs.getInt(1));
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
            //釋放資源
            JdbcUtils_JNDI.release(conn, st, rs);
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

Cannot create PoolableConnectionFactory (Could not create connection to database server.)

我遇到此問題是資料庫Mysql版本不對,下載正確的版本jar即可

mysql版本是8.0.11,mysql-connector-java版本是5.1.31,後來把mysql-connector-java改為最新版mysql-connector-java-5.1.46-bin.jar後,執行成功

tomcat拋java.lang.OutOfMemoryError解決

  • 1、首先是:java.lang.OutOfMemoryError: Java heap space

解釋: Heap size 設定 JVM堆的設定是指java程式執行過程中JVM可以調配使用的記憶體空間的設定.JVM在啟動的時候會自動設定Heap size的值,其初始空間(即-Xms)是實體記憶體的1/64,最大空間(-Xmx)是實體記憶體的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等選項可進行設定。Heap size 的大小是Young Generation 和Tenured Generaion 之和。  
提示:在JVM中如果98%的時間是用於GC且可用的Heap size 不足2%的時候將丟擲此異常資訊。  
提示:Heap Size 最大不要超過可用實體記憶體的80%,一般的要將-Xms和-Xmx選項設定為相同,而-Xmn為1/4的-Xmx值。  
解決方法: 手動設定Heap size 修改TOMCAT_HOME/bin/catalina.bat,在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: Java程式碼 set JAVA_OPTS=%JAVA_OPTS% -server -Xms800m -Xmx800m -XX:MaxNewSize=256m  或修改catalina.sh 在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: JAVA_OPTS="$JAVA_OPTS -server -Xms800m -Xmx800m -XX:MaxNewSize=256m"  

  • 2、其次是:java.lang.OutOfMemoryError: PermGen space

原因: PermGen space的全稱是Permanent Generation space,是指記憶體的永久儲存區域,這塊記憶體主要是被JVM存放Class和Meta資訊的,Class在被Loader時就會被放到PermGen space中,它和存放類例項(Instance)的Heap區域不同,GC(Garbage Collection)不會在主程式執行期對PermGen space進行清理,所以如果你的應用中有很CLASS的話,就很可能出現PermGen space錯誤,這種錯誤常見在web伺服器對JSP進行pre compile的時候。如果你的WEB APP下都用了大量的第三方jar, 其大小超過了jvm預設的大小(4M)那麼就會產生此錯誤資訊了。  
解決方法: 1. 手動設定MaxPermSize大小 修改TOMCAT_HOME/bin/catalina.bat(Linux下為catalina.sh),在Java程式碼 “echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: set JAVA_OPTS=%JAVA_OPTS% -server -XX:PermSize=128M -XX:MaxPermSize=512m 
catalina.sh下為: Java程式碼 JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=128M -XX:MaxPermSize=512m" 
另外看到了另外一個帖子,覺得挺好,摘抄如下:  
分析java.lang.OutOfMemoryError: PermGen space 發現很多人把問題歸因於: spring,hibernate,tomcat,因為他們動態產生類,導致JVM中的permanent heap溢位 。然後解決方法眾說紛紜,有人說升級 tomcat版本到最新甚至乾脆不用tomcat。還有人懷疑spring的問題,在spring論壇上討論很激烈,因為spring在AOP時使用CBLIB會動態產生很多類。 但問題是為什麼這些王牌的開源會出現同一個問題呢,那麼是不是更基礎的原因呢?tomcat在Q&A很隱晦的回答了這一點,我們知道這個問題,但這個問題是由一個更基礎的問題產生。 於是有人對更基礎的JVM做了檢查,發現了問題的關鍵。原來SUN 的JVM把記憶體分了不同的區,其中一個就是permenter區用來存放用得非常多的類和類描述。本來SUN設計的時候認為這個區域在JVM啟動的時候就固定了,但他沒有想到現在動態會用得這麼廣泛。而且這個區域有特殊的垃圾收回機制,現在的問題是動態載入類到這個區域後,gc根本沒辦法回收! 
 對於以上兩個問題,解決方式:  
在catalina.bat的第一行增加:  
Java程式碼 :set JAVA_OPTS=-Xms64m -Xmx256m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m   
在catalina.sh的第一行增加:  
Java程式碼 :JAVA_OPTS=-Xms64m -Xmx256m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m

 

 

相關文章