はじめに
Oracle Cloud Infrastructure(以下OCI)では、フルマネージドな自律型データベースサービスのAutonomous DBを提供しています。
パッチ適用、DB監視、バックアップ、チューニング、障害解決など、DB管理の全ライフサクルを自動化するため、保守運用作業を軽減することが可能です。
Autonomous DB は、現時点では以下の2種類のサービスを提供しています
- Autonomous Transaction Processing(ATP) : 汎用的なオンライントランザクション用途
- Autonomous Data Warehouse(ADW) : データウェアハウス用途
今回の記事では、CenetOS7, Apache Tomcat9, Apache HTTP Server から、ATPへ接続する方法を記載します。
環境構築編
ATP作成
OCI上で、Autonomous Transaction Processing(ATP)を適当に作成します。
必要に応じて、Documentを参照します。
https://docs.cloud.oracle.com/iaas/Content/Database/Tasks/adbcreating.htm
以下のパラメータでCreateを実行。Create完了まで数分かかります。
- Display name : atpdisname
- Database name : atpdataname
- Choose a workload type : Transaction Processing
- Chose a deployment type : Serverless
- CPU core count : 1
- Storage(TB) : 1
- Auto scaling : on
- Create administrator credentials password : 適当に (今回の例では、passwordPassword1で作成)
- Choose a license type : License Included
OCI の仮想ネットワークのポート開放
仮想インスタンスを作成する仮想ネットワーク上で、Security List と、Network Security Group のポートを開放します。
- TCP 80 (Apache HTTP Server)
- TCP 8080 (Apache Tomcat)
インスタンスの構成
インスタンス作成, Oracle JDK Install
OCI 上で Cent OS を建てて、Oracle JDK をインストールします。以下の記事を参照
https://qiita.com/sugimount/items/33c65e2f648ea46c7239
Firewalld 停止
OCIの仮想ネットワークの機能で、以下のFirewall の機能があるため、インスタンス上の Firewalld を停止します
- Security List (サブネット単位の設定)
- Network Security Group (NIC単位の設定)
systemctl stop firewalld
systemctl disable firewalld
Apache Tomcat を Install
yum を使えば、Repositoryからtomcatをinstallすることが出来ますが、最新版を使用したいため Apache Tomcat の最新版(9.0.22) から install を行います
まず、ユーザーを追加します
useradd -s /sbin/nologin tomcat
Tomcatの9.0.22 を Install するための tar.gz をダウンロードします。
cd ~
wget http://ftp.kddilabs.jp/infosystems/apache/tomcat/tomcat-9/v9.0.22/bin/apache-tomcat-9.0.22.tar.gz
tar.gz を解凍して、/opt 配下に格納します
tar -xzvf ~/apache-tomcat-9.0.22.tar.gz
mv ~/apache-tomcat-9.0.22 /opt
chown -R tomcat:tomcat /opt/apache-tomcat-9.0.22
systemd で管理するために、ファイルを作成します
cat <<'EOF' > /etc/systemd/system/tomcat.service
[Unit]
Description=Apache Tomcat 9
After=network.target
[Service]
User=tomcat
Group=tomcat
Type=oneshot
PIDFile=/opt/apache-tomcat-9.0.22/tomcat.pid
RemainAfterExit=yes
ExecStart=/opt/apache-tomcat-9.0.22/bin/startup.sh
ExecStop=/opt/apache-tomcat-9.0.22/bin/shutdown.sh
ExecReStart=/opt/apache-tomcat-9.0.22/bin/shutdown.sh;/opt/apache-tomcat-9.0.22/bin/startup.sh
[Install]
WantedBy=multi-user.target
EOF
chmod 755 /etc/systemd/system/tomcat.service
systemctl daemon-reload
tomcat を起動します。
systemctl restart tomcat
systemctl enable tomcat
仮想インスタンスの PublicIPの8080番ポートにアクセスして、Tomcat Logo が表示されることを確認します
Apache HTTP Server を Install
Apache HTTP Server をインストールします
yum install -y httpd
依存関係解決memo
===========================================================================================================================================================
Package Arch Version Repository Size
===========================================================================================================================================================
Installing:
httpd x86_64 2.4.6-89.0.1.el7_6 ol7_latest 1.2 M
Installing for dependencies:
apr x86_64 1.4.8-3.el7_4.1 ol7_latest 103 k
apr-util x86_64 1.5.2-6.0.1.el7 ol7_latest 91 k
httpd-tools x86_64 2.4.6-89.0.1.el7_6 ol7_latest 90 k
mailcap noarch 2.1.41-2.el7 ol7_latest 30 k
Transaction Summary
===========================================================================================================================================================
起動
systemctl restart httpd
systemctl enable httpd
仮想インスタンスに紐づいている Public IPの80番ポートにアクセスすると、以下のページが表示されます
Apache HTTP Server と Tomcat の連携
Apache HTTP Server と Tomcat 間の通信は、AJP(Apache JServ Protocol) という名前のプロトコルが使用されています。
Apache HTTP ServerからTomcat宛に ASP のリクエストを送付すると、リクエスト情報に従って、Tomcat は Servlet を起動します。
Tomcatの設定ファイルを確認します。
less /etc/tomcat/server.xml
以下のように、8080ポートと、8009ポートを受け付ける設定となっています。8080ポートは、TomcatとしてHTTPのアクセスを受け付けるポートとなっており、8009はServletを起動するためのポートとなっています。
Apache HTTP Server から Tomcatを呼びだすためには、8009ポート宛にAJP通信を行えば良いことが分かりました。
.... 省略 ...
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
.... 省略 ...
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
.... 省略 ...
Apache HTTP Server から、Tomcat へ通信するためには、mod_proxy_ajp
やmod_proxy
のモジュールが必要になります。
Apache HTTP Server のモジュール読み込み設定ファイルを確認します
less /etc/httpd/conf.modules.d/00-proxy.conf
下記のように、2種類のモジュールが有効になっていることが分かります。
# This file configures all the proxy modules:
LoadModule proxy_module modules/mod_proxy.so <============== mod_proxyが有効になっている
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so <====== mod_proxy_ajpが有効になっている
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_express_module modules/mod_proxy_express.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
では次に、どんなパスにアクセスされた時に、Tomcat と連携するのか、ProxyPass の設定を行います
以下の書式で設定する必要があります。
ProxyPass httpdでのパス ajp://サーバー名:8009/Tomcat上のパス/
例えば、Apache HTTP Server で受け付けたすべてのリクエストを Tomcat で処理したい場合は、次のようになります(httpd と Tomcat が同一ホストにある場合)
ProxyPass / ajp://localhost:8009/
また sample ディレクトリへのアクセスを Tomcat 上の example と連携したい場合は次のようになります。
ProxyPass /sample/ ajp://localhost:8009/example/
それでは、今回は全てのパスをProxyとして転送するために、以下の設定を入れましょう
echo "ProxyPass / ajp://localhost:8009/" > /etc/httpd/conf.d/proxy.conf
Apache HTTP Server の再起動を行います
systemctl restart httpd
Tomcat のテストページが、Apache の 80 ポートで表示されていればOKです
Oracle JDBC Driver の ダウンロード
Javaアプリケーションから、Oracle DB にアクセスを行うためには、Oracle JDBC Driver を Installする必要があります。
Oracle JDBC Driverには、大きく分けて以下2種類があります。
- Oracle Call Interface(OCI) Driverを使って接続する。Oracle JDBC Driver と Oracle Instant Clientを導入する必要がある
- Thin Driver を使って接続する。Javaのライブラリで接続するため、Oracle JDBC Driver の導入だけでOK
基本的に、Oracle Interface Driver の固有の機能(TAFなど)を使う必要がなければ、Thin Driverを使用します。
Oracle Call Interface Driver と Thin Driver の違いは以下の表に記載があります。
https://docs.oracle.com/cd/F19136_01/jjdbc/introducing-JDBC.html#GUID-696E8F49-4B61-4520-8557-318320CE7A66
また、My Oracle Support の Knowledge ページに、Oracle JDBC Driver の説明や、Install方法、バージョン互換性などが記載されているため、一度読んでおくと勉強になります。(My Oracle Supportのアカウントが必要になります)
https://support.oracle.com/epmos/faces/DocumentDisplay?id=1999901.1
OTN(Oracle Technology Network) から、Oracle JDBC Driver の Jar ファイルを ダウンロードします。以下のページから、ダウンロードしたいバージョンを選択します。基本的には最新で問題ないと思います。
https://www.oracle.com/technetwork/database/application-development/jdbc/downloads/index.html
ojdbc10-full.tar.gz ファイルをダウンロードして、OCI上のCentOSインスタンスに格納します。
tar.gz ファイルを解凍します
cd /home/opc
tar xfvz ojdbc10-full.tar.gz
今回の例では、以下のディレクトリに解凍をしています。
$ ls -la /home/opc/ojdbc10-full
total 8668
drwxr-xr-x. 2 opc opc 211 Apr 29 22:15 .
drwx------. 7 opc opc 183 Jul 20 03:00 ..
-rw-r--r--. 1 opc opc 2625 Apr 29 22:15 README.txt
-r-xr-xr-x. 1 opc opc 11596 Apr 24 21:07 ojdbc.policy
-r--r--r--. 1 opc opc 4243140 Apr 24 21:07 ojdbc10.jar
-r--r--r--. 1 opc opc 144681 Apr 24 21:07 ons.jar
-r--r--r--. 1 opc opc 306004 Apr 24 21:07 oraclepki.jar
-r--r--r--. 1 opc opc 1661488 Apr 24 21:07 orai18n.jar
-r--r--r--. 1 opc opc 205154 Apr 24 21:07 osdt_cert.jar
-r--r--r--. 1 opc opc 306854 Apr 24 21:07 osdt_core.jar
-r-xr-xr-x. 1 opc opc 29205 Apr 24 21:07 simplefan.jar
-r--r--r--. 1 opc opc 1680074 Apr 24 21:07 ucp.jar
-r--r--r--. 1 opc opc 262664 Apr 24 21:07 xdb.jar
(Skip)Oracle Instant ClientのInstall
今回の手順では、Oracle DB に接続するための、Oracle Instant Client はインストールしません。
JDBC Oracle Call Interface Driver 固有の機能を使用したい場合は、Oracle Instant Client を インストールする必要がありますので、ご注意ください。
ATP の Wallet をダウンロード
rootユーザーとなり、ATPから wallet をダウンロードして、以下のディレクトリに解凍します。
sudo su -
mkdir /opt/wallet
cp -p /home/opc/Wallet_atpdataname.zip /opt/wallet/
cd /opt/wallet/
unzip Wallet_atpdataname.zip
rm -f Wallet_atpdataname.zip
以下のディレクトリ構成になっていればOKです
# ls -la /opt/wallet
total 36
drwxr-xr-x. 2 root root 148 Jul 20 16:27 .
drwxr-xr-x. 4 root root 30 Jul 20 16:26 ..
-rw-r--r--. 1 root root 6661 Jul 20 16:27 cwallet.sso
-rw-r--r--. 1 root root 6616 Jul 20 16:27 ewallet.p12
-rw-r--r--. 1 root root 3242 Jul 20 16:27 keystore.jks
-rw-r--r--. 1 root root 87 Jul 20 16:27 ojdbc.properties
-rw-r--r--. 1 root root 114 Jul 20 16:27 sqlnet.ora
-rw-r--r--. 1 root root 1744 Jul 20 16:27 tnsnames.ora
-rw-r--r--. 1 root root 3335 Jul 20 16:27 truststore.jks
ATPにSampleDataを格納
ATPに接続して、以下のSQLを流すことでSampleDataを格納します。
自分の場合は、Vistual Studio Code から接続を行ってSQLを流しています。
以下のURLに導入方法を記載しています。
-- Create a new Relational table with 3 columns
CREATE TABLE SAMPLE_TABLE
(
id VARCHAR2(255) NOT NULL,
name VARCHAR2(1024)
);
-- Insert rows in a Table
INSERT INTO SAMPLE_TABLE
VALUES
(
'001',
'suzuki'
);
-- Insert rows in a Table
INSERT INTO SAMPLE_TABLE
VALUES
(
'002',
'satou'
);
-- Insert rows in a Table
INSERT INTO SAMPLE_TABLE
VALUES
(
'003',
'tanaka'
);
Javaアプリケーション編
純粋なJavaアプリから接続
動作確認のために、Tomcat を使用しない純粋なJavaアプリケーションから動作確認をします。
mkdir /home/opc/java/
cat <<'EOF' > /home/opc/java/SampleRun.java
import java.sql.*;
public class SampleRun {
public static void main(String[] args) {
final String path = "jdbc:oracle:thin:@atpdataname_high";
final String id = "ADMIN"; //ID
final String pw = "passwordPassword1"; //password
try (
Connection conn = DriverManager.getConnection(path, id, pw);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT NAME FROM SAMPLE_TABLE");
) {
while (rs.next()) {
String cn = rs.getString("name");
System.out.println("Name => " + cn);
}
} catch(SQLException ex) {
ex.printStackTrace(); //Error
}
}
}
EOF
コンパイル
javac /home/opc/java/SampleRun.java
実行
Walletの格納先を環境変数に指定
cd /home/opc/java
export TNS_ADMIN=/opt/wallet
java -classpath /home/opc/ojdbc10-full/ojdbc10.jar:\
/home/opc/ojdbc10-full/ucp.jar:\
/home/opc/ojdbc10-full/oraclepki.jar:\
/home/opc/ojdbc10-full/osdt_core.jar:\
/home/opc/ojdbc10-full/osdt_cert.jar:. \
SampleRun
実行例
# java -classpath /home/opc/ojdbc10-full/ojdbc10.jar:\
> /home/opc/ojdbc10-full/ucp.jar:\
> /home/opc/ojdbc10-full/oraclepki.jar:\
> /home/opc/ojdbc10-full/osdt_core.jar:\
> /home/opc/ojdbc10-full/osdt_cert.jar:. \
> SampleRun
Name => satou
Name => tanaka
Name => suzuki
Apache HTTP Server + Apache Tomcatから接続
Tomcat の webapps ディレクトリは、下のディレクトリになっています
/opt/apache-tomcat-9.0.22/webapps
demoアプリ作成のために、ディレクトリを作成します
mkdir /opt/apache-tomcat-9.0.22/webapps/demo
mkdir /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF
mkdir /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/lib
mkdir /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/classes
Tomcat の Servlet から、ATPに接続するための demo アプリを格納します
cat <<'EOF' > /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/classes/DemoServlet.java
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import java.sql.DatabaseMetaData;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class JDBCSample_Servlet
*/
@WebServlet("/demo")
public class DemoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public DemoServlet() {
super();
}
/**
* Method to get a connection to the Oracle Database and perform few
* database operations and display the results on a web page.
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.print("Sample JDBC Servlet\n");
try {
// Get a context for the JNDI look up
DataSource ds = getDataSource();
// With AutoCloseable, the connection is closed automatically.
try (Connection connection = ds.getConnection()) {
out.print("The database user is "
+ executeBusinessLogicOnDatabase(connection, out));
out.print("\n Sample JDBC Servlet Request was successful");
response.setStatus(200);
}
} catch (Exception e) {
response.setStatus(500);
response.setHeader("Exception", e.toString());
out.print("\n Web Request failed");
out.print("\n "+e.toString());
e.printStackTrace();
}
}
/*
* Method to create a datasource after the JNDI lookup
*/
private DataSource getDataSource() throws NamingException {
Context ctx;
ctx = new InitialContext();
Context envContext = (Context) ctx.lookup("java:/comp/env");
// Look up a data source
javax.sql.DataSource ds
= (javax.sql.DataSource) envContext.lookup ("tomcat/UCP_atp");
return ds;
}
/*
* Method to showcase database operations using the database connection
*/
private String executeBusinessLogicOnDatabase(Connection conn,
PrintWriter out) throws SQLException {
// Get the JDBC driver name and version
DatabaseMetaData dbmd = conn.getMetaData();
out.println("Driver Name: " + dbmd.getDriverName());
out.println("Driver Version: " + dbmd.getDriverVersion());
String user = "";
String query = "SELECT NAME FROM SAMPLE_TABLE";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
user = user + " " + rs.getString(1);
}
stmt.close();
rs.close();
return user;
}
public void destroy() { }
}
EOF
web.xml を作成します
cat <<'EOF' > /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Demo Application</display-name>
<description>
This is a demo web application.
</description>
<servlet>
<servlet-name>DemoServlet</servlet-name>
<servlet-class>DemoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DemoServlet</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
</web-app>
EOF
コンパイルします
javac -classpath /opt/apache-tomcat-9.0.22/lib/servlet-api.jar /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/classes/DemoServlet.java
Oracle JDBC Driverを格納します
cp /home/opc/ojdbc10-full/* /opt/apache-tomcat-9.0.22/webapps/demo/WEB-INF/lib
Tomcat から ATP に接続するために、context.xml を新規作成し、Resouce を定義します。
mkdir /opt/apache-tomcat-9.0.22/webapps/demo/META-INF
cat <<'EOF' > /opt/apache-tomcat-9.0.22/webapps/demo/META-INF/context.xml
<Context>
<Resource name="tomcat/UCP_atp" auth="Container"
factory="oracle.ucp.jdbc.PoolDataSourceImpl"
type="oracle.ucp.jdbc.PoolDataSource"
description="UCP Pool in Tomcat"
connectionFactoryClassName="oracle.jdbc.pool.OracleDataSource"
minPoolSize="5"
maxPoolSize="50"
initialPoolSize="15"
user="ADMIN"
password="passwordPassword1"
url="jdbc:oracle:thin:@atpdataname_high?TNS_ADMIN=/opt/wallet"
/>
</Context>
EOF
JAVA_OPTS を編集し、fanEnabledを無効化します
vim /opt/apache-tomcat-9.0.22/bin/catalina.sh
JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS"
JAVA_OPTS="$JAVA_OPTS -Doracle.jdbc.fanEnabled=false"
↑追加
Tomcat 再起動
systemctl restart tomcat
http://ipaddress/demo/demo
にアクセスして、Demoページが表示されていることを確認します。
The database user is ... と記載されている箇所が、ATPか取得してきたUserを表示しています
参考URL
Oracle JDBC Driverについて
https://support.oracle.com/epmos/faces/DocumentDisplay?id=1999901.1
Java開発者ガイド
https://docs.oracle.com/cd/F19136_01/jjdev/index.html
JDCB開発者ガイド
https://docs.oracle.com/cd/F19136_01/jjdbc/index.html
Java Connectivity to ATP
https://www.oracle.com/technetwork/database/application-development/jdbc/documentation/atp-5073445.html
Apache httpd と Tomcat を連携させる方法
https://weblabo.oscasierra.net/tomcat-mod-proxy-ajp/
GitHubでJavaアプリケーション
https://github.com/syobochim/code19-coding-hol/tree/master/spring-boot
上記GitHubの解説ブログ
https://syobochim.hatenablog.com/entry/2019/05/20/002555
IntelliJ IDEA で ATP に接続
https://syobochim.hatenablog.com/entry/2019/04/11/082800
Autonomous DB(ADW/ATP) に Java の JDBC Thin Driver で接続してみる。(OCI, Oracle Cloud Infrastructure)
https://qiita.com/ora_gonsuke777/items/91ec0e15848a78ede385