MB blog

ちょっぴりテクニカルな話題のメモです。

Polylang プラグインでデフォルト言語から別言語ページへのリダイレクトが発生する

Polylang で3ヶ国語運用している Wordpress サイトのトップページの読み込みが劇的に遅いことに気づき、WebPageTest で見てみると TTFB が 15秒とかありえない値でした。

 

最初は Polylang が原因とはわからずサーバ側リソースがサチっているのかと思ったけれど、ここまで遅いのはデフォルト言語のページだけで、他言語ページへはサクサク動く。ググってみるとまさにこれで、一旦デフォルト言語から英語ページにリダイレクトした上でまたデフォルト言語に戻るという訳のわからない挙動をしているよう。

 

Topic: Polylang slow TTFB | WordPress.org

 

そういえば、デフォルト言語を表示させたいのに第2言語で勝手に表示されてしまったり、意図しない動きをすることがたまにありました。見ないふりしてたけど。

 

フォーラムに記載の通り、Language の Setting から、ブラウザ言語の自動検知を無効にしたら治りました。焦った。

Wordpress サイトを Xdomain 無料サーバから AWS Lightsail に移行

独自ドメイン取得のついでに Xdomain の無料サーバ上に構築していた Wordpress サイト。無料でメールも使えるし、昔ながらの素朴な管理画面で気に入っていたですが、モバイルだとどうしても広告が出てしまい、やはり気になる... ということで、有料サーバに移管することにしました。

お引っ越し先は、月額わずか3.5ドルの AWS Lightsail サーバに決めました。Lightsail は、事前定義済みのアプリケーションが使える VPS のようなもの。EC2のような複雑な設定は不要で、Wordpress も一瞬で動かせます。

移行には、最高に簡単だと名高い All-in-One WP Migration を使ったのですが、なぜかいくつかハマってしまいましたので、解決までの記録も残しておきます。 

1. Lightsail インスタンスの作成と Wordpress のインストール

EC2 と比べてかなり直感的にインスタンスを作れるようになってます。Wordpress サーバを選択し、ポチポチやって行くとインスタンスの作成が出来てしまいました。ホームディレクトリの "bitnami_application_password" というファイルに、Wordpress 管理画面の初期パスワードが記載されているので、確認して http://<グローバルIPアドレス>/wp-admin から、ユーザ名 user でログイン可能。
なお、ここでは Wordpress の設定は何も変更しなくて大丈夫。All-in-One Migration プラグインが、管理ユーザをはじめ、あらゆる設定を移してくれるからです。

初期状態では、ブラウザで Wordpress サイトを確認すると右下に bitnami のアイコンが表示されてしまっていますが、設定で消しておきます。

sudo /opt/bitnami/apps/wordpress/bnconfig --disable_banner 1
sudo /opt/bitnami/ctlscript.sh restart apache

また、最初に払い出されるグローバル IP アドレスは固定IPではなく、スナップショットから復元するとIPが変わってしまいます。Lightsail の管理画面から固定グローバルIPに変更します。"ネットワーキング" タブから、静的IPアドレスを作成し、先ほど作ったインスタンスにアタッチ。完了すると、グローバルIPの表示にピン留め表示がされます。

ドメインの振り替えは、移行作業後に行います。

2. All-in-One WP Migration で移行作業

移行元の Xdomain 無料サーバ上の現行Wordpress、Lightsail サーバ上の初期状態の Wordpress それぞれでプラグインをインストール & アクティベートします。
以降元のプラグイン画面にて、EXPORT TO FILE を選択。ファイル以外の方法でエクスポートすることも出来ますが、無料版はファイルのみです。

ハマりポイント:エクスポートファイルをダウンロード出来ない

エクスポートが完了したので、ダウンロードボタンをクリックすると、500 Internal Server Error。ブラウザからダウンロード出来ないのは、おそらくエックスドメインサーバ側の制限かと思われます。代替策として、wp-content/ai1wm-backups にエクスポートファイルが吐き出されているので、FTP でダウンロード出来ました。

ハマりポイント:エクスポートファイルをインポート出来ない

取得したファイルを、移行先の Wordpress へインポートしようとすると、"Unable to Impoert - unable to open file for reading" とのエラー。
まずは、Wordpress にアップロードできるメディアファイルの上限を超えていることが原因ではなかろうかということで、 .htaccess や wp_config.php を修正したもののうまく行かず。結局、サポートフォーラムで作者が案内していた以下のプラグインを使うとインポートに成功しました。
import.wp-migration.com
私と同じく FILE でのインポートが出来ない場合の設定変更など諸々をやってくれ、無償版で許容される 512MB までのファイルをインポート出来るようにしてくれます。インポートが成功すると、パッと見は同じサイトが出現。

3. Xdomain の管理画面にて Lightsail インスタンスドメインの振り替え

さて、取得しているドメインを、旧 Xdomain 無料サーバから Lightsail インスタンスへと振り向けます。
Lightsail では無料で DNS サーバを使えるのでそちらに切り替えても良いのですが、あいにく Lightsail にはメールサービスは付いていません。Xdomain の無料メールサーバを Gmail に転送して独自ドメインメールとして愛用していたので、DNS サーバは継続して Xdomain 側を利用し、A レコードの IP アドレスのみ Lightsail インスタンスのものに書き換えて対応です。
さて、これでほぼ完成か?と思いきや、なんだかおかしい。

ハマりポイント:ドメインで新サイトにアクセスは出来るものの、アドレスバーにIPアドレスが表示されてしまう

All-in-One Migration は、移行時点でのサイト URL を元に Wordpress アドレス、サイトアドレスを書き換えてしまいます。そのため、各ページのパーマリンクには移行時点での URL であった IP アドレスが使われているし、アドレスバーに表示されてしまうのもそのためでしょう。
Wordpress ダッシュボードの Setting から、Wordpress アドレスとサイトアドレスの両方を独自ドメインに書き換えましたが、それだけでは挙動戻らず。MySQL を直接触って更新しなきゃいけないのかな(情弱)、慣れてないので怖いわ、とビビっていましたが、教えてもらった以下の方法で安全に URL を書き換えることが出来ました。

On your website, go to All-in-One WP Migration -> Export page.
Under advanced settings check every options exception “Do not export database” – this will export only the database and exclude plugins, themes, uploads.
Next, you need to use find/replace tool.
In Find field enter your ip address of the site, e.g. (127.0.0.1)
In Replace field enter the site url: cupoftea-takayama.net/en
Do not include http:// part.

Export to file then import from file on the same site. This should replace all instances of the IP address in the database with your domain name.

なるほど、こういったメタデータのみの書き換えにもこのプラグイン使えるのね。便利です!

今振り返ってみると、ドメイン切り替えのタイミング前にアドレス系は書き換えておくべきだったのではないかと。また同じような機会があれば、こちらのサイトを参考にさせていただこうと思います...。
hacknote.jp

WordPressに限らないWebサイト移行作業の一般的な流れですが、新サーバーに切り替える前からでもドメインで確認できるようにhostsの設定を行います。


SSL 化などの 残タスクは残っていますが、いったんはこれで終了。無事に、モバイル広告を出さないサイトにすることが出来ました。

Charles で HTTP レスポンスの書き換え

転職して、すっかりサーバサイドのプログラミングをしなくなりました。このブログを久々に見ました。 

さて、デモや検証などの目的で、お客さんのウェブサイト上で勝手にJavaScript を動かしたい... という時に、Charles Web Proxy というツールがとても便利です。 もともとは HTTP モニタリング/デバッグツールですが、もっぱら HTTP レスポンスの書き換え用途にのみ使っています。

www.charlesproxy.com

 

基本的に有償のツールで、私は会社の保有するライセンスを登録して使っています。無償でも使えますが、起動して15分間までしか使えないので、デモなどは難しいです。

リライト設定

Tools > Rewite で Enable Rewrite にチェックを入れて、Sets から新たなルールを Add します。 Type = Body を選択 (紛らわしいのですが、これは HTML body の意味ではなく、HTML のペイロードを書き換える時には head であっても必ず Body を選択するようです)、Where では Response にチェック。

JS を挿入したい時によくやるのは、<head> の閉じタグの直前に <script> を挿入する方法。</head> を <script>...</script></head> に置換 (=Replace All) すれば設定完了です。

f:id:lake_michigan:20170703211400p:plain

 

SSL Proxy の設定

書き換えをしたいサイトが SSL の場合、Proxy > SSL Proxy Settings... から、Enable SSL Proxying にチェックを入れておきます。Host には対象サイトの URL, Port は * と入力。

 

証明書のインストールと信頼

このままではブラウザでアクセスする際に、信頼できる証明書がないということでプライバシーエラーが出てしまいます。

Help > SSL Proxying > Install Charles Root Certificate を選択し、ルート証明書をインストールします。その後 Mac のキーチェーンアクセスツールを開き、Charles で検索。証明書が信頼されていないことを示す赤い×マークが出てくるので、そこをクリック。"信頼" セクションから、"常に信頼" を選択しておきます。

その後 Charles を再起動すると、リライトが始まります。

 

以上です。

一番簡単な WebLogic データソースのテスト

11g, 12c 以降の WebLogic データソースでは色々な機能が追加されており、データソースの設定をいじり回すことが多いです。

これまで WebLogic にデータソースを作成してテストをする際はわざわざ Web アプリにしてデプロイしていましたが、データソースがデプロイされている WebLogic Server の weblogic.jar をクラスパスに指定すれば、スタンドアロンJava プロセスからルックアップできることに今さらながら気がつきました。

1. WebLogic データソースの作成

ここでは jdbc/GridLinkDS という JNDI 名で、GridLink データソースを作成しています。

f:id:lake_michigan:20141204144712p:plain

2. テスト用の main クラスを記述&コンパイル

"jdbc/GridLinkDS"  で普通にルックアップしています。

public class MultiDSTest {

    public static void main(String args[]) {

        String serverHost = "localhost";
        String serverPort = "7001";
        String dbusername = "system";
        String dbpassword = "oracle";
        String dsname = "jdbc/GridLinkDS";

        Hashtable env = new Hashtable();

        env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
        env.put(Context.PROVIDER_URL, "t3://" + serverHost + ":" + serverPort);
        env.put("user", dbusername);
        env.put("password", dbpassword);

        String information = "";

        try {
            Context context = new InitialContext(env);
            javax.sql.DataSource ds =
                (javax.sql.DataSource) context.lookup(dsname);
            Connection  connection = ds.getConnection();
            Statement   statement = connection.createStatement();
            ResultSet   resultSet;
            String      sql;

            System.out.println("Got a connection from...");

            sql = "select sys_context('userenv', 'instance_name'), sys_context('userenv', 'server_host'), sys_context('userenv', 'service_name') from dual";
            resultSet = statement.executeQuery(sql);

            while (resultSet.next()) {
                information  = resultSet.getString(1) + "   " + resultSet.getString(2) + "   " + resultSet.getString(3);
            }
        System.out.println(information);
        
            statement.close();
            resultSet.close();
            connection.close();
        } catch (Exception e) {
            System.out.println("Error:" + e);
        }
    }
}

 

3. 実行

クラスパスに weblogic.jar を追加してから java コマンドで上記クラスファイルを実行すると、 "jdbc/GridLinkDS" が普通にルックアップできます。

weblogic.jar は 12.1.3 の場合、<MiddlewareHome>/wlserver/server/libweblogic.jar に存在します。

 

わざわざ WebApp の形にしてデプロイしなくても良いんですね。

WebLogic 管理サーバの起動に失敗

BEA-090870 The realm "myrealm" failed to be loaded:
新しく構築した仮想サーバ (OracleLinux 6U5) に WebLogic Server 12.1.2 をインストール、ドメイン作成して起動したところ、上記のエラーメッセージが出て起動できない。
原因は /etc/hosts にホスト名を書き忘れていたことでした。
WLS はホスト名を基準として IP アドレスをバインドするので、起動時に IP アドレスが取得できず、このようにセキュリティレルムのエラーが出力されるみたいです。これは、Configuration Wizard でドメイン構成時のリスン・アドレスに DNS 名ではなく IP アドレスを指定していても、同じことがおこりました。

RMI server port を明示的に指定する(7u4 and later)

JMX over RMIJMX モニタリングを行う際、サーバー側は「RMI registry port」(クライアントが接続時に指定するポート)と「RMI server port」(内部で使われるポート)と2つのポートを使います。後者の RMI server はデフォルトではランダムに振られるので、ssh tunnel で監視したいようなときは困ってしまうけど、Java7u4 以降は明示的に指定できるようになっているらしいのでメモ。

  • RMI registry port

デフォルトなし。かならず -Dcom.sun.management.jmxremote.port=$PORT で指定が必要。

  • RMI server port

デフォルトではランダムに振られる。明示的に固定したいときは、-Dcom.sun.management.jmxremote.rmi.port=$PORT を指定。