システム開発で思うところ

Javaで主にシステム開発をしながら思うところをツラツラを綴る。主に自分向けのメモ。EE関連の情報が少なく自分自身がそういう情報があったら良いなぁということで他の人の参考になれば幸い

クライアントのメモ

SPAとかJavascriptとかクライアント関連のメモ

SPAを構築するときに知っておいた方がいい7つの課題 | I am mitsuruog

Yeomanを使った簡単SPA開発手順 - albatrosary's blog

ブログをシングルページアプリケーション(SPA)にするメリット・デメリット | 綺麗に死ぬITエンジニア

www.slideshare.net

https://www.fieldexit.com/forum/display?threadid=208

SPAでhistory backでのスクロール位置 - chocotakaの日記

Java Web Startを久々に使ってみた - torutkの日記

speakerdeck.com

メッセージングのメモ

vermeer.hatenablog.jp

の流れで、ざっくりと拾い集めたもの。

Yahooの取り組み

www.slideshare.net

Kafka

sssslide.com

www.slideshare.net

www.slideshare.net

Pulsar

techblog.yahoo.co.jp

www.slideshare.net

www.slideshare.net

JJUG ナイトセミナー 「メッセージングミドルウェア特集」に参加してきました #jjug

まとめ

togetter.com


メモ

実運用して分かったRabbit MQの良いところ・気をつけること

www.slideshare.net

  • ブローカー無しのメッセージングはダメ!メッセージングミドル導入は絶対
  • メッセージは標準仕様が使えるよ
  • ロードバランサーはいらないよ(というか それが原因でメッセージロストして大変だったよ)
  • トラフィック統計と大量処理はトレードオフ
  • ディスクIO対策でマスタはHDD、スレーブはメモリ。2年運用しているけど 今のところ大丈夫

40分弱でわかるApache Kafka

CCCでも聞かせていただきましたが、今回は「製品の特長」に特化していた印象です。

  • ストリーミング処理に強みがあるよ
  • 事例が多いよ

以前、話を聞いたところもあり、メモは薄いですが 発表は相変わらず良かったですし、製品の特長も分かりやすかったです。ストリーミング処理基盤が必要だったら迷わずKafkaを選ぶと良さそうだ、と思います。

メッセージキュー「Pulsar」の紹介

www.slideshare.net

登壇者はコミッター。

新卒7年目でコミッター。

  • 3つの中では一番新しい製品だよ
  • Yahooが開発元だよ
  • 高いスループットに耐えられるよ
  • スケーリングに強いよ
  • マルチテナントだよ
  • 環境構築については3つの中では、一番手間かもしれないよ
  • 設定が階層的に継承できるよ
  • Kafkaクライアントラッパーがあるので、Kafkaからの移行も楽だよ*1

感想

ざっくり

  • 手始めにメッセージングを試してみたいなら、標準仕様を備えているRabbit MQ
  • メッセージングによるストリーミング処理を検討しているならKafka
  • 高いスループットが想定するならPulsar
  • 高いスループットを想定しなくても、メッセージングだったらPulsar
  • スケーリングが容易なのはPulsar
  • マルチテナントならPulsar
  • 個人的には使い勝手が良さそうな印象なのはKafka
  • Kafkaクライアントで実装しておいて、状況によりバックヤードはPulsarにするとか、っていうのはアリかも

Yahooという1つの企業で、メッセージングだけでも色々な製品を使っているというのが面白いですね。

なんとなくですがRabbit MQPulsarのマルチテナントの1つに まとまる方向になる気がしました。Kafkaはストリーミング処理への強み(便利さ)などを考えると 下手にまとめない方が良いという印象を受けました。

というような感じで、一言にメッセージングミドルで片づけてしまうところについて、製品特徴を鑑みて「ここには これを適用してみたら?」と思えるようになったのが最大の収穫だったと思います。

関連

www.slideshare.net

*1:そこまでは言っていないけど、そう言っているように思えた

要件定義のメモ

RDRA

www.slideshare.net


speakerdeck.com


ドメインモデルの根拠とドメインモデル貧血症の対策について - Chatwork Creator's Note


DDD Alliance! RDRA流概念モデル - connpass

の資料(資料への直接リンクはしない)


speakerdeck.com


「要件定義」の4つの構造と依存関係に着目した実践手法 (1/5):CodeZine(コードジン)

GitHubにMavenリポジトリをつくる

Mavenプロジェクトを細かく分割することを前提にしたら、私が作成しているものは公開リポジトリが無いと利用者側*1にとって凄く不便だなと思って調べてみました。

はじめに

さくっとは出来ないだろうなぁとは思いましたが案の定かなり苦戦しました。自分なりに 初めから やり直したので大丈夫な手順だとは思います*2

環境

Windows10、Java8、NetBeans8.2

なぜGitHub

コードの管理は今のところ基本的にBitBucketを使っています。その中でMavenリポジトリGitHubにしました。理由は知見量が多かったことと、当初、BitBucketでやろうとしたのですが良く分からなかったというのが一番の理由です。あと後付け的なところはありますが、公開する資産についてはGitHubの方が多くの人にとって馴染みがあるかな?というところもあってGitHubMavenリポジトリの置き場にすることにしました。

構築の流れ

格納先となるリポジトリを作成する

f:id:vermeer-1977:20170901131727p:plain

  • ブランチを作成

ブランチ名は「mvn-repo」

f:id:vermeer-1977:20170901132124p:plain

f:id:vermeer-1977:20170901132311p:plain

f:id:vermeer-1977:20170901132808p:plain

「save」ボタンを押すのを忘れずに

認証キーを作成する

Webで調べるとユーザー名とパスワードを設定するやり方が多かったように思いますが、OAuthによる認証の方がセキュリティー的にみて良いと思います。

f:id:vermeer-1977:20170901133320p:plain


f:id:vermeer-1977:20170901133524p:plain


Token description は「maven-pass」。ただのラベルなので何でも大丈夫です。

チェックボックスpublic_repo user:email だけ。必要最低限は この2つをチェックすれば良いようです*5

f:id:vermeer-1977:20170901133846p:plain


認証キーが生成されます。

後から確認は出来ませんので ここでメモしておくのを忘れずに。忘れたときは再生成することになるので気を付けましょう。

f:id:vermeer-1977:20170901134123p:plain

pom.xmlを編集する

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.vermeerlab</groupId>
    <artifactId>maven-git-sample</artifactId>
    <version>0.1.0</version>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <github.global.server>github</github.global.server>
        <git.branchName>mvn-repo</git.branchName>
        <git.repositoryOwner>vermeer-1977</git.repositoryOwner>
        <git.repositoryName>maven</git.repositoryName>
        <git.isMerge>true</git.isMerge>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8.2</version>
                <configuration>
                    <altDeploymentRepository>internal.repo::default::file://${project.build.directory}/${git.branchName}</altDeploymentRepository>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.github.github</groupId>
                <artifactId>site-maven-plugin</artifactId>
                <version>0.12</version>
                <configuration>
                    <!-- git commit message -->
                    <message>Maven artifacts for ${project.version}</message>
                    <noJekyll>true</noJekyll>
                    <outputDirectory>${project.build.directory}/${git.branchName}</outputDirectory>
                    <branch>refs/heads/${git.branchName}</branch>
                    <includes>
                        <include>**/*</include>
                    </includes>

                    <repositoryName>${git.repositoryName}</repositoryName>
                    <repositoryOwner>${git.repositoryOwner}</repositoryOwner>

                    <!-- true:履歴を残す false:直近バージョンのみ repositoryに残る -->
                    <merge>${git.isMerge}</merge>

                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>site</goal>
                        </goals>
                        <phase>deploy</phase>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.0</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.source}</target>
                    <compilerArgs>
                        <arg>-Xlint</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>

    </build>

    <distributionManagement>
        <repository>
            <id>internal.repo</id>
            <name>Temporary Staging Repository</name>
            <url>file://${project.build.directory}/${git.branchName}</url>
        </repository>
    </distributionManagement>
</project>
  • ローカル保存先の distributionManagementurl の指定でリポジトリ名と同じフォルダを指定しています。任意のフォルダ名で良く、特に意味を持たせる必然は無いけれど pom内に複数個所指定するので 記述誤りを防ぐために同名にしました。

  • git.isMergetrueであればアップロードした資産の履歴を残します。SNAPSHOTの場合は履歴を残すけど、そうじゃなくなったら履歴は不要というような指定をしたい場合に使用する想定かな?と思っています。

settings.xmlを編集する

...\.m2\settings.xmlに格納されています。

NetBeansMavenプロジェクトだったら、以下のものを編集。見た感じだとプロジェクト毎に存在するように見えますが 全てのプロジェクトで共通の資産です。どのプロジェクトのものを編集してもちゃんと反映されます*6

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <servers>
        <server>
            <id>github</id>
            <password>hogehogehogehogehogehogehogehogehogehoge</password>
        </server>
    </servers>
</settings>

hogehoge… は先に取得した認証キーを設定してください。

Maven資産をアップロード

mvn deploy コマンドを実行します。


f:id:vermeer-1977:20170901154750p:plain


f:id:vermeer-1977:20170901154823p:plain


f:id:vermeer-1977:20170901161244p:plain


アップロードされたリポジトリのアドレスは

GitHub - vermeer-1977/maven at mvn-repo

ちなみに通常のビルドではアップロードはされません。

簡易クラスを作成

次の工程で参照するためのクラスを追加します。

public class Sample {

    public void testPrint() {
        System.out.println("maven-test-sample");
    }
}

改めて deploy します。

リポジトリ資産を取り込む

public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new org.vermeerlab.maven.git.sample.Sample().testPrint();
    }

}

アップロードをした資産の取り込むための設定。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.vermeerlab</groupId>
    <artifactId>maven-git-client</artifactId>
    <version>0.1.0</version>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <github.global.server>github</github.global.server>
        <git.branchName>mvn-repo</git.branchName>
        <git.repositoryOwner>vermeer-1977</git.repositoryOwner>
        <git.repositoryName>maven</git.repositoryName>
        <git.isMerge>true</git.isMerge>
    </properties>

    <repositories>
        <repository>
            <id>github-maven</id>
            <url>https://raw.github.com/${git.repositoryOwner}/${git.repositoryName}/${git.branchName}/</url>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>always</updatePolicy>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>maven-git-sample</artifactId>
            <version>0.1.0</version>
        </dependency>
    </dependencies>

</project>

この流れだとローカルリポジトリを参照してしまいます。念のためローカルリポジトリの資産を削除して確認をすると良いと思います。ログをみたら、きちんとダウンロードをしていることが確認できます。

f:id:vermeer-1977:20170901165044p:plain

基本は以上です。

Git(コード)

vermeer_etc / maven-git-sample — Bitbucket

vermeer_etc / maven-git-client — Bitbucket


応用編(親子pomで共通化)

親pomを持つことで重厚なpom記述を全てのプロジェクトに記載しなくて良くなります。

同一ユーザーの別リポジトリにアップしたい

artifact単位でフォルダは作成されますが、意味のある単位としてリポジトリを分けておきたいケースがあります。その場合は、子pomの git.repositoryName を指定します。

子pomで指定

    <properties>
        <git.repositoryName>(変更したいリポジトリ名)</git.repositoryName>
    </properties>

同一ユーザーの別組織のリポジトリにアップしたい

リポジトリ名だけでなく、ライブラリ管理用のOrganizationを作成すると、製品毎に配布資産をグループ化することができます。

子pomで指定

    <properties>
        <git.repositoryOwner>(変更したい組織名)</git.repositoryOwner>
        <git.repositoryName>(変更したいリポジトリ名)</git.repositoryName>
    </properties>

別ユーザーのリポジトリにアップしたい

別ユーザー=認証キーが異なるアカウント管理配下のリポジトリを意図しています。例えばオーナーは別の人だけど配布資産のアップロード権限を持っている状態です。このケースはタグによる上書きだけでなく、対象権限の認証キーも併せて指定する必要があります。

★★あくまで理論上の話です*7。★★

別ユーザーや別組織のリポジトリにアップするためには、アップロード権限のある認証キーが必要です。

認証キーは別途入手できている前提として、いちいちsettings.xmlを書き換えるのは面倒です。ということで切り替えるというのが良いと思います。

  • settings.xmlidと認証キーを追記
<server>
    <id>github</id>
    <password>hogehogehogehogehogehogehogehogehogehoge</password>
</server>

<!-- 追記 -->
<server>
    <id>github-blog</id>
    <password>fugafugafugafugafugafugafugafugafugafuga</password>
</server>

  • 子pom
    <properties>
        <github.global.server>github-blog</github.global.server>
        <git.repositoryOwner>(変更したい組織名)</git.repositoryOwner>
        <git.repositoryName>(変更したいリポジトリ名)</git.repositoryName>
    </properties>

もし基本構造が全く同じであれば指定は不要ですが リポジトリ名など明示的に変更が必要なところがあれば それも指定してください。

間違ってリモートリポジトリにアップしない工夫

とりあえず現時点で私が思いつく懸念事項と対策案です。

  • 履歴を残す

上述していますがgit.isMergeは基本的にtrueにして子pom側で上書きをしないようにすることを推奨します。履歴を持つ分、リポジトリの容量が増えてしまいますが 間違ってアップロードしたときに履歴があれば戻すことが可能です*8

  • github.global.serverの指定は子pomで明示的にする

親pomで宛先を指定しておくと子pomの記述量は減るのですが、上述の事例にあるような切り替えを検討した場合、いくつかの偶然が重なると(各種名称が重複していた&ユーザーとしても更新権限を持っていた、など)、間違った宛先のリポジトリを更新してしまうことが懸念されます。親pomには無効な値を記述しておけば、未指定の場合はアップロードが出来ないのでリスクは減るかと思います。また子pomに本記述があることが先頭で分かるので「これは公開リポジトリにアップロードする対象の資産だな」ということが明示的に分かりやすいように思います。

ただ、切り替えは基本的にしないというのであれば、親pomに記述した方が良いと思います。仕事が増えるとミスの原因も増えます。

子pom

<plugins>
    <plugin>
        <groupId>com.github.github</groupId>
        <artifactId>site-maven-plugin</artifactId>
    </plugin>
</plugins>

のところを基本的にコメントアウトしておけば 間違ってdeploy を実行してもアップロードはされません。リポジトリに資産をアップする頻度にもよりますが、頻繁でないのであれば、こういう運用もありだと思います。

注意事項

親pomのビルドを忘れずに

子pomからローカルリポジトリを参照させたいので、子pomによるビルドの前に親pomのローカルリポジトリの作成またはコードを`git clone'してビルドをするのを忘れないようにしましょう。

ローカルリポジトリの指定を忘れずに

ローカルリポジトリの相対位置をrelativePathで指定しています。こうしておかないと子pomから親pomの参照ができないためエラーになります。今回は同一グループなので、このくらいの記述ですが別グループだと、こうはいかない可能性があります*9。基本的に親pomプロジェクトは同一グループにつくると思いますので、ご自身のグループを適当に作って親と子の資産を1つのグループとして扱うと良いでしょう。

    <parent>
        <groupId>org.vermeerlab</groupId>
        <artifactId>maven-git-parent</artifactId>
        <version>0.1.0</version>
        <relativePath>../</relativePath> <!-- この指定 -->
    </parent>

Git(コード)

  • 親pom

vermeer_etc / maven-git-parent — Bitbucket

  • 子pom

vermeer_etc / maven-git-child — Bitbucket


参考

Github を Maven リポジトリとして使う -

Github上に私設Mavenリポジトリをつくる - M12i.

GitHub の Pages を maven リポジトリとして使用するときのアカウント情報をセキュアにする(OAuth2Token) | KK.Kon の徒然メモ書き

http://synergian.github.io/wagon-git/usage.html

さいごに

これでオレオレリポジトリが気軽に作れるようになりました。
目的としていた「細かいMavenプロジェクトを作っても、利用したいときにコードのダウンロードで地獄を見ない」ということが実現できそうです。

本題とは関係ないですが、目次を初めて使ってみました。これは良いですね。

*1:自分自身も含めて

*2:やり直して思うところとしてはGitHub側の認証キーのところが原因だったかも。もしくはGitPageの作成かな?

*3:作ってから思いましたが紛らわしいので違う名前にした方が分かりやすかったかも

*4:あぁ、いきなり分かりにくい

*5:上手くいかなかったのは、user:email にチェックしていなかったからダメだったかも

*6:反映というか「同じ」なんですけどね

*7:GitHub上で別ユーザーの作成も考えましたが、今回のためだけに作成するのは ちょっと違うかな と思ってやめました

*8:ミスをしない工夫も大事ですが、ミスはするもの という前提を仕組みに入れておくと心理的に安心です

*9:試してはいませんが理屈上はそのはずです