LoginSignup
7
0

More than 3 years have passed since last update.

アプリケーションサーバをごっそり載せ替えた話

Last updated at Posted at 2019-06-28

およそ10年前のアプリケーションサーバを、サービスを停止することなく新サーバに載せ替えて欲しい、という依頼に対応したので、その移行手順を簡単に紹介。
image.png

仕様・要件

旧サーバで稼働するWebアプリケーションを新サーバに移転する。
新旧、両サーバの仕様は次の通りだ。

種別 旧サーバ 新サーバ
クラウド さくらのVPS Azure VM
OS CentOS 5.11 CentOS 7.4
WWWサーバ httpd 2.2.3 httpd 2.4.6
APサーバ Tomcat 5.5.26 Tomcat 5.5.26
コネクタ mod_jk mod_proxy_ajp
ランタイム jdk 1.5.0_22 jdk 1.8.0_162
DBMS PostgreSQL 8.1.23 PostgreSQL 9.2.23
  • BtoBのWebサービスであり、小規模とはいえ数十社に使われている24時間365日稼働のサービスである。
  • 新サーバには PHP/Laravel という新しめのフレームワークを追加し、データベースを JavaServlet/JSP と共有したいので、ミドルウェアも可能な限り新しくする。

新サーバの構築

Azureポータルの「リソースの作成」から CentOS-based 7.4 をデプロイする。
image.png
VMにログインし、必要なモジュールを追加していく。

Oracle Java8(JDK1.8)のインストール

OpenJDKはTomcatが公式にサポートしていないので使わなかった。

# rpm -ivh jdk-8u162-linux-x64.rpm

# java -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

WWWサーバ(Apache)のインストール

yum -y install httpd
yum -y install mod_ssl

httpd -v
Server version: Apache/2.4.6 (CentOS)

Tomcatと連携させる。

/etc/httpd/conf.d/foo.conf
<Location /foo/>
    ProxyPass ajp://127.0.0.1:8009/foo/
</Location>

業務上必要なポートに穴を開ける。

firewall-cmd --list-all
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

サーバ証明書まで入れたら、https://www.ssllabs.com/ssltest/ でSSL脆弱性診断を受け、指摘を直しておくと良いかも。

Tomcatのインストール

5.5系のlatestである5.5.36を採用したところ、一部の画面で HttpServletRequest#getAttribute メソッドが NullPointerException を投げたので、従来の 5.5.26 を維持した。
ソースコードが開示されていない、というか開発元が倒産しているので、IntelliJ IDEAのプラグインでデコンパイルして直す…なんてことはリスク高いのでやらない。

cd /usr/local
wget https://archive.apache.org/dist/tomcat/tomcat-5/v5.5.26/bin/apache-tomcat-5.5.26.tar.gz
tar zxvf apache-tomcat-5.5.26.tar.gz

ln -s apache-tomcat-5.5.26 tomcat5

コンテキスト記述子を作成する。

/usr/local/tomcat5/conf/Catalina/localhost/foo.xml
<?xml version="1.0" encoding="utf-8"?>
<Context path="/foo" reloadable="true" docBase="/var/app/webapps/foo"></Context>

Tomcatがmod_proxy_ajpと通信する8009ポートを設定する。

/usr/local/tomcat5/conf/server.xml
<Connector port="8009"
    maxThreads="150" minSpareThreads="25" maxSpareThreads="100"
    acceptCount="100" connectionTimeout="0"
/>

<Connector port="8080" ... /> はコメントアウトして無効にする。
サーブレットは、旧サーバから /var/app/webapps にまんまコピーしたので <Host name="localhost" ... /> の appBase は "/var/app/webapps" に変更する。

Tomcatをサービスに登録

/etc/systemd/system/tomcat.service
[Unit]
Description=Apache Tomcat 5 Servlet Container
After=syslog.target network.target

[Service]
Type=forking
ExecStart=/usr/local/tomcat5/bin/startup.sh
ExecStop=/usr/local/tomcat5/bin/shutdown.sh
KillMode=none

[Install]
WantedBy=multi-user.target

JDBCドライバの更新

webapps下のJDBCは古いままなので、PostgreSQL 9.2に対応するJDBCに差し替える。

cd /var/app/webapps/foo/WEB-INF/lib
wget https://jdbc.postgresql.org/download/postgresql-42.2.2.jar

PHP7のインストール

新サーバでは、JavaServlet/JSPに加えて、PHP/Laravelでもサービスを提供するためPHPが必要。

rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum -y install --enablerepo=remi-php72 php php-mbstring php-pear php-fpm php-pecl-mcrypt php-pecl-zip php-xml php-gd php-pdo php-mysqlnd php-pgsql

ついでにComposerも入れておこう。(本番サーバでは使わないが念の為)

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

DBサーバのインストール

# yum -y install postgresql-server
# postgresql-setup initdb

# psql --version
psql (PostgreSQL) 9.2.23

データベースの移行

旧サーバでダンプを取得し、新サーバにコピーする。

旧サーバ
su - postgres
pg_dump foo > /tmp/foo.txt

scp /tmp/foo.txt bar@new.example.com:/tmp

新サーバでリストアする。

su - postgres
createdb foo
psql foo < /tmp/foo.txt

暗黙キャストの追加

PostgreSQLは、バージョン8.3 から型変換のチェックが厳密になり、暗黙の型変換がされなくなったので、
https://qiita.com/seiketkm/items/9d069348c2906a6ae011
https://qiita.com/6in/items/f23ead1314b9e6d2f2b7
などの記事を参考に、暗黙キャストを追加する。

cat << 'EOF' > /tmp/cast.sql
CREATE CAST (int2 AS text) WITH INOUT AS IMPLICIT;
CREATE CAST (int4 AS text) WITH INOUT AS IMPLICIT;
CREATE CAST (int8 AS text) WITH INOUT AS IMPLICIT;
CREATE CAST (text AS numeric) WITH INOUT AS IMPLICIT;
CREATE CAST (numeric AS character) WITH INOUT AS IMPLICIT;
CREATE CAST (character varying AS numeric) WITH INOUT AS IMPLICIT;
CREATE CAST (timestamp without time zone AS text) WITH INOUT AS IMPLICIT;
CREATE CAST (timestamp without time zone AS character varying) WITH INOUT AS IMPLICIT;
CREATE CAST (character varying AS timestamp without time zone) WITH INOUT AS IMPLICIT;
CREATE CAST (timestamp with time zone AS text) WITH INOUT AS IMPLICIT;
CREATE FUNCTION textint4cat(text, int4) RETURNS text AS 'SELECT $1 || $2::pg_catalog.text' LANGUAGE sql IMMUTABLE STRICT;
CREATE OPERATOR || (PROCEDURE = textint4cat,LEFTARG = text, RIGHTARG = int4);
EOF

psql foo < /tmp/cast.sql

キャストの一覧を確認する。

psql foo
\dC

動作確認

ここまでで、いったんWebアプリケーションの動作を確認する。

移行

サービス利用者が圧倒的に少ない深夜帯に決行。
以下はすべて旧サーバのオペレーションである。

アクセスログのモニタリング

ターミナルをもうひとつ起動し、アクセスログをモニタリングしておく。

tail -f /var/log/httpd/old.example.com.access.log

データベースのコピー

アクセスがなければ、旧サーバのダンプを新サーバでリストアする。
もし、その間にアクセスがあれば、やり直し!

リダイレクトの設定

301リダイレクト(恒久的な転送)はブラウザにリダイレクトキャッシュが残り、戻せなくなるので、302リダイレクト(一時的な転送)にする。

httpd.conf
Redirect temp /foo/ https://new.example.com/foo/

再度アクセスが無いことを確認できたら、httpdを再起動。
リクエストが新サーバに転送されているか確認しよう。

旧サーバのデータベース名を変更

なんかの間違いで旧サーバにアクセスできてしまった場合でも、エラーとして確実に報告されるようにする。

su - postgres
psql
alter database "foo" rename to "foo_BK";

DNSの切り替え

バーチャルホストで運用している場合、公開時のドメインでアクセスしないと正しく表示されない。
DNSを書き替える前に新しいドメインでテストするには、クライアントのhostsファイルを編集する。
Windowsの場合、hostsファイルの場所は以下にある。

C:\Windows\System32\drivers\etc\hosts

メモ帳などのテキストエディタを管理者権限で起動し、「新IPアドレス(スペース)旧ドメイン」で追加しよう。

テストが問題なければDNSサーバのゾーンファイルを編集する。旧サーバのドメインに定義しているグローバルIPアドレスを、新サーバのグローバルIPアドレスに変更し、DNS伝播したところで旧サーバを閉鎖する。

/usr/local/etc/namedb/master/example.com.zone
$TTL 3600
$ORIGIN example.com.
@       IN      SOA     xxx.example.com. (
        2019070101      ; Serial
        43200           ; Refresh after 12 hours
        3600            ; Retry after one hour
        2419200         ; Expire after 4 weeks
        1200    )       ; Negative cache TTL of 20 minutes
;
; Authoritative name servers
;
        IN      NS      ns01.example.com.
;
; Host
;
old     3600     IN      A       nnn.nnn.nnn.nnn  ; 新サーバのIPアドレスに変更
7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0