我正在尝试在一些长生不老药节点之间设置群集。我的理解是,可以通过修改发行版vm.args进行设置。我正在使用Distillery来构建发行版,并且正在关注这里的文档:https://hexdocs.pm/distillery/config/runtime.html。
我的rel / vm.args文件如下:
-name <%= release_name %>@${HOSTNAME}
-setcookie <%= release.profile.cookie %>
-smp auto
-kernel inet_dist_listen_min 9100 inet_dist_listen_max 9155
-kernel sync_nodes_mandatory '[${SYNC_NODES_MANDATORY}]'
我有一个运行Ubuntu 18.04的构建服务器和两个运行Ubuntu 18.04的Web服务器。我正在构建服务器上构建发行版,将存档复制到Web服务器,然后将其取消存档并在此处启动。
在服务器上,两个vm.args文件计算为:
-name hifyre_platform@10.10.10.100
-setcookie wefijow89236wj289*PFJ#(*98j3fj()#J()#niof2jio
-smp auto
-kernel inet_dist_listen_min 9100 inet_dist_listen_max 9155
-kernel sync_nodes_mandatory '["\'my_app@10.10.10.100\'","\'my_app@10.10.10.200\'"]'
和
-name hifyre_platform@10.10.10.200
-setcookie wefijow89236wj289*PFJ#(*98j3fj()#J()#niof2jio
-smp auto
-kernel inet_dist_listen_min 9100 inet_dist_listen_max 9155
-kernel sync_nodes_mandatory '["\'my_app@10.10.10.100\'","\'my_app@10.10.10.200\'"]'
这些发布是通过具有以下配置的systemd运行的:
[Unit]
Description=My App
After=network.target
[Service]
Type=simple
User=ubuntu
Group=ubuntu
WorkingDirectory=/opt/app
ExecStart=/opt/app/bin/my_app foreground
Restart=on-failure
RestartSec=5
Environment=PORT=8080
Environment=LANG=en_US.UTF-8
Environment=REPLACE_OS_VARS=true
Environment=HOSTNAME=10.10.10.100
SyslogIdentifier=my_app
RemainAfterExit=no
[Install]
WantedBy=multi-user.target
两个服务器上的发行版都运行良好,但是当我打开远程控制台并运行Node.list()
时,除非手动连接两个节点,否则结果为空列表。
如果我手动运行Node.connect(:"my_app@10.10.10.200")
,则在每个节点上运行Node.list()
时都会看到另一个节点,但这在启动时不会自动发生。
答案 0 :(得分:3)
vm.args
文件最终使用-args_file
参数传递给Erlang。我去看了the documentation for -args_file
,发现它实际上没有很好的记录。事实证明,vm.args
就像一个洋葱,因为它有很多层,文档似乎都在源代码中。
让我们从我们要结束的地方开始。我们希望sync_nodes_mandatory
是原子列表,并且需要用Erlang语法编写。如果我们使用短节点名称,例如my_app@myhost
,我们可以避免不引用原子,但是其中带有点的原子需要使用单引号引起来:
['my_app@10.10.10.100','my_app@10.10.10.200']
我们希望它是the function build_args_from_string
in erlexec.c
的输出。此功能有四个规则:
因此,由于我们要将单引号传递给解析器,因此有两种选择。我们可以转义单引号:
[\'my_app@10.10.10.100\',\'my_app@10.10.10.200\']
或者我们可以将单引号括在双引号中:
["'my_app@10.10.10.100','my_app@10.10.10.200'"]
(实际上,只要将单引号的每次出现都放在一对双引号之内,我们放置双引号的数量和位置并不重要。这只是一种可行的实现方式。)
但是,如果我们选择使用反斜杠对单引号进行转义,则会遇到另一层! The function read_args_file
是在将文件vm.args
传递到build_args_from_string
之前实际从磁盘读取#
文件的功能,它首先施加了自己的规则!即:
[\'my_app@10.10.10.100\',\'my_app@10.10.10.200\']
字符会忽略所有字符,直到下一个换行符为止因此,如果我们要在vm.args
中写read_args_file
,则build_args_from_string
将使用反斜杠,而$ iex --erl '-args_file /tmp/vm.args'
2019-04-25 17:00:02.966277 application_controller: ~ts: ~ts~n
["syntax error before: ","'.'"]
"[my_app@10.10.10.100,my_app@10.10.10.200]"
{"could not start kernel pid",application_controller,"{bad_environment_value,\"[my_app@10.10.10.100,my_app@10.10.10.200]\"}"}
could not start kernel pid (application_controller) ({bad_environment_value,"[my_app@10.10.10.100,my_app@10.10.10.200]"})
Crash dump is being written to: erl_crash.dump...done
将使用单引号,从而给我们留下无效的条件,并且错误:
-kernel sync_nodes_mandatory [\\'my_app@10.10.10.100\\',\\'my_app@10.10.10.200\\']
所以我们可以使用双反斜杠:
-kernel sync_nodes_mandatory "['my_app@10.10.10.100','my_app@10.10.10.200']"
或者只用双引号(这次是不同的,同样有效的变体):
sync_nodes_timeout
如the documentation for the kernel
application中所述,您还需要将infinity
设置为毫秒或-kernel sync_nodes_timeout 10000
的时间:
指定此节点等待强制和可选节点启动的时间(以毫秒为单位)。如果未定义此参数,则不执行节点同步。
添加类似内容:
``class ElementPosPayment : FormElement, ValueFormElement,
ReadyFormElement, ApiDataView, View.OnClickListener {
//Error occurs here on both value and activity variables declarations
private var value: String? = null
private var activity: BaseActivity? = null
//The interface class for ValueFormElement is
interface ValueFormElement : BaseElement {
var value: Pair<Boolean, Hashtable<String, String>>
var name: String
fun setValue(value: String)
}
答案 1 :(得分:1)
这是另一种解决方案。我在调查此问题时发现了它。
创建具有以下内容的文件./priv/sync.config
:
[{kernel, [
{sync_nodes_mandatory, ['my_app@10.10.10.200', 'my_app@10.10.10.200']},
{sync_nodes_timeout, 15000}
]}].
将此行添加到vm.args
:
-config <%= :code.priv_dir(release_name) %>/sync
构建一个发行版,并在15秒钟(配置文件中的超时值)内连接控制台,并启动两个节点。执行Node.list()
进行验证。
现在,您可以在构建发行版时考虑生成此配置文件。