dev-cluster-host.sh 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. ## This starts configurable number of core and replicant nodes on the same host (not in docker).
  4. ## The nodes are named as core1, core2, replicant3, replicant4, ... where the number monotically increases.
  5. ## The number in node name is used as an offset for ekka to avoid clashing (see ekka_dist:offset/1).
  6. ## Nodes are started on loopback addresses starting from 127.0.0.1.
  7. ## The script uses sudo to add loopback aliases.
  8. ## The boot script is ./_build/emqx/rel/emqx/bin/emqx.
  9. ## The data and log directories are configured to use ./tmp/
  10. # ensure dir
  11. cd -P -- "$(dirname -- "$0")/../"
  12. help() {
  13. echo
  14. echo "$0 start|stop [-h|--help] [-n|--nodes <number>] [-c|--cores <number>] [-b|--boot <script>]"
  15. echo
  16. echo "-h|--help: To display this usage info"
  17. echo "-n|--nodes: total number of nodes to start (default: 2)"
  18. echo "-c|--cores: number of core nodes to start (default: 2)"
  19. echo "-b|--boot: boot script (default: ./_build/emqx/rel/emqx/bin/emqx)"
  20. echo "--no-cluster: don't create a cluster, just start separate nodes"
  21. }
  22. if [ "$#" -lt 1 ]; then
  23. help
  24. exit 1
  25. fi
  26. CMD="$1"
  27. shift || true
  28. export EMQX_NODE__COOKIE=test
  29. PROFILE=${PROFILE:-emqx}
  30. BOOT_SCRIPT="./_build/${PROFILE}/rel/emqx/bin/emqx"
  31. NODES=2
  32. CORE_NODES=2
  33. NO_CLUSTER=false
  34. while [ "$#" -gt 0 ]; do
  35. case $1 in
  36. -h|--help)
  37. help
  38. exit 0
  39. ;;
  40. -n|--nodes)
  41. NODES="$2"
  42. shift 2
  43. ;;
  44. -c|--cores)
  45. CORE_NODES="$2"
  46. shift 2
  47. ;;
  48. -b|--boot)
  49. BOOT_SCRIPT="$2"
  50. shift 2
  51. ;;
  52. --no-cluster)
  53. NO_CLUSTER=true
  54. shift
  55. ;;
  56. *)
  57. echo "unknown option $1"
  58. exit 1
  59. ;;
  60. esac
  61. done
  62. REPLICANT_NODES=$((NODES - CORE_NODES))
  63. # cannot use the same node name even IPs are different because Erlang distribution listens on 0.0.0.0
  64. CORE_IDS=()
  65. REPLICANT_IDS=()
  66. SEEDS_ARRAY=()
  67. for i in $(seq 1 "$CORE_NODES"); do
  68. SEEDS_ARRAY+=("core${i}@127.0.0.$i")
  69. CORE_IDS+=("$i")
  70. done
  71. if [ "$REPLICANT_NODES" -gt 0 ]; then
  72. for i in $(seq "$((CORE_NODES+1))" "$((CORE_NODES+REPLICANT_NODES))"); do
  73. REPLICANT_IDS+=("$i")
  74. done
  75. fi
  76. if [ "${NO_CLUSTER}" = true ]; then
  77. SEEDS_ARRAY=()
  78. fi
  79. SEEDS="$(IFS=,; echo "${SEEDS_ARRAY[*]}")"
  80. if [ "$CMD" = "stop" ]; then
  81. for id in "${REPLICANT_IDS[@]}"; do
  82. env EMQX_NODE_NAME="replicant${id}@127.0.0.$id" "$BOOT_SCRIPT" stop || true
  83. done
  84. for id in "${CORE_IDS[@]}"; do
  85. env EMQX_NODE_NAME="core${id}@127.0.0.$id" "$BOOT_SCRIPT" stop || true
  86. done
  87. exit 0
  88. fi
  89. start_cmd() {
  90. local role="$1"
  91. local id="$2"
  92. local ip="127.0.0.$id"
  93. local nodename="$role$id"
  94. local nodehome
  95. nodehome="$(pwd)/tmp/$nodename"
  96. mkdir -p "${nodehome}/data" "${nodehome}/log"
  97. cat <<-EOF
  98. env DEBUG="${DEBUG:-0}" \
  99. EMQX_NODE_NAME="$nodename@$ip" \
  100. EMQX_CLUSTER__STATIC__SEEDS="$SEEDS" \
  101. EMQX_CLUSTER__DISCOVERY_STRATEGY=static \
  102. EMQX_NODE__ROLE="$role" \
  103. EMQX_LOG__FILE_HANDLERS__DEFAULT__LEVEL="${EMQX_LOG__FILE_HANDLERS__DEFAULT__LEVEL:-debug}" \
  104. EMQX_LOG__FILE_HANDLERS__DEFAULT__FILE="${nodehome}/log/emqx.log" \
  105. EMQX_LOG_DIR="${nodehome}/log" \
  106. EMQX_NODE__DATA_DIR="${nodehome}/data" \
  107. EMQX_LISTENERS__TCP__DEFAULT__BIND="$ip:1883" \
  108. EMQX_LISTENERS__SSL__DEFAULT__BIND="$ip:8883" \
  109. EMQX_LISTENERS__WS__DEFAULT__BIND="$ip:8083" \
  110. EMQX_LISTENERS__WSS__DEFAULT__BIND="$ip:8084" \
  111. EMQX_DASHBOARD__LISTENERS__HTTP__BIND="$ip:18083" \
  112. "$BOOT_SCRIPT" start
  113. EOF
  114. }
  115. start_node() {
  116. local cmd
  117. cmd="$(start_cmd "$1" "$2" | envsubst)"
  118. echo "$cmd"
  119. eval "$cmd"
  120. }
  121. for id in "${CORE_IDS[@]}"; do
  122. set +e
  123. if ! ifconfig lo0 alias "127.0.0.$id" up; then
  124. echo "Failed to create an alias for loopback address 127.0.0.$id. Retrying with sudo."
  125. set -e
  126. sudo ifconfig lo0 alias "127.0.0.$id" up
  127. fi
  128. set -e
  129. start_node core "$id" &
  130. done
  131. for id in "${REPLICANT_IDS[@]}"; do
  132. set +e
  133. if ! ifconfig lo0 alias "127.0.0.$id" up; then
  134. echo "Failed to create an alias for loopback address 127.0.0.$id. Retrying with sudo."
  135. set -e
  136. sudo ifconfig lo0 alias "127.0.0.$id" up
  137. fi
  138. set -e
  139. start_node replicant "$id" &
  140. done