koudenpaのブログ

趣味のブログです。職業柄IT関連の記事が多いと思います。

アイキャッチ画像がない記事をシェアした際、ブログタイトルや本文などから画像を自動生成する機能を試す記事

staff.hatenablog.com

というなかなかイカした機能が追加されたので新規の記事で試したかった。

出来心と多少のアルコール摂取の影響でやった。

特に反省の必要はないと思う。

GitHub Actions で .NET Core の NuGet パッケージを Push した

以前 NuGet パッケージを作った時にはローカルマシンから nuget.org に Push したのだけれど、正直面倒くさいのでリポジトリにPushしたら勝手にパッケージがプッシュされて欲しい。

最近 GitHubCIサービス? の Actions が使えるようになり、GitHub Package Registry なるGitHub独自のパッケージレジストリも誕生したようだ。

となれば、試すしかない。

続きを読む

Azure Functions (.NET Core)の DI 事情

Azure Functions .NET Core の関数? をデプロイするにあたって、DIしたくてしたので周辺事情を書いておく。

必要な情報は案内されているので、それに従って処理すればDIできる。

docs.microsoft.com

しかし、DI対象の設定をどう構成するのか? が書かれていなかった。

ASP.NET Core の場合は、ファイルや環境変数へ行った設定をいい感じに取り扱ってくれる設定の仕組みがあり、DI時にもその仕組みを使うことができる。

どうやらこの設定の構成は対応途上で、現状はIssue上でワークアラウンドを工夫しているようだった。

その辺を 適当に取り込んだ結果 設定の構成を含むDIを行えた。

ConoHa の VPS で動かしているMySQLのデータディレクトリを追加SSDに移動した

掲題の出来事の記録記事。

追加SSDを設けるまでの経緯

まぁまぁ紆余曲折しているので経緯も書いておく。

前提としてConoHaのVPSWebサービスを動かしていて、RDB(実はMySQLでなくMariaDBだが……CentOS系なので)もVPS上で動かしている。

CoonHaのVPSは標準のストレージは50GB、任意で追加のSSDをアタッチできる。

  • RDB運用とかしたくないし、マネージドDBを使おう
  • マネージドDB、スペックはともかく同時接続数が厳しくてリクエストを捌けない
  • 仕方ないのでVPSMariaDBを動かす
    • 50GBのディスクなんて使い切るわけないじゃん!!
  • Mackerel がDBサーバのファイルシステム容量消費90%超のクリティカルアラートを通知してくる
    • f:id:koudenpa:20190821121636p:plain
    • 50GBのディスク使い切りそうじゃん……
  • 仕方ないので追加SSDをアタッチしてRDBのデータをそちらに配置することにした

追加作業

ディスクの追加自体はConoHaのヘルプ( 追加SSDの設定方法|ConoHa VPSサポート )の通り(例は ext4 だがCentOS7系だったので xfs にした程度)に、データディレクトリの移動は適当にググって出てきたページを雑多に参考にして処理した。

段取りの整理と、ミスした時のリカバリポイントを検討したかったので、スプレッドシートにやることを列挙してから作業した。

f:id:koudenpa:20190821120141p:plain
列挙した段取り

平時の運用でのバックアップ取得前にDBへのアクセスを打ち切ることで、作業が完全に失敗した場合でもまぁまぁ簡単に復旧したかった。それに頼ることはなかったけれど、使わないに越したことはない。

出来事

データディレクトリの設定を起動スクリプトスクリプト/etc/init.d/mysql )内の datadir 変数値書き換えで行った。

さしあたってそれでデータディレクトリは切り替わったのだけれど、DBをアップデートしたら起動スクリプトも更新されてデフォルトに戻ってしまった。

設定ファイル( /etc/my.cnf でインクルードしていた /etc/my.cnf.d に配置されていた server.cnf )でデータディレクトリを指定するようにした。

これで大丈夫だろう。多分。

結果

4倍以上のディスク容量を得て色んな余裕が生まれた。

経過

追記。

f:id:koudenpa:20190903013137p:plain
この対応前後のIOPSのメトリクス

色んな余裕にはピークIO性能もありそうでよかった。

ASP.NET Core で System.Random を使う

ASP.NET CoreC#)で System.Random を使った際の覚書記事です。

アプリケーションを作っていると乱数を使いたくなる場面は多々ある。各言語では概ね疑似乱数の実装が提供されている。

.NET Core でも System.Random クラスが提供されている。

疑似乱数の生成器は内部に状態をもって、次々に疑似乱数値を生成していくものだ。したがって、疑似乱数クラスのインスタンスは乱数が欲しい場面ごとにインスタンスを生成するのではなく、使いまわしすることが望ましい。

これで済むのでは?

// シングルトンインスタンスとしてDIコンテナに登録
services.AddSingleton<Random>(new Random());

と思ったけれど、ドキュメントを読むとこんなことが書いてあった。

クラスRandomはスレッドセーフではありません。 複数のスレッドRandomからメソッドを呼び出す場合は、次のセクションで説明するガイドラインに従ってください。

仕方ないのでガイドラインを参考にスレッドセーフになるようなRandomラッパーを書いて、それをDIコンテナに登録することにした。

// Randomのラッパーを作る。ここでは今回使うメソッドだけラップしている。
public interface IRandomizer
{
    int Next(int maxValue);
}
public class Randomizer : IRandomizer
{
    private Random random;
    private object syncRoot = new object();

    public Randomizer()
    {
        random = new Random();
    }

    public int Next(int maxValue)
    {
        lock (syncRoot)
        {
            return random.Next(maxValue);
        }
    }
}
// あとは Startup.cs でシングルトンに登録して
services.AddSingleton<IRandomizer>(new Randomizer());

// 使いたいところでコンストラクタインジェクションしてやればよい
public class HogeController : Controller
{
    private readonly ApplicationDbContext _context;
    private readonly IRandomizer _randomizer;
    public HogeController(
        ApplicationDbContext context,
        IRandomizer randomizer)
    {
        _context = context;
        _randomizer = randomizer;
    }
    // ...
}

パッと見動いていそうだった。

以下余談。

スレッドセーフなRandom実装を提供してくれれば楽なのだけれどなぁ。ConcurrentRandom のような感じで。

自分はC#Javaをたまに比較するのだけれど、JavaではRandomの実装はスレッドセーフらしい。ただ、スレッドセーフにするためにそれなりにオーバヘッドがあるようで、それを回避するならスレッド毎に乱数を生成する実装を使うようするのがいいそうだ。

この事情はC#だろうが変わらないだろうけれど、今回はアプリケーション内で唯一の乱数生成器を使うことを優先した。

リソース名を付ける時の名前長制限への対応

最近公私でいくつかリソース名の長さ制限に抵触する例が発生して面白かった。

ここでいうリソース名は、自分で長さの制御ができない接続先システムで一意にしたい名前だ。

一意な名前の作り方は幾つもあるけれど、以下のような場合が多いだろうか。

  1. 元々一意な値を使う
  2. UUID を生成する
  3. 幾つかの名前を組み合わせる
    • 環境名+システム名+リソースの種類・用途 など……

こうした何かしらの形で一意な値を作ったが、接続先システムのリソース名制限長がそれより短かったわけだ。

(最近はUUIDの文字列表現36文字は受け入れられることが多いけれど、そうではない場合もまぁある)

『私』の分では厳密に一意でなくてもどうにかなりそうな場面だったので、雑に超過した分を切り捨てて対応した。重複したらその時考えよう。

厳密に一意であって欲しい場合は『幾つかの名前を組み合わせる』の場合は命名規則を見直したり、『UUID』のように値が数値の場合は文字列表現を見直したりで対応していた。

Base64エンコードはなかなか短くなる。使用する文字(特に記号)が名前に使えない場合はBase32なんて手法もある。16進数に比べたら断然短くなる。

どうにもならなくなった場合は、衝突可能性はあるものの適当にハッシュを計算して、Base32エンコードするとどうにか収まったりするのではなかろうか。

たまたまが重なって面白かったこの頃だった。

ドラゴンクエスト ユア・ストーリーを観てきた

僕はユアには含まれていなかった。

多少ネタバレがある、ネガティブな感情の吐露エントリーです。

ブログ記事にせずTwitterへのつぶやきだけで済ましておいても良いかなぁ、とも思ったのだけれど、ドラクエは好きだし、映画をみて感じた辛さは相当なものだったので記録に残しておこうと思った次第です。

続きを読む