redshiftからクエリーを引くのが遅い。。

そして、アナウンスなしにマイナーバージョンアップが多い。。。

 

データの格納庫としては、

とても優れているけど、

データの引っ張る際は、

直接クエリーで引いてもよくないな。。

 

RDB側へサマリーしておいて、

それを引いたほうがいいかも。。

 

今後に期待。

投稿日時:2015年08月03日 15:40   カテゴリー:aws  

phpにも、pythonやrubyと同じようにインタラクティブシェルがあるんですね。。

最近知りました。。。

 

php -a

 

とやるみたい。。

 

投稿日時:2015年07月14日 13:13   カテゴリー:php  

6月12日にphp7-alphaがリリースされていた。

予定では、11月に正式版になるとのこと。

 

言語の書き方という面において、

個人的には、

  • 関数の戻り値型の指定
  • スカラー型によるタイプヒンティング

の導入は良いかなと思う。

 

たださ、なんかjavaにどんどん近づいているよね?

そのうち、javaのコレクションに相当するものが出てきそう。

 

httpdの組み合わせによる利用が一般的だから、

どんだけパフォーマンスでるんだろうね?

 

webサービスの場合、javaで書いたほうがよくね??

と個人的には思ってしまうよ。。

 

投稿日時:2015年06月25日 15:18   カテゴリー:php  

windows8.1

cygwinでphpビルトインサーバを用いて、

phalconフレームワークを動かしてみた。

 

予めやっておくことは、

  • ビルドできる環境
  • phpおよび関連モジュールのインストール
  • phalconのインストール(linuxの方法でcygwinもできます)

です。

 

そして、

サンプルの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ようにちょろっと修正しただけです。

投稿日時:2015年06月16日 17:36   カテゴリー:php  

新しいネタがないので、

過去の小ネタを。

 

phpでデーモンプログラムを組んで、

そこで、pdoを使う場合、

fetchを使うと処理が落ちる。

fetchAllでないとダメ。

 

理由は、、、忘れた。。

投稿日時:2015年06月16日 09:37   カテゴリー:php  

負荷試験をやっていると、

他人の状態を保持して、

その状態に応じて処理を行うということがある。

 

たとえば、

  • AさんがBさんに友達の申請をする
  • BさんがAさんの友達申請を許可する

という場合など。

 

これを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ループなどを組み合わせることで、

もっと複雑な処理が可能になる。

 

以上です。

まあ、小ネタだね。

投稿日時:2015年05月27日 10:38   カテゴリー:jmeter  

実行可能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の設定方法が書かれています。

https://github.com/jetty-project/embedded-jetty-websocket-examples/blob/master/javax.websocket-example/src/main/java/org/eclipse/jetty/demo/EventServer.java

 

以上

 

投稿日時:2015年05月15日 09:19   カテゴリー:java, websocket  

ちまたでは、chefやらansibleといった

インフラ構成ツールが流行っている。

 

しかし、個人的にはどっちもめんどくさい。

ドキュメントは充実しているが、

それなりに扱うには独自の書き方を習得する必要がある。

 

そこで、以下のように考えてみた。

  • ssh接続でコマンドを発行できる
  • ssh接続でファイルを操作し、部分置換・全体置換・追記ができる

以上があれば十分で、あと必要なものは、

  • 環境ごとの設定
  • サーバ用途でのグルーピング

ってくらいだろうか。。

 

そして、「冪等性」ってのを保つのは非常に重要。

 

これらを踏まえつつ、

基本的にはシェルスクリプトを作成し、

WEBベースで、実行・管理できればよいかなと思っている。

そんなツールに着手してみようかな。。

 

投稿日時:2015年04月16日 10:40   カテゴリー:server  

どうも「バッチサーバ」というのが好きでない。

 

WEB系をやっていると、WEBサーバ(APサーバも含む)とは別に、

バッチサーバなるものを用意するケースがあるが、

これって実はあんまりいらないと思っている。

(というか、外したいと思っている)

 

確かに、WEBサーバ側の負荷と切り離して考えられるメリットもある。

しかし、自分にとってはリソースを有効活用できていない感がある。。

 

最近では、

スクリプト言語でも、WEBサーバ内にバッチ処理用のソースコードを持つことが多々ある。

これは、どのサーバでも代替実行が出来るようにするという狙いからのものであるが、

実際はWEBサーバは複数あるケースが多く、

夜間などのアクセスが少ない時間帯で、

複数サーバで、一気にバッチを実行してしまうほうが処理が速く終わってよいと思う。

 

javaなんかでは、APサーバ内の1スレッドとして、

バッチ処理を動かすケースなんかもあるだろう。

 

ということで、こんな風にできたらいいなと思うバッチ処理をまとめてみる。

  • WEBサーバ(APサーバも含む)の1スレッドとしてバッチが実行できる
  • 手動でも実行できる
  • 同一のバッチが複数サーバで動いて欲しくないケースは排他制御をかける
  • 空いているリソースを見つけて分散できる
  • さらに、実行結果を1か所で確認できる

という感じ。

 

zookeeperなどの組み合わせることで、

上記を実現できるが、

インフラがやや複雑になり、プログラマーの管理ではなかなか厳しい。。

 

javaではcron4jなどがあったり、

nodeではcronのモジュールがあったりするので、

上手いことスレッドとして、組み込みつつ、

外側からも実行可能で、分散的に、必要あらば排他的に、

そして、出来るだけ簡素に。

そんなバッチが組めるような仕組みを考えてみたい。

 

投稿日時:2015年04月14日 17:01   カテゴリー:server  

まとめをしてみます。

  1. 第1回
  2. 第2回
  3. 第3回
  4. 第4回
  5. 第5回
  6. 第6回
  7. 第7回

という感じにまとまりました。

結局java側だけしかかけなったけど、

javaでは排他制御をかける(synchronizedブロック)がほんとに重要。

 

nodeはシングルスレッドだから、

排他制御は基本的には不要。

 

その他、大事なトピックとしては、

  • クライアントに送信しようとしても送信できないケースがある(たぶん避けらない)
  • バックエンドでDBを使う場合は、基本的にはつなぎっぱなし(ただし、RDBとRedisではちょっと扱いが違うので注意)

などでしょうか。

 

最後にスケールアウトについて。

単純にスケールアウトする場合、pub/subを使うしか手がない。

pub/subができるのは、

  • redis
  • ActiveMQ
  • Java Message Service

などがあるが、pub/subがあるとないとでは、

実装がかなり異なる。

重要なのは、

「sub」の接続を先に確立して、

処理を行い、

対象者に「pub」して、

「sub」でメッセージ送信を行う

という流れである。

 

pub/subを行うと、

データ自体もメモリに持てなくなるので、

十分注意しながらやっていただければと思います。

 

以上で、websocketの話はほんとにおしまい。

 

投稿日時:2015年04月02日 18:36   カテゴリー:java, node.js, websocket