#

テーマ:
ということで3分クッキング。というか6でそんな便利なの出てたのか。知らなかった。

package test;

import java.util.Comparator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class Test {
public static void main(String[] args) {
SortedMap<Integer, String> sourceMap = new TreeMap<Integer, String>();
sourceMap.put(1, "hoge01");
sourceMap.put(2, "hoge02");
sourceMap.put(3, "hoge03");

SortedMap<Integer, String> destMap = new TreeMap<Integer, String>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return -(o1.compareTo(o2));
}
});

int limit = 2;
for(Map.Entry<Integer, String> entry:sourceMap.entrySet()) {
if(entry.getKey().intValue() > limit) break;
destMap.put(entry.getKey(), entry.getValue());
}

for(Map.Entry<Integer, String> entry : destMap.entrySet()) {
System.out.println(entry);
}
}
}

実行結果↓
2=hoge02
1=hoge01
AD

[Java] 修得度

テーマ:
java 修得度問題
↑で、javaの問題が出されていたのでやってみた。
正直面白かったのだけど、結構手こずった・・・
ぱっと答えられたの(3)ぐらいか。。

こっから先は自分なりの回答を書くので、自力で解きたい人は先にリンク先いってください。




(1) スレッドダンプ。だけど動作を説明せよっていわれてもそのメカニズム全然しらないなあと愕然となった。そのうち別の機会にjvmの挙動として調べてみよう・・・
あといつもkill -3でやってたけどSIGQUITのほうがかっこいいな。


(2)
package sample;

class A<A>{
class B<B>{
public void out(){
System.out.print(a);
System.out.print("-");
System.out.println(b);
}

private A a;
private B b;
}

/**
* @param args
*/

public static void main(final String... args){
sample.A<String> instanceA = new sample.A<String>();
sample.A<String>.B<String> instanceB = instanceA.new B<String>();

instanceB.a = "20";
instanceB.b = "test";
instanceB.out();
}
}



(3)
package sample;

class A{
static interface AA{
String value();
}

enum B implements AA{
A,
B,
C;

private B(){

}
public String value(){
switch (this) {
case A:
return "hoge";
case B:
return "fuga";
default:
return "hogehoge";
}
}
}

/**
*
*
* @param args
*/

public static void main(final String... args)
{
System.out.println(B.A.value());
System.out.println(B.B.value());
System.out.println(B.C.value());
}
}


(4) まずmainメソッドのsysout内を分解してみると
C.class.getAnnotation(B.class).value() // D.class
.getAnnotation(B.class).value() // A.class
.newInstance().value() // A#value()

ということでAのvalue()メソッドが最後に呼ばれている。
value()メソッドを分解してみる。
return this.getClass() //A.class
.getAnnotation(B.class).value() //C.class
.newInstance().getClass() //C.class
.getAnnotation(B.class).value() //D.class
.newInstance().value(); //D#value()

今度はDのvalue()メソッドを呼んでいる。
同じように追っかけると、
return this.getClass() //D.class
.getAnnotation(B.class).value() //A.class
.newInstance().getClass() //A.class
.getAnnotation(B.class).value() //C.class
.newInstance().value(); //C#value()

ということで最終的にC#value()が呼ばれるので、"fugafuga"が出力される。

って元記事のはてブみたらscalaのひととかが回答のっけてた・・・
でもだいたいおんなじ感じだった。
いうても結構僕は(2)に手こずりました・・・
低レベルすぎて泣けてくる・・・
AD
APサーバとしてTomcatの複数台でのクラスタリング構成をする場合、
セッションの扱いってどうすんだろう。。ということでざっくり調べてみた。
つかTomcatに限った話じゃねえな。糞無知すぎる。

Session Persistence(Sticky Session)


同一のセッションアクセスを同一のノードに振り分ける、という方法。
Tomcat側は特に何もしなくても、LB側が対応できればよい。
なので例えばApacheがLBとして機能しているならmod_jkとかのsticky sessionモードにする。
技術的雑談-複数のTomcatを立ち上げてmod_jk経由でロードバランスさせる - Tsubasa's HomePage

LBがやればよいので、別にこれWebサーバである必要もなくて、
BIG IPとかLVSみたいなL4レベルで対応することもできる。
BIG IP 機能紹介 | 兼松エレクトロニクス KEL
lvsでsession persistence(セッションパーシステンス) - うまい棒blog

何をみて判断しているかはいろいろ方法があって、IPとかCookieとかが多いと思うがSSLのセッションIDとかURLとかっていうのもあるらしい。
まあでもCookieがポピュラーなのかな。

この方法のデメリットは、アクセスノードがユーザにとってはシングルポイントになるのでそのノードが落ちたらセッション情報が消失すること。再起動にもモロ影響を受ける。
あとLBにアクセスの判定っていう余計な?処理が増えるためそこでもパフォーマンスが低下するってところか。

セッションレプリケーション


ならセッション情報をレプリしちゃおうぜ!っていう方法。

これはTomcatのマニュアルに詳しい解説がある。
The Apache Tomcat 5.5 Servlet/JSP Container - Clustering/Session Replication HOW-TO
5.5ですまん。

方式はいくつかあるが要はセッション情報をコピーしてクラスタリングしている全てのノードで同じセッション情報をもつやり方。(all-to-all)
これならどのサーバに振られても同じセッション情報を参照できるので
今までアクセスしてたノードが落ちようが再起動かかろうが問題ない。

ただこの方法にも問題がある。
一つはセッション情報をいちいち全台にレプリするためトラフィックがはんぱないことになる。
さらには全台のユーザのセッション情報を全て持つので、メモリに抱える量も当然多くなる。

ドメインクラスタリング


じゃあ全台にレプリしなきゃいいんでしょ。って方法もある。
クラスタリングしてるノードをグループに分けて、そのグループ内だけでセッションレプリケーションを行う方法。
[ThinkIT] 第2回:Tomcatのクラスタ設定 (1/4)

たしかにこの方法なら冗長性も確保できる。
けど結局LBで処理しなきゃいけないし、グループの規模とかそういうチューニングを一歩間違えると前述の二つの方法のデメリットを両方引く可能性もある。
なにより複雑っす。。グループとかのルールが必要だし。ルール設定して振り分けみたいなのは事故る。

Tomcatじゃなくてmemcachedとかに持たせる


ああもう身も蓋もねえ。。

セッションに詰めとくような情報をmemcachedに持たせておけば、どこのノードに振られても大丈夫だし、レプリケーションによるトラフィックとかメモリのコストを気にしなくても良い。

まあこの方法の場合はmemcachedが落ちたら意味ないのだがかといってmemcachedの分散とかやりだすとキリがない。冗長性を確保したい場合はセッションDBとかでバックアップ、とかが現実的な落とし所か。


他にもあったら教えてほしいっす。革命的な何か。
AD