redshiftからクエリーを引くのが遅い。。
そして、アナウンスなしにマイナーバージョンアップが多い。。。
データの格納庫としては、
とても優れているけど、
データの引っ張る際は、
直接クエリーで引いてもよくないな。。
RDB側へサマリーしておいて、
それを引いたほうがいいかも。。
今後に期待。
IT系のめもを蓄積していこうかと
redshiftからクエリーを引くのが遅い。。
そして、アナウンスなしにマイナーバージョンアップが多い。。。
データの格納庫としては、
とても優れているけど、
データの引っ張る際は、
直接クエリーで引いてもよくないな。。
RDB側へサマリーしておいて、
それを引いたほうがいいかも。。
今後に期待。
phpにも、pythonやrubyと同じようにインタラクティブシェルがあるんですね。。
最近知りました。。。
php -a
とやるみたい。。
6月12日にphp7-alphaがリリースされていた。
予定では、11月に正式版になるとのこと。
言語の書き方という面において、
個人的には、
の導入は良いかなと思う。
たださ、なんかjavaにどんどん近づいているよね?
そのうち、javaのコレクションに相当するものが出てきそう。
httpdの組み合わせによる利用が一般的だから、
どんだけパフォーマンスでるんだろうね?
webサービスの場合、javaで書いたほうがよくね??
と個人的には思ってしまうよ。。
windows8.1
cygwinでphpビルトインサーバを用いて、
phalconフレームワークを動かしてみた。
予めやっておくことは、
です。
そして、
サンプルのinvoをダウンロードして、
公開ディレクトリに移動して、
php -S localhost:8000 routing.php
をたたけば起動する。
ここで、あらかじめ以下2点を対応しておく。
①invoのapp/config/config.iniのbaseUriを「/」に変更しておく
②公開ディレクトリ直下にrouting.phpを作成する。
<?php $route = parse_url(substr($_SERVER["REQUEST_URI"], 1))["path"]; if (is_file($route)) { if(substr($route, -4) == ".php"){ require $route; // Include requested script files exit; } return false; // Serve file as is } else { // Fallback to index.php $_GET["_url"] = "/" . $route; // Try to emulate the behaviour of your htaccess here, if needed require "index.php"; }
で、おしまい。
routing.phpについては、phpの公式ページに書いてあるのを、
phalconようにちょろっと修正しただけです。
新しいネタがないので、
過去の小ネタを。
phpでデーモンプログラムを組んで、
そこで、pdoを使う場合、
fetchを使うと処理が落ちる。
fetchAllでないとダメ。
理由は、、、忘れた。。
負荷試験をやっていると、
他人の状態を保持して、
その状態に応じて処理を行うということがある。
たとえば、
という場合など。
これをjmeterで試験する場合、
「BさんがAさんの友達申請を許可する」という処理は、
「AさんがBさんに友達の申請をする」が完了していないと成功しない。
そのためには、BさんはAさんの状態を取得する必要がある。
ここで、
AさんのIDを1
BさんのIDを2
とし、
jmeterのBSF(javascript)を使うと、
<(PostProcesser)AさんがBさん友達申請をする>
// 自分のID var my_id = 1; // 他人のID var other_id = 2; // レスポンスを取得 して申請が成功しているなら // Bさんの情報にAさんが申請したことを記録 var key = "appley-to-" + other_id; var value = my_id; props.put(key, value);
<(PreProcesser)BさんがAさんの友達申請を許可する>
// 自分のID var my_id = 2; // 他人のID var other_id = 1; // BさんがAさんからの申請状態を取得 var key = "appley-to-" + my_id; while (true) { var value = props.get(key); if (value != void(0)) { // 申請状態がとれたら、ループを抜ける break; } } // 許可処理を実行
という具合になる。
注意点としては、
jmeterが起動中は、
propsの値は常に保持されるので、
不要になったら、removeしておく必要がある。
もしくは、初期化処理でremoveしてから利用するなど。
もう1つ注意点としては、
永久ループで待機する場合は、
スレッドを停止しても処理が停止しないので、
何回かループしたら止めるとかを入れておいた方がよい。
あとは、カウンタとか、forEachループなどを組み合わせることで、
もっと複雑な処理が可能になる。
以上です。
まあ、小ネタだね。
実行可能warをmavenで作る場合、
warパッケージの直下にmainファイルを配備する必要がある。
しかし、warアプリケーションをpackageすると、
WEB-INF/classes以下にmainファイルも配備されてしまう。
そのため、maven3では、
antrunプラグインを用いて、mainファイルを移動する必要がある。
pom.xmlはこんな感じかな。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <id>move-main</id> <phase>prepare-package</phase> <configuration> <tasks> <move todir="target/${project.build.finalName}"> <fileset dir="target/classes"> <include name="app/AppMain.class" /> </fileset> </move> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin>
これにより、warファイル直下に実行可能クラスが配備される。
また、jettyなどのembedを組み込む場合、
一緒に依存関係も持って行ってやる必要がある。
こんな感じ。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>jetty-classpath</id> <phase>prepare-package</phase> <goals> <goal>unpack-dependencies</goal> </goals> <configuration> <includeGroupIds>org.eclipse.jetty,javax.servlet,javax.websocket</includeGroupIds> <excludes>META-INF/ECLIPSEF.*</excludes> <outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory> </configuration> </execution> </executions> </plugin>
そして、mainファイルはこんな感じ。
package app; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; import java.net.URL; public class AppMain { public static void main(String[] args) throws Exception { // 初期設定 int port = 8080; System.setProperty("prefix", "/"); // サーバ生成 Server server = new Server(port); // warを読み込むコンテクスト生成 URL warUrl = AppMain.class.getProtectionDomain().getCodeSource().getLocation(); String warLocation = warUrl.toExternalForm(); WebAppContext context = new WebAppContext(); context.setWar(warLocation); context.setContextPath("/"); // コンテクストにサーバをセットする // ※重要 context.setServer(server); // websocketを使えるようにする WebSocketServerContainerInitializer.configureContext(context); // 開始 server.setHandler(context); server.start(); server.join(); } }
上記が非常に重要。
これで、websocketのendpointをServletContextListener側で指定してやるとうまくいく。
package app; import websocket.WebsocketIndex; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.websocket.DeploymentException; import javax.websocket.server.ServerContainer; public class AppInitializeListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { // embed用のwebsocketの追加 try { ServerContainer wsContainer = (ServerContainer) sce.getServletContext().getAttribute(ServerContainer.class.getName()); System.out.println(String.format("wsContainer => %s", wsContainer)); if (wsContainer != null) { wsContainer.addEndpoint(WebsocketIndex.class); } } catch (DeploymentException e) { e.printStackTrace(); } } @Override public void contextDestroyed(ServletContextEvent sce) { } }
実行可能jarでwebsocketを作成する場合、
mainクラス内でendpointを設定してやればよいのだが、
実行可能warの場合、
mainクラスが実際のwebsocketのendpointのクラスの配備位置が異なるため、
クラスのロードが出来ない状態となる。
そのため、上記のような方法で、動的に指定してやることで、
実行可能warにおいて、websocketが利用できる。
【参考】
・実行可能warの生成の詳細がかかれています。
http://qiita.com/k_ui/items/1d3bbbd7993c4c9adf71
・実行可能jarでのwebsocketの設定方法が書かれています。
以上
ちまたでは、chefやらansibleといった
インフラ構成ツールが流行っている。
しかし、個人的にはどっちもめんどくさい。
ドキュメントは充実しているが、
それなりに扱うには独自の書き方を習得する必要がある。
そこで、以下のように考えてみた。
以上があれば十分で、あと必要なものは、
ってくらいだろうか。。
そして、「冪等性」ってのを保つのは非常に重要。
これらを踏まえつつ、
基本的にはシェルスクリプトを作成し、
WEBベースで、実行・管理できればよいかなと思っている。
そんなツールに着手してみようかな。。
どうも「バッチサーバ」というのが好きでない。
WEB系をやっていると、WEBサーバ(APサーバも含む)とは別に、
バッチサーバなるものを用意するケースがあるが、
これって実はあんまりいらないと思っている。
(というか、外したいと思っている)
確かに、WEBサーバ側の負荷と切り離して考えられるメリットもある。
しかし、自分にとってはリソースを有効活用できていない感がある。。
最近では、
スクリプト言語でも、WEBサーバ内にバッチ処理用のソースコードを持つことが多々ある。
これは、どのサーバでも代替実行が出来るようにするという狙いからのものであるが、
実際はWEBサーバは複数あるケースが多く、
夜間などのアクセスが少ない時間帯で、
複数サーバで、一気にバッチを実行してしまうほうが処理が速く終わってよいと思う。
javaなんかでは、APサーバ内の1スレッドとして、
バッチ処理を動かすケースなんかもあるだろう。
ということで、こんな風にできたらいいなと思うバッチ処理をまとめてみる。
という感じ。
zookeeperなどの組み合わせることで、
上記を実現できるが、
インフラがやや複雑になり、プログラマーの管理ではなかなか厳しい。。
javaではcron4jなどがあったり、
nodeではcronのモジュールがあったりするので、
上手いことスレッドとして、組み込みつつ、
外側からも実行可能で、分散的に、必要あらば排他的に、
そして、出来るだけ簡素に。
そんなバッチが組めるような仕組みを考えてみたい。
まとめをしてみます。
という感じにまとまりました。
結局java側だけしかかけなったけど、
javaでは排他制御をかける(synchronizedブロック)がほんとに重要。
nodeはシングルスレッドだから、
排他制御は基本的には不要。
その他、大事なトピックとしては、
などでしょうか。
最後にスケールアウトについて。
単純にスケールアウトする場合、pub/subを使うしか手がない。
pub/subができるのは、
などがあるが、pub/subがあるとないとでは、
実装がかなり異なる。
重要なのは、
「sub」の接続を先に確立して、
処理を行い、
対象者に「pub」して、
「sub」でメッセージ送信を行う
という流れである。
pub/subを行うと、
データ自体もメモリに持てなくなるので、
十分注意しながらやっていただければと思います。
以上で、websocketの話はほんとにおしまい。