タイトル/名前 | 更新者 | 更新日 |
---|---|---|
技術/Linux/systemd/graceful shutdown or config reload 参考メモ | msakamoto-sf | 2017-02-06 16:10:46 |
日記/2017/01/27/ネタ集め | msakamoto-sf | 2017-01-27 00:59:07 |
Java/Maven3/MultiModuleProjectのサンプル | msakamoto-sf | 2017-01-07 22:39:55 |
技術/IDE/Eclipse/Web Tools Platform (WTP), m2e-wtp | msakamoto-sf | 2017-01-07 22:35:54 |
技術/運用管理/Vagrant/"Minimal Desktop"インストールのCentOS 6.5のBox作例メモ | msakamoto-sf | 2017-01-07 22:25:08 |
JavaScript/DOMイベント,非同期処理とイベントループとスレッドモデル | msakamoto-sf | 2017-01-07 22:16:46 |
技術/運用管理/Vagrant | msakamoto-sf | 2017-01-07 22:11:43 |
日記/2015/04/29/ブログ引っ越しのお知らせ | msakamoto-sf | 2015-04-29 14:36:30 |
JavaScript/YUI Compressor メモ | msakamoto-sf | 2015-03-08 19:45:10 |
技術/Socketプログラミング/Wiresharkの使い方メモ | msakamoto-sf | 2015-03-08 19:13:48 |
systemdにてgraceful shutdown or graceful reload などを行うための参考メモ。
CentOS7でのApacheの例:
→ /usr/lib/systemd/system/httpd.service:
[Unit] Description=The Apache HTTP Server After=network.target remote-fs.target nss-lookup.target [Service] Type=notify EnvironmentFile=/etc/sysconfig/httpd ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND ExecReload=/usr/sbin/httpd $OPTIONS -k graceful ExecStop=/bin/kill -WINCH ${MAINPID} # We want systemd to give httpd some time to finish gracefully, but still want # it to kill httpd after TimeoutStopSec if something went wrong during the # graceful stop. Normally, Systemd sends SIGTERM signal right after the # ExecStop, which would kill httpd. We are sending useless SIGCONT here to give # httpd time to finish. KillSignal=SIGCONT PrivateTmp=true [Install] WantedBy=multi-user.target
ポイント:
systemd本家manページ:
RedHat のユニットファイルの解説:
その他参考:
WebExtensions :
https://developer.mozilla.org/ja/Add-ons/WebExtensions
WebRequestAPIを使ったHTTPリクエストへの介入 :
https://developer.mozilla.org/ja/Add-ons/WebExtensions/Intercept_HTTP_requests
Selenium (= WebDriver) でのスクリーンショット:
http://qiita.com/gluelan2013/items/496acff46b4c257c3ad0
http://qiita.com/meganetaaan/items/b11338d2867c8c8f072a
JavaからLibreOfficeのAPIを叩く:
http://www.slideshare.net/kenichitatsuhama/libreoffice-api
複数のMavenプロジェクトを束ねたmulti module型のプロジェクトのサンプル:
上記サンプルのポイントは、親のpom.xmlで定義したdependencyManagementとdependencyタグが、子のpom.xmlでどう扱われるか、という点。demolib1, demolib2で複数バージョン用意して、違いが分かるようにしています。
multi module型のプロジェクトの作り方自体は、以下の記事を参考:
Maven公式よりは以下の記事の方が端的な回答になってて分かりやすいかも:
Eclipse 4.2 (Juno) と NetBeans 7.4 で比較。
ポイント:マルチモジュール間のデバッグ、hotswap連携。
非常に単純な形式での実験になりますので、実際の開発環境での組み合わせによっては結果が変わる可能性もあります。上記結果は、著者個人の環境での、参考情報程度に扱って頂ければ。
Eclipse 4.2 (Juno) + m2e or m2e-wtp:
NetBeans 7.4:
EclipseでWTPツールやm2e-wtpを試したメモです。
ちょっと古いけど、Server登録後に新規プロジェクトで"Web" -> "Dynamic Web Project" or "Static Web Project" 作る流れは変わってない。
"Web"カテゴリから"Dynamic Web Project"を選択すればJavaEEのServletアプリを、"Static Web Project"を選択すれば静的なWebページプロジェクトを作れます。
多分、他にもWTPで作れるようになるプロジェクトあると思うんですが、代表例は上記2つかと。
"Dynamic Web Project"だと、"Java EE"パースペクティブでこんな感じになり、web.xmlの構成要素を視認しやすくなります。右クリックでServletを追加したりすることもできます。
"Static Web Project"はシンプルにこんな感じになります。JavaScript開発用のライブラリが追加されてます。
環境:
Win7Pro 64bit 日本語版 Eclipse 4.2 Juno SR2 Eclipse Java Web Developer Tools 3.4.2.v201209272000-7F7DFSpC26SrlX9qoilV1RGQC9ivZy86-bz-IBHe ServerとしてTomcat 7.0.x系
WTPを使ってDebug or Runを実行し、その最中にJavaのソースコードを修正すると、コンテキストの再ロードが発生するようです。
Tomcat 7.0.x系を使って起動している最中にJavaのソースを修正して保存したら、数秒後、以下のようなログがコンソールに出力されました。
8 03, 2014 6:43:11 午後 org.apache.catalina.core.StandardContext reload 情報: このコンテキストの再ロードを開始しました 8 03, 2014 6:43:13 午後 org.apache.catalina.core.StandardContext reload 情報: このコンテキストの再ロードが完了しました
コンテキストの再ロードになるので、ごっそり入れ替わるイメージになります。Servletアプリのshutdownとstartが発生するので、ContextListenerやstartup=1のServletのinit()などで複雑なクリーナップや準備処理をしていると、時間がかかるかもしれません。
Mavenプロジェクトの場合、Maven用のディレクトリ構成とEclipseのデフォルトのディレクトリ構成が大きく異なるため、そのままではWTPで処理できません。このギャップを埋めてくれるのがm2e-wtpプラグインになります。
本家:
参考:
試しに、自分で作った練習用のJersey + Servletソースを読み込ませてみました。
https://github.com/msakamoto-sf/jaxrs2-exercise-jersey-servlet
SourceTreeでcloneしたあと、EclipseのProjectのImportで、既存のMavenプロジェクトをインポートします。
→ Java パースペクティブですと、普通のMavenプロジェクトとして表示されます。
→ "Java EE" パースペクティブに切り替えると、m2e-wtpをインストールした状態ですと、自動的に認識して、WTPにあわせた見え方になりました。
Debug, Run も他のwtpプロジェクトと変わらずに操作できます。
MavenのServletアプリを通常のJavaプロジェクトで扱うと、"src/main/webapp" まで辿らないとHTMLやWEB-INFが開けないのですが、m2e-wtpであれば、"Deployed Resources" -> "webapp" から簡単にアクセスできる点も魅力的です。
WTPのプロジェクトでは、"Deployment Assembly" の設定がキモになるようですが、m2e-wtpがインストールされていると、以下の様な設定に調整してくれました。
今回試したケースでは、Mavenプロジェクトとしてインポートした後、Java EEパースペクティブに切り替えたら自動的に認識されました。そのため、明示的に"Dynamic Web Project"としてインポートする方法は未調査となります。
2014-08-02時点の環境:
Win7Pro 64bit 日本語版 Eclipse 4.2 Juno SR2 Eclipse Java Web Developer Tools 3.4.2.v201209272000-7F7DFSpC26SrlX9qoilV1RGQC9ivZy86-bz-IBHe m2e-wtp - Maven Integration for WTP 1.0.1.20130911-1545 ServerとしてTomcat 7.0.x系
※自動的に ".project" ファイルに以下のエントリーが追加される・・・。これ、m2e-wtpが入ってないEclipse環境で開いてもエラーにならないかな?
<buildSpec> <buildCommand> <name>org.eclipse.wst.common.project.facet.core.builder</name> <arguments> </arguments> </buildCommand> .... <buildSpec> <natures> ... <nature>org.eclipse.wst.common.project.facet.core.nature</nature> </natures>
WTPは単一のPlugin, Featureではなく、複数の要素から成り立っているため、細かいトラブルがぼちぼちありそうです。
以下、実際に遭遇したのを紹介します。
環境:
Win7Pro 64bit 日本語版 Eclipse 4.2 Juno SR2 Eclipse Java Web Developer Tools 3.4.2.v201209272000-7F7DFSpC26SrlX9qoilV1RGQC9ivZy86-bz-IBHe
こんな感じで、放置しとくと、どっかのタイミングで繰り返し、勝手にbreakします。
同様の症状:
どうも、Window -> Preference -> Java -> Debug で、"Suspend execution on uncaught exceptions"にチェックが入ってると、Tomcat内の部分についてもチェックするようになり、breakしてしまうようです。
→こんな感じで、チェックを外してあげれば、Debug実行で勝手にbreakすることは無くなりました。
とはいえ、本来はアプリのコードでbreakしてくれた方がうれしいので、チェックはONにしておきたいところではあります・・・。
環境:
Win7Pro 64bit 日本語版 Eclipse 4.2 Juno SR2 Eclipse Java Web Developer Tools 3.4.2.v201209272000-7F7DFSpC26SrlX9qoilV1RGQC9ivZy86-bz-IBHe
"Console"を開くとこんな例外が出てた:
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/jetty/webapp/WebAppContext at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2442) at java.lang.Class.getMethod0(Class.java:2685) at java.lang.Class.getMethod(Class.java:1620) at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:492) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:484) Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.webapp.WebAppContext at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) ... 6 more
検索するといくつか同様の症状が見つかったが、どれもJuno SR2で、自分も同じ。
一応対処法が載っているが、どうもかなり面倒くさい手順になりそう。
"Dynamic Web Project" + Tomcat ではこんなエラーは起きない。
"HTTP Preview Server"を使う時だけか?
結論としては、他のEclipseのバージョンで試してみるか、"Dynamic Web Project"化して試すか、別のIDEや環境にするか。
静的Webページを開発するのであれば、Eclipseに拘る必要も無いと思います。
技術/運用管理/Vagrant ではUbuntuでBoxを作った時のメモを載せてて、「CentOSならこうなる」的なのを簡単にメモで補足しただけでした。
今回はガッツリとCentOS 6.5で、"Minimal Desktop"インストールで作ったVirtualBoxのVMをBoxにしてみましたので、作例メモを残しておきます。
環境:
Windows7 Pro 64bit 日本語版 VirtualBox 4.3.12 Vagrant 1.6.3 CentOS 6.5 DVD iso イメージ
全体的には、技術/運用管理/Vagrant の参考資料欄にのせた記事を参考にさせてもらいました。
この辺は前回と同じです。今回はVMの名前を以下にしました。
vagrant-centos6.5-x86_64
ネットワークアダプタの1つめは、NATタイプにする必要があります:
※"vagrant-OS名"のような命名にしてる例を幾つか見かけたので、それに従いました。
例 : https://github.com/fespinoza/checklist_and_guides/wiki/Creating-a-vagrant-base-box-for-ubuntu-12.04-32bit-server
あとはrootユーザのパスワードを"vagrant"にしておきます。
最後にインストールタイプで"Minimal Desktop"タイプでインストールします。
インストール後に、SELinuxやiptablesの調整、vagrantユーザの追加、sudoの設定、VirtualBox Guest Additionのインストールなどを行います。
今回は"Minimal Desktop"でインストールしたためか、再起動後に、すぐにGUIでユーザ設定などを行う初期設定画面が表示されました。
ここでは、後でコマンドラインから確実に追加するため、何も入力せずに(上の画面では切れてしまってて分かりませんが)Forwardボタンをクリックします。
「本当にいいの?」と訊かれてきますが、「Yes」で進めてしまいます。
この後はrootユーザでログインします。
iptablesを無効化しておきます:
# service iptables stop # chkconfig iptables off # service ip6tables stop # chkconfig ip6tables off
selinuxも無効化します。前回記事の補足説明や、参考資料を参照してください。
eth0が起動時無効になってましたので、GUIから起動時有効に変更します。
MACアドレスが変更してもethNが変わらないよう、udevの設定ファイルを修正します。前回記事の補足説明や、参考資料を参照して下さい。
SSHを有効にしますが、"Minimal Desktop"インストールタイプでは既に有効になってました。
"admin"グループを追加し、"vagrant"ユーザを"admin"グループに所属させて作成します。
# groupadd admin # useradd -g admin vagrant # passwd vagrant (パスワードは"vagrant"に設定)
ここで一旦再起動して、本当にvagrantユーザでパスワード無しでsudoできるか確認しておきます。
VirtualBoxのGuest Additionをインストールする準備をします。
一旦、システム全体をアップデートしておきます:
$ sudo yum update
開発用のパッケージをまとめてインストールします:
$ sudo yum groupinstall -y "Development Tools"
※今回は"Minimal Desktop"でインストールしたせいか、kernel-headersやbzip2などもインストール済みでした。参考にした記事では、gcc, kernel-devel, kernel-headers, make, bzip2, perl とピンポイントで指定してインストールする例がありましたので、適宜調整になるかと思います。
この後、DKMSを導入する記事もあるのですが、RPMForge追加したりするのが面倒くさそうなのと、ぶっちゃけDKMS無しでも一応Guest Addition入れられたので、無しで進めます。
CentOSにDKMSを入れる参考:
こちらは、CentOSにVirtualBoxをインストールするためにDKMSをインストールするパターン
最後、"vagrant package" で圧縮する前に、キャッシュの削除やDiskのゼロ埋めを行い、圧縮率を高めます。
# yum clean all # rm -rf /tmp/* # dd if=/dev/zero of=/EMPTY bs=1M # rm -f /EMPTY
Boxファイルの生成:
> vagrant package -h Usage: vagrant package [options] [name] Options: --base NAME Name of a VM in virtualbox to package as a base box --output NAME Name of the file to output --include FILE... Additional files to package with the box --vagrantfile FILE Vagrantfile to package with the box -h, --help Print this help > vagrant package --base vagrant-centos6.5-x86_64 ==> vagrant-centos6.5-x86_64: Exporting VM... ==> vagrant-centos6.5-x86_64: Compressing package to: c:/work/package.box
BoxファイルをローカルのVagrant環境に追加する:
> vagrant box add centos65-64bit-minimal-desktop package.box ==> box: Adding box 'centos65-64bit-minimal-desktop' (v0) for provider: box: Downloading: file://c:/work/package.box box: Progress: 100% (Rate: 152M/s, Estimated time remaining: --:--:--) ==> box: Successfully added box 'centos65-64bit-minimal-desktop' (v0) for 'virtualbox'! > vagrant box list centos65-64bit-minimal-desktop (virtualbox, 0) hashicorp/precise32 (virtualbox, 1.0.0) hashicorp/precise64 (virtualbox, 1.1.0) ubuntu-1204-lts-t1 (virtualbox, 0)
この時点で、以下のディレクトリが作成され、圧縮状態のvmdk, metadata.json, Vagrantfile, box.ovf が展開される。ディレクトリ名が末尾"0"になってるところは多分ローカルのBoxで特にバージョン情報なども入ってないからだと思われる(Vagrant Cloudから追加した場合はバージョン番号になる)。
$HOME/.vagrant.d/boxes/centos65-64bit-minimal-desktop/0
テスト用のディレクトリを作成し、追加したBoxで初期化する:
> cd c:\work\tmp\vagrant_ex > mkdir t6 > cd t6 > vagrant init centos65-64bit-minimal-desktop A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on `vagrantup.com` for more information on using Vagrant.
この時点で、以下のディレクトリが作成され、Vagrantfileが生成される。
c:\work\tmp\vagrant_ex\t6
ここでVagrantfileに "config.vm.provider" でVirtualBox用のカスタマイズ設定を追加:
# -*- mode: ruby -*- # vi: set ft=ruby : # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| ... config.vm.provider "virtualbox" do |vb| vb.name = "centos65_md_demo" # Don't boot with headless mode vb.gui = true # Use VBoxManage to customize the VM. For example to change memory: vb.customize [ "modifyvm", :id, "--memory", "2048", "--vram", "64", "--cpus", "2", "--audio", "none", "--clipboard", "bidirectional", "--usb", "off", "--usbehci", "off", "--nic1", "nat", "--nictype1", "82540EM", "--cableconnected1", "on", "--nic2", "hostonly", "--nictype2", "82540EM", "--cableconnected2", "on", "--hostonlyadapter2", "VirtualBox Host-Only Ethernet Adapter", ] end ... end
Vagrantで仮想マシンを起動する:
> vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==> default: Importing base box 'centos65-64bit-minimal-desktop'... ==> default: Matching MAC address for NAT networking... ==> default: Setting the name of the VM: centos65_md_demo ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 22 => 2222 (adapter 1) ==> default: Running 'pre-boot' VM customizations... ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Connection timeout. Retrying... default: Warning: Connection timeout. Retrying... default: Warning: Remote connection disconnect. Retrying... ==> default: Machine booted and ready! ==> default: Checking for guest additions in VM... ==> default: Mounting shared folders... default: /vagrant => C:/work/tmp/vagrant_ex/t6
これによりVirtualBoxのVMが保存されてるディレクトリに以下のディレクトリが生成され、伸長されたvmdkが展開された。
$HOME/VirtualBox VMs/vagrant-centos6.5-x86_64
仮想マシンを停止する:
> vagrant suspend ==> default: Saving VM state and suspending execution...
仮想マシンを破棄する:
(t6のディレクトリにcdした状態で) > vagrant destroy
→ "$HOME/VirtualBox VMs/vagrant-centos6.5-x86_64" の中のvmdkは削除されるが、フォルダは残っていたので、手動で削除した。
タイミングかどうかわからないが、VirtualBoxのGUIマネージャ上に残ってしまうケースもあった。その場合も手動でGUIマネージャ上から削除した。
勉強中のメモです。
HTML開発でAjaxなどJavaScriptを活用しようとすると、コールバックを使った非同期処理が活躍します。
ここで一つ疑問に思ったのが、「内部実装としてはイベント処理ってどうしてるんだろう?」という点です。
Win32API開発経験者としては、「やっぱりイベントメッセージのループとかあるのかなぁ・・・」とか、「Ajaxとか非同期I/Oが発生すると、そこだけ別スレッドで処理して、処理が終わるなどのイベントが発生したら、元スレッドのイベントキューにpostしたりしてやりとりしてんのかなぁ」とか。
ということで、調査中の参考リンク、簡単なデモコードなどの仮置き場です。
JavaScriptのDOMイベントの分かりやすい概説
JavaScriptからDOMノードに任意のイベントハンドラを設定し、イベントを発生させるサンプルの解説
JavaScriptのイベントループの内部実装の解説系
html5rocksより:
SpiderMonkeyのThreadSafetyメモ
Javaでコールバック地獄を解決するためのアプローチ:
Javaでのマルチスレッドプログラミング
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> div { margin: 5px; padding: 5px; border: 1px solid red; } </style> <script> // [start : http://stackoverflow.com/questions/2490825/how-to-trigger-event-in-javascript の丸パクリ] // Add an event listener document.addEventListener("name-of-event", function(e) { console.log(e.detail); // Prints "Example of an event" }); // Create the event var event = new CustomEvent("name-of-event", { "detail": "Example of an event" }); // Dispatch/Trigger/Fire the event document.dispatchEvent(event); // [end] // stopPropagation() のテスト用グローバルフラグ window.div2_stop_propagate = false; function stop_propagete() { window.div2_stop_propagate = true; } function test() { // DOM要素が構築された後でないとgetElementById()でDOMノードを取り出せないので、body#onloadイベントで呼び出す。 var p1 = document.getElementById("p1"); p1.addEventListener("click", function(e) { console.log("p1-click", e); }); var div1 = document.getElementById("div1"); div1.addEventListener("click", function(e) { console.log("div1-click", e); }); var div2 = document.getElementById("div2"); div2.addEventListener("click", function(e) { console.log("div2-click", e); if (window.div2_stop_propagate) { // テスト用グローバルフラグがセットされていれば、stopPropagation()を呼んでみる。 e.stopPropagation(); } }); var div3 = document.getElementById("div3"); div3.addEventListener("click", function(e) { console.log("div3-click", e); }); } </script> </head> <body onload="test()"> <div id="div1"> div1 <div id="div2"> div2 <div id="div3"> div3 <p id="p1">click</p> </div> </div> </div> <hr> <input type="button" value="stop at div2" onclick="stop_propagete()"> </body> </html>
Firefox30での実行結果:
Chrome34での実行結果:
IE11での実行結果:
開発用VMのパッケージングとデプロイを簡略化してくれるVagrantのメモです。
紹介記事:
こちらのブログ、自分で作ったお手製のPHPサイトなんですが、PHPのバージョンアップに追従する時間の捻出が難しく、将来の不安が大きくなってきました。
そこで、今後は「はてなブログ」の方に記事を書いてくことにします。
既にいくつか練習を兼ねて記事を書いてて、以下のブログで引き続き技術メモなど書いていきます。
なお、こちらのサイトは引き続き公開を続けますので、既存記事はそのまま閲覧頂けます。
今後も新しいブログをよろしくお願いいたします。
公式:
使い方:
例:
デフォルトは難読化あり > java -jar yuicompressor-2.4.8.jar -o foo.min.js foo.js 難読化無し > java -jar yuicompressor-2.4.8.jar --nomunge -o bar.min.js bar.js
公式:
基本的な使い方はこの辺から:
キャプチャする時のフィルタ設定:
1.8になって、キャプチャフィルタの設定方法が少しわかりづらくなった:
表示するときのフィルタ設定:
Windowsでlocalhostをキャプチャしたい:
localhostのキャプチャについて、wireshark以外でRawCapというフリーソフトもある。フィルタとかは設定できないが、RawCap単体でlocalhostをキャプチャして、".pcap"ファイルに出力できるので、後でWiresharkで開いて解析出来る。
公式:
使い方は簡単。ただし、管理者権限が必要: