サーバーが重い、ページが開かない 20210819

運営サイトでサーバーが重くなった。タイムアウトでページが開かないことが多発した。
ipアドレスでアクセスした場合は問題なし。ドメインでアクセスした場合のみ問題が発生。

ニ三日前からページにアクセスしづらい状態がたびたび起こっている。ちょうどデーターベースの書き換えでサーバーに負荷のかかる作業だったので、それが原因かとデータベースを削除したり解決策を検索したが解決に至らず。

さくらインターネットに問い合わせて見る。

 

送ったメール内容
---------------------------------------------------------

サーバーに利用制限がかかっていませんか?
二日ほど前多少サーバーに負荷のかかる処理をしました。そのあとからページの表示がされにくくなりました。
ブラウザからページにアクセスしても「サーバーが応答しません」と出ます。
ipアドレスでアクセスした場合は問題なく表示されますが、ドメイン名でアクセスした場合のみ問題が起こります。
http://160.○○○.○○○.○○○/index.html ← 問題ない
http://独自ドメイン/index.html ← 表示されない
調査をお願いします。
---------------------------------------------------------

一時間ほどで返信あり。
返信の内容
---------------------------------------------------------
現時点で弊社にて実施している制限はございません。

また、IPアドレスでブラウズ可能ということでございましたら仮想サーバ
自体の障害や制限によるものとは考えにくいものでございます。

恐れ入りますが「さくらのVPS」は、お客様に管理者権限をお渡ししている
サービスとなり仮想サーバの構築・運用・保守にいたる管理全般をお客様にて
実施いただいております。

そのため、弊社ではお客様のご利用いただく仮想サーバ内のシステム状況
などを把握や調査、トラブルシューティング等の技術的なサポートは承って
おりません。

お手数ですが、仮想サーバ内の設定やドメインのゾーンを管理するネーム
サーバに問題がないなど、サーバ管理者様にてご確認いただきますよう
お願いいたします。
---------------------------------------------------------
このメールを受け取った前後に再度ページにアクセスしたら滞りなくページが開いた。
時間が解決してくれたということか?

一週間後・・・。

再びアクセスエラー。

再調査する。

このページが参考になりそう

https://meteoricstream.com/tips_detail/45.html

したこと。

手元の windows コマンドプロンプトから ping 送信 → 問題なし。

 

アクセスログを調べる。
rootで
cat /var/log/httpd/access_log

エラーログを調べる。
cat /var/log/httpd/error_log

 

エラーログ一部抜粋
-------------------------------------------------------------------------------------------
[Fri Aug 27 01:28:32 2021] [error] server reached MaxClients setting, consider raising the MaxClients setting
-------------------------------------------------------------------------------------------
訳:サーバーは MaxClients の設定値に達しました。MaxClients の設定値を大きくすることを検討してください。
setting → 設定(値)

↑ 上記メッセージは、Webサーバの起動後、リクエスト数がはじめてクライアントの同時接続数に達した際に一度だけ出るみたい。

 

MaxClients の値を上げるには httpd.conf の値を変えればいいらしい。

cat /etc/httpd/conf/httpd.conf

 

httpd.conf を開くと MaxClients ディレクティブが二つあった
httpd.conf 一部抜粋
-------------------------------------------------------------------------------------------
# prefork MPM

# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# ServerLimit: maximum value for MaxClients for the lifetime of the server
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>

# worker MPM
# StartServers: initial number of server processes to start
# MaxClients: maximum number of simultaneous client connections
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule worker.c>
StartServers 4
MaxClients 300
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
-------------------------------------------------------------------------------------------

workerで動いてるか、preforkで動いてるか確認

コンソールで apachectl -l もしくは httpd -l を実行
apachectl と httpd はほぼ同じ内容で、どちらも httpd の軌道や停止をするコマンド

-------------------------------------------------------------------------------------------
# apachectl -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
-------------------------------------------------------------------------------------------

prefork で動いているという事らしい
デフォルトでは prefork ということ

httpd -V もしくは apachectl -V コマンドでも確認できる
Server MPM: の部分を確認

結果
-------------------------------------------------------------------------------------------
# httpd -V
Server version: Apache/2.2.15 (Unix)
Server built: Oct 19 2017 16:43:38
Server's Module Magic Number: 20051115:25
Server loaded: APR 1.3.9, APR-Util 1.3.9
Compiled using: APR 1.3.9, APR-Util 1.3.9
Architecture: 64-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=128
-D HTTPD_ROOT="/etc/httpd"
-D SUEXEC_BIN="/usr/sbin/suexec"
-D DEFAULT_PIDLOG="run/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_LOCKFILE="logs/accept.lock"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"
-------------------------------------------------------------------------------------------

 

httpd.confより抜粋
-------------------------------------------------------------------------------------------
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>
-------------------------------------------------------------------------------------------

同時接続の上限はこの場合 256 になる。

 

問題が起きているときのプロセスの数を確認すると 258 であり、上限を超えている
-------------------------------------------------------------------------------------------
ps aux |grep httpd |wc -l
-------------------------------------------------------------------------------------------

httpd.conf を書き変えて、MaxClientsを増やす。

ServerLimit ディレクティブも同じように増やす必要がある。

ではベストな MaxClients はいくつなのか

MaxClients及びServerLimitのベストな設定値

 

また、ネットワークの状態を確認して、同一ipアドレスから大量のリクエストが来ていないか確認する

コマンド
-------------------------------------------------------------------------------------------
netstat -tpn
-------------------------------------------------------------------------------------------

結果
-------------------------------------------------------------------------------------------
tcp 0 0 160.16.63.○○○:443 154.21.212.○○:52041 SYN_RECV -
tcp 0 0 160.16.63.○○○:443 154.21.212.○○:65281 SYN_RECV -
tcp 0 0 160.16.63.○○○:443 154.21.212.○○:50095 SYN_RECV -
tcp 0 0 160.16.63.○○○:443 154.21.212.○○:62694 SYN_RECV -
tcp 0 0 160.16.63.○○○:443 154.21.212.○○:49490 SYN_RECV -
tcp 0 0 160.16.63.○○○:443 154.21.212.○○:64857 SYN_RECV -
tcp 0 0 160.16.63.○○○:443 154.21.212.○○:57942 SYN_RECV -
tcp 0 0 160.16.63.○○○:443 154.21.212.○○:51261 SYN_RECV -
-------------------------------------------------------------------------------------------
同一ipアドレスからの大量アクセスを確認。

.htaccess を編集して ipアドレスに制限を掛ける

-------------------------------------------------------------------------------------------
#ipアドレスの制限
order allow,deny
allow from all
deny from 154.21.212.○○
-------------------------------------------------------------------------------------------

禁止ipアドレスでアクセスするとcentOS のテストページが表示されてしまうので、forbidden が出るよう設定を変更

参考:https://www.dataplan.jp/blog/server/2089

問題のipアドレスを探す方法として、tcpdump でパケットキャプチャを仕掛けて分析するという方法もあるらしい。

↓サーバーを再起動するとerror_log に残る
-------------------------------------------------------------------------------------------
[Fri Aug 27 02:02:07 2021] [notice] caught SIGTERM, shutting down
-------------------------------------------------------------------------------------------

 

タイトルが分かれているISOファイルを字幕付きmkvで結合

1.ISOファイルを用意する

2.ISOファイル から hand break を使って 字幕付き mkv 形式で取り出す。

3.MKVToolNix で結合。「ファイルを追加結合する」で結合。

MKVToolNixでキャプチャ分割の仕方

Multiplexer の「出力タブ」の「ファイル分割」の「分割モード」を「before capters」にする。
チャプタ―番号を指定。

【さくらのVPS】WEBページが表示されない

ある日突然WEBページが表示されなくなった。
表示されなくなったサイトとは別のサイトのお問い合わせメールから知る。

アクセスするが確かに表示されない。2つ契約しているVPSサーバーのもう片方は問題なく表示できる。表示できないサイトと同じサーバーで運営している別サイトも表示できず。

さくらのVPSサーバーのコントロールパネルにはログイン可能。
特に問題も当たらず。

さくらのコールセンターに問い合わせる。

サーバーには問題ないとの答え。

ただ、ポート80(http)と443(https)が不通で通信ができてないとのこと。

問題を解決するにはポートを開放するか、apache の状態を確認しろと助言をもらう。

ターミナルからサーバーにアクセス。

apacheの状態を確認

//コマンド
----------------------------
/etc/init.d/httpd status
----------------------------

//結果
----------------------------
httpd status unknown due to insufficient privileges.
----------------------------

権限がないという事で root に変更して確認

//結果
----------------------------
httpd は停止しています。
----------------------------

やっぱり動いてなかった。

//apache を起動
----------------------------
service httpd start
----------------------------

//結果
----------------------------
httpd を起動中
----------------------------

無事WEBページを表示できた。

【PHP】stripeのwebhook設定

stripeのwebhook設定手順

参考ページ

https://stripe.com/docs/webhooks/setup

https://qiita.com/hirocueki2/items/9dc1eea6836e3f293f47

1.dashboard の「開発者」から webhook の設定をする

エンドポイントの例

https://example.com/stripe_test/webhook_test.php?action=stripehook

2.PHPファイルをサーバーに置く

PHPファイルの例
//////////////////////////////////////////////////////////
<?php

// ダウンロードしたStripeのPHPライブラリのinit.phpを読み込む
//require_once('/home/hoge/stripe-php/init.php'); //手動でダウンロードした場合は init.php になるらしい
require_once('/var/ruigo_stripe_composer/vendor/autoload.php');

// APIのシークレットキー

// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey('秘密キー');

// You can find your endpoint's secret in your webhook settings
$endpoint_secret = 'whsec_~から始まるエンドポイントの秘密キー';

$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;

try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400);
exit();
} catch(\Stripe\Error\SignatureVerification $e) {
// Invalid signature
http_response_code(400);
exit();
}

//
// $eventに対しての処理を行う
//

$event_json = json_decode($payload);

$event_id = $event_json->id;

//dashboard からのテスト送信だと id が 00000 になるのでエラーが返る
try {
$event = \Stripe\Event::retrieve($event_id);
} catch(\Stripe\Error\InvalidRequest $e) {
// Invalid payload
http_response_code(400);
exit();
} catch(\Stripe\Error $e) {
// Invalid payload
http_response_code(400);
exit();
}

if ($event->type == 'customer.created') {

//ここに自分自身にメール送信やデータベースへの登録などの処理を記述

}

if ($event->type == 'customer.subscription.deleted') {
}

if ($event->type == 'customer.subscription.updated') {
}

if ($event->type == 'invoice.payment_succeeded') {
}

echo "aa"; //このページからのレスポンス。stripe のダッシュボードで確認できる
http_response_code(200);

?>
//////////////////////////////////////////////////////////

【PHP】stripeでカード情報を更新してデフォルトに設定する

stripeでカード情報を更新してデフォルトに設定する

JCBカードは洗い替えに対応していないので更新を促す必要がある。
カード番号更新フォームに作り方。

https://stripe.com/jp/blog/smarter-saved-cards

//カード情報を更新してデフォルト 方法1
//////////////////////////////////////////////////
\Stripe\Customer::update($stripe_cus_id, [
'source' => $token, ← 顧客からフォームを通してカードを番号を入力してもらって取得
]);
//////////////////////////////////////////////////

リファレンス

https://stripe.com/docs/saving-cards

//カード情報を更新してデフォルト 方法2
//すでに登録されているカード情報に追加して、二枚目のカードとして新しいカードを登録する場合

//////////////////////////////////////////////////

//まず登録
$card = \Stripe\Customer::createSource(
$stripe_cus_id,
[
'source' => $token,
]);

//新しいカードをデフォルトに切り替える
$customer = \Stripe\Customer::retrieve($stripe_cus_id);
$customer->default_source=$card['id'];
//$customer->save();
//////////////////////////////////////////////////

mailコマンドでメールを見る

mailコマンドでメールを見る

ターミナルにログインして
---------------------------------------
mail
---------------------------------------

ローカルに受信したメールのタイトルや日時などの情報の一覧が出る。

受信したメールが多くて一画面に収まらない場合

次のページへ移動
---------------------------------------
z
---------------------------------------

前のページへ戻る
---------------------------------------
z-
---------------------------------------

メール内容を表示
---------------------------------------
p 999(メール番号を指定)
---------------------------------------

お問い合わせフォームからメールが届かなくなった

運営しているサイトのお問い合わせフォームからメールが届かなくなった。

さくらのVPSのサーバー名(hostname)を変更した後からメールが届いていない。

---------------------------------------------------
localhost.localdomain → 運営サイトのドメイン(~~.info)
---------------------------------------------------

ターミナルから maillog を見ると以下の記述

---------------------------------------------------
dsn=5.1.1, status=bounced (unknown user: "renraku")
---------------------------------------------------

ネットで調べると /etc/postfix/main.cf の設定を変えればいいとあるので変更
(参考: https://qiita.com/myzkyy/items/cfb6b1f95eb6af6261ec)

mydestination はローカルに送る送り先を指定するディレクティブ
---------------------------------------------------
mydestination = $myhostname, localhost.$mydomain, localhost

↓↓↓↓↓↓↓

mydestination =
---------------------------------------------------

postfix を再起動。

---------------------------------------------------
/etc/init.d/postfix restart
---------------------------------------------------

メールを再送して確認。OK。

サーバーを再起動したら mysql に繋がらなくなった。

サーバーを再起動したら mysql に繋がらなくなった。

サイトにアクセスしたときに表示された PHP のエラーメッセージ
-----------------------------------------------------------
Warning: mysql_set_charset(): No such file or directory in /var/www/libs/~~~~

Warning: mysql_set_charset(): A link to the server could not be established in /var/www/~~~~~
ConnectError!DB Error: connect failed
-----------------------------------------------------------

ターミナルから mysql にログインすると次のエラー
-----------------------------------------------------------
Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
-----------------------------------------------------------

socketファイルというものが無いのが原因のよう。

ターミナルから mysql を再起動するとsocketファイルが作られるらしいので、再起動して解決。
-----------------------------------------------------------
sudo /etc/init.d/mysqld restart
-----------------------------------------------------------

参考サイト

https://qiita.com/kanohisa/items/564035efd74d9c75bdcb

phpmyadminにログインできない

phpmyadminにログインできない

ログインすると以下の画面

mysql_error

Error during session start; please check your PHP and/or webserver log file and configure your PHP installation properly. Also ensure that cookies are enabled in your browser.

session_write_close(): write failed: No space left on device (28)

session_write_close(): Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/var/lib/php/session)

セッション開始中にエラーが発生しました。 PHPやWebサーバーのログファイルをチェックして、PHPのインストールを正しく設定してください。また、ブラウザでクッキーが有効になっていることを確認してください。

ターミナルから実行
--------------------------------
df -h コマンドを実行する。
--------------------------------

tarminal

ファイル容量がいっぱいなので不要なファイルを削除する

参考サイト

https://qiita.com/myzkyy/items/53e985cf028e3c3edfe5

stripe & phpで定額決済を導入

1.stripe のダッシュボードで定額商品を作成。ここで作られる プランid がスクリプトで必要になる。

プランid の他にも id がつくられるので間違えやすい。plan_ から始まるものが正解。 prod_ から始まるものは違う。

参考:
Stripe サブスクリプション実装の際に必要なidについて

2.php スクリプトを記述

//購入画面(order.html)
--------------------------------------------------
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>購入画面</title>
<!-- 購入ボタンのCSS -->
<style type="text/css">
.stripe-button-el {
width: 350px;
max-width: 100%;
}
.stripe-button-el span {
font-size: 18px;
padding-top: 15px;
min-height: 60px!important;
}
</style>
</head>

<body>
<form action="charge_subsc.php" method="POST">
<?php //data-key は公開キー ?>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="公開キー"
data-name="サブスクプラン"
data-description="◯◯◯◯◯◯◯"
data-locale="auto"
data-amount="400"
data-currency="jpy"
data-label="お申し込みする">
</script>
</form>
</body>
</html>
--------------------------------------------------
//購入画面からデータを投げる先(charge_subsc.php)
--------------------------------------------------
<?php
// ダウンロードしたStripeのPHPライブラリのinit.phpを読み込む
//require_once('/home/hoge/stripe-php/init.php'); //手動でダウンロードした場合は init.php になるらしい
require_once('/var/hoge/vendor/autoload.php');

// APIのシークレットキー
\Stripe\Stripe::setApiKey('秘密キー');

try
{
$customer = \Stripe\Customer::create(array(
'email' => $_POST['stripeEmail'],
'source' => $_POST['stripeToken'],
));

$subscription = \Stripe\Subscription::create(array(
'customer' => $customer->id,
'items' => array(array('plan' => '1で作ったプランのid')),
));

//データベース操作など stripe とは関係ない処理
//必要に応じてデータベースに保存する
$customer_id = $customer->id;
$subscription_id = $subscription->id;
$last4 = $customer->sources->data[0]->last4; //カード番号下四桁
$exp_month = $customer->sources->data[0]->exp_month; //カード有効月
$exp_year = $customer->sources->data[0]->exp_year; //カード有効年
$card_exp_date = $exp_month . "/" . $exp_year;

header('Location: thankyou.html');
exit;
}
catch(Exception $e)
{
// header('Location:oops.html');

echo "error:" . $e->getMessage();
error_log("unable to sign up customer:" . $_POST['stripeEmail'].
", error:" . $e->getMessage());
}
// サンキューページへリダイレクト
exit;
?>
--------------------------------------------------
これでできるはず。

ちなみにキャンセルはこれ
--------------------------------------------------
//サブスクリプションをキャンセル
$subscription = \Stripe\Subscription::retrieve($stripe_subsc_id);
$subscription->cancel();
--------------------------------------------------

メインで参考にしたページ

https://teratail.com/questions/118633