最近、おれおれライブラリの更新が進んでないわ。。
- greensofa
- bluechar / bluetable
- redchest
進めたいわ。。
IT系のめもを蓄積していこうかと
最近、おれおれライブラリの更新が進んでないわ。。
進めたいわ。。
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を使えるのであれば、これだけあれば結構いける気がする。
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>
意外とわからなかった。。
javaでsynchronizedブロックにて、
Stringを使うと、
異なるオブジェクトであっても、
文字列が同じであれば排他制御がかかる。
ただし、異なるオブジェクト・同一文字列で排他制御をかけるべきでない。
なぜなら、依存ライブラリ等でもしsyncrozinedブロックを使っていたら、
最悪デッドロック等もありえる。
(そんなライブラリはないと思うが。。)
これはStringの特性によるものなのだが、
いつか詳細を記載したいとは思う。
持続的接続をredisで行う場合、
接続は1つでよいと書いた記憶があったが、
javaでノンブロッキングでも大丈夫か検証してみた。
javaのredisクライアントはlettuceを使用し、
1つのコネクションを、
マルチスレッドで共有し、SET、GETを試みたところ、
結果にずれは生じなかった。
結論として、
redisはシングルスレッドであるため、
持続的接続の場合は1コネクションでOK。
ただし、javaではマルチスレッドの性能を生かすため、
CPU数 x 2〜3 ぐらいがいいのかなとは思う。
ちなみに、上記でやっても問題なしでした。
以上
JavaMailでSMTP接続をして、
メールを送信しようとした時、
javax.mail.MessagingException: 501 Syntax: HELO hostname
のエラーがでることがある。
これは送信元のサーバのホスト名が
/etc/hostsに掲載されていない場合に起こる。
その他にも色々方法はあるようだが、
/etc/hostsにhostnameをしっかり書いておくことは大事です。
とはいえ、最近クラウドばかり使っていると、
この辺疎かになりがち。。
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のページを見たが、それらしき記述はなかった。。
redisの冗長化を行うためには、
がある。
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の欠点は以下の通り。
などなど。
とくに、クライアントライブラリが少ないのは気がかりである。
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をベースに使っていて、
ノンブロッキングをサポートしているしね。
当サイトは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です。
昨日書いた記事を検証してみた。
以下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回やって、一度も不整合は起きず。