最近、おれおれライブラリの更新が進んでないわ。。

  • greensofa
  • bluechar / bluetable
  • redchest

進めたいわ。。

 

投稿日時:2016年02月10日 11:55   カテゴリー:other  

remiレポジトリにおいて、

php7対応のモジュールが結構出揃いましたね。

現時点で、以下が引っかかった。

 

$ yum search php70 --enablerepo=remi | grep -F "php70" | awk '{print $1;}'
php70-php-pecl-propro-devel.x86_64
php70-php-pecl-raphf-devel.x86_64
php70-php-pecl-xmldiff-devel.x86_64
php70-php-pecl-yaconf-devel.x86_64
php70-php-yaconf-devel.x86_64
php70-runtime.x86_64
php70-scldevel.x86_64
php70.x86_64
php70-build.x86_64
php70-php.x86_64
php70-php-ast.x86_64
php70-php-bcmath.x86_64
php70-php-cli.x86_64
php70-php-common.x86_64
php70-php-dba.x86_64
php70-php-dbg.x86_64
php70-php-devel.x86_64
php70-php-embedded.x86_64
php70-php-enchant.x86_64
php70-php-fpm.x86_64
php70-php-gd.x86_64
php70-php-gmp.x86_64
php70-php-horde-horde-lz4.x86_64
php70-php-imap.x86_64
php70-php-interbase.x86_64
php70-php-intl.x86_64
php70-php-json.x86_64
php70-php-ldap.x86_64
php70-php-litespeed.x86_64
php70-php-mbstring.x86_64
php70-php-mcrypt.x86_64
php70-php-mysqlnd.x86_64
php70-php-oci8.x86_64
php70-php-odbc.x86_64
php70-php-opcache.x86_64
php70-php-pdo.x86_64
php70-php-pdo-dblib.x86_64
php70-php-pear.noarch
php70-php-pecl-amqp.x86_64
php70-php-pecl-apcu.x86_64
php70-php-pecl-apcu-bc.x86_64
php70-php-pecl-apcu-devel.x86_64
php70-php-pecl-apfd.x86_64
php70-php-pecl-apm.x86_64
php70-php-pecl-crypto.x86_64
php70-php-pecl-eio.x86_64
php70-php-pecl-env.x86_64
php70-php-pecl-ev.x86_64
php70-php-pecl-gender.x86_64
php70-php-pecl-geoip.x86_64
php70-php-pecl-geospatial.x86_64
php70-php-pecl-gmagick.x86_64
php70-php-pecl-hdr-histogram.x86_64
php70-php-pecl-hprose.x86_64
php70-php-pecl-hrtime.x86_64
php70-php-pecl-http.x86_64
php70-php-pecl-http-devel.x86_64
php70-php-pecl-imagick.x86_64
php70-php-pecl-imagick-devel.x86_64
php70-php-pecl-json-post.x86_64
php70-php-pecl-libsodium.x86_64
php70-php-pecl-lzf.x86_64
php70-php-pecl-mailparse.x86_64
php70-php-pecl-memcache.x86_64
php70-php-pecl-memcached.x86_64
php70-php-pecl-mogilefs.x86_64
php70-php-pecl-mongodb.x86_64
php70-php-pecl-msgpack.x86_64
php70-php-pecl-msgpack-devel.x86_64
php70-php-pecl-mysql.x86_64
php70-php-pecl-oauth.x86_64
php70-php-pecl-pcs.x86_64
php70-php-pecl-pcs-devel.x86_64
php70-php-pecl-pq.x86_64
php70-php-pecl-propro.x86_64
php70-php-pecl-raphf.x86_64
php70-php-pecl-redis.x86_64
php70-php-pecl-rrd.x86_64
php70-php-pecl-seaslog.x86_64
php70-php-pecl-selinux.x86_64
php70-php-pecl-ssdeep.x86_64
php70-php-pecl-stats.x86_64
php70-php-pecl-swoole.x86_64
php70-php-pecl-taint.x86_64
php70-php-pecl-termbox.x86_64
php70-php-pecl-trader.x86_64
php70-php-pecl-translit.x86_64
php70-php-pecl-uploadprogress.x86_64
php70-php-pecl-uuid.x86_64
php70-php-pecl-varnish.x86_64
php70-php-pecl-weakref.x86_64
php70-php-pecl-xattr.x86_64
php70-php-pecl-xdebug.x86_64
php70-php-pecl-xmldiff.x86_64
php70-php-pecl-xxtea.x86_64
php70-php-pecl-yac.x86_64
php70-php-pecl-yaconf.x86_64
php70-php-pecl-yaf.x86_64
php70-php-pecl-yaml.x86_64
php70-php-pecl-yar.x86_64
php70-php-pecl-zip.x86_64
php70-php-pgsql.x86_64
php70-php-process.x86_64
php70-php-pspell.x86_64
php70-php-recode.x86_64
php70-php-smbclient.x86_64
php70-php-snmp.x86_64
php70-php-soap.x86_64
php70-php-tidy.x86_64
php70-php-xml.x86_64
php70-php-xmlrpc.x86_64
php70-php-yaconf.x86_64

 

centos7のbaseに入ってくるのは数年後だろうけど。。

remiを使えるのであれば、これだけあれば結構いける気がする。

 

投稿日時:2016年02月10日 09:26   カテゴリー:php  

jettyでtomcatJDBC poolを使っていたら、

以下のようなエラーに遭遇した。

java.util.ServiceConfigurationError: org.apache.juli.logging.Log: Provider org.eclipse.jetty.apache.jsp.JuliLog not a subtype

というわけで、
pomを修正して、tomcat jdbc poolが使っているロガーの依存関係を排除した。

<dependency>
  <groupId>org.apache.tomcat</groupId>
  <artifactId>tomcat-jdbc</artifactId>
  <version>8.0.28</version>
  <exclusions>
    <exclusion>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-juli</artifactId>
    </exclusion>
  </exclusions>
</dependency>

意外とわからなかった。。

投稿日時:2016年01月21日 13:56   カテゴリー:java  

javaでsynchronizedブロックにて、

Stringを使うと、

異なるオブジェクトであっても、

文字列が同じであれば排他制御がかかる。

 

ただし、異なるオブジェクト・同一文字列で排他制御をかけるべきでない。

なぜなら、依存ライブラリ等でもしsyncrozinedブロックを使っていたら、

最悪デッドロック等もありえる。

(そんなライブラリはないと思うが。。)

 

これはStringの特性によるものなのだが、

いつか詳細を記載したいとは思う。

 

投稿日時:2016年01月07日 19:20   カテゴリー:java  

持続的接続をredisで行う場合、

接続は1つでよいと書いた記憶があったが、

javaでノンブロッキングでも大丈夫か検証してみた。

 

javaのredisクライアントはlettuceを使用し、

1つのコネクションを、

マルチスレッドで共有し、SET、GETを試みたところ、

結果にずれは生じなかった。

 

結論として、

redisはシングルスレッドであるため、

持続的接続の場合は1コネクションでOK。

 

ただし、javaではマルチスレッドの性能を生かすため、

CPU数 x 2〜3 ぐらいがいいのかなとは思う。

ちなみに、上記でやっても問題なしでした。

 

以上

投稿日時:2015年12月29日 15:38   カテゴリー:java, redis  

JavaMailでSMTP接続をして、

メールを送信しようとした時、

javax.mail.MessagingException: 501 Syntax: HELO hostname

のエラーがでることがある。

 

これは送信元のサーバのホスト名が

/etc/hostsに掲載されていない場合に起こる。

 

その他にも色々方法はあるようだが、

/etc/hostsにhostnameをしっかり書いておくことは大事です。

とはいえ、最近クラウドばかり使っていると、

この辺疎かになりがち。。

 

投稿日時:2015年12月25日 13:45   カテゴリー:java  

javaのweb socketで、decoderとpathparamはある条件において不可能なようなだ。

 

以下の場合はダメ。

@ServerEndpoint(
  value = "/ws/{p1}/{p2}/"
  decoders = {HogeDecoder.class},
  encoders = {HogeEncoder.class})
public class HogeWebsocket {
  /**
   * open hander.
   */
  @OnOpen
  public void onOpen(@PathParam("p1") String p1, Session session, EndpointConfig config) {
    :
    :  
  }
}

 

これだと、p1がdecoderの対象になるみたい。

そのため、次のような方法で対処する。

 

@ServerEndpoint(
  value = "/ws/{p1}/{p2}/"
  decoders = {HogeDecoder.class},
  encoders = {HogeEncoder.class})
public class HogeWebsocket {
  /**
   * open hander.
   */
  @OnOpen
  public void onOpen(Session session, EndpointConfig config) {
    Map<String, String> pathParameters = session.getPathParameters();
    String p1 = pathParameters.get("p1");
    :  
  }
}

 

本件は、decoderでバイナリからテキストに変換しようとした際に起きた現象。

なので、decoderが何をするかによるとは思うが。。

javaのページを見たが、それらしき記述はなかった。。

 

投稿日時:2015年12月21日 18:38   カテゴリー:java, websocket  

redisの冗長化を行うためには、

  • master <-> slave構成
  • master <-> slave構成 + sentinel
  • cluster

がある。

clusterはredis3より正式サポートされた機能である。

 

特徴としては、以下の通り。

 

master <-> slave構成だと、

masterが倒れたときのフェイルオーバが皆無である。

 

master <-> slave構成 + sentinelだと、

masterが倒れたときに、slaveが自動昇格できる。

ただ、slave x 2以上、sentinel x 3以上が望ましい感じがする。

 

cluster構成だと、

分散でデータを保持しているため、

slaveも同時に使い、自動昇格させる必要がある。(slaveがあれば自動昇格する)

master x 3以上、slave x 3以上にする必要がある。

 

と考えると、clusterが一番な気がするが、

clusterの欠点は以下の通り。

  1. selectはない
  2. multi – execができない?
  3. 対応しているクライアントライブラリが少ない
  4. リダイレクトが発生するため、速度が遅くなる?
  5. クラスター再構築が難しめ

などなど。

とくに、クライアントライブラリが少ないのは気がかりである。

python, rubyではあるらしい。

javaでもlettuceが対応している。

javaのコードは以下の通り。

List<RedisURI> list = new ArrayList<>();
list.add(new RedisURI("192.168.1.45", 16381, 1, TimeUnit.SECONDS));
list.add(new RedisURI("192.168.1.45", 16382, 1, TimeUnit.SECONDS));
list.add(new RedisURI("192.168.1.45", 16383, 1, TimeUnit.SECONDS));
list.add(new RedisURI("192.168.1.45", 16384, 1, TimeUnit.SECONDS));
list.add(new RedisURI("192.168.1.45", 16385, 1, TimeUnit.SECONDS));
list.add(new RedisURI("192.168.1.45", 16386, 1, TimeUnit.SECONDS));

RedisClusterClient client = RedisClusterClient.create(new Iterable<RedisURI>() {
  @Override
  public Iterator<RedisURI> iterator() {
    return list.iterator();
  }
});

AsyncExecutions<String> excutions = null;

RedisAdvancedClusterAsyncCommands<String, String> con = client.connect().async();

AsyncNodeSelection<String, String> masters = con.masters();

excutions = masters.commands().set("hoge", "fuga");

excutions.forEach(result -> result.thenAccept(ret -> System.out.println(ret)));
excutions = masters.commands().get("hoge");

excutions.forEach(result -> result.thenAccept(ret -> System.out.println(ret)));
con.close();
client.shutdown();

 

しかし、multi – execができないのは結構痛い。。。

うまいことやればできるのかな。。

ただ、分散してしまうから、無理なきがする。

 

このlettuceっていうライブラリは良さげ。

nettyをベースに使っていて、

ノンブロッキングをサポートしているしね。

 

投稿日時:2015年12月10日 13:06   カテゴリー:java, redis  

当サイトはhttpサーバとして、

nginxで運用しているのだが、

nginxをipv4とipv6のハイブリット運用に変更したので、

メモを残す。

 

nginx.conf

user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
  worker_connections 1024;
  multi_accept on;
  use epoll;
}

http {
  server_tokens off;
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;

  keepalive_timeout 10;
  client_header_timeout 10;
  client_body_timeout 10;
  reset_timedout_connection on;

  send_timeout 10;
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  charset UTF-8;

  server {
    listen 80;
    listen [::]:80 ipv6only=on;
  }
  include /etc/nginx/conf.d/*.conf;
}

 

そして、一部sslサイトがあるので、

ssl側は以下のようにする。

※httpでアクセスしてきたときのリダイレクトも入れている

 

server {
  server_name  example.com;
  return 301 https://$host$request_uri;
}

server {
  listen 443;
  listen [::]:443 ipv6only=on ssl;

  ssl on;
  ssl_certificate /etc/pki/tls/certs/server.crt;
  ssl_certificate_key /etc/pki/tls/certs/server.key;

  server_name example.com;
  :
  :
}

 

netstatの結果、

nginxがipv4の80と443、ipv6の80と443で待ち受けていることがわかる。

# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      27124/nginx: master
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      27124/nginx: master
tcp6       0      0 :::443                  :::*                    LISTEN      27124/nginx: master
tcp6       0      0 :::80                   :::*                    LISTEN      27124/nginx: master

 

ちなみに、centos7で、nginxのバージョンは1.6.3です。

投稿日時:2015年12月07日 14:22   カテゴリー:nginx  

昨日書いた記事を検証してみた。

 

以下3つの例を検証。

 

1.単純ケース

@WebServlet(name = "test01", urlPatterns = {"/test01"})
public class Test01 extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String name = req.getParameter("name");

    try (PrintWriter writer = resp.getWriter();) {
      resp.setStatus(200);
      resp.setContentType("text/plain");
      writer.write("name is " + name);
      writer.flush();
      writer.close();
    }
  }
}

 

2.絶対ダメなケース

@WebServlet(name = "test02", urlPatterns = {"/test02"})
public class Test02 extends HttpServlet {

  private String name;

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    name = req.getParameter("name");

    try (PrintWriter writer = resp.getWriter();) {
      resp.setStatus(200);
      resp.setContentType("text/plain");
      writer.write("name is " + name);
      writer.flush();
      writer.close();
    }
  }
}

 

3.今回検証したかったケース

@WebServlet(name = "test03", urlPatterns = {"/test03"})
public class Test03 extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    new MyClass(req, resp).execute();
  }

  class MyClass {

    private HttpServletRequest req;
    private HttpServletResponse resp;
    private String name;

    public MyClass(HttpServletRequest req, HttpServletResponse resp) {
      this.req = req;
      this.resp = resp;

      name = req.getParameter("name");
    }

    public void execute() throws IOException {
      try (PrintWriter writer = resp.getWriter();) {
        resp.setStatus(200);
        resp.setContentType("text/plain");
        writer.write("name is " + name);
        writer.flush();
        writer.close();
      }
    }
  }
}

 

結論としては、3は大丈夫であった。

jmeterで同時接続100を10回やって、一度も不整合は起きず。

 

投稿日時:2015年11月27日 14:52   カテゴリー:java