我有一个相当嵌套的结构:
> MacOSX工作站运行…
>使用ubuntu / trusty64运行的Vagrant VirtualBox虚拟机…
> Docker容器正在运行……
>我用Grails编写的应用程序
每个层的配置方式都是从上面的层共享文件系统的一部分.这条路:
> Vagrant,在Vagrantfile中使用config.vm.synced_folder指令
> Docker,在Dockerfile中使用-v命令,如switch和VOLUME指令
这样我就可以在我的工作站上进行开发,底部的Grails应用程序应该(理想情况下)检测更改并动态重新编译/重新加载.这是我在MacOSX上直接运行相同应用程序时常用的功能,但现在grails似乎完全不知道文件更改.当然,如果我使用编辑器(在Docker容器内)打开文件,它们确实已经更改,实际上如果我停止/重新启动grails应用程序,则使用新代码.
我不知道grails如何实现监视策略,但如果它依赖于某些操作系统级别的功能,我怀疑文件更改通知会在链中的某处丢失.
任何人都知道可能是什么原因和/或我如何调试这个?
最佳答案 有两种方法可以检测文件更改(我知道):
轮询,这意味着以特定间隔检查文件夹中所有文件的时间戳.进行“近乎即时”的变化检测需要非常短的间隔.这是CPU和磁盘密集型的.
OS事件(Linux上的inotify,OS X上的FSEvents),由于文件操作通过OS子系统,因此可以检测到更改.这在CPU和磁盘上很容易.
网络文件系统(NFS)等不生成事件.由于文件更改不通过客户操作系统子系统,因此操作系统不知道更改;只有进行更改的操作系统(OS X)才知道它们.
Grails和许多其他File Watcher工具依赖于FSEvents或inotify(或类似)事件.
那么该怎么办?考虑到可能产生的流量,在正常情况下“广播”从主机到所有访客的NFS更改是不切实际的.但是,我认为VirtualBox的股票应算作特殊例外……
弥合这一差距的机制可能涉及一个进程,该进程监视主机的更改并触发guest虚拟机上的同步.
查看这些文章,了解一些有趣的想法和解决方案,包括某种类型的rsync操作:
http://drunomics.com/en/blog/syncd-sync-changes-vagrant-box(Linux)
https://github.com/ggreer/fsevents-tools(OS X)
与guest虚拟机(Docker)实例上的非NFS文件夹进行Rsync,还具有I / O性能显着提高的额外优势. VirtualBox的份额非常缓慢.
更新!
这就是我做的.首先安装lsyncd(OS X示例,更多信息,请访问http://kesar.es/tag/lsyncd/):
brew install lsyncd
在我Mac上的Vagrant文件夹中,我创建了文件lsyncd.lua:
settings {
logfile = "./lsyncd.log",
statusFile = "./lsyncd.status",
nodaemon = true,
pidfile = "./lsyncd.pid",
inotifyMode = "CloseWrite or Modify",
}
sync {
default.rsync,
delay = 2,
source = "./demo",
target = "vagrant@localhost:~/demo",
rsync = {
binary = "/usr/bin/rsync",
protect_args = false,
archive = true,
compress = false,
whole_file = false,
rsh = "/usr/bin/ssh -p 2222 -o StrictHostKeyChecking=no"
},
}
这样做是将我的Vagrant文件夹中的文件夹demo同步到/ home / vagrant / demo中的客户操作系统.请注意,您需要使用SSH密钥设置登录,以使此过程无摩擦.
然后,随着vagrant VM运行,我启动了lsyncd进程. -log Exec是可选的;它将其活动记录到标准输出:
sudo lsyncd lsyncd.lua -log Exec
在vagrant VM上,我在同步文件夹中启动了Grails(2.4.4):
cd /home/vagrant/demo
grails -reloading run-app
回到IntelliJ的Mac上我编辑了一个Controller类.它几乎立即触发lsyncd(延迟2秒),之后很快我确认Grails重新编译了这个类!
总结一下:
>在Mac上编辑项目文件,在VM上执行
>使用lsyncd将更改rsync同步到VM中的文件夹
> Grails会注意到更改并触发重新加载
>不使用VirtualBox共享,可以大大提高磁盘性能
问题:Textmate触发lsyncd尚未(尚未)识别的一种FSEvent,因此未检测到更改.不过,Vim和IntelliJ很好.
希望这有助于某人!我花了一天时间来解决这个问题.